Definitions/Def_ModularCurve_SpecializationMap.lean
Specialisation of places and divisor classes to characteristic ℓ
Two layers of material are set up here. The first is valuation-theoretic, for a place w of an extension F/K in the project's sense (AlgebraicCurve.Place: a proper valuation subring of F containing the image of K, with principal ideals, hence a discrete valuation ring, with order function ord). For f\in F and a\in K, AlgebraicCurve.Place.HasValueAt says that f-\mathrm{algebraMap}\,a lies in the nonunits of the valuation ring of w; equivalently f is w-integral with residue the image of a, and such an a is unique and behaves additively, multiplicatively and under inversion. Given moreover a valuation subring A\subseteq K, compSubring is the subring of those f\in F whose value at w lies in A, value the resulting surjective ring homomorphism onto A, and centre the preimage of the maximal ideal of A, a maximal ideal; when K surjects onto the residue field of w this subring is itself a valuation subring of F (compValuationSubring), the composite of w with A. Supporting results identify the subring generated by A and a transcendental element with a polynomial ring A[X] (hence integrally closed), show that elements integral over a subring of compSubring again lie in it when K is algebraically closed, give uniqueness of a value homomorphism on such a subring, and show that residue fields are finite over the residue field of a restricted place in a finite extension.
The second layer concerns the function fields. Over any commutative ring, jqModC is the Laurent series q^{-1}(1+\cdots) obtained from the integral j-numerator, jqNModC its substitution q\mapsto q^{N}, and modularFunctionFieldC k N the subfield of k((q)) generated by the two. It is shown that jqModC is transcendental over the base, that a modular polynomial datum for N (a bivariate integral polynomial, monic in one variable, vanishing on the pair (j(q),j(q^{N}))) continues to vanish after coefficientwise reduction, so that the second generator is integral — and, when the reduced polynomial over k(X) is separable, separable — over the subfield generated by the first, whence k(\tilde j,\tilde j_N) is finite separable over k(\tilde j); the same argument with the divisor expansions j(q^{d}), d\mid N, makes the base change of the characteristic-zero function field to \overline{\mathbb{Q}} finite over \overline{\mathbb{Q}}(\bar j). On this basis the module defines, relative to a fibre model of X_0(N) at a valuation subring A of \overline{\mathbb{Q}} with reduction A\to k (the structure FibreModel, which carries the two chart subrings, their reduction homomorphisms with prescribed values on the constants, on \bar j, \bar j_N and \bar j^{-1}, the kernels, and integrality and fraction-field clauses as fields), a specialisation map from places of the characteristic-zero function field to places of the characteristic-\ell fibre field, given by the finite chart when \bar j has a value in A at the place and by the pole chart otherwise, each branch arising as the place attached to the centre of a prime of the corresponding model ring; its \mathbb{Z}-linear extension to divisors; a predicate asserting that this divisor map preserves degree zero and principality; and the induced homomorphism on degree-zero divisor class groups, made total by taking the zero map where the predicate fails. A final packaging assembles these maps into the programme's place-specialisation structure from hypotheses matching its clauses.
Relation to Mathlib
Mathlib supplies valuation subrings, their nonunits, residue fields and ValuationSubring.ofSubring, together with integral closure and going-down machinery; the notion of place used throughout is the project's AlgebraicCurve.Place, and the composite of a place with a valuation subring of the constant field, the q-expansion function fields modularFunctionFieldC, and the specialisation maps on places, divisors and degree-zero divisor classes have no Mathlib counterpart.
Where it is used
These maps transport places and degree-zero divisor classes of X_0(N) from characteristic 0 to the fibre in characteristic \ell, which is the setting in which Hecke operators are compared with Frobenius. That comparison is what supplies the Galois representations attached to modular forms used in the level-lowering half of the proof of Fermat's Last Theorem.
References
- J. Igusa, Kroneckerian model of fields of elliptic modular functions, American Journal of Mathematics 81 (1959), 561–577
- P. Deligne and M. Rapoport, Les schémas de modules de courbes elliptiques, in: Modular Functions of One Variable II, Lecture Notes in Mathematics 349, Springer, 1973, 143–316
- O. Zariski and P. Samuel, Commutative Algebra II, Van Nostrand, 1960
References are suggested automatically and have not been individually verified.
English text generated automatically from the Lean source; the Lean statement is authoritative.
- 4,449 lines
- 237 declarations
- used in the statements of 106 theorems and imported by 112 proofs
- imports 8 definition modules
Source file: Definitions/Def_ModularCurve_SpecializationMap.lean
Imports
Imported by
- no other definition module
Declarations
- def
ModularCurve.CharPModel.laurentMapRingHom - theorem
ModularCurve.CharPModel.laurentMapRingHom_apply - theorem
ModularCurve.CharPModel.laurentMap_injective - theorem
ModularCurve.CharPModel.map_eval₂Bivar - theorem
ModularCurve.CharPModel.qExpand_map - theorem
ModularCurve.CharPModel.map_jqNModC - theorem
ModularCurve.CharPModel.intEval_eq_zero - theorem
ModularCurve.CharPModel.fibreEval_eq_zero - theorem
ModularCurve.CharPModel.intEvalSwap_eq_zero - theorem
ModularCurve.CharPModel.fibreEvalSwap_eq_zero - theorem
ModularCurve.CharPModel.transcendental_subtype - theorem
ModularCurve.CharPModel.tjq_pow - theorem
ModularCurve.CharPModel.tjq_constantCoeff_map - theorem
ModularCurve.CharPModel.tjq_coeff_pow_self - theorem
ModularCurve.CharPModel.tjq_coeff_pow_of_lt - theorem
ModularCurve.CharPModel.tjq_algebraMap_eq_single - theorem
ModularCurve.CharPModel.tjq_aeval_eq_zero - theorem
ModularCurve.CharPModel.tjq_transcendental - theorem
ModularCurve.CharPModel.coeffEmb_jq_eq_jqModC - theorem
ModularCurve.CharPModel.rf_linearIndependent_lift - theorem
ModularCurve.CharPModel.rf_finite_residueField - theorem
ModularCurve.CharPModel.transcendental_jBar - theorem
ModularCurve.CharPModel.transcendental_jC - theorem
ModularCurve.CharPModel.fibreEval_subtype - theorem
ModularCurve.CharPModel.adjoin_pair_subtype_eq_top - theorem
ModularCurve.CharPModel.isIntegral_adjoin_of_bivar_monic - theorem
ModularCurve.CharPModel.barEval_laurent - theorem
ModularCurve.CharPModel.barEval_subtype - theorem
ModularCurve.CharPModel.finiteDimensional_adjoin_jC - theorem
ModularCurve.CharPModel.algebraMap_comp_aeval_adjoin_self - def
ModularCurve.CharPModel.jLine - def
ModularCurve.CharPModel.jNLine - theorem
ModularCurve.CharPModel.transcendental_jLine - def
ModularCurve.CharPModel.lineEquivC - theorem
ModularCurve.CharPModel.lineEquivC_algebraMap - theorem
ModularCurve.CharPModel.lineX - theorem
ModularCurve.CharPModel.lineConst - theorem
ModularCurve.CharPModel.lineFun - theorem
ModularCurve.CharPModel.lineMapEq - theorem
ModularCurve.CharPModel.linePsep - theorem
ModularCurve.CharPModel.lineAevalZero - theorem
ModularCurve.CharPModel.lineDvd - theorem
ModularCurve.CharPModel.isSeparable_jNC - theorem
ModularCurve.CharPModel.isSeparable_line_fibre - def
ModularCurve.CharPModel.jdBar - theorem
ModularCurve.CharPModel.barEvalD_subtype - theorem
ModularCurve.CharPModel.lbc_eq_adjoin_divisors - theorem
ModularCurve.CharPModel.adjoin_val_preimage_eq_top - def
ModularCurve.CharPModel.barGenSet - theorem
ModularCurve.CharPModel.adjoin_barGenSet_eq_top - theorem
ModularCurve.CharPModel.barGenSet_finite - theorem
ModularCurve.CharPModel.jBar_mem_barGenSet - theorem
ModularCurve.CharPModel.barGenSet_integral - theorem
ModularCurve.CharPModel.finiteDimensional_lineBar_of_dataAll - theorem
ValuationSubring.closureConstantsAdjoin_eq_range_aeval - theorem
ValuationSubring.aeval_injective_of_transcendental - theorem
ValuationSubring.aeval_mem_closure - def
ValuationSubring.polynomialEquivClosure - theorem
ValuationSubring.polynomialEquivClosure_apply - theorem
ValuationSubring.isIntegrallyClosed_closure - theorem
Subring.isIntegral_iff_exists_monic_eval₂ - theorem
Subring.exists_ideal_le_comap_eq_of_isIntegral - theorem
AlgebraicCurve.Place.algebraMap_mem - theorem
AlgebraicCurve.Place.algebraMap_mem_nonunits_iff - theorem
AlgebraicCurve.Place.mul_mem_nonunits - theorem
AlgebraicCurve.Place.mem_of_ord_pos - theorem
AlgebraicCurve.Place.mem_nonunits_iff_ord_pos - def
AlgebraicCurve.Place.HasValueAt - theorem
AlgebraicCurve.Place.hasValueAt_iff - theorem
AlgebraicCurve.Place.hasValueAt_iff_ord_pos - theorem
AlgebraicCurve.Place.hasValueAt_of_ord_pos - theorem
AlgebraicCurve.Place.hasValueAt_algebraMap - theorem
AlgebraicCurve.Place.hasValueAt_zero_iff - theorem
AlgebraicCurve.Place.mem_of_hasValueAt - theorem
AlgebraicCurve.Place.HasValueAt.unique - theorem
AlgebraicCurve.Place.HasValueAt.add - theorem
AlgebraicCurve.Place.HasValueAt.neg - theorem
AlgebraicCurve.Place.HasValueAt.mul - theorem
AlgebraicCurve.Place.HasValueAt.inv - theorem
AlgebraicCurve.Place.HasValueAt.div - theorem
AlgebraicCurve.Place.hasValueAt_iff_residue - theorem
AlgebraicCurve.Place.exists_hasValueAt - theorem
AlgebraicCurve.Place.surjective_algebraMap_residueField_of_isAlgClosed - theorem
AlgebraicCurve.Place.surjective_algebraMap_residueField_of_deg_eq_one - def
AlgebraicCurve.Place.compSubring - theorem
AlgebraicCurve.Place.mem_compSubring_iff - theorem
AlgebraicCurve.Place.mem_compSubring_of_hasValueAt - theorem
AlgebraicCurve.Place.compSubring_le - theorem
AlgebraicCurve.Place.mem_compSubring_of_mem_nonunits - theorem
AlgebraicCurve.Place.algebraMap_mem_compSubring_iff - def
AlgebraicCurve.Place.value - theorem
AlgebraicCurve.Place.hasValueAt_value - theorem
AlgebraicCurve.Place.value_eq_of_hasValueAt - theorem
AlgebraicCurve.Place.ord_sub_value_pos - theorem
AlgebraicCurve.Place.value_eq_of_ord_pos - theorem
AlgebraicCurve.Place.value_algebraMap - theorem
AlgebraicCurve.Place.value_surjective - theorem
AlgebraicCurve.Place.value_eq_zero_of_mem_nonunits - def
AlgebraicCurve.Place.centre - instance
AlgebraicCurve.Place.centre_isPrime - instance
AlgebraicCurve.Place.centre_isMaximal - theorem
AlgebraicCurve.Place.mem_centre_iff - theorem
AlgebraicCurve.Place.mem_centre_iff_of_hasValueAt - theorem
AlgebraicCurve.Place.mem_centre_iff_of_ord_pos - theorem
AlgebraicCurve.Place.mem_centre_of_mem_nonunits - theorem
AlgebraicCurve.Place.mem_centre_of_ord_pos - theorem
AlgebraicCurve.Place.algebraMap_mem_centre_iff - theorem
AlgebraicCurve.Place.mem_compSubring_or_inv_mem - def
AlgebraicCurve.Place.compValuationSubring - theorem
AlgebraicCurve.Place.compValuationSubring_toSubring - theorem
AlgebraicCurve.Place.mem_compValuationSubring_iff - theorem
AlgebraicCurve.Place.mem_compSubring_of_isIntegral - theorem
AlgebraicCurve.Place.mem_compSubring_of_isIntegral' - theorem
AlgebraicCurve.Place.exists_unique_valueHom - theorem
AlgebraicCurve.Place.residue_comp_value_surjective - theorem
AlgebraicCurve.Place.ker_residue_comp_value - theorem
AlgebraicCurve.Place.centre_comap_isMaximal - theorem
AlgebraicCurve.Place.sub_value_mem_centre_comap - theorem
AlgebraicCurve.Place.algebraMap_mem_centre_comap_iff - theorem
ValuationSubring.algebraMap_bijective_of_isIntegral_of_isAlgClosed - abbrev
ValuationSubring.constants - theorem
ValuationSubring.exists_sub_constants_mem - theorem
ValuationSubring.constants_unique_mod - theorem
Subring.exists_valuationSubring_dominating - theorem
Subring.ne_top_of_dominating - theorem
Subring.algebraMap_mem_of_dominating - def
ValuationSubring.centreOver - instance
ValuationSubring.centreOver_isPrime - theorem
ValuationSubring.mem_centreOver_iff - theorem
ValuationSubring.inv_algebraMap_mem - theorem
ValuationSubring.centreOver_ne_bot - def
ValuationSubring.centreHeightOneSpectrum - theorem
ValuationSubring.valuationSubringAtPrime_centre_le - theorem
ValuationSubring.eq_valuationSubringAtPrime_centre - theorem
ValuationSubring.isPrincipalIdealRing_of_dedekind_le - def
AlgebraicCurve.Place.ofValuationSubringOver - theorem
AlgebraicCurve.Place.ofValuationSubringOver_toValuationSubring - theorem
AlgebraicCurve.Place.mem_nonunits_ofValuationSubringOver_iff - theorem
Valuation.exists_ne_map_eq_of_sum_eq_zero - theorem
ValuationSubring.natCast_mem_ker - theorem
ValuationSubring.natCast_mem_maximalIdeal - theorem
ValuationSubring.isUnit_intCast_of_not_dvd - theorem
ValuationSubring.map_intCast_eq_zero_of_not_isUnit - theorem
ValuationSubring.map_eq_zero_of_rat_mem_maximalIdeal - theorem
ValuationSubring.exists_pow_valuation_eq_of_isRoot - theorem
ValuationSubring.ker_eq_maximalIdeal_of_isAlgebraic - theorem
ValuationSubring.exists_mul_eq_one_of_map_ne_zero - theorem
ValuationSubring.ker_eq_maximalIdeal_apply - theorem
AlgebraicCurve.isPrincipalIdealRing_adjoin_singleton - theorem
AlgebraicCurve.isDedekindDomain_adjoin_singleton - theorem
AlgebraicCurve.isDedekindDomain_integralClosure_adjoin - theorem
AlgebraicCurve.isFractionRing_integralClosure_adjoin - theorem
AlgebraicCurve.integralClosure_adjoin_le_valuationSubring - theorem
AlgebraicCurve.algebraMap_mem_integralClosure_adjoin - theorem
AlgebraicCurve.self_mem_integralClosure_adjoin - theorem
AlgebraicCurve.le_integralClosure_adjoin_of_isIntegral - theorem
ValuationSubring.isAlgClosed_of_surjective - def
RingHom.imagePrime - theorem
RingHom.rangeRestrict_mem_imagePrime_iff - theorem
RingHom.mk_mem_imagePrime_iff - theorem
RingHom.mem_imagePrime_iff - theorem
RingHom.imagePrime_ne_top - theorem
RingHom.imagePrime_isPrime - theorem
RingHom.imagePrime_isMaximal - theorem
RingHom.eq_zero_of_const_mem_imagePrime - theorem
RingHom.const_mem_range - theorem
AlgebraicCurve.Place.eq_zero_of_X_sub_C_dvd_C - theorem
AlgebraicCurve.Place.exists_place_centre_comap_eq - theorem
AlgebraicCurve.Place.finite_residueField_of_adjoin_simple_eq_top_of_mem - theorem
IntermediateField.adjoin_simple_inv_eq - theorem
AlgebraicCurve.Place.finite_residueField_of_adjoin_simple_eq_top - theorem
AlgebraicCurve.Place.finiteResidue_of_adjoin_simple_eq_top - theorem
ValuationSubring.eq_of_forall_mem_nonunits_iff - theorem
AlgebraicCurve.Place.eq_of_forall_mem_nonunits_iff - theorem
AlgebraicCurve.Place.eq_of_forall_mem_nonunits_iff_of_surjective - theorem
AlgebraicCurve.Place.integralClosure_adjoin_le_of_forall_isIntegral_mem - theorem
AlgebraicCurve.Place.exists_eq_of_integralClosure_adjoin - theorem
ModularCurve.CharPModel.FibreModel.bfin_le_compSubring - theorem
ModularCurve.CharPModel.FibreModel.constFin_mem' - def
ModularCurve.CharPModel.FibreModel.centreFin - theorem
ModularCurve.CharPModel.FibreModel.centreFin_isMaximal - theorem
ModularCurve.CharPModel.FibreModel.ker_piFin_le_centreFin - theorem
ModularCurve.CharPModel.red_eq_zero_of_mem_maximalIdeal - def
ModularCurve.CharPModel.lineClosure - theorem
ModularCurve.CharPModel.FibreModel.exists_spFin - theorem
ModularCurve.CharPModel.transcendental_jLineInv - theorem
ModularCurve.CharPModel.FibreModel.binf_le_compSubring - def
ModularCurve.CharPModel.FibreModel.centreInf - theorem
ModularCurve.CharPModel.FibreModel.centreInf_isMaximal - theorem
ModularCurve.CharPModel.FibreModel.ker_piInf_le_centreInf - def
ModularCurve.CharPModel.lineClosureInf - theorem
ModularCurve.CharPModel.FibreModel.exists_spInf - theorem
ModularCurve.CharPModel.FibreModel.chart_dichotomy - theorem
ModularCurve.CharPModel.fibreEvalSwap_subtype - theorem
ModularCurve.CharPModel.barEvalSwap_laurent - theorem
ModularCurve.CharPModel.barEvalSwap_subtype - theorem
ModularCurve.CharPModel.transcendental_jNC - theorem
ModularCurve.CharPModel.transcendental_jNBar - theorem
ModularCurve.CharPModel.jBar_ne_const - theorem
ModularCurve.CharPModel.jLine_ne_const - theorem
ModularCurve.CharPModel.jLine_ne_zero - theorem
ModularCurve.CharPModel.mem_of_ord_nonneg - def
ModularCurve.CharPModel.FibreModel.sp - theorem
ModularCurve.CharPModel.FibreModel.sp_spec_fin - theorem
ModularCurve.CharPModel.FibreModel.sp_spec_inf - theorem
ModularCurve.CharPModel.FibreModel.value_jInv_mem_maximalIdeal - theorem
ModularCurve.CharPModel.FibreModel.sp_ord_jLine_neg - theorem
ModularCurve.CharPModel.FibreModel.sp_d0_j - theorem
ModularCurve.CharPModel.FibreModel.sp_d0_j_pole - theorem
ModularCurve.CharPModel.jNBar_ne_const - theorem
ModularCurve.CharPModel.jNLine_ne_const - theorem
ModularCurve.CharPModel.jNLine_ne_zero - theorem
ModularCurve.CharPModel.aeval_mem_subring - theorem
ModularCurve.CharPModel.ord_nonneg_of_mem' - theorem
ModularCurve.CharPModel.FibreModel.sp_d0_jN - theorem
ModularCurve.CharPModel.FibreModel.sp_d0_jN_pole - theorem
ModularCurve.CharPModel.FibreModel.piFin_mem_valuationSubring - theorem
ModularCurve.CharPModel.FibreModel.exists_sp_eq_fin - theorem
ModularCurve.CharPModel.FibreModel.piInf_mem_valuationSubring - theorem
ModularCurve.CharPModel.FibreModel.exists_sp_eq_inf - theorem
ModularCurve.CharPModel.FibreModel.sp_d4 - theorem
ModularCurve.CharPModel.FibreModel.exists_specializationMap_assembled - theorem
ModularCurve.CharPModel.FibreModel.sp_hasValueAt_inf - theorem
ModularCurve.CharPModel.FibreModel.sp_piInf_nonunits_iff - theorem
ModularCurve.CharPModel.FibreModel.sp_jLineInv_mem - theorem
ModularCurve.CharPModel.FibreModel.fibre_place_ext_inf_impl - theorem
ModularCurve.CharPModel.not_jBar_mem_compSubring_of_forall_ord_le - theorem
ModularCurve.CharPModel.FibreModel.exists_specializationMap_dict_impl - theorem
ModularCurve.CharPModel.FibreModel.sp_piInf_nonunits_iff_of_hasValueAt - def
ModularCurve.CharPModel.FibreModel.spPlace - def
ModularCurve.CharPModel.FibreModel.spDiv - def
ModularCurve.CharPModel.FibreModel.SpDivPreservesPrincipal - def
ModularCurve.CharPModel.FibreModel.spPic0 - theorem
ModularCurve.CharPModel.FibreModel.piInf_mem_spPlace_nonunits_iff - theorem
ModularCurve.CharPModel.FibreModel.piFin_mem_spPlace_nonunits_iff - theorem
ModularCurve.CharPModel.FibreModel.jLineInv_mem_spPlace - def
ModularCurve.CharPModel.FibreModel.placeSpecializationOf
Source
import Definitions.Def_ModularCurve_JqCoeff import Definitions.Def_ModularCurve_LaurentCoeff import Definitions.Def_ModularCurve_PhiGen import Definitions.Def_AlgebraicCurve_DivisorClassGroup import Mathlib.FieldTheory.IsAlgClosed.AlgebraicClosure ↗ import Mathlib.RingTheory.IntegralClosure.GoingDown ↗ import Mathlib.RingTheory.Polynomial.IsIntegral ↗ import Mathlib.RingTheory.Valuation.LocalSubring ↗ import Mathlib.RingTheory.Algebraic.Basic ↗ import Definitions.Def_AlgebraicCurve_PlacesOverDVR import Mathlib.FieldTheory.IsAlgClosed.Basic ↗ import Mathlib.Algebra.Polynomial.Lifts ↗ import Mathlib.RingTheory.Ideal.Quotient.Operations ↗ import Mathlib.RingTheory.Localization.AtPrime.Basic ↗ import Mathlib.RingTheory.Valuation.ValuationSubring ↗ import Mathlib.RingTheory.PrincipalIdealDomain ↗ import Mathlib.Algebra.CharP.Basic ↗ import Mathlib.Data.Int.CharZero ↗ import Mathlib.Data.Nat.Prime.Int ↗ import Mathlib.RingTheory.DedekindDomain.IntegralClosure ↗ import Mathlib.FieldTheory.IntermediateField.Adjoin.Algebra ↗ import Mathlib.RingTheory.Ideal.Maps ↗ import Mathlib.RingTheory.Ideal.Maximal ↗ import Mathlib.FieldTheory.IntermediateField.Adjoin.Basic ↗ import Definitions.Def_ModularCurve_FibreModel import Definitions.Def_ModularCurve_ArithmeticGalois import Definitions.Def_ModularCurve_PlaceSpecialization set_option autoImplicit false noncomputable section namespace ModularCurve namespace CharPModel open AlgebraicCurve variable (N : ℕ) [NeZero N] variable (A : ValuationSubring (AlgebraicClosure ℚ)) end CharPModel end ModularCurve set_option autoImplicit false noncomputable section namespace ModularCurve namespace CharPModel section LaurentMap variable {R S : Type*} [CommRing R] [CommRing S] private def laurentMapRingHom (f : R →+* S) : LaurentSeries R →+* LaurentSeries S where toFun x := x.map f map_one' := by ext g rw [HahnSeries.map_coeff, HahnSeries.coeff_one, HahnSeries.coeff_one, apply_ite f, map_one, map_zero] map_mul' x y := HahnSeries.map_mul f.toNonUnitalRingHom map_zero' := by ext g rw [HahnSeries.map_coeff, HahnSeries.coeff_zero, HahnSeries.coeff_zero, map_zero] map_add' x y := HahnSeries.map_add f.toAddMonoidHom @[simp] private theorem laurentMapRingHom_apply (f : R →+* S) (x : LaurentSeries R) : laurentMapRingHom f x = x.map f := rfl private theorem laurentMap_injective {f : R →+* S} (hf : Function.Injective f) {x y : LaurentSeries R} (h : x.map f = y.map f) : x = y := by ext g have hg := congrArg (fun z : LaurentSeries S => z.coeff g) h simpa only [HahnSeries.map_coeff] using hf hg private theorem map_eval₂Bivar (Φ : Polynomial (Polynomial ℤ)) (f : R →+* S) (u v : LaurentSeries R) : (Φ.eval₂ (Polynomial.aeval (R := ℤ) u).toRingHom v).map f = Φ.eval₂ (Polynomial.aeval (R := ℤ) (u.map f)).toRingHom (v.map f) := by have hcomp : (laurentMapRingHom f).comp (Polynomial.aeval (R := ℤ) u).toRingHom = (Polynomial.aeval (R := ℤ) (u.map f)).toRingHom := by apply Polynomial.ringHom_ext · intro a simp only [eq_intCast, map_intCast] · simp only [RingHom.coe_comp, Function.comp_apply, AlgHom.toRingHom_eq_coe, AlgHom.coe_toRingHom, Polynomial.aeval_X, laurentMapRingHom_apply] have h := Polynomial.hom_eval₂ Φ (Polynomial.aeval (R := ℤ) u).toRingHom (laurentMapRingHom f) v rw [← laurentMapRingHom_apply, h, hcomp, laurentMapRingHom_apply] end LaurentMap section FibreEval variable {R S : Type*} [CommRing R] [CommRing S] private theorem qExpand_map (N : ℕ) [NeZero N] (f : R →+* S) (x : LaurentSeries R) : (qExpand R N x).map f = qExpand S N (x.map f) := by ext k rw [HahnSeries.map_coeff] by_cases hk : (N : ℤ) ∣ k · obtain ⟨m, rfl⟩ := hk rw [qExpand_coeff_mul, qExpand_coeff_mul, HahnSeries.map_coeff] · have h1 := qExpand_coeff_of_not_dvd (R := R) (N := N) x hk have h2 := qExpand_coeff_of_not_dvd (R := S) (N := N) (x.map f) hk rw [h1, h2, map_zero] private theorem map_jqNModC (N : ℕ) [NeZero N] {K K' : Type*} [CommRing K] [CommRing K'] (f : K →+* K') : (jqNModC K N).map f = jqNModC K' N := by show (qExpand K N (jqModC K)).map f = qExpand K' N (jqModC K') rw [qExpand_map, map_jqModC] variable (N : ℕ) [NeZero N] (data : ModularPolynomialData N) private theorem intEval_eq_zero : data.Φ.eval₂ (Polynomial.aeval (R := ℤ) (jqModC ℤ)).toRingHom (jqNModC ℤ N) = 0 := by refine laurentMap_injective (f := Int.castRingHom ℚ) (Int.castRingHom ℚ).injective_int ?_ rw [map_eval₂Bivar, map_jqModC, map_jqNModC, show (0 : LaurentSeries ℤ).map (Int.castRingHom ℚ) = 0 from map_zero (laurentMapRingHom (Int.castRingHom ℚ))] exact data.eval_eq_zero private theorem fibreEval_eq_zero (k : Type*) [CommRing k] : data.Φ.eval₂ (Polynomial.aeval (R := ℤ) (jqModC k)).toRingHom (jqNModC k N) = 0 := by have h := congrArg (fun x : LaurentSeries ℤ => x.map (Int.castRingHom k)) (intEval_eq_zero N data) simpa only [map_eval₂Bivar, map_jqModC, map_jqNModC, show (0 : LaurentSeries ℤ).map (Int.castRingHom k) = 0 from map_zero (laurentMapRingHom (Int.castRingHom k))] using h private theorem intEvalSwap_eq_zero (hsym : EvalSymm data.Φ) : data.Φ.eval₂ (Polynomial.aeval (R := ℤ) (jqNModC ℤ N)).toRingHom (jqModC ℤ) = 0 := by refine laurentMap_injective (f := Int.castRingHom ℚ) (Int.castRingHom ℚ).injective_int ?_ rw [map_eval₂Bivar, map_jqModC, map_jqNModC, show (0 : LaurentSeries ℤ).map (Int.castRingHom ℚ) = 0 from map_zero (laurentMapRingHom (Int.castRingHom ℚ))] rw [show jqModC ℚ = jq from rfl, show jqNModC ℚ N = jqN N from rfl] rw [hsym (jqN N) jq] exact data.eval_eq_zero private theorem fibreEvalSwap_eq_zero (hsym : EvalSymm data.Φ) (k : Type*) [CommRing k] : data.Φ.eval₂ (Polynomial.aeval (R := ℤ) (jqNModC k N)).toRingHom (jqModC k) = 0 := by have h := congrArg (fun x : LaurentSeries ℤ => x.map (Int.castRingHom k)) (intEvalSwap_eq_zero N data hsym) simpa only [map_eval₂Bivar, map_jqModC, map_jqNModC, show (0 : LaurentSeries ℤ).map (Int.castRingHom k) = 0 from map_zero (laurentMapRingHom (Int.castRingHom k))] using h end FibreEval end CharPModel end ModularCurve noncomputable section namespace ModularCurve namespace CharPModel section LineTier private theorem transcendental_subtype {K L : Type*} [Field K] [Field L] [Algebra K L] (S : IntermediateField K L) {x : L} (hx : x ∈ S) (h : Transcendental K x) : Transcendental K (⟨x, hx⟩ : S) := by intro halg apply h obtain ⟨p, hp0, hp⟩ := halg refine ⟨p, hp0, ?_⟩ have h2 := congrArg S.val hp rw [map_zero, ← Polynomial.aeval_algHom_apply] at h2 simpa using h2 private theorem tjq_pow (K : Type*) [CommRing K] (n : ℕ) : (jqModC K) ^ n = HahnSeries.single (-(n : ℤ)) 1 * HahnSeries.ofPowerSeries ℤ K ((jNum.map (Int.castRingHom K)) ^ n) := by have h : n • (-1 : ℤ) = -(n : ℤ) := by simp rw [jqModC, mul_pow, HahnSeries.single_pow, one_pow, h, ← map_pow] private theorem tjq_constantCoeff_map (K : Type*) [CommRing K] : PowerSeries.constantCoeff (jNum.map (Int.castRingHom K)) = 1 := by rw [← PowerSeries.coeff_zero_eq_constantCoeff, PowerSeries.coeff_map, PowerSeries.coeff_zero_eq_constantCoeff, constantCoeff_jNum, map_one] private theorem tjq_coeff_pow_self (K : Type*) [CommRing K] (n : ℕ) : ((jqModC K) ^ n).coeff (-(n : ℤ)) = 1 := by rw [tjq_pow, HahnSeries.coeff_single_mul, one_mul, sub_neg_eq_add, neg_add_cancel, show (0 : ℤ) = ((0 : ℕ) : ℤ) from rfl, HahnSeries.ofPowerSeries_apply_coeff, PowerSeries.coeff_zero_eq_constantCoeff, map_pow, tjq_constantCoeff_map, one_pow] private theorem tjq_coeff_pow_of_lt (K : Type*) [CommRing K] {n : ℕ} {m : ℤ} (hm : m < -(n : ℤ)) : ((jqModC K) ^ n).coeff m = 0 := by rw [tjq_pow, HahnSeries.coeff_single_mul, one_mul] exact ofPowerSeries_coeff_of_neg _ (by omega) private theorem tjq_algebraMap_eq_single (K : Type*) [CommRing K] (c : K) : algebraMap K (LaurentSeries K) c = HahnSeries.single 0 c := by have h1 : algebraMap K (PowerSeries K) c = PowerSeries.C c := by simp rw [HahnSeries.algebraMap_apply', h1, HahnSeries.ofPowerSeries_C] rfl private theorem tjq_aeval_eq_zero (K : Type*) [CommRing K] {p : Polynomial K} (hp : Polynomial.aeval (jqModC K) p = 0) : p = 0 := by by_contra hp0 set n := p.natDegree with hn have hcoeff : (Polynomial.aeval (jqModC K) p).coeff (-(n : ℤ)) = p.coeff n := by rw [Polynomial.aeval_def, Polynomial.eval₂_eq_sum_range, HahnSeries.coeff_sum, Finset.sum_eq_single n] · rw [tjq_algebraMap_eq_single, HahnSeries.coeff_single_zero_mul, tjq_coeff_pow_self, mul_one] · intro i hi hin have hilt : i < n := lt_of_le_of_ne (Nat.lt_succ_iff.mp (Finset.mem_range.mp hi)) hin rw [tjq_algebraMap_eq_single, HahnSeries.coeff_single_zero_mul, tjq_coeff_pow_of_lt, mul_zero] omega · intro hn' exact absurd (Finset.self_mem_range_succ n) hn' rw [hp] at hcoeff simp only [HahnSeries.coeff_zero] at hcoeff exact hp0 (Polynomial.leadingCoeff_eq_zero.mp hcoeff.symm) private theorem tjq_transcendental (K : Type*) [CommRing K] : Transcendental K (jqModC K) := transcendental_iff.mpr fun _ hp => tjq_aeval_eq_zero K hp private theorem coeffEmb_jq_eq_jqModC : coeffEmb (AlgebraicClosure ℚ) jq = jqModC (AlgebraicClosure ℚ) := by have hmap : jNumQ.map (algebraMap ℚ (AlgebraicClosure ℚ)) = jNum.map (Int.castRingHom (AlgebraicClosure ℚ)) := by ext n simp [jNumQ, PowerSeries.coeff_map] rw [jq, jqModC, map_mul] congr 1 · ext k rw [coeffEmb_coeff] by_cases hk : k = (-1 : ℤ) <;> simp [hk] · ext k rw [coeffEmb_coeff] by_cases hk : 0 ≤ k · lift k to ℕ using hk rw [HahnSeries.ofPowerSeries_apply_coeff, HahnSeries.ofPowerSeries_apply_coeff, ← hmap, PowerSeries.coeff_map] · rw [ofPowerSeries_coeff_of_neg _ (by omega), ofPowerSeries_coeff_of_neg _ (by omega), map_zero] section ResidueFieldInline variable {K₀ F₀ F₀' : Type*} [Field K₀] [Field F₀] [Field F₀'] [Algebra K₀ F₀] [Algebra K₀ F₀'] [Algebra F₀ F₀'] [IsScalarTower K₀ F₀ F₀'] [FiniteDimensional F₀ F₀'] open IsLocalRing in private theorem rf_linearIndependent_lift (w : AlgebraicCurve.Place K₀ F₀') {ι : Type*} [Fintype ι] (x : ι → w.toValuationSubring) (hx : LinearIndependent (w.restrict F₀).ResidueField fun i => (residue w.toValuationSubring (x i) : w.ResidueField)) : LinearIndependent F₀ fun i => ((x i : w.toValuationSubring) : F₀') := by classical rw [Fintype.linearIndependent_iff] intro g hg by_contra hne obtain ⟨i₀, hi₀⟩ : ∃ i, g i ≠ 0 := not_forall.mp hne set O : ValuationSubring F₀ := (w.restrict F₀).toValuationSubring have hne' : (Finset.univ.filter fun i => g i ≠ 0).Nonempty := ⟨i₀, by simpa using hi₀⟩ obtain ⟨m, hm, hmmax⟩ := Finset.exists_max_image _ (fun i => O.valuation (g i)) hne' have hgm : g m ≠ 0 := by simpa using hm have hb : ∀ i, g i / g m ∈ O := by intro i by_cases hi : g i = 0 · simp [hi] · apply O.mem_of_valuation_le_one rw [map_div₀] have hm0 : (0 : O.ValueGroup) < O.valuation (g m) := by rw [zero_lt_iff]; exact (map_ne_zero _).mpr hgm exact (div_le_one₀ hm0).mpr (hmmax i (by simpa using hi)) let b : ι → O := fun i => ⟨g i / g m, hb i⟩ have hrel : ∑ i, AlgebraicCurve.Place.restrictInclusion F₀ w (b i) * x i = 0 := by apply Subtype.ext have hcoe : ((∑ i, AlgebraicCurve.Place.restrictInclusion F₀ w (b i) * x i : w.toValuationSubring) : F₀') = ∑ i, algebraMap F₀ F₀' (g i / g m) * (x i : F₀') := by rw [AddSubmonoidClass.coe_finsetSum] refine Finset.sum_congr rfl fun i _ => ?_ rw [MulMemClass.coe_mul, AlgebraicCurve.Place.coe_restrictInclusion] rw [hcoe] have : ∑ i, algebraMap F₀ F₀' (g i / g m) * (x i : F₀') = algebraMap F₀ F₀' (g m)⁻¹ * ∑ i, g i • ((x i : w.toValuationSubring) : F₀') := by rw [Finset.mul_sum] refine Finset.sum_congr rfl fun i _ => ?_ rw [Algebra.smul_def, div_eq_inv_mul, map_mul, mul_assoc] rw [this, hg, mul_zero] rfl have hres : ∑ i, (residue O (b i) : (w.restrict F₀).ResidueField) • (residue w.toValuationSubring (x i) : w.ResidueField) = 0 := by have h := congrArg (residue w.toValuationSubring) hrel rw [map_sum, map_zero] at h rw [← h] refine Finset.sum_congr rfl fun i _ => ?_ rw [Algebra.smul_def, AlgebraicCurve.Place.algebraMap_residueField_eq, AlgebraicCurve.Place.restrictResidueMap_residue, map_mul] have hm1 := (Fintype.linearIndependent_iff.mp hx) _ hres m have hbm : b m = 1 := Subtype.ext (div_self hgm) rw [hbm, map_one] at hm1 exact one_ne_zero hm1 open IsLocalRing in private theorem rf_finite_residueField (w : AlgebraicCurve.Place K₀ F₀') : Module.Finite (w.restrict F₀).ResidueField w.ResidueField := by classical rw [← Module.rank_lt_aleph0_iff] refine lt_of_le_of_lt (rank_le (n := Module.finrank F₀ F₀') fun s hs => ?_) Cardinal.natCast_lt_aleph0 choose x hx using fun y : s => residue_surjective (R := w.toValuationSubring) (y : w.ResidueField) have hs' : LinearIndependent (w.restrict F₀).ResidueField fun i : s => (residue w.toValuationSubring (x i) : w.ResidueField) := by simpa only [hx] using hs have := rf_linearIndependent_lift (F₀ := F₀) w x hs' simpa [Fintype.card_coe] using this.fintype_card_le_finrank end ResidueFieldInline private theorem transcendental_jBar (N : ℕ) [NeZero N] : Transcendental (AlgebraicClosure ℚ) (jBar N) := by have h := tjq_transcendental (AlgebraicClosure ℚ) rw [← coeffEmb_jq_eq_jqModC] at h exact transcendental_subtype _ (coeffEmb_mem_laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionField_le_full N (jq_mem N))) h private theorem transcendental_jC (k : Type*) [Field k] (N : ℕ) [NeZero N] : Transcendental k (⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N) := transcendental_subtype _ (jqModC_mem k N) (tjq_transcendental k) private theorem fibreEval_subtype (k : Type*) [Field k] (N : ℕ) [NeZero N] (data : ModularPolynomialData N) : data.Φ.eval₂ (Polynomial.aeval (R := ℤ) (⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N)).toRingHom (⟨jqNModC k N, jqNModC_mem k N⟩ : modularFunctionFieldC k N) = 0 := by have hcomp : ((modularFunctionFieldC k N).val.toRingHom).comp (Polynomial.aeval (R := ℤ) (⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N)).toRingHom = (Polynomial.aeval (R := ℤ) (jqModC k)).toRingHom := by apply Polynomial.ringHom_ext · intro a simp only [eq_intCast, map_intCast] · simp only [RingHom.coe_comp, Function.comp_apply, AlgHom.toRingHom_eq_coe, AlgHom.coe_toRingHom, Polynomial.aeval_X] rfl have h := Polynomial.hom_eval₂ data.Φ (Polynomial.aeval (R := ℤ) (⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N)).toRingHom ((modularFunctionFieldC k N).val.toRingHom) (⟨jqNModC k N, jqNModC_mem k N⟩ : modularFunctionFieldC k N) apply Subtype.val_injective have h0 : (modularFunctionFieldC k N).val.toRingHom (data.Φ.eval₂ (Polynomial.aeval (R := ℤ) (⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N)).toRingHom (⟨jqNModC k N, jqNModC_mem k N⟩ : modularFunctionFieldC k N)) = 0 := by rw [h, hcomp] exact fibreEval_eq_zero N data k simpa using h0 private theorem adjoin_pair_subtype_eq_top {K L : Type*} [Field K] [Field L] [Algebra K L] (x y : L) : IntermediateField.adjoin K ({⟨x, IntermediateField.subset_adjoin K {x, y} (Set.mem_insert x {y})⟩, ⟨y, IntermediateField.subset_adjoin K {x, y} (Set.mem_insert_of_mem x rfl)⟩} : Set (IntermediateField.adjoin K ({x, y} : Set L))) = ⊤ := by rw [eq_top_iff] rintro ⟨z, hz⟩ - induction hz using IntermediateField.adjoin_induction with | mem z hzm => rcases hzm with rfl | hzm · exact IntermediateField.subset_adjoin _ _ (Set.mem_insert _ _) · rcases hzm with rfl exact IntermediateField.subset_adjoin _ _ (Set.mem_insert_of_mem _ rfl) | algebraMap a => exact IntermediateField.algebraMap_mem _ a | add a b ha hb hia hib => exact add_mem hia hib | mul a b ha hb hia hib => exact mul_mem hia hib | inv a ha hia => exact inv_mem hia private theorem isIntegral_adjoin_of_bivar_monic {K L : Type*} [Field K] [Field L] [Algebra K L] {Φ : Polynomial (Polynomial ℤ)} (hΦ : Φ.Monic) {x y : L} (h : Φ.eval₂ (Polynomial.aeval (R := ℤ) x).toRingHom y = 0) : IsIntegral (IntermediateField.adjoin K ({x} : Set L)) y := by set g : Polynomial ℤ →+* IntermediateField.adjoin K ({x} : Set L) := (Polynomial.aeval (R := ℤ) (⟨x, IntermediateField.mem_adjoin_simple_self K x⟩ : IntermediateField.adjoin K ({x} : Set L))).toRingHom with hg have hcomp : (algebraMap (IntermediateField.adjoin K ({x} : Set L)) L).comp g = (Polynomial.aeval (R := ℤ) x).toRingHom := by apply Polynomial.ringHom_ext · intro a simp only [eq_intCast, map_intCast] · simp only [hg, RingHom.coe_comp, Function.comp_apply, AlgHom.toRingHom_eq_coe, AlgHom.coe_toRingHom, Polynomial.aeval_X] rfl refine ⟨Φ.map g, hΦ.map g, ?_⟩ rw [Polynomial.eval₂_map, hcomp] exact h private theorem barEval_laurent (N : ℕ) [NeZero N] (data : ModularPolynomialData N) : data.Φ.eval₂ (Polynomial.aeval (R := ℤ) (coeffEmb (AlgebraicClosure ℚ) jq)).toRingHom (coeffEmb (AlgebraicClosure ℚ) (qExpand ℚ N jq)) = 0 := by have hcomp : ((coeffEmb (AlgebraicClosure ℚ)).comp (Polynomial.aeval (R := ℤ) jq).toRingHom) = (Polynomial.aeval (R := ℤ) (coeffEmb (AlgebraicClosure ℚ) jq)).toRingHom := by apply Polynomial.ringHom_ext · intro a simp only [eq_intCast, map_intCast] · simp only [RingHom.coe_comp, Function.comp_apply, AlgHom.toRingHom_eq_coe, AlgHom.coe_toRingHom, Polynomial.aeval_X] have h := Polynomial.hom_eval₂ data.Φ (Polynomial.aeval (R := ℤ) jq).toRingHom (coeffEmb (AlgebraicClosure ℚ)) (qExpand ℚ N jq) have h0 := data.eval_eq_zero rw [show evalAtJ = (Polynomial.aeval (R := ℤ) jq).toRingHom from rfl, show jqN N = qExpand ℚ N jq from rfl] at h0 rw [h0, map_zero, hcomp] at h exact h.symm private theorem barEval_subtype (N : ℕ) [NeZero N] (data : ModularPolynomialData N) : data.Φ.eval₂ (Polynomial.aeval (R := ℤ) (jBar N)).toRingHom (jNBar N) = 0 := by have hcomp : (((laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)).val.toRingHom).comp (Polynomial.aeval (R := ℤ) (jBar N)).toRingHom) = (Polynomial.aeval (R := ℤ) (coeffEmb (AlgebraicClosure ℚ) jq)).toRingHom := by apply Polynomial.ringHom_ext · intro a simp only [eq_intCast, map_intCast] · simp only [RingHom.coe_comp, Function.comp_apply, AlgHom.toRingHom_eq_coe, AlgHom.coe_toRingHom, Polynomial.aeval_X] rfl have h := Polynomial.hom_eval₂ data.Φ (Polynomial.aeval (R := ℤ) (jBar N)).toRingHom ((laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)).val.toRingHom) (jNBar N) apply Subtype.val_injective have h0 : (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)).val.toRingHom (data.Φ.eval₂ (Polynomial.aeval (R := ℤ) (jBar N)).toRingHom (jNBar N)) = 0 := by rw [h, hcomp] exact barEval_laurent N data simpa using h0 set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 200000 in private theorem finiteDimensional_adjoin_jC (k : Type*) [Field k] (N : ℕ) [NeZero N] (data : ModularPolynomialData N) : FiniteDimensional (IntermediateField.adjoin k ({⟨jqModC k, jqModC_mem k N⟩} : Set (modularFunctionFieldC k N))) (modularFunctionFieldC k N) := by have hint : IsIntegral (IntermediateField.adjoin k ({⟨jqModC k, jqModC_mem k N⟩} : Set (modularFunctionFieldC k N))) (⟨jqNModC k N, jqNModC_mem k N⟩ : modularFunctionFieldC k N) := isIntegral_adjoin_of_bivar_monic data.monic (fibreEval_subtype k N data) have htop := adjoin_pair_subtype_eq_top (K := k) (jqModC k) (jqNModC k N) have htower := IntermediateField.adjoin_adjoin_left k ({⟨jqModC k, jqModC_mem k N⟩} : Set (modularFunctionFieldC k N)) {⟨jqNModC k N, jqNModC_mem k N⟩} rw [Set.singleton_union] at htower have hpair : IntermediateField.adjoin k ({⟨jqModC k, jqModC_mem k N⟩, ⟨jqNModC k N, jqNModC_mem k N⟩} : Set (modularFunctionFieldC k N)) = ⊤ := htop rw [hpair] at htower have hFD : FiniteDimensional (IntermediateField.adjoin k ({⟨jqModC k, jqModC_mem k N⟩} : Set (modularFunctionFieldC k N))) (IntermediateField.adjoin (IntermediateField.adjoin k ({⟨jqModC k, jqModC_mem k N⟩} : Set (modularFunctionFieldC k N))) ({⟨jqNModC k N, jqNModC_mem k N⟩} : Set (modularFunctionFieldC k N))) := IntermediateField.adjoin.finiteDimensional hint have h2 : IntermediateField.adjoin (IntermediateField.adjoin k ({⟨jqModC k, jqModC_mem k N⟩} : Set (modularFunctionFieldC k N))) ({⟨jqNModC k N, jqNModC_mem k N⟩} : Set (modularFunctionFieldC k N)) = ⊤ := IntermediateField.restrictScalars_injective k (htower.trans IntermediateField.restrictScalars_top.symm) rw [h2] at hFD exact (IntermediateField.topEquiv (F := IntermediateField.adjoin k ({⟨jqModC k, jqModC_mem k N⟩} : Set (modularFunctionFieldC k N)))).toLinearEquiv.finiteDimensional private theorem algebraMap_comp_aeval_adjoin_self {K L : Type*} [Field K] [Field L] [Algebra K L] (x : L) : (algebraMap (IntermediateField.adjoin K ({x} : Set L)) L).comp (Polynomial.aeval (R := ℤ) (IntermediateField.AdjoinSimple.gen K x)).toRingHom = (Polynomial.aeval (R := ℤ) x).toRingHom := by apply Polynomial.ringHom_ext · intro a simp only [eq_intCast, map_intCast] · simp only [RingHom.coe_comp, Function.comp_apply, AlgHom.toRingHom_eq_coe, AlgHom.coe_toRingHom, Polynomial.aeval_X] rfl set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private def jLine (k : Type*) [Field k] (N : ℕ) [NeZero N] : modularFunctionFieldC k N := ⟨jqModC k, jqModC_mem k N⟩ set_option synthInstance.maxHeartbeats 400000 in private def jNLine (k : Type*) [Field k] (N : ℕ) [NeZero N] : modularFunctionFieldC k N := ⟨jqNModC k N, jqNModC_mem k N⟩ private theorem transcendental_jLine (k : Type*) [Field k] (N : ℕ) [NeZero N] : Transcendental k (jLine k N) := transcendental_jC k N set_option synthInstance.maxHeartbeats 400000 in private noncomputable def lineEquivC (k : Type*) [Field k] (N : ℕ) [NeZero N] : RatFunc k ≃ₐ[k] (IntermediateField.adjoin k ({jLine k N} : Set (modularFunctionFieldC k N))) := RatFunc.algEquivOfTranscendental _ (transcendental_jLine k N) set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem lineEquivC_algebraMap (k : Type*) [Field k] (N : ℕ) [NeZero N] (g : Polynomial k) : lineEquivC k N (algebraMap (Polynomial k) (RatFunc k) g) = Polynomial.aeval (IntermediateField.AdjoinSimple.gen k (jLine k N)) g := RatFunc.algEquivOfTranscendental_algebraMap _ (transcendental_jLine k N) g set_option maxSynthPendingDepth 3 in set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem lineX (k : Type*) [Field k] (N : ℕ) [NeZero N] : lineEquivC k N (algebraMap (Polynomial k) (RatFunc k) Polynomial.X) = IntermediateField.AdjoinSimple.gen k (jLine k N) := by rw [lineEquivC_algebraMap, Polynomial.aeval_X] set_option maxSynthPendingDepth 3 in set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem lineConst (k : Type*) [Field k] (N : ℕ) [NeZero N] (a : ℤ) : Polynomial.aeval (R := ℤ) (IntermediateField.AdjoinSimple.gen k (jLine k N)) (Polynomial.C a) = lineEquivC k N (algebraMap (Polynomial k) (RatFunc k) ((Polynomial.C a).map (Int.castRingHom k))) := by rw [Polynomial.aeval_C, Polynomial.map_C, show Polynomial.C ((Int.castRingHom k) a) = algebraMap k (Polynomial k) ((Int.castRingHom k) a) from rfl, ← IsScalarTower.algebraMap_apply k (Polynomial k) (RatFunc k), AlgEquiv.commutes] simp only [eq_intCast, map_intCast] set_option maxSynthPendingDepth 3 in set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem lineFun (k : Type*) [Field k] (N : ℕ) [NeZero N] (p : Polynomial ℤ) : Polynomial.aeval (R := ℤ) (IntermediateField.AdjoinSimple.gen k (jLine k N)) p = lineEquivC k N (algebraMap (Polynomial k) (RatFunc k) (p.map (Int.castRingHom k))) := by induction p using Polynomial.induction_on with | C a => exact lineConst k N a | add p q hp hq => rw [Polynomial.map_add, map_add, map_add, map_add, hp, hq] | monomial n a _ => simp only [Polynomial.map_mul, Polynomial.map_pow, Polynomial.map_X, map_mul, map_pow, lineX, Polynomial.aeval_X] rw [lineConst k N a] set_option maxSynthPendingDepth 3 in set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem lineMapEq (k : Type*) [Field k] (N : ℕ) [NeZero N] (data : ModularPolynomialData N) : data.Φ.map ((Polynomial.aeval (R := ℤ) (IntermediateField.AdjoinSimple.gen k (jLine k N))).toRingHom) = ((data.Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).map (lineEquivC k N).toAlgHom.toRingHom := by apply Polynomial.ext intro n rw [Polynomial.coeff_map, Polynomial.coeff_map, Polynomial.coeff_map, Polynomial.coeff_map] exact lineFun k N (data.Φ.coeff n) set_option maxSynthPendingDepth 3 in set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem linePsep (k : Type*) [Field k] (N : ℕ) [NeZero N] (data : ModularPolynomialData N) (hsep : ((data.Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) : (data.Φ.map ((Polynomial.aeval (R := ℤ) (IntermediateField.AdjoinSimple.gen k (jLine k N))).toRingHom)).Separable := by rw [lineMapEq k N data] exact hsep.map set_option maxSynthPendingDepth 3 in set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in private theorem lineAevalZero (k : Type*) [Field k] (N : ℕ) [NeZero N] (data : ModularPolynomialData N) : Polynomial.aeval (R := IntermediateField.adjoin k ({jLine k N} : Set (modularFunctionFieldC k N))) (jNLine k N) (data.Φ.map ((Polynomial.aeval (R := ℤ) (IntermediateField.AdjoinSimple.gen k (jLine k N))).toRingHom)) = 0 := by rw [Polynomial.aeval_def, Polynomial.eval₂_map, algebraMap_comp_aeval_adjoin_self (jLine k N)] exact fibreEval_subtype k N data set_option maxSynthPendingDepth 3 in set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem lineDvd (k : Type*) [Field k] (N : ℕ) [NeZero N] (data : ModularPolynomialData N) : minpoly (IntermediateField.adjoin k ({jLine k N} : Set (modularFunctionFieldC k N))) (jNLine k N) ∣ data.Φ.map ((Polynomial.aeval (R := ℤ) (IntermediateField.AdjoinSimple.gen k (jLine k N))).toRingHom) := minpoly.dvd (IntermediateField.adjoin k ({jLine k N} : Set (modularFunctionFieldC k N))) (jNLine k N) (lineAevalZero k N data) set_option maxSynthPendingDepth 3 in set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem isSeparable_jNC (k : Type*) [Field k] (N : ℕ) [NeZero N] (data : ModularPolynomialData N) (hsep : ((data.Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) : IsSeparable (IntermediateField.adjoin k ({⟨jqModC k, jqModC_mem k N⟩} : Set (modularFunctionFieldC k N))) (⟨jqNModC k N, jqNModC_mem k N⟩ : modularFunctionFieldC k N) := (linePsep k N data hsep).of_dvd (lineDvd k N data) set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem isSeparable_line_fibre (k : Type*) [Field k] (N : ℕ) [NeZero N] (data : ModularPolynomialData N) (hsep : ((data.Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) : Algebra.IsSeparable (IntermediateField.adjoin k ({⟨jqModC k, jqModC_mem k N⟩} : Set (modularFunctionFieldC k N))) (modularFunctionFieldC k N) := by have hadj : Algebra.IsSeparable (IntermediateField.adjoin k ({⟨jqModC k, jqModC_mem k N⟩} : Set (modularFunctionFieldC k N))) (IntermediateField.adjoin (IntermediateField.adjoin k ({⟨jqModC k, jqModC_mem k N⟩} : Set (modularFunctionFieldC k N))) ({⟨jqNModC k N, jqNModC_mem k N⟩} : Set (modularFunctionFieldC k N))) := (IntermediateField.isSeparable_adjoin_simple_iff_isSeparable _ _).mpr (isSeparable_jNC k N data hsep) have htower := IntermediateField.adjoin_adjoin_left k ({⟨jqModC k, jqModC_mem k N⟩} : Set (modularFunctionFieldC k N)) {⟨jqNModC k N, jqNModC_mem k N⟩} rw [Set.singleton_union] at htower have hpair : IntermediateField.adjoin k ({⟨jqModC k, jqModC_mem k N⟩, ⟨jqNModC k N, jqNModC_mem k N⟩} : Set (modularFunctionFieldC k N)) = ⊤ := adjoin_pair_subtype_eq_top (K := k) (jqModC k) (jqNModC k N) rw [hpair] at htower have h2 : IntermediateField.adjoin (IntermediateField.adjoin k ({⟨jqModC k, jqModC_mem k N⟩} : Set (modularFunctionFieldC k N))) ({⟨jqNModC k N, jqNModC_mem k N⟩} : Set (modularFunctionFieldC k N)) = ⊤ := IntermediateField.restrictScalars_injective k (htower.trans IntermediateField.restrictScalars_top.symm) rw [h2] at hadj haveI := hadj exact AlgEquiv.Algebra.isSeparable IntermediateField.topEquiv end LineTier section BarFinDim private def jdBar (N : ℕ) [NeZero N] (d : ℕ) [NeZero d] (hd : d ∣ N) : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N) := ⟨coeffEmb (AlgebraicClosure ℚ) (qExpand ℚ d jq), coeffEmb_mem_laurentBaseChange (AlgebraicClosure ℚ) (jqd_mem_full N hd)⟩ set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem barEvalD_subtype (N : ℕ) [NeZero N] (d : ℕ) [NeZero d] (hd : d ∣ N) (data : ModularPolynomialData d) : data.Φ.eval₂ (Polynomial.aeval (R := ℤ) (jBar N)).toRingHom (jdBar N d hd) = 0 := by have hcomp : (((laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)).val.toRingHom).comp (Polynomial.aeval (R := ℤ) (jBar N)).toRingHom) = (Polynomial.aeval (R := ℤ) (coeffEmb (AlgebraicClosure ℚ) jq)).toRingHom := by apply Polynomial.ringHom_ext · intro a simp only [eq_intCast, map_intCast] · simp only [RingHom.coe_comp, Function.comp_apply, AlgHom.toRingHom_eq_coe, AlgHom.coe_toRingHom, Polynomial.aeval_X] rfl have h := Polynomial.hom_eval₂ data.Φ (Polynomial.aeval (R := ℤ) (jBar N)).toRingHom ((laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)).val.toRingHom) (jdBar N d hd) apply Subtype.val_injective have h0 : (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)).val.toRingHom (data.Φ.eval₂ (Polynomial.aeval (R := ℤ) (jBar N)).toRingHom (jdBar N d hd)) = 0 := by rw [h, hcomp] exact barEval_laurent d data simpa using h0 set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem lbc_eq_adjoin_divisors (N : ℕ) [NeZero N] : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N) = IntermediateField.adjoin (AlgebraicClosure ℚ) (⇑(coeffEmb (AlgebraicClosure ℚ)) '' divisorExpansions N) := by refine le_antisymm (IntermediateField.adjoin_le_iff.mpr ?_) (IntermediateField.adjoin_le_iff.mpr ?_) · rintro x ⟨y, hy, rfl⟩ have hy' : y ∈ IntermediateField.adjoin ℚ (divisorExpansions N) := hy induction hy' using IntermediateField.adjoin_induction with | mem z hz => exact IntermediateField.subset_adjoin _ _ ⟨z, hz, rfl⟩ | algebraMap a => rw [eq_ratCast, map_ratCast] simp | add a b ha hb hia hib => rw [map_add]; exact add_mem (hia ha) (hib hb) | mul a b ha hb hia hib => rw [map_mul]; exact mul_mem (hia ha) (hib hb) | inv a ha hia => rw [map_inv₀]; exact inv_mem (hia ha) · rintro x ⟨y, hy, rfl⟩ exact coeffEmb_mem_laurentBaseChange (AlgebraicClosure ℚ) (IntermediateField.subset_adjoin ℚ _ hy) set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem adjoin_val_preimage_eq_top {K L : Type*} [Field K] [Field L] [Algebra K L] {F : IntermediateField K L} {S : Set L} (hF : F = IntermediateField.adjoin K S) : IntermediateField.adjoin K (Subtype.val ⁻¹' S : Set F) = ⊤ := by subst hF rw [eq_top_iff] rintro ⟨z, hz⟩ - induction hz using IntermediateField.adjoin_induction with | mem w hw => exact IntermediateField.subset_adjoin _ _ hw | algebraMap a => exact IntermediateField.algebraMap_mem _ a | add a b ha hb hia hib => exact add_mem hia hib | mul a b ha hb hia hib => exact mul_mem hia hib | inv a ha hia => exact inv_mem hia private def barGenSet (N : ℕ) [NeZero N] : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) := Subtype.val ⁻¹' (⇑(coeffEmb (AlgebraicClosure ℚ)) '' divisorExpansions N) set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem adjoin_barGenSet_eq_top (N : ℕ) [NeZero N] : IntermediateField.adjoin (AlgebraicClosure ℚ) (barGenSet N) = ⊤ := adjoin_val_preimage_eq_top (lbc_eq_adjoin_divisors N) private theorem barGenSet_finite (N : ℕ) [NeZero N] : (barGenSet N).Finite := by apply Set.Finite.preimage Subtype.val_injective.injOn apply Set.Finite.image have hsub : divisorExpansions N ⊆ (fun d : {d // d ∈ N.divisors} => @qExpand ℚ _ d.1 ⟨(Nat.pos_of_mem_divisors d.2).ne'⟩ jq) '' Set.univ := by rintro x ⟨d, hne, hd, hx⟩ haveI := hne exact ⟨⟨d, Nat.mem_divisors.mpr ⟨hd, NeZero.ne N⟩⟩, Set.mem_univ _, hx.symm⟩ exact ((Set.finite_univ (α := {d // d ∈ N.divisors})).image _).subset hsub private theorem jBar_mem_barGenSet (N : ℕ) [NeZero N] : jBar N ∈ barGenSet N := ⟨qExpand ℚ 1 jq, mem_divisorExpansions N (one_dvd N), by rw [qExpand_one_apply]; rfl⟩ set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem barGenSet_integral (N : ℕ) [NeZero N] (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) : ∀ x ∈ barGenSet N, IsIntegral (IntermediateField.adjoin (AlgebraicClosure ℚ) ({jBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)))) x := by rintro ⟨xv, hxF⟩ hx obtain ⟨y, hy, hxy⟩ := hx obtain ⟨d, hdne, hd, rfl⟩ := hy haveI := hdne have hxel : (⟨xv, hxF⟩ : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) = jdBar N d hd := Subtype.ext hxy.symm rw [hxel] exact isIntegral_adjoin_of_bivar_monic (dataAll d hd).monic (barEvalD_subtype N d hd (dataAll d hd)) set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in private theorem finiteDimensional_lineBar_of_dataAll (N : ℕ) [NeZero N] (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) : FiniteDimensional (IntermediateField.adjoin (AlgebraicClosure ℚ) ({jBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)))) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) := by haveI : Finite ↥(barGenSet N) := (barGenSet_finite N).to_subtype have hint := barGenSet_integral N dataAll have htower := IntermediateField.adjoin_adjoin_left (AlgebraicClosure ℚ) ({jBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (barGenSet N) rw [Set.singleton_union, Set.insert_eq_self.mpr (jBar_mem_barGenSet N), adjoin_barGenSet_eq_top N] at htower have h2 : IntermediateField.adjoin (IntermediateField.adjoin (AlgebraicClosure ℚ) ({jBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)))) (barGenSet N) = ⊤ := IntermediateField.restrictScalars_injective (AlgebraicClosure ℚ) (htower.trans IntermediateField.restrictScalars_top.symm) have hFD : FiniteDimensional (IntermediateField.adjoin (AlgebraicClosure ℚ) ({jBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)))) (IntermediateField.adjoin (IntermediateField.adjoin (AlgebraicClosure ℚ) ({jBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)))) (barGenSet N)) := IntermediateField.finiteDimensional_adjoin hint rw [h2] at hFD exact (IntermediateField.topEquiv (F := IntermediateField.adjoin (AlgebraicClosure ℚ) ({jBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))))).toLinearEquiv.finiteDimensional end BarFinDim end CharPModel end ModularCurve set_option autoImplicit false open Polynomial namespace ValuationSubring variable {K F : Type*} [Field K] [Field F] [Algebra K F] (A : ValuationSubring K) private theorem closureConstantsAdjoin_eq_range_aeval (x : F) : Subring.closure (Set.range ((algebraMap K F).comp A.subtype) ∪ {x}) = (aeval (R := A) x).toRingHom.range := by apply le_antisymm · rw [Subring.closure_le] rintro y (⟨a, rfl⟩ | rfl) · refine ⟨C a, ?_⟩ simp only [AlgHom.toRingHom_eq_coe, RingHom.coe_coe, aeval_C, RingHom.coe_comp, Function.comp_apply] rfl · exact ⟨X, by simp⟩ · rintro y ⟨p, rfl⟩ simp only [AlgHom.toRingHom_eq_coe, RingHom.coe_coe] induction p using Polynomial.induction_on with | C a => rw [aeval_C] exact Subring.subset_closure (Or.inl ⟨a, rfl⟩) | add p q hp hq => rw [map_add] exact Subring.add_mem _ hp hq | monomial n a h => rw [pow_succ, ← mul_assoc, map_mul, aeval_X] exact Subring.mul_mem _ h (Subring.subset_closure (Or.inr rfl)) private theorem aeval_injective_of_transcendental {x : F} (hx : Transcendental K x) : Function.Injective (aeval (R := A) x) := by rw [injective_iff_map_eq_zero] intro p hp have hK : aeval x (p.map (algebraMap A K)) = 0 := by rwa [aeval_map_algebraMap] have hp' : p.map (algebraMap A K) = 0 := (injective_iff_map_eq_zero _).mp (transcendental_iff_injective.mp hx) _ hK exact (Polynomial.map_injective (algebraMap A K) Subtype.val_injective) (by rw [hp', Polynomial.map_zero]) private theorem aeval_mem_closure (x : F) (p : A[X]) : aeval x p ∈ Subring.closure (Set.range ((algebraMap K F).comp A.subtype) ∪ {x}) := by rw [closureConstantsAdjoin_eq_range_aeval] exact ⟨p, rfl⟩ private noncomputable def polynomialEquivClosure {x : F} (hx : Transcendental K x) : A[X] ≃+* Subring.closure (Set.range ((algebraMap K F).comp A.subtype) ∪ {x}) := RingEquiv.ofBijective ((aeval (R := A) x).toRingHom.codRestrict _ (A.aeval_mem_closure x)) ⟨fun p q h => A.aeval_injective_of_transcendental hx (Subtype.ext_iff.mp h), fun y => by obtain ⟨p, hp⟩ : (y : F) ∈ (aeval (R := A) x).toRingHom.range := by rw [← closureConstantsAdjoin_eq_range_aeval] exact y.2 exact ⟨p, Subtype.ext hp⟩⟩ @[simp] private theorem polynomialEquivClosure_apply {x : F} (hx : Transcendental K x) (p : A[X]) : (A.polynomialEquivClosure hx p : F) = aeval x p := rfl private theorem isIntegrallyClosed_closure {x : F} (hx : Transcendental K x) : IsIntegrallyClosed (Subring.closure (Set.range ((algebraMap K F).comp A.subtype) ∪ {x})) := IsIntegrallyClosed.of_equiv (A.polynomialEquivClosure hx) end ValuationSubring namespace Subring variable {F : Type*} [Field F] private theorem isIntegral_iff_exists_monic_eval₂ (S : Subring F) (b : F) : IsIntegral S b ↔ ∃ p : Polynomial S, p.Monic ∧ Polynomial.eval₂ S.subtype b p = 0 := Iff.rfl private theorem exists_ideal_le_comap_eq_of_isIntegral {S B : Subring F} (hSB : S ≤ B) [IsIntegrallyClosed S] (hint : ∀ b : B, IsIntegral S (b : F)) {p q : Ideal S} [p.IsPrime] [q.IsPrime] (hpq : p ≤ q) (Q : Ideal B) [Q.IsPrime] (hQ : Q.comap (Subring.inclusion hSB) = q) : ∃ P : Ideal B, P ≤ Q ∧ P.IsPrime ∧ P.comap (Subring.inclusion hSB) = p := by letI : Algebra S B := (Subring.inclusion hSB).toAlgebra have halg : ∀ s : S, algebraMap S B s = Subring.inclusion hSB s := fun _ => rfl haveI : FaithfulSMul S B := (faithfulSMul_iff_algebraMap_injective S B).mpr fun a b h => by rw [halg, halg] at h have h' : (a : F) = (b : F) := congrArg (fun y : B => (y : F)) h exact Subtype.ext h' haveI : Algebra.IsIntegral S B := ⟨fun b => by obtain ⟨f, hf, hfb⟩ := hint b refine ⟨f, hf, ?_⟩ apply Subtype.val_injective change B.subtype (Polynomial.eval₂ (algebraMap S B) b f) = ((0 : B) : F) have hc : B.subtype.comp (algebraMap S B) = S.subtype := RingHom.ext fun _ => rfl rw [Polynomial.hom_eval₂, hc] exact hfb⟩ haveI : Q.LiesOver q := ⟨by rw [Ideal.under_def, ← hQ]; rfl⟩ obtain ⟨P, hPQ, hP, hPp⟩ := Ideal.exists_ideal_le_liesOver_of_le (p := p) (q := q) Q hpq exact ⟨P, hPQ, hP, by rw [hPp.over, Ideal.under_def]; rfl⟩ end Subring set_option autoImplicit false noncomputable section open IsLocalRing namespace AlgebraicCurve namespace Place variable {K F : Type*} [Field K] [Field F] [Algebra K F] (w : Place K F) private theorem algebraMap_mem (a : K) : algebraMap K F a ∈ w.toValuationSubring := w.algebraMap_mem' a private theorem algebraMap_mem_nonunits_iff (a : K) : algebraMap K F a ∈ w.toValuationSubring.nonunits ↔ a = 0 := by constructor · intro h rcases (ValuationSubring.mem_nonunits_iff_or _).mp h with h0 | hinv · exact (map_eq_zero _).mp h0 · exact absurd (by simpa using w.algebraMap_mem a⁻¹) hinv · rintro rfl simp [ZeroMemClass.zero_mem] private theorem mul_mem_nonunits {x y : F} (hx : x ∈ w.toValuationSubring.nonunits) (hy : y ∈ w.toValuationSubring) : x * y ∈ w.toValuationSubring.nonunits := by rw [ValuationSubring.mem_nonunits_iff] at hx ⊢ rw [← ValuationSubring.valuation_le_one_iff] at hy calc w.toValuationSubring.valuation (x * y) = w.toValuationSubring.valuation x * w.toValuationSubring.valuation y := map_mul _ _ _ _ ≤ w.toValuationSubring.valuation x * 1 := by gcongr _ = w.toValuationSubring.valuation x := mul_one _ _ < 1 := hx private theorem mem_of_ord_pos {f : F} (h : 0 < w.ord f) : f ∈ w.toValuationSubring := by have hf : f ≠ 0 := by rintro rfl; simp at h obtain ⟨π, hπ⟩ := IsDiscreteValuationRing.exists_irreducible w.toValuationSubring obtain ⟨u, hu⟩ := w.exists_unit_mul_zpow hf hπ rw [hu, show w.ord f = (((w.ord f).toNat : ℕ) : ℤ) from (Int.toNat_of_nonneg h.le).symm, zpow_natCast] exact mul_mem (u : w.toValuationSubring).2 (pow_mem (π : w.toValuationSubring).2 _) private theorem mem_nonunits_iff_ord_pos {f : F} (hf : f ≠ 0) : f ∈ w.toValuationSubring.nonunits ↔ 0 < w.ord f := by constructor · intro h have hmem : f ∈ w.toValuationSubring := w.toValuationSubring.nonunits_subset h have h' : ((⟨f, hmem⟩ : w.toValuationSubring) : F) ∈ w.toValuationSubring.nonunits := h rw [ValuationSubring.coe_mem_nonunits_iff] at h' exact (w.mem_maximalIdeal_iff_ord_pos hf hmem).mp h' · intro h have hmem : f ∈ w.toValuationSubring := w.mem_of_ord_pos h have h' := (w.mem_maximalIdeal_iff_ord_pos hf hmem).mpr h rw [← ValuationSubring.coe_mem_nonunits_iff] at h' exact h' private def HasValueAt (f : F) (a : K) : Prop := f - algebraMap K F a ∈ w.toValuationSubring.nonunits private theorem hasValueAt_iff (f : F) (a : K) : w.HasValueAt f a ↔ f - algebraMap K F a ∈ w.toValuationSubring.nonunits := Iff.rfl private theorem hasValueAt_iff_ord_pos {f : F} {a : K} (h : f ≠ algebraMap K F a) : w.HasValueAt f a ↔ 0 < w.ord (f - algebraMap K F a) := w.mem_nonunits_iff_ord_pos (sub_ne_zero.mpr h) private theorem hasValueAt_of_ord_pos {f : F} {a : K} (h : 0 < w.ord (f - algebraMap K F a)) : w.HasValueAt f a := by have hne : f ≠ algebraMap K F a := by intro hfa; rw [hfa, sub_self] at h; simp at h exact (w.hasValueAt_iff_ord_pos hne).mpr h private theorem hasValueAt_algebraMap (a : K) : w.HasValueAt (algebraMap K F a) a := by simp [HasValueAt, ZeroMemClass.zero_mem] private theorem hasValueAt_zero_iff (f : F) : w.HasValueAt f 0 ↔ f ∈ w.toValuationSubring.nonunits := by simp [HasValueAt] private theorem mem_of_hasValueAt {f : F} {a : K} (h : w.HasValueAt f a) : f ∈ w.toValuationSubring := by have h1 : f - algebraMap K F a ∈ w.toValuationSubring := w.toValuationSubring.nonunits_subset h simpa using add_mem h1 (w.algebraMap_mem a) variable {w} in private theorem HasValueAt.unique {f : F} {a b : K} (ha : w.HasValueAt f a) (hb : w.HasValueAt f b) : a = b := by have h : algebraMap K F (a - b) ∈ w.toValuationSubring.nonunits := by have := sub_mem hb ha rwa [sub_sub_sub_cancel_left, ← map_sub] at this exact sub_eq_zero.mp ((w.algebraMap_mem_nonunits_iff _).mp h) variable {w} in private theorem HasValueAt.add {f g : F} {a b : K} (hf : w.HasValueAt f a) (hg : w.HasValueAt g b) : w.HasValueAt (f + g) (a + b) := by have := add_mem hf hg rw [HasValueAt, map_add] convert this using 1 ring variable {w} in private theorem HasValueAt.neg {f : F} {a : K} (hf : w.HasValueAt f a) : w.HasValueAt (-f) (-a) := by have := neg_mem hf rw [HasValueAt, map_neg] convert this using 1 ring variable {w} in private theorem HasValueAt.mul {f g : F} {a b : K} (hf : w.HasValueAt f a) (hg : w.HasValueAt g b) : w.HasValueAt (f * g) (a * b) := by have h1 : (f - algebraMap K F a) * g ∈ w.toValuationSubring.nonunits := w.mul_mem_nonunits hf (w.mem_of_hasValueAt hg) have h2 : (g - algebraMap K F b) * algebraMap K F a ∈ w.toValuationSubring.nonunits := w.mul_mem_nonunits hg (w.algebraMap_mem a) have := add_mem h1 h2 rw [HasValueAt, map_mul] convert this using 1 ring variable {w} in private theorem HasValueAt.inv {f : F} {a : K} (hf : w.HasValueAt f a) (ha : a ≠ 0) : w.HasValueAt f⁻¹ a⁻¹ := by have hf0 : f ≠ 0 := by rintro rfl have : w.HasValueAt (0 : F) 0 := by simpa using w.hasValueAt_algebraMap 0 exact ha (hf.unique this) have hfu : f ∉ w.toValuationSubring.nonunits := fun hfn => ha (hf.unique ((w.hasValueAt_zero_iff f).mpr hfn)) have hfinv : f⁻¹ ∈ w.toValuationSubring := by by_contra hne exact hfu ((ValuationSubring.mem_nonunits_iff_or _).mpr (Or.inr (by simpa using hne))) have hprod : (f - algebraMap K F a) * (f⁻¹ * algebraMap K F a⁻¹) ∈ w.toValuationSubring.nonunits := w.mul_mem_nonunits hf (mul_mem hfinv (w.algebraMap_mem _)) have := neg_mem hprod change f⁻¹ - algebraMap K F a⁻¹ ∈ w.toValuationSubring.nonunits convert this using 1 have haF : algebraMap K F a ≠ 0 := by simpa using ha rw [map_inv₀] field_simp ring variable {w} in private theorem HasValueAt.div {f g : F} {a b : K} (hf : w.HasValueAt f a) (hg : w.HasValueAt g b) (hb : b ≠ 0) : w.HasValueAt (f / g) (a / b) := by rw [div_eq_mul_inv, div_eq_mul_inv] exact hf.mul (hg.inv hb) private theorem hasValueAt_iff_residue {f : F} (hf : f ∈ w.toValuationSubring) (a : K) : w.HasValueAt f a ↔ residue w.toValuationSubring ⟨f, hf⟩ = algebraMap K w.ResidueField a := by have e : algebraMap K w.ResidueField a = residue w.toValuationSubring (algebraMap K w.toValuationSubring a) := rfl rw [e, ← sub_eq_zero, ← map_sub, residue_eq_zero_iff, ← ValuationSubring.coe_mem_nonunits_iff] rfl private theorem exists_hasValueAt (hw : Function.Surjective (algebraMap K w.ResidueField)) {f : F} (hf : f ∈ w.toValuationSubring) : ∃ a : K, w.HasValueAt f a := by obtain ⟨a, ha⟩ := hw (residue w.toValuationSubring ⟨f, hf⟩) exact ⟨a, (w.hasValueAt_iff_residue hf a).mpr ha.symm⟩ private theorem surjective_algebraMap_residueField_of_isAlgClosed [IsAlgClosed K] [Module.Finite K w.ResidueField] : Function.Surjective (algebraMap K w.ResidueField) := haveI : Algebra.IsIntegral K w.ResidueField := Algebra.IsIntegral.of_finite K w.ResidueField (IsAlgClosed.algebraMap_bijective_of_isIntegral (k := K) (K := w.ResidueField)).2 private theorem surjective_algebraMap_residueField_of_deg_eq_one [IsAlgClosed K] (h : w.deg = 1) : Function.Surjective (algebraMap K w.ResidueField) := haveI : Module.Finite K w.ResidueField := Module.finite_of_finrank_eq_succ (n := 0) h w.surjective_algebraMap_residueField_of_isAlgClosed variable (A : ValuationSubring K) private def compSubring : Subring F where carrier := {f | ∃ a : A, w.HasValueAt f a} mul_mem' := by rintro f g ⟨a, ha⟩ ⟨b, hb⟩ exact ⟨a * b, by simpa using ha.mul hb⟩ one_mem' := ⟨1, by simpa using w.hasValueAt_algebraMap 1⟩ add_mem' := by rintro f g ⟨a, ha⟩ ⟨b, hb⟩ exact ⟨a + b, by simpa using ha.add hb⟩ zero_mem' := ⟨0, by simpa using w.hasValueAt_algebraMap 0⟩ neg_mem' := by rintro f ⟨a, ha⟩ exact ⟨-a, by simpa using ha.neg⟩ variable {A} in private theorem mem_compSubring_iff {f : F} : f ∈ w.compSubring A ↔ ∃ a : A, w.HasValueAt f a := Iff.rfl variable {A} in private theorem mem_compSubring_of_hasValueAt {f : F} {a : K} (ha : a ∈ A) (h : w.HasValueAt f a) : f ∈ w.compSubring A := ⟨⟨a, ha⟩, h⟩ private theorem compSubring_le : w.compSubring A ≤ w.toValuationSubring.toSubring := by rintro f ⟨a, ha⟩ exact w.mem_of_hasValueAt ha private theorem mem_compSubring_of_mem_nonunits {f : F} (hf : f ∈ w.toValuationSubring.nonunits) : f ∈ w.compSubring A := ⟨0, by simpa [w.hasValueAt_zero_iff] using hf⟩ private theorem algebraMap_mem_compSubring_iff (a : K) : algebraMap K F a ∈ w.compSubring A ↔ a ∈ A := by constructor · rintro ⟨b, hb⟩ rw [(w.hasValueAt_algebraMap a).unique hb] exact b.2 · intro ha exact ⟨⟨a, ha⟩, w.hasValueAt_algebraMap a⟩ private def value : w.compSubring A →+* A where toFun f := Classical.choose f.2 map_one' := Subtype.ext <| (Classical.choose_spec (w.compSubring A).one_mem).unique (by simpa using w.hasValueAt_algebraMap 1) map_mul' f g := Subtype.ext <| (Classical.choose_spec (mul_mem f.2 g.2)).unique (by simpa using (Classical.choose_spec f.2).mul (Classical.choose_spec g.2)) map_zero' := Subtype.ext <| (Classical.choose_spec (w.compSubring A).zero_mem).unique (by simpa using w.hasValueAt_algebraMap 0) map_add' f g := Subtype.ext <| (Classical.choose_spec (add_mem f.2 g.2)).unique (by simpa using (Classical.choose_spec f.2).add (Classical.choose_spec g.2)) private theorem hasValueAt_value (f : w.compSubring A) : w.HasValueAt (f : F) (w.value A f : K) := Classical.choose_spec f.2 variable {A} in private theorem value_eq_of_hasValueAt {f : w.compSubring A} {a : A} (h : w.HasValueAt (f : F) a) : w.value A f = a := Subtype.ext ((w.hasValueAt_value A f).unique h) variable {A} in private theorem ord_sub_value_pos {f : w.compSubring A} (hf : (f : F) ≠ algebraMap K F (w.value A f)) : 0 < w.ord ((f : F) - algebraMap K F (w.value A f)) := (w.hasValueAt_iff_ord_pos hf).mp (w.hasValueAt_value A f) variable {A} in private theorem value_eq_of_ord_pos {f : w.compSubring A} {a : A} (h : 0 < w.ord ((f : F) - algebraMap K F a)) : w.value A f = a := w.value_eq_of_hasValueAt (w.hasValueAt_of_ord_pos h) private theorem value_algebraMap (a : A) : w.value A ⟨algebraMap K F a, (w.algebraMap_mem_compSubring_iff A a).mpr a.2⟩ = a := w.value_eq_of_hasValueAt (w.hasValueAt_algebraMap (a : K)) private theorem value_surjective : Function.Surjective (w.value A) := fun a => ⟨_, w.value_algebraMap A a⟩ variable {A} in private theorem value_eq_zero_of_mem_nonunits {f : w.compSubring A} (hf : (f : F) ∈ w.toValuationSubring.nonunits) : w.value A f = 0 := w.value_eq_of_hasValueAt (by simpa [w.hasValueAt_zero_iff] using hf) private def centre : Ideal (w.compSubring A) := (maximalIdeal A).comap (w.value A) private instance centre_isPrime : (w.centre A).IsPrime := Ideal.comap_isPrime _ _ private instance centre_isMaximal : (w.centre A).IsMaximal := Ideal.comap_isMaximal_of_surjective _ (w.value_surjective A) variable {A} in private theorem mem_centre_iff (f : w.compSubring A) : f ∈ w.centre A ↔ w.value A f ∈ maximalIdeal A := Iff.rfl variable {A} in private theorem mem_centre_iff_of_hasValueAt {f : w.compSubring A} {a : A} (h : w.HasValueAt (f : F) a) : f ∈ w.centre A ↔ a ∈ maximalIdeal A := by rw [mem_centre_iff, w.value_eq_of_hasValueAt h] variable {A} in private theorem mem_centre_iff_of_ord_pos {f : w.compSubring A} {a : A} (h : 0 < w.ord ((f : F) - algebraMap K F a)) : f ∈ w.centre A ↔ a ∈ maximalIdeal A := w.mem_centre_iff_of_hasValueAt (w.hasValueAt_of_ord_pos h) variable {A} in private theorem mem_centre_of_mem_nonunits {f : w.compSubring A} (hf : (f : F) ∈ w.toValuationSubring.nonunits) : f ∈ w.centre A := by rw [mem_centre_iff, w.value_eq_zero_of_mem_nonunits hf] exact Ideal.zero_mem _ variable {A} in private theorem mem_centre_of_ord_pos {f : w.compSubring A} (hf : 0 < w.ord (f : F)) : f ∈ w.centre A := w.mem_centre_of_mem_nonunits ((w.mem_nonunits_iff_ord_pos (by rintro h; simp [h] at hf)).mpr hf) private theorem algebraMap_mem_centre_iff (a : A) : (⟨algebraMap K F a, (w.algebraMap_mem_compSubring_iff A a).mpr a.2⟩ : w.compSubring A) ∈ w.centre A ↔ a ∈ maximalIdeal A := by rw [mem_centre_iff, value_algebraMap] private theorem mem_compSubring_or_inv_mem (hw : Function.Surjective (algebraMap K w.ResidueField)) (f : F) : f ∈ w.compSubring A ∨ f⁻¹ ∈ w.compSubring A := by by_cases hf : f ∈ w.toValuationSubring · obtain ⟨c, hc⟩ := w.exists_hasValueAt hw hf by_cases hcA : c ∈ A · exact Or.inl ⟨⟨c, hcA⟩, hc⟩ · right have hcA' : c⁻¹ ∈ A := (A.mem_or_inv_mem c).resolve_left hcA have hc0 : c ≠ 0 := fun h => hcA (h ▸ A.zero_mem) have hf0 : f ≠ 0 := by rintro rfl have : w.HasValueAt (0 : F) 0 := by simpa using w.hasValueAt_algebraMap 0 exact hc0 (hc.unique this) have hfu : f ∉ w.toValuationSubring.nonunits := by intro hfn exact hc0 (hc.unique ((w.hasValueAt_zero_iff f).mpr hfn)) have hfinv : f⁻¹ ∈ w.toValuationSubring := by by_contra hne exact hfu ((ValuationSubring.mem_nonunits_iff_or _).mpr (Or.inr (by simpa using hne))) refine ⟨⟨c⁻¹, hcA'⟩, ?_⟩ have hprod : (f - algebraMap K F c) * (f⁻¹ * algebraMap K F c⁻¹) ∈ w.toValuationSubring.nonunits := w.mul_mem_nonunits hc (mul_mem hfinv (w.algebraMap_mem _)) have := neg_mem hprod show f⁻¹ - algebraMap K F (c⁻¹ : K) ∈ w.toValuationSubring.nonunits convert this using 1 have hcF : algebraMap K F c ≠ 0 := by simpa using hc0 rw [map_inv₀] field_simp ring · right refine w.mem_compSubring_of_mem_nonunits A ?_ exact (ValuationSubring.inv_mem_nonunits_iff _).mpr (Or.inr hf) private def compValuationSubring (hw : Function.Surjective (algebraMap K w.ResidueField)) : ValuationSubring F := ValuationSubring.ofSubring (w.compSubring A) (w.mem_compSubring_or_inv_mem A hw) @[simp] private theorem compValuationSubring_toSubring (hw : Function.Surjective (algebraMap K w.ResidueField)) : (w.compValuationSubring A hw).toSubring = w.compSubring A := rfl private theorem mem_compValuationSubring_iff (hw : Function.Surjective (algebraMap K w.ResidueField)) (f : F) : f ∈ w.compValuationSubring A hw ↔ f ∈ w.compSubring A := Iff.rfl private theorem mem_compSubring_of_isIntegral (hw : Function.Surjective (algebraMap K w.ResidueField)) {S : Subring F} (hS : S ≤ w.compSubring A) {f : F} (hf : IsIntegral S f) : f ∈ w.compSubring A := by obtain ⟨p, hp, hpf⟩ := hf let V := w.compValuationSubring A hw let i : S →+* V := Subring.inclusion hS have hint : IsIntegral V f := by refine ⟨p.map i, hp.map i, ?_⟩ rw [Polynomial.eval₂_map] exact hpf obtain ⟨y, hy⟩ := IsIntegrallyClosed.isIntegral_iff.mp hint rw [← hy] exact y.2 private theorem mem_compSubring_of_isIntegral' [IsAlgClosed K] {S : Subring F} (hS : S ≤ w.compSubring A) {f : F} (hf : IsIntegral S f) : f ∈ w.compSubring A := by obtain ⟨p, hp, hpf⟩ := hf have hSO : ∀ s : S, (s : F) ∈ w.toValuationSubring := fun s => w.compSubring_le A (hS s.2) have hfO : f ∈ w.toValuationSubring := by refine w.mem_of_eval_monic_eq_zero (P := p.map S.subtype) (hp.map _) (fun i => ?_) ?_ · rw [Polynomial.coeff_map] exact hSO _ · rw [Polynomial.eval_map] exact hpf let vS : S →+* A := (w.value A).comp (Subring.inclusion hS) let ιS : S →+* w.toValuationSubring := S.subtype.codRestrict _ hSO have hres : (residue w.toValuationSubring).comp ιS = ((algebraMap K w.ResidueField).comp (algebraMap A K)).comp vS := by ext s change residue w.toValuationSubring ⟨s, hSO s⟩ = algebraMap K w.ResidueField ((w.value A ⟨s, hS s.2⟩ : A) : K) exact (w.hasValueAt_iff_residue (hSO s) _).mp (w.hasValueAt_value A ⟨s, hS s.2⟩) set r : w.ResidueField := residue w.toValuationSubring ⟨f, hfO⟩ with hr let Q : Polynomial A := p.map vS have hQ : Q.Monic := hp.map _ have hzero : Polynomial.eval₂ ιS ⟨f, hfO⟩ p = 0 := by apply Subtype.val_injective change w.toValuationSubring.subtype (Polynomial.eval₂ ιS ⟨f, hfO⟩ p) = ((0 : w.toValuationSubring) : F) rw [Polynomial.hom_eval₂] exact hpf have hrootκ : Polynomial.eval₂ (algebraMap K w.ResidueField) r (Q.map (algebraMap A K)) = 0 := by rw [Polynomial.eval₂_map, Polynomial.eval₂_map, ← hres, hr, ← Polynomial.hom_eval₂, hzero, map_zero] have hint : IsIntegral K r := ⟨Q.map (algebraMap A K), hQ.map _, hrootκ⟩ obtain ⟨c, hc⟩ : r ∈ (algebraMap K w.ResidueField).range := minpoly.mem_range_of_degree_eq_one K r (IsAlgClosed.degree_eq_one_of_irreducible K (minpoly.irreducible hint)) have hcroot : Polynomial.eval₂ (algebraMap A K) c Q = 0 := by apply (algebraMap K w.ResidueField).injective rw [Polynomial.hom_eval₂, ← Polynomial.eval₂_map, hc, hrootκ, map_zero] obtain ⟨y, hy⟩ := IsIntegrallyClosed.isIntegral_iff.mp (⟨Q, hQ, hcroot⟩ : IsIntegral A c) refine ⟨y, (w.hasValueAt_iff_residue hfO _).mpr ?_⟩ rw [← hr, ← hc, ← hy] rfl private theorem exists_unique_valueHom [IsAlgClosed K] (g : F) (B₀ : Subring F) (hint : ∀ b : B₀, ∃ p : Polynomial (Subring.closure (algebraMap K F '' (A : Set K) ∪ {g})), p.Monic ∧ Polynomial.eval₂ (Subring.closure (algebraMap K F '' (A : Set K) ∪ {g})).subtype (b : F) p = 0) (hw : ∃ a : A, g - algebraMap K F (a : K) ∈ w.toValuationSubring.nonunits) : ∃! φ : B₀ →+* A, ∀ b : B₀, (b : F) - algebraMap K F ((φ b : A) : K) ∈ w.toValuationSubring.nonunits := by obtain ⟨a₀, ha₀⟩ := hw have hg : g ∈ w.compSubring A := w.mem_compSubring_of_hasValueAt a₀.2 ha₀ have hS : Subring.closure (algebraMap K F '' (A : Set K) ∪ {g}) ≤ w.compSubring A := by rw [Subring.closure_le] rintro y (⟨c, hc, rfl⟩ | rfl) · exact (w.algebraMap_mem_compSubring_iff A c).mpr hc · exact hg have hB₀ : B₀ ≤ w.compSubring A := fun b hb => w.mem_compSubring_of_isIntegral' A hS (hint ⟨b, hb⟩) refine ⟨(w.value A).comp (Subring.inclusion hB₀), fun b => w.hasValueAt_value A ⟨b, hB₀ b.2⟩, ?_⟩ intro ψ hψ refine RingHom.ext fun b => ?_ have h1 : w.HasValueAt (b : F) ((ψ b : A) : K) := hψ b have h2 : ψ b = w.value A ⟨b, hB₀ b.2⟩ := Subtype.ext (h1.unique (w.hasValueAt_value A ⟨b, hB₀ b.2⟩)) exact h2 variable {A} in private theorem residue_comp_value_surjective {B : Subring F} (hB : B ≤ w.compSubring A) (hconst : ∀ a : A, algebraMap K F a ∈ B) : Function.Surjective (((IsLocalRing.residue A).comp (w.value A)).comp (Subring.inclusion hB)) := by intro x obtain ⟨a, rfl⟩ := IsLocalRing.residue_surjective x refine ⟨⟨algebraMap K F a, hconst a⟩, ?_⟩ change IsLocalRing.residue A (w.value A ⟨algebraMap K F a, hB (hconst a)⟩) = _ rw [w.value_eq_of_hasValueAt (w.hasValueAt_algebraMap (a : K))] variable {A} in private theorem ker_residue_comp_value {B : Subring F} (hB : B ≤ w.compSubring A) : RingHom.ker (((IsLocalRing.residue A).comp (w.value A)).comp (Subring.inclusion hB)) = (w.centre A).comap (Subring.inclusion hB) := by ext b rw [RingHom.mem_ker, Ideal.mem_comap, mem_centre_iff, RingHom.comp_apply, RingHom.comp_apply, IsLocalRing.residue_eq_zero_iff] variable {A} in private theorem centre_comap_isMaximal {B : Subring F} (hB : B ≤ w.compSubring A) (hconst : ∀ a : A, algebraMap K F a ∈ B) : ((w.centre A).comap (Subring.inclusion hB)).IsMaximal := by rw [← w.ker_residue_comp_value hB] exact RingHom.ker_isMaximal_of_surjective _ (w.residue_comp_value_surjective hB hconst) variable {A} in private theorem sub_value_mem_centre_comap {B : Subring F} (hB : B ≤ w.compSubring A) (hconst : ∀ a : A, algebraMap K F a ∈ B) (b : B) : b - ⟨algebraMap K F (w.value A ⟨b, hB b.2⟩ : K), hconst _⟩ ∈ (w.centre A).comap (Subring.inclusion hB) := by rw [Ideal.mem_comap, mem_centre_iff] simp only [map_sub] have h1 : w.value A (Subring.inclusion hB ⟨algebraMap K F (w.value A ⟨b, hB b.2⟩ : K), hconst _⟩) = w.value A ⟨b, hB b.2⟩ := w.value_eq_of_hasValueAt (w.hasValueAt_algebraMap _) have h2 : w.value A (Subring.inclusion hB b) = w.value A ⟨b, hB b.2⟩ := rfl rw [h1, h2, sub_self] exact Ideal.zero_mem _ variable {A} in private theorem algebraMap_mem_centre_comap_iff {B : Subring F} (hB : B ≤ w.compSubring A) (hconst : ∀ a : A, algebraMap K F a ∈ B) (a : A) : (⟨algebraMap K F a, hconst a⟩ : B) ∈ (w.centre A).comap (Subring.inclusion hB) ↔ a ∈ maximalIdeal A := by rw [Ideal.mem_comap] exact w.algebraMap_mem_centre_iff A a end Place end AlgebraicCurve set_option autoImplicit false namespace ValuationSubring variable {K : Type*} [Field K] (A : ValuationSubring K) private theorem algebraMap_bijective_of_isIntegral_of_isAlgClosed [IsAlgClosed K] (R : Type*) [CommRing R] [IsDomain R] [Algebra A R] [FaithfulSMul A R] [Algebra.IsIntegral A R] : Function.Bijective (algebraMap A R) := by have hinj : Function.Injective (algebraMap A R) := FaithfulSMul.algebraMap_injective A R refine ⟨hinj, fun r => ?_⟩ haveI : Algebra.IsAlgebraic A R := Algebra.IsIntegral.isAlgebraic let φ : R →ₐ[A] K := IsAlgClosed.lift have hφ : Function.Injective φ := by rw [injective_iff_map_eq_zero] intro x hx have hker : RingHom.ker φ.toRingHom = ⊥ := by refine Ideal.eq_bot_of_comap_eq_bot (R := A) ?_ rw [eq_bot_iff] intro a ha rw [Ideal.mem_comap, RingHom.mem_ker] at ha change φ (algebraMap A R a) = 0 at ha rw [AlgHom.commutes] at ha have h0 : (a : K) = 0 := ha have ha0 : a = 0 := by exact_mod_cast h0 rw [ha0] exact Ideal.zero_mem _ have hmem : x ∈ RingHom.ker φ.toRingHom := hx rw [hker] at hmem exact Ideal.mem_bot.mp hmem have hint : IsIntegral A (φ r) := (Algebra.IsIntegral.isIntegral (R := A) r).map φ obtain ⟨a, ha⟩ := IsIntegrallyClosed.isIntegral_iff.mp hint refine ⟨a, hφ ?_⟩ rw [AlgHom.commutes, ha] section Quotient open Polynomial variable {F : Type*} [Field F] [Algebra K F] private abbrev constants : A →+* F := (algebraMap K F).comp A.subtype variable {A} private theorem exists_sub_constants_mem [IsAlgClosed K] {x : F} {B : Subring F} (hconst : ∀ a : A, A.constants a ∈ B) (hxB : x ∈ B) (hint : ∀ b : B, IsIntegral (Subring.closure (Set.range (A.constants (F := F)) ∪ {x})) (b : F)) (𝔭 : Ideal B) [𝔭.IsPrime] (hbot : ∀ a : A, (⟨A.constants a, hconst a⟩ : B) ∈ 𝔭 → a = 0) (a₀ : A) (hx : (⟨x, hxB⟩ : B) - ⟨A.constants a₀, hconst a₀⟩ ∈ 𝔭) (b : B) : ∃ a : A, b - ⟨A.constants a, hconst a⟩ ∈ 𝔭 := by classical set S : Subring F := Subring.closure (Set.range (A.constants (F := F)) ∪ {x}) with hS have hSB : S ≤ B := by rw [hS, Subring.closure_le] rintro y (⟨a, rfl⟩ | rfl) exacts [hconst a, hxB] let cB : A →+* B := (A.constants (F := F)).codRestrict B hconst letI alg : Algebra A (B ⧸ 𝔭) := ((Ideal.Quotient.mk 𝔭).comp cB).toAlgebra have halg : ∀ a : A, algebraMap A (B ⧸ 𝔭) a = Ideal.Quotient.mk 𝔭 (cB a) := fun _ => rfl let ψ : S →+* B ⧸ 𝔭 := (Ideal.Quotient.mk 𝔭).comp (Subring.inclusion hSB) have step1 : ∀ (y : F) (hy : y ∈ S), ψ ⟨y, hy⟩ ∈ (algebraMap A (B ⧸ 𝔭)).range := by intro y hy induction hy using Subring.closure_induction with | mem y hy => rcases hy with ⟨a, rfl⟩ | h · exact ⟨a, rfl⟩ · have h' : x = y := (Set.mem_singleton_iff.mp h).symm subst h' refine ⟨a₀, ?_⟩ rw [halg] change Ideal.Quotient.mk 𝔭 (cB a₀) = Ideal.Quotient.mk 𝔭 ⟨x, hxB⟩ rw [Ideal.Quotient.eq] have := 𝔭.neg_mem hx rwa [neg_sub] at this | zero => change ψ 0 ∈ _ rw [map_zero] exact Subring.zero_mem _ | one => change ψ 1 ∈ _ rw [map_one] exact Subring.one_mem _ | add y z hy hz ihy ihz => change ψ (⟨y, hy⟩ + ⟨z, hz⟩) ∈ _ rw [map_add] exact Subring.add_mem _ ihy ihz | neg y hy ihy => change ψ (-⟨y, hy⟩) ∈ _ rw [map_neg] exact Subring.neg_mem _ ihy | mul y z hy hz ihy ihz => change ψ (⟨y, hy⟩ * ⟨z, hz⟩) ∈ _ rw [map_mul] exact Subring.mul_mem _ ihy ihz have step1' : ∀ s : S, ψ s ∈ (algebraMap A (B ⧸ 𝔭)).range := fun s => step1 s s.2 haveI hintq : Algebra.IsIntegral A (B ⧸ 𝔭) := by refine ⟨fun y => ?_⟩ obtain ⟨b, rfl⟩ := Ideal.Quotient.mk_surjective y obtain ⟨f, hf, hfb⟩ := hint b set g : Polynomial B := f.map (Subring.inclusion hSB) with hg have hgm : g.Monic := hf.map _ have hgb : g.eval b = 0 := by apply Subtype.val_injective change B.subtype (eval b (f.map (Subring.inclusion hSB))) = ((0 : B) : F) rw [eval_map, hom_eval₂] exact hfb set gq : Polynomial (B ⧸ 𝔭) := g.map (Ideal.Quotient.mk 𝔭) with hgq have hgqm : gq.Monic := hgm.map _ have hgqb : gq.eval (Ideal.Quotient.mk 𝔭 b) = 0 := by rw [hgq, eval_map, eval₂_hom, hgb, map_zero] have hlifts : gq ∈ Polynomial.lifts (algebraMap A (B ⧸ 𝔭)) := by rw [lifts_iff_coeff_lifts] intro n rw [hgq, coeff_map, hg, coeff_map] exact step1' (f.coeff n) obtain ⟨q, hqmap, -, hqm⟩ := lifts_and_degree_eq_and_monic hlifts hgqm refine ⟨q, hqm, ?_⟩ rw [← eval_map, hqmap, hgqb] haveI : FaithfulSMul A (B ⧸ 𝔭) := by rw [faithfulSMul_iff_algebraMap_injective, injective_iff_map_eq_zero] intro a ha rw [halg, Ideal.Quotient.eq_zero_iff_mem] at ha exact hbot a ha obtain ⟨a, ha⟩ := (A.algebraMap_bijective_of_isIntegral_of_isAlgClosed (B ⧸ 𝔭)).2 (Ideal.Quotient.mk 𝔭 b) refine ⟨a, ?_⟩ rw [halg, Ideal.Quotient.eq] at ha have := 𝔭.neg_mem ha rwa [neg_sub] at this private theorem constants_unique_mod {B : Subring F} (hconst : ∀ a : A, A.constants a ∈ B) (𝔭 : Ideal B) (hbot : ∀ a : A, (⟨A.constants a, hconst a⟩ : B) ∈ 𝔭 → a = 0) {a c : A} (h : (⟨A.constants a, hconst a⟩ : B) - ⟨A.constants c, hconst c⟩ ∈ 𝔭) : a = c := by have : (⟨A.constants (a - c), hconst (a - c)⟩ : B) ∈ 𝔭 := by convert h using 1 apply Subtype.ext push_cast rw [map_sub] exact sub_eq_zero.mp (hbot _ this) end Quotient end ValuationSubring set_option autoImplicit false noncomputable section open IsLocalRing IsDedekindDomain namespace Subring variable {F : Type*} [Field F] {B : Subring F} private theorem exists_valuationSubring_dominating (𝔭 : Ideal B) [𝔭.IsPrime] : ∃ O : ValuationSubring F, B ≤ O.toSubring ∧ ∀ b : B, (b : F) ∈ O.nonunits ↔ b ∈ 𝔭 := by let L := Localization.AtPrime 𝔭 have hunit : ∀ y : 𝔭.primeCompl, IsUnit (B.subtype y) := by intro y refine isUnit_iff_ne_zero.mpr fun h => y.2 ?_ have : (y : B) = 0 := Subtype.ext h rw [this] exact 𝔭.zero_mem let f : L →+* F := IsLocalization.lift hunit have hf : ∀ b : B, f (algebraMap B L b) = b := fun b => IsLocalization.lift_eq hunit b obtain ⟨O, hO, hloc⟩ := IsLocalRing.exists_factor_valuationRing f refine ⟨O, fun b hb => ?_, fun b => ?_⟩ · have := hO (algebraMap B L ⟨b, hb⟩) rwa [hf] at this · let z : O := ⟨f (algebraMap B L b), hO _⟩ have hz : f.codRestrict O.toSubring hO (algebraMap B L b) = z := rfl have key : IsUnit z ↔ b ∉ 𝔭 := by rw [← hz, isUnit_map_iff (f.codRestrict O.toSubring hO), IsLocalization.AtPrime.isUnit_to_map_iff L 𝔭 b] rfl have hzF : (z : F) = b := hf b rw [← hzF, ValuationSubring.coe_mem_nonunits_iff, IsLocalRing.mem_maximalIdeal, mem_nonunits_iff, key, not_not] private theorem ne_top_of_dominating {𝔭 : Ideal B} {O : ValuationSubring F} (hdom : ∀ b : B, (b : F) ∈ O.nonunits ↔ b ∈ 𝔭) (h𝔭 : 𝔭 ≠ ⊥) : O ≠ ⊤ := by intro htop apply h𝔭 rw [eq_bot_iff] intro b hb have hn : (b : F) ∈ O.nonunits := (hdom b).mpr hb rcases (ValuationSubring.mem_nonunits_iff_or _).mp hn with h0 | hinv · exact (Ideal.mem_bot).mpr (Subtype.ext h0) · exact absurd (htop ▸ ValuationSubring.mem_top _) hinv private theorem algebraMap_mem_of_dominating {K : Type*} [Field K] [Algebra K F] (A : ValuationSubring K) (hconst : ∀ a : A, algebraMap K F a ∈ B) {𝔭 : Ideal B} {O : ValuationSubring F} (hle : B ≤ O.toSubring) (hdom : ∀ b : B, (b : F) ∈ O.nonunits ↔ b ∈ 𝔭) (hbot : ∀ a : A, (⟨algebraMap K F a, hconst a⟩ : B) ∈ 𝔭 → a = 0) (c : K) : algebraMap K F c ∈ O := by by_cases hc : c ∈ A · exact hle (hconst ⟨c, hc⟩) · have hcinv : c⁻¹ ∈ A := (A.mem_or_inv_mem c).resolve_left hc have hc0 : c ≠ 0 := fun h => hc (h ▸ A.zero_mem) have hnot : (⟨algebraMap K F (c⁻¹ : K), hconst ⟨c⁻¹, hcinv⟩⟩ : B) ∉ 𝔭 := fun h => inv_ne_zero hc0 (by simpa using congrArg Subtype.val (hbot ⟨c⁻¹, hcinv⟩ h)) have hnu : algebraMap K F c⁻¹ ∉ O.nonunits := fun h => hnot ((hdom _).mp h) rw [map_inv₀, ValuationSubring.inv_mem_nonunits_iff, not_or] at hnu exact not_not.mp hnu.2 end Subring namespace ValuationSubring variable {F : Type*} [Field F] variable {R : Type*} [CommRing R] [IsDedekindDomain R] [Algebra R F] [IsFractionRing R F] variable (O : ValuationSubring F) private def centreOver (hO : ∀ r : R, algebraMap R F r ∈ O) : Ideal R := (IsLocalRing.maximalIdeal O).comap ((algebraMap R F).codRestrict O.toSubring hO) private instance centreOver_isPrime (hO : ∀ r : R, algebraMap R F r ∈ O) : (O.centreOver hO).IsPrime := Ideal.comap_isPrime _ _ omit [IsDedekindDomain R] [IsFractionRing R F] in private theorem mem_centreOver_iff (hO : ∀ r : R, algebraMap R F r ∈ O) {r : R} : r ∈ O.centreOver hO ↔ algebraMap R F r ∈ O.nonunits := by rw [centreOver, Ideal.mem_comap, ← ValuationSubring.coe_mem_nonunits_iff] rfl omit [IsDedekindDomain R] [IsFractionRing R F] in private theorem inv_algebraMap_mem (hO : ∀ r : R, algebraMap R F r ∈ O) {s : R} (hs : s ∉ O.centreOver hO) : (algebraMap R F s)⁻¹ ∈ O := by rw [mem_centreOver_iff, ValuationSubring.mem_nonunits_iff, not_lt] at hs have hy : O.valuation (algebraMap R F s) ≤ 1 := (O.valuation_le_one_iff _).mpr (hO s) have h1 : O.valuation (algebraMap R F s) = 1 := le_antisymm hy hs apply (O.valuation_le_one_iff _).mp rw [map_inv₀, h1, inv_one] private theorem centreOver_ne_bot (hO : ∀ r : R, algebraMap R F r ∈ O) (hne : O ≠ ⊤) : O.centreOver hO ≠ ⊥ := by intro hbot apply hne refine SetLike.ext fun x => ⟨fun _ => ValuationSubring.mem_top x, fun _ => ?_⟩ obtain ⟨a, b, hb, rfl⟩ := IsFractionRing.div_surjective (A := R) x rw [div_eq_mul_inv] refine O.mul_mem _ _ (hO a) (O.inv_algebraMap_mem hO fun hmem => ?_) rw [hbot, Ideal.mem_bot] at hmem exact nonZeroDivisors.ne_zero hb hmem private def centreHeightOneSpectrum (hO : ∀ r : R, algebraMap R F r ∈ O) (hne : O ≠ ⊤) : HeightOneSpectrum R := ⟨O.centreOver hO, inferInstance, O.centreOver_ne_bot hO hne⟩ private theorem valuationSubringAtPrime_centre_le (hO : ∀ r : R, algebraMap R F r ∈ O) (hne : O ≠ ⊤) : HeightOneSpectrum.valuationSubringAtPrime F (O.centreHeightOneSpectrum hO hne) ≤ O := by rintro x ⟨a, s, hs, rfl⟩ exact O.mul_mem _ _ (hO a) (O.inv_algebraMap_mem hO hs) private theorem eq_valuationSubringAtPrime_centre (hO : ∀ r : R, algebraMap R F r ∈ O) (hne : O ≠ ⊤) : O = HeightOneSpectrum.valuationSubringAtPrime F (O.centreHeightOneSpectrum hO hne) := (ValuationSubring.eq_of_le_of_ne_top _ (O.valuationSubringAtPrime_centre_le hO hne) hne).symm private theorem isPrincipalIdealRing_of_dedekind_le (hO : ∀ r : R, algebraMap R F r ∈ O) (hne : O ≠ ⊤) : IsPrincipalIdealRing O := by rw [O.eq_valuationSubringAtPrime_centre hO hne] infer_instance end ValuationSubring namespace AlgebraicCurve namespace Place variable {K F : Type*} [Field K] [Field F] [Algebra K F] variable {R : Type*} [CommRing R] [IsDedekindDomain R] [Algebra R F] [IsFractionRing R F] private def ofValuationSubringOver (O : ValuationSubring F) (hO : ∀ r : R, algebraMap R F r ∈ O) (hne : O ≠ ⊤) (hK : ∀ c : K, algebraMap K F c ∈ O) : Place K F where toValuationSubring := O algebraMap_mem' := hK ne_top' := hne isPrincipalIdealRing' := O.isPrincipalIdealRing_of_dedekind_le hO hne @[simp] private theorem ofValuationSubringOver_toValuationSubring (O : ValuationSubring F) (hO : ∀ r : R, algebraMap R F r ∈ O) (hne : O ≠ ⊤) (hK : ∀ c : K, algebraMap K F c ∈ O) : (ofValuationSubringOver O hO hne hK).toValuationSubring = O := rfl private theorem mem_nonunits_ofValuationSubringOver_iff (O : ValuationSubring F) (hO : ∀ r : R, algebraMap R F r ∈ O) (hne : O ≠ ⊤) (hK : ∀ c : K, algebraMap K F c ∈ O) {B : Subring F} {𝔭 : Ideal B} (hdom : ∀ b : B, (b : F) ∈ O.nonunits ↔ b ∈ 𝔭) (b : B) : (b : F) ∈ (ofValuationSubringOver O hO hne hK).toValuationSubring.nonunits ↔ b ∈ 𝔭 := hdom b end Place end AlgebraicCurve set_option autoImplicit false open IsLocalRing Polynomial namespace Valuation variable {R Γ₀ : Type*} [CommRing R] [LinearOrderedCommGroupWithZero Γ₀] private theorem exists_ne_map_eq_of_sum_eq_zero {ι : Type*} [DecidableEq ι] (v : Valuation R Γ₀) {s : Finset ι} {f : ι → R} (hs : ∑ i ∈ s, f i = 0) {j : ι} (hj : j ∈ s) (hj0 : v (f j) ≠ 0) (hmax : ∀ i ∈ s, v (f i) ≤ v (f j)) : ∃ i ∈ s, i ≠ j ∧ v (f i) = v (f j) := by by_contra h push Not at h have hlt : ∀ i ∈ s \ {j}, v (f i) < v (f j) := by intro i hi rw [Finset.mem_sdiff, Finset.mem_singleton] at hi exact lt_of_le_of_ne (hmax i hi.1) (h i hi.1 hi.2) have := v.map_sum_eq_of_lt hj hlt rw [hs, map_zero] at this exact hj0 this.symm end Valuation namespace ValuationSubring variable {K : Type*} [Field K] (A : ValuationSubring K) variable {k : Type*} [Field k] private theorem natCast_mem_ker (ℓ : ℕ) [CharP k ℓ] (red : A →+* k) : ((ℓ : ℕ) : A) ∈ RingHom.ker red := by rw [RingHom.mem_ker, map_natCast, CharP.cast_eq_zero] private theorem natCast_mem_maximalIdeal (ℓ : ℕ) [CharP k ℓ] (red : A →+* k) : ((ℓ : ℕ) : A) ∈ maximalIdeal A := IsLocalRing.le_maximalIdeal (RingHom.ker_ne_top red) (A.natCast_mem_ker ℓ red) private theorem isUnit_intCast_of_not_dvd (ℓ : ℕ) [Fact ℓ.Prime] [CharP k ℓ] (red : A →+* k) {m : ℤ} (hm : ¬ (ℓ : ℤ) ∣ m) : IsUnit ((m : ℤ) : A) := by have hprime : Prime (ℓ : ℤ) := Nat.prime_iff_prime_int.mp Fact.out obtain ⟨a, b, hab⟩ := (Irreducible.coprime_iff_not_dvd hprime.irreducible).mpr hm have hA : (a : A) * ((ℓ : ℕ) : A) + (b : A) * (m : A) = 1 := by have := congrArg (Int.cast : ℤ → A) hab push_cast at this exact this have hℓm : (a : A) * ((ℓ : ℕ) : A) ∈ maximalIdeal A := Ideal.mul_mem_left _ _ (A.natCast_mem_maximalIdeal ℓ red) have hu : IsUnit ((b : A) * (m : A)) := by by_contra hnu have hmem : (b : A) * (m : A) ∈ maximalIdeal A := (IsLocalRing.mem_maximalIdeal _).mpr hnu have h1 : (1 : A) ∈ maximalIdeal A := hA ▸ Ideal.add_mem _ hℓm hmem exact (IsLocalRing.maximalIdeal.isMaximal A).ne_top (Ideal.eq_top_of_isUnit_mem _ h1 isUnit_one) exact isUnit_of_mul_isUnit_right hu private theorem map_intCast_eq_zero_of_not_isUnit (ℓ : ℕ) [Fact ℓ.Prime] [CharP k ℓ] (red : A →+* k) {m : ℤ} (hm : ¬ IsUnit ((m : ℤ) : A)) : red (m : A) = 0 := by have hdvd : (ℓ : ℤ) ∣ m := by by_contra h exact hm (A.isUnit_intCast_of_not_dvd ℓ red h) obtain ⟨c, rfl⟩ := hdvd rw [map_intCast] push_cast rw [CharP.cast_eq_zero k ℓ, zero_mul] private theorem map_eq_zero_of_rat_mem_maximalIdeal (ℓ : ℕ) [Fact ℓ.Prime] [CharP k ℓ] (red : A →+* k) (φ : ℚ →+* K) (r : ℚ) (hrA : φ r ∈ A) (hr : (⟨φ r, hrA⟩ : A) ∈ maximalIdeal A) : red ⟨φ r, hrA⟩ = 0 := by have hnum : (⟨φ r, hrA⟩ : A) * ((r.den : ℕ) : A) = ((r.num : ℤ) : A) := by apply Subtype.ext change φ r * (((r.den : ℕ) : A) : K) = (((r.num : ℤ) : A) : K) push_cast rw [← map_natCast φ, ← map_intCast φ, ← map_mul, Rat.mul_den_eq_num] have hnum_mem : ((r.num : ℤ) : A) ∈ maximalIdeal A := hnum ▸ Ideal.mul_mem_right _ _ hr have hnum0 : red ((r.num : ℤ) : A) = 0 := A.map_intCast_eq_zero_of_not_isUnit ℓ red ((IsLocalRing.mem_maximalIdeal _).mp hnum_mem) have hden : ¬ (ℓ : ℤ) ∣ (r.den : ℤ) := by intro h have hℓnum : (ℓ : ℤ) ∣ r.num := by by_contra h' have hu : IsUnit ((r.num : ℤ) : A) := A.isUnit_intCast_of_not_dvd ℓ red h' exact (IsLocalRing.mem_maximalIdeal _).mp hnum_mem hu have h1 : (ℓ : ℤ) ∣ (Int.gcd r.num (r.den : ℤ) : ℤ) := Int.dvd_coe_gcd hℓnum h have hg : Int.gcd r.num (r.den : ℤ) = 1 := by simpa [Int.gcd, Int.natAbs_natCast] using r.reduced rw [hg] at h1 have := Int.eq_one_of_dvd_one (by positivity) h1 have hℓ1 : ℓ = 1 := by exact_mod_cast this exact (Fact.out : ℓ.Prime).one_lt.ne' hℓ1 have hden0 : red ((r.den : ℕ) : A) ≠ 0 := by rw [map_natCast] intro h0 rw [CharP.cast_eq_zero_iff k ℓ] at h0 exact hden (by exact_mod_cast h0) have := congrArg red hnum rw [map_mul, hnum0] at this exact (mul_eq_zero.mp this).resolve_right hden0 private theorem exists_pow_valuation_eq_of_isRoot (φ : ℚ →+* K) {x : K} (hx0 : x ≠ 0) {p : ℚ[X]} (hp0 : p ≠ 0) (hpx : p.eval₂ φ x = 0) : ∃ n : ℕ, 0 < n ∧ ∃ r : ℚ, r ≠ 0 ∧ A.valuation (x ^ n) = A.valuation (φ r) := by classical set v := A.valuation with hv let f : ℕ → K := fun i => φ (p.coeff i) * x ^ i have hsum : ∑ i ∈ p.support, f i = 0 := by rw [eval₂_eq_sum, Polynomial.sum_def] at hpx exact hpx have hvx : v x ≠ 0 := (v.ne_zero_iff).mpr hx0 have hf0 : ∀ i ∈ p.support, v (f i) ≠ 0 := by intro i hi refine (v.ne_zero_iff).mpr (mul_ne_zero ?_ (pow_ne_zero _ hx0)) exact (map_ne_zero φ).mpr (mem_support_iff.mp hi) obtain ⟨j, hj, hjmax⟩ := Finset.exists_max_image p.support (fun i => v (f i)) (support_nonempty.mpr hp0) obtain ⟨i, hi, hij, heq⟩ := v.exists_ne_map_eq_of_sum_eq_zero hsum hj (hf0 j hj) hjmax obtain ⟨a, b, hab, ha, hb, heq'⟩ : ∃ a b : ℕ, a < b ∧ a ∈ p.support ∧ b ∈ p.support ∧ v (f a) = v (f b) := by rcases lt_or_gt_of_ne hij with h | h · exact ⟨i, j, h, hi, hj, heq⟩ · exact ⟨j, i, h, hj, hi, heq.symm⟩ have hca0 : v (φ (p.coeff a)) ≠ 0 := (v.ne_zero_iff).mpr ((map_ne_zero φ).mpr (mem_support_iff.mp ha)) have hcb0 : v (φ (p.coeff b)) ≠ 0 := (v.ne_zero_iff).mpr ((map_ne_zero φ).mpr (mem_support_iff.mp hb)) have h1 : v (φ (p.coeff a)) * v x ^ a = (v (φ (p.coeff b)) * v x ^ (b - a)) * v x ^ a := by have e : v x ^ b = v x ^ (b - a) * v x ^ a := by rw [← pow_add, Nat.sub_add_cancel hab.le] have := heq' simp only [f, map_mul, map_pow] at this rw [this, e, ← mul_assoc] have h2 : v (φ (p.coeff a)) = v (φ (p.coeff b)) * v x ^ (b - a) := mul_right_cancel₀ (pow_ne_zero _ hvx) h1 refine ⟨b - a, Nat.sub_pos_of_lt hab, p.coeff a / p.coeff b, div_ne_zero (mem_support_iff.mp ha) (mem_support_iff.mp hb), ?_⟩ rw [map_div₀, map_div₀, map_pow, h2, mul_div_cancel_left₀ _ hcb0] private theorem ker_eq_maximalIdeal_of_isAlgebraic [Algebra ℚ K] [Algebra.IsAlgebraic ℚ K] (ℓ : ℕ) [Fact ℓ.Prime] [CharP k ℓ] (red : A →+* k) : RingHom.ker red = maximalIdeal A := by refine le_antisymm (IsLocalRing.le_maximalIdeal (RingHom.ker_ne_top red)) ?_ intro x hx rw [RingHom.mem_ker] rcases eq_or_ne x 0 with rfl | hx0 · exact map_zero red have hxK : (x : K) ≠ 0 := by simpa [ne_eq, ZeroMemClass.coe_eq_zero] using hx0 obtain ⟨p, hp0, hpx⟩ := Algebra.IsAlgebraic.isAlgebraic (R := ℚ) (x : K) obtain ⟨n, hn, r, hr0, hval⟩ := A.exists_pow_valuation_eq_of_isRoot (algebraMap ℚ K) hxK hp0 (by rwa [← aeval_def]) obtain ⟨u, hu⟩ := (A.valuation_eq_iff _ _).mp hval have hcoe : ((((u⁻¹ : Aˣ) : A) * x ^ n : A) : K) = algebraMap ℚ K r := by push_cast rw [← hu, ← mul_assoc, ← MulMemClass.coe_mul, Units.inv_mul, OneMemClass.coe_one, one_mul] have hrA : algebraMap ℚ K r ∈ A := hcoe ▸ SetLike.coe_mem _ have hxn : x ^ n = (u : A) * ⟨algebraMap ℚ K r, hrA⟩ := by apply Subtype.ext push_cast exact hu.symm have hrm : (⟨algebraMap ℚ K r, hrA⟩ : A) ∈ maximalIdeal A := by have hxnm : x ^ n ∈ maximalIdeal A := Ideal.pow_mem_of_mem _ hx n hn rw [hxn] at hxnm exact ((IsLocalRing.maximalIdeal.isMaximal A).isPrime.mem_or_mem hxnm).resolve_left (fun h => (IsLocalRing.mem_maximalIdeal _).mp h u.isUnit) have hr0' : red ⟨algebraMap ℚ K r, hrA⟩ = 0 := A.map_eq_zero_of_rat_mem_maximalIdeal ℓ red (algebraMap ℚ K) r hrA hrm have : red (x ^ n) = 0 := by rw [hxn, map_mul, hr0', mul_zero] rw [map_pow] at this exact pow_eq_zero_iff hn.ne' |>.mp this private theorem exists_mul_eq_one_of_map_ne_zero [Algebra ℚ K] [Algebra.IsAlgebraic ℚ K] (ℓ : ℕ) [Fact ℓ.Prime] [CharP k ℓ] (red : A →+* k) {a : A} (ha : red a ≠ 0) : ∃ b : A, red a * red b = 1 := by have hunit : IsUnit a := by by_contra h have : a ∈ RingHom.ker red := by rw [A.ker_eq_maximalIdeal_of_isAlgebraic ℓ red] exact (IsLocalRing.mem_maximalIdeal _).mpr h exact ha this obtain ⟨u, rfl⟩ := hunit exact ⟨((u⁻¹ : Aˣ) : A), by rw [← map_mul, Units.mul_inv, map_one]⟩ private theorem ker_eq_maximalIdeal_apply [Algebra ℚ K] [Algebra.IsAlgebraic ℚ K] (ℓ : ℕ) [Fact ℓ.Prime] [CharP k ℓ] (red : A →+* k) (a : A) : red a = 0 ↔ a ∈ maximalIdeal A := by rw [← RingHom.mem_ker, A.ker_eq_maximalIdeal_of_isAlgebraic ℓ red] end ValuationSubring set_option autoImplicit false noncomputable section open scoped IntermediateField.algebraAdjoinAdjoin open IntermediateField Polynomial namespace AlgebraicCurve variable {K F : Type*} [Field K] [Field F] [Algebra K F] {j : F} private theorem isPrincipalIdealRing_adjoin_singleton (hj : Transcendental K j) : IsPrincipalIdealRing (Algebra.adjoin K ({j} : Set F)) := IsPrincipalIdealRing.of_surjective (Polynomial.algEquivOfTranscendental K j hj).toRingHom (Polynomial.algEquivOfTranscendental K j hj).surjective private theorem isDedekindDomain_adjoin_singleton (hj : Transcendental K j) : IsDedekindDomain (Algebra.adjoin K ({j} : Set F)) := haveI := isPrincipalIdealRing_adjoin_singleton hj inferInstance private theorem isDedekindDomain_integralClosure_adjoin (hj : Transcendental K j) [FiniteDimensional K⟮j⟯ F] [Algebra.IsSeparable K⟮j⟯ F] : IsDedekindDomain (integralClosure (Algebra.adjoin K ({j} : Set F)) F) := haveI := isDedekindDomain_adjoin_singleton hj integralClosure.isDedekindDomain (Algebra.adjoin K ({j} : Set F)) K⟮j⟯ F private theorem isFractionRing_integralClosure_adjoin (hj : Transcendental K j) [FiniteDimensional K⟮j⟯ F] : IsFractionRing (integralClosure (Algebra.adjoin K ({j} : Set F)) F) F := haveI := isDedekindDomain_adjoin_singleton hj integralClosure.isFractionRing_of_finite_extension (A := Algebra.adjoin K ({j} : Set F)) K⟮j⟯ F private theorem integralClosure_adjoin_le_valuationSubring (O : ValuationSubring F) (hK : ∀ c : K, algebraMap K F c ∈ O) (hjO : j ∈ O) (r : integralClosure (Algebra.adjoin K ({j} : Set F)) F) : (r : F) ∈ O := by let O' : Subalgebra K F := { O.toSubring with algebraMap_mem' := hK } have hle : Algebra.adjoin K ({j} : Set F) ≤ O' := Algebra.adjoin_le (Set.singleton_subset_iff.mpr hjO) let φ : Algebra.adjoin K ({j} : Set F) →+* O := (Subalgebra.val _).toRingHom.codRestrict O.toSubring (fun y => hle y.2) obtain ⟨p, hp, hpr⟩ : IsIntegral (Algebra.adjoin K ({j} : Set F)) (r : F) := r.2 have hint : IsIntegral O (r : F) := by refine ⟨p.map φ, hp.map φ, ?_⟩ rw [eval₂_map] exact hpr obtain ⟨y, hy⟩ := IsIntegrallyClosed.isIntegral_iff.mp hint rw [← hy] exact y.2 private theorem algebraMap_mem_integralClosure_adjoin (c : K) : algebraMap K F c ∈ integralClosure (Algebra.adjoin K ({j} : Set F)) F := by rw [mem_integralClosure_iff, IsScalarTower.algebraMap_apply K (Algebra.adjoin K ({j} : Set F)) F] exact isIntegral_algebraMap private theorem self_mem_integralClosure_adjoin : j ∈ integralClosure (Algebra.adjoin K ({j} : Set F)) F := by rw [mem_integralClosure_iff] have : j = algebraMap (Algebra.adjoin K ({j} : Set F)) F ⟨j, Algebra.self_mem_adjoin_singleton K j⟩ := rfl rw [this] exact isIntegral_algebraMap private theorem le_integralClosure_adjoin_of_isIntegral {S B : Subring F} (hS : S ≤ (Algebra.adjoin K ({j} : Set F)).toSubring) (hint : ∀ b : B, IsIntegral S (b : F)) (b : B) : (b : F) ∈ integralClosure (Algebra.adjoin K ({j} : Set F)) F := by rw [mem_integralClosure_iff] obtain ⟨p, hp, hpb⟩ := hint b let φ : S →+* Algebra.adjoin K ({j} : Set F) := S.subtype.codRestrict (Algebra.adjoin K ({j} : Set F)).toSubring (fun y => hS y.2) refine ⟨p.map φ, hp.map φ, ?_⟩ rw [eval₂_map] exact hpb end AlgebraicCurve set_option autoImplicit false open Polynomial namespace ValuationSubring variable {K : Type*} [Field K] (A : ValuationSubring K) {k : Type*} [Field k] private theorem isAlgClosed_of_surjective [IsAlgClosed K] (red : A →+* k) (hred : Function.Surjective red) : IsAlgClosed k := by refine IsAlgClosed.of_exists_root k fun p hp hirr => ?_ have hlifts : p ∈ Polynomial.lifts red := (lifts_iff_coeff_lifts p).mpr fun n => hred _ obtain ⟨P, hPp, hPdeg, hP⟩ := lifts_and_degree_eq_and_monic hlifts hp have hdegK : (P.map (algebraMap A K)).degree ≠ 0 := by rw [hP.degree_map, hPdeg] exact (degree_pos_of_irreducible hirr).ne' obtain ⟨x, hx⟩ := IsAlgClosed.exists_root (P.map (algebraMap A K)) hdegK have hint : IsIntegral A x := ⟨P, hP, by rwa [IsRoot.def, eval_map] at hx⟩ obtain ⟨y, rfl⟩ := IsIntegrallyClosed.isIntegral_iff.mp hint have hy : P.eval y = 0 := by apply IsFractionRing.injective A K rw [map_zero, ← Polynomial.eval₂_at_apply, ← eval_map] exact hx refine ⟨red y, ?_⟩ rw [← hPp, eval_map, Polynomial.eval₂_at_apply, hy, map_zero] end ValuationSubring set_option autoImplicit false namespace RingHom variable {B C : Type*} [CommRing B] [CommRing C] (π : B →+* C) private def imagePrime (𝔮 : Ideal B) : Ideal π.range := 𝔮.map π.rangeRestrict variable {π} in private theorem rangeRestrict_mem_imagePrime_iff {𝔮 : Ideal B} (hker : ker π ≤ 𝔮) (b : B) : π.rangeRestrict b ∈ π.imagePrime 𝔮 ↔ b ∈ 𝔮 := by rw [imagePrime, ← Ideal.mem_comap, Ideal.comap_map_of_surjective _ π.rangeRestrict_surjective, ← RingHom.ker, ker_rangeRestrict, sup_eq_left.mpr hker] variable {π} in private theorem mk_mem_imagePrime_iff {𝔮 : Ideal B} (hker : ker π ≤ 𝔮) (b : B) (hb : π b ∈ π.range := π.mem_range_self b) : (⟨π b, hb⟩ : π.range) ∈ π.imagePrime 𝔮 ↔ b ∈ 𝔮 := rangeRestrict_mem_imagePrime_iff hker b variable {π} in private theorem mem_imagePrime_iff {𝔮 : Ideal B} (y : π.range) : y ∈ π.imagePrime 𝔮 ↔ ∃ b ∈ 𝔮, π.rangeRestrict b = y := by rw [imagePrime, Ideal.mem_map_iff_of_surjective _ π.rangeRestrict_surjective] variable {π} in private theorem imagePrime_ne_top {𝔮 : Ideal B} (hker : ker π ≤ 𝔮) (h𝔮 : 𝔮 ≠ ⊤) : π.imagePrime 𝔮 ≠ ⊤ := by intro htop apply h𝔮 rw [Ideal.eq_top_iff_one, ← rangeRestrict_mem_imagePrime_iff hker, map_one, htop] exact Submodule.mem_top variable {π} in private theorem imagePrime_isPrime {𝔮 : Ideal B} [𝔮.IsPrime] (hker : ker π ≤ 𝔮) : (π.imagePrime 𝔮).IsPrime := Ideal.map_isPrime_of_surjective π.rangeRestrict_surjective (by rwa [ker_rangeRestrict]) variable {π} in private theorem imagePrime_isMaximal {𝔮 : Ideal B} [h : 𝔮.IsMaximal] (hker : ker π ≤ 𝔮) : (π.imagePrime 𝔮).IsMaximal := (Ideal.map_eq_top_or_isMaximal_of_surjective _ π.rangeRestrict_surjective h).resolve_left (imagePrime_ne_top hker h.ne_top) variable {π} in private theorem eq_zero_of_const_mem_imagePrime {A k : Type*} [CommRing A] [CommRing k] (σ : A →+* B) (red : A →+* k) (ι : k →+* C) (hcompat : ∀ a : A, π (σ a) = ι (red a)) (hred : Function.Surjective red) {𝔮 : Ideal B} (hker : ker π ≤ 𝔮) (h𝔮 : ∀ a : A, σ a ∈ 𝔮 → red a = 0) (c : k) (hc : ι c ∈ π.range) (hmem : (⟨ι c, hc⟩ : π.range) ∈ π.imagePrime 𝔮) : c = 0 := by obtain ⟨a, rfl⟩ := hred c refine h𝔮 a ((rangeRestrict_mem_imagePrime_iff hker (σ a)).mp ?_) convert hmem using 1 exact Subtype.ext (hcompat a) variable {π} in private theorem const_mem_range {A k : Type*} [CommRing A] [CommRing k] (σ : A →+* B) (red : A →+* k) (ι : k →+* C) (hcompat : ∀ a : A, π (σ a) = ι (red a)) (hred : Function.Surjective red) (c : k) : ι c ∈ π.range := by obtain ⟨a, rfl⟩ := hred c exact ⟨σ a, hcompat a⟩ end RingHom namespace AlgebraicCurve namespace Place variable {K F : Type*} [Field K] [Field F] [Algebra K F] private theorem eq_zero_of_X_sub_C_dvd_C {R : Type*} [CommRing R] {a₀ a : R} (h : (Polynomial.X - Polynomial.C a₀) ∣ Polynomial.C a) : a = 0 := by obtain ⟨g, hg⟩ := h have := congrArg (Polynomial.eval a₀) hg simpa using this private theorem exists_place_centre_comap_eq [IsAlgClosed K] (A : ValuationSubring K) {j : F} (hj : Transcendental K j) [FiniteDimensional K⟮j⟯ F] [Algebra.IsSeparable K⟮j⟯ F] {B : Subring F} (hconst : ∀ a : A, algebraMap K F a ∈ B) (hjB : j ∈ B) (hint : ∀ b : B, IsIntegral (Subring.closure (Set.range ((algebraMap K F).comp A.subtype) ∪ {j})) (b : F)) (𝔮 : Ideal B) [𝔮.IsPrime] (h𝔮A : ∀ a : A, (⟨algebraMap K F a, hconst a⟩ : B) ∈ 𝔮 ↔ a ∈ IsLocalRing.maximalIdeal A) (a₀ : A) (hja : (⟨j, hjB⟩ : B) - ⟨algebraMap K F a₀, hconst a₀⟩ ∈ 𝔮) : ∃ (w : Place K F) (hB : B ≤ w.compSubring A), (w.centre A).comap (Subring.inclusion hB) = 𝔮 ∧ w.HasValueAt j a₀ := by classical set S : Subring F := Subring.closure (Set.range ((algebraMap K F).comp A.subtype) ∪ {j}) with hSdef have hSB : S ≤ B := by rw [hSdef, Subring.closure_le] rintro y (⟨a, rfl⟩ | rfl) exacts [hconst a, hjB] haveI : IsIntegrallyClosed S := A.isIntegrallyClosed_closure hj have hjS : j ∈ S := Subring.subset_closure (Or.inr rfl) have hcS : ∀ a : A, algebraMap K F a ∈ S := fun a => Subring.subset_closure (Or.inl ⟨a, rfl⟩) let e := A.polynomialEquivClosure hj have heX : (e Polynomial.X : F) = j := by rw [ValuationSubring.polynomialEquivClosure_apply, Polynomial.aeval_X] have heC : ∀ a : A, (e (Polynomial.C a) : F) = algebraMap K F a := fun a => by rw [ValuationSubring.polynomialEquivClosure_apply, Polynomial.aeval_C] rfl have hegen : e (Polynomial.X - Polynomial.C a₀) = ⟨j, hjS⟩ - ⟨algebraMap K F a₀, hcS a₀⟩ := by apply Subtype.ext rw [map_sub] push_cast rw [heX, heC] let p₀ : Ideal (Polynomial A) := Ideal.span {Polynomial.X - Polynomial.C a₀} haveI hp₀ : p₀.IsPrime := by rw [← Ideal.Quotient.isDomain_iff_prime] exact (Polynomial.quotientSpanXSubCAlgEquiv a₀).toMulEquiv.isDomain_iff.mpr inferInstance let p : Ideal S := p₀.map e.toRingHom haveI hp : p.IsPrime := Ideal.map_isPrime_of_equiv e have hp_span : p = Ideal.span {(⟨j, hjS⟩ : S) - ⟨algebraMap K F a₀, hcS a₀⟩} := by change Ideal.map e.toRingHom (Ideal.span _) = _ rw [Ideal.map_span, Set.image_singleton] exact congrArg (fun y => Ideal.span {y}) hegen let q : Ideal S := 𝔮.comap (Subring.inclusion hSB) have hpq : p ≤ q := by rw [hp_span, Ideal.span_le, Set.singleton_subset_iff] change Subring.inclusion hSB (⟨j, hjS⟩ - ⟨algebraMap K F a₀, hcS a₀⟩) ∈ 𝔮 rw [map_sub] exact hja obtain ⟨𝔭, h𝔭𝔮, h𝔭, h𝔭p⟩ := Subring.exists_ideal_le_comap_eq_of_isIntegral hSB hint hpq 𝔮 rfl haveI := h𝔭 have hj𝔭 : (⟨j, hjB⟩ : B) - ⟨algebraMap K F a₀, hconst a₀⟩ ∈ 𝔭 := by have : (⟨j, hjS⟩ : S) - ⟨algebraMap K F a₀, hcS a₀⟩ ∈ 𝔭.comap (Subring.inclusion hSB) := by rw [h𝔭p, hp_span] exact Ideal.subset_span rfl rw [Ideal.mem_comap, map_sub] at this exact this have hbot : ∀ a : A, (⟨algebraMap K F a, hconst a⟩ : B) ∈ 𝔭 → a = 0 := by intro a ha have h1 : (⟨algebraMap K F a, hcS a⟩ : S) ∈ 𝔭.comap (Subring.inclusion hSB) := by rw [Ideal.mem_comap] exact ha rw [h𝔭p, hp_span, Ideal.mem_span_singleton'] at h1 obtain ⟨g, hg⟩ := h1 have h3 : e (Polynomial.C a) = ⟨algebraMap K F a, hcS a⟩ := Subtype.ext (heC a) have h4 : e.symm g * (Polynomial.X - Polynomial.C a₀) = Polynomial.C a := by apply e.injective rw [map_mul, e.apply_symm_apply, hegen, h3, hg] exact eq_zero_of_X_sub_C_dvd_C ⟨e.symm g, by rw [mul_comm]; exact h4.symm⟩ have hj_ne : j - algebraMap K F a₀ ≠ 0 := by intro h apply hj rw [sub_eq_zero] at h rw [h] exact isAlgebraic_algebraMap (a₀ : K) have h𝔭ne : 𝔭 ≠ ⊥ := by intro h rw [h, Ideal.mem_bot] at hj𝔭 exact hj_ne (by simpa using congrArg Subtype.val hj𝔭) obtain ⟨O, hle, hdom⟩ := Subring.exists_valuationSubring_dominating 𝔭 have hne : O ≠ ⊤ := Subring.ne_top_of_dominating hdom h𝔭ne have hK : ∀ c : K, algebraMap K F c ∈ O := Subring.algebraMap_mem_of_dominating A hconst hle hdom hbot let R := integralClosure (Algebra.adjoin K ({j} : Set F)) F haveI : IsDedekindDomain R := isDedekindDomain_integralClosure_adjoin hj haveI : IsFractionRing R F := isFractionRing_integralClosure_adjoin hj have hO : ∀ r : R, algebraMap R F r ∈ O := fun r => integralClosure_adjoin_le_valuationSubring O hK (hle hjB) r let w : Place K F := Place.ofValuationSubringOver O hO hne hK have hval : w.HasValueAt j a₀ := by have := (hdom (⟨j, hjB⟩ - ⟨algebraMap K F a₀, hconst a₀⟩)).mpr hj𝔭 simp at this exact this have hS_le : S ≤ w.compSubring A := by rw [hSdef, Subring.closure_le] rintro y (⟨a, rfl⟩ | rfl) · exact (w.algebraMap_mem_compSubring_iff A _).mpr a.2 · exact w.mem_compSubring_of_hasValueAt a₀.2 hval have hB : B ≤ w.compSubring A := fun b hb => w.mem_compSubring_of_isIntegral' A hS_le (hint ⟨b, hb⟩) refine ⟨w, hB, ?_, hval⟩ have h𝔭𝔓 : 𝔭 ≤ (w.centre A).comap (Subring.inclusion hB) := fun x hx => w.mem_centre_of_mem_nonunits ((hdom x).mpr hx) ext b obtain ⟨a, hab⟩ := ValuationSubring.exists_sub_constants_mem hconst hjB hint 𝔭 hbot a₀ hj𝔭 b have hab' : b - ⟨algebraMap K F a, hconst a⟩ ∈ 𝔭 := hab have key : ∀ (I : Ideal B), 𝔭 ≤ I → (b ∈ I ↔ (⟨algebraMap K F a, hconst a⟩ : B) ∈ I) := by intro I hI constructor · intro hb have := I.sub_mem hb (hI hab') rwa [sub_sub_cancel] at this · intro ha have := I.add_mem (hI hab') ha rwa [sub_add_cancel] at this rw [key _ h𝔭𝔓, key _ h𝔭𝔮, w.algebraMap_mem_centre_comap_iff hB hconst, h𝔮A] end Place end AlgebraicCurve namespace AlgebraicCurve namespace Place variable {K E : Type*} [Field K] [Field E] [Algebra K E] private theorem finite_residueField_of_adjoin_simple_eq_top_of_mem {x : E} (hx : Transcendental K x) (htop : IntermediateField.adjoin K ({x} : Set E) = ⊤) (v : Place K E) (hxv : x ∈ v.toValuationSubring) : Module.Finite K v.ResidueField := by classical haveI : IsDedekindDomain (Algebra.adjoin K ({x} : Set E)) := isDedekindDomain_adjoin_singleton hx haveI : FaithfulSMul (Algebra.adjoin K ({x} : Set E)) E := (faithfulSMul_iff_algebraMap_injective _ E).mpr Subtype.val_injective haveI : IsFractionRing (Algebra.adjoin K ({x} : Set E)) E := by refine IsFractionRing.of_field (Algebra.adjoin K ({x} : Set E)) E (fun z => ?_) have hz : z ∈ IntermediateField.adjoin K ({x} : Set E) := by rw [htop] exact IntermediateField.mem_top obtain ⟨r, hr, s, hs, rfl⟩ := IntermediateField.mem_adjoin_iff_div.mp hz exact ⟨⟨r, hr⟩, ⟨s, hs⟩, rfl⟩ set O := v.toValuationSubring with hOdef have hO : ∀ r : Algebra.adjoin K ({x} : Set E), algebraMap _ E r ∈ O := by intro r have hle : Algebra.adjoin K ({x} : Set E) ≤ { O.toSubring with algebraMap_mem' := v.algebraMap_mem' } := Algebra.adjoin_le (Set.singleton_subset_iff.mpr hxv) exact hle r.2 have hne : O ≠ ⊤ := v.ne_top' let xO : O := ⟨x, hxv⟩ let xbar : v.ResidueField := IsLocalRing.residue O xO have hcomp : (IsLocalRing.residue O).comp (algebraMap K O) = algebraMap K v.ResidueField := RingHom.ext fun _ => rfl have hres_aeval : ∀ p : K[X], IsLocalRing.residue O (Polynomial.aeval xO p) = Polynomial.aeval xbar p := fun p => by rw [Polynomial.aeval_def, Polynomial.aeval_def, Polynomial.hom_eval₂, hcomp] have hcoe_aeval : ∀ p : K[X], ((Polynomial.aeval xO p : O) : E) = Polynomial.aeval x p := fun p => by have := Polynomial.aeval_algHom_apply (IsScalarTower.toAlgHom K O E) xO p exact this.symm let e := Polynomial.algEquivOfTranscendental K x hx have hcoe_e : ∀ p : K[X], ((e p : Algebra.adjoin K ({x} : Set E)) : E) = Polynomial.aeval x p := fun p => by rw [Polynomial.algEquivOfTranscendental_apply, Polynomial.aeval_subalgebra_coe] have hOe : ∀ p : K[X], (⟨((e p : Algebra.adjoin K ({x} : Set E)) : E), hO (e p)⟩ : O) = Polynomial.aeval xO p := fun p => Subtype.ext (by rw [hcoe_aeval, hcoe_e]) obtain ⟨f, hf𝔭, hf0⟩ := Submodule.exists_mem_ne_zero_of_ne_bot (O.centreOver_ne_bot hO hne) obtain ⟨g, rfl⟩ := e.surjective f have hg0 : g ≠ 0 := fun h => hf0 (by rw [h, map_zero]) have hgbar : Polynomial.aeval xbar g = 0 := by rw [← hres_aeval, IsLocalRing.residue_eq_zero_iff, ← hOe, ← ValuationSubring.coe_mem_nonunits_iff] exact (O.mem_centreOver_iff hO).mp hf𝔭 have halg : IsAlgebraic K xbar := ⟨g, hg0, hgbar⟩ have hint : IsIntegral K xbar := halg.isIntegral haveI : FiniteDimensional K K⟮xbar⟯ := IntermediateField.adjoin.finiteDimensional hint have htop' : K⟮xbar⟯ = ⊤ := by rw [eq_top_iff] intro y _ obtain ⟨z, rfl⟩ := IsLocalRing.residue_surjective y have hz : (z : E) ∈ IsDedekindDomain.HeightOneSpectrum.valuationSubringAtPrime E (O.centreHeightOneSpectrum hO hne) := by rw [← O.eq_valuationSubringAtPrime_centre hO hne] exact z.2 obtain ⟨a, s, hs, hz'⟩ := hz obtain ⟨ga, rfl⟩ := e.surjective a obtain ⟨gs, rfl⟩ := e.surjective s have hsn : ((e gs : Algebra.adjoin K ({x} : Set E)) : E) ∉ O.nonunits := fun h => hs ((O.mem_centreOver_iff hO).mpr h) have hres_s : IsLocalRing.residue O (Polynomial.aeval xO gs) ≠ 0 := by rw [Ne, IsLocalRing.residue_eq_zero_iff, ← hOe, ← ValuationSubring.coe_mem_nonunits_iff] exact hsn have hs0 : ((e gs : Algebra.adjoin K ({x} : Set E)) : E) ≠ 0 := fun h => hsn (h ▸ (zero_mem O.nonunits)) have hmul : z * Polynomial.aeval xO gs = Polynomial.aeval xO ga := by rw [← hOe, ← hOe] apply Subtype.ext change (z : E) * _ = _ push_cast rw [hz'] exact inv_mul_cancel_right₀ hs0 _ have hzq : IsLocalRing.residue O z = Polynomial.aeval xbar ga / Polynomial.aeval xbar gs := by rw [eq_div_iff (by rwa [← hres_aeval]), ← hres_aeval, ← hres_aeval, ← map_mul, hmul] rw [hzq] refine div_mem ?_ ?_ <;> exact IntermediateField.algebra_adjoin_le_adjoin K _ (Polynomial.aeval_mem_adjoin_singleton K _) have : FiniteDimensional K (⊤ : IntermediateField K v.ResidueField) := by rw [← htop'] infer_instance exact IntermediateField.topEquiv.toLinearEquiv.finiteDimensional private theorem _root_.IntermediateField.adjoin_simple_inv_eq (x : E) : IntermediateField.adjoin K ({x⁻¹} : Set E) = IntermediateField.adjoin K ({x} : Set E) := by apply le_antisymm · rw [IntermediateField.adjoin_simple_le_iff] exact inv_mem (IntermediateField.mem_adjoin_simple_self K x) · rw [IntermediateField.adjoin_simple_le_iff] have h := inv_mem (IntermediateField.mem_adjoin_simple_self K x⁻¹) rwa [inv_inv] at h private theorem finite_residueField_of_adjoin_simple_eq_top {x : E} (hx : Transcendental K x) (htop : IntermediateField.adjoin K ({x} : Set E) = ⊤) (v : Place K E) : Module.Finite K v.ResidueField := by by_cases hxv : x ∈ v.toValuationSubring · exact finite_residueField_of_adjoin_simple_eq_top_of_mem hx htop v hxv · have hxinv : x⁻¹ ∈ v.toValuationSubring := (v.toValuationSubring.mem_or_inv_mem x).resolve_left hxv have hx' : Transcendental K x⁻¹ := fun h => hx (by simpa using h.inv) have htop' : IntermediateField.adjoin K ({x⁻¹} : Set E) = ⊤ := by rw [IntermediateField.adjoin_simple_inv_eq x, htop] exact finite_residueField_of_adjoin_simple_eq_top_of_mem hx' htop' v hxinv private theorem finiteResidue_of_adjoin_simple_eq_top {x : E} (hx : Transcendental K x) (htop : IntermediateField.adjoin K ({x} : Set E) = ⊤) (v : Place K E) : v.FiniteResidue := ⟨finite_residueField_of_adjoin_simple_eq_top hx htop v⟩ end Place end AlgebraicCurve namespace ValuationSubring variable {F : Type*} [Field F] variable {R : Type*} [CommRing R] [IsDedekindDomain R] [Algebra R F] [IsFractionRing R F] private theorem eq_of_forall_mem_nonunits_iff {O₁ O₂ : ValuationSubring F} (h₁ : ∀ r : R, algebraMap R F r ∈ O₁) (hne₁ : O₁ ≠ ⊤) (h₂ : ∀ r : R, algebraMap R F r ∈ O₂) (hne₂ : O₂ ≠ ⊤) (h : ∀ r : R, algebraMap R F r ∈ O₁.nonunits ↔ algebraMap R F r ∈ O₂.nonunits) : O₁ = O₂ := by have hc : O₁.centreHeightOneSpectrum h₁ hne₁ = O₂.centreHeightOneSpectrum h₂ hne₂ := by ext r change r ∈ O₁.centreOver h₁ ↔ r ∈ O₂.centreOver h₂ rw [mem_centreOver_iff, mem_centreOver_iff] exact h r rw [O₁.eq_valuationSubringAtPrime_centre h₁ hne₁, O₂.eq_valuationSubringAtPrime_centre h₂ hne₂, hc] end ValuationSubring namespace AlgebraicCurve namespace Place variable {K F : Type*} [Field K] [Field F] [Algebra K F] private theorem eq_of_forall_mem_nonunits_iff (R : Type*) [CommRing R] [IsDedekindDomain R] [Algebra R F] [IsFractionRing R F] {v₁ v₂ : Place K F} (h₁ : ∀ r : R, algebraMap R F r ∈ v₁.toValuationSubring) (h₂ : ∀ r : R, algebraMap R F r ∈ v₂.toValuationSubring) (h : ∀ r : R, algebraMap R F r ∈ v₁.toValuationSubring.nonunits ↔ algebraMap R F r ∈ v₂.toValuationSubring.nonunits) : v₁ = v₂ := Place.ext (ValuationSubring.eq_of_forall_mem_nonunits_iff h₁ v₁.ne_top' h₂ v₂.ne_top' h) private theorem eq_of_forall_mem_nonunits_iff_of_surjective (R : Type*) [CommRing R] [IsDedekindDomain R] [Algebra R F] [IsFractionRing R F] {v₁ v₂ : Place K F} (h₁ : ∀ r : R, algebraMap R F r ∈ v₁.toValuationSubring) (h₂ : ∀ r : R, algebraMap R F r ∈ v₂.toValuationSubring) {ι : Type*} (f : ι → F) (hsurj : ∀ r : R, ∃ i, f i = algebraMap R F r) (h : ∀ i, f i ∈ v₁.toValuationSubring.nonunits ↔ f i ∈ v₂.toValuationSubring.nonunits) : v₁ = v₂ := eq_of_forall_mem_nonunits_iff R h₁ h₂ fun r => by obtain ⟨i, hi⟩ := hsurj r rw [← hi] exact h i variable (K) in private theorem integralClosure_adjoin_le_of_forall_isIntegral_mem {j : F} {S : Subring F} (hK : ∀ c : K, algebraMap K F c ∈ S) (hj : j ∈ S) (hS : ∀ x : F, (∃ p : Polynomial S, p.Monic ∧ Polynomial.eval₂ S.subtype x p = 0) → x ∈ S) (r : integralClosure (Algebra.adjoin K ({j} : Set F)) F) : (r : F) ∈ S := by let S' : Subalgebra K F := { S with algebraMap_mem' := hK } have hle : Algebra.adjoin K ({j} : Set F) ≤ S' := Algebra.adjoin_le (Set.singleton_subset_iff.mpr hj) let φ : Algebra.adjoin K ({j} : Set F) →+* S := (Subalgebra.val _).toRingHom.codRestrict S (fun y => hle y.2) obtain ⟨p, hp, hpr⟩ : IsIntegral (Algebra.adjoin K ({j} : Set F)) (r : F) := r.2 refine hS r ⟨p.map φ, hp.map φ, ?_⟩ rw [Polynomial.eval₂_map] exact hpr private theorem exists_eq_of_integralClosure_adjoin {j : F} {B : Type*} (π : B → F) {S : Subring F} (hrange : ∀ x, x ∈ S ↔ ∃ b, π b = x) (hK : ∀ c : K, algebraMap K F c ∈ S) (hj : j ∈ S) (hS : ∀ x : F, (∃ p : Polynomial S, p.Monic ∧ Polynomial.eval₂ S.subtype x p = 0) → x ∈ S) (r : integralClosure (Algebra.adjoin K ({j} : Set F)) F) : ∃ b, π b = algebraMap (integralClosure (Algebra.adjoin K ({j} : Set F)) F) F r := (hrange r).mp (integralClosure_adjoin_le_of_forall_isIntegral_mem K hK hj hS r) end Place end AlgebraicCurve namespace ModularCurve namespace CharPModel open AlgebraicCurve AlgebraicCurve.Place section SpecializationConstruction variable {A : ValuationSubring (AlgebraicClosure ℚ)} {N : ℕ} [NeZero N] {ℓ : ℕ} [Fact ℓ.Prime] {k : Type*} [Field k] [CharP k ℓ] {red : A →+* k} set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.bfin_le_compSubring (fm : FibreModel N A ℓ k red) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (hwFin : (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A) : fm.BFin ≤ (w.compSubring A : Subring (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) := by have hS : affineBaseFin N A ≤ w.compSubring A := by refine Subring.closure_le.mpr ?_ rintro x (⟨a, rfl⟩ | rfl) · exact (w.algebraMap_mem_compSubring_iff A _).mpr a.2 · exact hwFin exact fun x hx => w.mem_compSubring_of_isIntegral' A hS (fm.integralFin ⟨x, hx⟩) set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.constFin_mem' (fm : FibreModel N A ℓ k red) : ∀ a : A, algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) a ∈ fm.BFin := fm.constFin_mem private noncomputable def FibreModel.centreFin (fm : FibreModel N A ℓ k red) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (hwFin : (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A) : Ideal fm.BFin := (w.centre A).comap (Subring.inclusion (fm.bfin_le_compSubring w hwFin)) set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.centreFin_isMaximal (fm : FibreModel N A ℓ k red) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (hwFin : (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A) : (fm.centreFin w hwFin).IsMaximal := w.centre_comap_isMaximal (fm.bfin_le_compSubring w hwFin) fm.constFin_mem' set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.ker_piFin_le_centreFin (fm : FibreModel N A ℓ k red) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (hwFin : (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A) : RingHom.ker fm.piFin ≤ fm.centreFin w hwFin := by rw [fm.ker_piFin, Ideal.span_le] rintro x ⟨a, ha, rfl⟩ show _ ∈ (w.centre A).comap (Subring.inclusion (fm.bfin_le_compSubring w hwFin)) rw [Ideal.mem_comap] exact (w.algebraMap_mem_centre_iff A a).mpr ha include ℓ in set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem red_eq_zero_of_mem_maximalIdeal {a : A} (ha : a ∈ IsLocalRing.maximalIdeal A) : red a = 0 := by have hker := @ValuationSubring.ker_eq_maximalIdeal_of_isAlgebraic _ _ A _ _ (AlgebraicClosure.instAlgebra ℚ) (AlgebraicClosure.isAlgebraic ℚ) ℓ _ _ red exact RingHom.mem_ker.mp (hker ▸ ha) private noncomputable def lineClosure (k : Type*) [Field k] (N : ℕ) [NeZero N] : Subalgebra (Algebra.adjoin k ({jLine k N} : Set (modularFunctionFieldC k N))) (modularFunctionFieldC k N) := integralClosure (Algebra.adjoin k ({jLine k N} : Set (modularFunctionFieldC k N))) (modularFunctionFieldC k N) set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.exists_spFin (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (data : ModularPolynomialData N) (hsep : ((data.Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (hwFin : (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A) : ∃ v' : Place k (modularFunctionFieldC k N), ∀ b : fm.BFin, (fm.piFin b : modularFunctionFieldC k N) ∈ v'.toValuationSubring.nonunits ↔ b ∈ fm.centreFin w hwFin := by haveI hmax : (fm.centreFin w hwFin).IsMaximal := fm.centreFin_isMaximal w hwFin have hker := fm.ker_piFin_le_centreFin w hwFin haveI hPmax : (fm.piFin.imagePrime (fm.centreFin w hwFin)).IsMaximal := fm.piFin.imagePrime_isMaximal hker haveI hPprime : (fm.piFin.imagePrime (fm.centreFin w hwFin)).IsPrime := hPmax.isPrime obtain ⟨O, hle, hdom⟩ := Subring.exists_valuationSubring_dominating (B := fm.piFin.range) (fm.piFin.imagePrime (fm.centreFin w hwFin)) have hPne : fm.piFin.imagePrime (fm.centreFin w hwFin) ≠ ⊥ := by have hmem : (⟨jBar N, fm.jBar_mem⟩ : fm.BFin) - ⟨constantsHom N A (w.value A ⟨jBar N, hwFin⟩), fm.constFin_mem _⟩ ∈ fm.centreFin w hwFin := w.sub_value_mem_centre_comap (fm.bfin_le_compSubring w hwFin) fm.constFin_mem' _ have hy : fm.piFin.rangeRestrict ((⟨jBar N, fm.jBar_mem⟩ : fm.BFin) - ⟨constantsHom N A (w.value A ⟨jBar N, hwFin⟩), fm.constFin_mem _⟩) ∈ fm.piFin.imagePrime (fm.centreFin w hwFin) := (fm.piFin.rangeRestrict_mem_imagePrime_iff hker _).mpr hmem intro hbot rw [hbot, Ideal.mem_bot] at hy have hval : fm.piFin ((⟨jBar N, fm.jBar_mem⟩ : fm.BFin) - ⟨constantsHom N A (w.value A ⟨jBar N, hwFin⟩), fm.constFin_mem _⟩) = 0 := by have := congrArg Subtype.val hy simpa using this rw [map_sub] at hval have hj : fm.piFin ⟨jBar N, fm.jBar_mem⟩ = jLine k N := fm.piFin_j have hc : fm.piFin ⟨constantsHom N A (w.value A ⟨jBar N, hwFin⟩), fm.constFin_mem _⟩ = algebraMap k (modularFunctionFieldC k N) (red (w.value A ⟨jBar N, hwFin⟩)) := fm.piFin_const _ rw [hj, hc, sub_eq_zero] at hval exact (transcendental_jLine k N) (hval ▸ isAlgebraic_algebraMap _) have hne : O ≠ ⊤ := Subring.ne_top_of_dominating hdom hPne have hconstR : ∀ c : k, algebraMap k (modularFunctionFieldC k N) c ∈ fm.piFin.range := by intro c obtain ⟨a, rfl⟩ := hred c exact ⟨⟨constantsHom N A a, fm.constFin_mem a⟩, (fm.piFin_const a).symm ▸ rfl⟩ have hK : ∀ c : k, algebraMap k (modularFunctionFieldC k N) c ∈ O := by intro c obtain ⟨a, rfl⟩ := hred c exact hle (hconstR (red a)) haveI hFD : FiniteDimensional (IntermediateField.adjoin k ({jLine k N} : Set (modularFunctionFieldC k N))) (modularFunctionFieldC k N) := finiteDimensional_adjoin_jC k N data haveI hSep : Algebra.IsSeparable (IntermediateField.adjoin k ({jLine k N} : Set (modularFunctionFieldC k N))) (modularFunctionFieldC k N) := isSeparable_line_fibre k N data hsep haveI hDed : IsDedekindDomain (lineClosure k N) := isDedekindDomain_integralClosure_adjoin (K := k) (F := modularFunctionFieldC k N) (transcendental_jLine k N) haveI hFrac : IsFractionRing (lineClosure k N) (modularFunctionFieldC k N) := isFractionRing_integralClosure_adjoin (K := k) (F := modularFunctionFieldC k N) (transcendental_jLine k N) have hjO : (jLine k N : modularFunctionFieldC k N) ∈ O := by have h := hle (fm.piFin.mem_range_self ⟨jBar N, fm.jBar_mem⟩) have hj : fm.piFin ⟨jBar N, fm.jBar_mem⟩ = jLine k N := fm.piFin_j rwa [hj] at h refine ⟨Place.ofValuationSubringOver (R := lineClosure k N) O (fun r => integralClosure_adjoin_le_valuationSubring O hK hjO r) hne hK, ?_⟩ intro b exact (hdom (fm.piFin.rangeRestrict b)).trans (fm.piFin.rangeRestrict_mem_imagePrime_iff hker b) set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem transcendental_jLineInv (k : Type*) [Field k] (N : ℕ) [NeZero N] : Transcendental k (((jLine k N)⁻¹ : modularFunctionFieldC k N)) := by intro h exact transcendental_jLine k N (by simpa using h.inv) set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.binf_le_compSubring (fm : FibreModel N A ℓ k red) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (hwInf : ((jBar N)⁻¹ : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A) : fm.BInf ≤ (w.compSubring A : Subring (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) := by have hS : affineBaseInf N A ≤ w.compSubring A := by refine Subring.closure_le.mpr ?_ rintro x (⟨a, rfl⟩ | rfl) · exact (w.algebraMap_mem_compSubring_iff A _).mpr a.2 · exact hwInf exact fun x hx => w.mem_compSubring_of_isIntegral' A hS (fm.integralInf ⟨x, hx⟩) private noncomputable def FibreModel.centreInf (fm : FibreModel N A ℓ k red) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (hwInf : ((jBar N)⁻¹ : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A) : Ideal fm.BInf := (w.centre A).comap (Subring.inclusion (fm.binf_le_compSubring w hwInf)) set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.centreInf_isMaximal (fm : FibreModel N A ℓ k red) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (hwInf : ((jBar N)⁻¹ : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A) : (fm.centreInf w hwInf).IsMaximal := w.centre_comap_isMaximal (fm.binf_le_compSubring w hwInf) fm.constInf_mem set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.ker_piInf_le_centreInf (fm : FibreModel N A ℓ k red) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (hwInf : ((jBar N)⁻¹ : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A) : RingHom.ker fm.piInf ≤ fm.centreInf w hwInf := by rw [fm.ker_piInf, Ideal.span_le] rintro x ⟨a, ha, rfl⟩ show _ ∈ (w.centre A).comap (Subring.inclusion (fm.binf_le_compSubring w hwInf)) rw [Ideal.mem_comap] exact (w.algebraMap_mem_centre_iff A a).mpr ha private noncomputable def lineClosureInf (k : Type*) [Field k] (N : ℕ) [NeZero N] : Subalgebra (Algebra.adjoin k (({(jLine k N)⁻¹} : Set (modularFunctionFieldC k N)))) (modularFunctionFieldC k N) := integralClosure (Algebra.adjoin k (({(jLine k N)⁻¹} : Set (modularFunctionFieldC k N)))) (modularFunctionFieldC k N) set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.exists_spInf (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (data : ModularPolynomialData N) (hsep : ((data.Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (hwInf : ((jBar N)⁻¹ : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A) : ∃ v' : Place k (modularFunctionFieldC k N), ∀ b : fm.BInf, (fm.piInf b : modularFunctionFieldC k N) ∈ v'.toValuationSubring.nonunits ↔ b ∈ fm.centreInf w hwInf := by haveI hmax : (fm.centreInf w hwInf).IsMaximal := fm.centreInf_isMaximal w hwInf have hker := fm.ker_piInf_le_centreInf w hwInf haveI hPmax : (fm.piInf.imagePrime (fm.centreInf w hwInf)).IsMaximal := fm.piInf.imagePrime_isMaximal hker haveI hPprime : (fm.piInf.imagePrime (fm.centreInf w hwInf)).IsPrime := hPmax.isPrime obtain ⟨O, hle, hdom⟩ := Subring.exists_valuationSubring_dominating (B := fm.piInf.range) (fm.piInf.imagePrime (fm.centreInf w hwInf)) have hPne : fm.piInf.imagePrime (fm.centreInf w hwInf) ≠ ⊥ := by have hmem : (⟨(jBar N)⁻¹, fm.jInvBar_mem⟩ : fm.BInf) - ⟨constantsHom N A (w.value A ⟨(jBar N)⁻¹, hwInf⟩), fm.constInf_mem _⟩ ∈ fm.centreInf w hwInf := w.sub_value_mem_centre_comap (fm.binf_le_compSubring w hwInf) fm.constInf_mem _ have hy : fm.piInf.rangeRestrict ((⟨(jBar N)⁻¹, fm.jInvBar_mem⟩ : fm.BInf) - ⟨constantsHom N A (w.value A ⟨(jBar N)⁻¹, hwInf⟩), fm.constInf_mem _⟩) ∈ fm.piInf.imagePrime (fm.centreInf w hwInf) := (fm.piInf.rangeRestrict_mem_imagePrime_iff hker _).mpr hmem intro hbot rw [hbot, Ideal.mem_bot] at hy have hval : fm.piInf ((⟨(jBar N)⁻¹, fm.jInvBar_mem⟩ : fm.BInf) - ⟨constantsHom N A (w.value A ⟨(jBar N)⁻¹, hwInf⟩), fm.constInf_mem _⟩) = 0 := by have := congrArg Subtype.val hy simpa using this rw [map_sub] at hval have hj : fm.piInf ⟨(jBar N)⁻¹, fm.jInvBar_mem⟩ = (jLine k N)⁻¹ := fm.piInf_jInv have hc : fm.piInf ⟨constantsHom N A (w.value A ⟨(jBar N)⁻¹, hwInf⟩), fm.constInf_mem _⟩ = algebraMap k (modularFunctionFieldC k N) (red (w.value A ⟨(jBar N)⁻¹, hwInf⟩)) := fm.piInf_const _ rw [hj, hc, sub_eq_zero] at hval exact (transcendental_jLineInv k N) (hval ▸ isAlgebraic_algebraMap _) have hne : O ≠ ⊤ := Subring.ne_top_of_dominating hdom hPne have hconstR : ∀ c : k, algebraMap k (modularFunctionFieldC k N) c ∈ fm.piInf.range := by intro c obtain ⟨a, rfl⟩ := hred c exact ⟨⟨constantsHom N A a, fm.constInf_mem a⟩, (fm.piInf_const a).symm ▸ rfl⟩ have hK : ∀ c : k, algebraMap k (modularFunctionFieldC k N) c ∈ O := by intro c obtain ⟨a, rfl⟩ := hred c exact hle (hconstR (red a)) haveI hFD : FiniteDimensional (IntermediateField.adjoin k (({(jLine k N)⁻¹} : Set (modularFunctionFieldC k N)))) (modularFunctionFieldC k N) := by rw [IntermediateField.adjoin_simple_inv_eq (jLine k N)] exact finiteDimensional_adjoin_jC k N data haveI hSep : Algebra.IsSeparable (IntermediateField.adjoin k (({(jLine k N)⁻¹} : Set (modularFunctionFieldC k N)))) (modularFunctionFieldC k N) := by rw [IntermediateField.adjoin_simple_inv_eq (jLine k N)] exact isSeparable_line_fibre k N data hsep haveI hDed : IsDedekindDomain (lineClosureInf k N) := isDedekindDomain_integralClosure_adjoin (K := k) (F := modularFunctionFieldC k N) (transcendental_jLineInv k N) haveI hFrac : IsFractionRing (lineClosureInf k N) (modularFunctionFieldC k N) := isFractionRing_integralClosure_adjoin (K := k) (F := modularFunctionFieldC k N) (transcendental_jLineInv k N) have hjO : ((jLine k N)⁻¹ : modularFunctionFieldC k N) ∈ O := by have h := hle (fm.piInf.mem_range_self ⟨(jBar N)⁻¹, fm.jInvBar_mem⟩) have hj : fm.piInf ⟨(jBar N)⁻¹, fm.jInvBar_mem⟩ = (jLine k N)⁻¹ := fm.piInf_jInv rwa [hj] at h refine ⟨Place.ofValuationSubringOver (R := lineClosureInf k N) O (fun r => integralClosure_adjoin_le_valuationSubring O hK hjO r) hne hK, ?_⟩ intro b exact (hdom (fm.piInf.rangeRestrict b)).trans (fm.piInf.rangeRestrict_mem_imagePrime_iff hker b) set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.chart_dichotomy (_fm : FibreModel N A ℓ k red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) : (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A ∨ ((jBar N)⁻¹ : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A := by haveI hFD : FiniteDimensional (IntermediateField.adjoin (AlgebraicClosure ℚ) ({jBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)))) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) := finiteDimensional_lineBar_of_dataAll N dataAll haveI h1 : Module.Finite ((w.restrict (IntermediateField.adjoin (AlgebraicClosure ℚ) ({jBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))))).ResidueField) w.ResidueField := rf_finite_residueField w haveI h2 : Module.Finite (AlgebraicClosure ℚ) ((w.restrict (IntermediateField.adjoin (AlgebraicClosure ℚ) ({jBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))))).ResidueField) := by have htop : IntermediateField.adjoin (AlgebraicClosure ℚ) ({⟨jBar N, IntermediateField.mem_adjoin_simple_self _ (jBar N)⟩} : Set (IntermediateField.adjoin (AlgebraicClosure ℚ) ({jBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))))) = ⊤ := by have h := adjoin_val_preimage_eq_top (K := AlgebraicClosure ℚ) (F := IntermediateField.adjoin (AlgebraicClosure ℚ) ({jBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)))) (S := {jBar N}) rfl have hset : (Subtype.val ⁻¹' {jBar N} : Set (IntermediateField.adjoin (AlgebraicClosure ℚ) ({jBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))))) = {⟨jBar N, IntermediateField.mem_adjoin_simple_self _ (jBar N)⟩} := by ext z simp only [Set.mem_preimage, Set.mem_singleton_iff] exact ⟨fun hz => Subtype.ext hz, fun hz => by rw [hz]⟩ rwa [hset] at h exact AlgebraicCurve.Place.finite_residueField_of_adjoin_simple_eq_top (transcendental_subtype _ (IntermediateField.mem_adjoin_simple_self _ (jBar N)) (transcendental_jBar N)) htop _ haveI h3 : Module.Finite (AlgebraicClosure ℚ) w.ResidueField := Module.Finite.trans ((w.restrict (IntermediateField.adjoin (AlgebraicClosure ℚ) ({jBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))))).ResidueField) w.ResidueField exact w.mem_compSubring_or_inv_mem A (w.surjective_algebraMap_residueField_of_isAlgClosed) (jBar N) set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem fibreEvalSwap_subtype (k : Type*) [Field k] (N : ℕ) [NeZero N] (data : ModularPolynomialData N) (hsym : EvalSymm data.Φ) : data.Φ.eval₂ (Polynomial.aeval (R := ℤ) (⟨jqNModC k N, jqNModC_mem k N⟩ : modularFunctionFieldC k N)).toRingHom (⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N) = 0 := by have hcomp : ((modularFunctionFieldC k N).val.toRingHom).comp (Polynomial.aeval (R := ℤ) (⟨jqNModC k N, jqNModC_mem k N⟩ : modularFunctionFieldC k N)).toRingHom = (Polynomial.aeval (R := ℤ) (jqNModC k N)).toRingHom := by apply Polynomial.ringHom_ext · intro a simp only [eq_intCast, map_intCast] · simp only [RingHom.coe_comp, Function.comp_apply, AlgHom.toRingHom_eq_coe, AlgHom.coe_toRingHom, Polynomial.aeval_X] rfl have h := Polynomial.hom_eval₂ data.Φ (Polynomial.aeval (R := ℤ) (⟨jqNModC k N, jqNModC_mem k N⟩ : modularFunctionFieldC k N)).toRingHom ((modularFunctionFieldC k N).val.toRingHom) (⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N) apply Subtype.val_injective have h0 : (modularFunctionFieldC k N).val.toRingHom (data.Φ.eval₂ (Polynomial.aeval (R := ℤ) (⟨jqNModC k N, jqNModC_mem k N⟩ : modularFunctionFieldC k N)).toRingHom (⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N)) = 0 := by rw [h, hcomp] exact fibreEvalSwap_eq_zero N data hsym k simpa using h0 set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem barEvalSwap_laurent (N : ℕ) [NeZero N] (data : ModularPolynomialData N) (hsym : EvalSymm data.Φ) : data.Φ.eval₂ (Polynomial.aeval (R := ℤ) (coeffEmb (AlgebraicClosure ℚ) (qExpand ℚ N jq))).toRingHom (coeffEmb (AlgebraicClosure ℚ) jq) = 0 := by have hswap0 : data.Φ.eval₂ (Polynomial.aeval (R := ℤ) (qExpand ℚ N jq)).toRingHom jq = 0 := by rw [show qExpand ℚ N jq = jqN N from rfl, hsym (jqN N) jq] have h0 := data.eval_eq_zero rw [show evalAtJ = (Polynomial.aeval (R := ℤ) jq).toRingHom from rfl] at h0 exact h0 have hcomp : ((coeffEmb (AlgebraicClosure ℚ)).comp (Polynomial.aeval (R := ℤ) (qExpand ℚ N jq)).toRingHom) = (Polynomial.aeval (R := ℤ) (coeffEmb (AlgebraicClosure ℚ) (qExpand ℚ N jq))).toRingHom := by apply Polynomial.ringHom_ext · intro a simp only [eq_intCast, map_intCast] · simp only [RingHom.coe_comp, Function.comp_apply, AlgHom.toRingHom_eq_coe, AlgHom.coe_toRingHom, Polynomial.aeval_X] have h := Polynomial.hom_eval₂ data.Φ (Polynomial.aeval (R := ℤ) (qExpand ℚ N jq)).toRingHom (coeffEmb (AlgebraicClosure ℚ)) jq rw [hswap0, map_zero, hcomp] at h exact h.symm set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem barEvalSwap_subtype (N : ℕ) [NeZero N] (data : ModularPolynomialData N) (hsym : EvalSymm data.Φ) : data.Φ.eval₂ (Polynomial.aeval (R := ℤ) (jNBar N)).toRingHom (jBar N) = 0 := by have hcomp : (((laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)).val.toRingHom).comp (Polynomial.aeval (R := ℤ) (jNBar N)).toRingHom) = (Polynomial.aeval (R := ℤ) (coeffEmb (AlgebraicClosure ℚ) (qExpand ℚ N jq))).toRingHom := by apply Polynomial.ringHom_ext · intro a simp only [eq_intCast, map_intCast] · simp only [RingHom.coe_comp, Function.comp_apply, AlgHom.toRingHom_eq_coe, AlgHom.coe_toRingHom, Polynomial.aeval_X] rfl have h := Polynomial.hom_eval₂ data.Φ (Polynomial.aeval (R := ℤ) (jNBar N)).toRingHom ((laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)).val.toRingHom) (jBar N) apply Subtype.val_injective have h0 : (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)).val.toRingHom (data.Φ.eval₂ (Polynomial.aeval (R := ℤ) (jNBar N)).toRingHom (jBar N)) = 0 := by rw [h, hcomp] exact barEvalSwap_laurent N data hsym simpa using h0 set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in private theorem transcendental_jNC (k : Type*) [Field k] (N : ℕ) [NeZero N] (data : ModularPolynomialData N) (hsym : EvalSymm data.Φ) : Transcendental k (⟨jqNModC k N, jqNModC_mem k N⟩ : modularFunctionFieldC k N) := by intro halg haveI hFD : FiniteDimensional k (IntermediateField.adjoin k ({⟨jqNModC k N, jqNModC_mem k N⟩} : Set (modularFunctionFieldC k N))) := IntermediateField.adjoin.finiteDimensional halg.isIntegral have h2 : IsIntegral (IntermediateField.adjoin k ({⟨jqNModC k N, jqNModC_mem k N⟩} : Set (modularFunctionFieldC k N))) (⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N) := isIntegral_adjoin_of_bivar_monic data.monic (fibreEvalSwap_subtype k N data hsym) have h3 : IsIntegral k (⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N) := by haveI : Algebra.IsIntegral k (IntermediateField.adjoin k ({⟨jqNModC k N, jqNModC_mem k N⟩} : Set (modularFunctionFieldC k N))) := Algebra.IsIntegral.of_finite _ _ exact isIntegral_trans _ h2 exact (transcendental_jC k N) h3.isAlgebraic set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in private theorem transcendental_jNBar (N : ℕ) [NeZero N] (data : ModularPolynomialData N) (hsym : EvalSymm data.Φ) : Transcendental (AlgebraicClosure ℚ) (jNBar N) := by intro halg haveI hFD : FiniteDimensional (AlgebraicClosure ℚ) (IntermediateField.adjoin (AlgebraicClosure ℚ) ({jNBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)))) := IntermediateField.adjoin.finiteDimensional halg.isIntegral have h2 : IsIntegral (IntermediateField.adjoin (AlgebraicClosure ℚ) ({jNBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)))) (jBar N) := isIntegral_adjoin_of_bivar_monic data.monic (barEvalSwap_subtype N data hsym) have h3 : IsIntegral (AlgebraicClosure ℚ) (jBar N) := by haveI : Algebra.IsIntegral (AlgebraicClosure ℚ) (IntermediateField.adjoin (AlgebraicClosure ℚ) ({jNBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)))) := Algebra.IsIntegral.of_finite _ _ exact isIntegral_trans _ h2 exact (transcendental_jBar N) h3.isAlgebraic private theorem jBar_ne_const (N : ℕ) [NeZero N] (c : AlgebraicClosure ℚ) : jBar N ≠ algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) c := fun h => transcendental_jBar N (h ▸ isAlgebraic_algebraMap c) private theorem jLine_ne_const (k : Type*) [Field k] (N : ℕ) [NeZero N] (c : k) : jLine k N ≠ algebraMap k (modularFunctionFieldC k N) c := fun h => transcendental_jLine k N (h ▸ isAlgebraic_algebraMap c) private theorem jLine_ne_zero (k : Type*) [Field k] (N : ℕ) [NeZero N] : (jLine k N : modularFunctionFieldC k N) ≠ 0 := fun h => transcendental_jLine k N (h ▸ isAlgebraic_zero) set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem mem_of_ord_nonneg {k' F' : Type*} [Field k'] [Field F'] [Algebra k' F'] (v : Place k' F') {x : F'} (hx : x ≠ 0) (h : 0 ≤ v.ord x) : x ∈ v.toValuationSubring := by by_contra hmem rcases v.toValuationSubring.mem_or_inv_mem x with hx' | hinv · exact hmem hx' have hinv_nu : x⁻¹ ∈ v.toValuationSubring.nonunits := by refine (ValuationSubring.mem_nonunits_iff_or _).mpr (Or.inr ?_) rwa [inv_inv] have hpos : 0 < v.ord x⁻¹ := (v.mem_nonunits_iff_ord_pos (inv_ne_zero hx)).mp hinv_nu rw [v.ord_inv] at hpos exact absurd h (not_le.mpr (neg_pos.mp hpos)) open Classical in private noncomputable def FibreModel.sp (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) → Place k (modularFunctionFieldC k N) := fun w => if h : (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A then (fm.exists_spFin hred (dataAll N (dvd_refl N)) hsep w h).choose else (fm.exists_spInf hred (dataAll N (dvd_refl N)) hsep w ((fm.chart_dichotomy dataAll w).resolve_left h)).choose set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.sp_spec_fin (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (h : (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A) : ∀ b : fm.BFin, (fm.piFin b : modularFunctionFieldC k N) ∈ (fm.sp hred dataAll hsep w).toValuationSubring.nonunits ↔ b ∈ fm.centreFin w h := by have hsp : fm.sp hred dataAll hsep w = (fm.exists_spFin hred (dataAll N (dvd_refl N)) hsep w h).choose := by unfold FibreModel.sp rw [dif_pos h] rw [hsp] exact (fm.exists_spFin hred (dataAll N (dvd_refl N)) hsep w h).choose_spec set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.sp_spec_inf (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (h : ¬ (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A) : ∀ b : fm.BInf, (fm.piInf b : modularFunctionFieldC k N) ∈ (fm.sp hred dataAll hsep w).toValuationSubring.nonunits ↔ b ∈ fm.centreInf w ((fm.chart_dichotomy dataAll w).resolve_left h) := by have hsp : fm.sp hred dataAll hsep w = (fm.exists_spInf hred (dataAll N (dvd_refl N)) hsep w ((fm.chart_dichotomy dataAll w).resolve_left h)).choose := by unfold FibreModel.sp rw [dif_neg h] rw [hsp] exact (fm.exists_spInf hred (dataAll N (dvd_refl N)) hsep w ((fm.chart_dichotomy dataAll w).resolve_left h)).choose_spec set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.value_jInv_mem_maximalIdeal (fm : FibreModel N A ℓ k red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (h : ¬ (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A) : w.value A ⟨(jBar N)⁻¹, (fm.chart_dichotomy dataAll w).resolve_left h⟩ ∈ IsLocalRing.maximalIdeal A := by have hinv := (fm.chart_dichotomy dataAll w).resolve_left h by_contra hcu have hcu' : IsUnit (w.value A ⟨(jBar N)⁻¹, hinv⟩) := by by_contra hn exact hcu ((IsLocalRing.mem_maximalIdeal _).mpr hn) obtain ⟨u, hu⟩ := hcu' have hc0 : ((w.value A ⟨(jBar N)⁻¹, hinv⟩ : A) : AlgebraicClosure ℚ) ≠ 0 := by intro h0 apply hcu have hz : w.value A ⟨(jBar N)⁻¹, hinv⟩ = 0 := Subtype.ext h0 rw [hz] exact zero_mem _ have hmul : ((u : A) : AlgebraicClosure ℚ) * (((u⁻¹ : Aˣ) : A) : AlgebraicClosure ℚ) = 1 := by exact_mod_cast congrArg (Subtype.val) (Units.mul_inv u) have hd : (((u⁻¹ : Aˣ) : A) : AlgebraicClosure ℚ) = ((w.value A ⟨(jBar N)⁻¹, hinv⟩ : A) : AlgebraicClosure ℚ)⁻¹ := by rw [← hu] at hc0 ⊢ exact eq_inv_of_mul_eq_one_right (by rw [mul_comm] at hmul ⊢; exact hmul) have hv := (w.hasValueAt_value A ⟨(jBar N)⁻¹, hinv⟩).inv hc0 rw [inv_inv, ← hd] at hv exact h (w.mem_compSubring_of_hasValueAt ((u⁻¹ : Aˣ) : A).2 hv) set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.sp_ord_jLine_neg (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (h : ¬ (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A) : (fm.sp hred dataAll hsep w).ord (jLine k N) < 0 := by have hinv := (fm.chart_dichotomy dataAll w).resolve_left h have hcent : (⟨(jBar N)⁻¹, fm.jInvBar_mem⟩ : fm.BInf) ∈ fm.centreInf w hinv := by show _ ∈ (w.centre A).comap (Subring.inclusion (fm.binf_le_compSubring w hinv)) rw [Ideal.mem_comap] exact (w.mem_centre_iff _).mpr (fm.value_jInv_mem_maximalIdeal dataAll w h) have hnu := (fm.sp_spec_inf hred dataAll hsep w h ⟨(jBar N)⁻¹, fm.jInvBar_mem⟩).mpr hcent rw [show fm.piInf ⟨(jBar N)⁻¹, fm.jInvBar_mem⟩ = (jLine k N)⁻¹ from fm.piInf_jInv] at hnu have hpos : 0 < (fm.sp hred dataAll hsep w).ord ((jLine k N : modularFunctionFieldC k N))⁻¹ := ((fm.sp hred dataAll hsep w).mem_nonunits_iff_ord_pos (inv_ne_zero (jLine_ne_zero k N))).mp hnu rw [(fm.sp hred dataAll hsep w).ord_inv] at hpos exact neg_pos.mp hpos set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.sp_d0_j (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (a : A) (hord : 0 < w.ord (jBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ))) : 0 < (fm.sp hred dataAll hsep w).ord (jLine k N - algebraMap k (modularFunctionFieldC k N) (red a)) := by by_cases h : (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A · have hmem : (⟨jBar N, fm.jBar_mem⟩ - ⟨constantsHom N A a, fm.constFin_mem a⟩ : fm.BFin) ∈ fm.centreFin w h := by show _ ∈ (w.centre A).comap (Subring.inclusion (fm.bfin_le_compSubring w h)) rw [Ideal.mem_comap] exact w.mem_centre_of_ord_pos hord have hnu := (fm.sp_spec_fin hred dataAll hsep w h _).mpr hmem rw [map_sub, fm.piFin_j, fm.piFin_const a] at hnu exact ((fm.sp hred dataAll hsep w).mem_nonunits_iff_ord_pos (sub_ne_zero.mpr (jLine_ne_const k N (red a)))).mp hnu · exfalso apply h have hval : w.HasValueAt (jBar N) (a : AlgebraicClosure ℚ) := by rw [hasValueAt_iff] exact (w.mem_nonunits_iff_ord_pos (sub_ne_zero.mpr (jBar_ne_const N (a : AlgebraicClosure ℚ)))).mpr hord exact w.mem_compSubring_of_hasValueAt a.2 hval set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.sp_d0_j_pole (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (hpole : ∀ a : A, w.ord (jBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) ≤ 0) : (fm.sp hred dataAll hsep w).ord (jLine k N) < 0 := by by_cases h : (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A · exfalso have ha₀ := w.ord_sub_value_pos (f := ⟨jBar N, h⟩) (jBar_ne_const N (w.value A ⟨jBar N, h⟩ : AlgebraicClosure ℚ)) exact absurd ha₀ (not_lt.mpr (hpole (w.value A ⟨jBar N, h⟩))) · exact fm.sp_ord_jLine_neg hred dataAll hsep w h private theorem jNBar_ne_const (N : ℕ) [NeZero N] (data : ModularPolynomialData N) (hsym : EvalSymm data.Φ) (c : AlgebraicClosure ℚ) : jNBar N ≠ algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) c := fun h => transcendental_jNBar N data hsym (h ▸ isAlgebraic_algebraMap c) private theorem jNLine_ne_const (k : Type*) [Field k] (N : ℕ) [NeZero N] (data : ModularPolynomialData N) (hsym : EvalSymm data.Φ) (c : k) : jNLine k N ≠ algebraMap k (modularFunctionFieldC k N) c := by intro h have htr : Transcendental k (jNLine k N) := transcendental_jNC k N data hsym exact htr (h ▸ isAlgebraic_algebraMap c) private theorem jNLine_ne_zero (k : Type*) [Field k] (N : ℕ) [NeZero N] (data : ModularPolynomialData N) (hsym : EvalSymm data.Φ) : (jNLine k N : modularFunctionFieldC k N) ≠ 0 := by intro h have htr : Transcendental k (jNLine k N) := transcendental_jNC k N data hsym exact htr (h ▸ isAlgebraic_zero) set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem aeval_mem_subring {F' : Type*} [Field F'] (S : Subring F') {x : F'} (hx : x ∈ S) (p : Polynomial ℤ) : Polynomial.aeval (R := ℤ) x p ∈ S := by have hcomp : (S.subtype).comp (Polynomial.aeval (R := ℤ) (⟨x, hx⟩ : S)).toRingHom = (Polynomial.aeval (R := ℤ) x).toRingHom := by apply Polynomial.ringHom_ext · intro a simp only [eq_intCast, map_intCast] · rw [RingHom.comp_apply] rw [show (Polynomial.aeval (R := ℤ) (⟨x, hx⟩ : S)).toRingHom Polynomial.X = (⟨x, hx⟩ : S) from Polynomial.aeval_X _] rw [show (Polynomial.aeval (R := ℤ) x).toRingHom Polynomial.X = x from Polynomial.aeval_X _] rfl have h := congrArg (fun φ : Polynomial ℤ →+* F' => φ p) hcomp simp only [RingHom.coe_comp, Function.comp_apply] at h rw [show Polynomial.aeval (R := ℤ) x p = (Polynomial.aeval (R := ℤ) x).toRingHom p from rfl, ← h] exact SetLike.coe_mem _ set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem ord_nonneg_of_mem' {k' F' : Type*} [Field k'] [Field F'] [Algebra k' F'] (v : Place k' F') {x : F'} (hx : x ≠ 0) (h : x ∈ v.toValuationSubring) : 0 ≤ v.ord x := by by_contra hneg have hpos : 0 < v.ord x⁻¹ := by rw [v.ord_inv] exact neg_pos.mpr (not_le.mp hneg) have hnu : x⁻¹ ∈ v.toValuationSubring.nonunits := (v.mem_nonunits_iff_ord_pos (inv_ne_zero hx)).mpr hpos rcases (ValuationSubring.mem_nonunits_iff_or _).mp hnu with h0 | hninv · exact inv_ne_zero hx h0 · rw [inv_inv] at hninv exact hninv h set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.sp_d0_jN (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsym : EvalSymm (dataAll N (dvd_refl N)).Φ) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (a : A) (hord : 0 < w.ord (jNBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ))) : 0 < (fm.sp hred dataAll hsep w).ord (jNLine k N - algebraMap k (modularFunctionFieldC k N) (red a)) := by by_cases h : (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A · have hmem : (⟨jNBar N, fm.jNBar_mem⟩ - ⟨constantsHom N A a, fm.constFin_mem a⟩ : fm.BFin) ∈ fm.centreFin w h := by show _ ∈ (w.centre A).comap (Subring.inclusion (fm.bfin_le_compSubring w h)) rw [Ideal.mem_comap] exact w.mem_centre_of_ord_pos hord have hnu := (fm.sp_spec_fin hred dataAll hsep w h _).mpr hmem rw [map_sub, fm.piFin_jN, fm.piFin_const a] at hnu exact ((fm.sp hred dataAll hsep w).mem_nonunits_iff_ord_pos (sub_ne_zero.mpr (jNLine_ne_const k N (dataAll N (dvd_refl N)) hsym (red a)))).mp hnu · exfalso apply h have hvN : (jNBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A := by refine w.mem_compSubring_of_hasValueAt a.2 ?_ rw [hasValueAt_iff] exact (w.mem_nonunits_iff_ord_pos (sub_ne_zero.mpr (jNBar_ne_const N (dataAll N (dvd_refl N)) hsym (a : AlgebraicClosure ℚ)))).mpr hord have hS : Subring.closure (Set.range ((algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))).comp A.subtype) ∪ {jNBar N}) ≤ w.compSubring A := by refine Subring.closure_le.mpr ?_ rintro x (⟨a', rfl⟩ | rfl) · exact (w.algebraMap_mem_compSubring_iff A _).mpr a'.2 · exact hvN refine w.mem_compSubring_of_isIntegral' A hS ?_ refine ⟨(dataAll N (dvd_refl N)).Φ.map ((Polynomial.aeval (R := ℤ) (⟨jNBar N, Subring.subset_closure (Set.mem_union_right _ rfl)⟩ : Subring.closure (Set.range ((algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))).comp A.subtype) ∪ {jNBar N}))).toRingHom), (dataAll N (dvd_refl N)).monic.map _, ?_⟩ rw [Polynomial.eval₂_map] have hcomp : ((algebraMap (Subring.closure (Set.range ((algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))).comp A.subtype) ∪ {jNBar N})) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))).comp ((Polynomial.aeval (R := ℤ) (⟨jNBar N, Subring.subset_closure (Set.mem_union_right _ rfl)⟩ : Subring.closure (Set.range ((algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))).comp A.subtype) ∪ {jNBar N}))).toRingHom)) = (Polynomial.aeval (R := ℤ) (jNBar N)).toRingHom := by apply Polynomial.ringHom_ext · intro b simp only [eq_intCast, map_intCast] · rw [RingHom.comp_apply] rw [show (Polynomial.aeval (R := ℤ) (⟨jNBar N, Subring.subset_closure (Set.mem_union_right _ rfl)⟩ : Subring.closure (Set.range ((algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))).comp A.subtype) ∪ {jNBar N}))).toRingHom Polynomial.X = (⟨jNBar N, Subring.subset_closure (Set.mem_union_right _ rfl)⟩ : Subring.closure (Set.range ((algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))).comp A.subtype) ∪ {jNBar N})) from Polynomial.aeval_X _] rw [show (Polynomial.aeval (R := ℤ) (jNBar N)).toRingHom Polynomial.X = jNBar N from Polynomial.aeval_X _] rfl rw [hcomp] exact barEvalSwap_subtype N (dataAll N (dvd_refl N)) hsym set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.sp_d0_jN_pole (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsym : EvalSymm (dataAll N (dvd_refl N)).Φ) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (hpole : ∀ a : A, w.ord (jNBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) ≤ 0) : (fm.sp hred dataAll hsep w).ord (jNLine k N) < 0 := by by_cases h : (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A · exfalso have hvN : (jNBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A := fm.bfin_le_compSubring w h fm.jNBar_mem have ha₀ := w.ord_sub_value_pos (f := ⟨jNBar N, hvN⟩) (jNBar_ne_const N (dataAll N (dvd_refl N)) hsym (w.value A ⟨jNBar N, hvN⟩ : AlgebraicClosure ℚ)) exact absurd ha₀ (not_lt.mpr (hpole (w.value A ⟨jNBar N, hvN⟩))) · have hjneg := fm.sp_ord_jLine_neg hred dataAll hsep w h by_contra hge have hmemN : (jNLine k N : modularFunctionFieldC k N) ∈ (fm.sp hred dataAll hsep w).toValuationSubring := mem_of_ord_nonneg _ (jNLine_ne_zero k N (dataAll N (dvd_refl N)) hsym) (not_lt.mp hge) have hmemJ : (jLine k N : modularFunctionFieldC k N) ∈ (fm.sp hred dataAll hsep w).toValuationSubring := by refine (fm.sp hred dataAll hsep w).mem_of_eval_monic_eq_zero (P := (dataAll N (dvd_refl N)).Φ.map ((Polynomial.aeval (R := ℤ) (jNLine k N)).toRingHom)) ((dataAll N (dvd_refl N)).monic.map _) (fun i => ?_) ?_ · rw [Polynomial.coeff_map] exact aeval_mem_subring (fm.sp hred dataAll hsep w).toValuationSubring.toSubring hmemN _ · rw [Polynomial.eval_map] exact fibreEvalSwap_subtype k N (dataAll N (dvd_refl N)) hsym exact absurd (ord_nonneg_of_mem' _ (jLine_ne_zero k N) hmemJ) (not_le.mpr hjneg) set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.piFin_mem_valuationSubring (fm : FibreModel N A ℓ k red) (v' : Place k (modularFunctionFieldC k N)) (hjO : (jLine k N : modularFunctionFieldC k N) ∈ v'.toValuationSubring) (b : fm.BFin) : (fm.piFin b : modularFunctionFieldC k N) ∈ v'.toValuationSubring := by obtain ⟨p, hp, hpe⟩ := fm.integralFin b have hABle : affineBaseFin N A ≤ fm.BFin := by refine Subring.closure_le.mpr ?_ rintro x (⟨a, rfl⟩ | rfl) · exact fm.constFin_mem a · exact fm.jBar_mem have hψO : ∀ (x : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (hx : x ∈ affineBaseFin N A), fm.piFin ⟨x, hABle hx⟩ ∈ v'.toValuationSubring := by intro x hx induction hx using Subring.closure_induction with | mem y hy => rcases hy with ⟨a, rfl⟩ | rfl · rw [show ∀ h : constantsHom N A a ∈ fm.BFin, fm.piFin ⟨constantsHom N A a, h⟩ = algebraMap k (modularFunctionFieldC k N) (red a) from fun _ => fm.piFin_const a] exact v'.algebraMap_mem' (red a) · rw [show ∀ h : jBar N ∈ fm.BFin, fm.piFin ⟨jBar N, h⟩ = jLine k N from fun _ => fm.piFin_j] exact hjO | one => have h1 : fm.piFin ⟨1, hABle (one_mem _)⟩ = 1 := by rw [show (⟨1, hABle (one_mem _)⟩ : fm.BFin) = 1 from Subtype.ext rfl, map_one] exact h1 ▸ one_mem _ | zero => have h0 : fm.piFin ⟨0, hABle (zero_mem _)⟩ = 0 := by rw [show (⟨0, hABle (zero_mem _)⟩ : fm.BFin) = 0 from Subtype.ext rfl, map_zero] exact h0 ▸ zero_mem _ | add y z hy hz ihy ihz => have ha : fm.piFin ⟨y + z, hABle (add_mem hy hz)⟩ = fm.piFin ⟨y, hABle hy⟩ + fm.piFin ⟨z, hABle hz⟩ := by rw [show (⟨y + z, hABle (add_mem hy hz)⟩ : fm.BFin) = ⟨y, hABle hy⟩ + ⟨z, hABle hz⟩ from Subtype.ext rfl, map_add] exact ha ▸ add_mem ihy ihz | neg y hy ihy => have hn : fm.piFin ⟨-y, hABle (neg_mem hy)⟩ = -fm.piFin ⟨y, hABle hy⟩ := by rw [show (⟨-y, hABle (neg_mem hy)⟩ : fm.BFin) = -(⟨y, hABle hy⟩ : fm.BFin) from Subtype.ext rfl, map_neg] exact hn ▸ neg_mem ihy | mul y z hy hz ihy ihz => have hm : fm.piFin ⟨y * z, hABle (mul_mem hy hz)⟩ = fm.piFin ⟨y, hABle hy⟩ * fm.piFin ⟨z, hABle hz⟩ := by rw [show (⟨y * z, hABle (mul_mem hy hz)⟩ : fm.BFin) = ⟨y, hABle hy⟩ * ⟨z, hABle hz⟩ from Subtype.ext rfl, map_mul] exact hm ▸ mul_mem ihy ihz have hq : Polynomial.eval₂ (Subring.inclusion hABle) b p = 0 := by apply Subtype.val_injective have h := Polynomial.hom_eval₂ p (Subring.inclusion hABle) fm.BFin.subtype b have hcomp : (fm.BFin.subtype).comp (Subring.inclusion hABle) = (affineBaseFin N A).subtype := by apply RingHom.ext intro x rfl rw [hcomp] at h calc (↑(Polynomial.eval₂ (Subring.inclusion hABle) b p) : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) = fm.BFin.subtype (Polynomial.eval₂ (Subring.inclusion hABle) b p) := rfl _ = Polynomial.eval₂ ((affineBaseFin N A).subtype) (fm.BFin.subtype b) p := h _ = 0 := hpe refine v'.mem_of_eval_monic_eq_zero (P := p.map (fm.piFin.comp (Subring.inclusion hABle))) (hp.map _) (fun i => ?_) ?_ · rw [Polynomial.coeff_map] exact hψO _ (p.coeff i).2 · rw [Polynomial.eval_map] have h := Polynomial.hom_eval₂ p (Subring.inclusion hABle) fm.piFin b rw [← h, hq, map_zero] set_option maxHeartbeats 3200000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.exists_sp_eq_fin (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (v' : Place k (modularFunctionFieldC k N)) (hjO : (jLine k N : modularFunctionFieldC k N) ∈ v'.toValuationSubring) : ∃ w, fm.sp hred dataAll hsep w = v' := by haveI : IsAlgClosed k := A.isAlgClosed_of_surjective red hred haveI hFD : FiniteDimensional (IntermediateField.adjoin k ({jLine k N} : Set (modularFunctionFieldC k N))) (modularFunctionFieldC k N) := finiteDimensional_adjoin_jC k N (dataAll N (dvd_refl N)) haveI h1 : Module.Finite ((v'.restrict (IntermediateField.adjoin k ({jLine k N} : Set (modularFunctionFieldC k N)))).ResidueField) v'.ResidueField := rf_finite_residueField v' haveI h2 : Module.Finite k ((v'.restrict (IntermediateField.adjoin k ({jLine k N} : Set (modularFunctionFieldC k N)))).ResidueField) := by have htop : IntermediateField.adjoin k ({⟨jLine k N, IntermediateField.mem_adjoin_simple_self _ (jLine k N)⟩} : Set (IntermediateField.adjoin k ({jLine k N} : Set (modularFunctionFieldC k N)))) = ⊤ := by have h := adjoin_val_preimage_eq_top (K := k) (F := IntermediateField.adjoin k ({jLine k N} : Set (modularFunctionFieldC k N))) (S := {jLine k N}) rfl have hset : (Subtype.val ⁻¹' {jLine k N} : Set (IntermediateField.adjoin k ({jLine k N} : Set (modularFunctionFieldC k N)))) = {⟨jLine k N, IntermediateField.mem_adjoin_simple_self _ (jLine k N)⟩} := by ext z simp only [Set.mem_preimage, Set.mem_singleton_iff] exact ⟨fun hz => Subtype.ext hz, fun hz => by rw [hz]⟩ rwa [hset] at h exact AlgebraicCurve.Place.finite_residueField_of_adjoin_simple_eq_top (transcendental_subtype _ (IntermediateField.mem_adjoin_simple_self _ (jLine k N)) (transcendental_jLine k N)) htop _ haveI h3 : Module.Finite k v'.ResidueField := Module.Finite.trans ((v'.restrict (IntermediateField.adjoin k ({jLine k N} : Set (modularFunctionFieldC k N)))).ResidueField) v'.ResidueField have hsurj : Function.Surjective (algebraMap k v'.ResidueField) := v'.surjective_algebraMap_residueField_of_isAlgClosed let φ : fm.BFin →+* v'.toValuationSubring := fm.piFin.codRestrict v'.toValuationSubring (fm.piFin_mem_valuationSubring v' hjO) let ρ := (IsLocalRing.residue (v'.toValuationSubring : Type _)).comp φ haveI : (RingHom.ker ρ).IsPrime := RingHom.ker_isPrime ρ have h𝔮A : ∀ a : A, (⟨constantsHom N A a, fm.constFin_mem a⟩ : fm.BFin) ∈ RingHom.ker ρ ↔ a ∈ IsLocalRing.maximalIdeal A := by intro a rw [RingHom.mem_ker] have hφc : φ ⟨constantsHom N A a, fm.constFin_mem a⟩ = ⟨algebraMap k (modularFunctionFieldC k N) (red a), v'.algebraMap_mem' (red a)⟩ := by apply Subtype.ext exact fm.piFin_const a rw [show ρ ⟨constantsHom N A a, fm.constFin_mem a⟩ = IsLocalRing.residue _ (φ ⟨constantsHom N A a, fm.constFin_mem a⟩) from rfl, hφc, IsLocalRing.residue_eq_zero_iff, ← ValuationSubring.coe_mem_nonunits_iff] constructor · intro h have h0 : v'.HasValueAt (algebraMap k (modularFunctionFieldC k N) (red a)) 0 := by rw [hasValueAt_zero_iff] exact h have hza : red a = 0 := ((v'.hasValueAt_algebraMap (red a)).unique h0) exact (@ValuationSubring.ker_eq_maximalIdeal_apply _ _ A _ _ (AlgebraicClosure.instAlgebra ℚ) (AlgebraicClosure.isAlgebraic ℚ) ℓ _ _ red a).mp hza · intro ha have hza : red a = 0 := (@ValuationSubring.ker_eq_maximalIdeal_apply _ _ A _ _ (AlgebraicClosure.instAlgebra ℚ) (AlgebraicClosure.isAlgebraic ℚ) ℓ _ _ red a).mpr ha show algebraMap k (modularFunctionFieldC k N) (red a) ∈ v'.toValuationSubring.nonunits rw [hza, map_zero] exact (ValuationSubring.mem_nonunits_iff_or _).mpr (Or.inl rfl) obtain ⟨c, hc⟩ := v'.exists_hasValueAt hsurj hjO obtain ⟨a₀, rfl⟩ := hred c have hja : (⟨jBar N, fm.jBar_mem⟩ : fm.BFin) - ⟨constantsHom N A a₀, fm.constFin_mem a₀⟩ ∈ RingHom.ker ρ := by rw [RingHom.mem_ker] rw [show ρ (⟨jBar N, fm.jBar_mem⟩ - ⟨constantsHom N A a₀, fm.constFin_mem a₀⟩) = IsLocalRing.residue _ (φ (⟨jBar N, fm.jBar_mem⟩ - ⟨constantsHom N A a₀, fm.constFin_mem a₀⟩)) from rfl, IsLocalRing.residue_eq_zero_iff, ← ValuationSubring.coe_mem_nonunits_iff] have hval : ((φ (⟨jBar N, fm.jBar_mem⟩ - ⟨constantsHom N A a₀, fm.constFin_mem a₀⟩) : v'.toValuationSubring) : modularFunctionFieldC k N) = jLine k N - algebraMap k (modularFunctionFieldC k N) (red a₀) := by show (fm.piFin (⟨jBar N, fm.jBar_mem⟩ - ⟨constantsHom N A a₀, fm.constFin_mem a₀⟩) : modularFunctionFieldC k N) = _ rw [map_sub, fm.piFin_j, fm.piFin_const a₀] rfl rw [hval] exact hc haveI hFDbar : FiniteDimensional (IntermediateField.adjoin (AlgebraicClosure ℚ) ({jBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)))) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) := finiteDimensional_lineBar_of_dataAll N dataAll haveI hCZ : CharZero (IntermediateField.adjoin (AlgebraicClosure ℚ) ({jBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)))) := charZero_of_injective_algebraMap (algebraMap (AlgebraicClosure ℚ) _).injective haveI hSepBar : Algebra.IsSeparable (IntermediateField.adjoin (AlgebraicClosure ℚ) ({jBar N} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)))) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) := inferInstance obtain ⟨w, hB, hcent, hval⟩ := AlgebraicCurve.Place.exists_place_centre_comap_eq A (transcendental_jBar N) fm.constFin_mem fm.jBar_mem fm.integralFin (RingHom.ker ρ) h𝔮A a₀ hja refine ⟨w, ?_⟩ have hwFin : (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A := w.mem_compSubring_of_hasValueAt a₀.2 hval have hspec := fm.sp_spec_fin hred dataAll hsep w hwFin have hcent' : fm.centreFin w hwFin = RingHom.ker ρ := hcent have hjOu : (jLine k N : modularFunctionFieldC k N) ∈ (fm.sp hred dataAll hsep w).toValuationSubring := by have h1 : (⟨jBar N, fm.jBar_mem⟩ : fm.BFin) - ⟨constantsHom N A a₀, fm.constFin_mem a₀⟩ ∈ fm.centreFin w hwFin := by rw [hcent'] exact hja have h2 := (hspec _).mpr h1 rw [map_sub, fm.piFin_j, fm.piFin_const a₀] at h2 have h3 := (fm.sp hred dataAll hsep w).toValuationSubring.nonunits_subset h2 have h4 := add_mem h3 ((fm.sp hred dataAll hsep w).algebraMap_mem' (red a₀)) simpa [jLine] using h4 have hconstR : ∀ c : k, algebraMap k (modularFunctionFieldC k N) c ∈ fm.piFin.range := by intro c obtain ⟨a, rfl⟩ := hred c exact ⟨⟨constantsHom N A a, fm.constFin_mem a⟩, (fm.piFin_const a).symm ▸ rfl⟩ haveI hSepLine : Algebra.IsSeparable (IntermediateField.adjoin k ({jLine k N} : Set (modularFunctionFieldC k N))) (modularFunctionFieldC k N) := isSeparable_line_fibre k N (dataAll N (dvd_refl N)) hsep haveI hDed : IsDedekindDomain (lineClosure k N) := isDedekindDomain_integralClosure_adjoin (K := k) (F := modularFunctionFieldC k N) (transcendental_jLine k N) haveI hFrac : IsFractionRing (lineClosure k N) (modularFunctionFieldC k N) := isFractionRing_integralClosure_adjoin (K := k) (F := modularFunctionFieldC k N) (transcendental_jLine k N) refine AlgebraicCurve.Place.eq_of_forall_mem_nonunits_iff_of_surjective (lineClosure k N) (fun r => integralClosure_adjoin_le_valuationSubring _ (fun c => (fm.sp hred dataAll hsep w).algebraMap_mem' c) hjOu r) (fun r => integralClosure_adjoin_le_valuationSubring _ (fun c => v'.algebraMap_mem' c) hjO r) (fun b : fm.BFin => (fm.piFin b : modularFunctionFieldC k N)) (AlgebraicCurve.Place.exists_eq_of_integralClosure_adjoin (fun b : fm.BFin => (fm.piFin b : modularFunctionFieldC k N)) (fun x => RingHom.mem_range) hconstR ⟨⟨jBar N, fm.jBar_mem⟩, fm.piFin_j⟩ fm.intClosed_piFin) (fun b => ?_) rw [hspec b, hcent', RingHom.mem_ker, show ρ b = IsLocalRing.residue _ (φ b) from rfl, IsLocalRing.residue_eq_zero_iff, ← ValuationSubring.coe_mem_nonunits_iff] rfl set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.piInf_mem_valuationSubring (fm : FibreModel N A ℓ k red) (v' : Place k (modularFunctionFieldC k N)) (hjO : ((jLine k N)⁻¹ : modularFunctionFieldC k N) ∈ v'.toValuationSubring) (b : fm.BInf) : (fm.piInf b : modularFunctionFieldC k N) ∈ v'.toValuationSubring := by obtain ⟨p, hp, hpe⟩ := fm.integralInf b have hABle : affineBaseInf N A ≤ fm.BInf := by refine Subring.closure_le.mpr ?_ rintro x (⟨a, rfl⟩ | rfl) · exact fm.constInf_mem a · exact fm.jInvBar_mem have hψO : ∀ (x : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (hx : x ∈ affineBaseInf N A), fm.piInf ⟨x, hABle hx⟩ ∈ v'.toValuationSubring := by intro x hx induction hx using Subring.closure_induction with | mem y hy => rcases hy with ⟨a, rfl⟩ | rfl · rw [show ∀ h : constantsHom N A a ∈ fm.BInf, fm.piInf ⟨constantsHom N A a, h⟩ = algebraMap k (modularFunctionFieldC k N) (red a) from fun _ => fm.piInf_const a] exact v'.algebraMap_mem' (red a) · rw [show ∀ h : (jBar N)⁻¹ ∈ fm.BInf, fm.piInf ⟨(jBar N)⁻¹, h⟩ = (jLine k N)⁻¹ from fun _ => fm.piInf_jInv] exact hjO | one => have h1 : fm.piInf ⟨1, hABle (one_mem _)⟩ = 1 := by rw [show (⟨1, hABle (one_mem _)⟩ : fm.BInf) = 1 from Subtype.ext rfl, map_one] exact h1 ▸ one_mem _ | zero => have h0 : fm.piInf ⟨0, hABle (zero_mem _)⟩ = 0 := by rw [show (⟨0, hABle (zero_mem _)⟩ : fm.BInf) = 0 from Subtype.ext rfl, map_zero] exact h0 ▸ zero_mem _ | add y z hy hz ihy ihz => have ha : fm.piInf ⟨y + z, hABle (add_mem hy hz)⟩ = fm.piInf ⟨y, hABle hy⟩ + fm.piInf ⟨z, hABle hz⟩ := by rw [show (⟨y + z, hABle (add_mem hy hz)⟩ : fm.BInf) = ⟨y, hABle hy⟩ + ⟨z, hABle hz⟩ from Subtype.ext rfl, map_add] exact ha ▸ add_mem ihy ihz | neg y hy ihy => have hn : fm.piInf ⟨-y, hABle (neg_mem hy)⟩ = -fm.piInf ⟨y, hABle hy⟩ := by rw [show (⟨-y, hABle (neg_mem hy)⟩ : fm.BInf) = -(⟨y, hABle hy⟩ : fm.BInf) from Subtype.ext rfl, map_neg] exact hn ▸ neg_mem ihy | mul y z hy hz ihy ihz => have hm : fm.piInf ⟨y * z, hABle (mul_mem hy hz)⟩ = fm.piInf ⟨y, hABle hy⟩ * fm.piInf ⟨z, hABle hz⟩ := by rw [show (⟨y * z, hABle (mul_mem hy hz)⟩ : fm.BInf) = ⟨y, hABle hy⟩ * ⟨z, hABle hz⟩ from Subtype.ext rfl, map_mul] exact hm ▸ mul_mem ihy ihz have hq : Polynomial.eval₂ (Subring.inclusion hABle) b p = 0 := by apply Subtype.val_injective have h := Polynomial.hom_eval₂ p (Subring.inclusion hABle) fm.BInf.subtype b have hcomp : (fm.BInf.subtype).comp (Subring.inclusion hABle) = (affineBaseInf N A).subtype := by apply RingHom.ext intro x rfl rw [hcomp] at h calc (↑(Polynomial.eval₂ (Subring.inclusion hABle) b p) : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) = fm.BInf.subtype (Polynomial.eval₂ (Subring.inclusion hABle) b p) := rfl _ = Polynomial.eval₂ ((affineBaseInf N A).subtype) (fm.BInf.subtype b) p := h _ = 0 := hpe refine v'.mem_of_eval_monic_eq_zero (P := p.map (fm.piInf.comp (Subring.inclusion hABle))) (hp.map _) (fun i => ?_) ?_ · rw [Polynomial.coeff_map] exact hψO _ (p.coeff i).2 · rw [Polynomial.eval_map] have h := Polynomial.hom_eval₂ p (Subring.inclusion hABle) fm.piInf b rw [← h, hq, map_zero] set_option maxHeartbeats 3200000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.exists_sp_eq_inf (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (v' : Place k (modularFunctionFieldC k N)) (hjinvO : ((jLine k N)⁻¹ : modularFunctionFieldC k N) ∈ v'.toValuationSubring) (hjO : ¬ (jLine k N : modularFunctionFieldC k N) ∈ v'.toValuationSubring) : ∃ w, fm.sp hred dataAll hsep w = v' := by let φ : fm.BInf →+* v'.toValuationSubring := fm.piInf.codRestrict v'.toValuationSubring (fm.piInf_mem_valuationSubring v' hjinvO) let ρ := (IsLocalRing.residue (v'.toValuationSubring : Type _)).comp φ haveI : (RingHom.ker ρ).IsPrime := RingHom.ker_isPrime ρ have h𝔮A : ∀ a : A, (⟨constantsHom N A a, fm.constInf_mem a⟩ : fm.BInf) ∈ RingHom.ker ρ ↔ a ∈ IsLocalRing.maximalIdeal A := by intro a rw [RingHom.mem_ker] have hφc : φ ⟨constantsHom N A a, fm.constInf_mem a⟩ = ⟨algebraMap k (modularFunctionFieldC k N) (red a), v'.algebraMap_mem' (red a)⟩ := by apply Subtype.ext exact fm.piInf_const a rw [show ρ ⟨constantsHom N A a, fm.constInf_mem a⟩ = IsLocalRing.residue _ (φ ⟨constantsHom N A a, fm.constInf_mem a⟩) from rfl, hφc, IsLocalRing.residue_eq_zero_iff, ← ValuationSubring.coe_mem_nonunits_iff] constructor · intro h have h0 : v'.HasValueAt (algebraMap k (modularFunctionFieldC k N) (red a)) 0 := by rw [hasValueAt_zero_iff] exact h have hza : red a = 0 := ((v'.hasValueAt_algebraMap (red a)).unique h0) exact (@ValuationSubring.ker_eq_maximalIdeal_apply _ _ A _ _ (AlgebraicClosure.instAlgebra ℚ) (AlgebraicClosure.isAlgebraic ℚ) ℓ _ _ red a).mp hza · intro ha have hza : red a = 0 := (@ValuationSubring.ker_eq_maximalIdeal_apply _ _ A _ _ (AlgebraicClosure.instAlgebra ℚ) (AlgebraicClosure.isAlgebraic ℚ) ℓ _ _ red a).mpr ha show algebraMap k (modularFunctionFieldC k N) (red a) ∈ v'.toValuationSubring.nonunits rw [hza, map_zero] exact (ValuationSubring.mem_nonunits_iff_or _).mpr (Or.inl rfl) have hjnu : ((jLine k N)⁻¹ : modularFunctionFieldC k N) ∈ v'.toValuationSubring.nonunits := by refine (ValuationSubring.mem_nonunits_iff_or _).mpr (Or.inr ?_) rwa [inv_inv] have hja : (⟨(jBar N)⁻¹, fm.jInvBar_mem⟩ : fm.BInf) - ⟨constantsHom N A 0, fm.constInf_mem 0⟩ ∈ RingHom.ker ρ := by rw [RingHom.mem_ker] rw [show ρ (⟨(jBar N)⁻¹, fm.jInvBar_mem⟩ - ⟨constantsHom N A 0, fm.constInf_mem 0⟩) = IsLocalRing.residue _ (φ (⟨(jBar N)⁻¹, fm.jInvBar_mem⟩ - ⟨constantsHom N A 0, fm.constInf_mem 0⟩)) from rfl, IsLocalRing.residue_eq_zero_iff, ← ValuationSubring.coe_mem_nonunits_iff] have hval : ((φ (⟨(jBar N)⁻¹, fm.jInvBar_mem⟩ - ⟨constantsHom N A 0, fm.constInf_mem 0⟩) : v'.toValuationSubring) : modularFunctionFieldC k N) = ((jLine k N)⁻¹ : modularFunctionFieldC k N) := by show (fm.piInf (⟨(jBar N)⁻¹, fm.jInvBar_mem⟩ - ⟨constantsHom N A 0, fm.constInf_mem 0⟩) : modularFunctionFieldC k N) = _ rw [map_sub, fm.piInf_jInv, fm.piInf_const 0, map_zero, map_zero, sub_zero] rfl rw [hval] exact hjnu have htrinv : Transcendental (AlgebraicClosure ℚ) ((jBar N)⁻¹ : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) := by intro halg exact transcendental_jBar N (inv_inv (jBar N) ▸ halg.inv) haveI hFDbar : FiniteDimensional (IntermediateField.adjoin (AlgebraicClosure ℚ) ({(jBar N)⁻¹} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)))) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) := by rw [IntermediateField.adjoin_simple_inv_eq (jBar N)] exact finiteDimensional_lineBar_of_dataAll N dataAll haveI hCZ : CharZero (IntermediateField.adjoin (AlgebraicClosure ℚ) ({(jBar N)⁻¹} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)))) := charZero_of_injective_algebraMap (algebraMap (AlgebraicClosure ℚ) _).injective haveI hSepBar : Algebra.IsSeparable (IntermediateField.adjoin (AlgebraicClosure ℚ) ({(jBar N)⁻¹} : Set (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)))) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) := inferInstance obtain ⟨w, hB, hcent, hval⟩ := AlgebraicCurve.Place.exists_place_centre_comap_eq A htrinv fm.constInf_mem fm.jInvBar_mem fm.integralInf (RingHom.ker ρ) h𝔮A 0 (by simpa using hja) refine ⟨w, ?_⟩ have hval0 : ((jBar N)⁻¹ : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.toValuationSubring.nonunits := by have h := hval rw [HasValueAt] at h rwa [show ((0 : A) : AlgebraicClosure ℚ) = 0 from rfl, map_zero, sub_zero] at h have hwInf : ¬ (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A := by intro hmem obtain ⟨c, hc⟩ := (w.mem_compSubring_iff (A := A)).mp hmem have hjne : (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ≠ 0 := fun h => transcendental_jBar N (h ▸ isAlgebraic_zero) have hjmem : (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.toValuationSubring := by have h1 := w.toValuationSubring.nonunits_subset hc have h2 := add_mem h1 (w.algebraMap_mem' (c : AlgebraicClosure ℚ)) simpa using h2 have h𝔪 : (⟨(jBar N)⁻¹, w.toValuationSubring.nonunits_subset hval0⟩ : w.toValuationSubring) ∈ IsLocalRing.maximalIdeal _ := by rw [← ValuationSubring.coe_mem_nonunits_iff] exact hval0 have hone : (⟨jBar N, hjmem⟩ : w.toValuationSubring) * ⟨(jBar N)⁻¹, w.toValuationSubring.nonunits_subset hval0⟩ = 1 := by apply Subtype.ext show (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) * (jBar N)⁻¹ = 1 exact mul_inv_cancel₀ hjne have htop : (1 : w.toValuationSubring) ∈ IsLocalRing.maximalIdeal _ := by rw [← hone] exact Ideal.mul_mem_left _ _ h𝔪 exact (IsLocalRing.maximalIdeal.isMaximal _).ne_top (Ideal.eq_top_of_isUnit_mem _ htop isUnit_one) have hspec := fm.sp_spec_inf hred dataAll hsep w hwInf have hcent' : fm.centreInf w ((fm.chart_dichotomy dataAll w).resolve_left hwInf) = RingHom.ker ρ := hcent have hjinvOu : (((jLine k N)⁻¹ : modularFunctionFieldC k N)) ∈ (fm.sp hred dataAll hsep w).toValuationSubring := by have h1 : (⟨(jBar N)⁻¹, fm.jInvBar_mem⟩ : fm.BInf) - ⟨constantsHom N A 0, fm.constInf_mem 0⟩ ∈ fm.centreInf w ((fm.chart_dichotomy dataAll w).resolve_left hwInf) := by rw [hcent'] exact hja have h2 := (hspec _).mpr h1 rw [map_sub, fm.piInf_jInv, fm.piInf_const 0, map_zero, map_zero, sub_zero] at h2 exact (fm.sp hred dataAll hsep w).toValuationSubring.nonunits_subset h2 have hconstR : ∀ c : k, algebraMap k (modularFunctionFieldC k N) c ∈ fm.piInf.range := by intro c obtain ⟨a, rfl⟩ := hred c exact ⟨⟨constantsHom N A a, fm.constInf_mem a⟩, (fm.piInf_const a).symm ▸ rfl⟩ haveI hSepLine : Algebra.IsSeparable (IntermediateField.adjoin k (({(jLine k N)⁻¹} : Set (modularFunctionFieldC k N)))) (modularFunctionFieldC k N) := by rw [IntermediateField.adjoin_simple_inv_eq (jLine k N)] exact isSeparable_line_fibre k N (dataAll N (dvd_refl N)) hsep haveI hFDLine : FiniteDimensional (IntermediateField.adjoin k (({(jLine k N)⁻¹} : Set (modularFunctionFieldC k N)))) (modularFunctionFieldC k N) := by rw [IntermediateField.adjoin_simple_inv_eq (jLine k N)] exact finiteDimensional_adjoin_jC k N (dataAll N (dvd_refl N)) haveI hDed : IsDedekindDomain (lineClosureInf k N) := isDedekindDomain_integralClosure_adjoin (K := k) (F := modularFunctionFieldC k N) (transcendental_jLineInv k N) haveI hFrac : IsFractionRing (lineClosureInf k N) (modularFunctionFieldC k N) := isFractionRing_integralClosure_adjoin (K := k) (F := modularFunctionFieldC k N) (transcendental_jLineInv k N) refine AlgebraicCurve.Place.eq_of_forall_mem_nonunits_iff_of_surjective (lineClosureInf k N) (fun r => integralClosure_adjoin_le_valuationSubring _ (fun c => (fm.sp hred dataAll hsep w).algebraMap_mem' c) hjinvOu r) (fun r => integralClosure_adjoin_le_valuationSubring _ (fun c => v'.algebraMap_mem' c) hjinvO r) (fun b : fm.BInf => (fm.piInf b : modularFunctionFieldC k N)) (AlgebraicCurve.Place.exists_eq_of_integralClosure_adjoin (fun b : fm.BInf => (fm.piInf b : modularFunctionFieldC k N)) (fun x => RingHom.mem_range) hconstR ⟨⟨(jBar N)⁻¹, fm.jInvBar_mem⟩, fm.piInf_jInv⟩ fm.intClosed_piInf) (fun b => ?_) rw [hspec b, hcent', RingHom.mem_ker, show ρ b = IsLocalRing.residue _ (φ b) from rfl, IsLocalRing.residue_eq_zero_iff, ← ValuationSubring.coe_mem_nonunits_iff] rfl set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.sp_d4 (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) : Function.Surjective (fm.sp hred dataAll hsep) := by intro v' by_cases hjO : (jLine k N : modularFunctionFieldC k N) ∈ v'.toValuationSubring · exact fm.exists_sp_eq_fin hred dataAll hsep v' hjO · exact fm.exists_sp_eq_inf hred dataAll hsep v' ((v'.toValuationSubring.mem_or_inv_mem _).resolve_left hjO) hjO set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.exists_specializationMap_assembled (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsym : EvalSymm (dataAll N (dvd_refl N)).Φ) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (fm : FibreModel N A ℓ k red) : ∃ sp : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) → Place k (modularFunctionFieldC k N), (∀ w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)), ∀ a : A, 0 < w.ord (jBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) → 0 < (sp w).ord ((⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N) - algebraMap k (modularFunctionFieldC k N) (red a))) ∧ (∀ w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)), (∀ a : A, w.ord (jBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) ≤ 0) → (sp w).ord ((⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N)) < 0) ∧ (∀ w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)), ∀ a : A, 0 < w.ord (jNBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) → 0 < (sp w).ord ((⟨jqNModC k N, jqNModC_mem k N⟩ : modularFunctionFieldC k N) - algebraMap k (modularFunctionFieldC k N) (red a))) ∧ (∀ w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)), (∀ a : A, w.ord (jNBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) ≤ 0) → (sp w).ord ((⟨jqNModC k N, jqNModC_mem k N⟩ : modularFunctionFieldC k N)) < 0) ∧ Function.Surjective sp := ⟨fm.sp hred dataAll hsep, fun w a h => fm.sp_d0_j hred dataAll hsep w a h, fun w h => fm.sp_d0_j_pole hred dataAll hsep w h, fun w a h => fm.sp_d0_jN hred dataAll hsym hsep w a h, fun w h => fm.sp_d0_jN_pole hred dataAll hsym hsep w h, fm.sp_d4 hred dataAll hsep⟩ set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.sp_hasValueAt_inf (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (h : ¬ (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A) (b : fm.BInf) (a : A) (hb : w.HasValueAt (b : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) : (fm.sp hred dataAll hsep w).HasValueAt (fm.piInf b : modularFunctionFieldC k N) (red a) := by have hinv := (fm.chart_dichotomy dataAll w).resolve_left h set b' : fm.BInf := b - ⟨constantsHom N A a, fm.constInf_mem a⟩ with hb' have hcentmem : b' ∈ fm.centreInf w hinv := by rw [FibreModel.centreInf, Ideal.mem_comap] refine (w.mem_centre_iff_of_hasValueAt (a := (0 : A)) ?_).mpr (zero_mem _) show w.HasValueAt ((b' : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) ((0 : A) : AlgebraicClosure ℚ) show (b' : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) - algebraMap _ _ ((0 : A) : AlgebraicClosure ℚ) ∈ w.toValuationSubring.nonunits rw [show (((0 : A) : AlgebraicClosure ℚ)) = 0 from rfl, map_zero, sub_zero] show ((b : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) - constantsHom N A a) ∈ w.toValuationSubring.nonunits exact hb have h2 := (fm.sp_spec_inf hred dataAll hsep w h b').mpr hcentmem rw [hb', map_sub, fm.piInf_const a] at h2 exact h2 set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.sp_piInf_nonunits_iff (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (h : ¬ (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A) (b : fm.BInf) : (fm.piInf b : modularFunctionFieldC k N) ∈ (fm.sp hred dataAll hsep w).toValuationSubring.nonunits ↔ w.value A (Subring.inclusion (fm.binf_le_compSubring w ((fm.chart_dichotomy dataAll w).resolve_left h)) b) ∈ IsLocalRing.maximalIdeal A := by rw [fm.sp_spec_inf hred dataAll hsep w h b] rw [FibreModel.centreInf, Ideal.mem_comap] exact w.mem_centre_iff _ set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.sp_jLineInv_mem (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (h : ¬ (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A) : (((jLine k N)⁻¹ : modularFunctionFieldC k N)) ∈ (fm.sp hred dataAll hsep w).toValuationSubring := by have hneg := fm.sp_ord_jLine_neg hred dataAll hsep w h refine mem_of_ord_nonneg _ (inv_ne_zero (jLine_ne_zero k N)) ?_ rw [(fm.sp hred dataAll hsep w).ord_inv] exact (neg_pos.mpr hneg).le set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.fibre_place_ext_inf_impl (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (v₁ v₂ : Place k (modularFunctionFieldC k N)) (h₁ : ((jLine k N)⁻¹ : modularFunctionFieldC k N) ∈ v₁.toValuationSubring) (h₂ : ((jLine k N)⁻¹ : modularFunctionFieldC k N) ∈ v₂.toValuationSubring) (hagree : ∀ b : fm.BInf, ((fm.piInf b : modularFunctionFieldC k N) ∈ v₁.toValuationSubring.nonunits ↔ (fm.piInf b : modularFunctionFieldC k N) ∈ v₂.toValuationSubring.nonunits)) : v₁ = v₂ := by have hconstR : ∀ c : k, algebraMap k (modularFunctionFieldC k N) c ∈ fm.piInf.range := by intro c obtain ⟨a, rfl⟩ := hred c exact ⟨⟨constantsHom N A a, fm.constInf_mem a⟩, (fm.piInf_const a).symm ▸ rfl⟩ haveI hSepLine : Algebra.IsSeparable (IntermediateField.adjoin k (({(jLine k N)⁻¹} : Set (modularFunctionFieldC k N)))) (modularFunctionFieldC k N) := by rw [IntermediateField.adjoin_simple_inv_eq (jLine k N)] exact isSeparable_line_fibre k N (dataAll N (dvd_refl N)) hsep haveI hFDLine : FiniteDimensional (IntermediateField.adjoin k (({(jLine k N)⁻¹} : Set (modularFunctionFieldC k N)))) (modularFunctionFieldC k N) := by rw [IntermediateField.adjoin_simple_inv_eq (jLine k N)] exact finiteDimensional_adjoin_jC k N (dataAll N (dvd_refl N)) haveI hDed : IsDedekindDomain (lineClosureInf k N) := isDedekindDomain_integralClosure_adjoin (K := k) (F := modularFunctionFieldC k N) (transcendental_jLineInv k N) haveI hFrac : IsFractionRing (lineClosureInf k N) (modularFunctionFieldC k N) := isFractionRing_integralClosure_adjoin (K := k) (F := modularFunctionFieldC k N) (transcendental_jLineInv k N) exact AlgebraicCurve.Place.eq_of_forall_mem_nonunits_iff_of_surjective (lineClosureInf k N) (fun r => integralClosure_adjoin_le_valuationSubring _ (fun c => v₁.algebraMap_mem' c) h₁ r) (fun r => integralClosure_adjoin_le_valuationSubring _ (fun c => v₂.algebraMap_mem' c) h₂ r) (fun b : fm.BInf => (fm.piInf b : modularFunctionFieldC k N)) (AlgebraicCurve.Place.exists_eq_of_integralClosure_adjoin (fun b : fm.BInf => (fm.piInf b : modularFunctionFieldC k N)) (fun x => RingHom.mem_range) hconstR ⟨⟨(jBar N)⁻¹, fm.jInvBar_mem⟩, fm.piInf_jInv⟩ fm.intClosed_piInf) hagree set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem not_jBar_mem_compSubring_of_forall_ord_le (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (hpole : ∀ a : A, w.ord (jBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) ≤ 0) : ¬ (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A := by intro hmem have ha₀ := w.ord_sub_value_pos (f := ⟨jBar N, hmem⟩) (jBar_ne_const N (w.value A ⟨jBar N, hmem⟩ : AlgebraicClosure ℚ)) exact absurd ha₀ (not_lt.mpr (hpole (w.value A ⟨jBar N, hmem⟩))) set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.exists_specializationMap_dict_impl (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsym : EvalSymm (dataAll N (dvd_refl N)).Φ) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (fm : FibreModel N A ℓ k red) : ∃ sp : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) → Place k (modularFunctionFieldC k N), (∀ w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)), ∀ a : A, 0 < w.ord (jBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) → 0 < (sp w).ord ((⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N) - algebraMap k (modularFunctionFieldC k N) (red a))) ∧ (∀ w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)), (∀ a : A, w.ord (jBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) ≤ 0) → (sp w).ord ((⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N)) < 0) ∧ (∀ w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)), ∀ a : A, 0 < w.ord (jNBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) → 0 < (sp w).ord ((⟨jqNModC k N, jqNModC_mem k N⟩ : modularFunctionFieldC k N) - algebraMap k (modularFunctionFieldC k N) (red a))) ∧ (∀ w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)), (∀ a : A, w.ord (jNBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) ≤ 0) → (sp w).ord ((⟨jqNModC k N, jqNModC_mem k N⟩ : modularFunctionFieldC k N)) < 0) ∧ Function.Surjective sp ∧ (∀ w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)), (∀ a : A, w.ord (jBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) ≤ 0) → ∀ b : fm.BInf, ∀ a : A, ((b : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) ∈ w.toValuationSubring.nonunits → ((fm.piInf b : modularFunctionFieldC k N) - algebraMap k (modularFunctionFieldC k N) (red a)) ∈ (sp w).toValuationSubring.nonunits) ∧ (∀ w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)), (∀ a : A, w.ord (jBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) ≤ 0) → (((⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N))⁻¹ ∈ (sp w).toValuationSubring)) ∧ (∀ w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)), (∀ a : A, w.ord (jBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) ≤ 0) → ∀ b : fm.BInf, ((fm.piInf b : modularFunctionFieldC k N) ∈ (sp w).toValuationSubring.nonunits ↔ ∃ a : A, a ∈ IsLocalRing.maximalIdeal A ∧ ((b : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) ∈ w.toValuationSubring.nonunits)) := ⟨fm.sp hred dataAll hsep, fun w a h => fm.sp_d0_j hred dataAll hsep w a h, fun w h => fm.sp_d0_j_pole hred dataAll hsep w h, fun w a h => fm.sp_d0_jN hred dataAll hsym hsep w a h, fun w h => fm.sp_d0_jN_pole hred dataAll hsym hsep w h, fm.sp_d4 hred dataAll hsep, fun w hpole b a hb => fm.sp_hasValueAt_inf hred dataAll hsep w (not_jBar_mem_compSubring_of_forall_ord_le w hpole) b a hb, fun w hpole => fm.sp_jLineInv_mem hred dataAll hsep w (not_jBar_mem_compSubring_of_forall_ord_le w hpole), fun w hpole b => by have h := not_jBar_mem_compSubring_of_forall_ord_le w hpole constructor · intro hnu have hval := (fm.sp_piInf_nonunits_iff hred dataAll hsep w h b).mp hnu exact ⟨w.value A (Subring.inclusion (fm.binf_le_compSubring w ((fm.chart_dichotomy dataAll w).resolve_left h)) b), hval, w.hasValueAt_value A (Subring.inclusion (fm.binf_le_compSubring w ((fm.chart_dichotomy dataAll w).resolve_left h)) b)⟩ · rintro ⟨a, ha𝔪, hval⟩ have ht : ((fm.piInf b : modularFunctionFieldC k N) - algebraMap k (modularFunctionFieldC k N) (red a)) ∈ (fm.sp hred dataAll hsep w).toValuationSubring.nonunits := fm.sp_hasValueAt_inf hred dataAll hsep w h b a hval have hred0 : red a = 0 := (@ValuationSubring.ker_eq_maximalIdeal_apply _ _ A _ _ (AlgebraicClosure.instAlgebra ℚ) (AlgebraicClosure.isAlgebraic ℚ) ℓ _ _ red a).mpr ha𝔪 rwa [hred0, map_zero, sub_zero] at ht⟩ set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in private theorem FibreModel.sp_piInf_nonunits_iff_of_hasValueAt (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (h : ¬ (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A) (b : fm.BInf) (a : A) (hb : w.HasValueAt (b : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) : (fm.piInf b : modularFunctionFieldC k N) ∈ (fm.sp hred dataAll hsep w).toValuationSubring.nonunits ↔ a ∈ IsLocalRing.maximalIdeal A := by rw [fm.sp_piInf_nonunits_iff hred dataAll hsep w h b, w.value_eq_of_hasValueAt (f := Subring.inclusion (fm.binf_le_compSubring w ((fm.chart_dichotomy dataAll w).resolve_left h)) b) hb] noncomputable def FibreModel.spPlace (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) → Place k (modularFunctionFieldC k N) := fm.sp hred dataAll hsep noncomputable def FibreModel.spDiv (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) : Divisor (AlgebraicClosure ℚ) (modularFunctionFieldBar N) → Divisor k (modularFunctionFieldC k N) := Finsupp.mapDomain (fm.spPlace hred dataAll hsep) def FibreModel.SpDivPreservesPrincipal (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) : Prop := (∀ D ∈ Divisor.degZero (K := AlgebraicClosure ℚ) (F := modularFunctionFieldBar N), fm.spDiv hred dataAll hsep D ∈ Divisor.degZero (K := k) (F := modularFunctionFieldC k N)) ∧ (∀ D ∈ Divisor.degZero (K := AlgebraicClosure ℚ) (F := modularFunctionFieldBar N), D ∈ Divisor.principal (K := AlgebraicClosure ℚ) (F := modularFunctionFieldBar N) → fm.spDiv hred dataAll hsep D ∈ Divisor.principal (K := k) (F := modularFunctionFieldC k N)) open Classical in noncomputable def FibreModel.spPic0 (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) : JZero N →+ Pic0 k (modularFunctionFieldC k N) := if h : fm.SpDivPreservesPrincipal hred dataAll hsep then QuotientAddGroup.map _ _ (AddMonoidHom.mk' (fun D => ⟨fm.spDiv hred dataAll hsep ↑D, h.1 ↑D D.2⟩) (fun D E => Subtype.ext (by show fm.spDiv hred dataAll hsep ↑(D + E) = fm.spDiv hred dataAll hsep ↑D + fm.spDiv hred dataAll hsep ↑E rw [AddSubgroup.coe_add] exact Finsupp.mapDomain_add))) (fun D hD => AddSubgroup.mem_comap.mpr ((AddSubgroup.mem_addSubgroupOf).mpr (h.2 ↑D D.2 ((AddSubgroup.mem_addSubgroupOf).mp hD)))) else 0 set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in theorem FibreModel.piInf_mem_spPlace_nonunits_iff (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (hpole : ∀ a : A, w.ord (jBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) ≤ 0) (b : fm.BInf) : ((fm.piInf b : modularFunctionFieldC k N) ∈ (fm.spPlace hred dataAll hsep w).toValuationSubring.nonunits ↔ ∃ a : A, a ∈ IsLocalRing.maximalIdeal A ∧ ((b : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) ∈ w.toValuationSubring.nonunits) := by have h := not_jBar_mem_compSubring_of_forall_ord_le w hpole constructor · intro hnu have hval := (fm.sp_piInf_nonunits_iff hred dataAll hsep w h b).mp hnu exact ⟨w.value A (Subring.inclusion (fm.binf_le_compSubring w ((fm.chart_dichotomy dataAll w).resolve_left h)) b), hval, w.hasValueAt_value A (Subring.inclusion (fm.binf_le_compSubring w ((fm.chart_dichotomy dataAll w).resolve_left h)) b)⟩ · rintro ⟨a, ha, hval⟩ have ht : ((fm.piInf b : modularFunctionFieldC k N) - algebraMap k (modularFunctionFieldC k N) (red a)) ∈ (fm.spPlace hred dataAll hsep w).toValuationSubring.nonunits := fm.sp_hasValueAt_inf hred dataAll hsep w h b a hval have hred0 : red a = 0 := (@ValuationSubring.ker_eq_maximalIdeal_apply _ _ A _ _ (AlgebraicClosure.instAlgebra ℚ) (AlgebraicClosure.isAlgebraic ℚ) ℓ _ _ red a).mpr ha rwa [hred0, map_zero, sub_zero] at ht set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in theorem FibreModel.piFin_mem_spPlace_nonunits_iff (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (a₀ : A) (ha₀ : 0 < w.ord (jBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a₀ : AlgebraicClosure ℚ))) (b : fm.BFin) : ((fm.piFin b : modularFunctionFieldC k N) ∈ (fm.spPlace hred dataAll hsep w).toValuationSubring.nonunits ↔ ∃ a : A, a ∈ IsLocalRing.maximalIdeal A ∧ ((b : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) ∈ w.toValuationSubring.nonunits) := by have hmem : (jBar N : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ∈ w.compSubring A := w.mem_compSubring_of_hasValueAt a₀.2 (w.hasValueAt_of_ord_pos ha₀) have hspec := fm.sp_spec_fin hred dataAll hsep w hmem b constructor · intro hnu have hcent := hspec.mp hnu rw [FibreModel.centreFin, Ideal.mem_comap] at hcent exact ⟨w.value A (Subring.inclusion (fm.bfin_le_compSubring w hmem) b), (w.mem_centre_iff _).mp hcent, w.hasValueAt_value A (Subring.inclusion (fm.bfin_le_compSubring w hmem) b)⟩ · rintro ⟨a, ha, hval⟩ refine hspec.mpr ?_ rw [FibreModel.centreFin, Ideal.mem_comap] have hval' : w.HasValueAt (Subring.inclusion (fm.bfin_le_compSubring w hmem) b : laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) ↑a := hval exact (w.mem_centre_iff_of_hasValueAt hval').mpr ha set_option maxHeartbeats 800000 in set_option synthInstance.maxHeartbeats 400000 in theorem FibreModel.jLineInv_mem_spPlace (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (w : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N))) (hpole : ∀ a : A, w.ord (jBar N - algebraMap (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull N)) (a : AlgebraicClosure ℚ)) ≤ 0) : (((⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N))⁻¹ ∈ (fm.spPlace hred dataAll hsep w).toValuationSubring) := fm.sp_jLineInv_mem hred dataAll hsep w (not_jBar_mem_compSubring_of_forall_ord_le w hpole) set_option maxHeartbeats 1600000 in set_option synthInstance.maxHeartbeats 400000 in noncomputable def FibreModel.placeSpecializationOf (fm : FibreModel N A ℓ k red) (hred : Function.Surjective red) (dataAll : ∀ (d : ℕ) [NeZero d], d ∣ N → ModularPolynomialData d) (hsep : (((dataAll N (dvd_refl N)).Φ.map (Polynomial.mapRingHom (Int.castRingHom k))).map (algebraMap (Polynomial k) (RatFunc k))).Separable) (data : ModularPolynomialData ℓ) (hKr : KroneckerCongruence ℓ data) (hα : HeckeAlphaBarIntegral (AlgebraicClosure ℚ) N ℓ) (hβ : HeckeBetaBarIntegral (AlgebraicClosure ℚ) N ℓ) (h_d0_j : ∀ w : Place (AlgebraicClosure ℚ) (modularFunctionFieldBar N), ∀ a : A, 0 < w.ord (⟨coeffEmb (AlgebraicClosure ℚ) jq, coeffEmb_mem_laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionField_le_full N (jq_mem N))⟩ - algebraMap (AlgebraicClosure ℚ) (modularFunctionFieldBar N) (a : AlgebraicClosure ℚ)) → 0 < ((fm.spPlace hred dataAll hsep) w).ord (⟨jqModC k, jqModC_mem k N⟩ - algebraMap k (modularFunctionFieldC k N) (red a))) (h_d0_j_pole : ∀ w : Place (AlgebraicClosure ℚ) (modularFunctionFieldBar N), (∀ a : A, w.ord (⟨coeffEmb (AlgebraicClosure ℚ) jq, coeffEmb_mem_laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionField_le_full N (jq_mem N))⟩ - algebraMap (AlgebraicClosure ℚ) (modularFunctionFieldBar N) (a : AlgebraicClosure ℚ)) ≤ 0) → ((fm.spPlace hred dataAll hsep) w).ord (⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N) < 0) (h_d0_jN : ∀ w : Place (AlgebraicClosure ℚ) (modularFunctionFieldBar N), ∀ a : A, 0 < w.ord (⟨coeffEmb (AlgebraicClosure ℚ) (qExpand ℚ N jq), coeffEmb_mem_laurentBaseChange (AlgebraicClosure ℚ) (jqd_mem_full N (dvd_refl N))⟩ - algebraMap (AlgebraicClosure ℚ) (modularFunctionFieldBar N) (a : AlgebraicClosure ℚ)) → 0 < ((fm.spPlace hred dataAll hsep) w).ord (⟨jqNModC k N, jqNModC_mem k N⟩ - algebraMap k (modularFunctionFieldC k N) (red a))) (h_d0_jN_pole : ∀ w : Place (AlgebraicClosure ℚ) (modularFunctionFieldBar N), (∀ a : A, w.ord (⟨coeffEmb (AlgebraicClosure ℚ) (qExpand ℚ N jq), coeffEmb_mem_laurentBaseChange (AlgebraicClosure ℚ) (jqd_mem_full N (dvd_refl N))⟩ - algebraMap (AlgebraicClosure ℚ) (modularFunctionFieldBar N) (a : AlgebraicClosure ℚ)) ≤ 0) → ((fm.spPlace hred dataAll hsep) w).ord (⟨jqNModC k N, jqNModC_mem k N⟩ : modularFunctionFieldC k N) < 0) (h_d1 : ∀ W : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull (N * ℓ))), (fm.spPlace hred dataAll hsep) (W.restrictAlong (heckeAlphaBar (AlgebraicClosure ℚ) N ℓ) hα) = frobOnPlacesGeomLevel k N data hKr ((fm.spPlace hred dataAll hsep) (W.restrictAlong (heckeBetaBar (AlgebraicClosure ℚ) N ℓ) hβ)) ∨ frobOnPlacesGeomLevel k N data hKr ((fm.spPlace hred dataAll hsep) (W.restrictAlong (heckeAlphaBar (AlgebraicClosure ℚ) N ℓ) hα)) = (fm.spPlace hred dataAll hsep) (W.restrictAlong (heckeBetaBar (AlgebraicClosure ℚ) N ℓ) hβ)) (h_d2 : ∀ v : Place (AlgebraicClosure ℚ) (modularFunctionFieldBar N), frobOnPlacesGeomLevel k N data hKr (frobOnPlacesGeomLevel k N data hKr ((fm.spPlace hred dataAll hsep) v)) ≠ (fm.spPlace hred dataAll hsep) v → ∃ W₀ : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull (N * ℓ))), W₀.restrictAlong (heckeBetaBar (AlgebraicClosure ℚ) N ℓ) hβ = v ∧ (fm.spPlace hred dataAll hsep) (W₀.restrictAlong (heckeAlphaBar (AlgebraicClosure ℚ) N ℓ) hα) = frobOnPlacesGeomLevel k N data hKr ((fm.spPlace hred dataAll hsep) v) ∧ W₀.ramificationIndexAlong (heckeBetaBar (AlgebraicClosure ℚ) N ℓ) = 1 ∧ ∀ W : Place (AlgebraicClosure ℚ) (laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionFieldFull (N * ℓ))), W.restrictAlong (heckeBetaBar (AlgebraicClosure ℚ) N ℓ) hβ = v → (fm.spPlace hred dataAll hsep) (W.restrictAlong (heckeAlphaBar (AlgebraicClosure ℚ) N ℓ) hα) = frobOnPlacesGeomLevel k N data hKr ((fm.spPlace hred dataAll hsep) v) → W = W₀) (h_d4 : Function.Surjective (fm.spPlace hred dataAll hsep)) (h_d5 : ∀ f : modularFunctionFieldBar N, f ≠ 0 → ∀ D : Divisor (AlgebraicClosure ℚ) (modularFunctionFieldBar N), (∀ v, D v = v.ord f) → ∃ g : modularFunctionFieldC k N, g ≠ 0 ∧ ∀ v' : Place k (modularFunctionFieldC k N), Finsupp.mapDomain (fm.spPlace hred dataAll hsep) D v' = v'.ord g) (h_d6_inertia : ∀ σ : AlgebraicClosure ℚ ≃ₐ[ℚ] AlgebraicClosure ℚ, σ ∈ A.inertiaSubgroupIn ℚ → ∀ w : Place (AlgebraicClosure ℚ) (modularFunctionFieldBar N), (fm.spPlace hred dataAll hsep) (arithmeticGalois (modularFunctionFieldFull N) σ • w) = (fm.spPlace hred dataAll hsep) w) (h_d6_frobenius : ∀ σ : AlgebraicClosure ℚ ≃ₐ[ℚ] AlgebraicClosure ℚ, A.IsFrobeniusAt σ ℓ → ∀ w : Place (AlgebraicClosure ℚ) (modularFunctionFieldBar N), (fm.spPlace hred dataAll hsep) (arithmeticGalois (modularFunctionFieldFull N) σ • w) = frobOnPlacesGeomLevel k N data hKr ((fm.spPlace hred dataAll hsep) w)) (h_d7_dictInfty : ∀ (w : Place (AlgebraicClosure ℚ) (modularFunctionFieldBar N)) (τ : A) (ht : (⟨coeffEmb (AlgebraicClosure ℚ) (qExpand ℚ N jq), coeffEmb_mem_laurentBaseChange (AlgebraicClosure ℚ) (jqd_mem_full N (dvd_refl N))⟩ : modularFunctionFieldBar N) / (⟨coeffEmb (AlgebraicClosure ℚ) jq, coeffEmb_mem_laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionField_le_full N (jq_mem N))⟩ : modularFunctionFieldBar N) ^ N ∈ w.toValuationSubring), (∀ a : A, w.ord (⟨coeffEmb (AlgebraicClosure ℚ) jq, coeffEmb_mem_laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionField_le_full N (jq_mem N))⟩ - algebraMap (AlgebraicClosure ℚ) (modularFunctionFieldBar N) (a : AlgebraicClosure ℚ)) ≤ 0) → IsLocalRing.residue w.toValuationSubring ⟨_, ht⟩ = algebraMap (AlgebraicClosure ℚ) w.ResidueField (τ : AlgebraicClosure ℚ) → ⟨jqNModC k N, jqNModC_mem k N⟩ / (⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N) ^ N - algebraMap k (modularFunctionFieldC k N) (red τ) = 0 ∨ 0 < ((fm.spPlace hred dataAll hsep) w).ord (⟨jqNModC k N, jqNModC_mem k N⟩ / (⟨jqModC k, jqModC_mem k N⟩ : modularFunctionFieldC k N) ^ N - algebraMap k (modularFunctionFieldC k N) (red τ))) (h_d7_dictZero : ∀ (w : Place (AlgebraicClosure ℚ) (modularFunctionFieldBar N)) (τ : A) (ht : (⟨coeffEmb (AlgebraicClosure ℚ) jq, coeffEmb_mem_laurentBaseChange (AlgebraicClosure ℚ) (modularFunctionField_le_full N (jq_mem N))⟩ : modularFunctionFieldBar N) / (⟨coeffEmb (AlgebraicClosure ℚ) (qExpand ℚ N jq), coeffEmb_mem_laurentBaseChange (AlgebraicClosure ℚ) (jqd_mem_full N (dvd_refl N))⟩ : modularFunctionFieldBar N) ^ N ∈ w.toValuationSubring), (∀ a : A, w.ord (⟨coeffEmb (AlgebraicClosure ℚ) (qExpand ℚ N jq), coeffEmb_mem_laurentBaseChange (AlgebraicClosure ℚ) (jqd_mem_full N (dvd_refl N))⟩ - algebraMap (AlgebraicClosure ℚ) (modularFunctionFieldBar N) (a : AlgebraicClosure ℚ)) ≤ 0) → IsLocalRing.residue w.toValuationSubring ⟨_, ht⟩ = algebraMap (AlgebraicClosure ℚ) w.ResidueField (τ : AlgebraicClosure ℚ) → ⟨jqModC k, jqModC_mem k N⟩ / (⟨jqNModC k N, jqNModC_mem k N⟩ : modularFunctionFieldC k N) ^ N - algebraMap k (modularFunctionFieldC k N) (red τ) = 0 ∨ 0 < ((fm.spPlace hred dataAll hsep) w).ord (⟨jqModC k, jqModC_mem k N⟩ / (⟨jqNModC k N, jqNModC_mem k N⟩ : modularFunctionFieldC k N) ^ N - algebraMap k (modularFunctionFieldC k N) (red τ))) (h_spPic0_compat : ∀ D : Divisor.degZero (K := AlgebraicClosure ℚ) (F := ↥(modularFunctionFieldBar N)), ∃ D' : Divisor.degZero (K := k) (F := ↥(modularFunctionFieldC k N)), (D' : Divisor k (modularFunctionFieldC k N)) = Finsupp.mapDomain (fm.spPlace hred dataAll hsep) (D : Divisor (AlgebraicClosure ℚ) (modularFunctionFieldBar N)) ∧ (fm.spPic0 hred dataAll hsep) (Pic0.mk D) = Pic0.mk D') : PlaceSpecialization A ℓ N data hKr k red hα hβ := ⟨fm.spPlace hred dataAll hsep, fm.spPic0 hred dataAll hsep, h_d0_j, h_d0_j_pole, h_d0_jN, h_d0_jN_pole, h_d1, h_d2, h_d4, h_d5, h_d6_inertia, h_d6_frobenius, h_d7_dictInfty, h_d7_dictZero, h_spPic0_compat⟩ end SpecializationConstruction end CharPModel end ModularCurve
Statements phrased using this module (106)
- Good-reduction specialisation datum for J₀(N), N prime
ModularCurve.CharPModel.FibreModel.exists_jZeroGoodReductionSpecialization_sp_eq_spPic0_of_prime1,099 below · depth 9 - Finite flat model of Eisenstein quotient torsion along `spPic0`
ModularCurve.CharPModel.FibreModel.exists_le_finiteFlat_model_eisensteinQuotient_torsion_spPic0_of_ne_two2,013 below · depth 9 - Packaging the fibre-model specialisation as a place-specialisation packet
ModularCurve.CharPModel.FibreModel.exists_placeSpecialization_spPic0_eq_of_prime998 below · depth 9 - Divisor specialisation preserves degree zero and principality
ModularCurve.CharPModel.FibreModel.spDiv_preservesPrincipal_of_reductionInputs313 below · depth 9 - Normal fibre model with cusp chart for X₀(p)
ModularCurve.CharPModel.exists_fibreModel_cuspChart_integrallyClosed_of_prime743 below · depth 9 - Specialisation on J₀(N) is injective on prime-to-ℓ torsion
ModularCurve.CharPModel.FibreModel.eq_zero_of_spPic0_eq_zero_of_prime_pow_smul_eq_zero_residueField1,002 below · depth 10 - Hecke descent along the fibre specialisation, Eichler–Shimura at ℓ
ModularCurve.CharPModel.FibreModel.exists_heckeDescentFamily_spPic0_and_match_of_prime1,032 below · depth 10 - Specialisation pushforward computes the divisor of the reduced q-expansion
ModularCurve.CharPModel.FibreModel.mapDomain_spPlace_eq_ord_coeffMap292 below · depth 10 - Reduction mod ℓ on J₀(N) equals the constructed specialisation
ModularCurve.CharPModel.FibreModel.reductionModL_eq_pic0Congr_spPic0812 below · depth 10 - Specialisation on Pic⁰ is induced by pushforward of divisors
ModularCurve.CharPModel.FibreModel.spPic0_compat0 below · depth 10 - Finite-chart value dictionary for j under place specialization
ModularCurve.CharPModel.FibreModel.spPlace_d0_j110 below · depth 10 - Specialisation of a place preserves vanishing of j(q^N)-a
ModularCurve.CharPModel.FibreModel.spPlace_d0_jN110 below · depth 10 - Poles of jmath̃_N at places where jmath̄_N has no value in A
ModularCurve.CharPModel.FibreModel.spPlace_d0_jN_pole113 below · depth 10 - Places giving jmath̄ no A-value specialise to j-poles
ModularCurve.CharPModel.FibreModel.spPlace_d0_j_pole113 below · depth 10 - Eichler–Shimura relation at specialised places of X₀(N)
ModularCurve.CharPModel.FibreModel.spPlace_d1_of_cuspChart257 below · depth 10 - Unramified Frobenius lift for the specialisation map, clause d2
ModularCurve.CharPModel.FibreModel.spPlace_d2972 below · depth 10 - Specialisation carries arithmetic Frobenius to geometric Frobenius
ModularCurve.CharPModel.FibreModel.spPlace_d6_frobenius_of_cuspChart263 below · depth 10 - Inertia acts trivially on specialised places
ModularCurve.CharPModel.FibreModel.spPlace_d6_inertia245 below · depth 10 - Cusp dictionary at the j-pole for `spPlace`
ModularCurve.CharPModel.FibreModel.spPlace_d7_dictInfty0 below · depth 10 - Cusp dictionary for j/j_N^N at spPlace, prime level
ModularCurve.CharPModel.FibreModel.spPlace_d7_dictZero_of_prime150 below · depth 10 - Surjectivity of the place specialisation map of a fibre model
ModularCurve.CharPModel.FibreModel.spPlace_surjective111 below · depth 10 - Specialisation of J₀(N) intertwines T_q with the special-fibre operator
ModularCurve.CharPModel.FibreModel.heckePic0Fibre_spPic0_eq_spPic0_heckeGen_smul963 below · depth 11 - Eichler–Shimura congruence on all divisors, squarefree level
ModularCurve.CharPModel.FibreModel.mapDomain_spPlace_heckeDivBar970 below · depth 11 - Reduction of places equals the fibre-model specialisation map
ModularCurve.CharPModel.FibreModel.placeReductionModL_eq_spPlace810 below · depth 11 - Places of the reduced modular field agreeing on the finite chart
ModularCurve.CharPModel.FibreModel.place_eq_of_forall_finChart_mem_nonunits_iff4 below · depth 11 - Specialisation on Pic⁰ computes by divisor pushforward
ModularCurve.CharPModel.FibreModel.spPic0_apply0 below · depth 11 - Cusp-zero dictionary, t-small branch, prime level
ModularCurve.CharPModel.FibreModel.spPlace_d7_dictZero_of_t_small_of_prime145 below · depth 11 - Transported specialisation is a reduction of places mod ℓ
ModularCurve.CharPModel.FibreModel.isPlaceReductionModL_congr_spPlace299 below · depth 12 - Eichler–Shimura relation on specialised principal divisors
ModularCurve.CharPModel.FibreModel.mapDomain_spPlace_heckeDivBar_of_mem_principal788 below · depth 12 - Fibre-model specialisation carries divisors to divisors of reductions
ModularCurve.CharPModel.FibreModel.mapDomain_spPlace_eq_ord_coeffMap_of_surjective293 below · depth 13 - Eichler–Shimura relation on principal divisors, with cusp chart
ModularCurve.CharPModel.FibreModel.mapDomain_spPlace_heckeDivBar_of_mem_principal_of_cuspChart312 below · depth 13 - Divisor specialisation on X₀(N) preserves degree zero and principality
ModularCurve.CharPModel.FibreModel.spDiv_preservesPrincipal_of_not_dvd296 below · depth 13 - Eichler–Shimura relation for the specialisation map on places
ModularCurve.CharPModel.FibreModel.spPlace_d1_of_cuspChart_of_level257 below · depth 13 - Unique unramified β-lift above a singular point, level prime to ℓ
ModularCurve.CharPModel.FibreModel.spPlace_d2_of_derivative_evalEval_eq_zero_of_level975 below · depth 13 - Unique unramified β-lift above a smooth point of the reduced model
ModularCurve.CharPModel.FibreModel.spPlace_d2_of_derivative_evalEval_ne_zero_of_level228 below · depth 13 - Unique unramified crossing place above a Frobenius-moved pole
ModularCurve.CharPModel.FibreModel.spPlace_d2_of_pole_of_cuspChart_of_level833 below · depth 13 - Specialisation transports arithmetic Frobenius to geometric Frobenius
ModularCurve.CharPModel.FibreModel.spPlace_d6_frobenius_of_cuspChart_of_level263 below · depth 13 - Inertia acts trivially on specialised places of X₀(N)
ModularCurve.CharPModel.FibreModel.spPlace_d6_inertia_of_level245 below · depth 13 - Cusp dictionary in the chart j_N/j^N at j-poles
ModularCurve.CharPModel.FibreModel.spPlace_d7_dictInfty_of_level0 below · depth 13 - Cusp dictionary at the j_N-pole in the chart j/j_N^N
ModularCurve.CharPModel.FibreModel.spPlace_d7_dictZero_of_level301 below · depth 13 - Strict points reduce to reduceFst and reduceSnd
ModularCurve.DRModelPackageLevel.compat_reduceFst_reduceSnd_of_sp_eq_spPlace1,848 below · depth 13 - Extension to an A-point of relative Pic⁰ versus good classes
ModularCurve.DRModelPackageLevel.extendsToPlace_pts_iff_isGoodClass3,053 below · depth 13 - Cusp law on the infinity branch for prolongation tuples
ModularCurve.PlaceSpecialization.ProlongationTuple.cuspLawInfty_of_sp_eq_spPlace_of_cuspChart636 below · depth 13 - Values at places over a supersingular node reduce to branch residues
ModularCurve.PlaceSpecialization.ProlongationTuple.hasValue_nodeResidue_red_of_hasValue_of_sp_eq_spPlace862 below · depth 13 - Both residues regular at a Frobenius-square-fixed ordinary affine place
ModularCurve.PlaceSpecialization.ProlongationTuple.ord_residueFst_nonneg_and_ord_residueSnd_nonneg_of_fixed_of_isAffineGeomPlace_of_notMem_ssPlaces_of_sp_eq_spPlace420 below · depth 13 - Charts at every place not fixed by φ²
ModularCurve.PlaceSpecialization.hasCharts_of_sp_eq_spPlace_of_not_dvd644 below · depth 13 - Coordinates for specialisations arising from fibre models
ModularCurve.PlaceSpecialization.hasCoordinates_of_sp_eq_spPlace196 below · depth 13 - Model and order laws pin the place specialisation of X₀(N)
ModularCurve.PlaceSpecialization.sp_eq_spPlace_of_isModel_of_orderLawFixed342 below · depth 13 - Eichler–Shimura relation for sp_* at level N prime to ℓ
ModularCurve.CharPModel.FibreModel.mapDomain_spPlace_heckeDivBar_of_cuspChart_of_level831 below · depth 14 - Type-one β-ramification sum equals one at nodal points
ModularCurve.CharPModel.FibreModel.spPlace_d2_sum_ramification_typeOne_eq_one_of_level973 below · depth 14 - Reduction relation at j-integral functions pins down spPlace P
ModularCurve.CharPModel.FibreModel.spPlace_eq_of_forall_residue_sub_mem_nonunits182 below · depth 14 - Pole-chart place is pinned by the reduction relation
ModularCurve.CharPModel.FibreModel.spPlace_eq_of_forall_residue_sub_mem_nonunits_jInv182 below · depth 14 - Fibre model with cusp chart for X₀(N) at ℓ∤ N
ModularCurve.CharPModel.exists_fibreModel_cuspChart_of_not_dvd743 below · depth 14 - Extension over A implies good class for P
ModularCurve.DRModelPackageLevel.isGoodClass_of_extendsToPlace_pts3,008 below · depth 14 - Strict places reduce to reduceFst, reduceSnd on the Deligne–Rapoport model
ModularCurve.DRModelPackageLevel.placeOfPoint_eq_reduce_of_isModel_of_orderLawFixed1,896 below · depth 14 - Package fibre dictionary and centre-pinned model read equal places
ModularCurve.DRModelPackageLevel.pointEquivPlace_efib_inv_eq_congrRingEquiv_pointEquivPlace_of_finChart_centrePin126 below · depth 14 - Centre pins for the chart-pinned generic fibre of the Igusa scheme
ModularCurve.IgusaScheme.coeffEmb_sub_mem_nonunits_pointEquivPlace_ofGenerator_of_chartPin0 below · depth 14 - Centre pins on special fibres of the Igusa scheme
ModularCurve.IgusaScheme.exists_spBase_and_cuspChart_centrePin_of_genericFibre_iso_ofGenerator815 below · depth 14 - Reduction of Igusa-scheme points matches the fibre model's specialisation of places
ModularCurve.IgusaScheme.pointReduction_eq_congr_spPlace_of_cuspChart_centrePin191 below · depth 14 - Value bridge at a supersingular node over number fields
ModularCurve.PlaceSpecialization.ProlongationTuple.hasValue_nodeResidue_red_of_hasValue_of_mem_nodeIntegersOver_of_sp_eq_spPlace860 below · depth 14 - Charts at affine places not fixed by φ²
ModularCurve.PlaceSpecialization.exists_isChartAt_of_isAffineGeomPlace292 below · depth 14 - Existence of charts at non-affine places off the φ²-fixed locus
ModularCurve.PlaceSpecialization.exists_isChartAt_of_not_isAffineGeomPlace642 below · depth 14 - Eichler–Shimura relation on principal divisors, level prime to ℓ
ModularCurve.CharPModel.FibreModel.mapDomain_spPlace_heckeDivBar_of_mem_principal_of_cuspChart_of_level312 below · depth 15 - Centre-pinned specialisation of places on the finite j-chart
ModularCurve.CharPModel.FibreModel.placeFullC_eq_congr_spPlace_of_finChart_centrePin186 below · depth 15 - Centre-pinned specialisation of places on the pole chart at a cusp
ModularCurve.CharPModel.FibreModel.placeFullC_eq_congr_spPlace_of_infChart_centrePin_of_mem_maximalIdeal184 below · depth 15 - Specialisation of the Hecke correspondence at finite-centre places
ModularCurve.CharPModel.FibreModel.spDiv_heckeDivBar_eq_heckeFibreGeomLevel_of_finiteCentre_of_level972 below · depth 15 - Integral D-points have vanishing component invariant
ModularCurve.DRModelPackageLevel.comp_eq_zero_of_exists_schemeHomOver_of_depthCompLaw_of_abelJacobiPin_of_surjective_red_of_sp_eq_spPlace2,485 below · depth 15 - Value bridge at a supersingular node for j-integral elements
ModularCurve.PlaceSpecialization.ProlongationTuple.exists_hasValue_residue_red_of_mem_jIntegralClosure_of_sp_eq_spPlace834 below · depth 15 - Node integers are fractions with denominator a unit at the node
ModularCurve.PlaceSpecialization.ProlongationTuple.exists_mul_eq_mem_jIntegralClosure_of_mem_nodeIntegersOver_of_sp_eq_spPlace286 below · depth 15 - A fibre model with cusp chart yields a place-specialization packet
ModularCurve.CharPModel.FibreModel.exists_placeSpecialization_spPic0_eq998 below · depth 16 - A charted fibre model realising a place specialization at level N>1
ModularCurve.CharPModel.exists_fibreModel_cuspChart_placeSpecialization_sp_eq_spPlace_of_one_lt1,020 below · depth 16 - Existence of a resolved Deligne–Rapoport model with place–component dictionary
ModularCurve.DRModelPackageLevel.exists_dRResolvedModelPackageLevel_nodeEquiv_swap_nodeCoordinates_of_surjective_of_sp_eq_spPlace2,427 below · depth 16 - Places with nodal value law at w have first reduction w
ModularCurve.PlaceSpecialization.ProlongationTuple.exists_forall_reduceFst_eq_of_forall_hasValue_of_sp_eq_spPlace221 below · depth 16 - Node value law at a supersingular place of level Nq
ModularCurve.PlaceSpecialization.ProlongationTuple.exists_hasValue_iff_hasValue_residueFst_zero_jIntegralClosure_of_sp_eq_spPlace833 below · depth 16 - Agreement of the two residue conditions at a supersingular node
ModularCurve.PlaceSpecialization.ProlongationTuple.exists_hasValue_residueFst_iff_residueSnd_jIntegralClosure_of_sp_eq_spPlace832 below · depth 16 - Cusp dictionary in the chart j/j_N^N at poles of j_N
ModularCurve.CharPModel.FibreModel.spPlace_d7_dictZero303 below · depth 17 - Depth-to-component dictionary for the resolved Deligne–Rapoport model
ModularCurve.DRModelPackageLevel.exists_nodeCoordinates_and_forall_mem_support_iff_chainPos_of_charts_of_sp_eq_spPlace2,052 below · depth 17 - Strict places specialise into one labelled component
ModularCurve.DRModelPackageLevel.exists_swap_forall_isStrict_section_mem_range_comp_of_sp_eq_spPlace1,861 below · depth 17 - Node widths of the resolved model equal place widths
ModularCurve.DRModelPackageLevel.forall_width_eq_of_charts_of_sp_eq_spPlace2,299 below · depth 17 - Non-strict inertia-fixed places specialise to crossings
ModularCurve.DRModelPackageLevel.section_base_closedPoint_eq_crossing_of_reduceFst_mem_of_sp_eq_spPlace1,891 below · depth 17 - Integral closure of k[jmath̄] in the level-N fibre field
ModularCurve.isDedekindDomain_integralClosure_adjoin_jGeomGen_of_separable0 below · depth 17 - Cusp zero-chart specialisation dictionary under a small opposite coordinate
ModularCurve.CharPModel.FibreModel.spPlace_d7_dictZero_of_t_small302 below · depth 18 - Node coordinates and chain position at one supersingular crossing
ModularCurve.DRModelPackageLevel.exists_nodeCoordinates_and_forall_mem_support_iff_chainPos_of_chartPresentation2,007 below · depth 18 - Function field of the O-model inside ℚ̄(X₀(N₀q))
ModularCurve.DRModelPackageLevel.exists_ringHom_functionField_pullback_forall_eq_algebraMap_and_coe_eq_coeffEmb0 below · depth 18 - Strict places orient sections onto the two special-fibre components
ModularCurve.DRModelPackageLevel.forall_isStrict_section_mem_range_comp_zero_comp_one_of_sp_eq_spPlace1,861 below · depth 18 - Integrality of the q-adic base change of the Deligne–Rapoport model
ModularCurve.DRModelPackageLevel.isIntegral_pullback_toBase_specMap3 below · depth 18 - Non-emptiness of the finite Igusa chart over O
ModularCurve.DRModelPackageLevel.nonempty_preimage_iotaFin_pullback_toBase_specMap0 below · depth 18 - Cusp zero-chart dictionary under a small opposite coordinate
ModularCurve.CharPModel.FibreModel.spPlace_d7_dictZero_of_t_small_of_level301 below · depth 19 - Germ of j(q^q)-j^q vanishing along the first component
ModularCurve.DRModelPackageLevel.exists_germ_jq_sub_pow_and_stalkSpecializes_mem_maximalIdeal_comp_zero299 below · depth 19 - Maximal ideals preserved at crossings under base change
ModularCurve.DRModelPackageLevel.map_maximalIdeal_stalkMap_bcMap_eq_of_inertia_grain0 below · depth 19 - Germs at a supersingular crossing lie in the node ring
ModularCurve.DRModelPackageLevel.mem_nodeIntegers_of_stalk_of_specializes_of_nodeEquiv_eq1,993 below · depth 19 - Branch residues and orders at a supersingular crossing
ModularCurve.DRModelPackageLevel.nodeResidue_eq_zero_iff_and_ord_eq_of_specializes_of_mem_maximalIdeal364 below · depth 19 - Crossing coordinates are uniformisers on the two branches
ModularCurve.DRModelPackageLevel.ord_placeOfPoint_stalkMap_eq_one_of_span_eq_maximalIdeal0 below · depth 19 - Evaluation at a place equals pull-back along an O-section
ModularCurve.DRModelPackageLevel.phi_mem_and_evalAt_eq_stalkClosedPointTo_of_section3 below · depth 19 - Crossing points are rational over the inertia ring O
ModularCurve.DRModelPackageLevel.surjective_residue_comp_germ_comp_appTop_of_inertia_grain10 below · depth 19 - Node pack at a supersingular place with no order-one j-difference
ModularCurve.PlaceSpecialization.ProlongationTuple.nodePack_residueField_of_not_ord_sub_pow_sq_eq_one_or1,764 below · depth 19 - Node pack at supersingular places over κ_A
ModularCurve.PlaceSpecialization.ProlongationTuple.nodePack_residueField_of_ord_sub_pow_sq_eq_one_or1,764 below · depth 19 - A-points above supersingular places specialise to the crossing
ModularCurve.DRModelPackageLevel.base_closedPoint_eq_crossing_of_reduceFst_eq_of_sp_eq_spPlace1,891 below · depth 20 - Branch germs read as Gauss residues on X₀(N₀)_{κ_A}
ModularCurve.DRModelPackageLevel.ffEquiv_symm_stalkMap_genericPoint_eq_residue_phi363 below · depth 20 - Germs at a point met by both branches lie in both prolongations
ModularCurve.DRModelPackageLevel.mem_integers_and_mem_integers_of_stalk_of_specializes361 below · depth 20 - Branch generic stalks map into the two Gauss prolongations
ModularCurve.DRModelPackageLevel.phi_algebraMap_stalk_mem_integers_comp_genericPoint360 below · depth 20 - Chart-pinned readings agree at the generic point
ModularCurve.DRModelPackageLevel.specMap_comp_fromSpecStalk_genericPoint_comp_fst_eq_of_coe_eq_coeffEmb0 below · depth 20 - Node integers at a supersingular place are local and noetherian
ModularCurve.PlaceSpecialization.ProlongationTuple.isLocalRing_and_isNoetherianRing_nodeIntegersOver_of_sp_eq_spPlace870 below · depth 20 - Saturation of the two node residues at a supersingular place
ModularCurve.PlaceSpecialization.ProlongationTuple.nodeResidue_saturated_of_sp_eq_spPlace_residueField1,762 below · depth 20 - Fibre-model independence of the specialisation of places
ModularCurve.CharPModel.FibreModel.spPlace_eq_of_surjective749 below · depth 21 - Fibre-model independence of the specialisation of places
ModularCurve.CharPModel.FibreModel.spPlace_eq745 below · depth 22