File: Mathlib/AlgebraicGeometry/EllipticCurve/Jacobian.lean

full_name: _aux_Mathlib_AlgebraicGeometry_EllipticCurve_Jacobian___macroRules_termX_1
code: local notation3 "x" => (0 : Fin 3)
goal: Lean.Macro

full_name: _aux_Mathlib_AlgebraicGeometry_EllipticCurve_Jacobian___macroRules_termY_1
code: local notation3 "y" => (1 : Fin 3)
goal: Lean.Macro

full_name: _aux_Mathlib_AlgebraicGeometry_EllipticCurve_Jacobian___macroRules_termZ_1
code: local notation3 "z" => (2 : Fin 3)
goal: Lean.Macro

full_name: _aux_Mathlib_AlgebraicGeometry_EllipticCurve_Jacobian___macroRules_tacticMatrix_simp_1
code: macro "matrix_simp" : tactic =>
  `(tactic| simp only [Matrix.head_cons, Matrix.tail_cons, Matrix.smul_empty, Matrix.smul_cons,
    Matrix.cons_val_zero, Matrix.cons_val_one, Matrix.cons_val_two])
goal: Lean.Macro

full_name: tacticMatrix_simp._@.Mathlib.AlgebraicGeometry.EllipticCurve.Jacobian._hyg.960
code: macro "matrix_simp" : tactic =>
  `(tactic| simp only [Matrix.head_cons, Matrix.tail_cons, Matrix.smul_empty, Matrix.smul_cons,
    Matrix.cons_val_zero, Matrix.cons_val_one, Matrix.cons_val_two])
goal: Lean.ParserDescr

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

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

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

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

full_name: WeierstrassCurve.Jacobian.tacticPderiv_simp._@.Mathlib.AlgebraicGeometry.EllipticCurve.Jacobian._hyg.1733
code: macro "pderiv_simp" : tactic =>
  `(tactic| simp only [map_ofNat, map_neg, map_add, map_sub, map_mul, pderiv_mul, pderiv_pow,
    pderiv_C, pderiv_X_self, pderiv_X_of_ne one_ne_zero, pderiv_X_of_ne one_ne_zero.symm,
    pderiv_X_of_ne (by decide : z ≠ x), pderiv_X_of_ne (by decide : x ≠ z),
    pderiv_X_of_ne (by decide : z ≠ y), pderiv_X_of_ne (by decide : y ≠ z)])
goal: Lean.ParserDescr

full_name: WeierstrassCurve.Jacobian._aux_Mathlib_AlgebraicGeometry_EllipticCurve_Jacobian___macroRules_WeierstrassCurve_Jacobian_tacticPderiv_simp_1
code: macro "pderiv_simp" : tactic =>
  `(tactic| simp only [map_ofNat, map_neg, map_add, map_sub, map_mul, pderiv_mul, pderiv_pow,
    pderiv_C, pderiv_X_self, pderiv_X_of_ne one_ne_zero, pderiv_X_of_ne one_ne_zero.symm,
    pderiv_X_of_ne (by decide : z ≠ x), pderiv_X_of_ne (by decide : x ≠ z),
    pderiv_X_of_ne (by decide : z ≠ y), pderiv_X_of_ne (by decide : y ≠ z)])
goal: Lean.Macro

full_name: WeierstrassCurve.Jacobian.fin3_def
code: lemma fin3_def (P : Fin 3 → R) : ![P x, P y, P z] = P 
goal: ![P x, P y, P z] = P

full_name: WeierstrassCurve.Jacobian.fin3_def_ext
code: lemma fin3_def_ext (X Y Z : R) : ![X, Y, Z] x = X ∧ ![X, Y, Z] y = Y ∧ ![X, Y, Z] z = Z 
goal: ![X, Y, Z] x = X ∧ ![X, Y, Z] y = Y ∧ ![X, Y, Z] z = Z

full_name: WeierstrassCurve.Jacobian.comp_fin3
code: lemma comp_fin3 {S} (f : R → S) (X Y Z : R) : f ∘ ![X, Y, Z] = ![f X, f Y, f Z] 
goal: f ∘ ![X, Y, Z] = ![f X, f Y, f Z]

full_name: WeierstrassCurve.Jacobian.instSMulPoint
code: /-- The scalar multiplication on a point representative. -/
scoped instance instSMulPoint : SMul R <| Fin 3 → R 
goal: SMul R (Fin 3 → R)

full_name: WeierstrassCurve.Jacobian.smul_fin3
code: lemma smul_fin3 (P : Fin 3 → R) (u : R) : u • P = ![u ^ 2 * P x, u ^ 3 * P y, u * P z] 
goal: u • P = ![u ^ 2 * P x, u ^ 3 * P y, u * P z]

full_name: WeierstrassCurve.Jacobian.smul_fin3_ext
code: lemma smul_fin3_ext (P : Fin 3 → R) (u : R) :
    (u • P) x = u ^ 2 * P x ∧ (u • P) y = u ^ 3 * P y ∧ (u • P) z = u * P z 
goal: (u • P) x = u ^ 2 * P x ∧ (u • P) y = u ^ 3 * P y ∧ (u • P) z = u * P z

full_name: WeierstrassCurve.Jacobian.instMulActionPoint
code: /-- The multiplicative action on a point representative. -/
scoped instance instMulActionPoint : MulAction R <| Fin 3 → R 
goal: MulAction R (Fin 3 → R)

full_name: WeierstrassCurve.Jacobian.instSetoidPoint
code: /-- The equivalence setoid for a point representative. -/
scoped instance instSetoidPoint : Setoid <| Fin 3 → R 
goal: Setoid (Fin 3 → R)

full_name: WeierstrassCurve.Jacobian.PointClass
code: /-- The equivalence class of a point representative. -/
abbrev PointClass : Type u 
goal: Type u

full_name: WeierstrassCurve.Jacobian.smul_equiv
code: lemma smul_equiv (P : Fin 3 → R) {u : R} (hu : IsUnit u) : u • P ≈ P 
goal: u • P ≈ P

full_name: WeierstrassCurve.Jacobian.smul_eq
code: @[simp]
lemma smul_eq (P : Fin 3 → R) {u : R} (hu : IsUnit u) : (⟦u • P⟧ : PointClass R) = ⟦P⟧ 
goal: ⟦u • P⟧ = ⟦P⟧

full_name: WeierstrassCurve.Jacobian.toAffine
code: /-- The coercion to a Weierstrass curve in affine coordinates. -/
abbrev toAffine : Affine R 
goal: WeierstrassCurve.Affine R

full_name: WeierstrassCurve.Jacobian.equiv_iff_eq_of_Z_eq'
code: lemma equiv_iff_eq_of_Z_eq' {P Q : Fin 3 → R} (hz : P z = Q z) (mem : Q z ∈ nonZeroDivisors R) :
    P ≈ Q ↔ P = Q 
goal: P ≈ Q ↔ P = Q

full_name: WeierstrassCurve.Jacobian.equiv_iff_eq_of_Z_eq
code: lemma equiv_iff_eq_of_Z_eq [NoZeroDivisors R] {P Q : Fin 3 → R} (hz : P z = Q z) (hQz : Q z ≠ 0) :
    P ≈ Q ↔ P = Q 
goal: P ≈ Q ↔ P = Q

full_name: WeierstrassCurve.Jacobian.Z_eq_zero_of_equiv
code: lemma Z_eq_zero_of_equiv {P Q : Fin 3 → R} (h : P ≈ Q) : P z = 0 ↔ Q z = 0 
goal: P z = 0 ↔ Q z = 0

full_name: WeierstrassCurve.Jacobian.X_eq_of_equiv
code: lemma X_eq_of_equiv {P Q : Fin 3 → R} (h : P ≈ Q) : P x * Q z ^ 2 = Q x * P z ^ 2 
goal: P x * Q z ^ 2 = Q x * P z ^ 2

full_name: WeierstrassCurve.Jacobian.Y_eq_of_equiv
code: lemma Y_eq_of_equiv {P Q : Fin 3 → R} (h : P ≈ Q) : P y * Q z ^ 3 = Q y * P z ^ 3 
goal: P y * Q z ^ 3 = Q y * P z ^ 3

full_name: WeierstrassCurve.Jacobian.not_equiv_of_Z_eq_zero_left
code: lemma not_equiv_of_Z_eq_zero_left {P Q : Fin 3 → R} (hPz : P z = 0) (hQz : Q z ≠ 0) : ¬P ≈ Q 
goal: ¬P ≈ Q

full_name: WeierstrassCurve.Jacobian.not_equiv_of_Z_eq_zero_right
code: lemma not_equiv_of_Z_eq_zero_right {P Q : Fin 3 → R} (hPz : P z ≠ 0) (hQz : Q z = 0) : ¬P ≈ Q 
goal: ¬P ≈ Q

full_name: WeierstrassCurve.Jacobian.not_equiv_of_X_ne
code: lemma not_equiv_of_X_ne {P Q : Fin 3 → R} (hx : P x * Q z ^ 2 ≠ Q x * P z ^ 2) : ¬P ≈ Q 
goal: ¬P ≈ Q

full_name: WeierstrassCurve.Jacobian.not_equiv_of_Y_ne
code: lemma not_equiv_of_Y_ne {P Q : Fin 3 → R} (hy : P y * Q z ^ 3 ≠ Q y * P z ^ 3) : ¬P ≈ Q 
goal: ¬P ≈ Q

full_name: WeierstrassCurve.Jacobian.equiv_of_X_eq_of_Y_eq
code: lemma equiv_of_X_eq_of_Y_eq {P Q : Fin 3 → F} (hPz : P z ≠ 0) (hQz : Q z ≠ 0)
    (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 = Q y * P z ^ 3) : P ≈ Q 
goal: P ≈ Q

full_name: WeierstrassCurve.Jacobian.equiv_some_of_Z_ne_zero
code: lemma equiv_some_of_Z_ne_zero {P : Fin 3 → F} (hPz : P z ≠ 0) :
    P ≈ ![P x / P z ^ 2, P y / P z ^ 3, 1] 
goal: P ≈ ![P x / P z ^ 2, P y / P z ^ 3, 1]

full_name: WeierstrassCurve.Jacobian.X_eq_iff
code: lemma X_eq_iff {P Q : Fin 3 → F} (hPz : P z ≠ 0) (hQz : Q z ≠ 0) :
    P x * Q z ^ 2 = Q x * P z ^ 2 ↔ P x / P z ^ 2 = Q x / Q z ^ 2 
goal: P x * Q z ^ 2 = Q x * P z ^ 2 ↔ P x / P z ^ 2 = Q x / Q z ^ 2

full_name: WeierstrassCurve.Jacobian.Y_eq_iff
code: lemma Y_eq_iff {P Q : Fin 3 → F} (hPz : P z ≠ 0) (hQz : Q z ≠ 0) :
    P y * Q z ^ 3 = Q y * P z ^ 3 ↔ P y / P z ^ 3 = Q y / Q z ^ 3 
goal: P y * Q z ^ 3 = Q y * P z ^ 3 ↔ P y / P z ^ 3 = Q y / Q z ^ 3

full_name: WeierstrassCurve.Jacobian.polynomial
code: /-- The polynomial $W(X, Y, Z) := Y^2 + a_1XYZ + a_3YZ^3 - (X^3 + a_2X^2Z^2 + a_4XZ^4 + a_6Z^6)$
associated to a Weierstrass curve `W'` over `R`. This is represented as a term of type
`MvPolynomial (Fin 3) R`, where `X 0`, `X 1`, and `X 2` represent $X$, $Y$, and $Z$ respectively. -/
noncomputable def polynomial : MvPolynomial (Fin 3) R 
goal: MvPolynomial (Fin 3) R

full_name: WeierstrassCurve.Jacobian.eval_polynomial
code: lemma eval_polynomial (P : Fin 3 → R) : eval P W'.polynomial =
    P y ^ 2 + W'.a₁ * P x * P y * P z + W'.a₃ * P y * P z ^ 3
      - (P x ^ 3 + W'.a₂ * P x ^ 2 * P z ^ 2 + W'.a₄ * P x * P z ^ 4 + W'.a₆ * P z ^ 6) 
goal: (MvPolynomial.eval P) W'.polynomial =
  P y ^ 2 + W'.a₁ * P x * P y * P z + W'.a₃ * P y * P z ^ 3 -
    (P x ^ 3 + W'.a₂ * P x ^ 2 * P z ^ 2 + W'.a₄ * P x * P z ^ 4 + W'.a₆ * P z ^ 6)

full_name: WeierstrassCurve.Jacobian.eval_polynomial_of_Z_ne_zero
code: lemma eval_polynomial_of_Z_ne_zero {P : Fin 3 → F} (hPz : P z ≠ 0) : eval P W.polynomial / P z ^ 6 =
    W.toAffine.polynomial.evalEval (P x / P z ^ 2) (P y / P z ^ 3) 
goal: (MvPolynomial.eval P) W.polynomial / P z ^ 6 = Polynomial.evalEval (P x / P z ^ 2) (P y / P z ^ 3) W.toAffine.polynomial

full_name: WeierstrassCurve.Jacobian.Equation
code: /-- The proposition that a point representative $(x, y, z)$ lies in `W'`.
In other words, $W(x, y, z) = 0$. -/
def Equation (P : Fin 3 → R) : Prop 
goal: Prop

full_name: WeierstrassCurve.Jacobian.equation_iff
code: lemma equation_iff (P : Fin 3 → R) : W'.Equation P ↔
    P y ^ 2 + W'.a₁ * P x * P y * P z + W'.a₃ * P y * P z ^ 3
      - (P x ^ 3 + W'.a₂ * P x ^ 2 * P z ^ 2 + W'.a₄ * P x * P z ^ 4 + W'.a₆ * P z ^ 6) = 0 
goal: W'.Equation P ↔
  P y ^ 2 + W'.a₁ * P x * P y * P z + W'.a₃ * P y * P z ^ 3 -
      (P x ^ 3 + W'.a₂ * P x ^ 2 * P z ^ 2 + W'.a₄ * P x * P z ^ 4 + W'.a₆ * P z ^ 6) =
    0

full_name: WeierstrassCurve.Jacobian.equation_smul
code: lemma equation_smul (P : Fin 3 → R) {u : R} (hu : IsUnit u) : W'.Equation (u • P) ↔ W'.Equation P 
goal: W'.Equation (u • P) ↔ W'.Equation P

full_name: WeierstrassCurve.Jacobian.equation_of_equiv
code: lemma equation_of_equiv {P Q : Fin 3 → R} (h : P ≈ Q) : W'.Equation P ↔ W'.Equation Q 
goal: W'.Equation P ↔ W'.Equation Q

full_name: WeierstrassCurve.Jacobian.equation_of_Z_eq_zero
code: lemma equation_of_Z_eq_zero {P : Fin 3 → R} (hPz : P z = 0) :
    W'.Equation P ↔ P y ^ 2 = P x ^ 3 
goal: W'.Equation P ↔ P y ^ 2 = P x ^ 3

full_name: WeierstrassCurve.Jacobian.equation_zero
code: lemma equation_zero : W'.Equation ![1, 1, 0] 
goal: W'.Equation ![1, 1, 0]

full_name: WeierstrassCurve.Jacobian.equation_some
code: lemma equation_some (X Y : R) : W'.Equation ![X, Y, 1] ↔ W'.toAffine.Equation X Y 
goal: W'.Equation ![X, Y, 1] ↔ W'.toAffine.Equation X Y

full_name: WeierstrassCurve.Jacobian.equation_of_Z_ne_zero
code: lemma equation_of_Z_ne_zero {P : Fin 3 → F} (hPz : P z ≠ 0) :
    W.Equation P ↔ W.toAffine.Equation (P x / P z ^ 2) (P y / P z ^ 3) 
goal: W.Equation P ↔ W.toAffine.Equation (P x / P z ^ 2) (P y / P z ^ 3)

full_name: WeierstrassCurve.Jacobian.polynomialX
code: /-- The partial derivative $W_X(X, Y, Z)$ of $W(X, Y, Z)$ with respect to $X$. -/
noncomputable def polynomialX : MvPolynomial (Fin 3) R 
goal: MvPolynomial (Fin 3) R

full_name: WeierstrassCurve.Jacobian.polynomialX_eq
code: lemma polynomialX_eq : W'.polynomialX =
    C W'.a₁ * X 1 * X 2 - (C 3 * X 0 ^ 2 + C (2 * W'.a₂) * X 0 * X 2 ^ 2 + C W'.a₄ * X 2 ^ 4) 
goal: W'.polynomialX =
  MvPolynomial.C W'.a₁ * MvPolynomial.X y * MvPolynomial.X z -
    (MvPolynomial.C 3 * MvPolynomial.X x ^ 2 + MvPolynomial.C (2 * W'.a₂) * MvPolynomial.X x * MvPolynomial.X z ^ 2 +
      MvPolynomial.C W'.a₄ * MvPolynomial.X z ^ 4)

full_name: WeierstrassCurve.Jacobian.eval_polynomialX
code: lemma eval_polynomialX (P : Fin 3 → R) : eval P W'.polynomialX =
    W'.a₁ * P y * P z - (3 * P x ^ 2 + 2 * W'.a₂ * P x * P z ^ 2 + W'.a₄ * P z ^ 4) 
goal: (MvPolynomial.eval P) W'.polynomialX = W'.a₁ * P y * P z - (3 * P x ^ 2 + 2 * W'.a₂ * P x * P z ^ 2 + W'.a₄ * P z ^ 4)

full_name: WeierstrassCurve.Jacobian.eval_polynomialX_of_Z_ne_zero
code: lemma eval_polynomialX_of_Z_ne_zero {P : Fin 3 → F} (hPz : P z ≠ 0) :
    eval P W.polynomialX / P z ^ 4 =
      W.toAffine.polynomialX.evalEval (P x / P z ^ 2) (P y / P z ^ 3) 
goal: (MvPolynomial.eval P) W.polynomialX / P z ^ 4 =
  Polynomial.evalEval (P x / P z ^ 2) (P y / P z ^ 3) W.toAffine.polynomialX

full_name: WeierstrassCurve.Jacobian.polynomialY
code: /-- The partial derivative $W_Y(X, Y, Z)$ of $W(X, Y, Z)$ with respect to $Y$. -/
noncomputable def polynomialY : MvPolynomial (Fin 3) R 
goal: MvPolynomial (Fin 3) R

full_name: WeierstrassCurve.Jacobian.polynomialY_eq
code: lemma polynomialY_eq : W'.polynomialY = C 2 * X 1 + C W'.a₁ * X 0 * X 2 + C W'.a₃ * X 2 ^ 3 
goal: W'.polynomialY =
  MvPolynomial.C 2 * MvPolynomial.X y + MvPolynomial.C W'.a₁ * MvPolynomial.X x * MvPolynomial.X z +
    MvPolynomial.C W'.a₃ * MvPolynomial.X z ^ 3

full_name: WeierstrassCurve.Jacobian.eval_polynomialY
code: lemma eval_polynomialY (P : Fin 3 → R) :
    eval P W'.polynomialY = 2 * P y + W'.a₁ * P x * P z + W'.a₃ * P z ^ 3 
goal: (MvPolynomial.eval P) W'.polynomialY = 2 * P y + W'.a₁ * P x * P z + W'.a₃ * P z ^ 3

full_name: WeierstrassCurve.Jacobian.eval_polynomialY_of_Z_ne_zero
code: lemma eval_polynomialY_of_Z_ne_zero {P : Fin 3 → F} (hPz : P z ≠ 0) :
    eval P W.polynomialY / P z ^ 3 =
      W.toAffine.polynomialY.evalEval (P x / P z ^ 2) (P y / P z ^ 3) 
goal: (MvPolynomial.eval P) W.polynomialY / P z ^ 3 =
  Polynomial.evalEval (P x / P z ^ 2) (P y / P z ^ 3) W.toAffine.polynomialY

full_name: WeierstrassCurve.Jacobian.polynomialZ
code: /-- The partial derivative $W_Z(X, Y, Z)$ of $W(X, Y, Z)$ with respect to $Z$. -/
noncomputable def polynomialZ : MvPolynomial (Fin 3) R 
goal: MvPolynomial (Fin 3) R

full_name: WeierstrassCurve.Jacobian.polynomialZ_eq
code: lemma polynomialZ_eq : W'.polynomialZ = C W'.a₁ * X 0 * X 1 + C (3 * W'.a₃) * X 1 * X 2 ^ 2 -
    (C (2 * W'.a₂) * X 0 ^ 2 * X 2 + C (4 * W'.a₄) * X 0 * X 2 ^ 3 + C (6 * W'.a₆) * X 2 ^ 5) 
goal: W'.polynomialZ =
  MvPolynomial.C W'.a₁ * MvPolynomial.X x * MvPolynomial.X y +
      MvPolynomial.C (3 * W'.a₃) * MvPolynomial.X y * MvPolynomial.X z ^ 2 -
    (MvPolynomial.C (2 * W'.a₂) * MvPolynomial.X x ^ 2 * MvPolynomial.X z +
        MvPolynomial.C (4 * W'.a₄) * MvPolynomial.X x * MvPolynomial.X z ^ 3 +
      MvPolynomial.C (6 * W'.a₆) * MvPolynomial.X z ^ 5)

full_name: WeierstrassCurve.Jacobian.eval_polynomialZ
code: lemma eval_polynomialZ (P : Fin 3 → R) : eval P W'.polynomialZ =
    W'.a₁ * P x * P y + 3 * W'.a₃ * P y * P z ^ 2 -
      (2 * W'.a₂ * P x ^ 2 * P z + 4 * W'.a₄ * P x * P z ^ 3 + 6 * W'.a₆ * P z ^ 5) 
goal: (MvPolynomial.eval P) W'.polynomialZ =
  W'.a₁ * P x * P y + 3 * W'.a₃ * P y * P z ^ 2 -
    (2 * W'.a₂ * P x ^ 2 * P z + 4 * W'.a₄ * P x * P z ^ 3 + 6 * W'.a₆ * P z ^ 5)

full_name: WeierstrassCurve.Jacobian.Nonsingular
code: /-- The proposition that a point representative $(x, y, z)$ in `W'` is nonsingular.
In other words, either $W_X(x, y, z) \ne 0$, $W_Y(x, y, z) \ne 0$, or $W_Z(x, y, z) \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 (P : Fin 3 → R) : Prop 
goal: Prop

full_name: WeierstrassCurve.Jacobian.nonsingular_iff
code: lemma nonsingular_iff (P : Fin 3 → R) : W'.Nonsingular P ↔ W'.Equation P ∧
    (W'.a₁ * P y * P z - (3 * P x ^ 2 + 2 * W'.a₂ * P x * P z ^ 2 + W'.a₄ * P z ^ 4) ≠ 0 ∨
      2 * P y + W'.a₁ * P x * P z + W'.a₃ * P z ^ 3 ≠ 0 ∨
      W'.a₁ * P x * P y + 3 * W'.a₃ * P y * P z ^ 2
        - (2 * W'.a₂ * P x ^ 2 * P z + 4 * W'.a₄ * P x * P z ^ 3 + 6 * W'.a₆ * P z ^ 5) ≠ 0) 
goal: W'.Nonsingular P ↔
  W'.Equation P ∧
    (W'.a₁ * P y * P z - (3 * P x ^ 2 + 2 * W'.a₂ * P x * P z ^ 2 + W'.a₄ * P z ^ 4) ≠ 0 ∨
      2 * P y + W'.a₁ * P x * P z + W'.a₃ * P z ^ 3 ≠ 0 ∨
        W'.a₁ * P x * P y + 3 * W'.a₃ * P y * P z ^ 2 -
            (2 * W'.a₂ * P x ^ 2 * P z + 4 * W'.a₄ * P x * P z ^ 3 + 6 * W'.a₆ * P z ^ 5) ≠
          0)

full_name: WeierstrassCurve.Jacobian.nonsingular_smul
code: lemma nonsingular_smul (P : Fin 3 → R) {u : R} (hu : IsUnit u) :
    W'.Nonsingular (u • P) ↔ W'.Nonsingular P 
goal: W'.Nonsingular (u • P) ↔ W'.Nonsingular P

full_name: WeierstrassCurve.Jacobian.nonsingular_of_equiv
code: lemma nonsingular_of_equiv {P Q : Fin 3 → R} (h : P ≈ Q) : W'.Nonsingular P ↔ W'.Nonsingular Q 
goal: W'.Nonsingular P ↔ W'.Nonsingular Q

full_name: WeierstrassCurve.Jacobian.nonsingular_of_Z_eq_zero
code: lemma nonsingular_of_Z_eq_zero {P : Fin 3 → R} (hPz : P z = 0) :
    W'.Nonsingular P ↔ W'.Equation P ∧ (3 * P x ^ 2 ≠ 0 ∨ 2 * P y ≠ 0 ∨ W'.a₁ * P x * P y ≠ 0) 
goal: W'.Nonsingular P ↔ W'.Equation P ∧ (3 * P x ^ 2 ≠ 0 ∨ 2 * P y ≠ 0 ∨ W'.a₁ * P x * P y ≠ 0)

full_name: WeierstrassCurve.Jacobian.nonsingular_zero
code: lemma nonsingular_zero [Nontrivial R] : W'.Nonsingular ![1, 1, 0] 
goal: W'.Nonsingular ![1, 1, 0]

full_name: WeierstrassCurve.Jacobian.nonsingular_some
code: lemma nonsingular_some (X Y : R) : W'.Nonsingular ![X, Y, 1] ↔ W'.toAffine.Nonsingular X Y 
goal: W'.Nonsingular ![X, Y, 1] ↔ W'.toAffine.Nonsingular X Y

full_name: WeierstrassCurve.Jacobian.nonsingular_of_Z_ne_zero
code: lemma nonsingular_of_Z_ne_zero {P : Fin 3 → F} (hPz : P z ≠ 0) :
    W.Nonsingular P ↔ W.toAffine.Nonsingular (P x / P z ^ 2) (P y / P z ^ 3) 
goal: W.Nonsingular P ↔ W.toAffine.Nonsingular (P x / P z ^ 2) (P y / P z ^ 3)

full_name: WeierstrassCurve.Jacobian.nonsingular_iff_of_Z_ne_zero
code: lemma nonsingular_iff_of_Z_ne_zero {P : Fin 3 → F} (hPz : P z ≠ 0) :
    W.Nonsingular P ↔ W.Equation P ∧ (eval P W.polynomialX ≠ 0 ∨ eval P W.polynomialY ≠ 0) 
goal: W.Nonsingular P ↔ W.Equation P ∧ ((MvPolynomial.eval P) W.polynomialX ≠ 0 ∨ (MvPolynomial.eval P) W.polynomialY ≠ 0)

full_name: WeierstrassCurve.Jacobian.X_ne_zero_of_Z_eq_zero
code: lemma X_ne_zero_of_Z_eq_zero [NoZeroDivisors R] {P : Fin 3 → R} (hP : W'.Nonsingular P)
    (hPz : P z = 0) : P x ≠ 0 
goal: P x ≠ 0

full_name: WeierstrassCurve.Jacobian.isUnit_X_of_Z_eq_zero
code: lemma isUnit_X_of_Z_eq_zero {P : Fin 3 → F} (hP : W.Nonsingular P) (hPz : P z = 0) : IsUnit (P x) 
goal: IsUnit (P x)

full_name: WeierstrassCurve.Jacobian.Y_ne_zero_of_Z_eq_zero
code: lemma Y_ne_zero_of_Z_eq_zero [NoZeroDivisors R] {P : Fin 3 → R} (hP : W'.Nonsingular P)
    (hPz : P z = 0) : P y ≠ 0 
goal: P y ≠ 0

full_name: WeierstrassCurve.Jacobian.isUnit_Y_of_Z_eq_zero
code: lemma isUnit_Y_of_Z_eq_zero {P : Fin 3 → F} (hP : W.Nonsingular P) (hPz : P z = 0) : IsUnit (P y) 
goal: IsUnit (P y)

full_name: WeierstrassCurve.Jacobian.equiv_of_Z_eq_zero
code: lemma equiv_of_Z_eq_zero {P Q : Fin 3 → F} (hP : W.Nonsingular P) (hQ : W.Nonsingular Q)
    (hPz : P z = 0) (hQz : Q z = 0) : P ≈ Q 
goal: P ≈ Q

full_name: WeierstrassCurve.Jacobian.equiv_zero_of_Z_eq_zero
code: lemma equiv_zero_of_Z_eq_zero {P : Fin 3 → F} (hP : W.Nonsingular P) (hPz : P z = 0) :
    P ≈ ![1, 1, 0] 
goal: P ≈ ![1, 1, 0]

full_name: WeierstrassCurve.Jacobian.NonsingularLift
code: /-- The proposition that a point class on `W'` is nonsingular. If `P` is a point representative,
then `W'.NonsingularLift ⟦P⟧` is definitionally equivalent to `W'.Nonsingular P`. -/
def NonsingularLift (P : PointClass R) : Prop 
goal: Prop

full_name: WeierstrassCurve.Jacobian.nonsingularLift_iff
code: lemma nonsingularLift_iff (P : Fin 3 → R) : W'.NonsingularLift ⟦P⟧ ↔ W'.Nonsingular P 
goal: W'.NonsingularLift ⟦P⟧ ↔ W'.Nonsingular P

full_name: WeierstrassCurve.Jacobian.nonsingularLift_zero
code: lemma nonsingularLift_zero [Nontrivial R] : W'.NonsingularLift ⟦![1, 1, 0]⟧ 
goal: W'.NonsingularLift ⟦![1, 1, 0]⟧

full_name: WeierstrassCurve.Jacobian.nonsingularLift_some
code: lemma nonsingularLift_some (X Y : R) :
    W'.NonsingularLift ⟦![X, Y, 1]⟧ ↔ W'.toAffine.Nonsingular X Y 
goal: W'.NonsingularLift ⟦![X, Y, 1]⟧ ↔ W'.toAffine.Nonsingular X Y

full_name: WeierstrassCurve.Jacobian.negY
code: /-- The $Y$-coordinate of the negation of a point representative. -/
def negY (P : Fin 3 → R) : R 
goal: R

full_name: WeierstrassCurve.Jacobian.negY_smul
code: lemma negY_smul (P : Fin 3 → R) {u : R} : W'.negY (u • P) = u ^ 3 * W'.negY P 
goal: W'.negY (u • P) = u ^ 3 * W'.negY P

full_name: WeierstrassCurve.Jacobian.negY_of_Z_eq_zero
code: lemma negY_of_Z_eq_zero {P : Fin 3 → R} (hPz : P z = 0) : W'.negY P = -P y 
goal: W'.negY P = -P y

full_name: WeierstrassCurve.Jacobian.negY_of_Z_ne_zero
code: lemma negY_of_Z_ne_zero {P : Fin 3 → F} (hPz : P z ≠ 0) :
    W.negY P / P z ^ 3 = W.toAffine.negY (P x / P z ^ 2) (P y / P z ^ 3) 
goal: W.negY P / P z ^ 3 = W.toAffine.negY (P x / P z ^ 2) (P y / P z ^ 3)

full_name: WeierstrassCurve.Jacobian.Y_sub_Y_mul_Y_sub_negY
code: lemma Y_sub_Y_mul_Y_sub_negY {P Q : Fin 3 → R} (hP : W'.Equation P) (hQ : W'.Equation Q)
    (hx : P x * Q z ^ 2 = Q x * P z ^ 2) :
    (P y * Q z ^ 3 - Q y * P z ^ 3) * (P y * Q z ^ 3 - W'.negY Q * P z ^ 3) = 0 
goal: (P y * Q z ^ 3 - Q y * P z ^ 3) * (P y * Q z ^ 3 - W'.negY Q * P z ^ 3) = 0

full_name: WeierstrassCurve.Jacobian.Y_eq_of_Y_ne
code: lemma Y_eq_of_Y_ne {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q)
    (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 ≠ Q y * P z ^ 3) :
    P y * Q z ^ 3 = W.negY Q * P z ^ 3 
goal: P y * Q z ^ 3 = W.negY Q * P z ^ 3

full_name: WeierstrassCurve.Jacobian.Y_eq_of_Y_ne'
code: lemma Y_eq_of_Y_ne' {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q)
    (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 ≠ W.negY Q * P z ^ 3) :
    P y * Q z ^ 3 = Q y * P z ^ 3 
goal: P y * Q z ^ 3 = Q y * P z ^ 3

full_name: WeierstrassCurve.Jacobian.Y_eq_iff'
code: lemma Y_eq_iff' {P Q : Fin 3 → F} (hPz : P z ≠ 0) (hQz : Q z ≠ 0) :
    P y * Q z ^ 3 = W.negY Q * P z ^ 3 ↔
      P y / P z ^ 3 = W.toAffine.negY (Q x / Q z ^ 2) (Q y / Q z ^ 3) 
goal: P y * Q z ^ 3 = W.negY Q * P z ^ 3 ↔ P y / P z ^ 3 = W.toAffine.negY (Q x / Q z ^ 2) (Q y / Q z ^ 3)

full_name: WeierstrassCurve.Jacobian.Y_sub_Y_add_Y_sub_negY
code: lemma Y_sub_Y_add_Y_sub_negY (P Q : Fin 3 → R) (hx : P x * Q z ^ 2 = Q x * P z ^ 2) :
    (P y * Q z ^ 3 - Q y * P z ^ 3) + (P y * Q z ^ 3 - W'.negY Q * P z ^ 3) =
      (P y - W'.negY P) * Q z ^ 3 
goal: P y * Q z ^ 3 - Q y * P z ^ 3 + (P y * Q z ^ 3 - W'.negY Q * P z ^ 3) = (P y - W'.negY P) * Q z ^ 3

full_name: WeierstrassCurve.Jacobian.Y_ne_negY_of_Y_ne
code: lemma Y_ne_negY_of_Y_ne [NoZeroDivisors R] {P Q : Fin 3 → R} (hP : W'.Equation P)
    (hQ : W'.Equation Q) (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 ≠ Q y * P z ^ 3) :
    P y ≠ W'.negY P 
goal: P y ≠ W'.negY P

full_name: WeierstrassCurve.Jacobian.Y_ne_negY_of_Y_ne'
code: lemma Y_ne_negY_of_Y_ne' [NoZeroDivisors R] {P Q : Fin 3 → R} (hP : W'.Equation P)
    (hQ : W'.Equation Q) (hx : P x * Q z ^ 2 = Q x * P z ^ 2)
    (hy : P y * Q z ^ 3 ≠ W'.negY Q * P z ^ 3) : P y ≠ W'.negY P 
goal: P y ≠ W'.negY P

full_name: WeierstrassCurve.Jacobian.Y_eq_negY_of_Y_eq
code: lemma Y_eq_negY_of_Y_eq [NoZeroDivisors R] {P Q : Fin 3 → R} (hQz : Q z ≠ 0)
    (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 = Q y * P z ^ 3)
    (hy' : P y * Q z ^ 3 = W'.negY Q * P z ^ 3) : P y = W'.negY P 
goal: P y = W'.negY P

full_name: WeierstrassCurve.Jacobian.nonsingular_iff_of_Y_eq_negY
code: lemma nonsingular_iff_of_Y_eq_negY {P : Fin 3 → F} (hPz : P z ≠ 0) (hy : P y = W.negY P) :
    W.Nonsingular P ↔ W.Equation P ∧ eval P W.polynomialX ≠ 0 
goal: W.Nonsingular P ↔ W.Equation P ∧ (MvPolynomial.eval P) W.polynomialX ≠ 0

full_name: WeierstrassCurve.Jacobian.dblU
code: /-- The unit associated to the doubling of a 2-torsion point.
More specifically, the unit `u` such that `W.add P P = u • ![1, 1, 0]` where `P = W.neg P`. -/
noncomputable def dblU (P : Fin 3 → R) : R 
goal: R

full_name: WeierstrassCurve.Jacobian.dblU_eq
code: lemma dblU_eq (P : Fin 3 → R) : W'.dblU P =
    W'.a₁ * P y * P z - (3 * P x ^ 2 + 2 * W'.a₂ * P x * P z ^ 2 + W'.a₄ * P z ^ 4) 
goal: W'.dblU P = W'.a₁ * P y * P z - (3 * P x ^ 2 + 2 * W'.a₂ * P x * P z ^ 2 + W'.a₄ * P z ^ 4)

full_name: WeierstrassCurve.Jacobian.dblU_smul
code: lemma dblU_smul (P : Fin 3 → R) (u : R) : W'.dblU (u • P) = u ^ 4 * W'.dblU P 
goal: W'.dblU (u • P) = u ^ 4 * W'.dblU P

full_name: WeierstrassCurve.Jacobian.dblU_of_Z_eq_zero
code: lemma dblU_of_Z_eq_zero {P : Fin 3 → R} (hPz : P z = 0) : W'.dblU P = -3 * P x ^ 2 
goal: W'.dblU P = -3 * P x ^ 2

full_name: WeierstrassCurve.Jacobian.dblU_ne_zero_of_Y_eq
code: lemma dblU_ne_zero_of_Y_eq {P Q : Fin 3 → F} (hP : W.Nonsingular P) (hPz : P z ≠ 0) (hQz : Q z ≠ 0)
    (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 = Q y * P z ^ 3)
    (hy' : P y * Q z ^ 3 = W.negY Q * P z ^ 3) : W.dblU P ≠ 0 
goal: W.dblU P ≠ 0

full_name: WeierstrassCurve.Jacobian.isUnit_dblU_of_Y_eq
code: lemma isUnit_dblU_of_Y_eq {P Q : Fin 3 → F} (hP : W.Nonsingular P) (hPz : P z ≠ 0) (hQz : Q z ≠ 0)
    (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 = Q y * P z ^ 3)
    (hy' : P y * Q z ^ 3 = W.negY Q * P z ^ 3) : IsUnit (W.dblU P) 
goal: IsUnit (W.dblU P)

full_name: WeierstrassCurve.Jacobian.dblZ
code: /-- The $Z$-coordinate of the doubling of a point representative. -/
def dblZ (P : Fin 3 → R) : R 
goal: R

full_name: WeierstrassCurve.Jacobian.dblZ_smul
code: lemma dblZ_smul (P : Fin 3 → R) (u : R) : W'.dblZ (u • P) = u ^ 4 * W'.dblZ P 
goal: W'.dblZ (u • P) = u ^ 4 * W'.dblZ P

full_name: WeierstrassCurve.Jacobian.dblZ_of_Z_eq_zero
code: lemma dblZ_of_Z_eq_zero {P : Fin 3 → R} (hPz : P z = 0) : W'.dblZ P = 0 
goal: W'.dblZ P = 0

full_name: WeierstrassCurve.Jacobian.dblZ_of_Y_eq
code: lemma dblZ_of_Y_eq [NoZeroDivisors R] {P Q : Fin 3 → R} (hQz : Q z ≠ 0)
    (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 = Q y * P z ^ 3)
    (hy' : P y * Q z ^ 3 = W'.negY Q * P z ^ 3) : W'.dblZ P = 0 
goal: W'.dblZ P = 0

full_name: WeierstrassCurve.Jacobian.dblZ_ne_zero_of_Y_ne
code: lemma dblZ_ne_zero_of_Y_ne [NoZeroDivisors R] {P Q : Fin 3 → R} (hP : W'.Equation P)
    (hQ : W'.Equation Q) (hPz : P z ≠ 0) (hx : P x * Q z ^ 2 = Q x * P z ^ 2)
    (hy : P y * Q z ^ 3 ≠ Q y * P z ^ 3) : W'.dblZ P ≠ 0 
goal: W'.dblZ P ≠ 0

full_name: WeierstrassCurve.Jacobian.isUnit_dblZ_of_Y_ne
code: lemma isUnit_dblZ_of_Y_ne {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 ≠ Q y * P z ^ 3) : IsUnit (W.dblZ P) 
goal: IsUnit (W.dblZ P)

full_name: WeierstrassCurve.Jacobian.dblZ_ne_zero_of_Y_ne'
code: lemma dblZ_ne_zero_of_Y_ne' [NoZeroDivisors R] {P Q : Fin 3 → R} (hP : W'.Equation P)
    (hQ : W'.Equation Q) (hPz : P z ≠ 0) (hx : P x * Q z ^ 2 = Q x * P z ^ 2)
    (hy : P y * Q z ^ 3 ≠ W'.negY Q * P z ^ 3) : W'.dblZ P ≠ 0 
goal: W'.dblZ P ≠ 0

full_name: WeierstrassCurve.Jacobian.isUnit_dblZ_of_Y_ne'
code: lemma isUnit_dblZ_of_Y_ne' {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 ≠ W.negY Q * P z ^ 3) :
    IsUnit (W.dblZ P) 
goal: IsUnit (W.dblZ P)

full_name: _private.Mathlib.AlgebraicGeometry.EllipticCurve.Jacobian.0.WeierstrassCurve.Jacobian.toAffine_slope_of_eq
code: private lemma toAffine_slope_of_eq {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q)
    (hPz : P z ≠ 0) (hQz : Q z ≠ 0) (hx : P x * Q z ^ 2 = Q x * P z ^ 2)
    (hy : P y * Q z ^ 3 ≠ W.negY Q * P z ^ 3) :
    W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3) =
      -W.dblU P / W.dblZ P 
goal: W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3) = -W.dblU P / W.dblZ P

full_name: WeierstrassCurve.Jacobian.dblX
code: /-- The $X$-coordinate of the doubling of a point representative. -/
noncomputable def dblX (P : Fin 3 → R) : R 
goal: R

full_name: WeierstrassCurve.Jacobian.dblX_smul
code: lemma dblX_smul (P : Fin 3 → R) (u : R) : W'.dblX (u • P) = (u ^ 4) ^ 2 * W'.dblX P 
goal: W'.dblX (u • P) = (u ^ 4) ^ 2 * W'.dblX P

full_name: WeierstrassCurve.Jacobian.dblX_of_Z_eq_zero
code: lemma dblX_of_Z_eq_zero {P : Fin 3 → R} (hP : W'.Equation P) (hPz : P z = 0) :
    W'.dblX P = (P x ^ 2) ^ 2 
goal: W'.dblX P = (P x ^ 2) ^ 2

full_name: WeierstrassCurve.Jacobian.dblX_of_Y_eq
code: lemma dblX_of_Y_eq [NoZeroDivisors R] {P Q : Fin 3 → R} (hQz : Q z ≠ 0)
    (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 = Q y * P z ^ 3)
    (hy' : P y * Q z ^ 3 = W'.negY Q * P z ^ 3) : W'.dblX P = W'.dblU P ^ 2 
goal: W'.dblX P = W'.dblU P ^ 2

full_name: _private.Mathlib.AlgebraicGeometry.EllipticCurve.Jacobian.0.WeierstrassCurve.Jacobian.toAffine_addX_of_eq
code: private lemma toAffine_addX_of_eq {P : Fin 3 → F} {n d : F} (hPz : P z ≠ 0) (hd : d ≠ 0) :
    W.toAffine.addX (P x / P z ^ 2) (P x / P z ^ 2) (-n / (P z * d)) =
      (n ^ 2 - W.a₁ * n * P z * d - W.a₂ * P z ^ 2 * d ^ 2 - 2 * P x * d ^ 2) / (P z * d) ^ 2 
goal: W.toAffine.addX (P x / P z ^ 2) (P x / P z ^ 2) (-n / (P z * d)) =
  (n ^ 2 - W.a₁ * n * P z * d - W.a₂ * P z ^ 2 * d ^ 2 - 2 * P x * d ^ 2) / (P z * d) ^ 2

full_name: WeierstrassCurve.Jacobian.dblX_of_Z_ne_zero
code: lemma dblX_of_Z_ne_zero {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hQz : Q z ≠ 0) (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 ≠ W.negY Q * P z ^ 3) :
    W.dblX P / W.dblZ P ^ 2 = W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2)
      (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)) 
goal: W.dblX P / W.dblZ P ^ 2 =
  W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2)
    (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3))

full_name: WeierstrassCurve.Jacobian.negDblY
code: /-- The $Y$-coordinate of the negated doubling of a point representative. -/
noncomputable def negDblY (P : Fin 3 → R) : R 
goal: R

full_name: WeierstrassCurve.Jacobian.negDblY_smul
code: lemma negDblY_smul (P : Fin 3 → R) (u : R) : W'.negDblY (u • P) = (u ^ 4) ^ 3 * W'.negDblY P 
goal: W'.negDblY (u • P) = (u ^ 4) ^ 3 * W'.negDblY P

full_name: WeierstrassCurve.Jacobian.negDblY_of_Z_eq_zero
code: lemma negDblY_of_Z_eq_zero {P : Fin 3 → R} (hP : W'.Equation P) (hPz : P z = 0) :
    W'.negDblY P = -(P x ^ 2) ^ 3 
goal: W'.negDblY P = -(P x ^ 2) ^ 3

full_name: WeierstrassCurve.Jacobian.negDblY_of_Y_eq
code: lemma negDblY_of_Y_eq [NoZeroDivisors R] {P Q : Fin 3 → R} (hQz : Q z ≠ 0)
    (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 = Q y * P z ^ 3)
    (hy' : P y * Q z ^ 3 = W'.negY Q * P z ^ 3) : W'.negDblY P = (-W'.dblU P) ^ 3 
goal: W'.negDblY P = (-W'.dblU P) ^ 3

full_name: _private.Mathlib.AlgebraicGeometry.EllipticCurve.Jacobian.0.WeierstrassCurve.Jacobian.toAffine_negAddY_of_eq
code: private lemma toAffine_negAddY_of_eq {P : Fin 3 → F} {n d : F} (hPz : P z ≠ 0) (hd : d ≠ 0) :
    W.toAffine.negAddY (P x / P z ^ 2) (P x / P z ^ 2) (P y / P z ^ 3) (-n / (P z * d)) =
      (-n * (n ^ 2 - W.a₁ * n * P z * d - W.a₂ * P z ^ 2 * d ^ 2 - 2 * P x * d ^ 2 - P x * d ^ 2)
        + P y * d ^ 3) / (P z * d) ^ 3 
goal: W.toAffine.negAddY (P x / P z ^ 2) (P x / P z ^ 2) (P y / P z ^ 3) (-n / (P z * d)) =
  (-n * (n ^ 2 - W.a₁ * n * P z * d - W.a₂ * P z ^ 2 * d ^ 2 - 2 * P x * d ^ 2 - P x * d ^ 2) + P y * d ^ 3) /
    (P z * d) ^ 3

full_name: WeierstrassCurve.Jacobian.negDblY_of_Z_ne_zero
code: lemma negDblY_of_Z_ne_zero {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q)
    (hPz : P z ≠ 0) (hQz : Q z ≠ 0) (hx : P x * Q z ^ 2 = Q x * P z ^ 2)
    (hy : P y * Q z ^ 3 ≠ W.negY Q * P z ^ 3) : W.negDblY P / W.dblZ P ^ 3 =
    W.toAffine.negAddY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
      (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)) 
goal: W.negDblY P / W.dblZ P ^ 3 =
  W.toAffine.negAddY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
    (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3))

full_name: WeierstrassCurve.Jacobian.dblY
code: /-- The $Y$-coordinate of the doubling of a point representative. -/
noncomputable def dblY (P : Fin 3 → R) : R 
goal: R

full_name: WeierstrassCurve.Jacobian.dblY_smul
code: lemma dblY_smul (P : Fin 3 → R) (u : R) : W'.dblY (u • P) = (u ^ 4) ^ 3 * W'.dblY P 
goal: W'.dblY (u • P) = (u ^ 4) ^ 3 * W'.dblY P

full_name: WeierstrassCurve.Jacobian.dblY_of_Z_eq_zero
code: lemma dblY_of_Z_eq_zero {P : Fin 3 → R} (hP : W'.Equation P) (hPz : P z = 0) :
    W'.dblY P = (P x ^ 2) ^ 3 
goal: W'.dblY P = (P x ^ 2) ^ 3

full_name: WeierstrassCurve.Jacobian.dblY_of_Y_eq
code: lemma dblY_of_Y_eq [NoZeroDivisors R] {P Q : Fin 3 → R} (hQz : Q z ≠ 0)
    (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 = Q y * P z ^ 3)
    (hy' : P y * Q z ^ 3 = W'.negY Q * P z ^ 3) : W'.dblY P = W'.dblU P ^ 3 
goal: W'.dblY P = W'.dblU P ^ 3

full_name: WeierstrassCurve.Jacobian.dblY_of_Z_ne_zero
code: lemma dblY_of_Z_ne_zero {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hQz : Q z ≠ 0) (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 ≠ W.negY Q * P z ^ 3) :
    W.dblY P / W.dblZ P ^ 3 = W.toAffine.addY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
      (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)) 
goal: W.dblY P / W.dblZ P ^ 3 =
  W.toAffine.addY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
    (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3))

full_name: WeierstrassCurve.Jacobian.dblXYZ
code: /-- The coordinates of the doubling of a point representative. -/
noncomputable def dblXYZ (P : Fin 3 → R) : Fin 3 → R 
goal: Fin 3 → R

full_name: WeierstrassCurve.Jacobian.dblXYZ_smul
code: lemma dblXYZ_smul (P : Fin 3 → R) (u : R) : W'.dblXYZ (u • P) = (u ^ 4) • W'.dblXYZ P 
goal: W'.dblXYZ (u • P) = u ^ 4 • W'.dblXYZ P

full_name: WeierstrassCurve.Jacobian.dblXYZ_of_Z_eq_zero
code: lemma dblXYZ_of_Z_eq_zero {P : Fin 3 → R} (hP : W'.Equation P) (hPz : P z = 0) :
    W'.dblXYZ P = P x ^ 2 • ![1, 1, 0] 
goal: W'.dblXYZ P = P x ^ 2 • ![1, 1, 0]

full_name: WeierstrassCurve.Jacobian.dblXYZ_of_Y_eq'
code: lemma dblXYZ_of_Y_eq' [NoZeroDivisors R] {P Q : Fin 3 → R} (hQz : Q z ≠ 0)
    (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 = Q y * P z ^ 3)
    (hy' : P y * Q z ^ 3 = W'.negY Q * P z ^ 3) :
    W'.dblXYZ P = ![W'.dblU P ^ 2, W'.dblU P ^ 3, 0] 
goal: W'.dblXYZ P = ![W'.dblU P ^ 2, W'.dblU P ^ 3, 0]

full_name: WeierstrassCurve.Jacobian.dblXYZ_of_Y_eq
code: lemma dblXYZ_of_Y_eq {P Q : Fin 3 → F} (hQz : Q z ≠ 0) (hx : P x * Q z ^ 2 = Q x * P z ^ 2)
    (hy : P y * Q z ^ 3 = Q y * P z ^ 3) (hy' : P y * Q z ^ 3 = W.negY Q * P z ^ 3) :
    W.dblXYZ P = W.dblU P • ![1, 1, 0] 
goal: W.dblXYZ P = W.dblU P • ![1, 1, 0]

full_name: WeierstrassCurve.Jacobian.dblXYZ_of_Z_ne_zero
code: lemma dblXYZ_of_Z_ne_zero {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hQz : Q z ≠ 0) (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 ≠ W.negY Q * P z ^ 3) :
    W.dblXYZ P = W.dblZ P •
      ![W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2)
          (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
        W.toAffine.addY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
          (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
        1] 
goal: W.dblXYZ P =
  W.dblZ P •
    ![W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2)
        (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
      W.toAffine.addY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
        (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
      1]

full_name: WeierstrassCurve.Jacobian.addU
code: /-- The unit associated to the addition of a non-2-torsion point with its negation.
More specifically, the unit `u` such that `W.add P Q = u • ![1, 1, 0]` where
`P x / P z ^ 2 = Q x / Q z ^ 2` but `P ≠ W.neg P`. -/
def addU (P Q : Fin 3 → F) : F 
goal: F

full_name: WeierstrassCurve.Jacobian.addU_smul
code: lemma addU_smul {P Q : Fin 3 → F} (hPz : P z ≠ 0) (hQz : Q z ≠ 0) {u v : F} (hu : u ≠ 0)
    (hv : v ≠ 0) : addU (u • P) (v • Q) = (u * v) ^ 2 * addU P Q 
goal: WeierstrassCurve.Jacobian.addU (u • P) (v • Q) = (u * v) ^ 2 * WeierstrassCurve.Jacobian.addU P Q

full_name: WeierstrassCurve.Jacobian.addU_of_Z_eq_zero_left
code: lemma addU_of_Z_eq_zero_left {P Q : Fin 3 → F} (hPz : P z = 0) : addU P Q = 0 
goal: WeierstrassCurve.Jacobian.addU P Q = 0

full_name: WeierstrassCurve.Jacobian.addU_of_Z_eq_zero_right
code: lemma addU_of_Z_eq_zero_right {P Q : Fin 3 → F} (hQz : Q z = 0) : addU P Q = 0 
goal: WeierstrassCurve.Jacobian.addU P Q = 0

full_name: WeierstrassCurve.Jacobian.addU_ne_zero_of_Y_ne
code: lemma addU_ne_zero_of_Y_ne {P Q : Fin 3 → F} (hPz : P z ≠ 0) (hQz : Q z ≠ 0)
    (hy : P y * Q z ^ 3 ≠ Q y * P z ^ 3) : addU P Q ≠ 0 
goal: WeierstrassCurve.Jacobian.addU P Q ≠ 0

full_name: WeierstrassCurve.Jacobian.isUnit_addU_of_Y_ne
code: lemma isUnit_addU_of_Y_ne {P Q : Fin 3 → F} (hPz : P z ≠ 0) (hQz : Q z ≠ 0)
    (hy : P y * Q z ^ 3 ≠ Q y * P z ^ 3) : IsUnit (addU P Q) 
goal: IsUnit (WeierstrassCurve.Jacobian.addU P Q)

full_name: WeierstrassCurve.Jacobian.addZ
code: /-- The $Z$-coordinate of the addition of two distinct point representatives. -/
def addZ (P Q : Fin 3 → R) : R 
goal: R

full_name: WeierstrassCurve.Jacobian.addZ_self
code: lemma addZ_self {P : Fin 3 → R} : addZ P P = 0 
goal: WeierstrassCurve.Jacobian.addZ P P = 0

full_name: WeierstrassCurve.Jacobian.addZ_smul
code: lemma addZ_smul (P Q : Fin 3 → R) (u v : R) : addZ (u • P) (v • Q) = (u * v) ^ 2 * addZ P Q 
goal: WeierstrassCurve.Jacobian.addZ (u • P) (v • Q) = (u * v) ^ 2 * WeierstrassCurve.Jacobian.addZ P Q

full_name: WeierstrassCurve.Jacobian.addZ_of_Z_eq_zero_left
code: lemma addZ_of_Z_eq_zero_left {P Q : Fin 3 → R} (hPz : P z = 0) : addZ P Q = P x * Q z * Q z 
goal: WeierstrassCurve.Jacobian.addZ P Q = P x * Q z * Q z

full_name: WeierstrassCurve.Jacobian.addZ_of_Z_eq_zero_right
code: lemma addZ_of_Z_eq_zero_right {P Q : Fin 3 → R} (hQz : Q z = 0) :
    addZ P Q = -(Q x * P z) * P z 
goal: WeierstrassCurve.Jacobian.addZ P Q = -(Q x * P z) * P z

full_name: WeierstrassCurve.Jacobian.addZ_of_X_eq
code: lemma addZ_of_X_eq {P Q : Fin 3 → R} (hx : P x * Q z ^ 2 = Q x * P z ^ 2) : addZ P Q = 0 
goal: WeierstrassCurve.Jacobian.addZ P Q = 0

full_name: WeierstrassCurve.Jacobian.addZ_ne_zero_of_X_ne
code: lemma addZ_ne_zero_of_X_ne {P Q : Fin 3 → R} (hx : P x * Q z ^ 2 ≠ Q x * P z ^ 2) : addZ P Q ≠ 0 
goal: WeierstrassCurve.Jacobian.addZ P Q ≠ 0

full_name: WeierstrassCurve.Jacobian.isUnit_addZ_of_X_ne
code: lemma isUnit_addZ_of_X_ne {P Q : Fin 3 → F} (hx : P x * Q z ^ 2 ≠ Q x * P z ^ 2) :
    IsUnit <| addZ P Q 
goal: IsUnit (WeierstrassCurve.Jacobian.addZ P Q)

full_name: _private.Mathlib.AlgebraicGeometry.EllipticCurve.Jacobian.0.WeierstrassCurve.Jacobian.toAffine_slope_of_ne
code: private lemma toAffine_slope_of_ne {P Q : Fin 3 → F} (hPz : P z ≠ 0) (hQz : Q z ≠ 0)
    (hx : P x * Q z ^ 2 ≠ Q x * P z ^ 2) :
    W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3) =
      (P y * Q z ^ 3 - Q y * P z ^ 3) / (P z * Q z * addZ P Q) 
goal: W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3) =
  (P y * Q z ^ 3 - Q y * P z ^ 3) / (P z * Q z * WeierstrassCurve.Jacobian.addZ P Q)

full_name: WeierstrassCurve.Jacobian.addX
code: /-- The $X$-coordinate of the addition of two distinct point representatives. -/
def addX (P Q : Fin 3 → R) : R 
goal: R

full_name: WeierstrassCurve.Jacobian.addX_self
code: lemma addX_self {P : Fin 3 → R} (hP : W'.Equation P) : W'.addX P P = 0 
goal: W'.addX P P = 0

full_name: WeierstrassCurve.Jacobian.addX_eq'
code: lemma addX_eq' {P Q : Fin 3 → R} (hP : W'.Equation P) (hQ : W'.Equation Q) :
    W'.addX P Q * (P z * Q z) ^ 2 =
      (P y * Q z ^ 3 - Q y * P z ^ 3) ^ 2
        + W'.a₁ * (P y * Q z ^ 3 - Q y * P z ^ 3) * P z * Q z * addZ P Q
        - W'.a₂ * P z ^ 2 * Q z ^ 2 * addZ P Q ^ 2 - P x * Q z ^ 2 * addZ P Q ^ 2
        - Q x * P z ^ 2 * addZ P Q ^ 2 
goal: W'.addX P Q * (P z * Q z) ^ 2 =
  (P y * Q z ^ 3 - Q y * P z ^ 3) ^ 2 +
          W'.a₁ * (P y * Q z ^ 3 - Q y * P z ^ 3) * P z * Q z * WeierstrassCurve.Jacobian.addZ P Q -
        W'.a₂ * P z ^ 2 * Q z ^ 2 * WeierstrassCurve.Jacobian.addZ P Q ^ 2 -
      P x * Q z ^ 2 * WeierstrassCurve.Jacobian.addZ P Q ^ 2 -
    Q x * P z ^ 2 * WeierstrassCurve.Jacobian.addZ P Q ^ 2

full_name: WeierstrassCurve.Jacobian.addX_eq
code: lemma addX_eq {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hQz : Q z ≠ 0) : W.addX P Q =
      ((P y * Q z ^ 3 - Q y * P z ^ 3) ^ 2
        + W.a₁ * (P y * Q z ^ 3 - Q y * P z ^ 3) * P z * Q z * addZ P Q
        - W.a₂ * P z ^ 2 * Q z ^ 2 * addZ P Q ^ 2 - P x * Q z ^ 2 * addZ P Q ^ 2
        - Q x * P z ^ 2 * addZ P Q ^ 2) / (P z * Q z) ^ 2 
goal: W.addX P Q =
  ((P y * Q z ^ 3 - Q y * P z ^ 3) ^ 2 +
            W.a₁ * (P y * Q z ^ 3 - Q y * P z ^ 3) * P z * Q z * WeierstrassCurve.Jacobian.addZ P Q -
          W.a₂ * P z ^ 2 * Q z ^ 2 * WeierstrassCurve.Jacobian.addZ P Q ^ 2 -
        P x * Q z ^ 2 * WeierstrassCurve.Jacobian.addZ P Q ^ 2 -
      Q x * P z ^ 2 * WeierstrassCurve.Jacobian.addZ P Q ^ 2) /
    (P z * Q z) ^ 2

full_name: WeierstrassCurve.Jacobian.addX_smul
code: lemma addX_smul (P Q : Fin 3 → R) (u v : R) :
    W'.addX (u • P) (v • Q) = ((u * v) ^ 2) ^ 2 * W'.addX P Q 
goal: W'.addX (u • P) (v • Q) = ((u * v) ^ 2) ^ 2 * W'.addX P Q

full_name: WeierstrassCurve.Jacobian.addX_of_Z_eq_zero_left
code: lemma addX_of_Z_eq_zero_left {P Q : Fin 3 → R} (hPz : P z = 0) :
    W'.addX P Q = (P x * Q z) ^ 2 * Q x 
goal: W'.addX P Q = (P x * Q z) ^ 2 * Q x

full_name: WeierstrassCurve.Jacobian.addX_of_Z_eq_zero_right
code: lemma addX_of_Z_eq_zero_right {P Q : Fin 3 → R} (hQz : Q z = 0) :
    W'.addX P Q = (-(Q x * P z)) ^ 2 * P x 
goal: W'.addX P Q = (-(Q x * P z)) ^ 2 * P x

full_name: WeierstrassCurve.Jacobian.addX_of_X_eq'
code: lemma addX_of_X_eq' {P Q : Fin 3 → R} (hP : W'.Equation P) (hQ : W'.Equation Q)
    (hx : P x * Q z ^ 2 = Q x * P z ^ 2) :
    W'.addX P Q * (P z * Q z) ^ 2 = (P y * Q z ^ 3 - Q y * P z ^ 3) ^ 2 
goal: W'.addX P Q * (P z * Q z) ^ 2 = (P y * Q z ^ 3 - Q y * P z ^ 3) ^ 2

full_name: WeierstrassCurve.Jacobian.addX_of_X_eq
code: lemma addX_of_X_eq {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hQz : Q z ≠ 0) (hx : P x * Q z ^ 2 = Q x * P z ^ 2) : W.addX P Q = addU P Q ^ 2 
goal: W.addX P Q = WeierstrassCurve.Jacobian.addU P Q ^ 2

full_name: _private.Mathlib.AlgebraicGeometry.EllipticCurve.Jacobian.0.WeierstrassCurve.Jacobian.toAffine_addX_of_ne
code: private lemma toAffine_addX_of_ne {P Q : Fin 3 → F} {n d : F} (hPz : P z ≠ 0) (hQz : Q z ≠ 0)
    (hd : d ≠ 0) : W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2) (n / (P z * Q z * d)) =
      (n ^ 2 + W.a₁ * n * P z * Q z * d - W.a₂ * P z ^ 2 * Q z ^ 2 * d ^ 2 - P x * Q z ^ 2 * d ^ 2
        - Q x * P z ^ 2 * d ^ 2) / (P z * Q z * d) ^ 2 
goal: W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2) (n / (P z * Q z * d)) =
  (n ^ 2 + W.a₁ * n * P z * Q z * d - W.a₂ * P z ^ 2 * Q z ^ 2 * d ^ 2 - P x * Q z ^ 2 * d ^ 2 -
      Q x * P z ^ 2 * d ^ 2) /
    (P z * Q z * d) ^ 2

full_name: WeierstrassCurve.Jacobian.addX_of_Z_ne_zero
code: lemma addX_of_Z_ne_zero {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hQz : Q z ≠ 0) (hx : P x * Q z ^ 2 ≠ Q x * P z ^ 2) :
    W.addX P Q / addZ P Q ^ 2 = W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2)
      (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)) 
goal: W.addX P Q / WeierstrassCurve.Jacobian.addZ P Q ^ 2 =
  W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2)
    (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3))

full_name: WeierstrassCurve.Jacobian.negAddY
code: /-- The $Y$-coordinate of the negated addition of two distinct point representatives. -/
def negAddY (P Q : Fin 3 → R) : R 
goal: R

full_name: WeierstrassCurve.Jacobian.negAddY_self
code: lemma negAddY_self {P : Fin 3 → R} : W'.negAddY P P = 0 
goal: W'.negAddY P P = 0

full_name: WeierstrassCurve.Jacobian.negAddY_eq'
code: lemma negAddY_eq' {P Q : Fin 3 → R} : W'.negAddY P Q * (P z * Q z) ^ 3 =
    (P y * Q z ^ 3 - Q y * P z ^ 3) * (W'.addX P Q * (P z * Q z) ^ 2 - P x * Q z ^ 2 * addZ P Q ^ 2)
      + P y * Q z ^ 3 * addZ P Q ^ 3 
goal: W'.negAddY P Q * (P z * Q z) ^ 3 =
  (P y * Q z ^ 3 - Q y * P z ^ 3) *
      (W'.addX P Q * (P z * Q z) ^ 2 - P x * Q z ^ 2 * WeierstrassCurve.Jacobian.addZ P Q ^ 2) +
    P y * Q z ^ 3 * WeierstrassCurve.Jacobian.addZ P Q ^ 3

full_name: WeierstrassCurve.Jacobian.negAddY_eq
code: lemma negAddY_eq {P Q : Fin 3 → F} (hPz : P z ≠ 0) (hQz : Q z ≠ 0) : W.negAddY P Q =
    ((P y * Q z ^ 3 - Q y * P z ^ 3) * (W.addX P Q * (P z * Q z) ^ 2 - P x * Q z ^ 2 * addZ P Q ^ 2)
      + P y * Q z ^ 3 * addZ P Q ^ 3) / (P z * Q z) ^ 3 
goal: W.negAddY P Q =
  ((P y * Q z ^ 3 - Q y * P z ^ 3) *
        (W.addX P Q * (P z * Q z) ^ 2 - P x * Q z ^ 2 * WeierstrassCurve.Jacobian.addZ P Q ^ 2) +
      P y * Q z ^ 3 * WeierstrassCurve.Jacobian.addZ P Q ^ 3) /
    (P z * Q z) ^ 3

full_name: WeierstrassCurve.Jacobian.negAddY_smul
code: lemma negAddY_smul (P Q : Fin 3 → R) (u v : R) :
    W'.negAddY (u • P) (v • Q) = ((u * v) ^ 2) ^ 3 * W'.negAddY P Q 
goal: W'.negAddY (u • P) (v • Q) = ((u * v) ^ 2) ^ 3 * W'.negAddY P Q

full_name: WeierstrassCurve.Jacobian.negAddY_of_Z_eq_zero_left
code: lemma negAddY_of_Z_eq_zero_left {P Q : Fin 3 → R} (hP : W'.Equation P) (hPz : P z = 0) :
    W'.negAddY P Q = (P x * Q z) ^ 3 * W'.negY Q 
goal: W'.negAddY P Q = (P x * Q z) ^ 3 * W'.negY Q

full_name: WeierstrassCurve.Jacobian.negAddY_of_Z_eq_zero_right
code: lemma negAddY_of_Z_eq_zero_right {P Q : Fin 3 → R} (hQ : W'.Equation Q) (hQz : Q z = 0) :
    W'.negAddY P Q = (-(Q x * P z)) ^ 3 * W'.negY P 
goal: W'.negAddY P Q = (-(Q x * P z)) ^ 3 * W'.negY P

full_name: WeierstrassCurve.Jacobian.negAddY_of_X_eq'
code: lemma negAddY_of_X_eq' {P Q : Fin 3 → R} (hP : W'.Equation P) (hQ : W'.Equation Q)
    (hx : P x * Q z ^ 2 = Q x * P z ^ 2) :
    W'.negAddY P Q * (P z * Q z) ^ 3 = (P y * Q z ^ 3 - Q y * P z ^ 3) ^ 3 
goal: W'.negAddY P Q * (P z * Q z) ^ 3 = (P y * Q z ^ 3 - Q y * P z ^ 3) ^ 3

full_name: WeierstrassCurve.Jacobian.negAddY_of_X_eq
code: lemma negAddY_of_X_eq {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hQz : Q z ≠ 0) (hx : P x * Q z ^ 2 = Q x * P z ^ 2) : W.negAddY P Q = (-addU P Q) ^ 3 
goal: W.negAddY P Q = (-WeierstrassCurve.Jacobian.addU P Q) ^ 3

full_name: _private.Mathlib.AlgebraicGeometry.EllipticCurve.Jacobian.0.WeierstrassCurve.Jacobian.toAffine_negAddY_of_ne
code: private lemma toAffine_negAddY_of_ne {P Q : Fin 3 → F} {n d : F} (hPz : P z ≠ 0) (hQz : Q z ≠ 0)
    (hd : d ≠ 0) :
    W.toAffine.negAddY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (n / (P z * Q z * d)) =
      (n * (n ^ 2 + W.a₁ * n * P z * Q z * d - W.a₂ * P z ^ 2 * Q z ^ 2 * d ^ 2
          - P x * Q z ^ 2 * d ^ 2 - Q x * P z ^ 2 * d ^ 2 - P x * Q z ^ 2 * d ^ 2)
        + P y * Q z ^ 3 * d ^ 3) / (P z * Q z * d) ^ 3 
goal: W.toAffine.negAddY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (n / (P z * Q z * d)) =
  (n *
        (n ^ 2 + W.a₁ * n * P z * Q z * d - W.a₂ * P z ^ 2 * Q z ^ 2 * d ^ 2 - P x * Q z ^ 2 * d ^ 2 -
            Q x * P z ^ 2 * d ^ 2 -
          P x * Q z ^ 2 * d ^ 2) +
      P y * Q z ^ 3 * d ^ 3) /
    (P z * Q z * d) ^ 3

full_name: WeierstrassCurve.Jacobian.negAddY_of_Z_ne_zero
code: lemma negAddY_of_Z_ne_zero {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hQz : Q z ≠ 0) (hx : P x * Q z ^ 2 ≠ Q x * P z ^ 2) : W.negAddY P Q / addZ P Q ^ 3 =
      W.toAffine.negAddY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
        (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)) 
goal: W.negAddY P Q / WeierstrassCurve.Jacobian.addZ P Q ^ 3 =
  W.toAffine.negAddY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
    (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3))

full_name: WeierstrassCurve.Jacobian.addY
code: /-- The $Y$-coordinate of the addition of two distinct point representatives. -/
def addY (P Q : Fin 3 → R) : R 
goal: R

full_name: WeierstrassCurve.Jacobian.addY_self
code: lemma addY_self {P : Fin 3 → R} (hP : W'.Equation P) : W'.addY P P = 0 
goal: W'.addY P P = 0

full_name: WeierstrassCurve.Jacobian.addY_smul
code: lemma addY_smul (P Q : Fin 3 → R) (u v : R) :
    W'.addY (u • P) (v • Q) = ((u * v) ^ 2) ^ 3 * W'.addY P Q 
goal: W'.addY (u • P) (v • Q) = ((u * v) ^ 2) ^ 3 * W'.addY P Q

full_name: WeierstrassCurve.Jacobian.addY_of_Z_eq_zero_left
code: lemma addY_of_Z_eq_zero_left {P Q : Fin 3 → R} (hP : W'.Equation P) (hPz : P z = 0) :
    W'.addY P Q = (P x * Q z) ^ 3 * Q y 
goal: W'.addY P Q = (P x * Q z) ^ 3 * Q y

full_name: WeierstrassCurve.Jacobian.addY_of_Z_eq_zero_right
code: lemma addY_of_Z_eq_zero_right {P Q : Fin 3 → R} (hQ : W'.Equation Q) (hQz : Q z = 0) :
    W'.addY P Q = (-(Q x * P z)) ^ 3 * P y 
goal: W'.addY P Q = (-(Q x * P z)) ^ 3 * P y

full_name: WeierstrassCurve.Jacobian.addY_of_X_eq'
code: lemma addY_of_X_eq' {P Q : Fin 3 → R} (hP : W'.Equation P) (hQ : W'.Equation Q)
    (hx : P x * Q z ^ 2 = Q x * P z ^ 2) :
    W'.addY P Q * (P z * Q z) ^ 3 = (-(P y * Q z ^ 3 - Q y * P z ^ 3)) ^ 3 
goal: W'.addY P Q * (P z * Q z) ^ 3 = (-(P y * Q z ^ 3 - Q y * P z ^ 3)) ^ 3

full_name: WeierstrassCurve.Jacobian.addY_of_X_eq
code: lemma addY_of_X_eq {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hQz : Q z ≠ 0) (hx : P x * Q z ^ 2 = Q x * P z ^ 2) : W.addY P Q = addU P Q ^ 3 
goal: W.addY P Q = WeierstrassCurve.Jacobian.addU P Q ^ 3

full_name: WeierstrassCurve.Jacobian.addY_of_Z_ne_zero
code: lemma addY_of_Z_ne_zero {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hQz : Q z ≠ 0) (hx : P x * Q z ^ 2 ≠ Q x * P z ^ 2) :
    W.addY P Q / addZ P Q ^ 3 = W.toAffine.addY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
      (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)) 
goal: W.addY P Q / WeierstrassCurve.Jacobian.addZ P Q ^ 3 =
  W.toAffine.addY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
    (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3))

full_name: WeierstrassCurve.Jacobian.addXYZ
code: /-- The coordinates of the addition of two distinct point representatives. -/
noncomputable def addXYZ (P Q : Fin 3 → R) : Fin 3 → R 
goal: Fin 3 → R

full_name: WeierstrassCurve.Jacobian.addXYZ_self
code: lemma addXYZ_self {P : Fin 3 → R} (hP : W'.Equation P) : W'.addXYZ P P = ![0, 0, 0] 
goal: W'.addXYZ P P = ![0, 0, 0]

full_name: WeierstrassCurve.Jacobian.addXYZ_smul
code: lemma addXYZ_smul (P Q : Fin 3 → R) (u v : R) :
    W'.addXYZ (u • P) (v • Q) = (u * v) ^ 2 • W'.addXYZ P Q 
goal: W'.addXYZ (u • P) (v • Q) = (u * v) ^ 2 • W'.addXYZ P Q

full_name: WeierstrassCurve.Jacobian.addXYZ_of_Z_eq_zero_left
code: lemma addXYZ_of_Z_eq_zero_left {P Q : Fin 3 → R} (hP : W'.Equation P) (hPz : P z = 0) :
    W'.addXYZ P Q = (P x * Q z) • Q 
goal: W'.addXYZ P Q = (P x * Q z) • Q

full_name: WeierstrassCurve.Jacobian.addXYZ_of_Z_eq_zero_right
code: lemma addXYZ_of_Z_eq_zero_right {P Q : Fin 3 → R} (hQ : W'.Equation Q) (hQz : Q z = 0) :
    W'.addXYZ P Q = -(Q x * P z) • P 
goal: W'.addXYZ P Q = -(Q x * P z) • P

full_name: WeierstrassCurve.Jacobian.addXYZ_of_X_eq
code: lemma addXYZ_of_X_eq {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hQz : Q z ≠ 0) (hx : P x * Q z ^ 2 = Q x * P z ^ 2) :
    W.addXYZ P Q = addU P Q • ![1, 1, 0] 
goal: W.addXYZ P Q = WeierstrassCurve.Jacobian.addU P Q • ![1, 1, 0]

full_name: WeierstrassCurve.Jacobian.addXYZ_of_Z_ne_zero
code: lemma addXYZ_of_Z_ne_zero {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hQz : Q z ≠ 0) (hx : P x * Q z ^ 2 ≠ Q x * P z ^ 2) :
    W.addXYZ P Q = addZ P Q •
      ![W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2)
          (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
        W.toAffine.addY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
          (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
        1] 
goal: W.addXYZ P Q =
  WeierstrassCurve.Jacobian.addZ P Q •
    ![W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2)
        (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
      W.toAffine.addY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
        (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
      1]

full_name: WeierstrassCurve.Jacobian.neg
code: /-- The negation of a point representative. -/
def neg (P : Fin 3 → R) : Fin 3 → R 
goal: Fin 3 → R

full_name: WeierstrassCurve.Jacobian.neg_smul
code: lemma neg_smul (P : Fin 3 → R) (u : R) : W'.neg (u • P) = u • W'.neg P 
goal: W'.neg (u • P) = u • W'.neg P

full_name: WeierstrassCurve.Jacobian.neg_smul_equiv
code: lemma neg_smul_equiv (P : Fin 3 → R) {u : R} (hu : IsUnit u) : W'.neg (u • P) ≈ W'.neg P 
goal: W'.neg (u • P) ≈ W'.neg P

full_name: WeierstrassCurve.Jacobian.neg_equiv
code: lemma neg_equiv {P Q : Fin 3 → R} (h : P ≈ Q) : W'.neg P ≈ W'.neg Q 
goal: W'.neg P ≈ W'.neg Q

full_name: WeierstrassCurve.Jacobian.neg_of_Z_eq_zero'
code: lemma neg_of_Z_eq_zero' {P : Fin 3 → R} (hPz : P z = 0) : W'.neg P = ![P x, -P y, 0] 
goal: W'.neg P = ![P x, -P y, 0]

full_name: WeierstrassCurve.Jacobian.neg_of_Z_eq_zero
code: lemma neg_of_Z_eq_zero {P : Fin 3 → F} (hP : W.Nonsingular P) (hPz : P z = 0) :
    W.neg P = -(P y / P x) • ![1, 1, 0] 
goal: W.neg P = -(P y / P x) • ![1, 1, 0]

full_name: WeierstrassCurve.Jacobian.neg_of_Z_ne_zero
code: lemma neg_of_Z_ne_zero {P : Fin 3 → F} (hPz : P z ≠ 0) :
    W.neg P = P z • ![P x / P z ^ 2, W.toAffine.negY (P x / P z ^ 2) (P y / P z ^ 3), 1] 
goal: W.neg P = P z • ![P x / P z ^ 2, W.toAffine.negY (P x / P z ^ 2) (P y / P z ^ 3), 1]

full_name: _private.Mathlib.AlgebraicGeometry.EllipticCurve.Jacobian.0.WeierstrassCurve.Jacobian.nonsingular_neg_of_Z_ne_zero
code: private lemma nonsingular_neg_of_Z_ne_zero {P : Fin 3 → F} (hP : W.Nonsingular P) (hPz : P z ≠ 0) :
    W.Nonsingular ![P x / P z ^ 2, W.toAffine.negY (P x / P z ^ 2) (P y / P z ^ 3), 1] 
goal: W.Nonsingular ![P x / P z ^ 2, W.toAffine.negY (P x / P z ^ 2) (P y / P z ^ 3), 1]

full_name: WeierstrassCurve.Jacobian.nonsingular_neg
code: lemma nonsingular_neg {P : Fin 3 → F} (hP : W.Nonsingular P) : W.Nonsingular <| W.neg P 
goal: W.Nonsingular (W.neg P)

full_name: WeierstrassCurve.Jacobian.addZ_neg
code: lemma addZ_neg {P : Fin 3 → R} : addZ P (W'.neg P) = 0 
goal: WeierstrassCurve.Jacobian.addZ P (W'.neg P) = 0

full_name: WeierstrassCurve.Jacobian.addX_neg
code: lemma addX_neg {P : Fin 3 → R} (hP : W'.Equation P) : W'.addX P (W'.neg P) = W'.dblZ P ^ 2 
goal: W'.addX P (W'.neg P) = W'.dblZ P ^ 2

full_name: WeierstrassCurve.Jacobian.negAddY_neg
code: lemma negAddY_neg {P : Fin 3 → R} (hP : W'.Equation P) :
    W'.negAddY P (W'.neg P) = W'.dblZ P ^ 3 
goal: W'.negAddY P (W'.neg P) = W'.dblZ P ^ 3

full_name: WeierstrassCurve.Jacobian.addY_neg
code: lemma addY_neg {P : Fin 3 → R} (hP : W'.Equation P) : W'.addY P (W'.neg P) = -W'.dblZ P ^ 3 
goal: W'.addY P (W'.neg P) = -W'.dblZ P ^ 3

full_name: WeierstrassCurve.Jacobian.addXYZ_neg
code: lemma addXYZ_neg {P : Fin 3 → R} (hP : W'.Equation P) :
    W'.addXYZ P (W'.neg P) = -W'.dblZ P • ![1, 1, 0] 
goal: W'.addXYZ P (W'.neg P) = -W'.dblZ P • ![1, 1, 0]

full_name: WeierstrassCurve.Jacobian.negMap
code: /-- The negation of a point class. If `P` is a point representative,
then `W'.negMap ⟦P⟧` is definitionally equivalent to `W'.neg P`. -/
def negMap (P : PointClass R) : PointClass R 
goal: WeierstrassCurve.Jacobian.PointClass R

full_name: WeierstrassCurve.Jacobian.negMap_eq
code: lemma negMap_eq {P : Fin 3 → R} : W'.negMap ⟦P⟧ = ⟦W'.neg P⟧ 
goal: W'.negMap ⟦P⟧ = ⟦W'.neg P⟧

full_name: WeierstrassCurve.Jacobian.negMap_of_Z_eq_zero
code: lemma negMap_of_Z_eq_zero {P : Fin 3 → F} (hP : W.Nonsingular P) (hPz : P z = 0) :
    W.negMap ⟦P⟧ = ⟦![1, 1, 0]⟧ 
goal: W.negMap ⟦P⟧ = ⟦![1, 1, 0]⟧

full_name: WeierstrassCurve.Jacobian.negMap_of_Z_ne_zero
code: lemma negMap_of_Z_ne_zero {P : Fin 3 → F} (hPz : P z ≠ 0) :
    W.negMap ⟦P⟧ = ⟦![P x / P z ^ 2, W.toAffine.negY (P x / P z ^ 2) (P y / P z ^ 3), 1]⟧ 
goal: W.negMap ⟦P⟧ = ⟦![P x / P z ^ 2, W.toAffine.negY (P x / P z ^ 2) (P y / P z ^ 3), 1]⟧

full_name: WeierstrassCurve.Jacobian.nonsingularLift_negMap
code: lemma nonsingularLift_negMap {P : PointClass F} (hP : W.NonsingularLift P) :
    W.NonsingularLift <| W.negMap P 
goal: W.NonsingularLift (W.negMap P)

full_name: WeierstrassCurve.Jacobian.add
code: /-- The addition of two point representatives. -/
noncomputable def add (P Q : Fin 3 → R) : Fin 3 → R 
goal: Fin 3 → R

full_name: WeierstrassCurve.Jacobian.add_of_equiv
code: lemma add_of_equiv {P Q : Fin 3 → R} (h : P ≈ Q) : W'.add P Q = W'.dblXYZ P 
goal: W'.add P Q = W'.dblXYZ P

full_name: WeierstrassCurve.Jacobian.add_smul_of_equiv
code: lemma add_smul_of_equiv {P Q : Fin 3 → R} (h : P ≈ Q) {u v : R} (hu : IsUnit u) (hv : IsUnit v) :
    W'.add (u • P) (v • Q) = u ^ 4 • W'.add P Q 
goal: W'.add (u • P) (v • Q) = u ^ 4 • W'.add P Q

full_name: WeierstrassCurve.Jacobian.add_self
code: lemma add_self (P : Fin 3 → R) : W'.add P P = W'.dblXYZ P 
goal: W'.add P P = W'.dblXYZ P

full_name: WeierstrassCurve.Jacobian.add_of_eq
code: lemma add_of_eq {P Q : Fin 3 → R} (h : P = Q) : W'.add P Q = W'.dblXYZ P 
goal: W'.add P Q = W'.dblXYZ P

full_name: WeierstrassCurve.Jacobian.add_of_not_equiv
code: lemma add_of_not_equiv {P Q : Fin 3 → R} (h : ¬P ≈ Q) : W'.add P Q = W'.addXYZ P Q 
goal: W'.add P Q = W'.addXYZ P Q

full_name: WeierstrassCurve.Jacobian.add_smul_of_not_equiv
code: lemma add_smul_of_not_equiv {P Q : Fin 3 → R} (h : ¬P ≈ Q) {u v : R} (hu : IsUnit u)
    (hv : IsUnit v) : W'.add (u • P) (v • Q) = (u * v) ^ 2 • W'.add P Q 
goal: W'.add (u • P) (v • Q) = (u * v) ^ 2 • W'.add P Q

full_name: WeierstrassCurve.Jacobian.add_smul_equiv
code: lemma add_smul_equiv (P Q : Fin 3 → R) {u v : R} (hu : IsUnit u) (hv : IsUnit v) :
    W'.add (u • P) (v • Q) ≈ W'.add P Q 
goal: W'.add (u • P) (v • Q) ≈ W'.add P Q

full_name: WeierstrassCurve.Jacobian.add_equiv
code: lemma add_equiv {P P' Q Q' : Fin 3 → R} (hP : P ≈ P') (hQ : Q ≈ Q') :
    W'.add P Q ≈ W'.add P' Q' 
goal: W'.add P Q ≈ W'.add P' Q'

full_name: WeierstrassCurve.Jacobian.add_of_Z_eq_zero
code: lemma add_of_Z_eq_zero {P Q : Fin 3 → F} (hP : W.Nonsingular P) (hQ : W.Nonsingular Q)
    (hPz : P z = 0) (hQz : Q z = 0) : W.add P Q = P x ^ 2 • ![1, 1, 0] 
goal: W.add P Q = P x ^ 2 • ![1, 1, 0]

full_name: WeierstrassCurve.Jacobian.add_of_Z_eq_zero_left
code: lemma add_of_Z_eq_zero_left {P Q : Fin 3 → R} (hP : W'.Equation P) (hPz : P z = 0) (hQz : Q z ≠ 0) :
    W'.add P Q = (P x * Q z) • Q 
goal: W'.add P Q = (P x * Q z) • Q

full_name: WeierstrassCurve.Jacobian.add_of_Z_eq_zero_right
code: lemma add_of_Z_eq_zero_right {P Q : Fin 3 → R} (hQ : W'.Equation Q) (hPz : P z ≠ 0)
    (hQz : Q z = 0) : W'.add P Q = -(Q x * P z) • P 
goal: W'.add P Q = -(Q x * P z) • P

full_name: WeierstrassCurve.Jacobian.add_of_Y_eq
code: lemma add_of_Y_eq {P Q : Fin 3 → F} (hPz : P z ≠ 0) (hQz : Q z ≠ 0)
    (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 = Q y * P z ^ 3)
    (hy' : P y * Q z ^ 3 = W.negY Q * P z ^ 3) : W.add P Q = W.dblU P • ![1, 1, 0] 
goal: W.add P Q = W.dblU P • ![1, 1, 0]

full_name: WeierstrassCurve.Jacobian.add_of_Y_ne
code: lemma add_of_Y_ne {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hQz : Q z ≠ 0) (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 ≠ Q y * P z ^ 3) :
    W.add P Q = addU P Q • ![1, 1, 0] 
goal: W.add P Q = WeierstrassCurve.Jacobian.addU P Q • ![1, 1, 0]

full_name: WeierstrassCurve.Jacobian.add_of_Y_ne'
code: lemma add_of_Y_ne' {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hQz : Q z ≠ 0) (hx : P x * Q z ^ 2 = Q x * P z ^ 2) (hy : P y * Q z ^ 3 ≠ W.negY Q * P z ^ 3) :
    W.add P Q = W.dblZ P •
      ![W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2)
          (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
        W.toAffine.addY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
          (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
        1] 
goal: W.add P Q =
  W.dblZ P •
    ![W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2)
        (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
      W.toAffine.addY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
        (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
      1]

full_name: WeierstrassCurve.Jacobian.add_of_X_ne
code: lemma add_of_X_ne {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hQz : Q z ≠ 0) (hx : P x * Q z ^ 2 ≠ Q x * P z ^ 2) :
    W.add P Q = addZ P Q •
      ![W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2)
          (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
        W.toAffine.addY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
          (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
        1] 
goal: W.add P Q =
  WeierstrassCurve.Jacobian.addZ P Q •
    ![W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2)
        (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
      W.toAffine.addY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
        (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
      1]

full_name: _private.Mathlib.AlgebraicGeometry.EllipticCurve.Jacobian.0.WeierstrassCurve.Jacobian.nonsingular_add_of_Z_ne_zero
code: private lemma nonsingular_add_of_Z_ne_zero {P Q : Fin 3 → F} (hP : W.Nonsingular P)
    (hQ : W.Nonsingular Q) (hPz : P z ≠ 0) (hQz : Q z ≠ 0)
    (hxy : P x * Q z ^ 2 = Q x * P z ^ 2 → P y * Q z ^ 3 ≠ W.negY Q * P z ^ 3) : W.Nonsingular
      ![W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2)
          (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
        W.toAffine.addY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
          (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)), 1] 
goal: W.Nonsingular
  ![W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2)
      (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
    W.toAffine.addY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
      (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
    1]

full_name: WeierstrassCurve.Jacobian.nonsingular_add
code: lemma nonsingular_add {P Q : Fin 3 → F} (hP : W.Nonsingular P) (hQ : W.Nonsingular Q) :
    W.Nonsingular <| W.add P Q 
goal: W.Nonsingular (W.add P Q)

full_name: WeierstrassCurve.Jacobian.addMap
code: /-- The addition of two point classes. If `P` is a point representative,
then `W.addMap ⟦P⟧ ⟦Q⟧` is definitionally equivalent to `W.add P Q`. -/
noncomputable def addMap (P Q : PointClass R) : PointClass R 
goal: WeierstrassCurve.Jacobian.PointClass R

full_name: WeierstrassCurve.Jacobian.addMap_eq
code: lemma addMap_eq (P Q : Fin 3 → R) : W'.addMap ⟦P⟧ ⟦Q⟧ = ⟦W'.add P Q⟧ 
goal: W'.addMap ⟦P⟧ ⟦Q⟧ = ⟦W'.add P Q⟧

full_name: WeierstrassCurve.Jacobian.addMap_of_Z_eq_zero_left
code: lemma addMap_of_Z_eq_zero_left {P : Fin 3 → F} {Q : PointClass F} (hP : W.Nonsingular P)
    (hQ : W.NonsingularLift Q) (hPz : P z = 0) : W.addMap ⟦P⟧ Q = Q 
goal: W.addMap ⟦P⟧ Q = Q

full_name: WeierstrassCurve.Jacobian.addMap_of_Z_eq_zero_right
code: lemma addMap_of_Z_eq_zero_right {P : PointClass F} {Q : Fin 3 → F} (hP : W.NonsingularLift P)
    (hQ : W.Nonsingular Q) (hQz : Q z = 0) : W.addMap P ⟦Q⟧ = P 
goal: W.addMap P ⟦Q⟧ = P

full_name: WeierstrassCurve.Jacobian.addMap_of_Y_eq
code: lemma addMap_of_Y_eq {P Q : Fin 3 → F} (hP : W.Nonsingular P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hQz : Q z ≠ 0) (hx : P x * Q z ^ 2 = Q x * P z ^ 2)
    (hy' : P y * Q z ^ 3 = W.negY Q * P z ^ 3) : W.addMap ⟦P⟧ ⟦Q⟧ = ⟦![1, 1, 0]⟧ 
goal: W.addMap ⟦P⟧ ⟦Q⟧ = ⟦![1, 1, 0]⟧

full_name: WeierstrassCurve.Jacobian.addMap_of_Z_ne_zero
code: lemma addMap_of_Z_ne_zero {P Q : Fin 3 → F} (hP : W.Equation P) (hQ : W.Equation Q) (hPz : P z ≠ 0)
    (hQz : Q z ≠ 0) (hxy : P x * Q z ^ 2 = Q x * P z ^ 2 → P y * Q z ^ 3 ≠ W.negY Q * P z ^ 3) :
    W.addMap ⟦P⟧ ⟦Q⟧ =
      ⟦![W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2)
          (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
        W.toAffine.addY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
          (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
        1]⟧ 
goal: W.addMap ⟦P⟧ ⟦Q⟧ =
  ⟦![W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2)
        (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
      W.toAffine.addY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
        (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
      1]⟧

full_name: WeierstrassCurve.Jacobian.nonsingularLift_addMap
code: lemma nonsingularLift_addMap {P Q : PointClass F} (hP : W.NonsingularLift P)
    (hQ : W.NonsingularLift Q) : W.NonsingularLift <| W.addMap P Q 
goal: W.NonsingularLift (W.addMap P Q)

full_name: WeierstrassCurve.Jacobian.Point
code: /-- A nonsingular rational point on `W'`. -/
@[ext]
structure Point where
  /-- The point class underlying a nonsingular rational point on `W'`. -/
  {point : PointClass R}
  /-- The nonsingular condition underlying a nonsingular rational point on `W'`. -/
  (nonsingular : W'.NonsingularLift point)
goal: Type u

full_name: WeierstrassCurve.Jacobian.Point.nonsingular
code: /-- A nonsingular rational point on `W'`. -/
@[ext]
structure Point where
  /-- The point class underlying a nonsingular rational point on `W'`. -/
  {point : PointClass R}
  /-- The nonsingular condition underlying a nonsingular rational point on `W'`. -/
  (nonsingular : W'.NonsingularLift point)
goal: W'.NonsingularLift self.point

full_name: WeierstrassCurve.Jacobian.Point.point
code: /-- A nonsingular rational point on `W'`. -/
@[ext]
structure Point where
  /-- The point class underlying a nonsingular rational point on `W'`. -/
  {point : PointClass R}
  /-- The nonsingular condition underlying a nonsingular rational point on `W'`. -/
  (nonsingular : W'.NonsingularLift point)
goal: WeierstrassCurve.Jacobian.PointClass R

full_name: WeierstrassCurve.Jacobian.Point.mk_point
code: lemma mk_point {P : PointClass R} (h : W'.NonsingularLift P) : (mk h).point = P 
goal: (WeierstrassCurve.Jacobian.Point.mk h).point = P

full_name: WeierstrassCurve.Jacobian.Point.instZeroPoint
code: instance instZeroPoint [Nontrivial R] : Zero W'.Point 
goal: Zero W'.Point

full_name: WeierstrassCurve.Jacobian.Point.zero_def
code: lemma zero_def [Nontrivial R] : (0 : W'.Point) = ⟨nonsingularLift_zero⟩ 
goal: 0 = WeierstrassCurve.Jacobian.Point.mk ⋯

full_name: WeierstrassCurve.Jacobian.Point.zero_point
code: lemma zero_point [Nontrivial R] : (0 : W'.Point).point = ⟦![1, 1, 0]⟧ 
goal: WeierstrassCurve.Jacobian.Point.point 0 = ⟦![1, 1, 0]⟧

full_name: WeierstrassCurve.Jacobian.Point.fromAffine
code: /-- The map from a nonsingular rational point on a Weierstrass curve `W'` in affine coordinates
to the corresponding nonsingular rational point on `W'` in Jacobian coordinates. -/
def fromAffine [Nontrivial R] : W'.toAffine.Point → W'.Point
  
goal: W'.toAffine.Point → W'.Point

full_name: WeierstrassCurve.Jacobian.Point.fromAffine_zero
code: lemma fromAffine_zero [Nontrivial R] : fromAffine 0 = (0 : W'.Point) 
goal: WeierstrassCurve.Jacobian.Point.fromAffine 0 = 0

full_name: WeierstrassCurve.Jacobian.Point.fromAffine_some
code: lemma fromAffine_some [Nontrivial R] {X Y : R} (h : W'.toAffine.Nonsingular X Y) :
    fromAffine (.some h) = ⟨(nonsingularLift_some ..).mpr h⟩ 
goal: WeierstrassCurve.Jacobian.Point.fromAffine (WeierstrassCurve.Affine.Point.some h) = WeierstrassCurve.Jacobian.Point.mk ⋯

full_name: WeierstrassCurve.Jacobian.Point.fromAffine_ne_zero
code: lemma fromAffine_ne_zero [Nontrivial R] {X Y : R} (h : W'.toAffine.Nonsingular X Y) :
    fromAffine (.some h) ≠ 0 
goal: WeierstrassCurve.Jacobian.Point.fromAffine (WeierstrassCurve.Affine.Point.some h) ≠ 0

full_name: WeierstrassCurve.Jacobian.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 (P : W.Point) : W.Point 
goal: W.Point

full_name: WeierstrassCurve.Jacobian.Point.instNegPoint
code: instance instNegPoint : Neg W.Point 
goal: Neg W.Point

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

full_name: WeierstrassCurve.Jacobian.Point.neg_point
code: lemma neg_point (P : W.Point) : (-P).point = W.negMap P.point 
goal: (-P).point = W.negMap P.point

full_name: WeierstrassCurve.Jacobian.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 (P Q : W.Point) : W.Point 
goal: W.Point

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

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

full_name: WeierstrassCurve.Jacobian.Point.add_point
code: lemma add_point (P Q : W.Point) : (P + Q).point = W.addMap P.point Q.point 
goal: (P + Q).point = W.addMap P.point Q.point

full_name: WeierstrassCurve.Jacobian.Point.toAffine
code: /-- The map from a point representative that is nonsingular on a Weierstrass curve `W` in Jacobian
coordinates to the corresponding nonsingular rational point on `W` in affine coordinates. -/
noncomputable def toAffine (P : Fin 3 → F) : W.toAffine.Point 
goal: W.toAffine.Point

full_name: WeierstrassCurve.Jacobian.Point.toAffine_of_singular
code: lemma toAffine_of_singular {P : Fin 3 → F} (hP : ¬W.Nonsingular P) : toAffine W P = 0 
goal: WeierstrassCurve.Jacobian.Point.toAffine W P = 0

full_name: WeierstrassCurve.Jacobian.Point.toAffine_of_Z_eq_zero
code: lemma toAffine_of_Z_eq_zero {P : Fin 3 → F} (hPz : P z = 0) :
    toAffine W P = 0 
goal: WeierstrassCurve.Jacobian.Point.toAffine W P = 0

full_name: WeierstrassCurve.Jacobian.Point.toAffine_zero
code: lemma toAffine_zero : toAffine W ![1, 1, 0] = 0 
goal: WeierstrassCurve.Jacobian.Point.toAffine W ![1, 1, 0] = 0

full_name: WeierstrassCurve.Jacobian.Point.toAffine_of_Z_ne_zero
code: lemma toAffine_of_Z_ne_zero {P : Fin 3 → F} (hP : W.Nonsingular P) (hPz : P z ≠ 0) :
    toAffine W P = .some ((nonsingular_of_Z_ne_zero hPz).mp hP) 
goal: WeierstrassCurve.Jacobian.Point.toAffine W P = WeierstrassCurve.Affine.Point.some ⋯

full_name: WeierstrassCurve.Jacobian.Point.toAffine_some
code: lemma toAffine_some {X Y : F} (h : W.Nonsingular ![X, Y, 1]) :
    toAffine W ![X, Y, 1] = .some ((nonsingular_some ..).mp h) 
goal: WeierstrassCurve.Jacobian.Point.toAffine W ![X, Y, 1] = WeierstrassCurve.Affine.Point.some ⋯

full_name: WeierstrassCurve.Jacobian.Point.toAffine_smul
code: lemma toAffine_smul (P : Fin 3 → F) {u : F} (hu : IsUnit u) :
    toAffine W (u • P) = toAffine W P 
goal: WeierstrassCurve.Jacobian.Point.toAffine W (u • P) = WeierstrassCurve.Jacobian.Point.toAffine W P

full_name: WeierstrassCurve.Jacobian.Point.toAffine_of_equiv
code: lemma toAffine_of_equiv {P Q : Fin 3 → F} (h : P ≈ Q) : toAffine W P = toAffine W Q 
goal: WeierstrassCurve.Jacobian.Point.toAffine W P = WeierstrassCurve.Jacobian.Point.toAffine W Q

full_name: WeierstrassCurve.Jacobian.Point.toAffine_neg
code: lemma toAffine_neg {P : Fin 3 → F} (hP : W.Nonsingular P) :
    toAffine W (W.neg P) = -toAffine W P 
goal: WeierstrassCurve.Jacobian.Point.toAffine W (W.neg P) = -WeierstrassCurve.Jacobian.Point.toAffine W P

full_name: _private.Mathlib.AlgebraicGeometry.EllipticCurve.Jacobian.0.WeierstrassCurve.Jacobian.Point.toAffine_add_of_Z_ne_zero
code: private lemma toAffine_add_of_Z_ne_zero {P Q : Fin 3 → F} (hP : W.Nonsingular P)
    (hQ : W.Nonsingular Q) (hPz : P z ≠ 0) (hQz : Q z ≠ 0)
    (hxy : P x * Q z ^ 2 = Q x * P z ^ 2 → P y * Q z ^ 3 ≠ W.negY Q * P z ^ 3) :
    toAffine W
      ![W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2)
          (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
        W.toAffine.addY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
          (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
        1] = toAffine W P + toAffine W Q 
goal: WeierstrassCurve.Jacobian.Point.toAffine W
    ![W.toAffine.addX (P x / P z ^ 2) (Q x / Q z ^ 2)
        (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
      W.toAffine.addY (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3)
        (W.toAffine.slope (P x / P z ^ 2) (Q x / Q z ^ 2) (P y / P z ^ 3) (Q y / Q z ^ 3)),
      1] =
  WeierstrassCurve.Jacobian.Point.toAffine W P + WeierstrassCurve.Jacobian.Point.toAffine W Q

full_name: WeierstrassCurve.Jacobian.Point.toAffine_add
code: lemma toAffine_add {P Q : Fin 3 → F} (hP : W.Nonsingular P) (hQ : W.Nonsingular Q) :
    toAffine W (W.add P Q) = toAffine W P + toAffine W Q 
goal: WeierstrassCurve.Jacobian.Point.toAffine W (W.add P Q) =
  WeierstrassCurve.Jacobian.Point.toAffine W P + WeierstrassCurve.Jacobian.Point.toAffine W Q

full_name: WeierstrassCurve.Jacobian.Point.toAffineLift
code: /-- The map from a nonsingular rational point on a Weierstrass curve `W` in Jacobian coordinates
to the corresponding nonsingular rational point on `W` in affine coordinates. -/
noncomputable def toAffineLift (P : W.Point) : W.toAffine.Point 
goal: W.toAffine.Point

full_name: WeierstrassCurve.Jacobian.Point.toAffineLift_eq
code: lemma toAffineLift_eq {P : Fin 3 → F} (hP : W.NonsingularLift ⟦P⟧) :
    toAffineLift ⟨hP⟩ = toAffine W P 
goal: (WeierstrassCurve.Jacobian.Point.mk hP).toAffineLift = WeierstrassCurve.Jacobian.Point.toAffine W P

full_name: WeierstrassCurve.Jacobian.Point.toAffineLift_of_Z_eq_zero
code: lemma toAffineLift_of_Z_eq_zero {P : Fin 3 → F} (hP : W.NonsingularLift ⟦P⟧) (hPz : P z = 0) :
    toAffineLift ⟨hP⟩ = 0 
goal: (WeierstrassCurve.Jacobian.Point.mk hP).toAffineLift = 0

full_name: WeierstrassCurve.Jacobian.Point.toAffineLift_zero
code: lemma toAffineLift_zero : toAffineLift (0 : W.Point) = 0 
goal: WeierstrassCurve.Jacobian.Point.toAffineLift 0 = 0

full_name: WeierstrassCurve.Jacobian.Point.toAffineLift_of_Z_ne_zero
code: lemma toAffineLift_of_Z_ne_zero {P : Fin 3 → F} {hP : W.NonsingularLift ⟦P⟧} (hPz : P z ≠ 0) :
    toAffineLift ⟨hP⟩ = .some ((nonsingular_of_Z_ne_zero hPz).mp hP) 
goal: (WeierstrassCurve.Jacobian.Point.mk hP).toAffineLift = WeierstrassCurve.Affine.Point.some ⋯

full_name: WeierstrassCurve.Jacobian.Point.toAffineLift_some
code: lemma toAffineLift_some {X Y : F} (h : W.NonsingularLift ⟦![X, Y, 1]⟧) :
    toAffineLift ⟨h⟩ = .some ((nonsingular_some ..).mp h) 
goal: (WeierstrassCurve.Jacobian.Point.mk h).toAffineLift = WeierstrassCurve.Affine.Point.some ⋯

full_name: WeierstrassCurve.Jacobian.Point.toAffineLift_neg
code: lemma toAffineLift_neg (P : W.Point) : (-P).toAffineLift = -P.toAffineLift 
goal: (-P).toAffineLift = -P.toAffineLift

full_name: WeierstrassCurve.Jacobian.Point.toAffineLift_add
code: lemma toAffineLift_add (P Q : W.Point) :
    (P + Q).toAffineLift = P.toAffineLift + Q.toAffineLift 
goal: (P + Q).toAffineLift = P.toAffineLift + Q.toAffineLift

full_name: WeierstrassCurve.Jacobian.Point.toAffineAddEquiv
code: /-- The equivalence between the nonsingular rational points on a Weierstrass curve `W` in Jacobian
coordinates with the nonsingular rational points on `W` in affine coordinates. -/
@[simps]
noncomputable def toAffineAddEquiv : W.Point ≃+ W.toAffine.Point 
goal: W.Point ≃+ W.toAffine.Point

full_name: WeierstrassCurve.Jacobian.Point.toAffineAddEquiv_apply
code: /-- The equivalence between the nonsingular rational points on a Weierstrass curve `W` in Jacobian
coordinates with the nonsingular rational points on `W` in affine coordinates. -/
@[simps]
noncomputable def toAffineAddEquiv : W.Point ≃+ W.toAffine.Point 
goal: (WeierstrassCurve.Jacobian.Point.toAffineAddEquiv W) P = P.toAffineLift

full_name: WeierstrassCurve.Jacobian.Point.toAffineAddEquiv_symm_apply
code: /-- The equivalence between the nonsingular rational points on a Weierstrass curve `W` in Jacobian
coordinates with the nonsingular rational points on `W` in affine coordinates. -/
@[simps]
noncomputable def toAffineAddEquiv : W.Point ≃+ W.toAffine.Point 
goal: ∀ (a : W.toAffine.Point),
  (WeierstrassCurve.Jacobian.Point.toAffineAddEquiv W).symm a = WeierstrassCurve.Jacobian.Point.fromAffine a

full_name: WeierstrassCurve.Jacobian.map_smul
code: protected lemma map_smul (u : R) : f ∘ (u • P) = f u • (f ∘ P) 
goal: ⇑f ∘ (u • P) = f u • ⇑f ∘ P

full_name: WeierstrassCurve.Jacobian.map_addZ
code: @[simp] lemma map_addZ : addZ (f ∘ P) (f ∘ Q) = f (addZ P Q) 
goal: WeierstrassCurve.Jacobian.addZ (⇑f ∘ P) (⇑f ∘ Q) = f (WeierstrassCurve.Jacobian.addZ P Q)

full_name: WeierstrassCurve.Jacobian.map_addX
code: @[simp] lemma map_addX : addX (W'.map f) (f ∘ P) (f ∘ Q) = f (W'.addX P Q) 
goal: WeierstrassCurve.Jacobian.addX (WeierstrassCurve.map W' f) (⇑f ∘ P) (⇑f ∘ Q) = f (W'.addX P Q)

full_name: WeierstrassCurve.Jacobian.map_negAddY
code: @[simp] lemma map_negAddY : negAddY (W'.map f) (f ∘ P) (f ∘ Q) = f (W'.negAddY P Q) 
goal: WeierstrassCurve.Jacobian.negAddY (WeierstrassCurve.map W' f) (⇑f ∘ P) (⇑f ∘ Q) = f (W'.negAddY P Q)

full_name: WeierstrassCurve.Jacobian.map_negY
code: @[simp] lemma map_negY : negY (W'.map f) (f ∘ P) = f (W'.negY P) 
goal: WeierstrassCurve.Jacobian.negY (WeierstrassCurve.map W' f) (⇑f ∘ P) = f (W'.negY P)

full_name: WeierstrassCurve.Jacobian.map_neg
code: @[simp] protected lemma map_neg : neg (W'.map f) (f ∘ P) = f ∘ W'.neg P 
goal: WeierstrassCurve.Jacobian.neg (WeierstrassCurve.map W' f) (⇑f ∘ P) = ⇑f ∘ W'.neg P

full_name: WeierstrassCurve.Jacobian.map_addY
code: @[simp] lemma map_addY : addY (W'.map f) (f ∘ P) (f ∘ Q) = f (W'.addY P Q) 
goal: WeierstrassCurve.Jacobian.addY (WeierstrassCurve.map W' f) (⇑f ∘ P) (⇑f ∘ Q) = f (W'.addY P Q)

full_name: WeierstrassCurve.Jacobian.map_addXYZ
code: @[simp] lemma map_addXYZ : addXYZ (W'.map f) (f ∘ P) (f ∘ Q) = f ∘ addXYZ W' P Q 
goal: WeierstrassCurve.Jacobian.addXYZ (WeierstrassCurve.map W' f) (⇑f ∘ P) (⇑f ∘ Q) = ⇑f ∘ W'.addXYZ P Q

full_name: WeierstrassCurve.Jacobian.map_polynomial
code: lemma map_polynomial : (W'.map f).toJacobian.polynomial = MvPolynomial.map f W'.polynomial 
goal: (WeierstrassCurve.map W' f).toJacobian.polynomial = (MvPolynomial.map f) W'.polynomial

full_name: WeierstrassCurve.Jacobian.map_polynomialX
code: lemma map_polynomialX : (W'.map f).toJacobian.polynomialX = MvPolynomial.map f W'.polynomialX 
goal: (WeierstrassCurve.map W' f).toJacobian.polynomialX = (MvPolynomial.map f) W'.polynomialX

full_name: WeierstrassCurve.Jacobian.map_polynomialY
code: lemma map_polynomialY : (W'.map f).toJacobian.polynomialY = MvPolynomial.map f W'.polynomialY 
goal: (WeierstrassCurve.map W' f).toJacobian.polynomialY = (MvPolynomial.map f) W'.polynomialY

full_name: WeierstrassCurve.Jacobian.map_polynomialZ
code: lemma map_polynomialZ : (W'.map f).toJacobian.polynomialZ = MvPolynomial.map f W'.polynomialZ 
goal: (WeierstrassCurve.map W' f).toJacobian.polynomialZ = (MvPolynomial.map f) W'.polynomialZ

full_name: WeierstrassCurve.Jacobian.map_dblZ
code: @[simp] lemma map_dblZ : dblZ (W'.map f) (f ∘ P) = f (W'.dblZ P) 
goal: WeierstrassCurve.Jacobian.dblZ (WeierstrassCurve.map W' f) (⇑f ∘ P) = f (W'.dblZ P)

full_name: WeierstrassCurve.Jacobian.map_dblU
code: @[simp] lemma map_dblU : dblU (W'.map f) (f ∘ P) = f (W'.dblU P) 
goal: WeierstrassCurve.Jacobian.dblU (WeierstrassCurve.map W' f) (⇑f ∘ P) = f (W'.dblU P)

full_name: WeierstrassCurve.Jacobian.map_dblX
code: @[simp] lemma map_dblX : dblX (W'.map f) (f ∘ P) = f (W'.dblX P) 
goal: WeierstrassCurve.Jacobian.dblX (WeierstrassCurve.map W' f) (⇑f ∘ P) = f (W'.dblX P)

full_name: WeierstrassCurve.Jacobian.map_negDblY
code: @[simp] lemma map_negDblY : negDblY (W'.map f) (f ∘ P) = f (W'.negDblY P) 
goal: WeierstrassCurve.Jacobian.negDblY (WeierstrassCurve.map W' f) (⇑f ∘ P) = f (W'.negDblY P)

full_name: WeierstrassCurve.Jacobian.map_dblY
code: @[simp] lemma map_dblY : dblY (W'.map f) (f ∘ P) = f (W'.dblY P) 
goal: WeierstrassCurve.Jacobian.dblY (WeierstrassCurve.map W' f) (⇑f ∘ P) = f (W'.dblY P)

full_name: WeierstrassCurve.Jacobian.map_dblXYZ
code: @[simp] lemma map_dblXYZ : dblXYZ (W'.map f) (f ∘ P) = f ∘ dblXYZ W' P 
goal: WeierstrassCurve.Jacobian.dblXYZ (WeierstrassCurve.map W' f) (⇑f ∘ P) = ⇑f ∘ W'.dblXYZ P

full_name: WeierstrassCurve.Affine.Point.toJacobian
code: /-- An abbreviation for `WeierstrassCurve.Jacobian.Point.fromAffine` for dot notation. -/
abbrev WeierstrassCurve.Affine.Point.toJacobian {R : Type u} [CommRing R]
    [Nontrivial R] {W : Affine R} (P : W.Point) : W.toJacobian.Point 
goal: (WeierstrassCurve.toJacobian W).Point