[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ negY W x₁ (negY W x₁ y₁) = y₁
[PROOFSTEP]
simp only [negY]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ -(-y₁ - W.a₁ * x₁ - W.a₃) - W.a₁ * x₁ - W.a₃ = y₁
[PROOFSTEP]
ring1
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ negY (baseChange W A) (↑(algebraMap R A) x₁) (↑(algebraMap R A) y₁) = ↑(algebraMap R A) (negY W x₁ y₁)
[PROOFSTEP]
simp only [negY]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ -↑(algebraMap R A) y₁ - (baseChange W A).a₁ * ↑(algebraMap R A) x₁ - (baseChange W A).a₃ =
    ↑(algebraMap R A) (-y₁ - W.a₁ * x₁ - W.a₃)
[PROOFSTEP]
map_simp
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ -↑(algebraMap R A) y₁ - (baseChange W A).a₁ * ↑(algebraMap R A) x₁ - (baseChange W A).a₃ =
    -↑(algebraMap R A) y₁ - ↑(algebraMap R A) W.a₁ * ↑(algebraMap R A) x₁ - ↑(algebraMap R A) W.a₃
[PROOFSTEP]
rfl
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁✝ x₂ y₁✝ y₂ L : R
x₁ y₁ : A
⊢ negY (baseChange W B) (↑(algebraMap A B) x₁) (↑(algebraMap A B) y₁) = ↑(algebraMap A B) (negY (baseChange W A) x₁ y₁)
[PROOFSTEP]
rw [← baseChange_negY, baseChange_baseChange]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ eval x₁ (eval (↑C y₁) (negPolynomial W)) = negY W x₁ y₁
[PROOFSTEP]
rw [negY, sub_sub, negPolynomial]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ eval x₁ (eval (↑C y₁) (-Y - ↑C (↑C W.a₁ * Y + ↑C W.a₃))) = -y₁ - (W.a₁ * x₁ + W.a₃)
[PROOFSTEP]
eval_simp
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ XYIdeal W x₁ (↑C y₁) = XYIdeal W x₁ (linePolynomial x₁ y₁ L)
[PROOFSTEP]
simp only [XYIdeal, XClass, YClass, linePolynomial]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ span {↑(CoordinateRing.mk W) (↑C (Y - ↑C x₁)), ↑(CoordinateRing.mk W) (Y - ↑C (↑C y₁))} =
    span {↑(CoordinateRing.mk W) (↑C (Y - ↑C x₁)), ↑(CoordinateRing.mk W) (Y - ↑C (↑C L * (Y - ↑C x₁) + ↑C y₁))}
[PROOFSTEP]
rw [← span_pair_add_mul_right <| CoordinateRing.mk W <| C <| C <| -L, ← _root_.map_mul, ← map_add]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ span
      {↑(CoordinateRing.mk W) (↑C (Y - ↑C x₁)),
        ↑(CoordinateRing.mk W) (Y - ↑C (↑C y₁) + ↑C (Y - ↑C x₁) * ↑C (↑C (-L)))} =
    span {↑(CoordinateRing.mk W) (↑C (Y - ↑C x₁)), ↑(CoordinateRing.mk W) (Y - ↑C (↑C L * (Y - ↑C x₁) + ↑C y₁))}
[PROOFSTEP]
apply congr_arg (_ ∘ _ ∘ _ ∘ _)
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ Y - ↑C (↑C y₁) + ↑C (Y - ↑C x₁) * ↑C (↑C (-L)) = Y - ↑C (↑C L * (Y - ↑C x₁) + ↑C y₁)
[PROOFSTEP]
C_simp
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ Y - ↑C (↑C y₁) + (↑C Y - ↑C (↑C x₁)) * -↑C (↑C L) = Y - (↑C (↑C L) * (↑C Y - ↑C (↑C x₁)) + ↑C (↑C y₁))
[PROOFSTEP]
ring1
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ ↑C (addPolynomial W x₁ y₁ L) =
    (Y - ↑C (linePolynomial x₁ y₁ L)) * (negPolynomial W - ↑C (linePolynomial x₁ y₁ L)) + WeierstrassCurve.polynomial W
[PROOFSTEP]
rw [addPolynomial, linePolynomial, WeierstrassCurve.polynomial, negPolynomial]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ ↑C
      (eval (↑C L * (Y - ↑C x₁) + ↑C y₁)
        (Y ^ 2 + ↑C (↑C W.a₁ * Y + ↑C W.a₃) * Y - ↑C (Y ^ 3 + ↑C W.a₂ * Y ^ 2 + ↑C W.a₄ * Y + ↑C W.a₆))) =
    (Y - ↑C (↑C L * (Y - ↑C x₁) + ↑C y₁)) * (-Y - ↑C (↑C W.a₁ * Y + ↑C W.a₃) - ↑C (↑C L * (Y - ↑C x₁) + ↑C y₁)) +
      (Y ^ 2 + ↑C (↑C W.a₁ * Y + ↑C W.a₃) * Y - ↑C (Y ^ 3 + ↑C W.a₂ * Y ^ 2 + ↑C W.a₄ * Y + ↑C W.a₆))
[PROOFSTEP]
eval_simp
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ ↑C
      ((↑C L * (Y - ↑C x₁) + ↑C y₁) ^ 2 + (↑C W.a₁ * Y + ↑C W.a₃) * (↑C L * (Y - ↑C x₁) + ↑C y₁) -
        (Y ^ 3 + ↑C W.a₂ * Y ^ 2 + ↑C W.a₄ * Y + ↑C W.a₆)) =
    (Y - ↑C (↑C L * (Y - ↑C x₁) + ↑C y₁)) * (-Y - ↑C (↑C W.a₁ * Y + ↑C W.a₃) - ↑C (↑C L * (Y - ↑C x₁) + ↑C y₁)) +
      (Y ^ 2 + ↑C (↑C W.a₁ * Y + ↑C W.a₃) * Y - ↑C (Y ^ 3 + ↑C W.a₂ * Y ^ 2 + ↑C W.a₄ * Y + ↑C W.a₆))
[PROOFSTEP]
C_simp
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ (↑C (↑C L) * (↑C Y - ↑C (↑C x₁)) + ↑C (↑C y₁)) ^ 2 +
        (↑C (↑C W.a₁) * ↑C Y + ↑C (↑C W.a₃)) * (↑C (↑C L) * (↑C Y - ↑C (↑C x₁)) + ↑C (↑C y₁)) -
      (↑C Y ^ 3 + ↑C (↑C W.a₂) * ↑C Y ^ 2 + ↑C (↑C W.a₄) * ↑C Y + ↑C (↑C W.a₆)) =
    (Y - (↑C (↑C L) * (↑C Y - ↑C (↑C x₁)) + ↑C (↑C y₁))) *
        (-Y - (↑C (↑C W.a₁) * ↑C Y + ↑C (↑C W.a₃)) - (↑C (↑C L) * (↑C Y - ↑C (↑C x₁)) + ↑C (↑C y₁))) +
      (Y ^ 2 + (↑C (↑C W.a₁) * ↑C Y + ↑C (↑C W.a₃)) * Y -
        (↑C Y ^ 3 + ↑C (↑C W.a₂) * ↑C Y ^ 2 + ↑C (↑C W.a₄) * ↑C Y + ↑C (↑C W.a₆)))
[PROOFSTEP]
ring1
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ ↑C (addPolynomial W x₁ y₁ L) - (Y - ↑C (linePolynomial x₁ y₁ L)) * (negPolynomial W - ↑C (linePolynomial x₁ y₁ L)) =
    WeierstrassCurve.polynomial W * 1
[PROOFSTEP]
rw [W.C_addPolynomial, add_sub_cancel', mul_one]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ addPolynomial W x₁ y₁ L =
    -Cubic.toPoly
        { 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₆) }
[PROOFSTEP]
rw [addPolynomial, linePolynomial, WeierstrassCurve.polynomial, Cubic.toPoly]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ eval (↑C L * (Y - ↑C x₁) + ↑C y₁)
      (Y ^ 2 + ↑C (↑C W.a₁ * Y + ↑C W.a₃) * Y - ↑C (Y ^ 3 + ↑C W.a₂ * Y ^ 2 + ↑C W.a₄ * Y + ↑C W.a₆)) =
    -(↑C
                { 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₆) }.a *
              Y ^ 3 +
            ↑C
                { 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₆) }.b *
              Y ^ 2 +
          ↑C
              { 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₆) }.c *
            Y +
        ↑C
          { 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₆) }.d)
[PROOFSTEP]
eval_simp
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ (↑C L * (Y - ↑C x₁) + ↑C y₁) ^ 2 + (↑C W.a₁ * Y + ↑C W.a₃) * (↑C L * (Y - ↑C x₁) + ↑C y₁) -
      (Y ^ 3 + ↑C W.a₂ * Y ^ 2 + ↑C W.a₄ * Y + ↑C W.a₆) =
    -(↑C 1 * Y ^ 3 + ↑C (-L ^ 2 - W.a₁ * L + W.a₂) * Y ^ 2 +
          ↑C (2 * x₁ * L ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * L + (-W.a₁ * y₁ + W.a₄)) * Y +
        ↑C (-x₁ ^ 2 * L ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * L - (y₁ ^ 2 + W.a₃ * y₁ - W.a₆)))
[PROOFSTEP]
C_simp
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ (↑C L * (Y - ↑C x₁) + ↑C y₁) ^ 2 + (↑C W.a₁ * Y + ↑C W.a₃) * (↑C L * (Y - ↑C x₁) + ↑C y₁) -
      (Y ^ 3 + ↑C W.a₂ * Y ^ 2 + ↑C W.a₄ * Y + ↑C W.a₆) =
    -(1 * Y ^ 3 + (-↑C L ^ 2 - ↑C W.a₁ * ↑C L + ↑C W.a₂) * Y ^ 2 +
          (2 * ↑C x₁ * ↑C L ^ 2 + (↑C W.a₁ * ↑C x₁ - 2 * ↑C y₁ - ↑C W.a₃) * ↑C L + (-↑C W.a₁ * ↑C y₁ + ↑C W.a₄)) * Y +
        (-↑C x₁ ^ 2 * ↑C L ^ 2 + (2 * ↑C x₁ * ↑C y₁ + ↑C W.a₃ * ↑C x₁) * ↑C L -
          (↑C y₁ ^ 2 + ↑C W.a₃ * ↑C y₁ - ↑C W.a₆)))
[PROOFSTEP]
ring1
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ addX (baseChange W A) (↑(algebraMap R A) x₁) (↑(algebraMap R A) x₂) (↑(algebraMap R A) L) =
    ↑(algebraMap R A) (addX W x₁ x₂ L)
[PROOFSTEP]
simp only [addX]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ ↑(algebraMap R A) L ^ 2 + (baseChange W A).a₁ * ↑(algebraMap R A) L - (baseChange W A).a₂ - ↑(algebraMap R A) x₁ -
      ↑(algebraMap R A) x₂ =
    ↑(algebraMap R A) (L ^ 2 + W.a₁ * L - W.a₂ - x₁ - x₂)
[PROOFSTEP]
map_simp
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ ↑(algebraMap R A) L ^ 2 + (baseChange W A).a₁ * ↑(algebraMap R A) L - (baseChange W A).a₂ - ↑(algebraMap R A) x₁ -
      ↑(algebraMap R A) x₂ =
    ↑(algebraMap R A) L ^ 2 + ↑(algebraMap R A) W.a₁ * ↑(algebraMap R A) L - ↑(algebraMap R A) W.a₂ -
        ↑(algebraMap R A) x₁ -
      ↑(algebraMap R A) x₂
[PROOFSTEP]
rfl
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁✝ x₂✝ y₁ y₂ L✝ : R
x₁ x₂ L : A
⊢ addX (baseChange W B) (↑(algebraMap A B) x₁) (↑(algebraMap A B) x₂) (↑(algebraMap A B) L) =
    ↑(algebraMap A B) (addX (baseChange W A) x₁ x₂ L)
[PROOFSTEP]
rw [← baseChange_addX, baseChange_baseChange]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ addY' (baseChange W A) (↑(algebraMap R A) x₁) (↑(algebraMap R A) x₂) (↑(algebraMap R A) y₁) (↑(algebraMap R A) L) =
    ↑(algebraMap R A) (addY' W x₁ x₂ y₁ L)
[PROOFSTEP]
simp only [addY', baseChange_addX]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ ↑(algebraMap R A) L * (↑(algebraMap R A) (addX W x₁ x₂ L) - ↑(algebraMap R A) x₁) + ↑(algebraMap R A) y₁ =
    ↑(algebraMap R A) (L * (addX W x₁ x₂ L - x₁) + y₁)
[PROOFSTEP]
map_simp
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁✝ x₂✝ y₁✝ y₂ L✝ : R
x₁ x₂ y₁ L : A
⊢ addY' (baseChange W B) (↑(algebraMap A B) x₁) (↑(algebraMap A B) x₂) (↑(algebraMap A B) y₁) (↑(algebraMap A B) L) =
    ↑(algebraMap A B) (addY' (baseChange W A) x₁ x₂ y₁ L)
[PROOFSTEP]
rw [← baseChange_addY', baseChange_baseChange]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ addY (baseChange W A) (↑(algebraMap R A) x₁) (↑(algebraMap R A) x₂) (↑(algebraMap R A) y₁) (↑(algebraMap R A) L) =
    ↑(algebraMap R A) (addY W x₁ x₂ y₁ L)
[PROOFSTEP]
simp only [addY, baseChange_addY', baseChange_addX, baseChange_negY]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁✝ x₂✝ y₁✝ y₂ L✝ : R
x₁ x₂ y₁ L : A
⊢ addY (baseChange W B) (↑(algebraMap A B) x₁) (↑(algebraMap A B) x₂) (↑(algebraMap A B) y₁) (↑(algebraMap A B) L) =
    ↑(algebraMap A B) (addY (baseChange W A) x₁ x₂ y₁ L)
[PROOFSTEP]
rw [← baseChange_addY, baseChange_baseChange]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ XYIdeal W (addX W x₁ x₂ L) (↑C (addY W x₁ x₂ y₁ L)) =
    span {↑(CoordinateRing.mk W) (negPolynomial W - ↑C (linePolynomial x₁ y₁ L))} ⊔ XIdeal W (addX W x₁ x₂ L)
[PROOFSTEP]
simp only [XYIdeal, XIdeal, XClass, YClass, addY, addY', negY, negPolynomial, linePolynomial]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ span
      {↑(CoordinateRing.mk W) (↑C (Y - ↑C (addX W x₁ x₂ L))),
        ↑(CoordinateRing.mk W) (Y - ↑C (↑C (-(L * (addX W x₁ x₂ L - x₁) + y₁) - W.a₁ * addX W x₁ x₂ L - W.a₃)))} =
    span {↑(CoordinateRing.mk W) (-Y - ↑C (↑C W.a₁ * Y + ↑C W.a₃) - ↑C (↑C L * (Y - ↑C x₁) + ↑C y₁))} ⊔
      span {↑(CoordinateRing.mk W) (↑C (Y - ↑C (addX W x₁ x₂ L)))}
[PROOFSTEP]
rw [sub_sub <| -Y, neg_sub_left Y, map_neg, span_singleton_neg, sup_comm, ← span_insert, ←
  span_pair_add_mul_right <| CoordinateRing.mk W <| C <| C <| W.a₁ + L, ← _root_.map_mul, ← map_add]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ span
      {↑(CoordinateRing.mk W) (↑C (Y - ↑C (addX W x₁ x₂ L))),
        ↑(CoordinateRing.mk W)
          (Y - ↑C (↑C (-(L * (addX W x₁ x₂ L - x₁) + y₁) - W.a₁ * addX W x₁ x₂ L - W.a₃)) +
            ↑C (Y - ↑C (addX W x₁ x₂ L)) * ↑C (↑C (W.a₁ + L)))} =
    span
      {↑(CoordinateRing.mk W) (↑C (Y - ↑C (addX W x₁ x₂ L))),
        ↑(CoordinateRing.mk W) (↑C (↑C W.a₁ * Y + ↑C W.a₃) + ↑C (↑C L * (Y - ↑C x₁) + ↑C y₁) + Y)}
[PROOFSTEP]
apply congr_arg (_ ∘ _ ∘ _ ∘ _)
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ Y - ↑C (↑C (-(L * (addX W x₁ x₂ L - x₁) + y₁) - W.a₁ * addX W x₁ x₂ L - W.a₃)) +
      ↑C (Y - ↑C (addX W x₁ x₂ L)) * ↑C (↑C (W.a₁ + L)) =
    ↑C (↑C W.a₁ * Y + ↑C W.a₃) + ↑C (↑C L * (Y - ↑C x₁) + ↑C y₁) + Y
[PROOFSTEP]
C_simp
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ Y -
        (-(↑C (↑C L) * (↑C (↑C (addX W x₁ x₂ L)) - ↑C (↑C x₁)) + ↑C (↑C y₁)) - ↑C (↑C W.a₁) * ↑C (↑C (addX W x₁ x₂ L)) -
          ↑C (↑C W.a₃)) +
      (↑C Y - ↑C (↑C (addX W x₁ x₂ L))) * (↑C (↑C W.a₁) + ↑C (↑C L)) =
    ↑C (↑C W.a₁) * ↑C Y + ↑C (↑C W.a₃) + (↑C (↑C L) * (↑C Y - ↑C (↑C x₁)) + ↑C (↑C y₁)) + Y
[PROOFSTEP]
ring1
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ WeierstrassCurve.equation W (addX W x₁ x₂ L) (addY' W x₁ x₂ y₁ L) ↔
    eval (addX W x₁ x₂ L) (addPolynomial W x₁ y₁ L) = 0
[PROOFSTEP]
rw [WeierstrassCurve.equation, addY', addPolynomial, linePolynomial, WeierstrassCurve.polynomial]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ eval (addX W x₁ x₂ L)
        (eval (↑C (L * (addX W x₁ x₂ L - x₁) + y₁))
          (Y ^ 2 + ↑C (↑C W.a₁ * Y + ↑C W.a₃) * Y - ↑C (Y ^ 3 + ↑C W.a₂ * Y ^ 2 + ↑C W.a₄ * Y + ↑C W.a₆))) =
      0 ↔
    eval (addX W x₁ x₂ L)
        (eval (↑C L * (Y - ↑C x₁) + ↑C y₁)
          (Y ^ 2 + ↑C (↑C W.a₁ * Y + ↑C W.a₃) * Y - ↑C (Y ^ 3 + ↑C W.a₂ * Y ^ 2 + ↑C W.a₄ * Y + ↑C W.a₆))) =
      0
[PROOFSTEP]
eval_simp
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
hx' : WeierstrassCurve.equation W (addX W x₁ x₂ L) (addY' W x₁ x₂ y₁ L)
hx : eval (addX W x₁ x₂ L) (↑derivative (addPolynomial W x₁ y₁ L)) ≠ 0
⊢ WeierstrassCurve.nonsingular W (addX W x₁ x₂ L) (addY' W x₁ x₂ y₁ L)
[PROOFSTEP]
rw [WeierstrassCurve.nonsingular, and_iff_right hx', addY', WeierstrassCurve.polynomialX, WeierstrassCurve.polynomialY]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
hx' : WeierstrassCurve.equation W (addX W x₁ x₂ L) (addY' W x₁ x₂ y₁ L)
hx : eval (addX W x₁ x₂ L) (↑derivative (addPolynomial W x₁ y₁ L)) ≠ 0
⊢ eval (addX W x₁ x₂ L)
        (eval (↑C (L * (addX W x₁ x₂ L - x₁) + y₁))
          (↑C (↑C W.a₁) * Y - ↑C (↑C 3 * Y ^ 2 + ↑C (2 * W.a₂) * Y + ↑C W.a₄))) ≠
      0 ∨
    eval (addX W x₁ x₂ L) (eval (↑C (L * (addX W x₁ x₂ L - x₁) + y₁)) (↑C (↑C 2) * Y + ↑C (↑C W.a₁ * Y + ↑C W.a₃))) ≠ 0
[PROOFSTEP]
eval_simp
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
hx' : WeierstrassCurve.equation W (addX W x₁ x₂ L) (addY' W x₁ x₂ y₁ L)
hx : eval (addX W x₁ x₂ L) (↑derivative (addPolynomial W x₁ y₁ L)) ≠ 0
⊢ W.a₁ * (L * (addX W x₁ x₂ L - x₁) + y₁) - (3 * addX W x₁ x₂ L ^ 2 + 2 * W.a₂ * addX W x₁ x₂ L + W.a₄) ≠ 0 ∨
    2 * (L * (addX W x₁ x₂ L - x₁) + y₁) + (W.a₁ * addX W x₁ x₂ L + W.a₃) ≠ 0
[PROOFSTEP]
contrapose! hx
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
hx' : WeierstrassCurve.equation W (addX W x₁ x₂ L) (addY' W x₁ x₂ y₁ L)
hx :
  W.a₁ * (L * (addX W x₁ x₂ L - x₁) + y₁) - (3 * addX W x₁ x₂ L ^ 2 + 2 * W.a₂ * addX W x₁ x₂ L + W.a₄) = 0 ∧
    2 * (L * (addX W x₁ x₂ L - x₁) + y₁) + (W.a₁ * addX W x₁ x₂ L + W.a₃) = 0
⊢ eval (addX W x₁ x₂ L) (↑derivative (addPolynomial W x₁ y₁ L)) = 0
[PROOFSTEP]
rw [addPolynomial, linePolynomial, WeierstrassCurve.polynomial]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
hx' : WeierstrassCurve.equation W (addX W x₁ x₂ L) (addY' W x₁ x₂ y₁ L)
hx :
  W.a₁ * (L * (addX W x₁ x₂ L - x₁) + y₁) - (3 * addX W x₁ x₂ L ^ 2 + 2 * W.a₂ * addX W x₁ x₂ L + W.a₄) = 0 ∧
    2 * (L * (addX W x₁ x₂ L - x₁) + y₁) + (W.a₁ * addX W x₁ x₂ L + W.a₃) = 0
⊢ eval (addX W x₁ x₂ L)
      (↑derivative
        (eval (↑C L * (Y - ↑C x₁) + ↑C y₁)
          (Y ^ 2 + ↑C (↑C W.a₁ * Y + ↑C W.a₃) * Y - ↑C (Y ^ 3 + ↑C W.a₂ * Y ^ 2 + ↑C W.a₄ * Y + ↑C W.a₆)))) =
    0
[PROOFSTEP]
eval_simp
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
hx' : WeierstrassCurve.equation W (addX W x₁ x₂ L) (addY' W x₁ x₂ y₁ L)
hx :
  W.a₁ * (L * (addX W x₁ x₂ L - x₁) + y₁) - (3 * addX W x₁ x₂ L ^ 2 + 2 * W.a₂ * addX W x₁ x₂ L + W.a₄) = 0 ∧
    2 * (L * (addX W x₁ x₂ L - x₁) + y₁) + (W.a₁ * addX W x₁ x₂ L + W.a₃) = 0
⊢ eval (addX W x₁ x₂ L)
      (↑derivative
        ((↑C L * (Y - ↑C x₁) + ↑C y₁) ^ 2 + (↑C W.a₁ * Y + ↑C W.a₃) * (↑C L * (Y - ↑C x₁) + ↑C y₁) -
          (Y ^ 3 + ↑C W.a₂ * Y ^ 2 + ↑C W.a₄ * Y + ↑C W.a₆))) =
    0
[PROOFSTEP]
derivative_simp
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
hx' : WeierstrassCurve.equation W (addX W x₁ x₂ L) (addY' W x₁ x₂ y₁ L)
hx :
  W.a₁ * (L * (addX W x₁ x₂ L - x₁) + y₁) - (3 * addX W x₁ x₂ L ^ 2 + 2 * W.a₂ * addX W x₁ x₂ L + W.a₄) = 0 ∧
    2 * (L * (addX W x₁ x₂ L - x₁) + y₁) + (W.a₁ * addX W x₁ x₂ L + W.a₃) = 0
⊢ eval (addX W x₁ x₂ L)
      (↑C 2 * (↑C L * (Y - ↑C x₁) + ↑C y₁) * (0 * (Y - ↑C x₁) + ↑C L * (1 - 0) + 0) +
          ((0 * Y + ↑C W.a₁ * 1 + 0) * (↑C L * (Y - ↑C x₁) + ↑C y₁) +
            (↑C W.a₁ * Y + ↑C W.a₃) * (0 * (Y - ↑C x₁) + ↑C L * (1 - 0) + 0)) -
        (↑C ↑3 * Y ^ (3 - 1) + (0 * Y ^ 2 + ↑C W.a₂ * (↑C 2 * Y * 1)) + (0 * Y + ↑C W.a₄ * 1) + 0)) =
    0
[PROOFSTEP]
simp only [zero_add, add_zero, sub_zero, zero_mul, mul_one]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
hx' : WeierstrassCurve.equation W (addX W x₁ x₂ L) (addY' W x₁ x₂ y₁ L)
hx :
  W.a₁ * (L * (addX W x₁ x₂ L - x₁) + y₁) - (3 * addX W x₁ x₂ L ^ 2 + 2 * W.a₂ * addX W x₁ x₂ L + W.a₄) = 0 ∧
    2 * (L * (addX W x₁ x₂ L - x₁) + y₁) + (W.a₁ * addX W x₁ x₂ L + W.a₃) = 0
⊢ eval (addX W x₁ x₂ L)
      (↑C 2 * (↑C L * (Y - ↑C x₁) + ↑C y₁) * ↑C L +
          (↑C W.a₁ * (↑C L * (Y - ↑C x₁) + ↑C y₁) + (↑C W.a₁ * Y + ↑C W.a₃) * ↑C L) -
        (↑C ↑3 * Y ^ (3 - 1) + ↑C W.a₂ * (↑C 2 * Y) + ↑C W.a₄)) =
    0
[PROOFSTEP]
eval_simp
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
hx' : WeierstrassCurve.equation W (addX W x₁ x₂ L) (addY' W x₁ x₂ y₁ L)
hx :
  W.a₁ * (L * (addX W x₁ x₂ L - x₁) + y₁) - (3 * addX W x₁ x₂ L ^ 2 + 2 * W.a₂ * addX W x₁ x₂ L + W.a₄) = 0 ∧
    2 * (L * (addX W x₁ x₂ L - x₁) + y₁) + (W.a₁ * addX W x₁ x₂ L + W.a₃) = 0
⊢ 2 * (L * (addX W x₁ x₂ L - x₁) + y₁) * L +
        (W.a₁ * (L * (addX W x₁ x₂ L - x₁) + y₁) + (W.a₁ * addX W x₁ x₂ L + W.a₃) * L) -
      (↑3 * addX W x₁ x₂ L ^ (3 - 1) + W.a₂ * (2 * addX W x₁ x₂ L) + W.a₄) =
    0
[PROOFSTEP]
linear_combination (norm := (norm_num1; ring1)) hx.left + L * hx.right
[GOAL]
case a
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
hx' : WeierstrassCurve.equation W (addX W x₁ x₂ L) (addY' W x₁ x₂ y₁ L)
hx :
  W.a₁ * (L * (addX W x₁ x₂ L - x₁) + y₁) - (3 * addX W x₁ x₂ L ^ 2 + 2 * W.a₂ * addX W x₁ x₂ L + W.a₄) = 0 ∧
    2 * (L * (addX W x₁ x₂ L - x₁) + y₁) + (W.a₁ * addX W x₁ x₂ L + W.a₃) = 0
⊢ 2 * (L * (addX W x₁ x₂ L - x₁) + y₁) * L +
            (W.a₁ * (L * (addX W x₁ x₂ L - x₁) + y₁) + (W.a₁ * addX W x₁ x₂ L + W.a₃) * L) -
          (↑3 * addX W x₁ x₂ L ^ (3 - 1) + W.a₂ * (2 * addX W x₁ x₂ L) + W.a₄) -
        0 -
      (W.a₁ * (L * (addX W x₁ x₂ L - x₁) + y₁) - (3 * addX W x₁ x₂ L ^ 2 + 2 * W.a₂ * addX W x₁ x₂ L + W.a₄) +
          L * (2 * (L * (addX W x₁ x₂ L - x₁) + y₁) + (W.a₁ * addX W x₁ x₂ L + W.a₃)) -
        (0 + L * 0)) =
    0
[PROOFSTEP]
norm_num1
[GOAL]
case a
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
hx' : WeierstrassCurve.equation W (addX W x₁ x₂ L) (addY' W x₁ x₂ y₁ L)
hx :
  W.a₁ * (L * (addX W x₁ x₂ L - x₁) + y₁) - (3 * addX W x₁ x₂ L ^ 2 + 2 * W.a₂ * addX W x₁ x₂ L + W.a₄) = 0 ∧
    2 * (L * (addX W x₁ x₂ L - x₁) + y₁) + (W.a₁ * addX W x₁ x₂ L + W.a₃) = 0
⊢ 2 * (L * (addX W x₁ x₂ L - x₁) + y₁) * L +
            (W.a₁ * (L * (addX W x₁ x₂ L - x₁) + y₁) + (W.a₁ * addX W x₁ x₂ L + W.a₃) * L) -
          (3 * addX W x₁ x₂ L ^ 2 + W.a₂ * (2 * addX W x₁ x₂ L) + W.a₄) -
        0 -
      (W.a₁ * (L * (addX W x₁ x₂ L - x₁) + y₁) - (3 * addX W x₁ x₂ L ^ 2 + 2 * W.a₂ * addX W x₁ x₂ L + W.a₄) +
          L * (2 * (L * (addX W x₁ x₂ L - x₁) + y₁) + (W.a₁ * addX W x₁ x₂ L + W.a₃)) -
        (0 + L * 0)) =
    0
[PROOFSTEP]
ring1
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ WeierstrassCurve.equation W x₁ (negY W x₁ y₁) ↔ WeierstrassCurve.equation W x₁ y₁
[PROOFSTEP]
rw [equation_iff, equation_iff, negY]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ (-y₁ - W.a₁ * x₁ - W.a₃) ^ 2 + W.a₁ * x₁ * (-y₁ - W.a₁ * x₁ - W.a₃) + W.a₃ * (-y₁ - W.a₁ * x₁ - W.a₃) =
      x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆ ↔
    y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
[PROOFSTEP]
congr! 1
[GOAL]
case a.h.e'_2
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ (-y₁ - W.a₁ * x₁ - W.a₃) ^ 2 + W.a₁ * x₁ * (-y₁ - W.a₁ * x₁ - W.a₃) + W.a₃ * (-y₁ - W.a₁ * x₁ - W.a₃) =
    y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁
[PROOFSTEP]
ring1
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ WeierstrassCurve.nonsingular W x₁ (negY W x₁ y₁) ↔ WeierstrassCurve.nonsingular W x₁ y₁
[PROOFSTEP]
rw [nonsingular_iff, equation_neg_iff, ← negY, negY_negY, ← @ne_comm _ y₁, nonsingular_iff]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ WeierstrassCurve.equation W x₁ y₁ ∧ (W.a₁ * negY W x₁ y₁ ≠ 3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ ∨ y₁ ≠ negY W x₁ y₁) ↔
    WeierstrassCurve.equation W x₁ y₁ ∧ (W.a₁ * y₁ ≠ 3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ ∨ y₁ ≠ -y₁ - W.a₁ * x₁ - W.a₃)
[PROOFSTEP]
exact
  and_congr_right' <|
    (iff_congr not_and_or.symm not_and_or.symm).mpr <| not_congr <| and_congr_left fun h => by rw [← h]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
h : y₁ = negY W x₁ y₁
⊢ W.a₁ * negY W x₁ y₁ = 3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ ↔ W.a₁ * y₁ = 3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄
[PROOFSTEP]
rw [← h]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ ∀ (x : Point W), - -x = x
[PROOFSTEP]
rintro (_ | _)
[GOAL]
case zero
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L : R
⊢ - -zero = zero
[PROOFSTEP]
simp [zero_def]
[GOAL]
case some
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L x✝ y✝ : R
h✝ : WeierstrassCurve.nonsingular W x✝ y✝
⊢ - -some h✝ = some h✝
[PROOFSTEP]
simp [zero_def]
[GOAL]
case some
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
A : Type v
inst✝⁵ : CommRing A
inst✝⁴ : Algebra R A
B : Type w
inst✝³ : CommRing B
inst✝² : Algebra R B
inst✝¹ : Algebra A B
inst✝ : IsScalarTower R A B
x₁ x₂ y₁ y₂ L x✝ y✝ : R
h✝ : WeierstrassCurve.nonsingular W x✝ y✝
⊢ W.a₃ - (-y✝ - W.a₁ * x✝) - W.a₁ * x✝ - W.a₃ = y✝
[PROOFSTEP]
ring1
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
hy : y₁ = negY W x₂ y₂
⊢ slope W x₁ x₂ y₁ y₂ = 0
[PROOFSTEP]
rw [slope, if_pos hx, if_pos hy]
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
hy : y₁ ≠ negY W x₂ y₂
⊢ slope W x₁ x₂ y₁ y₂ = (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)
[PROOFSTEP]
rw [slope, if_pos hx, if_neg hy]
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ ≠ x₂
⊢ slope W x₁ x₂ y₁ y₂ = (y₁ - y₂) / (x₁ - x₂)
[PROOFSTEP]
rw [slope, if_neg hx]
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
hy : y₁ ≠ negY W x₂ y₂
⊢ slope W x₁ x₂ y₁ y₂ =
    -eval x₁ (eval (↑C y₁) (WeierstrassCurve.polynomialX W)) / eval x₁ (eval (↑C y₁) (WeierstrassCurve.polynomialY W))
[PROOFSTEP]
rw [slope_of_Y_ne hx hy, eval_polynomialX, neg_sub]
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
hy : y₁ ≠ negY W x₂ y₂
⊢ (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁) =
    (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / eval x₁ (eval (↑C y₁) (WeierstrassCurve.polynomialY W))
[PROOFSTEP]
congr 1
[GOAL]
case e_a
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
hy : y₁ ≠ negY W x₂ y₂
⊢ y₁ - negY W x₁ y₁ = eval x₁ (eval (↑C y₁) (WeierstrassCurve.polynomialY W))
[PROOFSTEP]
rw [negY, eval_polynomialY]
[GOAL]
case e_a
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
hy : y₁ ≠ negY W x₂ y₂
⊢ y₁ - (-y₁ - W.a₁ * x₁ - W.a₃) = 2 * y₁ + W.a₁ * x₁ + W.a₃
[PROOFSTEP]
ring1
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ slope (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₁) (↑(algebraMap F K) y₂) =
    ↑(algebraMap F K) (slope W x₁ x₂ y₁ y₂)
[PROOFSTEP]
by_cases hx : x₁ = x₂
[GOAL]
case pos
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
⊢ slope (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₁) (↑(algebraMap F K) y₂) =
    ↑(algebraMap F K) (slope W x₁ x₂ y₁ y₂)
[PROOFSTEP]
by_cases hy : y₁ = W.negY x₂ y₂
[GOAL]
case pos
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
hy : y₁ = negY W x₂ y₂
⊢ slope (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₁) (↑(algebraMap F K) y₂) =
    ↑(algebraMap F K) (slope W x₁ x₂ y₁ y₂)
[PROOFSTEP]
rw [slope_of_Y_eq hx hy, slope_of_Y_eq <| congr_arg _ hx, map_zero]
[GOAL]
case pos
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
hy : y₁ = negY W x₂ y₂
⊢ ↑(algebraMap F K) y₁ = negY (baseChange W K) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₂)
[PROOFSTEP]
rw [hy, baseChange_negY]
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
hy : ¬y₁ = negY W x₂ y₂
⊢ slope (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₁) (↑(algebraMap F K) y₂) =
    ↑(algebraMap F K) (slope W x₁ x₂ y₁ y₂)
[PROOFSTEP]
rw [slope_of_Y_ne hx hy, slope_of_Y_ne <| congr_arg _ hx]
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
hy : ¬y₁ = negY W x₂ y₂
⊢ (3 * ↑(algebraMap F K) x₁ ^ 2 + 2 * (baseChange W K).a₂ * ↑(algebraMap F K) x₁ + (baseChange W K).a₄ -
        (baseChange W K).a₁ * ↑(algebraMap F K) y₁) /
      (↑(algebraMap F K) y₁ - negY (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) y₁)) =
    ↑(algebraMap F K) ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁))
[PROOFSTEP]
map_simp
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
hy : ¬y₁ = negY W x₂ y₂
⊢ (3 * ↑(algebraMap F K) x₁ ^ 2 + 2 * (baseChange W K).a₂ * ↑(algebraMap F K) x₁ + (baseChange W K).a₄ -
        (baseChange W K).a₁ * ↑(algebraMap F K) y₁) /
      (↑(algebraMap F K) y₁ - negY (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) y₁)) =
    (3 * ↑(algebraMap F K) x₁ ^ 2 + 2 * ↑(algebraMap F K) W.a₂ * ↑(algebraMap F K) x₁ + ↑(algebraMap F K) W.a₄ -
        ↑(algebraMap F K) W.a₁ * ↑(algebraMap F K) y₁) /
      (↑(algebraMap F K) y₁ - ↑(algebraMap F K) (negY W x₁ y₁))
[PROOFSTEP]
simp only [baseChange_negY]
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
hy : ¬y₁ = negY W x₂ y₂
⊢ (3 * ↑(algebraMap F K) x₁ ^ 2 + 2 * (baseChange W K).a₂ * ↑(algebraMap F K) x₁ + (baseChange W K).a₄ -
        (baseChange W K).a₁ * ↑(algebraMap F K) y₁) /
      (↑(algebraMap F K) y₁ - ↑(algebraMap F K) (negY W x₁ y₁)) =
    (3 * ↑(algebraMap F K) x₁ ^ 2 + 2 * ↑(algebraMap F K) W.a₂ * ↑(algebraMap F K) x₁ + ↑(algebraMap F K) W.a₄ -
        ↑(algebraMap F K) W.a₁ * ↑(algebraMap F K) y₁) /
      (↑(algebraMap F K) y₁ - ↑(algebraMap F K) (negY W x₁ y₁))
[PROOFSTEP]
rfl
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
hy : ¬y₁ = negY W x₂ y₂
⊢ ↑(algebraMap F K) y₁ ≠ negY (baseChange W K) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₂)
[PROOFSTEP]
rw [baseChange_negY]
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
hy : ¬y₁ = negY W x₂ y₂
⊢ ↑(algebraMap F K) y₁ ≠ ↑(algebraMap F K) (negY W x₂ y₂)
[PROOFSTEP]
contrapose! hy
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
hy : ↑(algebraMap F K) y₁ = ↑(algebraMap F K) (negY W x₂ y₂)
⊢ y₁ = negY W x₂ y₂
[PROOFSTEP]
exact NoZeroSMulDivisors.algebraMap_injective F K hy
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : ¬x₁ = x₂
⊢ slope (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₁) (↑(algebraMap F K) y₂) =
    ↑(algebraMap F K) (slope W x₁ x₂ y₁ y₂)
[PROOFSTEP]
rw [slope_of_X_ne hx, slope_of_X_ne]
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : ¬x₁ = x₂
⊢ (↑(algebraMap F K) y₁ - ↑(algebraMap F K) y₂) / (↑(algebraMap F K) x₁ - ↑(algebraMap F K) x₂) =
    ↑(algebraMap F K) ((y₁ - y₂) / (x₁ - x₂))
[PROOFSTEP]
map_simp
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : ¬x₁ = x₂
⊢ ↑(algebraMap F K) x₁ ≠ ↑(algebraMap F K) x₂
[PROOFSTEP]
contrapose! hx
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : ↑(algebraMap F K) x₁ = ↑(algebraMap F K) x₂
⊢ x₁ = x₂
[PROOFSTEP]
exact NoZeroSMulDivisors.algebraMap_injective F K hx
[GOAL]
F✝ : Type u
inst✝⁹ : Field F✝
W✝ : WeierstrassCurve F✝
K✝ : Type v
inst✝⁸ : Field K✝
inst✝⁷ : Algebra F✝ K✝
x₁✝ x₂✝ y₁✝ y₂✝ : F✝
h₁ : WeierstrassCurve.nonsingular W✝ x₁✝ y₁✝
h₂ : WeierstrassCurve.nonsingular W✝ x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W✝ x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W✝ x₂✝ y₂✝
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ x₂ y₁ y₂ : F
⊢ slope (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₁) (↑(algebraMap F K) y₂) =
    ↑(algebraMap F K) (slope (baseChange W F) x₁ x₂ y₁ y₂)
[PROOFSTEP]
rw [← baseChange_slope, baseChange_baseChange]
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
⊢ y₁ = y₂ ∨ y₁ = negY W x₂ y₂
[PROOFSTEP]
rw [equation_iff] at h₁' h₂'
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
h₂' : y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ = x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆
hx : x₁ = x₂
⊢ y₁ = y₂ ∨ y₁ = negY W x₂ y₂
[PROOFSTEP]
rw [← sub_eq_zero, ← @sub_eq_zero _ _ y₁, ← mul_eq_zero, negY]
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
h₂' : y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ = x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆
hx : x₁ = x₂
⊢ (y₁ - y₂) * (y₁ - (-y₂ - W.a₁ * x₂ - W.a₃)) = 0
[PROOFSTEP]
linear_combination (norm := (rw [hx]; ring1)) h₁' - h₂'
[GOAL]
case a
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
h₂' : y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ = x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆
hx : x₁ = x₂
⊢ (y₁ - y₂) * (y₁ - (-y₂ - W.a₁ * x₂ - W.a₃)) - 0 -
      (y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ - (y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂) -
        (x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆ - (x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆))) =
    0
[PROOFSTEP]
rw [hx]
[GOAL]
case a
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
h₂' : y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ = x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆
hx : x₁ = x₂
⊢ (y₁ - y₂) * (y₁ - (-y₂ - W.a₁ * x₂ - W.a₃)) - 0 -
      (y₁ ^ 2 + W.a₁ * x₂ * y₁ + W.a₃ * y₁ - (y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂) -
        (x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆ - (x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆))) =
    0
[PROOFSTEP]
ring1
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ XYIdeal W x₂ (↑C y₂) = XYIdeal W x₂ (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))
[PROOFSTEP]
clear h₂
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ XYIdeal W x₂ (↑C y₂) = XYIdeal W x₂ (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))
[PROOFSTEP]
have hy₂ : y₂ = (linePolynomial x₁ y₁ <| W.slope x₁ x₂ y₁ y₂).eval x₂ :=
  by
  by_cases hx : x₁ = x₂
  · rcases hx, Y_eq_of_Y_ne h₁' h₂' hx <| hxy hx with ⟨rfl, rfl⟩
    field_simp [linePolynomial, sub_ne_zero_of_ne (hxy rfl)]
  · field_simp [linePolynomial, slope_of_X_ne hx, sub_ne_zero_of_ne hx]
    ring1
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ y₂ = eval x₂ (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))
[PROOFSTEP]
by_cases hx : x₁ = x₂
[GOAL]
case pos
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx : x₁ = x₂
⊢ y₂ = eval x₂ (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))
[PROOFSTEP]
rcases hx, Y_eq_of_Y_ne h₁' h₂' hx <| hxy hx with ⟨rfl, rfl⟩
[GOAL]
case pos
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' h₂' : WeierstrassCurve.equation W x₁ y₁
hxy : x₁ = x₁ → y₁ ≠ negY W x₁ y₁
⊢ y₁ = eval x₁ (linePolynomial x₁ y₁ (slope W x₁ x₁ y₁ y₁))
[PROOFSTEP]
field_simp [linePolynomial, sub_ne_zero_of_ne (hxy rfl)]
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx : ¬x₁ = x₂
⊢ y₂ = eval x₂ (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))
[PROOFSTEP]
field_simp [linePolynomial, slope_of_X_ne hx, sub_ne_zero_of_ne hx]
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx : ¬x₁ = x₂
⊢ y₂ * (x₁ - x₂) = (y₁ - y₂) * (x₂ - x₁) + y₁ * (x₁ - x₂)
[PROOFSTEP]
ring1
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hy₂ : y₂ = eval x₂ (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))
⊢ XYIdeal W x₂ (↑C y₂) = XYIdeal W x₂ (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))
[PROOFSTEP]
nth_rw 1 [hy₂]
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hy₂ : y₂ = eval x₂ (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))
⊢ XYIdeal W x₂ (↑C (eval x₂ (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)))) =
    XYIdeal W x₂ (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))
[PROOFSTEP]
simp only [XYIdeal, XClass, YClass, linePolynomial]
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hy₂ : y₂ = eval x₂ (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))
⊢ span
      {↑(CoordinateRing.mk W) (↑C (Y - ↑C x₂)),
        ↑(CoordinateRing.mk W) (Y - ↑C (↑C (eval x₂ (↑C (slope W x₁ x₂ y₁ y₂) * (Y - ↑C x₁) + ↑C y₁))))} =
    span
      {↑(CoordinateRing.mk W) (↑C (Y - ↑C x₂)),
        ↑(CoordinateRing.mk W) (Y - ↑C (↑C (slope W x₁ x₂ y₁ y₂) * (Y - ↑C x₁) + ↑C y₁))}
[PROOFSTEP]
rw [← span_pair_add_mul_right <| CoordinateRing.mk W <| C <| C <| -W.slope x₁ x₂ y₁ y₂, ← _root_.map_mul, ← map_add]
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hy₂ : y₂ = eval x₂ (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))
⊢ span
      {↑(CoordinateRing.mk W) (↑C (Y - ↑C x₂)),
        ↑(CoordinateRing.mk W)
          (Y - ↑C (↑C (eval x₂ (↑C (slope W x₁ x₂ y₁ y₂) * (Y - ↑C x₁) + ↑C y₁))) +
            ↑C (Y - ↑C x₂) * ↑C (↑C (-slope W x₁ x₂ y₁ y₂)))} =
    span
      {↑(CoordinateRing.mk W) (↑C (Y - ↑C x₂)),
        ↑(CoordinateRing.mk W) (Y - ↑C (↑C (slope W x₁ x₂ y₁ y₂) * (Y - ↑C x₁) + ↑C y₁))}
[PROOFSTEP]
apply congr_arg (_ ∘ _ ∘ _ ∘ _)
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hy₂ : y₂ = eval x₂ (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))
⊢ Y - ↑C (↑C (eval x₂ (↑C (slope W x₁ x₂ y₁ y₂) * (Y - ↑C x₁) + ↑C y₁))) +
      ↑C (Y - ↑C x₂) * ↑C (↑C (-slope W x₁ x₂ y₁ y₂)) =
    Y - ↑C (↑C (slope W x₁ x₂ y₁ y₂) * (Y - ↑C x₁) + ↑C y₁)
[PROOFSTEP]
eval_simp
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hy₂ : y₂ = eval x₂ (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))
⊢ Y - ↑C (↑C (slope W x₁ x₂ y₁ y₂ * (x₂ - x₁) + y₁)) + ↑C (Y - ↑C x₂) * ↑C (↑C (-slope W x₁ x₂ y₁ y₂)) =
    Y - ↑C (↑C (slope W x₁ x₂ y₁ y₂) * (Y - ↑C x₁) + ↑C y₁)
[PROOFSTEP]
C_simp
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hy₂ : y₂ = eval x₂ (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))
⊢ Y - (↑C (↑C (slope W x₁ x₂ y₁ y₂)) * (↑C (↑C x₂) - ↑C (↑C x₁)) + ↑C (↑C y₁)) +
      (↑C Y - ↑C (↑C x₂)) * -↑C (↑C (slope W x₁ x₂ y₁ y₂)) =
    Y - (↑C (↑C (slope W x₁ x₂ y₁ y₂)) * (↑C Y - ↑C (↑C x₁)) + ↑C (↑C y₁))
[PROOFSTEP]
ring1
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ addPolynomial W x₁ y₁ (slope W x₁ x₂ y₁ y₂) =
    -((Y - ↑C x₁) * (Y - ↑C x₂) * (Y - ↑C (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))))
[PROOFSTEP]
clear h₂
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ addPolynomial W x₁ y₁ (slope W x₁ x₂ y₁ y₂) =
    -((Y - ↑C x₁) * (Y - ↑C x₂) * (Y - ↑C (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))))
[PROOFSTEP]
rw [addPolynomial_eq, neg_inj, Cubic.prod_X_sub_C_eq, Cubic.toPoly_injective]
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ { a := 1, b := -slope W x₁ x₂ y₁ y₂ ^ 2 - W.a₁ * slope W x₁ x₂ y₁ y₂ + W.a₂,
      c := 2 * x₁ * slope W x₁ x₂ y₁ y₂ ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * slope W x₁ x₂ y₁ y₂ + (-W.a₁ * y₁ + W.a₄),
      d :=
        -x₁ ^ 2 * slope W x₁ x₂ y₁ y₂ ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * slope W x₁ x₂ y₁ y₂ -
          (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) } =
    { a := 1, b := -(x₁ + x₂ + addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)),
      c := x₁ * x₂ + x₁ * addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) + x₂ * addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂),
      d := -(x₁ * x₂ * addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) }
[PROOFSTEP]
by_cases hx : x₁ = x₂
[GOAL]
case pos
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx : x₁ = x₂
⊢ { a := 1, b := -slope W x₁ x₂ y₁ y₂ ^ 2 - W.a₁ * slope W x₁ x₂ y₁ y₂ + W.a₂,
      c := 2 * x₁ * slope W x₁ x₂ y₁ y₂ ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * slope W x₁ x₂ y₁ y₂ + (-W.a₁ * y₁ + W.a₄),
      d :=
        -x₁ ^ 2 * slope W x₁ x₂ y₁ y₂ ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * slope W x₁ x₂ y₁ y₂ -
          (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) } =
    { a := 1, b := -(x₁ + x₂ + addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)),
      c := x₁ * x₂ + x₁ * addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) + x₂ * addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂),
      d := -(x₁ * x₂ * addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) }
[PROOFSTEP]
rcases hx, Y_eq_of_Y_ne h₁' h₂' hx (hxy hx) with ⟨rfl, rfl⟩
[GOAL]
case pos
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' h₂' : WeierstrassCurve.equation W x₁ y₁
hxy : x₁ = x₁ → y₁ ≠ negY W x₁ y₁
⊢ { a := 1, b := -slope W x₁ x₁ y₁ y₁ ^ 2 - W.a₁ * slope W x₁ x₁ y₁ y₁ + W.a₂,
      c := 2 * x₁ * slope W x₁ x₁ y₁ y₁ ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * slope W x₁ x₁ y₁ y₁ + (-W.a₁ * y₁ + W.a₄),
      d :=
        -x₁ ^ 2 * slope W x₁ x₁ y₁ y₁ ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * slope W x₁ x₁ y₁ y₁ -
          (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) } =
    { a := 1, b := -(x₁ + x₁ + addX W x₁ x₁ (slope W x₁ x₁ y₁ y₁)),
      c := x₁ * x₁ + x₁ * addX W x₁ x₁ (slope W x₁ x₁ y₁ y₁) + x₁ * addX W x₁ x₁ (slope W x₁ x₁ y₁ y₁),
      d := -(x₁ * x₁ * addX W x₁ x₁ (slope W x₁ x₁ y₁ y₁)) }
[PROOFSTEP]
rw [equation_iff] at h₁' h₂'
[GOAL]
case pos
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' h₂' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
hxy : x₁ = x₁ → y₁ ≠ negY W x₁ y₁
⊢ { a := 1, b := -slope W x₁ x₁ y₁ y₁ ^ 2 - W.a₁ * slope W x₁ x₁ y₁ y₁ + W.a₂,
      c := 2 * x₁ * slope W x₁ x₁ y₁ y₁ ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * slope W x₁ x₁ y₁ y₁ + (-W.a₁ * y₁ + W.a₄),
      d :=
        -x₁ ^ 2 * slope W x₁ x₁ y₁ y₁ ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * slope W x₁ x₁ y₁ y₁ -
          (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) } =
    { a := 1, b := -(x₁ + x₁ + addX W x₁ x₁ (slope W x₁ x₁ y₁ y₁)),
      c := x₁ * x₁ + x₁ * addX W x₁ x₁ (slope W x₁ x₁ y₁ y₁) + x₁ * addX W x₁ x₁ (slope W x₁ x₁ y₁ y₁),
      d := -(x₁ * x₁ * addX W x₁ x₁ (slope W x₁ x₁ y₁ y₁)) }
[PROOFSTEP]
rw [slope_of_Y_ne rfl <| hxy rfl]
[GOAL]
case pos
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' h₂' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
hxy : x₁ = x₁ → y₁ ≠ negY W x₁ y₁
⊢ { a := 1,
      b :=
        -((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 -
            W.a₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
          W.a₂,
      c :=
        2 * x₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 +
            (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
          (-W.a₁ * y₁ + W.a₄),
      d :=
        -x₁ ^ 2 * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 +
            (2 * x₁ * y₁ + W.a₃ * x₁) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) -
          (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) } =
    { a := 1, b := -(x₁ + x₁ + addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁))),
      c :=
        x₁ * x₁ + x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
          x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)),
      d := -(x₁ * x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁))) }
[PROOFSTEP]
rw [negY, ← sub_ne_zero] at hxy
[GOAL]
case pos
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' h₂' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
hxy✝ : x₁ = x₁ → y₁ ≠ -y₁ - W.a₁ * x₁ - W.a₃
hxy : x₁ = x₁ → y₁ - (-y₁ - W.a₁ * x₁ - W.a₃) ≠ 0
⊢ { a := 1,
      b :=
        -((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 -
            W.a₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
          W.a₂,
      c :=
        2 * x₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 +
            (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
          (-W.a₁ * y₁ + W.a₄),
      d :=
        -x₁ ^ 2 * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 +
            (2 * x₁ * y₁ + W.a₃ * x₁) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) -
          (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) } =
    { a := 1, b := -(x₁ + x₁ + addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁))),
      c :=
        x₁ * x₁ + x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
          x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)),
      d := -(x₁ * x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁))) }
[PROOFSTEP]
ext
[GOAL]
case pos.a
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' h₂' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
hxy✝ : x₁ = x₁ → y₁ ≠ -y₁ - W.a₁ * x₁ - W.a₃
hxy : x₁ = x₁ → y₁ - (-y₁ - W.a₁ * x₁ - W.a₃) ≠ 0
⊢ { a := 1,
        b :=
          -((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 -
              W.a₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
            W.a₂,
        c :=
          2 * x₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 +
              (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
            (-W.a₁ * y₁ + W.a₄),
        d :=
          -x₁ ^ 2 * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 +
              (2 * x₁ * y₁ + W.a₃ * x₁) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) -
            (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) }.a =
    { a := 1, b := -(x₁ + x₁ + addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁))),
        c :=
          x₁ * x₁ + x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
            x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)),
        d := -(x₁ * x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁))) }.a
[PROOFSTEP]
rfl
[GOAL]
case pos.b
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' h₂' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
hxy✝ : x₁ = x₁ → y₁ ≠ -y₁ - W.a₁ * x₁ - W.a₃
hxy : x₁ = x₁ → y₁ - (-y₁ - W.a₁ * x₁ - W.a₃) ≠ 0
⊢ { a := 1,
        b :=
          -((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 -
              W.a₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
            W.a₂,
        c :=
          2 * x₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 +
              (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
            (-W.a₁ * y₁ + W.a₄),
        d :=
          -x₁ ^ 2 * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 +
              (2 * x₁ * y₁ + W.a₃ * x₁) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) -
            (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) }.b =
    { a := 1, b := -(x₁ + x₁ + addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁))),
        c :=
          x₁ * x₁ + x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
            x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)),
        d := -(x₁ * x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁))) }.b
[PROOFSTEP]
simp only [addX]
[GOAL]
case pos.b
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' h₂' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
hxy✝ : x₁ = x₁ → y₁ ≠ -y₁ - W.a₁ * x₁ - W.a₃
hxy : x₁ = x₁ → y₁ - (-y₁ - W.a₁ * x₁ - W.a₃) ≠ 0
⊢ -((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 -
        W.a₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
      W.a₂ =
    -(x₁ + x₁ +
        (((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 +
                W.a₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) -
              W.a₂ -
            x₁ -
          x₁))
[PROOFSTEP]
ring1
[GOAL]
case pos.c
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' h₂' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
hxy✝ : x₁ = x₁ → y₁ ≠ -y₁ - W.a₁ * x₁ - W.a₃
hxy : x₁ = x₁ → y₁ - (-y₁ - W.a₁ * x₁ - W.a₃) ≠ 0
⊢ { a := 1,
        b :=
          -((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 -
              W.a₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
            W.a₂,
        c :=
          2 * x₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 +
              (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
            (-W.a₁ * y₁ + W.a₄),
        d :=
          -x₁ ^ 2 * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 +
              (2 * x₁ * y₁ + W.a₃ * x₁) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) -
            (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) }.c =
    { a := 1, b := -(x₁ + x₁ + addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁))),
        c :=
          x₁ * x₁ + x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
            x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)),
        d := -(x₁ * x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁))) }.c
[PROOFSTEP]
field_simp [hxy rfl]
[GOAL]
case pos.c
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' h₂' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
hxy✝ : x₁ = x₁ → y₁ ≠ -y₁ - W.a₁ * x₁ - W.a₃
hxy : x₁ = x₁ → y₁ - (-y₁ - W.a₁ * x₁ - W.a₃) ≠ 0
⊢ 2 * x₁ * (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) ^ 2 * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) +
        (W.a₁ * x₁ - 2 * y₁ - W.a₃) * (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) *
          (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2 +
      (-(W.a₁ * y₁) + W.a₄) * ((y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2 * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃))) =
    x₁ * x₁ * ((y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2 * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃))) +
        x₁ *
          ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) ^ 2 * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) +
                  W.a₁ * (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2 -
                (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2 * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) * W.a₂ -
              (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2 * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) * x₁ -
            (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2 * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) * x₁) +
      x₁ *
        ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) ^ 2 * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) +
                W.a₁ * (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2 -
              (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2 * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) * W.a₂ -
            (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2 * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) * x₁ -
          (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2 * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) * x₁)
[PROOFSTEP]
ring1
[GOAL]
case pos.d
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' h₂' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
hxy✝ : x₁ = x₁ → y₁ ≠ -y₁ - W.a₁ * x₁ - W.a₃
hxy : x₁ = x₁ → y₁ - (-y₁ - W.a₁ * x₁ - W.a₃) ≠ 0
⊢ { a := 1,
        b :=
          -((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 -
              W.a₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
            W.a₂,
        c :=
          2 * x₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 +
              (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
            (-W.a₁ * y₁ + W.a₄),
        d :=
          -x₁ ^ 2 * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 +
              (2 * x₁ * y₁ + W.a₃ * x₁) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) -
            (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) }.d =
    { a := 1, b := -(x₁ + x₁ + addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁))),
        c :=
          x₁ * x₁ + x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
            x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)),
        d := -(x₁ * x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁))) }.d
[PROOFSTEP]
linear_combination (norm := (field_simp [hxy rfl]; ring1)) -h₁'
[GOAL]
case a
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' h₂' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
hxy✝ : x₁ = x₁ → y₁ ≠ -y₁ - W.a₁ * x₁ - W.a₃
hxy : x₁ = x₁ → y₁ - (-y₁ - W.a₁ * x₁ - W.a₃) ≠ 0
⊢ { a := 1,
            b :=
              -((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 -
                  W.a₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
                W.a₂,
            c :=
              2 * x₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 +
                  (W.a₁ * x₁ - 2 * y₁ - W.a₃) *
                    ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
                (-W.a₁ * y₁ + W.a₄),
            d :=
              -x₁ ^ 2 * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) ^ 2 +
                  (2 * x₁ * y₁ + W.a₃ * x₁) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) -
                (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) }.d -
        { a := 1,
            b := -(x₁ + x₁ + addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁))),
            c :=
              x₁ * x₁ + x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)) +
                x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁)),
            d := -(x₁ * x₁ * addX W x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - negY W x₁ y₁))) }.d -
      (-(y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁) - -(x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆)) =
    0
[PROOFSTEP]
field_simp [hxy rfl]
[GOAL]
case a
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' h₂' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
hxy✝ : x₁ = x₁ → y₁ ≠ -y₁ - W.a₁ * x₁ - W.a₃
hxy : x₁ = x₁ → y₁ - (-y₁ - W.a₁ * x₁ - W.a₃) ≠ 0
⊢ -(x₁ ^ 2 * (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) ^ 2 * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃))) +
            (2 * x₁ * y₁ + W.a₃ * x₁) * (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) *
              (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2 -
          (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2 * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) * (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) +
        x₁ * x₁ *
          ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) ^ 2 * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) +
                  W.a₁ * (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2 -
                (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2 * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) * W.a₂ -
              (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2 * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) * x₁ -
            (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2 * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) * x₁) -
      (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2 * (y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) *
        (-(W.a₃ * y₁) + (-(W.a₁ * x₁ * y₁) + -y₁ ^ 2) - (-W.a₆ + (-(W.a₄ * x₁) + (-(W.a₂ * x₁ ^ 2) + -x₁ ^ 3)))) =
    0
[PROOFSTEP]
ring1
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx : ¬x₁ = x₂
⊢ { a := 1, b := -slope W x₁ x₂ y₁ y₂ ^ 2 - W.a₁ * slope W x₁ x₂ y₁ y₂ + W.a₂,
      c := 2 * x₁ * slope W x₁ x₂ y₁ y₂ ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * slope W x₁ x₂ y₁ y₂ + (-W.a₁ * y₁ + W.a₄),
      d :=
        -x₁ ^ 2 * slope W x₁ x₂ y₁ y₂ ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * slope W x₁ x₂ y₁ y₂ -
          (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) } =
    { a := 1, b := -(x₁ + x₂ + addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)),
      c := x₁ * x₂ + x₁ * addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) + x₂ * addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂),
      d := -(x₁ * x₂ * addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) }
[PROOFSTEP]
rw [equation_iff] at h₁' h₂'
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
h₂' : y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ = x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx : ¬x₁ = x₂
⊢ { a := 1, b := -slope W x₁ x₂ y₁ y₂ ^ 2 - W.a₁ * slope W x₁ x₂ y₁ y₂ + W.a₂,
      c := 2 * x₁ * slope W x₁ x₂ y₁ y₂ ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * slope W x₁ x₂ y₁ y₂ + (-W.a₁ * y₁ + W.a₄),
      d :=
        -x₁ ^ 2 * slope W x₁ x₂ y₁ y₂ ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * slope W x₁ x₂ y₁ y₂ -
          (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) } =
    { a := 1, b := -(x₁ + x₂ + addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)),
      c := x₁ * x₂ + x₁ * addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) + x₂ * addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂),
      d := -(x₁ * x₂ * addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) }
[PROOFSTEP]
rw [slope_of_X_ne hx]
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
h₂' : y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ = x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx : ¬x₁ = x₂
⊢ { a := 1, b := -((y₁ - y₂) / (x₁ - x₂)) ^ 2 - W.a₁ * ((y₁ - y₂) / (x₁ - x₂)) + W.a₂,
      c :=
        2 * x₁ * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((y₁ - y₂) / (x₁ - x₂)) +
          (-W.a₁ * y₁ + W.a₄),
      d :=
        -x₁ ^ 2 * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * ((y₁ - y₂) / (x₁ - x₂)) -
          (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) } =
    { a := 1, b := -(x₁ + x₂ + addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))),
      c := x₁ * x₂ + x₁ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)) + x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)),
      d := -(x₁ * x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))) }
[PROOFSTEP]
rw [← sub_eq_zero] at hx
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
h₂' : y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ = x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx✝ : ¬x₁ = x₂
hx : ¬x₁ - x₂ = 0
⊢ { a := 1, b := -((y₁ - y₂) / (x₁ - x₂)) ^ 2 - W.a₁ * ((y₁ - y₂) / (x₁ - x₂)) + W.a₂,
      c :=
        2 * x₁ * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((y₁ - y₂) / (x₁ - x₂)) +
          (-W.a₁ * y₁ + W.a₄),
      d :=
        -x₁ ^ 2 * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * ((y₁ - y₂) / (x₁ - x₂)) -
          (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) } =
    { a := 1, b := -(x₁ + x₂ + addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))),
      c := x₁ * x₂ + x₁ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)) + x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)),
      d := -(x₁ * x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))) }
[PROOFSTEP]
ext
[GOAL]
case neg.a
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
h₂' : y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ = x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx✝ : ¬x₁ = x₂
hx : ¬x₁ - x₂ = 0
⊢ { a := 1, b := -((y₁ - y₂) / (x₁ - x₂)) ^ 2 - W.a₁ * ((y₁ - y₂) / (x₁ - x₂)) + W.a₂,
        c :=
          2 * x₁ * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((y₁ - y₂) / (x₁ - x₂)) +
            (-W.a₁ * y₁ + W.a₄),
        d :=
          -x₁ ^ 2 * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * ((y₁ - y₂) / (x₁ - x₂)) -
            (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) }.a =
    { a := 1, b := -(x₁ + x₂ + addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))),
        c := x₁ * x₂ + x₁ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)) + x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)),
        d := -(x₁ * x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))) }.a
[PROOFSTEP]
rfl
[GOAL]
case neg.b
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
h₂' : y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ = x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx✝ : ¬x₁ = x₂
hx : ¬x₁ - x₂ = 0
⊢ { a := 1, b := -((y₁ - y₂) / (x₁ - x₂)) ^ 2 - W.a₁ * ((y₁ - y₂) / (x₁ - x₂)) + W.a₂,
        c :=
          2 * x₁ * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((y₁ - y₂) / (x₁ - x₂)) +
            (-W.a₁ * y₁ + W.a₄),
        d :=
          -x₁ ^ 2 * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * ((y₁ - y₂) / (x₁ - x₂)) -
            (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) }.b =
    { a := 1, b := -(x₁ + x₂ + addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))),
        c := x₁ * x₂ + x₁ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)) + x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)),
        d := -(x₁ * x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))) }.b
[PROOFSTEP]
simp only [addX]
[GOAL]
case neg.b
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
h₂' : y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ = x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx✝ : ¬x₁ = x₂
hx : ¬x₁ - x₂ = 0
⊢ -((y₁ - y₂) / (x₁ - x₂)) ^ 2 - W.a₁ * ((y₁ - y₂) / (x₁ - x₂)) + W.a₂ =
    -(x₁ + x₂ + (((y₁ - y₂) / (x₁ - x₂)) ^ 2 + W.a₁ * ((y₁ - y₂) / (x₁ - x₂)) - W.a₂ - x₁ - x₂))
[PROOFSTEP]
ring1
[GOAL]
case neg.c
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
h₂' : y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ = x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx✝ : ¬x₁ = x₂
hx : ¬x₁ - x₂ = 0
⊢ { a := 1, b := -((y₁ - y₂) / (x₁ - x₂)) ^ 2 - W.a₁ * ((y₁ - y₂) / (x₁ - x₂)) + W.a₂,
        c :=
          2 * x₁ * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((y₁ - y₂) / (x₁ - x₂)) +
            (-W.a₁ * y₁ + W.a₄),
        d :=
          -x₁ ^ 2 * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * ((y₁ - y₂) / (x₁ - x₂)) -
            (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) }.c =
    { a := 1, b := -(x₁ + x₂ + addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))),
        c := x₁ * x₂ + x₁ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)) + x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)),
        d := -(x₁ * x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))) }.c
[PROOFSTEP]
apply mul_right_injective₀ hx
[GOAL]
case neg.c.a
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
h₂' : y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ = x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx✝ : ¬x₁ = x₂
hx : ¬x₁ - x₂ = 0
⊢ (fun x x_1 => x * x_1) (x₁ - x₂)
      { a := 1, b := -((y₁ - y₂) / (x₁ - x₂)) ^ 2 - W.a₁ * ((y₁ - y₂) / (x₁ - x₂)) + W.a₂,
          c :=
            2 * x₁ * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((y₁ - y₂) / (x₁ - x₂)) +
              (-W.a₁ * y₁ + W.a₄),
          d :=
            -x₁ ^ 2 * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * ((y₁ - y₂) / (x₁ - x₂)) -
              (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) }.c =
    (fun x x_1 => x * x_1) (x₁ - x₂)
      { a := 1, b := -(x₁ + x₂ + addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))),
          c := x₁ * x₂ + x₁ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)) + x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)),
          d := -(x₁ * x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))) }.c
[PROOFSTEP]
linear_combination (norm := (field_simp [hx]; ring1)) h₂' - h₁'
[GOAL]
case a
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
h₂' : y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ = x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx✝ : ¬x₁ = x₂
hx : ¬x₁ - x₂ = 0
⊢ (fun x x_1 => x * x_1) (x₁ - x₂)
          { a := 1, b := -((y₁ - y₂) / (x₁ - x₂)) ^ 2 - W.a₁ * ((y₁ - y₂) / (x₁ - x₂)) + W.a₂,
              c :=
                2 * x₁ * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((y₁ - y₂) / (x₁ - x₂)) +
                  (-W.a₁ * y₁ + W.a₄),
              d :=
                -x₁ ^ 2 * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * ((y₁ - y₂) / (x₁ - x₂)) -
                  (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) }.c -
        (fun x x_1 => x * x_1) (x₁ - x₂)
          { a := 1, b := -(x₁ + x₂ + addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))),
              c := x₁ * x₂ + x₁ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)) + x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)),
              d := -(x₁ * x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))) }.c -
      (y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ - (y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁) -
        (x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆ - (x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆))) =
    0
[PROOFSTEP]
field_simp [hx]
[GOAL]
case a
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
h₂' : y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ = x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx✝ : ¬x₁ = x₂
hx : ¬x₁ - x₂ = 0
⊢ (x₁ - x₂) *
          (2 * x₁ * (y₁ - y₂) ^ 2 * (x₁ - x₂) + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * (y₁ - y₂) * (x₁ - x₂) ^ 2 +
            (-(W.a₁ * y₁) + W.a₄) * ((x₁ - x₂) ^ 2 * (x₁ - x₂))) -
        (x₁ - x₂) *
          (x₁ * x₂ * ((x₁ - x₂) ^ 2 * (x₁ - x₂)) +
              x₁ *
                ((y₁ - y₂) ^ 2 * (x₁ - x₂) + W.a₁ * (y₁ - y₂) * (x₁ - x₂) ^ 2 - (x₁ - x₂) ^ 2 * (x₁ - x₂) * W.a₂ -
                    (x₁ - x₂) ^ 2 * (x₁ - x₂) * x₁ -
                  (x₁ - x₂) ^ 2 * (x₁ - x₂) * x₂) +
            x₂ *
              ((y₁ - y₂) ^ 2 * (x₁ - x₂) + W.a₁ * (y₁ - y₂) * (x₁ - x₂) ^ 2 - (x₁ - x₂) ^ 2 * (x₁ - x₂) * W.a₂ -
                  (x₁ - x₂) ^ 2 * (x₁ - x₂) * x₁ -
                (x₁ - x₂) ^ 2 * (x₁ - x₂) * x₂)) -
      (x₁ - x₂) ^ 2 * (x₁ - x₂) *
        (y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ - (y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁) -
          (x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ - (x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁))) =
    0
[PROOFSTEP]
ring1
[GOAL]
case neg.d
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
h₂' : y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ = x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx✝ : ¬x₁ = x₂
hx : ¬x₁ - x₂ = 0
⊢ { a := 1, b := -((y₁ - y₂) / (x₁ - x₂)) ^ 2 - W.a₁ * ((y₁ - y₂) / (x₁ - x₂)) + W.a₂,
        c :=
          2 * x₁ * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((y₁ - y₂) / (x₁ - x₂)) +
            (-W.a₁ * y₁ + W.a₄),
        d :=
          -x₁ ^ 2 * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * ((y₁ - y₂) / (x₁ - x₂)) -
            (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) }.d =
    { a := 1, b := -(x₁ + x₂ + addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))),
        c := x₁ * x₂ + x₁ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)) + x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)),
        d := -(x₁ * x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))) }.d
[PROOFSTEP]
apply mul_right_injective₀ hx
[GOAL]
case neg.d.a
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
h₂' : y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ = x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx✝ : ¬x₁ = x₂
hx : ¬x₁ - x₂ = 0
⊢ (fun x x_1 => x * x_1) (x₁ - x₂)
      { a := 1, b := -((y₁ - y₂) / (x₁ - x₂)) ^ 2 - W.a₁ * ((y₁ - y₂) / (x₁ - x₂)) + W.a₂,
          c :=
            2 * x₁ * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((y₁ - y₂) / (x₁ - x₂)) +
              (-W.a₁ * y₁ + W.a₄),
          d :=
            -x₁ ^ 2 * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * ((y₁ - y₂) / (x₁ - x₂)) -
              (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) }.d =
    (fun x x_1 => x * x_1) (x₁ - x₂)
      { a := 1, b := -(x₁ + x₂ + addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))),
          c := x₁ * x₂ + x₁ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)) + x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)),
          d := -(x₁ * x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))) }.d
[PROOFSTEP]
linear_combination (norm := (field_simp [hx]; ring1)) x₂ * h₁' - x₁ * h₂'
[GOAL]
case a
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
h₂' : y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ = x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx✝ : ¬x₁ = x₂
hx : ¬x₁ - x₂ = 0
⊢ (fun x x_1 => x * x_1) (x₁ - x₂)
          { a := 1, b := -((y₁ - y₂) / (x₁ - x₂)) ^ 2 - W.a₁ * ((y₁ - y₂) / (x₁ - x₂)) + W.a₂,
              c :=
                2 * x₁ * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((y₁ - y₂) / (x₁ - x₂)) +
                  (-W.a₁ * y₁ + W.a₄),
              d :=
                -x₁ ^ 2 * ((y₁ - y₂) / (x₁ - x₂)) ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * ((y₁ - y₂) / (x₁ - x₂)) -
                  (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) }.d -
        (fun x x_1 => x * x_1) (x₁ - x₂)
          { a := 1, b := -(x₁ + x₂ + addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))),
              c := x₁ * x₂ + x₁ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)) + x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂)),
              d := -(x₁ * x₂ * addX W x₁ x₂ ((y₁ - y₂) / (x₁ - x₂))) }.d -
      (x₂ * (y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁) - x₁ * (y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂) -
        (x₂ * (x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆) - x₁ * (x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆))) =
    0
[PROOFSTEP]
field_simp [hx]
[GOAL]
case a
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁ = x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆
h₂' : y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂ = x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx✝ : ¬x₁ = x₂
hx : ¬x₁ - x₂ = 0
⊢ (x₁ - x₂) *
          (-(x₁ ^ 2 * (y₁ - y₂) ^ 2 * (x₁ - x₂)) + (2 * x₁ * y₁ + W.a₃ * x₁) * (y₁ - y₂) * (x₁ - x₂) ^ 2 -
            (x₁ - x₂) ^ 2 * (x₁ - x₂) * (y₁ ^ 2 + W.a₃ * y₁ - W.a₆)) +
        (x₁ - x₂) *
          (x₁ * x₂ *
            ((y₁ - y₂) ^ 2 * (x₁ - x₂) + W.a₁ * (y₁ - y₂) * (x₁ - x₂) ^ 2 - (x₁ - x₂) ^ 2 * (x₁ - x₂) * W.a₂ -
                (x₁ - x₂) ^ 2 * (x₁ - x₂) * x₁ -
              (x₁ - x₂) ^ 2 * (x₁ - x₂) * x₂)) -
      (x₁ - x₂) ^ 2 * (x₁ - x₂) *
        (x₂ * (y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁) - x₁ * (y₂ ^ 2 + W.a₁ * x₂ * y₂ + W.a₃ * y₂) -
          (x₂ * (x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆) - x₁ * (x₂ ^ 3 + W.a₂ * x₂ ^ 2 + W.a₄ * x₂ + W.a₆))) =
    0
[PROOFSTEP]
ring1
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ ↑(mk W) (↑C (addPolynomial W x₁ y₁ (slope W x₁ x₂ y₁ y₂))) =
    -(XClass W x₁ * XClass W x₂ * XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)))
[PROOFSTEP]
simp only [addPolynomial_slope h₁' h₂' hxy, C_neg, mk, map_neg, neg_inj, _root_.map_mul]
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ ↑(AdjoinRoot.mk (WeierstrassCurve.polynomial W)) (↑C (Y - ↑C x₁)) *
        ↑(AdjoinRoot.mk (WeierstrassCurve.polynomial W)) (↑C (Y - ↑C x₂)) *
      ↑(AdjoinRoot.mk (WeierstrassCurve.polynomial W)) (↑C (Y - ↑C (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)))) =
    XClass W x₁ * XClass W x₂ * XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))
[PROOFSTEP]
rfl
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ ↑derivative (addPolynomial W x₁ y₁ (slope W x₁ x₂ y₁ y₂)) =
    -((Y - ↑C x₁) * (Y - ↑C x₂) + (Y - ↑C x₁) * (Y - ↑C (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))) +
        (Y - ↑C x₂) * (Y - ↑C (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))))
[PROOFSTEP]
rw [addPolynomial_slope h₁' h₂' hxy]
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ ↑derivative (-((Y - ↑C x₁) * (Y - ↑C x₂) * (Y - ↑C (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))))) =
    -((Y - ↑C x₁) * (Y - ↑C x₂) + (Y - ↑C x₁) * (Y - ↑C (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))) +
        (Y - ↑C x₂) * (Y - ↑C (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))))
[PROOFSTEP]
derivative_simp
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ -(((1 - 0) * (Y - ↑C x₂) + (Y - ↑C x₁) * (1 - 0)) * (Y - ↑C (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))) +
        (Y - ↑C x₁) * (Y - ↑C x₂) * (1 - 0)) =
    -((Y - ↑C x₁) * (Y - ↑C x₂) + (Y - ↑C x₁) * (Y - ↑C (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))) +
        (Y - ↑C x₂) * (Y - ↑C (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))))
[PROOFSTEP]
ring1
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ WeierstrassCurve.equation W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (addY' W x₁ x₂ y₁ (slope W x₁ x₂ y₁ y₂))
[PROOFSTEP]
rw [equation_add_iff, addPolynomial_slope h₁' h₂' hxy]
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ eval (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))
      (-((Y - ↑C x₁) * (Y - ↑C x₂) * (Y - ↑C (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))))) =
    0
[PROOFSTEP]
eval_simp
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ -((addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) - x₁) * (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) - x₂) *
        (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) - addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))) =
    0
[PROOFSTEP]
rw [neg_eq_zero, sub_self, mul_zero]
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ WeierstrassCurve.nonsingular W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (addY' W x₁ x₂ y₁ (slope W x₁ x₂ y₁ y₂))
[PROOFSTEP]
clear h₂'
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ WeierstrassCurve.nonsingular W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (addY' W x₁ x₂ y₁ (slope W x₁ x₂ y₁ y₂))
[PROOFSTEP]
by_cases hx₁ : W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂) = x₁
[GOAL]
case pos
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx₁ : addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) = x₁
⊢ WeierstrassCurve.nonsingular W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (addY' W x₁ x₂ y₁ (slope W x₁ x₂ y₁ y₂))
[PROOFSTEP]
rwa [addY', hx₁, sub_self, mul_zero, zero_add]
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx₁ : ¬addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) = x₁
⊢ WeierstrassCurve.nonsingular W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (addY' W x₁ x₂ y₁ (slope W x₁ x₂ y₁ y₂))
[PROOFSTEP]
by_cases hx₂ : W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂) = x₂
[GOAL]
case pos
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx₁ : ¬addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) = x₁
hx₂ : addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) = x₂
⊢ WeierstrassCurve.nonsingular W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (addY' W x₁ x₂ y₁ (slope W x₁ x₂ y₁ y₂))
[PROOFSTEP]
by_cases hx : x₁ = x₂
[GOAL]
case pos
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx₁ : ¬addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) = x₁
hx₂ : addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) = x₂
hx : x₁ = x₂
⊢ WeierstrassCurve.nonsingular W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (addY' W x₁ x₂ y₁ (slope W x₁ x₂ y₁ y₂))
[PROOFSTEP]
subst hx
[GOAL]
case pos
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₁ y₂
hxy : x₁ = x₁ → y₁ ≠ negY W x₁ y₂
hx₁ : ¬addX W x₁ x₁ (slope W x₁ x₁ y₁ y₂) = x₁
hx₂ : addX W x₁ x₁ (slope W x₁ x₁ y₁ y₂) = x₁
⊢ WeierstrassCurve.nonsingular W (addX W x₁ x₁ (slope W x₁ x₁ y₁ y₂)) (addY' W x₁ x₁ y₁ (slope W x₁ x₁ y₁ y₂))
[PROOFSTEP]
contradiction
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx₁ : ¬addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) = x₁
hx₂ : addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) = x₂
hx : ¬x₁ = x₂
⊢ WeierstrassCurve.nonsingular W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (addY' W x₁ x₂ y₁ (slope W x₁ x₂ y₁ y₂))
[PROOFSTEP]
rwa [addY', ← neg_sub, mul_neg, hx₂, slope_of_X_ne hx, div_mul_cancel _ <| sub_ne_zero_of_ne hx, neg_sub,
  sub_add_cancel]
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx₁ : ¬addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) = x₁
hx₂ : ¬addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) = x₂
⊢ WeierstrassCurve.nonsingular W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (addY' W x₁ x₂ y₁ (slope W x₁ x₂ y₁ y₂))
[PROOFSTEP]
apply W.nonsingular_add_of_eval_derivative_ne_zero _ _ _ _ (equation_add' h₁.1 h₂.1 hxy)
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx₁ : ¬addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) = x₁
hx₂ : ¬addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) = x₂
⊢ eval (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (↑derivative (addPolynomial W x₁ y₁ (slope W x₁ x₂ y₁ y₂))) ≠ 0
[PROOFSTEP]
rw [derivative_addPolynomial_slope h₁.left h₂.left hxy]
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx₁ : ¬addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) = x₁
hx₂ : ¬addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) = x₂
⊢ eval (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))
      (-((Y - ↑C x₁) * (Y - ↑C x₂) + (Y - ↑C x₁) * (Y - ↑C (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))) +
          (Y - ↑C x₂) * (Y - ↑C (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))))) ≠
    0
[PROOFSTEP]
eval_simp
[GOAL]
case neg
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
hx₁ : ¬addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) = x₁
hx₂ : ¬addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) = x₂
⊢ -((addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) - x₁) * (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) - x₂) +
          (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) - x₁) *
            (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) - addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) +
        (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) - x₂) *
          (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂) - addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))) ≠
    0
[PROOFSTEP]
simpa only [neg_ne_zero, sub_self, mul_zero, add_zero] using mul_ne_zero (sub_ne_zero_of_ne hx₁) (sub_ne_zero_of_ne hx₂)
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ ∀ (a : Point W), 0 + a = a
[PROOFSTEP]
rintro (_ | _)
[GOAL]
case zero
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ 0 + zero = zero
[PROOFSTEP]
rfl
[GOAL]
case some
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
x✝ y✝ : F
h✝ : WeierstrassCurve.nonsingular W x✝ y✝
⊢ 0 + some h✝ = some h✝
[PROOFSTEP]
rfl
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ ∀ (a : Point W), a + 0 = a
[PROOFSTEP]
rintro (_ | _)
[GOAL]
case zero
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ zero + 0 = zero
[PROOFSTEP]
rfl
[GOAL]
case some
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
x✝ y✝ : F
h✝ : WeierstrassCurve.nonsingular W x✝ y✝
⊢ some h✝ + 0 = some h✝
[PROOFSTEP]
rfl
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
hy : y₁ = negY W x₂ y₂
⊢ some h₁ + some h₂ = 0
[PROOFSTEP]
simp only [← add_def, add, dif_pos hx, dif_pos hy]
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ = x₂
hy : y₁ ≠ negY W x₂ y₂
⊢ some h₁ + some h₂ =
    some
      (_ : WeierstrassCurve.nonsingular W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (addY W x₁ x₂ y₁ (slope W x₁ x₂ y₁ y₂)))
[PROOFSTEP]
simp only [← add_def, add, dif_pos hx, dif_neg hy]
[GOAL]
F : Type u
inst✝² : Field F
W : WeierstrassCurve F
K : Type v
inst✝¹ : Field K
inst✝ : Algebra F K
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hx : x₁ ≠ x₂
⊢ some h₁ + some h₂ =
    some
      (_ : WeierstrassCurve.nonsingular W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (addY W x₁ x₂ y₁ (slope W x₁ x₂ y₁ y₂)))
[PROOFSTEP]
simp only [← add_def, add, dif_neg hx]
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ XYIdeal W x₁ (↑C (negY W x₁ y₁)) * XYIdeal W x₁ (↑C y₁) = XIdeal W x₁
[PROOFSTEP]
have Y_rw :
  (Y - C (C y₁)) * (Y - C (C (W.negY x₁ y₁))) -
      C (X - C x₁) * (C (X ^ 2 + C (x₁ + W.a₂) * X + C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - C (C W.a₁) * Y) =
    W.polynomial * 1 :=
  by
  linear_combination (norm := (rw [negY, WeierstrassCurve.polynomial]; C_simp; ring1))
    congr_arg C (congr_arg C ((W.equation_iff _ _).mp h₁.left).symm)
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
[PROOFSTEP]
linear_combination (norm := (rw [negY, WeierstrassCurve.polynomial]; C_simp; ring1))
  congr_arg C (congr_arg C ((W.equation_iff _ _).mp h₁.left).symm)
[GOAL]
case a
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
          ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) -
        WeierstrassCurve.polynomial W * 1 -
      (↑C (↑C (x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆)) - ↑C (↑C (y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁))) =
    0
[PROOFSTEP]
rw [negY, WeierstrassCurve.polynomial]
[GOAL]
case a
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (-y₁ - W.a₁ * x₁ - W.a₃))) -
          ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) -
        (Y ^ 2 + ↑C (↑C W.a₁ * Y + ↑C W.a₃) * Y - ↑C (Y ^ 3 + ↑C W.a₂ * Y ^ 2 + ↑C W.a₄ * Y + ↑C W.a₆)) * 1 -
      (↑C (↑C (x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆)) - ↑C (↑C (y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁))) =
    0
[PROOFSTEP]
C_simp
[GOAL]
case a
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ (Y - ↑C (↑C y₁)) * (Y - (-↑C (↑C y₁) - ↑C (↑C W.a₁) * ↑C (↑C x₁) - ↑C (↑C W.a₃))) -
          (↑C Y - ↑C (↑C x₁)) *
            (↑C Y ^ 2 + (↑C (↑C x₁) + ↑C (↑C W.a₂)) * ↑C Y +
                (↑C (↑C x₁) ^ 2 + ↑C (↑C W.a₂) * ↑C (↑C x₁) + ↑C (↑C W.a₄)) -
              ↑C (↑C W.a₁) * Y) -
        (Y ^ 2 + (↑C (↑C W.a₁) * ↑C Y + ↑C (↑C W.a₃)) * Y -
            (↑C Y ^ 3 + ↑C (↑C W.a₂) * ↑C Y ^ 2 + ↑C (↑C W.a₄) * ↑C Y + ↑C (↑C W.a₆))) *
          1 -
      (↑C (↑C x₁) ^ 3 + ↑C (↑C W.a₂) * ↑C (↑C x₁) ^ 2 + ↑C (↑C W.a₄) * ↑C (↑C x₁) + ↑C (↑C W.a₆) -
        (↑C (↑C y₁) ^ 2 + ↑C (↑C W.a₁) * ↑C (↑C x₁) * ↑C (↑C y₁) + ↑C (↑C W.a₃) * ↑C (↑C y₁))) =
    0
[PROOFSTEP]
ring1
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
⊢ XYIdeal W x₁ (↑C (negY W x₁ y₁)) * XYIdeal W x₁ (↑C y₁) = XIdeal W x₁
[PROOFSTEP]
simp_rw [XYIdeal, XClass, YClass, span_pair_mul_span_pair, mul_comm, ← _root_.map_mul,
  AdjoinRoot.mk_eq_mk.mpr ⟨1, Y_rw⟩, _root_.map_mul, span_insert, ← span_singleton_mul_span_singleton, ← mul_sup, ←
  span_insert]
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
⊢ span {↑(CoordinateRing.mk W) (↑C (Y - ↑C x₁))} *
      span
        {↑(CoordinateRing.mk W) (↑C (Y - ↑C x₁)), ↑(CoordinateRing.mk W) (Y - ↑C (↑C y₁)),
          ↑(CoordinateRing.mk W) (Y - ↑C (↑C (negY W x₁ y₁))),
          ↑(AdjoinRoot.mk (WeierstrassCurve.polynomial W))
            (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y)} =
    XIdeal W x₁
[PROOFSTEP]
convert mul_top (_ : Ideal W.CoordinateRing) using 2
[GOAL]
case h.e'_2.h.e'_6
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
⊢ span
      {↑(CoordinateRing.mk W) (↑C (Y - ↑C x₁)), ↑(CoordinateRing.mk W) (Y - ↑C (↑C y₁)),
        ↑(CoordinateRing.mk W) (Y - ↑C (↑C (negY W x₁ y₁))),
        ↑(AdjoinRoot.mk (WeierstrassCurve.polynomial W))
          (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y)} =
    ⊤
[PROOFSTEP]
simp_rw [← @Set.image_singleton _ _ <| CoordinateRing.mk W, ← Set.image_insert_eq, ← map_span]
[GOAL]
case h.e'_2.h.e'_6
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
⊢ Ideal.map (CoordinateRing.mk W)
      (span
        {↑C (Y - ↑C x₁), Y - ↑C (↑C y₁), Y - ↑C (↑C (negY W x₁ y₁)),
          ↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y}) =
    ⊤
[PROOFSTEP]
convert map_top (R := F[X][Y]) (CoordinateRing.mk W) using 1
[GOAL]
case h.e'_2
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
⊢ Ideal.map (CoordinateRing.mk W)
      (span
        {↑C (Y - ↑C x₁), Y - ↑C (↑C y₁), Y - ↑C (↑C (negY W x₁ y₁)),
          ↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y}) =
    Ideal.map (CoordinateRing.mk W) ⊤
[PROOFSTEP]
apply congr_arg
[GOAL]
case h.e'_2.h
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
⊢ span
      {↑C (Y - ↑C x₁), Y - ↑C (↑C y₁), Y - ↑C (↑C (negY W x₁ y₁)),
        ↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y} =
    ⊤
[PROOFSTEP]
simp_rw [eq_top_iff_one, mem_span_insert', mem_span_singleton']
[GOAL]
case h.e'_2.h
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
⊢ ∃ a a_1 a_2 a_3,
    a_3 * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
      1 + a * ↑C (Y - ↑C x₁) + a_1 * (Y - ↑C (↑C y₁)) + a_2 * (Y - ↑C (↑C (negY W x₁ y₁)))
[PROOFSTEP]
rcases((W.nonsingular_iff' _ _).mp h₁).right with hx | hy
[GOAL]
case h.e'_2.h.inl
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
hx : W.a₁ * y₁ - (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄) ≠ 0
⊢ ∃ a a_1 a_2 a_3,
    a_3 * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
      1 + a * ↑C (Y - ↑C x₁) + a_1 * (Y - ↑C (↑C y₁)) + a_2 * (Y - ↑C (↑C (negY W x₁ y₁)))
[PROOFSTEP]
let W_X := W.a₁ * y₁ - (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄)
[GOAL]
case h.e'_2.h.inl
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
hx : W.a₁ * y₁ - (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄) ≠ 0
W_X : F := W.a₁ * y₁ - (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄)
⊢ ∃ a a_1 a_2 a_3,
    a_3 * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
      1 + a * ↑C (Y - ↑C x₁) + a_1 * (Y - ↑C (↑C y₁)) + a_2 * (Y - ↑C (↑C (negY W x₁ y₁)))
[PROOFSTEP]
refine ⟨C (C W_X⁻¹ * -(X + C (2 * x₁ + W.a₂))), C (C <| W_X⁻¹ * W.a₁), 0, C (C <| W_X⁻¹ * -1), ?_⟩
[GOAL]
case h.e'_2.h.inl
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
hx : W.a₁ * y₁ - (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄) ≠ 0
W_X : F := W.a₁ * y₁ - (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄)
⊢ ↑C (↑C (W_X⁻¹ * -1)) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    1 + ↑C (↑C W_X⁻¹ * -(Y + ↑C (2 * x₁ + W.a₂))) * ↑C (Y - ↑C x₁) + ↑C (↑C (W_X⁻¹ * W.a₁)) * (Y - ↑C (↑C y₁)) +
      0 * (Y - ↑C (↑C (negY W x₁ y₁)))
[PROOFSTEP]
rw [← mul_right_inj' <| C_ne_zero.mpr <| C_ne_zero.mpr hx]
[GOAL]
case h.e'_2.h.inl
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
hx : W.a₁ * y₁ - (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄) ≠ 0
W_X : F := W.a₁ * y₁ - (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄)
⊢ ↑C (↑C (W.a₁ * y₁ - (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄))) *
      (↑C (↑C (W_X⁻¹ * -1)) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y)) =
    ↑C (↑C (W.a₁ * y₁ - (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄))) *
      (1 + ↑C (↑C W_X⁻¹ * -(Y + ↑C (2 * x₁ + W.a₂))) * ↑C (Y - ↑C x₁) + ↑C (↑C (W_X⁻¹ * W.a₁)) * (Y - ↑C (↑C y₁)) +
        0 * (Y - ↑C (↑C (negY W x₁ y₁))))
[PROOFSTEP]
simp only [mul_add, ← mul_assoc, ← C_mul, mul_inv_cancel hx]
[GOAL]
case h.e'_2.h.inl
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
hx : W.a₁ * y₁ - (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄) ≠ 0
W_X : F := W.a₁ * y₁ - (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄)
⊢ ↑C (↑C (1 * -1)) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    ↑C (↑C (W.a₁ * y₁ - (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄))) * 1 +
          ↑C (↑C 1 * -(Y + ↑C (2 * x₁ + W.a₂)) * (Y - ↑C x₁)) +
        ↑C (↑C (1 * W.a₁)) * (Y - ↑C (↑C y₁)) +
      ↑C (↑C (W.a₁ * y₁ - (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄))) * 0 * (Y - ↑C (↑C (negY W x₁ y₁)))
[PROOFSTEP]
C_simp
[GOAL]
case h.e'_2.h.inl
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
hx : W.a₁ * y₁ - (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄) ≠ 0
W_X : F := W.a₁ * y₁ - (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄)
⊢ 1 * -1 *
      (↑C Y ^ 2 + (↑C (↑C x₁) + ↑C (↑C W.a₂)) * ↑C Y + (↑C (↑C x₁) ^ 2 + ↑C (↑C W.a₂) * ↑C (↑C x₁) + ↑C (↑C W.a₄)) -
        ↑C (↑C W.a₁) * Y) =
    (↑C (↑C W.a₁) * ↑C (↑C y₁) - (3 * ↑C (↑C x₁) ^ 2 + 2 * ↑C (↑C W.a₂) * ↑C (↑C x₁) + ↑C (↑C W.a₄))) * 1 +
          1 * -(↑C Y + (2 * ↑C (↑C x₁) + ↑C (↑C W.a₂))) * (↑C Y - ↑C (↑C x₁)) +
        1 * ↑C (↑C W.a₁) * (Y - ↑C (↑C y₁)) +
      (↑C (↑C W.a₁) * ↑C (↑C y₁) - (3 * ↑C (↑C x₁) ^ 2 + 2 * ↑C (↑C W.a₂) * ↑C (↑C x₁) + ↑C (↑C W.a₄))) * 0 *
        (Y - ↑C (↑C (negY W x₁ y₁)))
[PROOFSTEP]
ring1
[GOAL]
case h.e'_2.h.inr
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
hy : 2 * y₁ + W.a₁ * x₁ + W.a₃ ≠ 0
⊢ ∃ a a_1 a_2 a_3,
    a_3 * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
      1 + a * ↑C (Y - ↑C x₁) + a_1 * (Y - ↑C (↑C y₁)) + a_2 * (Y - ↑C (↑C (negY W x₁ y₁)))
[PROOFSTEP]
let W_Y := 2 * y₁ + W.a₁ * x₁ + W.a₃
[GOAL]
case h.e'_2.h.inr
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
hy : 2 * y₁ + W.a₁ * x₁ + W.a₃ ≠ 0
W_Y : F := 2 * y₁ + W.a₁ * x₁ + W.a₃
⊢ ∃ a a_1 a_2 a_3,
    a_3 * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
      1 + a * ↑C (Y - ↑C x₁) + a_1 * (Y - ↑C (↑C y₁)) + a_2 * (Y - ↑C (↑C (negY W x₁ y₁)))
[PROOFSTEP]
refine ⟨0, C (C W_Y⁻¹), C (C <| W_Y⁻¹ * -1), 0, ?_⟩
[GOAL]
case h.e'_2.h.inr
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
hy : 2 * y₁ + W.a₁ * x₁ + W.a₃ ≠ 0
W_Y : F := 2 * y₁ + W.a₁ * x₁ + W.a₃
⊢ 0 * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    1 + 0 * ↑C (Y - ↑C x₁) + ↑C (↑C W_Y⁻¹) * (Y - ↑C (↑C y₁)) + ↑C (↑C (W_Y⁻¹ * -1)) * (Y - ↑C (↑C (negY W x₁ y₁)))
[PROOFSTEP]
rw [negY, ← mul_right_inj' <| C_ne_zero.mpr <| C_ne_zero.mpr hy]
[GOAL]
case h.e'_2.h.inr
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
hy : 2 * y₁ + W.a₁ * x₁ + W.a₃ ≠ 0
W_Y : F := 2 * y₁ + W.a₁ * x₁ + W.a₃
⊢ ↑C (↑C (2 * y₁ + W.a₁ * x₁ + W.a₃)) *
      (0 * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y)) =
    ↑C (↑C (2 * y₁ + W.a₁ * x₁ + W.a₃)) *
      (1 + 0 * ↑C (Y - ↑C x₁) + ↑C (↑C W_Y⁻¹) * (Y - ↑C (↑C y₁)) +
        ↑C (↑C (W_Y⁻¹ * -1)) * (Y - ↑C (↑C (-y₁ - W.a₁ * x₁ - W.a₃))))
[PROOFSTEP]
simp only [mul_add, ← mul_assoc, ← C_mul, mul_inv_cancel hy]
[GOAL]
case h.e'_2.h.inr
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
hy : 2 * y₁ + W.a₁ * x₁ + W.a₃ ≠ 0
W_Y : F := 2 * y₁ + W.a₁ * x₁ + W.a₃
⊢ ↑C (↑C (2 * y₁ + W.a₁ * x₁ + W.a₃)) * 0 *
      (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    ↑C (↑C (2 * y₁ + W.a₁ * x₁ + W.a₃)) * 1 + ↑C (↑C (2 * y₁ + W.a₁ * x₁ + W.a₃)) * 0 * ↑C (Y - ↑C x₁) +
        ↑C (↑C 1) * (Y - ↑C (↑C y₁)) +
      ↑C (↑C (1 * -1)) * (Y - ↑C (↑C (-y₁ - W.a₁ * x₁ - W.a₃)))
[PROOFSTEP]
C_simp
[GOAL]
case h.e'_2.h.inr
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
Y_rw :
  (Y - ↑C (↑C y₁)) * (Y - ↑C (↑C (negY W x₁ y₁))) -
      ↑C (Y - ↑C x₁) * (↑C (Y ^ 2 + ↑C (x₁ + W.a₂) * Y + ↑C (x₁ ^ 2 + W.a₂ * x₁ + W.a₄)) - ↑C (↑C W.a₁) * Y) =
    WeierstrassCurve.polynomial W * 1
hy : 2 * y₁ + W.a₁ * x₁ + W.a₃ ≠ 0
W_Y : F := 2 * y₁ + W.a₁ * x₁ + W.a₃
⊢ (2 * ↑C (↑C y₁) + ↑C (↑C W.a₁) * ↑C (↑C x₁) + ↑C (↑C W.a₃)) * 0 *
      (↑C Y ^ 2 + (↑C (↑C x₁) + ↑C (↑C W.a₂)) * ↑C Y + (↑C (↑C x₁) ^ 2 + ↑C (↑C W.a₂) * ↑C (↑C x₁) + ↑C (↑C W.a₄)) -
        ↑C (↑C W.a₁) * Y) =
    (2 * ↑C (↑C y₁) + ↑C (↑C W.a₁) * ↑C (↑C x₁) + ↑C (↑C W.a₃)) * 1 +
          (2 * ↑C (↑C y₁) + ↑C (↑C W.a₁) * ↑C (↑C x₁) + ↑C (↑C W.a₃)) * 0 * (↑C Y - ↑C (↑C x₁)) +
        1 * (Y - ↑C (↑C y₁)) +
      1 * -1 * (Y - (-↑C (↑C y₁) - ↑C (↑C W.a₁) * ↑C (↑C x₁) - ↑C (↑C W.a₃)))
[PROOFSTEP]
ring1
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ ↑(XYIdeal W x₁ (↑C y₁)) * (↑(XYIdeal W x₁ (↑C (negY W x₁ y₁))) * (↑(XIdeal W x₁))⁻¹) = 1
[PROOFSTEP]
rw [← mul_assoc, ← FractionalIdeal.coeIdeal_mul, mul_comm <| XYIdeal W _ _, XYIdeal_neg_mul h₁, XIdeal,
  FractionalIdeal.coe_ideal_span_singleton_mul_inv W.FunctionField <| XClass_ne_zero W x₁]
  -- porting note: increased `maxHeartbeats` for `ring1`
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ XIdeal W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) * (XYIdeal W x₁ (↑C y₁) * XYIdeal W x₂ (↑C y₂)) =
    YIdeal W (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)) *
      XYIdeal W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (↑C (addY W x₁ x₂ y₁ (slope W x₁ x₂ y₁ y₂)))
[PROOFSTEP]
clear h₂
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ XIdeal W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) * (XYIdeal W x₁ (↑C y₁) * XYIdeal W x₂ (↑C y₂)) =
    YIdeal W (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)) *
      XYIdeal W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (↑C (addY W x₁ x₂ y₁ (slope W x₁ x₂ y₁ y₂)))
[PROOFSTEP]
have sup_rw : ∀ a b c d : Ideal W.CoordinateRing, a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c := fun _ _ c _ => by
  rw [← sup_assoc, @sup_comm _ _ c, sup_sup_sup_comm, ← sup_assoc]
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
x✝² x✝¹ c x✝ : Ideal (CoordinateRing W)
⊢ x✝² ⊔ (x✝¹ ⊔ (c ⊔ x✝)) = x✝² ⊔ x✝ ⊔ x✝¹ ⊔ c
[PROOFSTEP]
rw [← sup_assoc, @sup_comm _ _ c, sup_sup_sup_comm, ← sup_assoc]
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
⊢ XIdeal W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) * (XYIdeal W x₁ (↑C y₁) * XYIdeal W x₂ (↑C y₂)) =
    YIdeal W (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)) *
      XYIdeal W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (↑C (addY W x₁ x₂ y₁ (slope W x₁ x₂ y₁ y₂)))
[PROOFSTEP]
rw [XYIdeal_add_eq, XIdeal, mul_comm, W.XYIdeal_eq₁ x₁ y₁ <| W.slope x₁ x₂ y₁ y₂, XYIdeal, XYIdeal_eq₂ h₁' h₂' hxy,
  XYIdeal, span_pair_mul_span_pair]
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
⊢ span
        {XClass W x₁ * XClass W x₂, XClass W x₁ * YClass W (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)),
          YClass W (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)) * XClass W x₂,
          YClass W (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)) *
            YClass W (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))} *
      span {XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))} =
    YIdeal W (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)) *
      (span {↑(CoordinateRing.mk W) (negPolynomial W - ↑C (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)))} ⊔
        span {XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))})
[PROOFSTEP]
simp_rw [span_insert, sup_rw, sup_mul, span_singleton_mul_span_singleton]
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
⊢ span {XClass W x₁ * XClass W x₂ * XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))} ⊔
          span
            {YClass W (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)) *
                  YClass W (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)) *
                XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))} ⊔
        span
          {XClass W x₁ * YClass W (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)) *
              XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))} ⊔
      span
        {YClass W (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)) * XClass W x₂ *
            XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))} =
    YIdeal W (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)) *
      (span {↑(CoordinateRing.mk W) (negPolynomial W - ↑C (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)))} ⊔
        span {XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))})
[PROOFSTEP]
rw [← neg_eq_iff_eq_neg.mpr <| CoordinateRing.C_addPolynomial_slope h₁' h₂' hxy, span_singleton_neg,
  CoordinateRing.C_addPolynomial, _root_.map_mul, YClass]
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
⊢ span
            {↑(CoordinateRing.mk W) (Y - ↑C (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))) *
                ↑(CoordinateRing.mk W) (negPolynomial W - ↑C (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)))} ⊔
          span
            {↑(CoordinateRing.mk W) (Y - ↑C (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))) *
                  ↑(CoordinateRing.mk W) (Y - ↑C (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))) *
                XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))} ⊔
        span
          {XClass W x₁ * ↑(CoordinateRing.mk W) (Y - ↑C (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))) *
              XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))} ⊔
      span
        {↑(CoordinateRing.mk W) (Y - ↑C (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂))) * XClass W x₂ *
            XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))} =
    YIdeal W (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)) *
      (span {↑(CoordinateRing.mk W) (negPolynomial W - ↑C (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)))} ⊔
        span {XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))})
[PROOFSTEP]
simp_rw [mul_comm <| XClass W x₁, mul_assoc, ← span_singleton_mul_span_singleton, ← mul_sup]
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
⊢ span {↑(CoordinateRing.mk W) (Y - ↑C (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)))} *
      (span {↑(CoordinateRing.mk W) (negPolynomial W - ↑C (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)))} ⊔
            span {↑(CoordinateRing.mk W) (Y - ↑C (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)))} *
              span {XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))} ⊔
          span {XClass W x₁} * span {XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))} ⊔
        span {XClass W x₂} * span {XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))}) =
    YIdeal W (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)) *
      (span {↑(CoordinateRing.mk W) (negPolynomial W - ↑C (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)))} ⊔
        span {XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))})
[PROOFSTEP]
rw [span_singleton_mul_span_singleton, ← span_insert, ←
  span_pair_add_mul_right <| -(XClass W <| W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂), mul_neg, ← sub_eq_add_neg, ← sub_mul, ←
  map_sub <| CoordinateRing.mk W, sub_sub_sub_cancel_right, span_insert, ← span_singleton_mul_span_singleton, ← sup_rw,
  ← sup_mul, ← sup_mul]
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
⊢ span {↑(CoordinateRing.mk W) (Y - ↑C (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)))} *
      (span {↑(CoordinateRing.mk W) (negPolynomial W - ↑C (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)))} ⊔
        (span {XClass W x₁} ⊔ (span {XClass W x₂} ⊔ span {↑(CoordinateRing.mk W) (Y - negPolynomial W)})) *
          span {XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))}) =
    YIdeal W (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)) *
      (span {↑(CoordinateRing.mk W) (negPolynomial W - ↑C (linePolynomial x₁ y₁ (slope W x₁ x₂ y₁ y₂)))} ⊔
        span {XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))})
[PROOFSTEP]
apply congr_arg (_ ∘ _)
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
⊢ (span {XClass W x₁} ⊔ (span {XClass W x₂} ⊔ span {↑(CoordinateRing.mk W) (Y - negPolynomial W)})) *
      span {XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))} =
    span {XClass W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂))}
[PROOFSTEP]
convert top_mul (_ : Ideal W.CoordinateRing)
[GOAL]
case h.e'_2.h.e'_5
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
⊢ span {XClass W x₁} ⊔ (span {XClass W x₂} ⊔ span {↑(CoordinateRing.mk W) (Y - negPolynomial W)}) = ⊤
[PROOFSTEP]
simp_rw [XClass, ← @Set.image_singleton _ _ <| CoordinateRing.mk W, ← map_span, ← Ideal.map_sup, eq_top_iff_one,
  mem_map_iff_of_surjective _ <| AdjoinRoot.mk_surjective W.monic_polynomial, ← span_insert, mem_span_insert',
  mem_span_singleton']
[GOAL]
case h.e'_2.h.e'_5
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
⊢ ∃ x,
    (∃ a a_1 a_2, a_2 * (Y - negPolynomial W) = x + a * ↑C (Y - ↑C x₁) + a_1 * ↑C (Y - ↑C x₂)) ∧
      ↑(AdjoinRoot.mk (WeierstrassCurve.polynomial W)) x = 1
[PROOFSTEP]
by_cases hx : x₁ = x₂
[GOAL]
case pos
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
hx : x₁ = x₂
⊢ ∃ x,
    (∃ a a_1 a_2, a_2 * (Y - negPolynomial W) = x + a * ↑C (Y - ↑C x₁) + a_1 * ↑C (Y - ↑C x₂)) ∧
      ↑(AdjoinRoot.mk (WeierstrassCurve.polynomial W)) x = 1
[PROOFSTEP]
rcases hx, Y_eq_of_Y_ne h₁' h₂' hx (hxy hx) with ⟨rfl, rfl⟩
[GOAL]
case pos
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
h₂' : WeierstrassCurve.equation W x₁ y₁
hxy : x₁ = x₁ → y₁ ≠ negY W x₁ y₁
⊢ ∃ x,
    (∃ a a_1 a_2, a_2 * (Y - negPolynomial W) = x + a * ↑C (Y - ↑C x₁) + a_1 * ↑C (Y - ↑C x₁)) ∧
      ↑(AdjoinRoot.mk (WeierstrassCurve.polynomial W)) x = 1
[PROOFSTEP]
let y := (y₁ - W.negY x₁ y₁) ^ 2
[GOAL]
case pos
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
h₂' : WeierstrassCurve.equation W x₁ y₁
hxy : x₁ = x₁ → y₁ ≠ negY W x₁ y₁
y : F := (y₁ - negY W x₁ y₁) ^ 2
⊢ ∃ x,
    (∃ a a_1 a_2, a_2 * (Y - negPolynomial W) = x + a * ↑C (Y - ↑C x₁) + a_1 * ↑C (Y - ↑C x₁)) ∧
      ↑(AdjoinRoot.mk (WeierstrassCurve.polynomial W)) x = 1
[PROOFSTEP]
replace hxy := pow_ne_zero 2 (sub_ne_zero_of_ne <| hxy rfl)
[GOAL]
case pos
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
h₂' : WeierstrassCurve.equation W x₁ y₁
y : F := (y₁ - negY W x₁ y₁) ^ 2
hxy : (y₁ - negY W x₁ y₁) ^ 2 ≠ 0
⊢ ∃ x,
    (∃ a a_1 a_2, a_2 * (Y - negPolynomial W) = x + a * ↑C (Y - ↑C x₁) + a_1 * ↑C (Y - ↑C x₁)) ∧
      ↑(AdjoinRoot.mk (WeierstrassCurve.polynomial W)) x = 1
[PROOFSTEP]
refine
  ⟨1 + C (C <| y⁻¹ * 4) * W.polynomial,
    ⟨C <| C y⁻¹ * (C 4 * X ^ 2 + C (4 * x₁ + W.b₂) * X + C (4 * x₁ ^ 2 + W.b₂ * x₁ + 2 * W.b₄)), 0,
      C (C y⁻¹) * (Y - W.negPolynomial), ?_⟩,
    by rw [map_add, map_one, _root_.map_mul <| CoordinateRing.mk W, AdjoinRoot.mk_self, mul_zero, add_zero]⟩
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
h₂' : WeierstrassCurve.equation W x₁ y₁
y : F := (y₁ - negY W x₁ y₁) ^ 2
hxy : (y₁ - negY W x₁ y₁) ^ 2 ≠ 0
⊢ ↑(AdjoinRoot.mk (WeierstrassCurve.polynomial W)) (1 + ↑C (↑C (y⁻¹ * 4)) * WeierstrassCurve.polynomial W) = 1
[PROOFSTEP]
rw [map_add, map_one, _root_.map_mul <| CoordinateRing.mk W, AdjoinRoot.mk_self, mul_zero, add_zero]
[GOAL]
case pos
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
h₂' : WeierstrassCurve.equation W x₁ y₁
y : F := (y₁ - negY W x₁ y₁) ^ 2
hxy : (y₁ - negY W x₁ y₁) ^ 2 ≠ 0
⊢ ↑C (↑C y⁻¹) * (Y - negPolynomial W) * (Y - negPolynomial W) =
    1 + ↑C (↑C (y⁻¹ * 4)) * WeierstrassCurve.polynomial W +
        ↑C (↑C y⁻¹ * (↑C 4 * Y ^ 2 + ↑C (4 * x₁ + b₂ W) * Y + ↑C (4 * x₁ ^ 2 + b₂ W * x₁ + 2 * b₄ W))) *
          ↑C (Y - ↑C x₁) +
      0 * ↑C (Y - ↑C x₁)
[PROOFSTEP]
rw [WeierstrassCurve.polynomial, negPolynomial, ← mul_right_inj' <| C_ne_zero.mpr <| C_ne_zero.mpr hxy]
[GOAL]
case pos
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
h₂' : WeierstrassCurve.equation W x₁ y₁
y : F := (y₁ - negY W x₁ y₁) ^ 2
hxy : (y₁ - negY W x₁ y₁) ^ 2 ≠ 0
⊢ ↑C (↑C ((y₁ - negY W x₁ y₁) ^ 2)) *
      (↑C (↑C y⁻¹) * (Y - (-Y - ↑C (↑C W.a₁ * Y + ↑C W.a₃))) * (Y - (-Y - ↑C (↑C W.a₁ * Y + ↑C W.a₃)))) =
    ↑C (↑C ((y₁ - negY W x₁ y₁) ^ 2)) *
      (1 +
            ↑C (↑C (y⁻¹ * 4)) *
              (Y ^ 2 + ↑C (↑C W.a₁ * Y + ↑C W.a₃) * Y - ↑C (Y ^ 3 + ↑C W.a₂ * Y ^ 2 + ↑C W.a₄ * Y + ↑C W.a₆)) +
          ↑C (↑C y⁻¹ * (↑C 4 * Y ^ 2 + ↑C (4 * x₁ + b₂ W) * Y + ↑C (4 * x₁ ^ 2 + b₂ W * x₁ + 2 * b₄ W))) *
            ↑C (Y - ↑C x₁) +
        0 * ↑C (Y - ↑C x₁))
[PROOFSTEP]
simp only [mul_add, ← mul_assoc, ← C_mul, mul_inv_cancel hxy]
[GOAL]
case pos
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
h₂' : WeierstrassCurve.equation W x₁ y₁
y : F := (y₁ - negY W x₁ y₁) ^ 2
hxy : (y₁ - negY W x₁ y₁) ^ 2 ≠ 0
⊢ ↑C (↑C 1) * (Y - (-Y - ↑C (↑C W.a₁ * Y + ↑C W.a₃))) * (Y - (-Y - ↑C (↑C W.a₁ * Y + ↑C W.a₃))) =
    ↑C (↑C ((y₁ - negY W x₁ y₁) ^ 2)) * 1 +
          ↑C (↑C (1 * 4)) *
            (Y ^ 2 + ↑C (↑C W.a₁ * Y + ↑C W.a₃) * Y - ↑C (Y ^ 3 + ↑C W.a₂ * Y ^ 2 + ↑C W.a₄ * Y + ↑C W.a₆)) +
        ↑C
          ((↑C (1 * 4) * Y ^ 2 + ↑C (1 * 4 * x₁ + 1 * b₂ W) * Y + ↑C (1 * 4 * x₁ ^ 2 + 1 * b₂ W * x₁ + 1 * 2 * b₄ W)) *
            (Y - ↑C x₁)) +
      ↑C (↑C ((y₁ - negY W x₁ y₁) ^ 2)) * 0 * ↑C (Y - ↑C x₁)
[PROOFSTEP]
linear_combination (norm := (rw [b₂, b₄, negY]; C_simp; ring1))
  -4 * congr_arg C (congr_arg C <| (W.equation_iff _ _).mp h₁')
[GOAL]
case a
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
h₂' : WeierstrassCurve.equation W x₁ y₁
y : F := (y₁ - negY W x₁ y₁) ^ 2
hxy : (y₁ - negY W x₁ y₁) ^ 2 ≠ 0
⊢ ↑C (↑C 1) * (Y - (-Y - ↑C (↑C W.a₁ * Y + ↑C W.a₃))) * (Y - (-Y - ↑C (↑C W.a₁ * Y + ↑C W.a₃))) -
        (↑C (↑C ((y₁ - negY W x₁ y₁) ^ 2)) * 1 +
              ↑C (↑C (1 * 4)) *
                (Y ^ 2 + ↑C (↑C W.a₁ * Y + ↑C W.a₃) * Y - ↑C (Y ^ 3 + ↑C W.a₂ * Y ^ 2 + ↑C W.a₄ * Y + ↑C W.a₆)) +
            ↑C
              ((↑C (1 * 4) * Y ^ 2 + ↑C (1 * 4 * x₁ + 1 * b₂ W) * Y +
                  ↑C (1 * 4 * x₁ ^ 2 + 1 * b₂ W * x₁ + 1 * 2 * b₄ W)) *
                (Y - ↑C x₁)) +
          ↑C (↑C ((y₁ - negY W x₁ y₁) ^ 2)) * 0 * ↑C (Y - ↑C x₁)) -
      (-4 * ↑C (↑C (y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁)) - -4 * ↑C (↑C (x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆))) =
    0
[PROOFSTEP]
rw [b₂, b₄, negY]
[GOAL]
case a
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
h₂' : WeierstrassCurve.equation W x₁ y₁
y : F := (y₁ - negY W x₁ y₁) ^ 2
hxy : (y₁ - negY W x₁ y₁) ^ 2 ≠ 0
⊢ ↑C (↑C 1) * (Y - (-Y - ↑C (↑C W.a₁ * Y + ↑C W.a₃))) * (Y - (-Y - ↑C (↑C W.a₁ * Y + ↑C W.a₃))) -
        (↑C (↑C ((y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2)) * 1 +
              ↑C (↑C (1 * 4)) *
                (Y ^ 2 + ↑C (↑C W.a₁ * Y + ↑C W.a₃) * Y - ↑C (Y ^ 3 + ↑C W.a₂ * Y ^ 2 + ↑C W.a₄ * Y + ↑C W.a₆)) +
            ↑C
              ((↑C (1 * 4) * Y ^ 2 + ↑C (1 * 4 * x₁ + 1 * (W.a₁ ^ 2 + 4 * W.a₂)) * Y +
                  ↑C (1 * 4 * x₁ ^ 2 + 1 * (W.a₁ ^ 2 + 4 * W.a₂) * x₁ + 1 * 2 * (2 * W.a₄ + W.a₁ * W.a₃))) *
                (Y - ↑C x₁)) +
          ↑C (↑C ((y₁ - (-y₁ - W.a₁ * x₁ - W.a₃)) ^ 2)) * 0 * ↑C (Y - ↑C x₁)) -
      (-4 * ↑C (↑C (y₁ ^ 2 + W.a₁ * x₁ * y₁ + W.a₃ * y₁)) - -4 * ↑C (↑C (x₁ ^ 3 + W.a₂ * x₁ ^ 2 + W.a₄ * x₁ + W.a₆))) =
    0
[PROOFSTEP]
C_simp
[GOAL]
case a
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
h₂' : WeierstrassCurve.equation W x₁ y₁
y : F := (y₁ - negY W x₁ y₁) ^ 2
hxy : (y₁ - negY W x₁ y₁) ^ 2 ≠ 0
⊢ 1 * (Y - (-Y - (↑C (↑C W.a₁) * ↑C Y + ↑C (↑C W.a₃)))) * (Y - (-Y - (↑C (↑C W.a₁) * ↑C Y + ↑C (↑C W.a₃)))) -
        ((↑C (↑C y₁) - (-↑C (↑C y₁) - ↑C (↑C W.a₁) * ↑C (↑C x₁) - ↑C (↑C W.a₃))) ^ 2 * 1 +
              1 * 4 *
                (Y ^ 2 + (↑C (↑C W.a₁) * ↑C Y + ↑C (↑C W.a₃)) * Y -
                  (↑C Y ^ 3 + ↑C (↑C W.a₂) * ↑C Y ^ 2 + ↑C (↑C W.a₄) * ↑C Y + ↑C (↑C W.a₆))) +
            (1 * 4 * ↑C Y ^ 2 + (1 * 4 * ↑C (↑C x₁) + 1 * (↑C (↑C W.a₁) ^ 2 + 4 * ↑C (↑C W.a₂))) * ↑C Y +
                (1 * 4 * ↑C (↑C x₁) ^ 2 + 1 * (↑C (↑C W.a₁) ^ 2 + 4 * ↑C (↑C W.a₂)) * ↑C (↑C x₁) +
                  1 * 2 * (2 * ↑C (↑C W.a₄) + ↑C (↑C W.a₁) * ↑C (↑C W.a₃)))) *
              (↑C Y - ↑C (↑C x₁)) +
          (↑C (↑C y₁) - (-↑C (↑C y₁) - ↑C (↑C W.a₁) * ↑C (↑C x₁) - ↑C (↑C W.a₃))) ^ 2 * 0 * (↑C Y - ↑C (↑C x₁))) -
      (-4 * (↑C (↑C y₁) ^ 2 + ↑C (↑C W.a₁) * ↑C (↑C x₁) * ↑C (↑C y₁) + ↑C (↑C W.a₃) * ↑C (↑C y₁)) -
        -4 * (↑C (↑C x₁) ^ 3 + ↑C (↑C W.a₂) * ↑C (↑C x₁) ^ 2 + ↑C (↑C W.a₄) * ↑C (↑C x₁) + ↑C (↑C W.a₆))) =
    0
[PROOFSTEP]
ring1
[GOAL]
case neg
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
hx : ¬x₁ = x₂
⊢ ∃ x,
    (∃ a a_1 a_2, a_2 * (Y - negPolynomial W) = x + a * ↑C (Y - ↑C x₁) + a_1 * ↑C (Y - ↑C x₂)) ∧
      ↑(AdjoinRoot.mk (WeierstrassCurve.polynomial W)) x = 1
[PROOFSTEP]
replace hx := sub_ne_zero_of_ne hx
[GOAL]
case neg
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
hx : x₁ - x₂ ≠ 0
⊢ ∃ x,
    (∃ a a_1 a_2, a_2 * (Y - negPolynomial W) = x + a * ↑C (Y - ↑C x₁) + a_1 * ↑C (Y - ↑C x₂)) ∧
      ↑(AdjoinRoot.mk (WeierstrassCurve.polynomial W)) x = 1
[PROOFSTEP]
refine ⟨_, ⟨⟨C <| C (x₁ - x₂)⁻¹, C <| C <| (x₁ - x₂)⁻¹ * -1, 0, ?_⟩, map_one _⟩⟩
[GOAL]
case neg
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
hx : x₁ - x₂ ≠ 0
⊢ 0 * (Y - negPolynomial W) = 1 + ↑C (↑C (x₁ - x₂)⁻¹) * ↑C (Y - ↑C x₁) + ↑C (↑C ((x₁ - x₂)⁻¹ * -1)) * ↑C (Y - ↑C x₂)
[PROOFSTEP]
rw [← mul_right_inj' <| C_ne_zero.mpr <| C_ne_zero.mpr hx]
[GOAL]
case neg
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
hx : x₁ - x₂ ≠ 0
⊢ ↑C (↑C (x₁ - x₂)) * (0 * (Y - negPolynomial W)) =
    ↑C (↑C (x₁ - x₂)) * (1 + ↑C (↑C (x₁ - x₂)⁻¹) * ↑C (Y - ↑C x₁) + ↑C (↑C ((x₁ - x₂)⁻¹ * -1)) * ↑C (Y - ↑C x₂))
[PROOFSTEP]
simp only [← mul_assoc, mul_add, ← C_mul, mul_inv_cancel hx]
[GOAL]
case neg
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
hx : x₁ - x₂ ≠ 0
⊢ ↑C (↑C (x₁ - x₂)) * 0 * (Y - negPolynomial W) =
    ↑C (↑C (x₁ - x₂)) * 1 + ↑C (↑C 1 * (Y - ↑C x₁)) + ↑C (↑C (1 * -1) * (Y - ↑C x₂))
[PROOFSTEP]
C_simp
[GOAL]
case neg
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
sup_rw : ∀ (a b c d : Ideal (CoordinateRing W)), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
hx : x₁ - x₂ ≠ 0
⊢ (↑C (↑C x₁) - ↑C (↑C x₂)) * 0 * (Y - negPolynomial W) =
    (↑C (↑C x₁) - ↑C (↑C x₂)) * 1 + 1 * (↑C Y - ↑C (↑C x₁)) + 1 * -1 * (↑C Y - ↑C (↑C x₂))
[PROOFSTEP]
ring1
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ ↑ClassGroup.mk (XYIdeal' (_ : WeierstrassCurve.nonsingular W x₁ (negY W x₁ y₁))) * ↑ClassGroup.mk (XYIdeal' h₁) = 1
[PROOFSTEP]
rw [← _root_.map_mul]
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ ↑ClassGroup.mk (XYIdeal' (_ : WeierstrassCurve.nonsingular W x₁ (negY W x₁ y₁)) * XYIdeal' h₁) = 1
[PROOFSTEP]
exact
  (ClassGroup.mk_eq_one_of_coe_ideal <| by
        exact
          (FractionalIdeal.coeIdeal_mul _ _).symm.trans <| FractionalIdeal.coeIdeal_inj.mpr <| XYIdeal_neg_mul h₁).mpr
    ⟨_, XClass_ne_zero W _, rfl⟩
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ ↑(XYIdeal' (_ : WeierstrassCurve.nonsingular W x₁ (negY W x₁ y₁)) * XYIdeal' h₁) = ↑(span {XClass W ?m.4456306})
[PROOFSTEP]
exact (FractionalIdeal.coeIdeal_mul _ _).symm.trans <| FractionalIdeal.coeIdeal_inj.mpr <| XYIdeal_neg_mul h₁
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ ↑ClassGroup.mk (XYIdeal' h₁) * ↑ClassGroup.mk (XYIdeal' h₂) =
    ↑ClassGroup.mk
      (XYIdeal'
        (_ :
          WeierstrassCurve.nonsingular W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (addY W x₁ x₂ y₁ (slope W x₁ x₂ y₁ y₂))))
[PROOFSTEP]
rw [← _root_.map_mul]
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ ↑ClassGroup.mk (XYIdeal' h₁ * XYIdeal' h₂) =
    ↑ClassGroup.mk
      (XYIdeal'
        (_ :
          WeierstrassCurve.nonsingular W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (addY W x₁ x₂ y₁ (slope W x₁ x₂ y₁ y₂))))
[PROOFSTEP]
exact
  (ClassGroup.mk_eq_mk_of_coe_ideal (by exact (FractionalIdeal.coeIdeal_mul _ _).symm) <| XYIdeal'_eq _).mpr
    ⟨_, _, XClass_ne_zero W _, YClass_ne_zero W _, XYIdeal_mul_XYIdeal h₁.left h₂.left hxy⟩
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ negY W x₂ y₂
⊢ ↑(XYIdeal' h₁ * XYIdeal' h₂) = ↑(XYIdeal W x₁ (↑C y₁) * XYIdeal W x₂ (↑C y₂))
[PROOFSTEP]
exact (FractionalIdeal.coeIdeal_mul _ _).symm
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ ∀ (x y : Point W),
    ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } (x + y) =
      ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } x +
        ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } y
[PROOFSTEP]
rintro (_ | @⟨x₁, y₁, h₁⟩) (_ | @⟨x₂, y₂, h₂⟩)
[GOAL]
case zero.zero
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } (zero + zero) =
    ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } zero +
      ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } zero
case zero.some
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂✝ y₁ y₂✝ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂✝ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₂ y₂ : F
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
⊢ ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } (zero + some h₂) =
    ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } zero +
      ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } (some h₂)
case some.zero
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂ y₁✝ y₂ : F
h₁✝ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂ y₂
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
⊢ ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } (some h₁ + zero) =
    ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } (some h₁) +
      ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } zero
case some.some
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁✝ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂✝ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
⊢ ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } (some h₁ + some h₂) =
    ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } (some h₁) +
      ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } (some h₂)
[PROOFSTEP]
any_goals simp only [zero_def, toClassFun, _root_.zero_add, _root_.add_zero]
[GOAL]
case zero.zero
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } (zero + zero) =
    ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } zero +
      ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } zero
[PROOFSTEP]
simp only [zero_def, toClassFun, _root_.zero_add, _root_.add_zero]
[GOAL]
case zero.some
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂✝ y₁ y₂✝ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂✝ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₂ y₂ : F
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
⊢ ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } (zero + some h₂) =
    ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } zero +
      ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } (some h₂)
[PROOFSTEP]
simp only [zero_def, toClassFun, _root_.zero_add, _root_.add_zero]
[GOAL]
case some.zero
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂ y₁✝ y₂ : F
h₁✝ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂ y₂
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
⊢ ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } (some h₁ + zero) =
    ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } (some h₁) +
      ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } zero
[PROOFSTEP]
simp only [zero_def, toClassFun, _root_.zero_add, _root_.add_zero]
[GOAL]
case some.some
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁✝ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂✝ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
⊢ ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } (some h₁ + some h₂) =
    ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } (some h₁) +
      ZeroHom.toFun { toFun := toClassFun, map_zero' := (_ : toClassFun 0 = toClassFun 0) } (some h₂)
[PROOFSTEP]
simp only [zero_def, toClassFun, _root_.zero_add, _root_.add_zero]
[GOAL]
case some.some
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁✝ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂✝ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
⊢ (match some h₁ + some h₂ with
    | zero => 0
    | some h => ↑Additive.ofMul (↑ClassGroup.mk (XYIdeal' h))) =
    ↑Additive.ofMul (↑ClassGroup.mk (XYIdeal' h₁)) + ↑Additive.ofMul (↑ClassGroup.mk (XYIdeal' h₂))
[PROOFSTEP]
by_cases hx : x₁ = x₂
[GOAL]
case pos
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁✝ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂✝ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
hx : x₁ = x₂
⊢ (match some h₁ + some h₂ with
    | zero => 0
    | some h => ↑Additive.ofMul (↑ClassGroup.mk (XYIdeal' h))) =
    ↑Additive.ofMul (↑ClassGroup.mk (XYIdeal' h₁)) + ↑Additive.ofMul (↑ClassGroup.mk (XYIdeal' h₂))
[PROOFSTEP]
by_cases hy : y₁ = W.negY x₂ y₂
[GOAL]
case pos
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁✝ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂✝ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
hx : x₁ = x₂
hy : y₁ = negY W x₂ y₂
⊢ (match some h₁ + some h₂ with
    | zero => 0
    | some h => ↑Additive.ofMul (↑ClassGroup.mk (XYIdeal' h))) =
    ↑Additive.ofMul (↑ClassGroup.mk (XYIdeal' h₁)) + ↑Additive.ofMul (↑ClassGroup.mk (XYIdeal' h₂))
[PROOFSTEP]
substs hx hy
[GOAL]
case pos
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂ y₁ y₂✝ : F
h₁✝ : WeierstrassCurve.nonsingular W x₁✝ y₁
h₂✝ : WeierstrassCurve.nonsingular W x₂ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂✝
x₁ y₂ : F
h₂ : WeierstrassCurve.nonsingular W x₁ y₂
h₁ : WeierstrassCurve.nonsingular W x₁ (negY W x₁ y₂)
⊢ (match some h₁ + some h₂ with
    | zero => 0
    | some h => ↑Additive.ofMul (↑ClassGroup.mk (XYIdeal' h))) =
    ↑Additive.ofMul (↑ClassGroup.mk (XYIdeal' h₁)) + ↑Additive.ofMul (↑ClassGroup.mk (XYIdeal' h₂))
[PROOFSTEP]
simpa only [some_add_some_of_Y_eq rfl rfl] using (mk_XYIdeal'_mul_mk_XYIdeal'_of_Y_eq h₂).symm
[GOAL]
case neg
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁✝ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂✝ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
hx : x₁ = x₂
hy : ¬y₁ = negY W x₂ y₂
⊢ (match some h₁ + some h₂ with
    | zero => 0
    | some h => ↑Additive.ofMul (↑ClassGroup.mk (XYIdeal' h))) =
    ↑Additive.ofMul (↑ClassGroup.mk (XYIdeal' h₁)) + ↑Additive.ofMul (↑ClassGroup.mk (XYIdeal' h₂))
[PROOFSTEP]
simpa only [some_add_some_of_Y_ne hx hy] using (mk_XYIdeal'_mul_mk_XYIdeal' h₁ h₂ fun _ => hy).symm
[GOAL]
case neg
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁✝ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂✝ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
hx : ¬x₁ = x₂
⊢ (match some h₁ + some h₂ with
    | zero => 0
    | some h => ↑Additive.ofMul (↑ClassGroup.mk (XYIdeal' h))) =
    ↑Additive.ofMul (↑ClassGroup.mk (XYIdeal' h₁)) + ↑Additive.ofMul (↑ClassGroup.mk (XYIdeal' h₂))
[PROOFSTEP]
simpa only [some_add_some_of_X_ne hx] using (mk_XYIdeal'_mul_mk_XYIdeal' h₁ h₂ fun h => (hx h).elim).symm
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
P Q : Point W
⊢ P + Q = 0 ↔ P = -Q
[PROOFSTEP]
rcases P, Q with ⟨_ | @⟨x₁, y₁, _⟩, _ | @⟨x₂, y₂, _⟩⟩
[GOAL]
case zero.zero
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ zero + zero = 0 ↔ zero = -zero
case zero.some
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂✝ y₁ y₂✝ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular W x₂ y₂
⊢ zero + some h✝ = 0 ↔ zero = -some h✝
case some.zero
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂ y₁✝ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂ y₂
x₁ y₁ : F
h✝ : WeierstrassCurve.nonsingular W x₁ y₁
⊢ some h✝ + zero = 0 ↔ some h✝ = -zero
case some.some
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular W x₂ y₂
⊢ some h✝¹ + some h✝ = 0 ↔ some h✝¹ = -some h✝
[PROOFSTEP]
any_goals rfl
[GOAL]
case zero.zero
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ zero + zero = 0 ↔ zero = -zero
[PROOFSTEP]
rfl
[GOAL]
case zero.some
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂✝ y₁ y₂✝ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular W x₂ y₂
⊢ zero + some h✝ = 0 ↔ zero = -some h✝
[PROOFSTEP]
rfl
[GOAL]
case some.zero
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂ y₁✝ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂ y₂
x₁ y₁ : F
h✝ : WeierstrassCurve.nonsingular W x₁ y₁
⊢ some h✝ + zero = 0 ↔ some h✝ = -zero
[PROOFSTEP]
rfl
[GOAL]
case some.some
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular W x₂ y₂
⊢ some h✝¹ + some h✝ = 0 ↔ some h✝¹ = -some h✝
[PROOFSTEP]
rfl
[GOAL]
case zero.some
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂✝ y₁ y₂✝ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular W x₂ y₂
⊢ zero + some h✝ = 0 ↔ zero = -some h✝
[PROOFSTEP]
rw [zero_def, zero_add, ← neg_eq_iff_eq_neg, neg_zero, eq_comm]
[GOAL]
case some.some
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular W x₂ y₂
⊢ some h✝¹ + some h✝ = 0 ↔ some h✝¹ = -some h✝
[PROOFSTEP]
rw [neg_some, some.injEq]
[GOAL]
case some.some
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular W x₂ y₂
⊢ some h✝¹ + some h✝ = 0 ↔ x₁ = x₂ ∧ y₁ = negY W x₂ y₂
[PROOFSTEP]
constructor
[GOAL]
case some.some.mp
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular W x₂ y₂
⊢ some h✝¹ + some h✝ = 0 → x₁ = x₂ ∧ y₁ = negY W x₂ y₂
[PROOFSTEP]
intro h
[GOAL]
case some.some.mp
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular W x₂ y₂
h : some h✝¹ + some h✝ = 0
⊢ x₁ = x₂ ∧ y₁ = negY W x₂ y₂
[PROOFSTEP]
by_cases hx : x₁ = x₂
[GOAL]
case pos
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular W x₂ y₂
h : some h✝¹ + some h✝ = 0
hx : x₁ = x₂
⊢ x₁ = x₂ ∧ y₁ = negY W x₂ y₂
[PROOFSTEP]
by_cases hy : y₁ = W.negY x₂ y₂
[GOAL]
case pos
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular W x₂ y₂
h : some h✝¹ + some h✝ = 0
hx : x₁ = x₂
hy : y₁ = negY W x₂ y₂
⊢ x₁ = x₂ ∧ y₁ = negY W x₂ y₂
[PROOFSTEP]
exact ⟨hx, hy⟩
[GOAL]
case neg
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular W x₂ y₂
h : some h✝¹ + some h✝ = 0
hx : x₁ = x₂
hy : ¬y₁ = negY W x₂ y₂
⊢ x₁ = x₂ ∧ y₁ = negY W x₂ y₂
[PROOFSTEP]
rw [some_add_some_of_Y_ne hx hy] at h
[GOAL]
case neg
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular W x₂ y₂
hx : x₁ = x₂
hy : ¬y₁ = negY W x₂ y₂
h :
  some
      (_ :
        WeierstrassCurve.nonsingular W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (addY W x₁ x₂ y₁ (slope W x₁ x₂ y₁ y₂))) =
    0
⊢ x₁ = x₂ ∧ y₁ = negY W x₂ y₂
[PROOFSTEP]
contradiction
[GOAL]
case neg
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular W x₂ y₂
h : some h✝¹ + some h✝ = 0
hx : ¬x₁ = x₂
⊢ x₁ = x₂ ∧ y₁ = negY W x₂ y₂
[PROOFSTEP]
rw [some_add_some_of_X_ne hx] at h
[GOAL]
case neg
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular W x₂ y₂
hx : ¬x₁ = x₂
h :
  some
      (_ :
        WeierstrassCurve.nonsingular W (addX W x₁ x₂ (slope W x₁ x₂ y₁ y₂)) (addY W x₁ x₂ y₁ (slope W x₁ x₂ y₁ y₂))) =
    0
⊢ x₁ = x₂ ∧ y₁ = negY W x₂ y₂
[PROOFSTEP]
contradiction
[GOAL]
case some.some.mpr
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁✝ x₂✝ y₁✝ y₂✝ : F
h₁ : WeierstrassCurve.nonsingular W x₁✝ y₁✝
h₂ : WeierstrassCurve.nonsingular W x₂✝ y₂✝
h₁' : WeierstrassCurve.equation W x₁✝ y₁✝
h₂' : WeierstrassCurve.equation W x₂✝ y₂✝
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular W x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular W x₂ y₂
⊢ x₁ = x₂ ∧ y₁ = negY W x₂ y₂ → some h✝¹ + some h✝ = 0
[PROOFSTEP]
exact fun ⟨hx, hy⟩ => some_add_some_of_Y_eq hx hy
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
P : Point W
⊢ -P + P = 0
[PROOFSTEP]
rw [add_eq_zero]
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
P Q : Point W
⊢ -P + Q = 0 ↔ P = Q
[PROOFSTEP]
rw [add_eq_zero, neg_inj]
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
P : Point W
⊢ ↑toClass P = 0 ↔ P = 0
[PROOFSTEP]
constructor
[GOAL]
case mp
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
P : Point W
⊢ ↑toClass P = 0 → P = 0
[PROOFSTEP]
intro hP
[GOAL]
case mp
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
P : Point W
hP : ↑toClass P = 0
⊢ P = 0
[PROOFSTEP]
rcases P with (_ | @⟨_, _, ⟨h, _⟩⟩)
[GOAL]
case mp.zero
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
hP : ↑toClass zero = 0
⊢ zero = 0
[PROOFSTEP]
rfl
[GOAL]
case mp.some.intro
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
x✝ y✝ : F
h : WeierstrassCurve.equation W x✝ y✝
right✝ :
  eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialX W)) ≠ 0 ∨
    eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialY W)) ≠ 0
hP :
  ↑toClass
      (some
        (_ :
          WeierstrassCurve.equation W x✝ y✝ ∧
            (eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialX W)) ≠ 0 ∨
              eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialY W)) ≠ 0))) =
    0
⊢ some
      (_ :
        WeierstrassCurve.equation W x✝ y✝ ∧
          (eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialX W)) ≠ 0 ∨
            eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialY W)) ≠ 0)) =
    0
[PROOFSTEP]
rcases(ClassGroup.mk_eq_one_of_coe_ideal <| by rfl).mp hP with ⟨p, h0, hp⟩
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
x✝ y✝ : F
h : WeierstrassCurve.equation W x✝ y✝
right✝ :
  eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialX W)) ≠ 0 ∨
    eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialY W)) ≠ 0
hP :
  ↑toClass
      (some
        (_ :
          WeierstrassCurve.equation W x✝ y✝ ∧
            (eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialX W)) ≠ 0 ∨
              eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialY W)) ≠ 0))) =
    0
⊢ ↑(XYIdeal'
        (_ :
          WeierstrassCurve.equation W x✝ y✝ ∧
            (eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialX W)) ≠ 0 ∨
              eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialY W)) ≠ 0))) =
    ↑?m.4705169
[PROOFSTEP]
rfl
[GOAL]
case mp.some.intro.intro.intro
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
x✝ y✝ : F
h : WeierstrassCurve.equation W x✝ y✝
right✝ :
  eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialX W)) ≠ 0 ∨
    eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialY W)) ≠ 0
hP :
  ↑toClass
      (some
        (_ :
          WeierstrassCurve.equation W x✝ y✝ ∧
            (eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialX W)) ≠ 0 ∨
              eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialY W)) ≠ 0))) =
    0
p : CoordinateRing W
h0 : p ≠ 0
hp : XYIdeal W x✝ (↑C y✝) = span {p}
⊢ some
      (_ :
        WeierstrassCurve.equation W x✝ y✝ ∧
          (eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialX W)) ≠ 0 ∨
            eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialY W)) ≠ 0)) =
    0
[PROOFSTEP]
apply (p.natDegree_norm_ne_one _).elim
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
x✝ y✝ : F
h : WeierstrassCurve.equation W x✝ y✝
right✝ :
  eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialX W)) ≠ 0 ∨
    eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialY W)) ≠ 0
hP :
  ↑toClass
      (some
        (_ :
          WeierstrassCurve.equation W x✝ y✝ ∧
            (eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialX W)) ≠ 0 ∨
              eval x✝ (eval (↑C y✝) (WeierstrassCurve.polynomialY W)) ≠ 0))) =
    0
p : CoordinateRing W
h0 : p ≠ 0
hp : XYIdeal W x✝ (↑C y✝) = span {p}
⊢ natDegree (↑(Algebra.norm F[X]) p) = 1
[PROOFSTEP]
rw [← finrank_quotient_span_eq_natDegree_norm (CoordinateRing.basis W) h0, ←
  (quotientEquivAlgOfEq F hp).toLinearEquiv.finrank_eq, (quotientXYIdealEquiv W h).toLinearEquiv.finrank_eq,
  FiniteDimensional.finrank_self]
[GOAL]
case mpr
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
P : Point W
⊢ P = 0 → ↑toClass P = 0
[PROOFSTEP]
exact congr_arg toClass
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
⊢ Function.Injective ↑toClass
[PROOFSTEP]
rintro (_ | h) _ hP
[GOAL]
case zero
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
a₂✝ : Point W
hP : ↑toClass zero = ↑toClass a₂✝
⊢ zero = a₂✝
case some
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
x✝ y✝ : F
h : WeierstrassCurve.nonsingular W x✝ y✝
a₂✝ : Point W
hP : ↑toClass (some h) = ↑toClass a₂✝
⊢ some h = a₂✝
[PROOFSTEP]
all_goals rw [← neg_add_eq_zero, ← toClass_eq_zero, map_add, ← hP]
[GOAL]
case zero
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
a₂✝ : Point W
hP : ↑toClass zero = ↑toClass a₂✝
⊢ zero = a₂✝
[PROOFSTEP]
rw [← neg_add_eq_zero, ← toClass_eq_zero, map_add, ← hP]
[GOAL]
case some
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
x✝ y✝ : F
h : WeierstrassCurve.nonsingular W x✝ y✝
a₂✝ : Point W
hP : ↑toClass (some h) = ↑toClass a₂✝
⊢ some h = a₂✝
[PROOFSTEP]
rw [← neg_add_eq_zero, ← toClass_eq_zero, map_add, ← hP]
[GOAL]
case zero
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
a₂✝ : Point W
hP : ↑toClass zero = ↑toClass a₂✝
⊢ ↑toClass (-zero) + ↑toClass zero = 0
[PROOFSTEP]
exact zero_add 0
[GOAL]
case some
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
x✝ y✝ : F
h : WeierstrassCurve.nonsingular W x✝ y✝
a₂✝ : Point W
hP : ↑toClass (some h) = ↑toClass a₂✝
⊢ ↑toClass (-some h) + ↑toClass (some h) = 0
[PROOFSTEP]
exact mk_XYIdeal'_mul_mk_XYIdeal'_of_Y_eq h
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
P Q : Point W
⊢ ↑toClass (P + Q) = ↑toClass (Q + P)
[PROOFSTEP]
simp only [map_add, _root_.add_comm]
[GOAL]
F : Type u
inst✝ : Field F
W : WeierstrassCurve F
x₁ x₂ y₁ y₂ : F
h₁ : WeierstrassCurve.nonsingular W x₁ y₁
h₂ : WeierstrassCurve.nonsingular W x₂ y₂
h₁' : WeierstrassCurve.equation W x₁ y₁
h₂' : WeierstrassCurve.equation W x₂ y₂
P Q R : Point W
⊢ ↑toClass (P + Q + R) = ↑toClass (P + (Q + R))
[PROOFSTEP]
simp only [map_add, _root_.add_assoc]
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
⊢ ∀ (x y : W⟮F⟯),
    ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (x + y) =
      ZeroHom.toFun
          { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) } x +
        ZeroHom.toFun
          { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) } y
[PROOFSTEP]
rintro (_ | @⟨x₁, y₁, _⟩) (_ | @⟨x₂, y₂, _⟩)
[GOAL]
case zero.zero
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
⊢ ZeroHom.toFun { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
      (zero + zero) =
    ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) } zero +
      ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) } zero
case zero.some
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
⊢ ZeroHom.toFun { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
      (zero + some h✝) =
    ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) } zero +
      ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (some h✝)
case some.zero
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
⊢ ZeroHom.toFun { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
      (some h✝ + zero) =
    ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (some h✝) +
      ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) } zero
case some.some
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
⊢ ZeroHom.toFun { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
      (some h✝¹ + some h✝) =
    ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (some h✝¹) +
      ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (some h✝)
[PROOFSTEP]
any_goals rfl
[GOAL]
case zero.zero
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
⊢ ZeroHom.toFun { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
      (zero + zero) =
    ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) } zero +
      ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) } zero
[PROOFSTEP]
rfl
[GOAL]
case zero.some
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
⊢ ZeroHom.toFun { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
      (zero + some h✝) =
    ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) } zero +
      ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (some h✝)
[PROOFSTEP]
rfl
[GOAL]
case some.zero
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
⊢ ZeroHom.toFun { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
      (some h✝ + zero) =
    ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (some h✝) +
      ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) } zero
[PROOFSTEP]
rfl
[GOAL]
case some.some
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
⊢ ZeroHom.toFun { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
      (some h✝¹ + some h✝) =
    ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (some h✝¹) +
      ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (some h✝)
[PROOFSTEP]
rfl
[GOAL]
case some.some
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
⊢ ZeroHom.toFun { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
      (some h✝¹ + some h✝) =
    ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (some h✝¹) +
      ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (some h✝)
[PROOFSTEP]
by_cases hx : x₁ = x₂
[GOAL]
case pos
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
hx : x₁ = x₂
⊢ ZeroHom.toFun { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
      (some h✝¹ + some h✝) =
    ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (some h✝¹) +
      ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (some h✝)
[PROOFSTEP]
by_cases hy : y₁ = (W.baseChange F).negY x₂ y₂
[GOAL]
case pos
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
hx : x₁ = x₂
hy : y₁ = negY (baseChange W F) x₂ y₂
⊢ ZeroHom.toFun { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
      (some h✝¹ + some h✝) =
    ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (some h✝¹) +
      ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (some h✝)
[PROOFSTEP]
simp only [some_add_some_of_Y_eq hx hy, ofBaseChangeFun]
[GOAL]
case pos
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
hx : x₁ = x₂
hy : y₁ = negY (baseChange W F) x₂ y₂
⊢ 0 =
    some (_ : WeierstrassCurve.nonsingular (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) y₁)) +
      some (_ : WeierstrassCurve.nonsingular (baseChange W K) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₂))
[PROOFSTEP]
rw [some_add_some_of_Y_eq <| congr_arg _ hx]
[GOAL]
case pos
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
hx : x₁ = x₂
hy : y₁ = negY (baseChange W F) x₂ y₂
⊢ ↑(algebraMap F K) y₁ = negY (baseChange W K) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₂)
[PROOFSTEP]
rw [hy, baseChange_negY_of_baseChange]
[GOAL]
case neg
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
hx : x₁ = x₂
hy : ¬y₁ = negY (baseChange W F) x₂ y₂
⊢ ZeroHom.toFun { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
      (some h✝¹ + some h✝) =
    ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (some h✝¹) +
      ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (some h✝)
[PROOFSTEP]
simp only [some_add_some_of_Y_ne hx hy, ofBaseChangeFun]
[GOAL]
case neg
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
hx : x₁ = x₂
hy : ¬y₁ = negY (baseChange W F) x₂ y₂
⊢ some
      (_ :
        WeierstrassCurve.nonsingular (baseChange W K)
          (↑(algebraMap F K) (addX (baseChange W F) x₁ x₂ (slope (baseChange W F) x₁ x₂ y₁ y₂)))
          (↑(algebraMap F K) (addY (baseChange W F) x₁ x₂ y₁ (slope (baseChange W F) x₁ x₂ y₁ y₂)))) =
    some (_ : WeierstrassCurve.nonsingular (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) y₁)) +
      some (_ : WeierstrassCurve.nonsingular (baseChange W K) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₂))
[PROOFSTEP]
rw [some_add_some_of_Y_ne <| congr_arg _ hx]
[GOAL]
case neg
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
hx : x₁ = x₂
hy : ¬y₁ = negY (baseChange W F) x₂ y₂
⊢ some
      (_ :
        WeierstrassCurve.nonsingular (baseChange W K)
          (↑(algebraMap F K) (addX (baseChange W F) x₁ x₂ (slope (baseChange W F) x₁ x₂ y₁ y₂)))
          (↑(algebraMap F K) (addY (baseChange W F) x₁ x₂ y₁ (slope (baseChange W F) x₁ x₂ y₁ y₂)))) =
    some
      (_ :
        WeierstrassCurve.nonsingular (baseChange W K)
          (addX (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) x₂)
            (slope (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₁)
              (↑(algebraMap F K) y₂)))
          (addY (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₁)
            (slope (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₁)
              (↑(algebraMap F K) y₂))))
[PROOFSTEP]
simp only [baseChange_addX_of_baseChange, baseChange_addY_of_baseChange, baseChange_slope_of_baseChange]
[GOAL]
case neg
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
hx : x₁ = x₂
hy : ¬y₁ = negY (baseChange W F) x₂ y₂
⊢ ↑(algebraMap F K) y₁ ≠ negY (baseChange W K) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₂)
[PROOFSTEP]
rw [baseChange_negY_of_baseChange]
[GOAL]
case neg
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
hx : x₁ = x₂
hy : ¬y₁ = negY (baseChange W F) x₂ y₂
⊢ ↑(algebraMap F K) y₁ ≠ ↑(algebraMap F K) (negY (baseChange W F) x₂ y₂)
[PROOFSTEP]
contrapose! hy
[GOAL]
case neg
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
hx : x₁ = x₂
hy : ↑(algebraMap F K) y₁ = ↑(algebraMap F K) (negY (baseChange W F) x₂ y₂)
⊢ y₁ = negY (baseChange W F) x₂ y₂
[PROOFSTEP]
exact NoZeroSMulDivisors.algebraMap_injective F K hy
[GOAL]
case neg
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
hx : ¬x₁ = x₂
⊢ ZeroHom.toFun { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
      (some h✝¹ + some h✝) =
    ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (some h✝¹) +
      ZeroHom.toFun
        { toFun := ofBaseChangeFun W F K, map_zero' := (_ : ofBaseChangeFun W F K 0 = ofBaseChangeFun W F K 0) }
        (some h✝)
[PROOFSTEP]
simp only [some_add_some_of_X_ne hx, ofBaseChangeFun]
[GOAL]
case neg
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
hx : ¬x₁ = x₂
⊢ some
      (_ :
        WeierstrassCurve.nonsingular (baseChange W K)
          (↑(algebraMap F K) (addX (baseChange W F) x₁ x₂ (slope (baseChange W F) x₁ x₂ y₁ y₂)))
          (↑(algebraMap F K) (addY (baseChange W F) x₁ x₂ y₁ (slope (baseChange W F) x₁ x₂ y₁ y₂)))) =
    some (_ : WeierstrassCurve.nonsingular (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) y₁)) +
      some (_ : WeierstrassCurve.nonsingular (baseChange W K) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₂))
[PROOFSTEP]
rw [some_add_some_of_X_ne]
[GOAL]
case neg
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
hx : ¬x₁ = x₂
⊢ some
      (_ :
        WeierstrassCurve.nonsingular (baseChange W K)
          (↑(algebraMap F K) (addX (baseChange W F) x₁ x₂ (slope (baseChange W F) x₁ x₂ y₁ y₂)))
          (↑(algebraMap F K) (addY (baseChange W F) x₁ x₂ y₁ (slope (baseChange W F) x₁ x₂ y₁ y₂)))) =
    some
      (_ :
        WeierstrassCurve.nonsingular (baseChange W K)
          (addX (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) x₂)
            (slope (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₁)
              (↑(algebraMap F K) y₂)))
          (addY (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₁)
            (slope (baseChange W K) (↑(algebraMap F K) x₁) (↑(algebraMap F K) x₂) (↑(algebraMap F K) y₁)
              (↑(algebraMap F K) y₂))))
[PROOFSTEP]
simp only [baseChange_addX_of_baseChange, baseChange_addY_of_baseChange, baseChange_slope_of_baseChange]
[GOAL]
case neg
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
hx : ¬x₁ = x₂
⊢ ↑(algebraMap F K) x₁ ≠ ↑(algebraMap F K) x₂
[PROOFSTEP]
contrapose! hx
[GOAL]
case neg
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x₁ y₁ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x₁ y₁
x₂ y₂ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x₂ y₂
hx : ↑(algebraMap F K) x₁ = ↑(algebraMap F K) x₂
⊢ x₁ = x₂
[PROOFSTEP]
exact NoZeroSMulDivisors.algebraMap_injective F K hx
[GOAL]
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
⊢ Function.Injective ↑(ofBaseChange W F K)
[PROOFSTEP]
rintro (_ | _) (_ | _) h
[GOAL]
case zero.zero
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
h : ↑(ofBaseChange W F K) zero = ↑(ofBaseChange W F K) zero
⊢ zero = zero
case zero.some
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x✝ y✝ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x✝ y✝
h : ↑(ofBaseChange W F K) zero = ↑(ofBaseChange W F K) (some h✝)
⊢ zero = some h✝
case some.zero
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x✝ y✝ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x✝ y✝
h : ↑(ofBaseChange W F K) (some h✝) = ↑(ofBaseChange W F K) zero
⊢ some h✝ = zero
case some.some
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x✝¹ y✝¹ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x✝¹ y✝¹
x✝ y✝ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x✝ y✝
h : ↑(ofBaseChange W F K) (some h✝¹) = ↑(ofBaseChange W F K) (some h✝)
⊢ some h✝¹ = some h✝
[PROOFSTEP]
any_goals contradiction
[GOAL]
case zero.zero
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
h : ↑(ofBaseChange W F K) zero = ↑(ofBaseChange W F K) zero
⊢ zero = zero
[PROOFSTEP]
contradiction
[GOAL]
case zero.some
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x✝ y✝ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x✝ y✝
h : ↑(ofBaseChange W F K) zero = ↑(ofBaseChange W F K) (some h✝)
⊢ zero = some h✝
[PROOFSTEP]
contradiction
[GOAL]
case some.zero
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x✝ y✝ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x✝ y✝
h : ↑(ofBaseChange W F K) (some h✝) = ↑(ofBaseChange W F K) zero
⊢ some h✝ = zero
[PROOFSTEP]
contradiction
[GOAL]
case some.some
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x✝¹ y✝¹ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x✝¹ y✝¹
x✝ y✝ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x✝ y✝
h : ↑(ofBaseChange W F K) (some h✝¹) = ↑(ofBaseChange W F K) (some h✝)
⊢ some h✝¹ = some h✝
[PROOFSTEP]
contradiction
[GOAL]
case zero.zero
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
h : ↑(ofBaseChange W F K) zero = ↑(ofBaseChange W F K) zero
⊢ zero = zero
[PROOFSTEP]
rfl
[GOAL]
case some.some
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x✝¹ y✝¹ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x✝¹ y✝¹
x✝ y✝ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x✝ y✝
h : ↑(ofBaseChange W F K) (some h✝¹) = ↑(ofBaseChange W F K) (some h✝)
⊢ some h✝¹ = some h✝
[PROOFSTEP]
rw [some.injEq]
[GOAL]
case some.some
R : Type u
inst✝⁶ : CommRing R
W : WeierstrassCurve R
F : Type v
inst✝⁵ : Field F
inst✝⁴ : Algebra R F
K : Type w
inst✝³ : Field K
inst✝² : Algebra R K
inst✝¹ : Algebra F K
inst✝ : IsScalarTower R F K
x✝¹ y✝¹ : F
h✝¹ : WeierstrassCurve.nonsingular (baseChange W F) x✝¹ y✝¹
x✝ y✝ : F
h✝ : WeierstrassCurve.nonsingular (baseChange W F) x✝ y✝
h : ↑(ofBaseChange W F K) (some h✝¹) = ↑(ofBaseChange W F K) (some h✝)
⊢ x✝¹ = x✝ ∧ y✝¹ = y✝
[PROOFSTEP]
exact
  ⟨NoZeroSMulDivisors.algebraMap_injective F K (some.inj h).left,
    NoZeroSMulDivisors.algebraMap_injective F K (some.inj h).right⟩