File: Mathlib/AlgebraicGeometry/EllipticCurve/Affine.lean

full_name: tacticC_simp._@.Mathlib.AlgebraicGeometry.EllipticCurve.Affine._hyg.4
code: macro "C_simp" : tactic =>
  `(tactic| simp only [map_ofNat, C_0, C_1, C_neg, C_add, C_sub, C_mul, C_pow])
goal: Lean.ParserDescr

full_name: _aux_Mathlib_AlgebraicGeometry_EllipticCurve_Affine___macroRules_tacticC_simp_1
code: macro "C_simp" : tactic =>
  `(tactic| simp only [map_ofNat, C_0, C_1, C_neg, C_add, C_sub, C_mul, C_pow])
goal: Lean.Macro

full_name: tacticDerivative_simp._@.Mathlib.AlgebraicGeometry.EllipticCurve.Affine._hyg.419
code: macro "derivative_simp" : tactic =>
  `(tactic| simp only [derivative_C, derivative_X, derivative_X_pow, derivative_neg, derivative_add,
    derivative_sub, derivative_mul, derivative_sq])
goal: Lean.ParserDescr

full_name: _aux_Mathlib_AlgebraicGeometry_EllipticCurve_Affine___macroRules_tacticDerivative_simp_1
code: macro "derivative_simp" : tactic =>
  `(tactic| simp only [derivative_C, derivative_X, derivative_X_pow, derivative_neg, derivative_add,
    derivative_sub, derivative_mul, derivative_sq])
goal: Lean.Macro

full_name: _aux_Mathlib_AlgebraicGeometry_EllipticCurve_Affine___macroRules_tacticEval_simp_1
code: macro "eval_simp" : tactic =>
  `(tactic| simp only [eval_C, eval_X, eval_neg, eval_add, eval_sub, eval_mul, eval_pow, evalEval])
goal: Lean.Macro

full_name: tacticEval_simp._@.Mathlib.AlgebraicGeometry.EllipticCurve.Affine._hyg.834
code: macro "eval_simp" : tactic =>
  `(tactic| simp only [eval_C, eval_X, eval_neg, eval_add, eval_sub, eval_mul, eval_pow, evalEval])
goal: Lean.ParserDescr

full_name: tacticMap_simp._@.Mathlib.AlgebraicGeometry.EllipticCurve.Affine._hyg.1252
code: macro "map_simp" : tactic =>
  `(tactic| simp only [map_ofNat, map_neg, map_add, map_sub, map_mul, map_pow, map_div₀,
    Polynomial.map_ofNat, map_C, map_X, Polynomial.map_neg, Polynomial.map_add, Polynomial.map_sub,
    Polynomial.map_mul, Polynomial.map_pow, Polynomial.map_div, coe_mapRingHom,
    WeierstrassCurve.map])
goal: Lean.ParserDescr

full_name: _aux_Mathlib_AlgebraicGeometry_EllipticCurve_Affine___macroRules_tacticMap_simp_1
code: macro "map_simp" : tactic =>
  `(tactic| simp only [map_ofNat, map_neg, map_add, map_sub, map_mul, map_pow, map_div₀,
    Polynomial.map_ofNat, map_C, map_X, Polynomial.map_neg, Polynomial.map_add, Polynomial.map_sub,
    Polynomial.map_mul, Polynomial.map_pow, Polynomial.map_div, coe_mapRingHom,
    WeierstrassCurve.map])
goal: Lean.Macro

full_name: WeierstrassCurve.Affine
code: /-- An abbreviation for a Weierstrass curve in affine coordinates. -/
abbrev WeierstrassCurve.Affine (R : Type u) : Type u 
goal: Type u

full_name: WeierstrassCurve.toAffine
code: /-- The coercion to a Weierstrass curve in affine coordinates. -/
abbrev WeierstrassCurve.toAffine {R : Type u} (W : WeierstrassCurve R) : Affine R 
goal: WeierstrassCurve.Affine R

full_name: WeierstrassCurve.Affine.polynomial
code: /-- The polynomial $W(X, Y) := Y^2 + a_1XY + a_3Y - (X^3 + a_2X^2 + a_4X + a_6)$ associated to a
Weierstrass curve `W` over `R`. For ease of polynomial manipulation, this is represented as a term
of type `R[X][X]`, where the inner variable represents $X$ and the outer variable represents $Y$.
For clarity, the alternative notations `Y` and `R[X][Y]` are provided in the `Polynomial`
scope to represent the outer variable and the bivariate polynomial ring `R[X][X]` respectively. -/
noncomputable def polynomial : R[X][Y] 
goal: R[X][Y]

full_name: WeierstrassCurve.Affine.polynomial_eq
code: lemma polynomial_eq : W.polynomial =
    Cubic.toPoly
      ⟨0, 1, Cubic.toPoly ⟨0, 0, W.a₁, W.a₃⟩, Cubic.toPoly ⟨-1, -W.a₂, -W.a₄, -W.a₆⟩⟩ 
goal: W.polynomial =
  { a := 0, b := 1, c := { a := 0, b := 0, c := W.a₁, d := W.a₃ }.toPoly,
      d := { a := -1, b := -W.a₂, c := -W.a₄, d := -W.a₆ }.toPoly }.toPoly

full_name: WeierstrassCurve.Affine.polynomial_ne_zero
code: lemma polynomial_ne_zero [Nontrivial R] : W.polynomial ≠ 0 
goal: W.polynomial ≠ 0

full_name: WeierstrassCurve.Affine.degree_polynomial
code: @[simp]
lemma degree_polynomial [Nontrivial R] : W.polynomial.degree = 2 
goal: W.polynomial.degree = 2

full_name: WeierstrassCurve.Affine.natDegree_polynomial
code: @[simp]
lemma natDegree_polynomial [Nontrivial R] : W.polynomial.natDegree = 2 
goal: W.polynomial.natDegree = 2

full_name: WeierstrassCurve.Affine.monic_polynomial
code: lemma monic_polynomial : W.polynomial.Monic 
goal: W.polynomial.Monic

full_name: WeierstrassCurve.Affine.irreducible_polynomial
code: lemma irreducible_polynomial [IsDomain R] : Irreducible W.polynomial 
goal: Irreducible W.polynomial

full_name: WeierstrassCurve.Affine.evalEval_polynomial
code: lemma evalEval_polynomial (x y : R) : W.polynomial.evalEval x y =
    y ^ 2 + W.a₁ * x * y + W.a₃ * y - (x ^ 3 + W.a₂ * x ^ 2 + W.a₄ * x + W.a₆) 
goal: Polynomial.evalEval x y W.polynomial = y ^ 2 + W.a₁ * x * y + W.a₃ * y - (x ^ 3 + W.a₂ * x ^ 2 + W.a₄ * x + W.a₆)

full_name: WeierstrassCurve.Affine.evalEval_polynomial_zero
code: @[simp]
lemma evalEval_polynomial_zero : W.polynomial.evalEval 0 0 = -W.a₆ 
goal: Polynomial.evalEval 0 0 W.polynomial = -W.a₆

full_name: WeierstrassCurve.Affine.Equation
code: /-- The proposition that an affine point $(x, y)$ lies in `W`. In other words, $W(x, y) = 0$. -/
def Equation (x y : R) : Prop 
goal: Prop

full_name: WeierstrassCurve.Affine.equation_iff'
code: lemma equation_iff' (x y : R) : W.Equation x y ↔
    y ^ 2 + W.a₁ * x * y + W.a₃ * y - (x ^ 3 + W.a₂ * x ^ 2 + W.a₄ * x + W.a₆) = 0 
goal: W.Equation x y ↔ y ^ 2 + W.a₁ * x * y + W.a₃ * y - (x ^ 3 + W.a₂ * x ^ 2 + W.a₄ * x + W.a₆) = 0

full_name: WeierstrassCurve.Affine.equation_iff
code: lemma equation_iff (x y : R) :
    W.Equation x y ↔ y ^ 2 + W.a₁ * x * y + W.a₃ * y = x ^ 3 + W.a₂ * x ^ 2 + W.a₄ * x + W.a₆ 
goal: W.Equation x y ↔ y ^ 2 + W.a₁ * x * y + W.a₃ * y = x ^ 3 + W.a₂ * x ^ 2 + W.a₄ * x + W.a₆

full_name: WeierstrassCurve.Affine.equation_zero
code: @[simp]
lemma equation_zero : W.Equation 0 0 ↔ W.a₆ = 0 
goal: W.Equation 0 0 ↔ W.a₆ = 0

full_name: WeierstrassCurve.Affine.equation_iff_variableChange
code: lemma equation_iff_variableChange (x y : R) :
    W.Equation x y ↔ (W.variableChange ⟨1, x, 0, y⟩).toAffine.Equation 0 0 
goal: W.Equation x y ↔ (WeierstrassCurve.variableChange W { u := 1, r := x, s := 0, t := y }).toAffine.Equation 0 0

full_name: WeierstrassCurve.Affine.polynomialX
code: /-- The partial derivative $W_X(X, Y)$ of $W(X, Y)$ with respect to $X$.

TODO: define this in terms of `Polynomial.derivative`. -/
noncomputable def polynomialX : R[X][Y] 
goal: R[X][Y]

full_name: WeierstrassCurve.Affine.evalEval_polynomialX
code: lemma evalEval_polynomialX (x y : R) :
    W.polynomialX.evalEval x y = W.a₁ * y - (3 * x ^ 2 + 2 * W.a₂ * x + W.a₄) 
goal: Polynomial.evalEval x y W.polynomialX = W.a₁ * y - (3 * x ^ 2 + 2 * W.a₂ * x + W.a₄)

full_name: WeierstrassCurve.Affine.evalEval_polynomialX_zero
code: @[simp]
lemma evalEval_polynomialX_zero : W.polynomialX.evalEval 0 0 = -W.a₄ 
goal: Polynomial.evalEval 0 0 W.polynomialX = -W.a₄

full_name: WeierstrassCurve.Affine.polynomialY
code: /-- The partial derivative $W_Y(X, Y)$ of $W(X, Y)$ with respect to $Y$.

TODO: define this in terms of `Polynomial.derivative`. -/
noncomputable def polynomialY : R[X][Y] 
goal: R[X][Y]

full_name: WeierstrassCurve.Affine.evalEval_polynomialY
code: lemma evalEval_polynomialY (x y : R) :
    W.polynomialY.evalEval x y = 2 * y + W.a₁ * x + W.a₃ 
goal: Polynomial.evalEval x y W.polynomialY = 2 * y + W.a₁ * x + W.a₃

full_name: WeierstrassCurve.Affine.evalEval_polynomialY_zero
code: @[simp]
lemma evalEval_polynomialY_zero : W.polynomialY.evalEval 0 0 = W.a₃ 
goal: Polynomial.evalEval 0 0 W.polynomialY = W.a₃

full_name: WeierstrassCurve.Affine.Nonsingular
code: /-- The proposition that an affine point $(x, y)$ in `W` is nonsingular.
In other words, either $W_X(x, y) \ne 0$ or $W_Y(x, y) \ne 0$.

Note that this definition is only mathematically accurate for fields.
TODO: generalise this definition to be mathematically accurate for a larger class of rings. -/
def Nonsingular (x y : R) : Prop 
goal: Prop

full_name: WeierstrassCurve.Affine.nonsingular_iff'
code: lemma nonsingular_iff' (x y : R) : W.Nonsingular x y ↔ W.Equation x y ∧
    (W.a₁ * y - (3 * x ^ 2 + 2 * W.a₂ * x + W.a₄) ≠ 0 ∨ 2 * y + W.a₁ * x + W.a₃ ≠ 0) 
goal: W.Nonsingular x y ↔ W.Equation x y ∧ (W.a₁ * y - (3 * x ^ 2 + 2 * W.a₂ * x + W.a₄) ≠ 0 ∨ 2 * y + W.a₁ * x + W.a₃ ≠ 0)

full_name: WeierstrassCurve.Affine.nonsingular_iff
code: lemma nonsingular_iff (x y : R) : W.Nonsingular x y ↔
    W.Equation x y ∧ (W.a₁ * y ≠ 3 * x ^ 2 + 2 * W.a₂ * x + W.a₄ ∨ y ≠ -y - W.a₁ * x - W.a₃) 
goal: W.Nonsingular x y ↔ W.Equation x y ∧ (W.a₁ * y ≠ 3 * x ^ 2 + 2 * W.a₂ * x + W.a₄ ∨ y ≠ -y - W.a₁ * x - W.a₃)

full_name: WeierstrassCurve.Affine.nonsingular_zero
code: @[simp]
lemma nonsingular_zero : W.Nonsingular 0 0 ↔ W.a₆ = 0 ∧ (W.a₃ ≠ 0 ∨ W.a₄ ≠ 0) 
goal: W.Nonsingular 0 0 ↔ W.a₆ = 0 ∧ (W.a₃ ≠ 0 ∨ W.a₄ ≠ 0)

full_name: WeierstrassCurve.Affine.nonsingular_iff_variableChange
code: lemma nonsingular_iff_variableChange (x y : R) :
    W.Nonsingular x y ↔ (W.variableChange ⟨1, x, 0, y⟩).toAffine.Nonsingular 0 0 
goal: W.Nonsingular x y ↔ (WeierstrassCurve.variableChange W { u := 1, r := x, s := 0, t := y }).toAffine.Nonsingular 0 0

full_name: WeierstrassCurve.Affine.nonsingular_zero_of_Δ_ne_zero
code: lemma nonsingular_zero_of_Δ_ne_zero (h : W.Equation 0 0) (hΔ : W.Δ ≠ 0) : W.Nonsingular 0 0 
goal: W.Nonsingular 0 0

full_name: WeierstrassCurve.Affine.nonsingular_of_Δ_ne_zero
code: /-- A Weierstrass curve is nonsingular at every point if its discriminant is non-zero. -/
lemma nonsingular_of_Δ_ne_zero {x y : R} (h : W.Equation x y) (hΔ : W.Δ ≠ 0) : W.Nonsingular x y 
goal: W.Nonsingular x y

full_name: WeierstrassCurve.Affine.negPolynomial
code: /-- The polynomial $-Y - a_1X - a_3$ associated to negation. -/
noncomputable def negPolynomial : R[X][Y] 
goal: R[X][Y]

full_name: WeierstrassCurve.Affine.Y_sub_polynomialY
code: lemma Y_sub_polynomialY : Y - W.polynomialY = W.negPolynomial 
goal: Y - W.polynomialY = W.negPolynomial

full_name: WeierstrassCurve.Affine.Y_sub_negPolynomial
code: lemma Y_sub_negPolynomial : Y - W.negPolynomial = W.polynomialY 
goal: Y - W.negPolynomial = W.polynomialY

full_name: WeierstrassCurve.Affine.negY
code: /-- The $Y$-coordinate of the negation of an affine point in `W`.

This depends on `W`, and has argument order: $x$, $y$. -/
@[simp]
def negY (x y : R) : R 
goal: R

full_name: WeierstrassCurve.Affine.negY_negY
code: lemma negY_negY (x y : R) : W.negY x (W.negY x y) = y 
goal: W.negY x (W.negY x y) = y

full_name: WeierstrassCurve.Affine.eval_negPolynomial
code: lemma eval_negPolynomial (x y : R) : W.negPolynomial.evalEval x y = W.negY x y 
goal: Polynomial.evalEval x y W.negPolynomial = W.negY x y

full_name: WeierstrassCurve.Affine.linePolynomial
code: /-- The polynomial $L(X - x) + y$ associated to the line $Y = L(X - x) + y$,
with a slope of $L$ that passes through an affine point $(x, y)$.

This does not depend on `W`, and has argument order: $x$, $y$, $L$. -/
noncomputable def linePolynomial (x y L : R) : R[X] 
goal: R[X]

full_name: WeierstrassCurve.Affine.addPolynomial
code: /-- The polynomial obtained by substituting the line $Y = L*(X - x) + y$, with a slope of $L$
that passes through an affine point $(x, y)$, into the polynomial $W(X, Y)$ associated to `W`.
If such a line intersects `W` at another point $(x', y')$, then the roots of this polynomial are
precisely $x$, $x'$, and the $X$-coordinate of the addition of $(x, y)$ and $(x', y')$.

This depends on `W`, and has argument order: $x$, $y$, $L$. -/
noncomputable def addPolynomial (x y L : R) : R[X] 
goal: R[X]

full_name: WeierstrassCurve.Affine.C_addPolynomial
code: lemma C_addPolynomial (x y L : R) : C (W.addPolynomial x y L) =
    (Y - C (linePolynomial x y L)) * (W.negPolynomial - C (linePolynomial x y L)) +
      W.polynomial 
goal: Polynomial.C (W.addPolynomial x y L) =
  (Y - Polynomial.C (WeierstrassCurve.Affine.linePolynomial x y L)) *
      (W.negPolynomial - Polynomial.C (WeierstrassCurve.Affine.linePolynomial x y L)) +
    W.polynomial

full_name: WeierstrassCurve.Affine.addPolynomial_eq
code: lemma addPolynomial_eq (x y L : R) : W.addPolynomial x y L = -Cubic.toPoly
    ⟨1, -L ^ 2 - W.a₁ * L + W.a₂,
      2 * x * L ^ 2 + (W.a₁ * x - 2 * y - W.a₃) * L + (-W.a₁ * y + W.a₄),
      -x ^ 2 * L ^ 2 + (2 * x * y + W.a₃ * x) * L - (y ^ 2 + W.a₃ * y - W.a₆)⟩ 
goal: W.addPolynomial x y L =
  -{ a := 1, b := -L ^ 2 - W.a₁ * L + W.a₂, c := 2 * x * L ^ 2 + (W.a₁ * x - 2 * y - W.a₃) * L + (-W.a₁ * y + W.a₄),
        d := -x ^ 2 * L ^ 2 + (2 * x * y + W.a₃ * x) * L - (y ^ 2 + W.a₃ * y - W.a₆) }.toPoly

full_name: WeierstrassCurve.Affine.addX
code: /-- The $X$-coordinate of the addition of two affine points $(x_1, y_1)$ and $(x_2, y_2)$ in `W`,
where the line through them is not vertical and has a slope of $L$.

This depends on `W`, and has argument order: $x_1$, $x_2$, $L$. -/
@[simp]
def addX (x₁ x₂ L : R) : R 
goal: R

full_name: WeierstrassCurve.Affine.negAddY
code: /-- The $Y$-coordinate of the negated addition of two affine points $(x_1, y_1)$ and $(x_2, y_2)$,
where the line through them is not vertical and has a slope of $L$.

This depends on `W`, and has argument order: $x_1$, $x_2$, $y_1$, $L$. -/
@[simp]
def negAddY (x₁ x₂ y₁ L : R) : R 
goal: R

full_name: WeierstrassCurve.Affine.addY
code: /-- The $Y$-coordinate of the addition of two affine points $(x_1, y_1)$ and $(x_2, y_2)$ in `W`,
where the line through them is not vertical and has a slope of $L$.

This depends on `W`, and has argument order: $x_1$, $x_2$, $y_1$, $L$. -/
@[simp]
def addY (x₁ x₂ y₁ L : R) : R 
goal: R

full_name: WeierstrassCurve.Affine.equation_neg_iff
code: lemma equation_neg_iff (x y : R) : W.Equation x (W.negY x y) ↔ W.Equation x y 
goal: W.Equation x (W.negY x y) ↔ W.Equation x y

full_name: WeierstrassCurve.Affine.nonsingular_neg_iff
code: lemma nonsingular_neg_iff (x y : R) : W.Nonsingular x (W.negY x y) ↔ W.Nonsingular x y 
goal: W.Nonsingular x (W.negY x y) ↔ W.Nonsingular x y

full_name: WeierstrassCurve.Affine.equation_add_iff
code: lemma equation_add_iff (x₁ x₂ y₁ L : R) :
    W.Equation (W.addX x₁ x₂ L) (W.negAddY x₁ x₂ y₁ L) ↔
      (W.addPolynomial x₁ y₁ L).eval (W.addX x₁ x₂ L) = 0 
goal: W.Equation (W.addX x₁ x₂ L) (W.negAddY x₁ x₂ y₁ L) ↔ Polynomial.eval (W.addX x₁ x₂ L) (W.addPolynomial x₁ y₁ L) = 0

full_name: WeierstrassCurve.Affine.equation_neg_of
code: lemma equation_neg_of {x y : R} (h : W.Equation x <| W.negY x y) : W.Equation x y 
goal: W.Equation x y

full_name: WeierstrassCurve.Affine.equation_neg
code: /-- The negation of an affine point in `W` lies in `W`. -/
lemma equation_neg {x y : R} (h : W.Equation x y) : W.Equation x <| W.negY x y 
goal: W.Equation x (W.negY x y)

full_name: WeierstrassCurve.Affine.nonsingular_neg_of
code: lemma nonsingular_neg_of {x y : R} (h : W.Nonsingular x <| W.negY x y) : W.Nonsingular x y 
goal: W.Nonsingular x y

full_name: WeierstrassCurve.Affine.nonsingular_neg
code: /-- The negation of a nonsingular affine point in `W` is nonsingular. -/
lemma nonsingular_neg {x y : R} (h : W.Nonsingular x y) : W.Nonsingular x <| W.negY x y 
goal: W.Nonsingular x (W.negY x y)

full_name: WeierstrassCurve.Affine.nonsingular_negAdd_of_eval_derivative_ne_zero
code: lemma nonsingular_negAdd_of_eval_derivative_ne_zero {x₁ x₂ y₁ L : R}
    (hx' : W.Equation (W.addX x₁ x₂ L) (W.negAddY x₁ x₂ y₁ L))
    (hx : (W.addPolynomial x₁ y₁ L).derivative.eval (W.addX x₁ x₂ L) ≠ 0) :
    W.Nonsingular (W.addX x₁ x₂ L) (W.negAddY x₁ x₂ y₁ L) 
goal: W.Nonsingular (W.addX x₁ x₂ L) (W.negAddY x₁ x₂ y₁ L)

full_name: WeierstrassCurve.Affine.slope
code: /-- The slope of the line through two affine points $(x_1, y_1)$ and $(x_2, y_2)$ in `W`.
If $x_1 \ne x_2$, then this line is the secant of `W` through $(x_1, y_1)$ and $(x_2, y_2)$,
and has slope $(y_1 - y_2) / (x_1 - x_2)$. Otherwise, if $y_1 \ne -y_1 - a_1x_1 - a_3$,
then this line is the tangent of `W` at $(x_1, y_1) = (x_2, y_2)$, and has slope
$(3x_1^2 + 2a_2x_1 + a_4 - a_1y_1) / (2y_1 + a_1x_1 + a_3)$. Otherwise, this line is vertical,
and has undefined slope, in which case this function returns the value 0.

This depends on `W`, and has argument order: $x_1$, $x_2$, $y_1$, $y_2$. -/
noncomputable def slope {F : Type u} [Field F] (W : Affine F) (x₁ x₂ y₁ y₂ : F) : F 
goal: F

full_name: WeierstrassCurve.Affine.slope_of_Y_eq
code: @[simp]
lemma slope_of_Y_eq {x₁ x₂ y₁ y₂ : F} (hx : x₁ = x₂) (hy : y₁ = W.negY x₂ y₂) :
    W.slope x₁ x₂ y₁ y₂ = 0 
goal: W.slope x₁ x₂ y₁ y₂ = 0

full_name: WeierstrassCurve.Affine.slope_of_Y_ne
code: @[simp]
lemma slope_of_Y_ne {x₁ x₂ y₁ y₂ : F} (hx : x₁ = x₂) (hy : y₁ ≠ W.negY x₂ y₂) :
    W.slope x₁ x₂ y₁ y₂ =
      (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁) 
goal: W.slope x₁ x₂ y₁ y₂ = (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)

full_name: WeierstrassCurve.Affine.slope_of_X_ne
code: @[simp]
lemma slope_of_X_ne {x₁ x₂ y₁ y₂ : F} (hx : x₁ ≠ x₂) :
    W.slope x₁ x₂ y₁ y₂ = (y₁ - y₂) / (x₁ - x₂) 
goal: W.slope x₁ x₂ y₁ y₂ = (y₁ - y₂) / (x₁ - x₂)

full_name: WeierstrassCurve.Affine.slope_of_Y_ne_eq_eval
code: lemma slope_of_Y_ne_eq_eval {x₁ x₂ y₁ y₂ : F} (hx : x₁ = x₂) (hy : y₁ ≠ W.negY x₂ y₂) :
    W.slope x₁ x₂ y₁ y₂ = -W.polynomialX.evalEval x₁ y₁ / W.polynomialY.evalEval x₁ y₁ 
goal: W.slope x₁ x₂ y₁ y₂ = -Polynomial.evalEval x₁ y₁ W.polynomialX / Polynomial.evalEval x₁ y₁ W.polynomialY

full_name: WeierstrassCurve.Affine.Y_eq_of_X_eq
code: lemma Y_eq_of_X_eq {x₁ x₂ y₁ y₂ : F} (h₁ : W.Equation x₁ y₁) (h₂ : W.Equation x₂ y₂)
    (hx : x₁ = x₂) : y₁ = y₂ ∨ y₁ = W.negY x₂ y₂ 
goal: y₁ = y₂ ∨ y₁ = W.negY x₂ y₂

full_name: WeierstrassCurve.Affine.Y_eq_of_Y_ne
code: lemma Y_eq_of_Y_ne {x₁ x₂ y₁ y₂ : F} (h₁ : W.Equation x₁ y₁) (h₂ : W.Equation x₂ y₂) (hx : x₁ = x₂)
    (hy : y₁ ≠ W.negY x₂ y₂) : y₁ = y₂ 
goal: y₁ = y₂

full_name: WeierstrassCurve.Affine.addPolynomial_slope
code: lemma addPolynomial_slope {x₁ x₂ y₁ y₂ : F} (h₁ : W.Equation x₁ y₁) (h₂ : W.Equation x₂ y₂)
    (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) : W.addPolynomial x₁ y₁ (W.slope x₁ x₂ y₁ y₂) =
      -((X - C x₁) * (X - C x₂) * (X - C (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂))) 
goal: W.addPolynomial x₁ y₁ (W.slope x₁ x₂ y₁ y₂) =
  -((Polynomial.X - Polynomial.C x₁) * (Polynomial.X - Polynomial.C x₂) *
      (Polynomial.X - Polynomial.C (W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂))))

full_name: WeierstrassCurve.Affine.equation_negAdd
code: /-- The negated addition of two affine points in `W` on a sloped line lies in `W`. -/
lemma equation_negAdd {x₁ x₂ y₁ y₂ : F} (h₁ : W.Equation x₁ y₁) (h₂ : W.Equation x₂ y₂)
    (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) : W.Equation
      (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂) (W.negAddY x₁ x₂ y₁ <| W.slope x₁ x₂ y₁ y₂) 
goal: W.Equation (W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂)) (W.negAddY x₁ x₂ y₁ (W.slope x₁ x₂ y₁ y₂))

full_name: WeierstrassCurve.Affine.equation_add
code: /-- The addition of two affine points in `W` on a sloped line lies in `W`. -/
lemma equation_add {x₁ x₂ y₁ y₂ : F} (h₁ : W.Equation x₁ y₁) (h₂ : W.Equation x₂ y₂)
    (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) :
    W.Equation (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂) (W.addY x₁ x₂ y₁ <| W.slope x₁ x₂ y₁ y₂) 
goal: W.Equation (W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂)) (W.addY x₁ x₂ y₁ (W.slope x₁ x₂ y₁ y₂))

full_name: WeierstrassCurve.Affine.derivative_addPolynomial_slope
code: lemma derivative_addPolynomial_slope {x₁ x₂ y₁ y₂ : F} (h₁ : W.Equation x₁ y₁)
    (h₂ : W.Equation x₂ y₂) (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) :
    derivative (W.addPolynomial x₁ y₁ <| W.slope x₁ x₂ y₁ y₂) =
      -((X - C x₁) * (X - C x₂) + (X - C x₁) * (X - C (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂)) +
          (X - C x₂) * (X - C (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂))) 
goal: Polynomial.derivative (W.addPolynomial x₁ y₁ (W.slope x₁ x₂ y₁ y₂)) =
  -((Polynomial.X - Polynomial.C x₁) * (Polynomial.X - Polynomial.C x₂) +
        (Polynomial.X - Polynomial.C x₁) * (Polynomial.X - Polynomial.C (W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂))) +
      (Polynomial.X - Polynomial.C x₂) * (Polynomial.X - Polynomial.C (W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂))))

full_name: WeierstrassCurve.Affine.nonsingular_negAdd
code: /-- The negated addition of two nonsingular affine points in `W` on a sloped line is nonsingular. -/
lemma nonsingular_negAdd {x₁ x₂ y₁ y₂ : F} (h₁ : W.Nonsingular x₁ y₁) (h₂ : W.Nonsingular x₂ y₂)
    (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) : W.Nonsingular
      (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂) (W.negAddY x₁ x₂ y₁ <| W.slope x₁ x₂ y₁ y₂) 
goal: W.Nonsingular (W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂)) (W.negAddY x₁ x₂ y₁ (W.slope x₁ x₂ y₁ y₂))

full_name: WeierstrassCurve.Affine.nonsingular_add
code: /-- The addition of two nonsingular affine points in `W` on a sloped line is nonsingular. -/
lemma nonsingular_add {x₁ x₂ y₁ y₂ : F} (h₁ : W.Nonsingular x₁ y₁) (h₂ : W.Nonsingular x₂ y₂)
    (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) :
    W.Nonsingular (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂) (W.addY x₁ x₂ y₁ <| W.slope x₁ x₂ y₁ y₂) 
goal: W.Nonsingular (W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂)) (W.addY x₁ x₂ y₁ (W.slope x₁ x₂ y₁ y₂))

full_name: WeierstrassCurve.Affine.addX_eq_addX_negY_sub
code: /-- The formula x(P₁ + P₂) = x(P₁ - P₂) - ψ(P₁)ψ(P₂) / (x(P₂) - x(P₁))²,
where ψ(x,y) = 2y + a₁x + a₃. -/
lemma addX_eq_addX_negY_sub :
    W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂) = W.addX x₁ x₂ (W.slope x₁ x₂ y₁ (W.negY x₂ y₂))
      - (y₁ - W.negY x₁ y₁) * (y₂ - W.negY x₂ y₂) / (x₂ - x₁) ^ 2 
goal: W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂) =
  W.addX x₁ x₂ (W.slope x₁ x₂ y₁ (W.negY x₂ y₂)) - (y₁ - W.negY x₁ y₁) * (y₂ - W.negY x₂ y₂) / (x₂ - x₁) ^ 2

full_name: WeierstrassCurve.Affine.cyclic_sum_Y_mul_X_sub_X
code: /-- The formula y(P₁)(x(P₂) - x(P₃)) + y(P₂)(x(P₃) - x(P₁)) + y(P₃)(x(P₁) - x(P₂)) = 0,
assuming that P₁ + P₂ + P₃ = O. -/
lemma cyclic_sum_Y_mul_X_sub_X :
    letI x₃ := W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂)
    y₁ * (x₂ - x₃) + y₂ * (x₃ - x₁) + W.negAddY x₁ x₂ y₁ (W.slope x₁ x₂ y₁ y₂) * (x₁ - x₂) = 0 
goal: y₁ * (x₂ - W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂)) + y₂ * (W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂) - x₁) +
    W.negAddY x₁ x₂ y₁ (W.slope x₁ x₂ y₁ y₂) * (x₁ - x₂) =
  0

full_name: WeierstrassCurve.Affine.addY_sub_negY_addY
code: /-- The formula
ψ(P₁ + P₂) = (ψ(P₂)(x(P₁) - x(P₃)) - ψ(P₁)(x(P₂) - x(P₃))) / (x(P₂) - x(P₁)),
where ψ(x,y) = 2y + a₁x + a₃. -/
lemma addY_sub_negY_addY :
    letI x₃ := W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂)
    letI y₃ := W.addY x₁ x₂ y₁ (W.slope x₁ x₂ y₁ y₂)
    y₃ - W.negY x₃ y₃ =
      ((y₂ - W.negY x₂ y₂) * (x₁ - x₃) - (y₁ - W.negY x₁ y₁) * (x₂ - x₃)) / (x₂ - x₁) 
goal: W.addY x₁ x₂ y₁ (W.slope x₁ x₂ y₁ y₂) -
    W.negY (W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂)) (W.addY x₁ x₂ y₁ (W.slope x₁ x₂ y₁ y₂)) =
  ((y₂ - W.negY x₂ y₂) * (x₁ - W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂)) -
      (y₁ - W.negY x₁ y₁) * (x₂ - W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂))) /
    (x₂ - x₁)

full_name: WeierstrassCurve.Affine.Point
code: /-- A nonsingular rational point on a Weierstrass curve `W` in affine coordinates. This is either
the unique point at infinity `WeierstrassCurve.Affine.Point.zero` or the nonsingular affine points
`WeierstrassCurve.Affine.Point.some` $(x, y)$ satisfying the Weierstrass equation of `W`. -/
inductive Point
  | zero
  | some {x y : R} (h : W.Nonsingular x y)
goal: Type u

full_name: WeierstrassCurve.Affine.Point.zero
code: /-- A nonsingular rational point on a Weierstrass curve `W` in affine coordinates. This is either
the unique point at infinity `WeierstrassCurve.Affine.Point.zero` or the nonsingular affine points
`WeierstrassCurve.Affine.Point.some` $(x, y)$ satisfying the Weierstrass equation of `W`. -/
inductive Point
  | zero
  | some {x y : R} (h : W.Nonsingular x y)
goal: W.Point

full_name: WeierstrassCurve.Affine.Point.some
code: /-- A nonsingular rational point on a Weierstrass curve `W` in affine coordinates. This is either
the unique point at infinity `WeierstrassCurve.Affine.Point.zero` or the nonsingular affine points
`WeierstrassCurve.Affine.Point.some` $(x, y)$ satisfying the Weierstrass equation of `W`. -/
inductive Point
  | zero
  | some {x y : R} (h : W.Nonsingular x y)
goal: W.Point

full_name: WeierstrassCurve.Affine.«_aux_Mathlib_AlgebraicGeometry_EllipticCurve_Affine___macroRules_WeierstrassCurve_Affine_term_⟮_⟯_1»
code: /-- For an algebraic extension `S` of `R`, the type of nonsingular `S`-rational points on `W`. -/
scoped notation3:max W "⟮" S "⟯" => Affine.Point <| baseChange W S
goal: Lean.Macro

full_name: WeierstrassCurve.Affine.Point.instInhabited
code: instance : Inhabited W.Point 
goal: Inhabited W.Point

full_name: WeierstrassCurve.Affine.Point.instZero
code: instance : Zero W.Point 
goal: Zero W.Point

full_name: WeierstrassCurve.Affine.Point.zero_def
code: lemma zero_def : (zero : W.Point) = 0 
goal: WeierstrassCurve.Affine.Point.zero = 0

full_name: WeierstrassCurve.Affine.Point.some_ne_zero
code: lemma some_ne_zero {x y : R} (h : W.Nonsingular x y) : some h ≠ 0 
goal: WeierstrassCurve.Affine.Point.some h ≠ 0

full_name: WeierstrassCurve.Affine.Point.neg
code: /-- The negation of a nonsingular rational point on `W`.

Given a nonsingular rational point `P` on `W`, use `-P` instead of `neg P`. -/
def neg : W.Point → W.Point
  
goal: W.Point → W.Point

full_name: WeierstrassCurve.Affine.Point.instNeg
code: instance : Neg W.Point 
goal: Neg W.Point

full_name: WeierstrassCurve.Affine.Point.neg_def
code: lemma neg_def (P : W.Point) : P.neg = -P 
goal: P.neg = -P

full_name: WeierstrassCurve.Affine.Point.neg_zero
code: @[simp]
lemma neg_zero : (-0 : W.Point) = 0 
goal: -0 = 0

full_name: WeierstrassCurve.Affine.Point.neg_some
code: @[simp]
lemma neg_some {x y : R} (h : W.Nonsingular x y) : -some h = some (nonsingular_neg h) 
goal: -WeierstrassCurve.Affine.Point.some h = WeierstrassCurve.Affine.Point.some ⋯

full_name: WeierstrassCurve.Affine.Point.instInvolutiveNeg
code: instance : InvolutiveNeg W.Point 
goal: InvolutiveNeg W.Point

full_name: WeierstrassCurve.Affine.Point.add
code: /-- The addition of two nonsingular rational points on `W`.

Given two nonsingular rational points `P` and `Q` on `W`, use `P + Q` instead of `add P Q`. -/
noncomputable def add : W.Point → W.Point → W.Point
  
goal: W.Point → W.Point → W.Point

full_name: WeierstrassCurve.Affine.Point.instAddPoint
code: noncomputable instance instAddPoint : Add W.Point 
goal: Add W.Point

full_name: WeierstrassCurve.Affine.Point.add_def
code: lemma add_def (P Q : W.Point) : P.add Q = P + Q 
goal: P.add Q = P + Q

full_name: WeierstrassCurve.Affine.Point.instAddZeroClassPoint
code: noncomputable instance instAddZeroClassPoint : AddZeroClass W.Point 
goal: AddZeroClass W.Point

full_name: WeierstrassCurve.Affine.Point.add_of_Y_eq
code: @[simp]
lemma add_of_Y_eq {x₁ x₂ y₁ y₂ : F} {h₁ : W.Nonsingular x₁ y₁} {h₂ : W.Nonsingular x₂ y₂}
    (hx : x₁ = x₂) (hy : y₁ = W.negY x₂ y₂) : some h₁ + some h₂ = 0 
goal: WeierstrassCurve.Affine.Point.some h₁ + WeierstrassCurve.Affine.Point.some h₂ = 0

full_name: WeierstrassCurve.Affine.Point.add_self_of_Y_eq
code: @[simp]
lemma add_self_of_Y_eq {x₁ y₁ : F} {h₁ : W.Nonsingular x₁ y₁} (hy : y₁ = W.negY x₁ y₁) :
    some h₁ + some h₁ = 0 
goal: WeierstrassCurve.Affine.Point.some h₁ + WeierstrassCurve.Affine.Point.some h₁ = 0

full_name: WeierstrassCurve.Affine.Point.add_of_imp
code: @[simp]
lemma add_of_imp {x₁ x₂ y₁ y₂ : F} {h₁ : W.Nonsingular x₁ y₁} {h₂ : W.Nonsingular x₂ y₂}
    (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) : some h₁ + some h₂ = some (nonsingular_add h₁ h₂ hxy) 
goal: WeierstrassCurve.Affine.Point.some h₁ + WeierstrassCurve.Affine.Point.some h₂ = WeierstrassCurve.Affine.Point.some ⋯

full_name: WeierstrassCurve.Affine.Point.add_of_Y_ne
code: @[simp]
lemma add_of_Y_ne {x₁ x₂ y₁ y₂ : F} {h₁ : W.Nonsingular x₁ y₁} {h₂ : W.Nonsingular x₂ y₂}
    (hy : y₁ ≠ W.negY x₂ y₂) :
    some h₁ + some h₂ = some (nonsingular_add h₁ h₂ fun _ ↦ hy) 
goal: WeierstrassCurve.Affine.Point.some h₁ + WeierstrassCurve.Affine.Point.some h₂ = WeierstrassCurve.Affine.Point.some ⋯

full_name: WeierstrassCurve.Affine.Point.add_of_Y_ne'
code: lemma add_of_Y_ne' {x₁ x₂ y₁ y₂ : F} {h₁ : W.Nonsingular x₁ y₁} {h₂ : W.Nonsingular x₂ y₂}
    (hy : y₁ ≠ W.negY x₂ y₂) :
    some h₁ + some h₂ = -some (nonsingular_negAdd h₁ h₂ fun _ ↦ hy) 
goal: WeierstrassCurve.Affine.Point.some h₁ + WeierstrassCurve.Affine.Point.some h₂ = -WeierstrassCurve.Affine.Point.some ⋯

full_name: WeierstrassCurve.Affine.Point.add_self_of_Y_ne
code: @[simp]
lemma add_self_of_Y_ne {x₁ y₁ : F} {h₁ : W.Nonsingular x₁ y₁} (hy : y₁ ≠ W.negY x₁ y₁) :
    some h₁ + some h₁ = some (nonsingular_add h₁ h₁ fun _ => hy) 
goal: WeierstrassCurve.Affine.Point.some h₁ + WeierstrassCurve.Affine.Point.some h₁ = WeierstrassCurve.Affine.Point.some ⋯

full_name: WeierstrassCurve.Affine.Point.add_self_of_Y_ne'
code: lemma add_self_of_Y_ne' {x₁ y₁ : F} {h₁ : W.Nonsingular x₁ y₁} (hy : y₁ ≠ W.negY x₁ y₁) :
    some h₁ + some h₁ = -some (nonsingular_negAdd h₁ h₁ fun _ => hy) 
goal: WeierstrassCurve.Affine.Point.some h₁ + WeierstrassCurve.Affine.Point.some h₁ = -WeierstrassCurve.Affine.Point.some ⋯

full_name: WeierstrassCurve.Affine.Point.add_of_X_ne
code: @[simp]
lemma add_of_X_ne {x₁ x₂ y₁ y₂ : F} {h₁ : W.Nonsingular x₁ y₁} {h₂ : W.Nonsingular x₂ y₂}
    (hx : x₁ ≠ x₂) : some h₁ + some h₂ = some (nonsingular_add h₁ h₂ fun h => (hx h).elim) 
goal: WeierstrassCurve.Affine.Point.some h₁ + WeierstrassCurve.Affine.Point.some h₂ = WeierstrassCurve.Affine.Point.some ⋯

full_name: WeierstrassCurve.Affine.Point.add_of_X_ne'
code: lemma add_of_X_ne' {x₁ x₂ y₁ y₂ : F} {h₁ : W.Nonsingular x₁ y₁} {h₂ : W.Nonsingular x₂ y₂}
    (hx : x₁ ≠ x₂) : some h₁ + some h₂ = -some (nonsingular_negAdd h₁ h₂ fun h => (hx h).elim) 
goal: WeierstrassCurve.Affine.Point.some h₁ + WeierstrassCurve.Affine.Point.some h₂ = -WeierstrassCurve.Affine.Point.some ⋯

full_name: WeierstrassCurve.Affine.map_polynomial
code: lemma map_polynomial : (W.map f).toAffine.polynomial = W.polynomial.map (mapRingHom f) 
goal: (WeierstrassCurve.map W f).toAffine.polynomial = Polynomial.map (Polynomial.mapRingHom f) W.polynomial

full_name: WeierstrassCurve.Affine.evalEval_baseChange_polynomial_X_Y
code: lemma evalEval_baseChange_polynomial_X_Y :
    (W.baseChange R[X][Y]).toAffine.polynomial.evalEval (C X) Y = W.polynomial 
goal: Polynomial.evalEval (Polynomial.C Polynomial.X) Y (WeierstrassCurve.baseChange W R[X][Y]).toAffine.polynomial =
  W.polynomial

full_name: WeierstrassCurve.Affine.Equation.map
code: lemma Equation.map {x y : R} (h : W.Equation x y) : Equation (W.map f) (f x) (f y) 
goal: WeierstrassCurve.Affine.Equation (WeierstrassCurve.map W f) (f x) (f y)

full_name: WeierstrassCurve.Affine.map_equation
code: lemma map_equation (hf : Function.Injective f) (x y : R) :
    (W.map f).toAffine.Equation (f x) (f y) ↔ W.Equation x y 
goal: (WeierstrassCurve.map W f).toAffine.Equation (f x) (f y) ↔ W.Equation x y

full_name: WeierstrassCurve.Affine.map_polynomialX
code: lemma map_polynomialX : (W.map f).toAffine.polynomialX = W.polynomialX.map (mapRingHom f) 
goal: (WeierstrassCurve.map W f).toAffine.polynomialX = Polynomial.map (Polynomial.mapRingHom f) W.polynomialX

full_name: WeierstrassCurve.Affine.map_polynomialY
code: lemma map_polynomialY : (W.map f).toAffine.polynomialY = W.polynomialY.map (mapRingHom f) 
goal: (WeierstrassCurve.map W f).toAffine.polynomialY = Polynomial.map (Polynomial.mapRingHom f) W.polynomialY

full_name: WeierstrassCurve.Affine.map_nonsingular
code: lemma map_nonsingular (hf : Function.Injective f) (x y : R) :
    (W.map f).toAffine.Nonsingular (f x) (f y) ↔ W.Nonsingular x y 
goal: (WeierstrassCurve.map W f).toAffine.Nonsingular (f x) (f y) ↔ W.Nonsingular x y

full_name: WeierstrassCurve.Affine.map_negPolynomial
code: lemma map_negPolynomial :
    (W.map f).toAffine.negPolynomial = W.negPolynomial.map (mapRingHom f) 
goal: (WeierstrassCurve.map W f).toAffine.negPolynomial = Polynomial.map (Polynomial.mapRingHom f) W.negPolynomial

full_name: WeierstrassCurve.Affine.map_negY
code: lemma map_negY (x y : R) : (W.map f).toAffine.negY (f x) (f y) = f (W.negY x y) 
goal: (WeierstrassCurve.map W f).toAffine.negY (f x) (f y) = f (W.negY x y)

full_name: WeierstrassCurve.Affine.map_linePolynomial
code: lemma map_linePolynomial (x y L : R) :
    linePolynomial (f x) (f y) (f L) = (linePolynomial x y L).map f 
goal: WeierstrassCurve.Affine.linePolynomial (f x) (f y) (f L) =
  Polynomial.map f (WeierstrassCurve.Affine.linePolynomial x y L)

full_name: WeierstrassCurve.Affine.map_addPolynomial
code: lemma map_addPolynomial (x y L : R) :
    (W.map f).toAffine.addPolynomial (f x) (f y) (f L) = (W.addPolynomial x y L).map f 
goal: (WeierstrassCurve.map W f).toAffine.addPolynomial (f x) (f y) (f L) = Polynomial.map f (W.addPolynomial x y L)

full_name: WeierstrassCurve.Affine.map_addX
code: lemma map_addX (x₁ x₂ L : R) :
    (W.map f).toAffine.addX (f x₁) (f x₂) (f L) = f (W.addX x₁ x₂ L) 
goal: (WeierstrassCurve.map W f).toAffine.addX (f x₁) (f x₂) (f L) = f (W.addX x₁ x₂ L)

full_name: WeierstrassCurve.Affine.map_negAddY
code: lemma map_negAddY (x₁ x₂ y₁ L : R) :
    (W.map f).toAffine.negAddY (f x₁) (f x₂) (f y₁) (f L) = f (W.negAddY x₁ x₂ y₁ L) 
goal: (WeierstrassCurve.map W f).toAffine.negAddY (f x₁) (f x₂) (f y₁) (f L) = f (W.negAddY x₁ x₂ y₁ L)

full_name: WeierstrassCurve.Affine.map_addY
code: lemma map_addY (x₁ x₂ y₁ L : R) :
    (W.map f).toAffine.addY (f x₁) (f x₂) (f y₁) (f L) = f (W.toAffine.addY x₁ x₂ y₁ L) 
goal: (WeierstrassCurve.map W f).toAffine.addY (f x₁) (f x₂) (f y₁) (f L) = f ((WeierstrassCurve.toAffine W).addY x₁ x₂ y₁ L)

full_name: WeierstrassCurve.Affine.map_slope
code: lemma map_slope {F : Type u} [Field F] (W : Affine F) {K : Type v} [Field K] (f : F →+* K)
    (x₁ x₂ y₁ y₂ : F) : (W.map f).toAffine.slope (f x₁) (f x₂) (f y₁) (f y₂) =
      f (W.slope x₁ x₂ y₁ y₂) 
goal: (WeierstrassCurve.map W f).toAffine.slope (f x₁) (f x₂) (f y₁) (f y₂) = f (W.slope x₁ x₂ y₁ y₂)

full_name: WeierstrassCurve.Affine.baseChange_polynomial
code: lemma baseChange_polynomial : (W.baseChange B).toAffine.polynomial =
    (W.baseChange A).toAffine.polynomial.map (mapRingHom f) 
goal: (WeierstrassCurve.baseChange W B).toAffine.polynomial =
  Polynomial.map (Polynomial.mapRingHom ↑f) (WeierstrassCurve.baseChange W A).toAffine.polynomial

full_name: WeierstrassCurve.Affine.baseChange_equation
code: lemma baseChange_equation (hf : Function.Injective f) (x y : A) :
    (W.baseChange B).toAffine.Equation (f x) (f y) ↔ (W.baseChange A).toAffine.Equation x y 
goal: (WeierstrassCurve.baseChange W B).toAffine.Equation (f x) (f y) ↔
  (WeierstrassCurve.baseChange W A).toAffine.Equation x y

full_name: WeierstrassCurve.Affine.baseChange_polynomialX
code: lemma baseChange_polynomialX : (W.baseChange B).toAffine.polynomialX =
    (W.baseChange A).toAffine.polynomialX.map (mapRingHom f) 
goal: (WeierstrassCurve.baseChange W B).toAffine.polynomialX =
  Polynomial.map (Polynomial.mapRingHom ↑f) (WeierstrassCurve.baseChange W A).toAffine.polynomialX

full_name: WeierstrassCurve.Affine.baseChange_polynomialY
code: lemma baseChange_polynomialY : (W.baseChange B).toAffine.polynomialY =
    (W.baseChange A).toAffine.polynomialY.map (mapRingHom f) 
goal: (WeierstrassCurve.baseChange W B).toAffine.polynomialY =
  Polynomial.map (Polynomial.mapRingHom ↑f) (WeierstrassCurve.baseChange W A).toAffine.polynomialY

full_name: WeierstrassCurve.Affine.baseChange_nonsingular
code: lemma baseChange_nonsingular (hf : Function.Injective f) (x y : A) :
    (W.baseChange B).toAffine.Nonsingular (f x) (f y) ↔
      (W.baseChange A).toAffine.Nonsingular x y 
goal: (WeierstrassCurve.baseChange W B).toAffine.Nonsingular (f x) (f y) ↔
  (WeierstrassCurve.baseChange W A).toAffine.Nonsingular x y

full_name: WeierstrassCurve.Affine.baseChange_negPolynomial
code: lemma baseChange_negPolynomial :
    (W.baseChange B).toAffine.negPolynomial =
      (W.baseChange A).toAffine.negPolynomial.map (mapRingHom f) 
goal: (WeierstrassCurve.baseChange W B).toAffine.negPolynomial =
  Polynomial.map (Polynomial.mapRingHom ↑f) (WeierstrassCurve.baseChange W A).toAffine.negPolynomial

full_name: WeierstrassCurve.Affine.baseChange_negY
code: lemma baseChange_negY (x y : A) :
    (W.baseChange B).toAffine.negY (f x) (f y) = f ((W.baseChange A).toAffine.negY x y) 
goal: (WeierstrassCurve.baseChange W B).toAffine.negY (f x) (f y) = f ((WeierstrassCurve.baseChange W A).toAffine.negY x y)

full_name: WeierstrassCurve.Affine.baseChange_addPolynomial
code: lemma baseChange_addPolynomial (x y L : A) :
    (W.baseChange B).toAffine.addPolynomial (f x) (f y) (f L) =
      ((W.baseChange A).toAffine.addPolynomial x y L).map f 
goal: (WeierstrassCurve.baseChange W B).toAffine.addPolynomial (f x) (f y) (f L) =
  Polynomial.map (↑f) ((WeierstrassCurve.baseChange W A).toAffine.addPolynomial x y L)

full_name: WeierstrassCurve.Affine.baseChange_addX
code: lemma baseChange_addX (x₁ x₂ L : A) :
    (W.baseChange B).toAffine.addX (f x₁) (f x₂) (f L) =
      f ((W.baseChange A).toAffine.addX x₁ x₂ L) 
goal: (WeierstrassCurve.baseChange W B).toAffine.addX (f x₁) (f x₂) (f L) =
  f ((WeierstrassCurve.baseChange W A).toAffine.addX x₁ x₂ L)

full_name: WeierstrassCurve.Affine.baseChange_negAddY
code: lemma baseChange_negAddY (x₁ x₂ y₁ L : A) :
    (W.baseChange B).toAffine.negAddY (f x₁) (f x₂) (f y₁) (f L) =
      f ((W.baseChange A).toAffine.negAddY x₁ x₂ y₁ L) 
goal: (WeierstrassCurve.baseChange W B).toAffine.negAddY (f x₁) (f x₂) (f y₁) (f L) =
  f ((WeierstrassCurve.baseChange W A).toAffine.negAddY x₁ x₂ y₁ L)

full_name: WeierstrassCurve.Affine.baseChange_addY
code: lemma baseChange_addY (x₁ x₂ y₁ L : A) :
    (W.baseChange B).toAffine.addY (f x₁) (f x₂) (f y₁) (f L) =
      f ((W.baseChange A).toAffine.addY x₁ x₂ y₁ L) 
goal: (WeierstrassCurve.baseChange W B).toAffine.addY (f x₁) (f x₂) (f y₁) (f L) =
  f ((WeierstrassCurve.baseChange W A).toAffine.addY x₁ x₂ y₁ L)

full_name: WeierstrassCurve.Affine.baseChange_slope
code: lemma baseChange_slope (x₁ x₂ y₁ y₂ : F) :
    (W.baseChange K).toAffine.slope (f x₁) (f x₂) (f y₁) (f y₂) =
      f ((W.baseChange F).toAffine.slope x₁ x₂ y₁ y₂) 
goal: (WeierstrassCurve.baseChange W K).toAffine.slope (f x₁) (f x₂) (f y₁) (f y₂) =
  f ((WeierstrassCurve.baseChange W F).toAffine.slope x₁ x₂ y₁ y₂)

full_name: WeierstrassCurve.Affine.Point.mapFun
code: /-- The function from `W⟮F⟯` to `W⟮K⟯` induced by an algebra homomorphism `f : F →ₐ[S] K`,
where `W` is defined over a subring of a ring `S`, and `F` and `K` are field extensions of `S`. -/
def mapFun : W⟮F⟯ → W⟮K⟯
  
goal: WeierstrassCurve.Affine.Point (WeierstrassCurve.baseChange W F) →
  WeierstrassCurve.Affine.Point (WeierstrassCurve.baseChange W K)

full_name: WeierstrassCurve.Affine.Point.map
code: /-- The group homomorphism from `W⟮F⟯` to `W⟮K⟯` induced by an algebra homomorphism `f : F →ₐ[S] K`,
where `W` is defined over a subring of a ring `S`, and `F` and `K` are field extensions of `S`. -/
def map : W⟮F⟯ →+ W⟮K⟯ 
goal: WeierstrassCurve.Affine.Point (WeierstrassCurve.baseChange W F) →+
  WeierstrassCurve.Affine.Point (WeierstrassCurve.baseChange W K)

full_name: WeierstrassCurve.Affine.Point.map_zero
code: lemma map_zero : map W f (0 : W⟮F⟯) = 0 
goal: (WeierstrassCurve.Affine.Point.map W f) 0 = 0

full_name: WeierstrassCurve.Affine.Point.map_some
code: lemma map_some {x y : F} (h : (W.baseChange F).toAffine.Nonsingular x y) :
    map W f (some h) = some ((W.baseChange_nonsingular f.injective ..).mpr h) 
goal: (WeierstrassCurve.Affine.Point.map W f) (WeierstrassCurve.Affine.Point.some h) = WeierstrassCurve.Affine.Point.some ⋯

full_name: WeierstrassCurve.Affine.Point.map_id
code: lemma map_id (P : W⟮F⟯) : map W (Algebra.ofId F F) P = P 
goal: (WeierstrassCurve.Affine.Point.map W (Algebra.ofId F F)) P = P

full_name: WeierstrassCurve.Affine.Point.map_map
code: lemma map_map (P : W⟮F⟯) : map W g (map W f P) = map W (g.comp f) P 
goal: (WeierstrassCurve.Affine.Point.map W g) ((WeierstrassCurve.Affine.Point.map W f) P) =
  (WeierstrassCurve.Affine.Point.map W (g.comp f)) P

full_name: WeierstrassCurve.Affine.Point.map_injective
code: lemma map_injective : Function.Injective <| map W f 
goal: Function.Injective ⇑(WeierstrassCurve.Affine.Point.map W f)

full_name: WeierstrassCurve.Affine.Point.baseChange
code: /-- The group homomorphism from `W⟮F⟯` to `W⟮K⟯` induced by the base change from `F` to `K`,
where `W` is defined over a subring of a ring `S`, and `F` and `K` are field extensions of `S`. -/
abbrev baseChange [Algebra F K] [IsScalarTower R F K] : W⟮F⟯ →+ W⟮K⟯ 
goal: WeierstrassCurve.Affine.Point (WeierstrassCurve.baseChange W F) →+
  WeierstrassCurve.Affine.Point (WeierstrassCurve.baseChange W K)

full_name: WeierstrassCurve.Affine.Point.map_baseChange
code: lemma map_baseChange [Algebra F K] [IsScalarTower R F K] [Algebra F L] [IsScalarTower R F L]
    (f : K →ₐ[F] L) (P : W⟮F⟯) : map W f (baseChange W F K P) = baseChange W F L P 
goal: (WeierstrassCurve.Affine.Point.map W f) ((WeierstrassCurve.Affine.Point.baseChange W F K) P) =
  (WeierstrassCurve.Affine.Point.baseChange W F L) P

full_name: EllipticCurve.toAffine
code: /-- The coercion from an elliptic curve to a Weierstrass curve in affine coordinates. -/
abbrev EllipticCurve.toAffine {R : Type u} [CommRing R] (E : EllipticCurve R) :
    WeierstrassCurve.Affine R 
goal: WeierstrassCurve.Affine R

full_name: EllipticCurve.Affine.nonsingular
code: lemma nonsingular [Nontrivial R] {x y : R} (h : E.toAffine.Equation x y) :
    E.toAffine.Nonsingular x y 
goal: E.toAffine.Nonsingular x y