Definitions/Def_WeierstrassCurve_ZeroComponentReduction.lean
Formal coordinates, kernel of reduction, zero component of Weierstrass models
Throughout, A is a valuation subring of a field L, with maximal ideal the set A.nonunits of elements of valuation <1 and residue field k, and W is a Weierstrass model over A; points are taken on the base change W to L and, after reduction, on the base change of W along A \to k. FormalCoordinates A G d is a structure packaging axiomatic formal-group data on an additive group G: a subgroup disc, a coordinate map G \to (\mathrm{Fin}\,d \to L), and as fields the assertions that all coordinates of members of disc lie in A.nonunits, that a member of disc with vanishing coordinates is 0, that 0 has vanishing coordinates, and the estimate that for P \in disc, n \in \mathbb{N} and each index i one has \mathrm{coord}(nP)_i - n\,\mathrm{coord}(P)_i = \sum_j c_j \mathrm{coord}(P)_j for some c_j of valuation <1. From these, FormalCoordinates.eq_zero_of_nsmul_eq_zero shows that if n is a unit of A then no nonzero element of disc is killed by n; FormalCoordinates.additive instantiates the structure on (\mathfrak m_A)^d with the identity coordinates.
WeierstrassCurve.formalParam sends O \mapsto 0 and (x,y) \mapsto -x/y; IsNonIntegral W P asserts that whenever P is the affine point (x,y) one has x \notin A (so O qualifies vacuously), and nonIntegralLocus is the resulting subgroup, closure under addition being proved through a common-depth choice of parameter and the formal-parameter estimate for addition. formalCoordinates exhibits this subgroup as formal-coordinate data of length 1 with coordinate -x/y, whence X_mem_of_nsmul_eq_zero_of_formalCoordinates: if n \neq 0 in k and n \cdot (x,y) = O, then x \in A.
HasNonsingularReduction W P asserts that whenever P = (x,y) with x, y \in A, the reduced pair (\bar x, \bar y) is a nonsingular point of W over k; it holds vacuously at O and at non-integral points, and holds for all points when the reduced discriminant is nonzero. reducePointSmooth sends O to O, an affine point with x \in A and nonsingular reduction to its reduction, and all other points to O; it commutes with negation and agrees with the reduction map reducePoint when the reduced discriminant is nonzero. zeroComponentSubgroup is the subgroup of points with nonsingular reduction; the case analysis behind its closure under addition — with valuation estimates on slopes and on addX — also yields that reducePointSmooth is additive on it. SmoothLocusReductionData is a structure carrying a subgroup, the assertion that its members are exactly the points with nonsingular reduction, and the additivity of reducePointSmooth on it; any such datum has underlying subgroup zeroComponentSubgroup, gives a homomorphism reduceHom₀ to the points of the reduced curve whose kernel is exactly nonIntegralLocus, and the canonical datum is smoothLocusReductionData. Auxiliary lemmas record that integers are units of A when not in A.nonunits, that nonIntegralLocus is contained in zeroComponentSubgroup, that the latter is everything under good reduction, and decidability of the Weierstrass equation and nonsingularity conditions over a ring with decidable equality.
Relation to Mathlib
Mathlib supplies WeierstrassCurve, affine point groups and ValuationSubring with its residue field, but has no formal-group coordinate data, no kernel of reduction and no zero component for a Weierstrass model over a valuation ring; these, together with the smooth-locus reduction map reducePointSmooth, are the project's own notions, and reducePointSmooth is compared with the project's good-reduction map reducePoint.
Where it is used
These local notions support the study of torsion on the Frey curve: the formal-coordinate argument gives integrality of the coordinates of a point whose order is invertible in the residue field, and the zero component with its reduction homomorphism is the setting in which a rational point of prime order is located relative to the components of the special fibre at a prime of multiplicative reduction.
References
- J. H. Silverman, The Arithmetic of Elliptic Curves, Graduate Texts in Mathematics 106, Springer, 1986, Ch. VII §2
- S. Bosch, W. Lütkebohmert and M. Raynaud, Néron Models, Ergebnisse der Mathematik und ihrer Grenzgebiete 21, Springer, 1990
References are suggested automatically and have not been individually verified.
English text generated automatically from the Lean source; the Lean statement is authoritative.
- 1,104 lines
- 77 declarations
- used in the statements of 0 theorems and imported by 3 proofs
- imports 1 definition modules
Source file: Definitions/Def_WeierstrassCurve_ZeroComponentReduction.lean
Imported by
- no other definition module
Declarations
- theorem
ValuationSubring.valuation_eq_one_of_notMem_nonunits - theorem
ValuationSubring.natCast_mem - theorem
ValuationSubring.valuation_natCast_eq_one - structure
FormalCoordinates - field
FormalCoordinates.d - field
FormalCoordinates.disc - field
FormalCoordinates.coord - field
FormalCoordinates.coord_mem_nonunits - field
FormalCoordinates.eq_zero_of_coord_eq_zero - field
FormalCoordinates.coord_zero - field
FormalCoordinates.coord_nsmul_sub - field
FormalCoordinates.coord - theorem
FormalCoordinates.exists_dominant_coord - theorem
FormalCoordinates.eq_zero_of_nsmul_eq_zero - def
FormalCoordinates.additive - instance
ModularCurve.ElevenA1.instDecidableEquation - instance
ModularCurve.ElevenA1.instDecidableNonsingular - def
WeierstrassCurve.formalParam - theorem
WeierstrassCurve.formalParam_zero - theorem
WeierstrassCurve.formalParam_some - def
WeierstrassCurve.IsNonIntegral - theorem
WeierstrassCurve.isNonIntegral_zero - theorem
WeierstrassCurve.isNonIntegral_some_iff - theorem
WeierstrassCurve.exists_common_depth - def
WeierstrassCurve.nonIntegralLocus - theorem
WeierstrassCurve.mem_nonIntegralLocus_some_iff - def
WeierstrassCurve.formalCoordinates - theorem
WeierstrassCurve.X_mem_of_nsmul_eq_zero_of_formalCoordinates - def
WeierstrassCurve.HasNonsingularReduction - theorem
WeierstrassCurve.hasNonsingularReduction_zero - theorem
WeierstrassCurve.hasNonsingularReduction_some_iff - theorem
WeierstrassCurve.hasNonsingularReduction_some_of_notMem - theorem
WeierstrassCurve.hasNonsingularReduction_of_good - theorem
WeierstrassCurve.hasNonsingularReduction_of_isNonIntegral - theorem
WeierstrassCurve.hasNonsingularReduction_neg - theorem
WeierstrassCurve.isNonIntegral_of_mem_nonIntegralLocus - theorem
WeierstrassCurve.hasNonsingularReduction_of_mem_nonIntegralLocus - lemma
WeierstrassCurve.some_smoothLocus_congr - def
WeierstrassCurve.reducePointSmooth - theorem
WeierstrassCurve.reducePointSmooth_zero - theorem
WeierstrassCurve.reducePointSmooth_some_of_mem - theorem
WeierstrassCurve.reducePointSmooth_some_of_notMem - theorem
WeierstrassCurve.reducePointSmooth_some_of_singular - theorem
WeierstrassCurve.reducePointSmooth_eq_reducePoint - theorem
WeierstrassCurve.reducePointSmooth_neg - theorem
WeierstrassCurve.reducePointSmooth_eq_zero_of_mem_nonIntegralLocus - theorem
WeierstrassCurve.mem_nonIntegralLocus_of_reducePointSmooth_eq_zero - theorem
WeierstrassCurve.Affine.notMem_nonunits_of_sub_negY_mem_nonunits_of_nonsingular_residue - theorem
WeierstrassCurve.Affine.slope_notMem_of_sub_mem_nonunits_of_nonsingular_residue - theorem
WeierstrassCurve.Affine.addX_notMem_of_sub_mem_nonunits_of_nonsingular_residue - structure
WeierstrassCurve.SmoothLocusReductionData - field
WeierstrassCurve.SmoothLocusReductionData.zeroComponent - field
WeierstrassCurve.SmoothLocusReductionData.mem_iff - field
WeierstrassCurve.SmoothLocusReductionData.reducePointSmooth_add - theorem
WeierstrassCurve.SmoothLocusReductionData.nonIntegralLocus_le - theorem
WeierstrassCurve.SmoothLocusReductionData.zero_mem - def
WeierstrassCurve.SmoothLocusReductionData.reduceHom₀ - theorem
WeierstrassCurve.SmoothLocusReductionData.reduceHom₀_apply - theorem
WeierstrassCurve.SmoothLocusReductionData.reduceHom₀_eq_zero_iff - lemma
WeierstrassCurve.some_smoothClosure_congr - theorem
WeierstrassCurve.addX_mem_of_not_inverse - theorem
WeierstrassCurve.addY_mem_of_not_inverse - theorem
WeierstrassCurve.residue_addX_of_not_inverse - theorem
WeierstrassCurve.residue_addY_of_not_inverse - lemma
WeierstrassCurve.addAux_of_mem_of_mem - lemma
WeierstrassCurve.addAux_of_notMem_of_notMem - lemma
WeierstrassCurve.addAux_of_mem_of_notMem - theorem
WeierstrassCurve.hasNonsingularReduction_add - theorem
WeierstrassCurve.reducePointSmooth_add_of_hasNonsingularReduction - def
WeierstrassCurve.zeroComponentSubgroup - theorem
WeierstrassCurve.mem_zeroComponentSubgroup_iff - def
WeierstrassCurve.smoothLocusReductionData - theorem
WeierstrassCurve.smoothLocusReductionData_zeroComponent - theorem
WeierstrassCurve.nonempty_smoothLocusReductionData - theorem
WeierstrassCurve.SmoothLocusReductionData.zeroComponent_eq - theorem
WeierstrassCurve.zeroComponentSubgroup_eq_top_of_good - theorem
WeierstrassCurve.nonIntegralLocus_le_zeroComponentSubgroup
Source
import Mathlib import Definitions.Def_WeierstrassCurve_ReduceHom set_option autoImplicit false open IsLocalRing Finset namespace ValuationSubring variable {L : Type*} [Field L] (A : ValuationSubring L) theorem valuation_eq_one_of_notMem_nonunits {a : L} (haA : a ∈ A) (ha : a ∉ A.nonunits) : A.valuation a = 1 := le_antisymm ((A.valuation_le_one_iff a).mpr haA) (not_lt.mp fun h => ha (A.mem_nonunits_iff.mpr h)) theorem natCast_mem (n : ℕ) : (n : L) ∈ A := by simp theorem valuation_natCast_eq_one {n : ℕ} (hn : (n : L) ∉ A.nonunits) : A.valuation (n : L) = 1 := A.valuation_eq_one_of_notMem_nonunits (A.natCast_mem n) hn end ValuationSubring variable {L : Type*} [Field L] structure FormalCoordinates (A : ValuationSubring L) (G : Type*) [AddCommGroup G] (d : ℕ) where disc : AddSubgroup G coord : G → Fin d → L coord_mem_nonunits : ∀ P ∈ disc, ∀ i, coord P i ∈ A.nonunits eq_zero_of_coord_eq_zero : ∀ P ∈ disc, (∀ i, coord P i = 0) → P = 0 coord_zero : ∀ i, coord 0 i = 0 coord_nsmul_sub : ∀ P ∈ disc, ∀ (n : ℕ) (i : Fin d), ∃ c : Fin d → L, (∀ j, c j ∈ A.nonunits) ∧ coord (n • P) i - n * coord P i = ∑ j, c j * coord P j namespace FormalCoordinates variable {A : ValuationSubring L} {G : Type*} [AddCommGroup G] {d : ℕ} theorem exists_dominant_coord (F : FormalCoordinates A G d) {P : G} {i₁ : Fin d} (hi₁ : F.coord P i₁ ≠ 0) : ∃ i₀, F.coord P i₀ ≠ 0 ∧ ∀ j, A.valuation (F.coord P j) ≤ A.valuation (F.coord P i₀) := by obtain ⟨i₀, -, hi₀⟩ := Finset.exists_max_image Finset.univ (fun i => A.valuation (F.coord P i)) ⟨i₁, Finset.mem_univ _⟩ refine ⟨i₀, fun h0 => hi₁ ?_, fun j => hi₀ j (Finset.mem_univ _)⟩ have h := hi₀ i₁ (Finset.mem_univ _) rw [h0, map_zero, le_zero_iff] at h exact (Valuation.zero_iff _).mp h theorem eq_zero_of_nsmul_eq_zero (F : FormalCoordinates A G d) {n : ℕ} (hn : (n : L) ∉ A.nonunits) {P : G} (hP : P ∈ F.disc) (h : n • P = 0) : P = 0 := by by_contra hP0 obtain ⟨i₁, hi₁⟩ : ∃ i, F.coord P i ≠ 0 := by by_contra hall push Not at hall exact hP0 (F.eq_zero_of_coord_eq_zero P hP hall) obtain ⟨i₀, hi₀ne, hi₀⟩ := F.exists_dominant_coord hi₁ have hv₀ : A.valuation (F.coord P i₀) ≠ 0 := (Valuation.ne_zero_iff _).mpr hi₀ne obtain ⟨c, hc, hest⟩ := F.coord_nsmul_sub P hP n i₀ have hcorr : A.valuation (∑ j, c j * F.coord P j) < A.valuation (F.coord P i₀) := by refine Valuation.map_sum_lt _ hv₀ fun j _ => ?_ rw [map_mul] calc A.valuation (c j) * A.valuation (F.coord P j) ≤ A.valuation (c j) * A.valuation (F.coord P i₀) := by gcongr exact hi₀ j _ = A.valuation (F.coord P i₀) * A.valuation (c j) := mul_comm _ _ _ < A.valuation (F.coord P i₀) * 1 := by have hk : A.valuation (c j) < 1 := A.mem_nonunits_iff.mp (hc j) exact lt_of_le_of_ne (mul_le_mul_right hk.le _) fun heq => (ne_of_lt hk) (mul_left_cancel₀ hv₀ heq) _ = A.valuation (F.coord P i₀) := mul_one _ have hlead : A.valuation ((n : L) * F.coord P i₀) = A.valuation (F.coord P i₀) := by rw [map_mul, A.valuation_natCast_eq_one hn, one_mul] have hkey : A.valuation (F.coord (n • P) i₀) = A.valuation (F.coord P i₀) := by have hsum : F.coord (n • P) i₀ = (n : L) * F.coord P i₀ + ∑ j, c j * F.coord P j := by rw [← hest]; ring rw [hsum, Valuation.map_add_eq_of_lt_left _ (hlead.symm ▸ hcorr), hlead] rw [h, F.coord_zero i₀, map_zero] at hkey exact hv₀ hkey.symm def additive (A : ValuationSubring L) (d : ℕ) : FormalCoordinates A (Fin d → L) d where disc := AddSubgroup.pi Set.univ fun _ => A.nonunits.toAddSubgroup coord f := f coord_mem_nonunits f hf i := hf i (Set.mem_univ i) eq_zero_of_coord_eq_zero f _ hf := funext hf coord_zero _ := rfl coord_nsmul_sub f _ n i := by refine ⟨fun _ => 0, fun _ => A.nonunits.zero_mem, ?_⟩ simp [Pi.smul_apply, nsmul_eq_mul] end FormalCoordinates set_option autoImplicit false namespace ModularCurve namespace ElevenA1 open WeierstrassCurve Affine section Count variable {K : Type*} [CommRing K] (W : WeierstrassCurve.Affine K) instance instDecidableEquation [DecidableEq K] (x y : K) : Decidable (W.Equation x y) := decidable_of_iff _ (W.equation_iff x y).symm instance instDecidableNonsingular [DecidableEq K] (x y : K) : Decidable (W.Nonsingular x y) := decidable_of_iff _ (W.nonsingular_iff x y).symm end Count end ElevenA1 end ModularCurve set_option autoImplicit false open IsLocalRing ValuationSubring WeierstrassCurve.Affine WeierstrassCurve.Affine.Point namespace WeierstrassCurve variable {L : Type*} [Field L] {A : ValuationSubring L} (W : WeierstrassCurve A) def formalParam : (W.map A.subtype).toAffine.Point → L | .zero => 0 | .some x y _ => -(x / y) @[simp] theorem formalParam_zero : W.formalParam 0 = 0 := rfl @[simp] theorem formalParam_some {x y : L} (h : (W.map A.subtype).toAffine.Nonsingular x y) : W.formalParam (some x y h) = -(x / y) := rfl def IsNonIntegral (P : (W.map A.subtype).toAffine.Point) : Prop := ∀ x y (h : (W.map A.subtype).toAffine.Nonsingular x y), P = some x y h → x ∉ A theorem isNonIntegral_zero : W.IsNonIntegral 0 := fun _ _ h heq => absurd heq (Ne.symm (some_ne_zero h)) theorem isNonIntegral_some_iff {x y : L} (h : (W.map A.subtype).toAffine.Nonsingular x y) : W.IsNonIntegral (some x y h) ↔ x ∉ A := by refine ⟨fun hP => hP x y h rfl, fun hx x' y' h' heq => ?_⟩ obtain ⟨rfl, rfl⟩ : x = x' ∧ y = y' := by rwa [Affine.Point.some.injEq] at heq exact hx theorem exists_common_depth {x₁ y₁ x₂ y₂ : L} (h₁ : (W.map A.subtype).toAffine.Equation x₁ y₁) (h₂ : (W.map A.subtype).toAffine.Equation x₂ y₂) (hx₁ : x₁ ∉ A) (hx₂ : x₂ ∉ A) : ∃ τ : L, τ ∈ A.nonunits ∧ τ ≠ 0 ∧ (x₁ / y₁) / τ ∈ A ∧ (x₂ / y₂) / τ ∈ A := by have hy₁0 : y₁ ≠ 0 := Y_ne_zero_of_X_notMem W h₁ hx₁ have hy₂0 : y₂ ≠ 0 := Y_ne_zero_of_X_notMem W h₂ hx₂ have hx₁0 : x₁ ≠ 0 := fun h0 => hx₁ (h0 ▸ A.zero_mem) have hx₂0 : x₂ ≠ 0 := fun h0 => hx₂ (h0 ▸ A.zero_mem) have ht₁0 : x₁ / y₁ ≠ 0 := div_ne_zero hx₁0 hy₁0 have ht₂0 : x₂ / y₂ ≠ 0 := div_ne_zero hx₂0 hy₂0 rcases A.mem_or_inv_mem ((x₁ / y₁) / (x₂ / y₂)) with hd | hd · exact ⟨x₂ / y₂, X_div_Y_mem_nonunits W h₂ hx₂, ht₂0, hd, by rw [div_self ht₂0]; exact A.one_mem⟩ · rw [show ((x₁ / y₁) / (x₂ / y₂))⁻¹ = (x₂ / y₂) / (x₁ / y₁) by rw [inv_div]] at hd exact ⟨x₁ / y₁, X_div_Y_mem_nonunits W h₁ hx₁, ht₁0, by rw [div_self ht₁0]; exact A.one_mem, hd⟩ variable [DecidableEq L] def nonIntegralLocus : AddSubgroup (W.map A.subtype).toAffine.Point where carrier := {P | W.IsNonIntegral P} zero_mem' := W.isNonIntegral_zero neg_mem' := by rintro (_ | @⟨a, b, hab⟩) hP · exact W.isNonIntegral_zero · rw [neg_some] exact (W.isNonIntegral_some_iff _).mpr ((W.isNonIntegral_some_iff hab).mp hP) add_mem' := by rintro (_ | @⟨x₁, y₁, h₁⟩) (_ | @⟨x₂, y₂, h₂⟩) hP hQ · simpa [← Affine.Point.zero_def] using W.isNonIntegral_zero · simpa [← Affine.Point.zero_def] using hQ · simpa [← Affine.Point.zero_def] using hP · have hx₁ : x₁ ∉ A := (W.isNonIntegral_some_iff h₁).mp hP have hx₂ : x₂ ∉ A := (W.isNonIntegral_some_iff h₂).mp hQ by_cases hxy : x₁ = x₂ ∧ y₁ = (W.map A.subtype).toAffine.negY x₂ y₂ · rw [add_of_Y_eq hxy.1 hxy.2] exact W.isNonIntegral_zero · rw [add_some hxy] obtain ⟨τ, hτ, hτ0, ht₁, ht₂⟩ := W.exists_common_depth h₁.1 h₂.1 hx₁ hx₂ exact (W.isNonIntegral_some_iff _).mpr (add_formal_param_estimate (W := W) h₁.1 h₂.1 hx₁ hx₂ hxy hτ hτ0 ht₁ ht₂).1 theorem mem_nonIntegralLocus_some_iff {x y : L} (h : (W.map A.subtype).toAffine.Nonsingular x y) : some x y h ∈ W.nonIntegralLocus ↔ x ∉ A := W.isNonIntegral_some_iff h def formalCoordinates : FormalCoordinates A (W.map A.subtype).toAffine.Point 1 where disc := W.nonIntegralLocus coord P _ := W.formalParam P coord_mem_nonunits := by rintro (_ | @⟨x, y, h⟩) hP i · exact A.nonunits.zero_mem · exact A.nonunits.neg_mem (X_div_Y_mem_nonunits W h.1 ((W.mem_nonIntegralLocus_some_iff h).mp hP)) eq_zero_of_coord_eq_zero := by rintro (_ | @⟨x, y, h⟩) hP hcoord · rfl · exfalso have hx : x ∉ A := (W.mem_nonIntegralLocus_some_iff h).mp hP have hy0 : y ≠ 0 := Y_ne_zero_of_X_notMem W h.1 hx have h0 := hcoord 0 rw [formalParam_some, neg_eq_zero, div_eq_zero_iff] at h0 exact hx ((h0.resolve_right hy0) ▸ A.zero_mem) coord_zero _ := rfl coord_nsmul_sub := by rintro (_ | @⟨x, y, h⟩) hP n i · exact ⟨fun _ => 0, fun _ => A.nonunits.zero_mem, by simp [← Affine.Point.zero_def]⟩ · have hx : x ∉ A := (W.mem_nonIntegralLocus_some_iff h).mp hP have hy0 : y ≠ 0 := Y_ne_zero_of_X_notMem W h.1 hx have hx0 : x ≠ 0 := fun h0 => hx (h0 ▸ A.zero_mem) have hτ0 : -(x / y) ≠ 0 := neg_ne_zero.mpr (div_ne_zero hx0 hy0) obtain ⟨hzero, haffine⟩ := formal_param_nsmul (W := W) h hx n rcases hnP : (n • (some x y h : (W.map A.subtype).toAffine.Point)) with _ | @⟨x', y', h'⟩ · refine ⟨fun _ => -(n : L), fun _ => A.nonunits.neg_mem (hzero hnP), ?_⟩ simp only [Fin.sum_univ_one, ← Affine.Point.zero_def, formalParam_zero, formalParam_some] ring · obtain ⟨-, hcong⟩ := haffine x' y' h' hnP refine ⟨fun _ => -(x' / y') / -(x / y) - (n : L), fun _ => hcong, ?_⟩ simp only [Fin.sum_univ_one, formalParam_some] rw [sub_mul, div_mul_cancel₀ _ hτ0] theorem X_mem_of_nsmul_eq_zero_of_formalCoordinates {n : ℕ} (hn : (n : ResidueField A) ≠ 0) {x y : L} (h : (W.map A.subtype).toAffine.Nonsingular x y) (hP : n • (some x y h : (W.map A.subtype).toAffine.Point) = 0) : x ∈ A := by by_contra hx refine some_ne_zero h (W.formalCoordinates.eq_zero_of_nsmul_eq_zero ?_ ((W.mem_nonIntegralLocus_some_iff h).mpr hx) hP) rw [A.natCast_mem_nonunits_iff_residue_eq_zero] exact hn end WeierstrassCurve set_option autoImplicit false open IsLocalRing namespace WeierstrassCurve section General variable {L : Type*} [Field L] {A : ValuationSubring L} (W : WeierstrassCurve A) def HasNonsingularReduction (P : (W.map A.subtype).toAffine.Point) : Prop := ∀ x y (h : (W.map A.subtype).toAffine.Nonsingular x y), P = .some x y h → ∀ (hx : x ∈ A) (hy : y ∈ A), (W.map (residue A)).toAffine.Nonsingular (residue A ⟨x, hx⟩) (residue A ⟨y, hy⟩) theorem hasNonsingularReduction_zero : W.HasNonsingularReduction 0 := fun _ _ h heq => absurd heq (Ne.symm (Affine.Point.some_ne_zero h)) theorem hasNonsingularReduction_some_iff {x y : L} (h : (W.map A.subtype).toAffine.Nonsingular x y) : W.HasNonsingularReduction (.some x y h) ↔ ∀ (hx : x ∈ A) (hy : y ∈ A), (W.map (residue A)).toAffine.Nonsingular (residue A ⟨x, hx⟩) (residue A ⟨y, hy⟩) := by refine ⟨fun hP hx hy => hP x y h rfl hx hy, fun hns x' y' h' heq hx' hy' => ?_⟩ obtain ⟨rfl, rfl⟩ : x = x' ∧ y = y' := by rwa [Affine.Point.some.injEq] at heq exact hns hx' hy' theorem hasNonsingularReduction_some_of_notMem {x y : L} (h : (W.map A.subtype).toAffine.Nonsingular x y) (hx : x ∉ A) : W.HasNonsingularReduction (.some x y h) := (W.hasNonsingularReduction_some_iff h).mpr fun hx' _ => absurd hx' hx theorem hasNonsingularReduction_of_good (hΔ : (W.map (residue A)).Δ ≠ 0) (P : (W.map A.subtype).toAffine.Point) : W.HasNonsingularReduction P := fun _ _ h _ _ _ => Affine.nonsingular_residue W hΔ h.1 theorem hasNonsingularReduction_of_isNonIntegral {P : (W.map A.subtype).toAffine.Point} (hP : W.IsNonIntegral P) : W.HasNonsingularReduction P := fun x y h heq hx _ => absurd hx (hP x y h heq) theorem hasNonsingularReduction_neg {P : (W.map A.subtype).toAffine.Point} (hP : W.HasNonsingularReduction P) : W.HasNonsingularReduction (-P) := by cases P with | zero => show W.HasNonsingularReduction (-(0 : (W.map A.subtype).toAffine.Point)) rw [Affine.Point.neg_zero] exact W.hasNonsingularReduction_zero | some x y h => rw [Affine.Point.neg_some] rw [W.hasNonsingularReduction_some_iff] at hP rw [W.hasNonsingularReduction_some_iff] intro hx hy' have hy : y ∈ A := Affine.Y_mem_of_X_mem W h.1 hx have hns := hP hx hy have hkey : residue A (⟨(W.map A.subtype).toAffine.negY x y, hy'⟩ : A) = (W.map (residue A)).toAffine.negY (residue A ⟨x, hx⟩) (residue A ⟨y, hy⟩) := by rw [A.residue_eq_of_coe_eq hy' (v := W.toAffine.negY ⟨x, hx⟩ ⟨y, hy⟩) (coe_negY hx hy).symm] exact residue_negY hx hy rw [hkey] exact (Affine.nonsingular_neg ..).mpr hns section NonIntegralLocus variable [DecidableEq L] theorem isNonIntegral_of_mem_nonIntegralLocus {P : (W.map A.subtype).toAffine.Point} (hP : P ∈ W.nonIntegralLocus) : W.IsNonIntegral P := fun _ _ h heq => (W.mem_nonIntegralLocus_some_iff h).mp (heq ▸ hP) theorem hasNonsingularReduction_of_mem_nonIntegralLocus {P : (W.map A.subtype).toAffine.Point} (hP : P ∈ W.nonIntegralLocus) : W.HasNonsingularReduction P := W.hasNonsingularReduction_of_isNonIntegral (W.isNonIntegral_of_mem_nonIntegralLocus hP) end NonIntegralLocus private lemma some_smoothLocus_congr {R : Type*} [CommRing R] {V : Affine R} {x₁ x₂ y₁ y₂ : R} (hx : x₁ = x₂) (hy : y₁ = y₂) (h₁ : V.Nonsingular x₁ y₁) (h₂ : V.Nonsingular x₂ y₂) : Affine.Point.some x₁ y₁ h₁ = Affine.Point.some x₂ y₂ h₂ := by subst hx; subst hy; rfl open Classical in noncomputable def reducePointSmooth : (W.map A.subtype).toAffine.Point → (W.map (residue A)).toAffine.Point | .zero => .zero | .some x y h => if hx : x ∈ A then if hns : (W.map (residue A)).toAffine.Nonsingular (residue A ⟨x, hx⟩) (residue A ⟨y, Affine.Y_mem_of_X_mem W h.1 hx⟩) then .some _ _ hns else .zero else .zero @[simp] theorem reducePointSmooth_zero : W.reducePointSmooth 0 = 0 := rfl theorem reducePointSmooth_some_of_mem {x y : L} (h : (W.map A.subtype).toAffine.Nonsingular x y) (hx : x ∈ A) {hy : y ∈ A} (hns : (W.map (residue A)).toAffine.Nonsingular (residue A ⟨x, hx⟩) (residue A ⟨y, hy⟩)) : W.reducePointSmooth (.some x y h) = .some (residue A ⟨x, hx⟩) (residue A ⟨y, hy⟩) hns := by simp only [reducePointSmooth] rw [dif_pos hx] exact dif_pos hns theorem reducePointSmooth_some_of_notMem {x y : L} (h : (W.map A.subtype).toAffine.Nonsingular x y) (hx : x ∉ A) : W.reducePointSmooth (.some x y h) = 0 := by simp only [reducePointSmooth] exact dif_neg hx theorem reducePointSmooth_some_of_singular {x y : L} (h : (W.map A.subtype).toAffine.Nonsingular x y) (hx : x ∈ A) {hy : y ∈ A} (hsing : ¬ (W.map (residue A)).toAffine.Nonsingular (residue A ⟨x, hx⟩) (residue A ⟨y, hy⟩)) : W.reducePointSmooth (.some x y h) = 0 := by simp only [reducePointSmooth] rw [dif_pos hx] exact dif_neg fun hcon => hsing hcon theorem reducePointSmooth_eq_reducePoint (hΔ : (W.map (residue A)).Δ ≠ 0) (P : (W.map A.subtype).toAffine.Point) : W.reducePointSmooth P = reducePoint hΔ P := by cases P with | zero => rfl | some x y h => by_cases hx : x ∈ A · rw [W.reducePointSmooth_some_of_mem h hx (Affine.nonsingular_residue W hΔ (x := ⟨x, hx⟩) (y := ⟨y, Affine.Y_mem_of_X_mem W h.1 hx⟩) h.1), reducePoint_some_of_mem _ _ hx] · rw [W.reducePointSmooth_some_of_notMem h hx, reducePoint_some_of_notMem _ _ hx] theorem reducePointSmooth_neg (P : (W.map A.subtype).toAffine.Point) : W.reducePointSmooth (-P) = -W.reducePointSmooth P := by cases P with | zero => show W.reducePointSmooth (-(0 : (W.map A.subtype).toAffine.Point)) = -W.reducePointSmooth (0 : (W.map A.subtype).toAffine.Point) rw [Affine.Point.neg_zero, reducePointSmooth_zero, Affine.Point.neg_zero] | some x y h => rw [Affine.Point.neg_some] by_cases hx : x ∈ A · have hy : y ∈ A := Affine.Y_mem_of_X_mem W h.1 hx have hy' : (W.map A.subtype).toAffine.negY x y ∈ A := negY_mem hx hy have hkey : residue A (⟨(W.map A.subtype).toAffine.negY x y, hy'⟩ : A) = (W.map (residue A)).toAffine.negY (residue A ⟨x, hx⟩) (residue A ⟨y, hy⟩) := by rw [A.residue_eq_of_coe_eq hy' (v := W.toAffine.negY ⟨x, hx⟩ ⟨y, hy⟩) (coe_negY hx hy).symm] exact residue_negY hx hy by_cases hns : (W.map (residue A)).toAffine.Nonsingular (residue A ⟨x, hx⟩) (residue A ⟨y, hy⟩) · have hns' : (W.map (residue A)).toAffine.Nonsingular (residue A ⟨x, hx⟩) (residue A ⟨(W.map A.subtype).toAffine.negY x y, hy'⟩) := by rw [hkey] exact (Affine.nonsingular_neg ..).mpr hns rw [W.reducePointSmooth_some_of_mem _ hx hns', W.reducePointSmooth_some_of_mem h hx hns, Affine.Point.neg_some] exact some_smoothLocus_congr rfl hkey _ _ · have hns' : ¬ (W.map (residue A)).toAffine.Nonsingular (residue A ⟨x, hx⟩) (residue A ⟨(W.map A.subtype).toAffine.negY x y, hy'⟩) := by rw [hkey] intro hcon exact hns ((Affine.nonsingular_neg ..).mp hcon) rw [W.reducePointSmooth_some_of_singular _ hx hns', W.reducePointSmooth_some_of_singular h hx hns] exact (Affine.Point.neg_zero).symm · rw [W.reducePointSmooth_some_of_notMem _ hx, W.reducePointSmooth_some_of_notMem h hx] exact (Affine.Point.neg_zero).symm section Kernel variable [DecidableEq L] theorem reducePointSmooth_eq_zero_of_mem_nonIntegralLocus {P : (W.map A.subtype).toAffine.Point} (hP : P ∈ W.nonIntegralLocus) : W.reducePointSmooth P = 0 := by cases P with | zero => exact W.reducePointSmooth_zero | some x y h => exact W.reducePointSmooth_some_of_notMem h ((W.mem_nonIntegralLocus_some_iff h).mp hP) theorem mem_nonIntegralLocus_of_reducePointSmooth_eq_zero {P : (W.map A.subtype).toAffine.Point} (hP : W.HasNonsingularReduction P) (h0 : W.reducePointSmooth P = 0) : P ∈ W.nonIntegralLocus := by cases P with | zero => exact zero_mem _ | some x y h => by_cases hx : x ∈ A · exfalso have hy : y ∈ A := Affine.Y_mem_of_X_mem W h.1 hx have hns := (W.hasNonsingularReduction_some_iff h).mp hP hx hy rw [W.reducePointSmooth_some_of_mem h hx hns] at h0 exact Affine.Point.some_ne_zero hns h0 · exact (W.mem_nonIntegralLocus_some_iff h).mpr hx end Kernel theorem Affine.notMem_nonunits_of_sub_negY_mem_nonunits_of_nonsingular_residue {x y : L} (hx : x ∈ A) (hy : y ∈ A) (hns : (W.map (residue A)).toAffine.Nonsingular (residue A ⟨x, hx⟩) (residue A ⟨y, hy⟩)) (hY : y - (W.map A.subtype).toAffine.negY x y ∈ A.nonunits) : 3 * x ^ 2 + 2 * (W.map A.subtype).toAffine.a₂ * x + (W.map A.subtype).toAffine.a₄ - (W.map A.subtype).toAffine.a₁ * y ∉ A.nonunits := by set eX : A := 3 * ⟨x, hx⟩ ^ 2 + 2 * W.a₂ * ⟨x, hx⟩ + W.a₄ - W.a₁ * ⟨y, hy⟩ with heX set eY : A := ⟨y, hy⟩ - W.toAffine.negY ⟨x, hx⟩ ⟨y, hy⟩ with heY have hcoeX : (eX : L) = 3 * x ^ 2 + 2 * (W.map A.subtype).toAffine.a₂ * x + (W.map A.subtype).toAffine.a₄ - (W.map A.subtype).toAffine.a₁ * y := by push_cast [heX] rfl have hcoeY : (eY : L) = y - (W.map A.subtype).toAffine.negY x y := by have h1 : ((W.toAffine.negY ⟨x, hx⟩ ⟨y, hy⟩ : A) : L) = (W.map A.subtype).toAffine.negY x y := (Affine.map_negY A.subtype (⟨x, hx⟩ : A) (⟨y, hy⟩ : A)).symm rw [heY] push_cast rw [h1] rw [Affine.nonsingular_iff] at hns have hY0 : residue A eY = 0 := by rw [← A.coe_mem_nonunits_iff_residue_eq_zero, hcoeY] exact hY have hX0 : residue A eX ≠ 0 := by rcases hns.2 with hX | hY' · intro h0 apply hX rw [heX] at h0 simp only [map_sub, map_add, map_mul, map_pow, map_ofNat] at h0 show residue A W.a₁ * residue A ⟨y, hy⟩ = 3 * residue A ⟨x, hx⟩ ^ 2 + 2 * residue A W.a₂ * residue A ⟨x, hx⟩ + residue A W.a₄ linear_combination -h0 · exact absurd (by show residue A ⟨y, hy⟩ = -residue A ⟨y, hy⟩ - residue A W.a₁ * residue A ⟨x, hx⟩ - residue A W.a₃ rw [heY] at hY0 simp only [Affine.negY, map_sub, map_neg, map_mul] at hY0 linear_combination hY0) hY' rw [← hcoeX, A.coe_mem_nonunits_iff_residue_eq_zero] exact hX0 section Slope variable [DecidableEq L] theorem Affine.slope_notMem_of_sub_mem_nonunits_of_nonsingular_residue {x₁ x₂ y₁ y₂ : L} (h₁ : (W.map A.subtype).toAffine.Equation x₁ y₁) (h₂ : (W.map A.subtype).toAffine.Equation x₂ y₂) (hx₁ : x₁ ∈ A) (hx₂ : x₂ ∈ A) (hy₁ : y₁ ∈ A) (hns₁ : (W.map (residue A)).toAffine.Nonsingular (residue A ⟨x₁, hx₁⟩) (residue A ⟨y₁, hy₁⟩)) (hPQ : ¬(x₁ = x₂ ∧ y₁ = (W.map A.subtype).toAffine.negY x₂ y₂)) (hxx : x₁ - x₂ ∈ A.nonunits) (hyy : y₁ - (W.map A.subtype).toAffine.negY x₂ y₂ ∈ A.nonunits) : (W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂ ∉ A := by have hy₂ : y₂ ∈ A := Affine.Y_mem_of_X_mem W h₂ hx₂ have ha₁ : (W.map A.subtype).toAffine.a₁ ∈ A := SetLike.coe_mem W.a₁ have ha₂ : (W.map A.subtype).toAffine.a₂ ∈ A := SetLike.coe_mem W.a₂ have ha₃ : (W.map A.subtype).toAffine.a₃ ∈ A := SetLike.coe_mem W.a₃ have ha₄ : (W.map A.subtype).toAffine.a₄ ∈ A := SetLike.coe_mem W.a₄ have hnegY : (W.map A.subtype).toAffine.negY x₂ y₂ ∈ A := by rw [Affine.negY] exact A.toSubring.sub_mem (A.toSubring.sub_mem (A.toSubring.neg_mem hy₂) (A.toSubring.mul_mem ha₁ hx₂)) ha₃ by_cases hx : x₁ = x₂ · have hy : y₁ ≠ (W.map A.subtype).toAffine.negY x₂ y₂ := fun h => hPQ ⟨hx, h⟩ have hy12 : y₁ = y₂ := (Affine.Y_eq_of_X_eq h₁ h₂ hx).resolve_right hy rw [Affine.slope_of_Y_ne hx hy] have hden : y₁ - (W.map A.subtype).toAffine.negY x₁ y₁ ∈ A.nonunits := by rwa [← hx, ← hy12] at hyy have hden0 : y₁ - (W.map A.subtype).toAffine.negY x₁ y₁ ≠ 0 := by rw [sub_ne_zero] intro hcon exact hy (by rw [← hx, ← hy12]; exact hcon) have hnum := Affine.notMem_nonunits_of_sub_negY_mem_nonunits_of_nonsingular_residue W hx₁ hy₁ hns₁ hden exact A.div_notMem hnum hden hden0 · by_cases hyy' : y₁ - y₂ ∈ A.nonunits · rw [Affine.slope_of_X_ne hx] have hden : y₁ - (W.map A.subtype).toAffine.negY x₁ y₁ ∈ A.nonunits := by have key : y₁ - (W.map A.subtype).toAffine.negY x₁ y₁ = (y₁ - (W.map A.subtype).toAffine.negY x₂ y₂) + (y₁ - y₂) + (W.map A.subtype).toAffine.a₁ * (x₁ - x₂) := by simp only [Affine.negY] ring rw [key] exact add_mem (add_mem hyy hyy') (A.mul_mem_nonunits ha₁ hxx) have hnum := Affine.notMem_nonunits_of_sub_negY_mem_nonunits_of_nonsingular_residue W hx₁ hy₁ hns₁ hden set N : L := x₁ ^ 2 + x₁ * x₂ + x₂ ^ 2 + (W.map A.subtype).toAffine.a₂ * (x₁ + x₂) + (W.map A.subtype).toAffine.a₄ - (W.map A.subtype).toAffine.a₁ * y₁ with hN have hNunit : N ∉ A.nonunits := by intro hmem apply hnum have key : 3 * x₁ ^ 2 + 2 * (W.map A.subtype).toAffine.a₂ * x₁ + (W.map A.subtype).toAffine.a₄ - (W.map A.subtype).toAffine.a₁ * y₁ = N - (x₁ + x₁ + x₂ + (W.map A.subtype).toAffine.a₂) * -(x₁ - x₂) := by rw [hN]; ring rw [key] exact sub_mem hmem (A.mul_mem_nonunits (add_mem (add_mem (add_mem hx₁ hx₁) hx₂) ha₂) (neg_mem hxx)) have hd0 : y₁ - (W.map A.subtype).toAffine.negY x₂ y₂ ≠ 0 := by intro hd apply hNunit rw [hN] have hid := Affine.sub_mul_sub_negY h₁ h₂ rw [hd, mul_zero] at hid rcases mul_eq_zero.mp hid.symm with h | h · exact absurd (sub_eq_zero.mp h) hx · rw [h] exact zero_mem _ have hslope : (y₁ - y₂) / (x₁ - x₂) = N / (y₁ - (W.map A.subtype).toAffine.negY x₂ y₂) := by rw [div_eq_div_iff (sub_ne_zero.mpr hx) hd0, hN] linear_combination Affine.sub_mul_sub_negY h₁ h₂ rw [hslope] exact A.div_notMem hNunit hyy hd0 · rw [Affine.slope_of_X_ne hx] exact A.div_notMem hyy' hxx (sub_ne_zero.mpr hx) theorem Affine.addX_notMem_of_sub_mem_nonunits_of_nonsingular_residue {x₁ x₂ y₁ y₂ : L} (h₁ : (W.map A.subtype).toAffine.Equation x₁ y₁) (h₂ : (W.map A.subtype).toAffine.Equation x₂ y₂) (hx₁ : x₁ ∈ A) (hx₂ : x₂ ∈ A) (hy₁ : y₁ ∈ A) (hns₁ : (W.map (residue A)).toAffine.Nonsingular (residue A ⟨x₁, hx₁⟩) (residue A ⟨y₁, hy₁⟩)) (hPQ : ¬(x₁ = x₂ ∧ y₁ = (W.map A.subtype).toAffine.negY x₂ y₂)) (hxx : x₁ - x₂ ∈ A.nonunits) (hyy : y₁ - (W.map A.subtype).toAffine.negY x₂ y₂ ∈ A.nonunits) : (W.map A.subtype).toAffine.addX x₁ x₂ ((W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂) ∉ A := by have hℓ := Affine.slope_notMem_of_sub_mem_nonunits_of_nonsingular_residue W h₁ h₂ hx₁ hx₂ hy₁ hns₁ hPQ hxx hyy set ℓ : L := (W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂ have ha₁ : (W.map A.subtype).toAffine.a₁ ∈ A := SetLike.coe_mem W.a₁ have ha₂ : (W.map A.subtype).toAffine.a₂ ∈ A := SetLike.coe_mem W.a₂ rw [show (W.map A.subtype).toAffine.addX x₁ x₂ ℓ = ℓ * (ℓ + (W.map A.subtype).toAffine.a₁) + (-(W.map A.subtype).toAffine.a₂ - x₁ - x₂) from by rw [Affine.addX]; ring] exact A.add_notMem (A.mul_notMem hℓ (by simpa [add_comm] using A.add_notMem hℓ ha₁)) (A.toSubring.sub_mem (A.toSubring.sub_mem (A.toSubring.neg_mem ha₂) hx₁) hx₂) end Slope section Carrier variable [DecidableEq L] [DecidableEq (ResidueField A)] structure SmoothLocusReductionData : Type _ where zeroComponent : AddSubgroup (W.map A.subtype).toAffine.Point mem_iff : ∀ P : (W.map A.subtype).toAffine.Point, P ∈ zeroComponent ↔ W.HasNonsingularReduction P reducePointSmooth_add : ∀ P Q : (W.map A.subtype).toAffine.Point, P ∈ zeroComponent → Q ∈ zeroComponent → W.reducePointSmooth (P + Q) = W.reducePointSmooth P + W.reducePointSmooth Q namespace SmoothLocusReductionData variable {W} theorem nonIntegralLocus_le (D : W.SmoothLocusReductionData) : W.nonIntegralLocus ≤ D.zeroComponent := fun P hP => (D.mem_iff P).mpr (W.hasNonsingularReduction_of_mem_nonIntegralLocus hP) theorem zero_mem (D : W.SmoothLocusReductionData) : (0 : (W.map A.subtype).toAffine.Point) ∈ D.zeroComponent := (D.mem_iff 0).mpr (W.hasNonsingularReduction_zero) noncomputable def reduceHom₀ (D : W.SmoothLocusReductionData) : D.zeroComponent →+ (W.map (residue A)).toAffine.Point where toFun P := W.reducePointSmooth (P : (W.map A.subtype).toAffine.Point) map_zero' := by simp map_add' P Q := by simpa using D.reducePointSmooth_add (P : (W.map A.subtype).toAffine.Point) (Q : (W.map A.subtype).toAffine.Point) P.2 Q.2 @[simp] theorem reduceHom₀_apply (D : W.SmoothLocusReductionData) (P : D.zeroComponent) : D.reduceHom₀ P = W.reducePointSmooth (P : (W.map A.subtype).toAffine.Point) := rfl theorem reduceHom₀_eq_zero_iff (D : W.SmoothLocusReductionData) (P : D.zeroComponent) : D.reduceHom₀ P = 0 ↔ (P : (W.map A.subtype).toAffine.Point) ∈ W.nonIntegralLocus := by constructor · intro h0 exact W.mem_nonIntegralLocus_of_reducePointSmooth_eq_zero ((D.mem_iff _).mp P.2) h0 · intro hmem exact W.reducePointSmooth_eq_zero_of_mem_nonIntegralLocus hmem end SmoothLocusReductionData end Carrier end General section ConsumerEngine variable {L : Type} [Field L] {A : ValuationSubring L} {W : WeierstrassCurve A} [DecidableEq L] [DecidableEq (ResidueField A)] end ConsumerEngine end WeierstrassCurve set_option autoImplicit false open IsLocalRing namespace WeierstrassCurve variable {L : Type*} [Field L] {A : ValuationSubring L} {W : WeierstrassCurve A} private lemma some_smoothClosure_congr {R : Type*} [CommRing R] {V : Affine R} {x₁ x₂ y₁ y₂ : R} (hx : x₁ = x₂) (hy : y₁ = y₂) (h₁ : V.Nonsingular x₁ y₁) (h₂ : V.Nonsingular x₂ y₂) : Affine.Point.some x₁ y₁ h₁ = Affine.Point.some x₂ y₂ h₂ := by subst hx; subst hy; rfl section CoordinatewiseEngine variable [DecidableEq L] [DecidableEq (ResidueField A)] theorem addX_mem_of_not_inverse {x₁ y₁ x₂ y₂ : L} (h₁ : (W.map A.subtype).toAffine.Equation x₁ y₁) (h₂ : (W.map A.subtype).toAffine.Equation x₂ y₂) (hx₁ : x₁ ∈ A) (hx₂ : x₂ ∈ A) (hred : ¬(x₁ - x₂ ∈ A.nonunits ∧ y₁ - (W.map A.subtype).toAffine.negY x₂ y₂ ∈ A.nonunits)) : (W.map A.subtype).toAffine.addX x₁ x₂ ((W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂) ∈ A := by obtain ⟨hsmem, -⟩ := slope_mem_residue_of_not_inverse h₁ h₂ hx₁ hx₂ hred have hX_coe : (W.map A.subtype).toAffine.addX x₁ x₂ ((W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂) = ((W.toAffine.addX ⟨x₁, hx₁⟩ ⟨x₂, hx₂⟩ ⟨(W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂, hsmem⟩ : A) : L) := Affine.map_addX (W' := W) A.subtype (⟨x₁, hx₁⟩ : A) (⟨x₂, hx₂⟩ : A) ⟨(W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂, hsmem⟩ rw [hX_coe] exact SetLike.coe_mem _ theorem addY_mem_of_not_inverse {x₁ y₁ x₂ y₂ : L} (h₁ : (W.map A.subtype).toAffine.Equation x₁ y₁) (h₂ : (W.map A.subtype).toAffine.Equation x₂ y₂) (hx₁ : x₁ ∈ A) (hx₂ : x₂ ∈ A) (hred : ¬(x₁ - x₂ ∈ A.nonunits ∧ y₁ - (W.map A.subtype).toAffine.negY x₂ y₂ ∈ A.nonunits)) : (W.map A.subtype).toAffine.addY x₁ x₂ y₁ ((W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂) ∈ A := by obtain ⟨hsmem, -⟩ := slope_mem_residue_of_not_inverse h₁ h₂ hx₁ hx₂ hred have hy₁ : y₁ ∈ A := Affine.Y_mem_of_X_mem W h₁ hx₁ have hY_coe : (W.map A.subtype).toAffine.addY x₁ x₂ y₁ ((W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂) = ((W.toAffine.addY ⟨x₁, hx₁⟩ ⟨x₂, hx₂⟩ ⟨y₁, hy₁⟩ ⟨(W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂, hsmem⟩ : A) : L) := Affine.map_addY (W' := W) A.subtype (⟨x₁, hx₁⟩ : A) (⟨y₁, hy₁⟩ : A) (⟨x₂, hx₂⟩ : A) ⟨(W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂, hsmem⟩ rw [hY_coe] exact SetLike.coe_mem _ set_option maxHeartbeats 800000 in theorem residue_addX_of_not_inverse {x₁ y₁ x₂ y₂ : L} (h₁ : (W.map A.subtype).toAffine.Equation x₁ y₁) (h₂ : (W.map A.subtype).toAffine.Equation x₂ y₂) (hx₁ : x₁ ∈ A) (hx₂ : x₂ ∈ A) (hy₁ : y₁ ∈ A) (hy₂ : y₂ ∈ A) (hred : ¬(x₁ - x₂ ∈ A.nonunits ∧ y₁ - (W.map A.subtype).toAffine.negY x₂ y₂ ∈ A.nonunits)) (hmem : (W.map A.subtype).toAffine.addX x₁ x₂ ((W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂) ∈ A) : residue A ⟨(W.map A.subtype).toAffine.addX x₁ x₂ ((W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂), hmem⟩ = (W.map (residue A)).toAffine.addX (residue A ⟨x₁, hx₁⟩) (residue A ⟨x₂, hx₂⟩) ((W.map (residue A)).toAffine.slope (residue A ⟨x₁, hx₁⟩) (residue A ⟨x₂, hx₂⟩) (residue A ⟨y₁, hy₁⟩) (residue A ⟨y₂, hy₂⟩)) := by obtain ⟨hsmem, hsres⟩ := slope_mem_residue_of_not_inverse h₁ h₂ hx₁ hx₂ hred have hsres' : residue A ⟨(W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂, hsmem⟩ = (W.map (residue A)).toAffine.slope (residue A ⟨x₁, hx₁⟩) (residue A ⟨x₂, hx₂⟩) (residue A ⟨y₁, hy₁⟩) (residue A ⟨y₂, hy₂⟩) := hsres have hX_coe : (W.map A.subtype).toAffine.addX x₁ x₂ ((W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂) = ((W.toAffine.addX ⟨x₁, hx₁⟩ ⟨x₂, hx₂⟩ ⟨(W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂, hsmem⟩ : A) : L) := Affine.map_addX (W' := W) A.subtype (⟨x₁, hx₁⟩ : A) (⟨x₂, hx₂⟩ : A) ⟨(W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂, hsmem⟩ calc residue A ⟨(W.map A.subtype).toAffine.addX x₁ x₂ ((W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂), hmem⟩ = residue A (W.toAffine.addX ⟨x₁, hx₁⟩ ⟨x₂, hx₂⟩ ⟨(W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂, hsmem⟩) := A.residue_eq_of_coe_eq hmem hX_coe _ = (W.map (residue A)).toAffine.addX (residue A ⟨x₁, hx₁⟩) (residue A ⟨x₂, hx₂⟩) (residue A ⟨(W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂, hsmem⟩) := (Affine.map_addX (W' := W) (residue A) (⟨x₁, hx₁⟩ : A) (⟨x₂, hx₂⟩ : A) ⟨(W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂, hsmem⟩).symm _ = _ := by rw [hsres'] set_option maxHeartbeats 800000 in theorem residue_addY_of_not_inverse {x₁ y₁ x₂ y₂ : L} (h₁ : (W.map A.subtype).toAffine.Equation x₁ y₁) (h₂ : (W.map A.subtype).toAffine.Equation x₂ y₂) (hx₁ : x₁ ∈ A) (hx₂ : x₂ ∈ A) (hy₁ : y₁ ∈ A) (hy₂ : y₂ ∈ A) (hred : ¬(x₁ - x₂ ∈ A.nonunits ∧ y₁ - (W.map A.subtype).toAffine.negY x₂ y₂ ∈ A.nonunits)) (hmem : (W.map A.subtype).toAffine.addY x₁ x₂ y₁ ((W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂) ∈ A) : residue A ⟨(W.map A.subtype).toAffine.addY x₁ x₂ y₁ ((W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂), hmem⟩ = (W.map (residue A)).toAffine.addY (residue A ⟨x₁, hx₁⟩) (residue A ⟨x₂, hx₂⟩) (residue A ⟨y₁, hy₁⟩) ((W.map (residue A)).toAffine.slope (residue A ⟨x₁, hx₁⟩) (residue A ⟨x₂, hx₂⟩) (residue A ⟨y₁, hy₁⟩) (residue A ⟨y₂, hy₂⟩)) := by obtain ⟨hsmem, hsres⟩ := slope_mem_residue_of_not_inverse h₁ h₂ hx₁ hx₂ hred have hsres' : residue A ⟨(W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂, hsmem⟩ = (W.map (residue A)).toAffine.slope (residue A ⟨x₁, hx₁⟩) (residue A ⟨x₂, hx₂⟩) (residue A ⟨y₁, hy₁⟩) (residue A ⟨y₂, hy₂⟩) := hsres have hY_coe : (W.map A.subtype).toAffine.addY x₁ x₂ y₁ ((W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂) = ((W.toAffine.addY ⟨x₁, hx₁⟩ ⟨x₂, hx₂⟩ ⟨y₁, hy₁⟩ ⟨(W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂, hsmem⟩ : A) : L) := Affine.map_addY (W' := W) A.subtype (⟨x₁, hx₁⟩ : A) (⟨y₁, hy₁⟩ : A) (⟨x₂, hx₂⟩ : A) ⟨(W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂, hsmem⟩ calc residue A ⟨(W.map A.subtype).toAffine.addY x₁ x₂ y₁ ((W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂), hmem⟩ = residue A (W.toAffine.addY ⟨x₁, hx₁⟩ ⟨x₂, hx₂⟩ ⟨y₁, hy₁⟩ ⟨(W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂, hsmem⟩) := A.residue_eq_of_coe_eq hmem hY_coe _ = (W.map (residue A)).toAffine.addY (residue A ⟨x₁, hx₁⟩) (residue A ⟨x₂, hx₂⟩) (residue A ⟨y₁, hy₁⟩) (residue A ⟨(W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂, hsmem⟩) := (Affine.map_addY (W' := W) (residue A) (⟨x₁, hx₁⟩ : A) (⟨y₁, hy₁⟩ : A) (⟨x₂, hx₂⟩ : A) ⟨(W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂, hsmem⟩).symm _ = _ := by rw [hsres'] end CoordinatewiseEngine section CaseAnalysis variable [DecidableEq L] [DecidableEq (ResidueField A)] set_option maxHeartbeats 1600000 in private lemma addAux_of_mem_of_mem {x₁ y₁ x₂ y₂ : L} (h₁ : (W.map A.subtype).toAffine.Nonsingular x₁ y₁) (h₂ : (W.map A.subtype).toAffine.Nonsingular x₂ y₂) (hx₁ : x₁ ∈ A) (hx₂ : x₂ ∈ A) (hP : W.HasNonsingularReduction (.some x₁ y₁ h₁)) (hQ : W.HasNonsingularReduction (.some x₂ y₂ h₂)) : W.HasNonsingularReduction (.some x₁ y₁ h₁ + .some x₂ y₂ h₂) ∧ W.reducePointSmooth (.some x₁ y₁ h₁ + .some x₂ y₂ h₂) = W.reducePointSmooth (.some x₁ y₁ h₁) + W.reducePointSmooth (.some x₂ y₂ h₂) := by have hy₁ : y₁ ∈ A := Affine.Y_mem_of_X_mem W h₁.1 hx₁ have hy₂ : y₂ ∈ A := Affine.Y_mem_of_X_mem W h₂.1 hx₂ have hns₁ := (W.hasNonsingularReduction_some_iff h₁).mp hP hx₁ hy₁ have hns₂ := (W.hasNonsingularReduction_some_iff h₂).mp hQ hx₂ hy₂ by_cases hred : x₁ - x₂ ∈ A.nonunits ∧ y₁ - (W.map A.subtype).toAffine.negY x₂ y₂ ∈ A.nonunits · obtain ⟨hredx, hredy⟩ := (residue_inverse_iff hx₁ hy₁ hx₂ hy₂).mpr hred by_cases hPQ : x₁ = x₂ ∧ y₁ = (W.map A.subtype).toAffine.negY x₂ y₂ · constructor · rw [Affine.Point.add_of_Y_eq hPQ.1 hPQ.2] exact W.hasNonsingularReduction_zero · rw [Affine.Point.add_of_Y_eq hPQ.1 hPQ.2, W.reducePointSmooth_zero, W.reducePointSmooth_some_of_mem h₁ hx₁ hns₁, W.reducePointSmooth_some_of_mem h₂ hx₂ hns₂, Affine.Point.add_of_Y_eq hredx hredy] · have haddX := Affine.addX_notMem_of_sub_mem_nonunits_of_nonsingular_residue W h₁.1 h₂.1 hx₁ hx₂ hy₁ hns₁ hPQ hred.1 hred.2 constructor · rw [Affine.Point.add_some hPQ] exact W.hasNonsingularReduction_some_of_notMem _ haddX · rw [Affine.Point.add_some hPQ, W.reducePointSmooth_some_of_notMem _ haddX, W.reducePointSmooth_some_of_mem h₁ hx₁ hns₁, W.reducePointSmooth_some_of_mem h₂ hx₂ hns₂, Affine.Point.add_of_Y_eq hredx hredy] · have hPQ : ¬(x₁ = x₂ ∧ y₁ = (W.map A.subtype).toAffine.negY x₂ y₂) := by rintro ⟨hxe, hye⟩ exact hred ⟨by rw [hxe, sub_self]; exact A.nonunits.zero_mem, by rw [hye, sub_self]; exact A.nonunits.zero_mem⟩ have hredk : ¬(residue A ⟨x₁, hx₁⟩ = residue A ⟨x₂, hx₂⟩ ∧ residue A ⟨y₁, hy₁⟩ = (W.map (residue A)).toAffine.negY (residue A ⟨x₂, hx₂⟩) (residue A ⟨y₂, hy₂⟩)) := fun h => hred ((residue_inverse_iff hx₁ hy₁ hx₂ hy₂).mp h) have hXmem : (W.map A.subtype).toAffine.addX x₁ x₂ ((W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂) ∈ A := addX_mem_of_not_inverse h₁.1 h₂.1 hx₁ hx₂ hred have hYmem : (W.map A.subtype).toAffine.addY x₁ x₂ y₁ ((W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂) ∈ A := addY_mem_of_not_inverse h₁.1 h₂.1 hx₁ hx₂ hred have hXres := residue_addX_of_not_inverse h₁.1 h₂.1 hx₁ hx₂ hy₁ hy₂ hred hXmem have hYres := residue_addY_of_not_inverse h₁.1 h₂.1 hx₁ hx₂ hy₁ hy₂ hred hYmem have hns₃ : (W.map (residue A)).toAffine.Nonsingular (residue A ⟨(W.map A.subtype).toAffine.addX x₁ x₂ ((W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂), hXmem⟩) (residue A ⟨(W.map A.subtype).toAffine.addY x₁ x₂ y₁ ((W.map A.subtype).toAffine.slope x₁ x₂ y₁ y₂), hYmem⟩) := by rw [hXres, hYres] exact Affine.nonsingular_add hns₁ hns₂ hredk constructor · rw [Affine.Point.add_some hPQ, W.hasNonsingularReduction_some_iff] intro hx hy exact hns₃ · rw [Affine.Point.add_some hPQ, W.reducePointSmooth_some_of_mem _ hXmem hns₃, W.reducePointSmooth_some_of_mem h₁ hx₁ hns₁, W.reducePointSmooth_some_of_mem h₂ hx₂ hns₂, Affine.Point.add_some hredk] exact some_smoothClosure_congr hXres hYres _ _ private lemma addAux_of_notMem_of_notMem {x₁ y₁ x₂ y₂ : L} (h₁ : (W.map A.subtype).toAffine.Nonsingular x₁ y₁) (h₂ : (W.map A.subtype).toAffine.Nonsingular x₂ y₂) (hx₁ : x₁ ∉ A) (hx₂ : x₂ ∉ A) : W.HasNonsingularReduction (.some x₁ y₁ h₁ + .some x₂ y₂ h₂) ∧ W.reducePointSmooth (.some x₁ y₁ h₁ + .some x₂ y₂ h₂) = W.reducePointSmooth (.some x₁ y₁ h₁) + W.reducePointSmooth (.some x₂ y₂ h₂) := by have hPmem : (.some x₁ y₁ h₁ : (W.map A.subtype).toAffine.Point) ∈ W.nonIntegralLocus := (W.mem_nonIntegralLocus_some_iff h₁).mpr hx₁ have hQmem : (.some x₂ y₂ h₂ : (W.map A.subtype).toAffine.Point) ∈ W.nonIntegralLocus := (W.mem_nonIntegralLocus_some_iff h₂).mpr hx₂ have hSmem : (.some x₁ y₁ h₁ + .some x₂ y₂ h₂ : (W.map A.subtype).toAffine.Point) ∈ W.nonIntegralLocus := add_mem hPmem hQmem refine ⟨W.hasNonsingularReduction_of_mem_nonIntegralLocus hSmem, ?_⟩ rw [W.reducePointSmooth_eq_zero_of_mem_nonIntegralLocus hSmem, W.reducePointSmooth_some_of_notMem h₁ hx₁, W.reducePointSmooth_some_of_notMem h₂ hx₂, add_zero] set_option maxHeartbeats 800000 in private lemma addAux_of_mem_of_notMem {x₁ y₁ x₂ y₂ : L} (h₁ : (W.map A.subtype).toAffine.Nonsingular x₁ y₁) (h₂ : (W.map A.subtype).toAffine.Nonsingular x₂ y₂) (hP : W.HasNonsingularReduction (.some x₁ y₁ h₁)) (hx₁ : x₁ ∈ A) (hx₂ : x₂ ∉ A) : W.HasNonsingularReduction (.some x₁ y₁ h₁ + .some x₂ y₂ h₂) ∧ W.reducePointSmooth (.some x₁ y₁ h₁ + .some x₂ y₂ h₂) = W.reducePointSmooth (.some x₁ y₁ h₁) + W.reducePointSmooth (.some x₂ y₂ h₂) := by have hy₁ : y₁ ∈ A := Affine.Y_mem_of_X_mem W h₁.1 hx₁ have hns₁ := (W.hasNonsingularReduction_some_iff h₁).mp hP hx₁ hy₁ have hPn : (W.map A.subtype).toAffine.Nonsingular x₁ ((W.map A.subtype).toAffine.negY x₁ y₁) := (Affine.nonsingular_neg _ _).mpr h₁ have hPneg : (.some x₁ ((W.map A.subtype).toAffine.negY x₁ y₁) hPn : (W.map A.subtype).toAffine.Point) = -(.some x₁ y₁ h₁) := (Affine.Point.neg_some h₁).symm cases hadd : (.some x₁ y₁ h₁ + .some x₂ y₂ h₂ : (W.map A.subtype).toAffine.Point) with | zero => exfalso have hPQ : (.some x₁ y₁ h₁ : (W.map A.subtype).toAffine.Point) = -(.some x₂ y₂ h₂) := eq_neg_of_add_eq_zero_left hadd rw [Affine.Point.neg_some] at hPQ simp only [Affine.Point.some.injEq] at hPQ exact hx₂ (hPQ.1 ▸ hx₁) | some X₃ Y₃ h₃ => by_cases hX₃ : X₃ ∈ A · have hY₃ : Y₃ ∈ A := Affine.Y_mem_of_X_mem W h₃.1 hX₃ have hkey : X₃ - x₁ ∈ A.nonunits ∧ Y₃ - (W.map A.subtype).toAffine.negY x₁ ((W.map A.subtype).toAffine.negY x₁ y₁) ∈ A.nonunits := by by_contra hcon have hSnegP : (.some X₃ Y₃ h₃ : (W.map A.subtype).toAffine.Point) + .some x₁ ((W.map A.subtype).toAffine.negY x₁ y₁) hPn = .some x₂ y₂ h₂ := by rw [hPneg, ← hadd]; abel have hSP : ¬(X₃ = x₁ ∧ Y₃ = (W.map A.subtype).toAffine.negY x₁ ((W.map A.subtype).toAffine.negY x₁ y₁)) := by rintro ⟨hX, hY⟩ have h0 : (.some X₃ Y₃ h₃ : (W.map A.subtype).toAffine.Point) + .some x₁ ((W.map A.subtype).toAffine.negY x₁ y₁) hPn = 0 := Affine.Point.add_of_Y_eq hX hY rw [hSnegP] at h0 exact Affine.Point.some_ne_zero h₂ h0 have haddX : (W.map A.subtype).toAffine.addX X₃ x₁ ((W.map A.subtype).toAffine.slope X₃ x₁ Y₃ ((W.map A.subtype).toAffine.negY x₁ y₁)) ∈ A := addX_mem_of_not_inverse h₃.1 hPn.1 hX₃ hx₁ hcon rw [Affine.Point.add_some hSP] at hSnegP simp only [Affine.Point.some.injEq] at hSnegP exact hx₂ (hSnegP.1 ▸ haddX) rw [Affine.negY_negY] at hkey have hXres : residue A ⟨X₃, hX₃⟩ = residue A ⟨x₁, hx₁⟩ := (A.residue_eq_residue_iff_sub_mem_nonunits hX₃ hx₁).mpr hkey.1 have hYres : residue A ⟨Y₃, hY₃⟩ = residue A ⟨y₁, hy₁⟩ := (A.residue_eq_residue_iff_sub_mem_nonunits hY₃ hy₁).mpr hkey.2 have hnsS : (W.map (residue A)).toAffine.Nonsingular (residue A ⟨X₃, hX₃⟩) (residue A ⟨Y₃, hY₃⟩) := by rw [hXres, hYres] exact hns₁ constructor · rw [W.hasNonsingularReduction_some_iff] intro hx hy exact hnsS · rw [W.reducePointSmooth_some_of_mem h₃ hX₃ hnsS, W.reducePointSmooth_some_of_notMem h₂ hx₂, W.reducePointSmooth_some_of_mem h₁ hx₁ hns₁, add_zero] exact some_smoothClosure_congr hXres hYres _ _ · exfalso have hS : (.some X₃ Y₃ h₃ : (W.map A.subtype).toAffine.Point) ∈ W.nonIntegralLocus := (W.mem_nonIntegralLocus_some_iff h₃).mpr hX₃ have hQmem : (.some x₂ y₂ h₂ : (W.map A.subtype).toAffine.Point) ∈ W.nonIntegralLocus := (W.mem_nonIntegralLocus_some_iff h₂).mpr hx₂ have hPmem : (.some x₁ y₁ h₁ : (W.map A.subtype).toAffine.Point) ∈ W.nonIntegralLocus := by have hPeq : (.some x₁ y₁ h₁ : (W.map A.subtype).toAffine.Point) = .some X₃ Y₃ h₃ - .some x₂ y₂ h₂ := by rw [← hadd]; abel rw [hPeq] exact sub_mem hS hQmem exact ((W.mem_nonIntegralLocus_some_iff h₁).mp hPmem) hx₁ end CaseAnalysis section Closure variable [DecidableEq L] [DecidableEq (ResidueField A)] theorem hasNonsingularReduction_add {P Q : (W.map A.subtype).toAffine.Point} (hP : W.HasNonsingularReduction P) (hQ : W.HasNonsingularReduction Q) : W.HasNonsingularReduction (P + Q) := by cases P with | zero => show W.HasNonsingularReduction ((0 : (W.map A.subtype).toAffine.Point) + Q) rw [zero_add] exact hQ | some x₁ y₁ h₁ => cases Q with | zero => show W.HasNonsingularReduction (.some x₁ y₁ h₁ + (0 : (W.map A.subtype).toAffine.Point)) rw [add_zero] exact hP | some x₂ y₂ h₂ => by_cases hx₁ : x₁ ∈ A <;> by_cases hx₂ : x₂ ∈ A · exact (addAux_of_mem_of_mem h₁ h₂ hx₁ hx₂ hP hQ).1 · exact (addAux_of_mem_of_notMem h₁ h₂ hP hx₁ hx₂).1 · rw [add_comm (Affine.Point.some x₁ y₁ h₁) (Affine.Point.some x₂ y₂ h₂)] exact (addAux_of_mem_of_notMem h₂ h₁ hQ hx₂ hx₁).1 · exact (addAux_of_notMem_of_notMem h₁ h₂ hx₁ hx₂).1 theorem reducePointSmooth_add_of_hasNonsingularReduction {P Q : (W.map A.subtype).toAffine.Point} (hP : W.HasNonsingularReduction P) (hQ : W.HasNonsingularReduction Q) : W.reducePointSmooth (P + Q) = W.reducePointSmooth P + W.reducePointSmooth Q := by cases P with | zero => show W.reducePointSmooth ((0 : (W.map A.subtype).toAffine.Point) + Q) = W.reducePointSmooth (0 : (W.map A.subtype).toAffine.Point) + W.reducePointSmooth Q rw [zero_add, W.reducePointSmooth_zero, zero_add] | some x₁ y₁ h₁ => cases Q with | zero => show W.reducePointSmooth (.some x₁ y₁ h₁ + (0 : (W.map A.subtype).toAffine.Point)) = W.reducePointSmooth (.some x₁ y₁ h₁) + W.reducePointSmooth (0 : (W.map A.subtype).toAffine.Point) rw [add_zero, W.reducePointSmooth_zero, add_zero] | some x₂ y₂ h₂ => by_cases hx₁ : x₁ ∈ A <;> by_cases hx₂ : x₂ ∈ A · exact (addAux_of_mem_of_mem h₁ h₂ hx₁ hx₂ hP hQ).2 · exact (addAux_of_mem_of_notMem h₁ h₂ hP hx₁ hx₂).2 · rw [add_comm (Affine.Point.some x₁ y₁ h₁) (Affine.Point.some x₂ y₂ h₂), (addAux_of_mem_of_notMem h₂ h₁ hQ hx₂ hx₁).2] exact add_comm _ _ · exact (addAux_of_notMem_of_notMem h₁ h₂ hx₁ hx₂).2 end Closure section Carrier variable [DecidableEq L] [DecidableEq (ResidueField A)] variable (W) in def zeroComponentSubgroup : AddSubgroup (W.map A.subtype).toAffine.Point where carrier := {P | W.HasNonsingularReduction P} zero_mem' := W.hasNonsingularReduction_zero neg_mem' := fun {_P} hP => W.hasNonsingularReduction_neg hP add_mem' := fun {_P _Q} hP hQ => W.hasNonsingularReduction_add hP hQ variable (W) in @[simp] theorem mem_zeroComponentSubgroup_iff {P : (W.map A.subtype).toAffine.Point} : P ∈ W.zeroComponentSubgroup ↔ W.HasNonsingularReduction P := Iff.rfl variable (W) in noncomputable def smoothLocusReductionData : W.SmoothLocusReductionData where zeroComponent := W.zeroComponentSubgroup mem_iff := fun _ => Iff.rfl reducePointSmooth_add := fun _ _ hP hQ => W.reducePointSmooth_add_of_hasNonsingularReduction hP hQ variable (W) in theorem smoothLocusReductionData_zeroComponent : (W.smoothLocusReductionData).zeroComponent = W.zeroComponentSubgroup := rfl variable (W) in theorem nonempty_smoothLocusReductionData : Nonempty (W.SmoothLocusReductionData) := ⟨W.smoothLocusReductionData⟩ theorem SmoothLocusReductionData.zeroComponent_eq (D : W.SmoothLocusReductionData) : D.zeroComponent = W.zeroComponentSubgroup := AddSubgroup.ext fun P => D.mem_iff P variable (W) in theorem zeroComponentSubgroup_eq_top_of_good (hΔ : (W.map (residue A)).Δ ≠ 0) : W.zeroComponentSubgroup = ⊤ := by refine AddSubgroup.ext fun P => ?_ simp only [AddSubgroup.mem_top, iff_true] exact W.hasNonsingularReduction_of_good hΔ P variable (W) in theorem nonIntegralLocus_le_zeroComponentSubgroup : W.nonIntegralLocus ≤ W.zeroComponentSubgroup := fun _ hP => W.hasNonsingularReduction_of_mem_nonIntegralLocus hP end Carrier end WeierstrassCurve
Statements phrased using this module (0)
No statement module imports it directly (it is used through other definition modules or by proofs).