l3lab/ntp-mathlib huggingface dataset:
lemma nonsingular_add_of_eval_derivative_ne_zero {x₁ x₂ y₁ L : R}
    (hx' : W.equation (W.addX x₁ x₂ L) (W.addY' x₁ x₂ y₁ L))
    (hx : (W.addPolynomial x₁ y₁ L).derivative.eval (W.addX x₁ x₂ L) ≠ 0) :
    W.nonsingular (W.addX x₁ x₂ L) (W.addY' x₁ x₂ y₁ L) := by
  rw [nonsingular, and_iff_right hx', addY', polynomialX, polynomialY]
  eval_simp
  contrapose! hx
  rw [addPolynomial, linePolynomial, polynomial]
  eval_simp
  derivative_simp
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
x₁ x₂ y₁ L : R
hx' : W.equation (W.addX x₁ x₂ L) (W.addY' x₁ x₂ y₁ L)
hx :
  W.a₁ * (L * (W.addX x₁ x₂ L - x₁) + y₁) - (3 * W.addX x₁ x₂ L ^ 2 + 2 * W.a₂ * W.addX x₁ x₂ L + W.a₄) = 0 ∧
    2 * (L * (W.addX x₁ x₂ L - x₁) + y₁) + (W.a₁ * W.addX x₁ x₂ L + W.a₃) = 0
⊢ eval (W.addX 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

Next tactic:
simp only [zero_add, add_zero, sub_zero, zero_mul, mul_one]
lemma nonsingular_add_of_eval_derivative_ne_zero {x₁ x₂ y₁ L : R}
    (hx' : W.equation (W.addX x₁ x₂ L) (W.addY' x₁ x₂ y₁ L))
    (hx : (W.addPolynomial x₁ y₁ L).derivative.eval (W.addX x₁ x₂ L) ≠ 0) :
    W.nonsingular (W.addX x₁ x₂ L) (W.addY' x₁ x₂ y₁ L) := by
  rw [nonsingular, and_iff_right hx', addY', polynomialX, polynomialY]
  eval_simp
  contrapose! hx
  rw [addPolynomial, linePolynomial, polynomial]
  eval_simp
  derivative_simp
  simp only [zero_add, add_zero, sub_zero, zero_mul, mul_one]
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
x₁ x₂ y₁ L : R
hx' : W.equation (W.addX x₁ x₂ L) (W.addY' x₁ x₂ y₁ L)
hx :
  W.a₁ * (L * (W.addX x₁ x₂ L - x₁) + y₁) - (3 * W.addX x₁ x₂ L ^ 2 + 2 * W.a₂ * W.addX x₁ x₂ L + W.a₄) = 0 ∧
    2 * (L * (W.addX x₁ x₂ L - x₁) + y₁) + (W.a₁ * W.addX x₁ x₂ L + W.a₃) = 0
⊢ eval (W.addX 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

Next tactic:
eval_simp
lemma nonsingular_add_of_eval_derivative_ne_zero {x₁ x₂ y₁ L : R}
    (hx' : W.equation (W.addX x₁ x₂ L) (W.addY' x₁ x₂ y₁ L))
    (hx : (W.addPolynomial x₁ y₁ L).derivative.eval (W.addX x₁ x₂ L) ≠ 0) :
    W.nonsingular (W.addX x₁ x₂ L) (W.addY' x₁ x₂ y₁ L) := by
  rw [nonsingular, and_iff_right hx', addY', polynomialX, polynomialY]
  eval_simp
  contrapose! hx
  rw [addPolynomial, linePolynomial, polynomial]
  eval_simp
  derivative_simp
  simp only [zero_add, add_zero, sub_zero, zero_mul, mul_one]
  eval_simp
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
x₁ x₂ y₁ L : R
hx' : W.equation (W.addX x₁ x₂ L) (W.addY' x₁ x₂ y₁ L)
hx :
  W.a₁ * (L * (W.addX x₁ x₂ L - x₁) + y₁) - (3 * W.addX x₁ x₂ L ^ 2 + 2 * W.a₂ * W.addX x₁ x₂ L + W.a₄) = 0 ∧
    2 * (L * (W.addX x₁ x₂ L - x₁) + y₁) + (W.a₁ * W.addX x₁ x₂ L + W.a₃) = 0
⊢ 2 * (L * (W.addX x₁ x₂ L - x₁) + y₁) * L +
        (W.a₁ * (L * (W.addX x₁ x₂ L - x₁) + y₁) + (W.a₁ * W.addX x₁ x₂ L + W.a₃) * L) -
      (↑3 * W.addX x₁ x₂ L ^ (3 - 1) + W.a₂ * (2 * W.addX x₁ x₂ L) + W.a₄) =
    0

Next tactic:
linear_combination (norm := (norm_num1; ring1)) hx.left + L * hx.right
lemma nonsingular_add_of_eval_derivative_ne_zero {x₁ x₂ y₁ L : R}
    (hx' : W.equation (W.addX x₁ x₂ L) (W.addY' x₁ x₂ y₁ L))
    (hx : (W.addPolynomial x₁ y₁ L).derivative.eval (W.addX x₁ x₂ L) ≠ 0) :
    W.nonsingular (W.addX x₁ x₂ L) (W.addY' x₁ x₂ y₁ L) := by
  rw [nonsingular, and_iff_right hx', addY', polynomialX, polynomialY]
  eval_simp
  contrapose! hx
  rw [addPolynomial, linePolynomial, polynomial]
  eval_simp
  derivative_simp
  simp only [zero_add, add_zero, sub_zero, zero_mul, mul_one]
  eval_simp
  linear_combination (norm := (

Proof state:
case a
R : Type u
inst✝ : CommRing R
W : Affine R
x₁ x₂ y₁ L : R
hx' : W.equation (W.addX x₁ x₂ L) (W.addY' x₁ x₂ y₁ L)
hx :
  W.a₁ * (L * (W.addX x₁ x₂ L - x₁) + y₁) - (3 * W.addX x₁ x₂ L ^ 2 + 2 * W.a₂ * W.addX x₁ x₂ L + W.a₄) = 0 ∧
    2 * (L * (W.addX x₁ x₂ L - x₁) + y₁) + (W.a₁ * W.addX x₁ x₂ L + W.a₃) = 0
⊢ 2 * (L * (W.addX x₁ x₂ L - x₁) + y₁) * L +
            (W.a₁ * (L * (W.addX x₁ x₂ L - x₁) + y₁) + (W.a₁ * W.addX x₁ x₂ L + W.a₃) * L) -
          (↑3 * W.addX x₁ x₂ L ^ (3 - 1) + W.a₂ * (2 * W.addX x₁ x₂ L) + W.a₄) -
        0 -
      (W.a₁ * (L * (W.addX x₁ x₂ L - x₁) + y₁) - (3 * W.addX x₁ x₂ L ^ 2 + 2 * W.a₂ * W.addX x₁ x₂ L + W.a₄) +
          L * (2 * (L * (W.addX x₁ x₂ L - x₁) + y₁) + (W.a₁ * W.addX x₁ x₂ L + W.a₃)) -
        (0 + L * 0)) =
    0

Next tactic:
norm_num1
lemma nonsingular_add_of_eval_derivative_ne_zero {x₁ x₂ y₁ L : R}
    (hx' : W.equation (W.addX x₁ x₂ L) (W.addY' x₁ x₂ y₁ L))
    (hx : (W.addPolynomial x₁ y₁ L).derivative.eval (W.addX x₁ x₂ L) ≠ 0) :
    W.nonsingular (W.addX x₁ x₂ L) (W.addY' x₁ x₂ y₁ L) := by
  rw [nonsingular, and_iff_right hx', addY', polynomialX, polynomialY]
  eval_simp
  contrapose! hx
  rw [addPolynomial, linePolynomial, polynomial]
  eval_simp
  derivative_simp
  simp only [zero_add, add_zero, sub_zero, zero_mul, mul_one]
  eval_simp
  linear_combination (norm := (norm_num1; 

Proof state:
case a
R : Type u
inst✝ : CommRing R
W : Affine R
x₁ x₂ y₁ L : R
hx' : W.equation (W.addX x₁ x₂ L) (W.addY' x₁ x₂ y₁ L)
hx :
  W.a₁ * (L * (W.addX x₁ x₂ L - x₁) + y₁) - (3 * W.addX x₁ x₂ L ^ 2 + 2 * W.a₂ * W.addX x₁ x₂ L + W.a₄) = 0 ∧
    2 * (L * (W.addX x₁ x₂ L - x₁) + y₁) + (W.a₁ * W.addX x₁ x₂ L + W.a₃) = 0
⊢ 2 * (L * (W.addX x₁ x₂ L - x₁) + y₁) * L +
            (W.a₁ * (L * (W.addX x₁ x₂ L - x₁) + y₁) + (W.a₁ * W.addX x₁ x₂ L + W.a₃) * L) -
          (3 * W.addX x₁ x₂ L ^ 2 + W.a₂ * (2 * W.addX x₁ x₂ L) + W.a₄) -
        0 -
      (W.a₁ * (L * (W.addX x₁ x₂ L - x₁) + y₁) - (3 * W.addX x₁ x₂ L ^ 2 + 2 * W.a₂ * W.addX x₁ x₂ L + W.a₄) +
          L * (2 * (L * (W.addX x₁ x₂ L - x₁) + y₁) + (W.a₁ * W.addX x₁ x₂ L + W.a₃)) -
        (0 + L * 0)) =
    0

Next tactic:
ring1
@[simp]
lemma slope_of_Yeq {x₁ x₂ y₁ y₂ : F} (hx : x₁ = x₂) (hy : y₁ = W.negY x₂ y₂) :
    W.slope x₁ x₂ y₁ y₂ = 0 := by
  

Proof state:
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ x₂ y₁ y₂ : F
hx : x₁ = x₂
hy : y₁ = W.negY x₂ y₂
⊢ W.slope x₁ x₂ y₁ y₂ = 0

Next tactic:
rw [slope, if_pos hx, if_pos hy]
@[simp]
lemma slope_of_Yne {x₁ x₂ y₁ y₂ : F} (hx : x₁ = x₂) (hy : y₁ ≠ W.negY x₂ y₂) : W.slope x₁ x₂ y₁ y₂ =
    (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁) := by
  

Proof state:
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ x₂ y₁ y₂ : F
hx : x₁ = x₂
hy : y₁ ≠ W.negY x₂ y₂
⊢ W.slope x₁ x₂ y₁ y₂ = (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)

Next tactic:
rw [slope, if_pos hx, if_neg hy]
@[simp]
lemma slope_of_Xne {x₁ x₂ y₁ y₂ : F} (hx : x₁ ≠ x₂) :
    W.slope x₁ x₂ y₁ y₂ = (y₁ - y₂) / (x₁ - x₂) := by
  

Proof state:
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ x₂ y₁ y₂ : F
hx : x₁ ≠ x₂
⊢ W.slope x₁ x₂ y₁ y₂ = (y₁ - y₂) / (x₁ - x₂)

Next tactic:
rw [slope, if_neg hx]
lemma slope_of_Yne_eq_eval {x₁ x₂ y₁ y₂ : F} (hx : x₁ = x₂) (hy : y₁ ≠ W.negY x₂ y₂) :
    W.slope x₁ x₂ y₁ y₂ =
      -(W.polynomialX.eval <| C y₁).eval x₁ / (W.polynomialY.eval <| C y₁).eval x₁ := by
  

Proof state:
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ x₂ y₁ y₂ : F
hx : x₁ = x₂
hy : y₁ ≠ W.negY x₂ y₂
⊢ W.slope x₁ x₂ y₁ y₂ = -eval x₁ (eval (C y₁) W.polynomialX) / eval x₁ (eval (C y₁) W.polynomialY)

Next tactic:
rw [slope_of_Yne hx hy, eval_polynomialX, neg_sub]
lemma slope_of_Yne_eq_eval {x₁ x₂ y₁ y₂ : F} (hx : x₁ = x₂) (hy : y₁ ≠ W.negY x₂ y₂) :
    W.slope x₁ x₂ y₁ y₂ =
      -(W.polynomialX.eval <| C y₁).eval x₁ / (W.polynomialY.eval <| C y₁).eval x₁ := by
  rw [slope_of_Yne hx hy, eval_polynomialX, neg_sub]
  

Proof state:
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ x₂ y₁ y₂ : F
hx : x₁ = x₂
hy : y₁ ≠ W.negY x₂ y₂
⊢ (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁) =
    (3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / eval x₁ (eval (C y₁) W.polynomialY)

Next tactic:
congr 1
lemma slope_of_Yne_eq_eval {x₁ x₂ y₁ y₂ : F} (hx : x₁ = x₂) (hy : y₁ ≠ W.negY x₂ y₂) :
    W.slope x₁ x₂ y₁ y₂ =
      -(W.polynomialX.eval <| C y₁).eval x₁ / (W.polynomialY.eval <| C y₁).eval x₁ := by
  rw [slope_of_Yne hx hy, eval_polynomialX, neg_sub]
  congr 1
  

Proof state:
case e_a
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ x₂ y₁ y₂ : F
hx : x₁ = x₂
hy : y₁ ≠ W.negY x₂ y₂
⊢ y₁ - W.negY x₁ y₁ = eval x₁ (eval (C y₁) W.polynomialY)

Next tactic:
rw [negY, eval_polynomialY]
lemma slope_of_Yne_eq_eval {x₁ x₂ y₁ y₂ : F} (hx : x₁ = x₂) (hy : y₁ ≠ W.negY x₂ y₂) :
    W.slope x₁ x₂ y₁ y₂ =
      -(W.polynomialX.eval <| C y₁).eval x₁ / (W.polynomialY.eval <| C y₁).eval x₁ := by
  rw [slope_of_Yne hx hy, eval_polynomialX, neg_sub]
  congr 1
  rw [negY, eval_polynomialY]
  

Proof state:
case e_a
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ x₂ y₁ y₂ : F
hx : x₁ = x₂
hy : y₁ ≠ W.negY x₂ y₂
⊢ y₁ - (-y₁ - W.a₁ * x₁ - W.a₃) = 2 * y₁ + W.a₁ * x₁ + W.a₃

Next tactic:
ring1
lemma Yeq_of_Xeq {x₁ x₂ y₁ y₂ : F} (h₁ : W.equation x₁ y₁) (h₂ : W.equation x₂ y₂) (hx : x₁ = x₂) :
    y₁ = y₂ ∨ y₁ = W.negY x₂ y₂ := by
  

Proof state:
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ x₂ y₁ y₂ : F
h₁ : W.equation x₁ y₁
h₂ : W.equation x₂ y₂
hx : x₁ = x₂
⊢ y₁ = y₂ ∨ y₁ = W.negY x₂ y₂

Next tactic:
rw [equation_iff] at h₁ h₂
lemma Yeq_of_Xeq {x₁ x₂ y₁ y₂ : F} (h₁ : W.equation x₁ y₁) (h₂ : W.equation x₂ y₂) (hx : x₁ = x₂) :
    y₁ = y₂ ∨ y₁ = W.negY x₂ y₂ := by
  rw [equation_iff] at h₁ h₂
  

Proof state:
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ x₂ y₁ y₂ : F
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₁ = W.negY x₂ y₂

Next tactic:
rw [← sub_eq_zero, ← sub_eq_zero (a := y₁), ← mul_eq_zero, negY]
lemma Yeq_of_Xeq {x₁ x₂ y₁ y₂ : F} (h₁ : W.equation x₁ y₁) (h₂ : W.equation x₂ y₂) (hx : x₁ = x₂) :
    y₁ = y₂ ∨ y₁ = W.negY x₂ y₂ := by
  rw [equation_iff] at h₁ h₂
  rw [← sub_eq_zero, ← sub_eq_zero (a := y₁), ← mul_eq_zero, negY]
  

Proof state:
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ x₂ y₁ y₂ : F
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

Next tactic:
linear_combination (norm := (rw [hx]; ring1)) h₁ - h₂
lemma Yeq_of_Xeq {x₁ x₂ y₁ y₂ : F} (h₁ : W.equation x₁ y₁) (h₂ : W.equation x₂ y₂) (hx : x₁ = x₂) :
    y₁ = y₂ ∨ y₁ = W.negY x₂ y₂ := by
  rw [equation_iff] at h₁ h₂
  rw [← sub_eq_zero, ← sub_eq_zero (a := y₁), ← mul_eq_zero, negY]
  linear_combination (norm := (

Proof state:
case a
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ x₂ y₁ y₂ : F
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

Next tactic:
rw [hx]
lemma Yeq_of_Xeq {x₁ x₂ y₁ y₂ : F} (h₁ : W.equation x₁ y₁) (h₂ : W.equation x₂ y₂) (hx : x₁ = x₂) :
    y₁ = y₂ ∨ y₁ = W.negY x₂ y₂ := by
  rw [equation_iff] at h₁ h₂
  rw [← sub_eq_zero, ← sub_eq_zero (a := y₁), ← mul_eq_zero, negY]
  linear_combination (norm := (rw [hx]; 

Proof state:
case a
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ x₂ y₁ y₂ : F
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

Next tactic:
ring1
lemma addPolynomial_slope {x₁ x₂ y₁ y₂ : F} (h₁ : W.equation x₁ y₁) (h₂ : W.equation x₂ y₂)
    (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) : W.addPolynomial x₁ y₁ (W.slope x₁ x₂ y₁ y₂) =
      -((X - C x₁) * (X - C x₂) * (X - C (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂))) := by
  

Proof state:
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ x₂ y₁ y₂ : F
h₁ : W.equation x₁ y₁
h₂ : W.equation x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂
⊢ W.addPolynomial x₁ y₁ (W.slope x₁ x₂ y₁ y₂) =
    -((Y - C x₁) * (Y - C x₂) * (Y - C (W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂))))

Next tactic:
rw [addPolynomial_eq, neg_inj, Cubic.prod_X_sub_C_eq, Cubic.toPoly_injective]
lemma addPolynomial_slope {x₁ x₂ y₁ y₂ : F} (h₁ : W.equation x₁ y₁) (h₂ : W.equation x₂ y₂)
    (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) : W.addPolynomial x₁ y₁ (W.slope x₁ x₂ y₁ y₂) =
      -((X - C x₁) * (X - C x₂) * (X - C (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂))) := by
  rw [addPolynomial_eq, neg_inj, Cubic.prod_X_sub_C_eq, Cubic.toPoly_injective]
  

Proof state:
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ x₂ y₁ y₂ : F
h₁ : W.equation x₁ y₁
h₂ : W.equation x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂
⊢ { a := 1, b := -W.slope x₁ x₂ y₁ y₂ ^ 2 - W.a₁ * W.slope x₁ x₂ y₁ y₂ + W.a₂,
      c := 2 * x₁ * W.slope x₁ x₂ y₁ y₂ ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * W.slope x₁ x₂ y₁ y₂ + (-W.a₁ * y₁ + W.a₄),
      d :=
        -x₁ ^ 2 * W.slope x₁ x₂ y₁ y₂ ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * W.slope x₁ x₂ y₁ y₂ -
          (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) } =
    { a := 1, b := -(x₁ + x₂ + W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂)),
      c := x₁ * x₂ + x₁ * W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂) + x₂ * W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂),
      d := -(x₁ * x₂ * W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂)) }

Next tactic:
by_cases hx : x₁ = x₂
lemma addPolynomial_slope {x₁ x₂ y₁ y₂ : F} (h₁ : W.equation x₁ y₁) (h₂ : W.equation x₂ y₂)
    (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) : W.addPolynomial x₁ y₁ (W.slope x₁ x₂ y₁ y₂) =
      -((X - C x₁) * (X - C x₂) * (X - C (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂))) := by
  rw [addPolynomial_eq, neg_inj, Cubic.prod_X_sub_C_eq, Cubic.toPoly_injective]
  by_cases hx : x₁ = x₂
  · 

Proof state:
case pos
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ x₂ y₁ y₂ : F
h₁ : W.equation x₁ y₁
h₂ : W.equation x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂
hx : x₁ = x₂
⊢ { a := 1, b := -W.slope x₁ x₂ y₁ y₂ ^ 2 - W.a₁ * W.slope x₁ x₂ y₁ y₂ + W.a₂,
      c := 2 * x₁ * W.slope x₁ x₂ y₁ y₂ ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * W.slope x₁ x₂ y₁ y₂ + (-W.a₁ * y₁ + W.a₄),
      d :=
        -x₁ ^ 2 * W.slope x₁ x₂ y₁ y₂ ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * W.slope x₁ x₂ y₁ y₂ -
          (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) } =
    { a := 1, b := -(x₁ + x₂ + W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂)),
      c := x₁ * x₂ + x₁ * W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂) + x₂ * W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂),
      d := -(x₁ * x₂ * W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂)) }

Next tactic:
rcases hx, Yeq_of_Yne h₁ h₂ hx (hxy hx) with ⟨rfl, rfl⟩
lemma addPolynomial_slope {x₁ x₂ y₁ y₂ : F} (h₁ : W.equation x₁ y₁) (h₂ : W.equation x₂ y₂)
    (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) : W.addPolynomial x₁ y₁ (W.slope x₁ x₂ y₁ y₂) =
      -((X - C x₁) * (X - C x₂) * (X - C (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂))) := by
  rw [addPolynomial_eq, neg_inj, Cubic.prod_X_sub_C_eq, Cubic.toPoly_injective]
  by_cases hx : x₁ = x₂
  · rcases hx, Yeq_of_Yne h₁ h₂ hx (hxy hx) with ⟨rfl, rfl⟩
    

Proof state:
case pos
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ y₁ : F
h₁ h₂ : W.equation x₁ y₁
hxy : x₁ = x₁ → y₁ ≠ W.negY x₁ y₁
⊢ { a := 1, b := -W.slope x₁ x₁ y₁ y₁ ^ 2 - W.a₁ * W.slope x₁ x₁ y₁ y₁ + W.a₂,
      c := 2 * x₁ * W.slope x₁ x₁ y₁ y₁ ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * W.slope x₁ x₁ y₁ y₁ + (-W.a₁ * y₁ + W.a₄),
      d :=
        -x₁ ^ 2 * W.slope x₁ x₁ y₁ y₁ ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * W.slope x₁ x₁ y₁ y₁ -
          (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) } =
    { a := 1, b := -(x₁ + x₁ + W.addX x₁ x₁ (W.slope x₁ x₁ y₁ y₁)),
      c := x₁ * x₁ + x₁ * W.addX x₁ x₁ (W.slope x₁ x₁ y₁ y₁) + x₁ * W.addX x₁ x₁ (W.slope x₁ x₁ y₁ y₁),
      d := -(x₁ * x₁ * W.addX x₁ x₁ (W.slope x₁ x₁ y₁ y₁)) }

Next tactic:
rw [equation_iff] at h₁ h₂
lemma addPolynomial_slope {x₁ x₂ y₁ y₂ : F} (h₁ : W.equation x₁ y₁) (h₂ : W.equation x₂ y₂)
    (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) : W.addPolynomial x₁ y₁ (W.slope x₁ x₂ y₁ y₂) =
      -((X - C x₁) * (X - C x₂) * (X - C (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂))) := by
  rw [addPolynomial_eq, neg_inj, Cubic.prod_X_sub_C_eq, Cubic.toPoly_injective]
  by_cases hx : x₁ = x₂
  · rcases hx, Yeq_of_Yne h₁ h₂ hx (hxy hx) with ⟨rfl, rfl⟩
    rw [equation_iff] at h₁ h₂
    

Proof state:
case pos
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ y₁ : F
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₁ ≠ W.negY x₁ y₁
⊢ { a := 1, b := -W.slope x₁ x₁ y₁ y₁ ^ 2 - W.a₁ * W.slope x₁ x₁ y₁ y₁ + W.a₂,
      c := 2 * x₁ * W.slope x₁ x₁ y₁ y₁ ^ 2 + (W.a₁ * x₁ - 2 * y₁ - W.a₃) * W.slope x₁ x₁ y₁ y₁ + (-W.a₁ * y₁ + W.a₄),
      d :=
        -x₁ ^ 2 * W.slope x₁ x₁ y₁ y₁ ^ 2 + (2 * x₁ * y₁ + W.a₃ * x₁) * W.slope x₁ x₁ y₁ y₁ -
          (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) } =
    { a := 1, b := -(x₁ + x₁ + W.addX x₁ x₁ (W.slope x₁ x₁ y₁ y₁)),
      c := x₁ * x₁ + x₁ * W.addX x₁ x₁ (W.slope x₁ x₁ y₁ y₁) + x₁ * W.addX x₁ x₁ (W.slope x₁ x₁ y₁ y₁),
      d := -(x₁ * x₁ * W.addX x₁ x₁ (W.slope x₁ x₁ y₁ y₁)) }

Next tactic:
rw [slope_of_Yne rfl <| hxy rfl]
lemma addPolynomial_slope {x₁ x₂ y₁ y₂ : F} (h₁ : W.equation x₁ y₁) (h₂ : W.equation x₂ y₂)
    (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) : W.addPolynomial x₁ y₁ (W.slope x₁ x₂ y₁ y₂) =
      -((X - C x₁) * (X - C x₂) * (X - C (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂))) := by
  rw [addPolynomial_eq, neg_inj, Cubic.prod_X_sub_C_eq, Cubic.toPoly_injective]
  by_cases hx : x₁ = x₂
  · rcases hx, Yeq_of_Yne h₁ h₂ hx (hxy hx) with ⟨rfl, rfl⟩
    rw [equation_iff] at h₁ h₂
    rw [slope_of_Yne rfl <| hxy rfl]
    

Proof state:
case pos
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ y₁ : F
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₁ ≠ W.negY x₁ y₁
⊢ { a := 1,
      b :=
        -((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) ^ 2 -
            W.a₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) +
          W.a₂,
      c :=
        2 * x₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) ^ 2 +
            (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) +
          (-W.a₁ * y₁ + W.a₄),
      d :=
        -x₁ ^ 2 * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) ^ 2 +
            (2 * x₁ * y₁ + W.a₃ * x₁) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) -
          (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) } =
    { a := 1, b := -(x₁ + x₁ + W.addX x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁))),
      c :=
        x₁ * x₁ + x₁ * W.addX x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) +
          x₁ * W.addX x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)),
      d := -(x₁ * x₁ * W.addX x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁))) }

Next tactic:
rw [negY, ← sub_ne_zero] at hxy
lemma addPolynomial_slope {x₁ x₂ y₁ y₂ : F} (h₁ : W.equation x₁ y₁) (h₂ : W.equation x₂ y₂)
    (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) : W.addPolynomial x₁ y₁ (W.slope x₁ x₂ y₁ y₂) =
      -((X - C x₁) * (X - C x₂) * (X - C (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂))) := by
  rw [addPolynomial_eq, neg_inj, Cubic.prod_X_sub_C_eq, Cubic.toPoly_injective]
  by_cases hx : x₁ = x₂
  · rcases hx, Yeq_of_Yne h₁ h₂ hx (hxy hx) with ⟨rfl, rfl⟩
    rw [equation_iff] at h₁ h₂
    rw [slope_of_Yne rfl <| hxy rfl]
    rw [negY, ← sub_ne_zero] at hxy
    

Proof state:
case pos
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ y₁ : F
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₃) ≠ 0
⊢ { a := 1,
      b :=
        -((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) ^ 2 -
            W.a₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) +
          W.a₂,
      c :=
        2 * x₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) ^ 2 +
            (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) +
          (-W.a₁ * y₁ + W.a₄),
      d :=
        -x₁ ^ 2 * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) ^ 2 +
            (2 * x₁ * y₁ + W.a₃ * x₁) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) -
          (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) } =
    { a := 1, b := -(x₁ + x₁ + W.addX x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁))),
      c :=
        x₁ * x₁ + x₁ * W.addX x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) +
          x₁ * W.addX x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)),
      d := -(x₁ * x₁ * W.addX x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁))) }

Next tactic:
ext
lemma addPolynomial_slope {x₁ x₂ y₁ y₂ : F} (h₁ : W.equation x₁ y₁) (h₂ : W.equation x₂ y₂)
    (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) : W.addPolynomial x₁ y₁ (W.slope x₁ x₂ y₁ y₂) =
      -((X - C x₁) * (X - C x₂) * (X - C (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂))) := by
  rw [addPolynomial_eq, neg_inj, Cubic.prod_X_sub_C_eq, Cubic.toPoly_injective]
  by_cases hx : x₁ = x₂
  · rcases hx, Yeq_of_Yne h₁ h₂ hx (hxy hx) with ⟨rfl, rfl⟩
    rw [equation_iff] at h₁ h₂
    rw [slope_of_Yne rfl <| hxy rfl]
    rw [negY, ← sub_ne_zero] at hxy
    ext
    · 

Proof state:
case pos.a
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x₁ y₁ : F
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₃) ≠ 0
⊢ { a := 1,
        b :=
          -((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) ^ 2 -
              W.a₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) +
            W.a₂,
        c :=
          2 * x₁ * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) ^ 2 +
              (W.a₁ * x₁ - 2 * y₁ - W.a₃) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) +
            (-W.a₁ * y₁ + W.a₄),
        d :=
          -x₁ ^ 2 * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) ^ 2 +
              (2 * x₁ * y₁ + W.a₃ * x₁) * ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) -
            (y₁ ^ 2 + W.a₃ * y₁ - W.a₆) }.a =
    { a := 1, b := -(x₁ + x₁ + W.addX x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁))),
        c :=
          x₁ * x₁ + x₁ * W.addX x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)) +
            x₁ * W.addX x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁)),
        d := -(x₁ * x₁ * W.addX x₁ x₁ ((3 * x₁ ^ 2 + 2 * W.a₂ * x₁ + W.a₄ - W.a₁ * y₁) / (y₁ - W.negY x₁ y₁))) }.a

Next tactic:
rfl