l3lab/ntp-mathlib huggingface dataset:
lemma XYIdeal_mul_XYIdeal {x₁ x₂ y₁ y₂ : F} (h₁ : W.equation x₁ y₁) (h₂ : W.equation x₂ y₂)
    (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) :
    XIdeal W (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂) * (XYIdeal W x₁ (C y₁) * XYIdeal W x₂ (C y₂)) =
      YIdeal W (linePolynomial x₁ y₁ <| W.slope x₁ x₂ y₁ y₂) *
        XYIdeal W (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂)
          (C <| W.addY x₁ x₂ y₁ <| W.slope x₁ x₂ y₁ y₂) := by
  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]
  rw [XYIdeal_add_eq, XIdeal, mul_comm, XYIdeal_eq₁ W x₁ y₁ <| W.slope x₁ x₂ y₁ y₂, XYIdeal,
    XYIdeal_eq₂ h₁ h₂ hxy, XYIdeal, span_pair_mul_span_pair]
  simp_rw [span_insert, sup_rw, sup_mul, span_singleton_mul_span_singleton]
  rw [← neg_eq_iff_eq_neg.mpr <| C_addPolynomial_slope h₁ h₂ hxy, span_singleton_neg,
    C_addPolynomial, _root_.map_mul, YClass]
  simp_rw [mul_comm <| XClass W x₁, mul_assoc, ← span_singleton_mul_span_singleton, ← mul_sup]
  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 <| mk W, sub_sub_sub_cancel_right,
    span_insert, ← span_singleton_mul_span_singleton, ← sup_rw, ← sup_mul, ← sup_mul]
  apply congr_arg (_ ∘ _)
  convert top_mul (_ : Ideal W.CoordinateRing)
  simp_rw [XClass, ← @Set.image_singleton _ _ <| mk W, ← map_span, ← Ideal.map_sup,
    eq_top_iff_one, mem_map_iff_of_surjective _ AdjoinRoot.mk_surjective, ← span_insert,
    mem_span_insert', mem_span_singleton']
  by_cases hx : x₁ = x₂
  · rcases hx, Yeq_of_Yne h₁ h₂ hx (hxy hx) with ⟨rfl, rfl⟩
    let y := (y₁ - W.negY x₁ y₁) ^ 2
    replace hxy := pow_ne_zero 2 (sub_ne_zero_of_ne <| hxy rfl)
    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 <| mk W, AdjoinRoot.mk_self, mul_zero,
        add_zero]⟩
    rw [polynomial, negPolynomial, ← mul_right_inj' <| C_ne_zero.mpr <| C_ne_zero.mpr hxy]
    simp only [mul_add, ← mul_assoc, ← C_mul, mul_inv_cancel hxy]
    linear_combination (norm := (rw [b₂, b₄, negY]; C_simp; ring1))
      -4 * congr_arg C (congr_arg C <| (W.equation_iff _ _).mp h₁)
  · replace hx := sub_ne_zero_of_ne hx
    refine ⟨_, ⟨⟨C <| C (x₁ - x₂)⁻¹, C <| C <| (x₁ - x₂)⁻¹ * -1, 0, ?_⟩, map_one _⟩⟩
    rw [← mul_right_inj' <| C_ne_zero.mpr <| C_ne_zero.mpr hx]
    

Proof state:
case neg
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₂
sup_rw : ∀ (a b c d : Ideal W.CoordinateRing), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
hx : x₁ - x₂ ≠ 0
⊢ C (C (x₁ - x₂)) * (0 * (Y - W.negPolynomial)) =
    C (C (x₁ - x₂)) * (1 + C (C (x₁ - x₂)⁻¹) * C (Y - C x₁) + C (C ((x₁ - x₂)⁻¹ * -1)) * C (Y - C x₂))

Next tactic:
simp only [← mul_assoc, mul_add, ← C_mul, mul_inv_cancel hx]
lemma XYIdeal_mul_XYIdeal {x₁ x₂ y₁ y₂ : F} (h₁ : W.equation x₁ y₁) (h₂ : W.equation x₂ y₂)
    (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) :
    XIdeal W (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂) * (XYIdeal W x₁ (C y₁) * XYIdeal W x₂ (C y₂)) =
      YIdeal W (linePolynomial x₁ y₁ <| W.slope x₁ x₂ y₁ y₂) *
        XYIdeal W (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂)
          (C <| W.addY x₁ x₂ y₁ <| W.slope x₁ x₂ y₁ y₂) := by
  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]
  rw [XYIdeal_add_eq, XIdeal, mul_comm, XYIdeal_eq₁ W x₁ y₁ <| W.slope x₁ x₂ y₁ y₂, XYIdeal,
    XYIdeal_eq₂ h₁ h₂ hxy, XYIdeal, span_pair_mul_span_pair]
  simp_rw [span_insert, sup_rw, sup_mul, span_singleton_mul_span_singleton]
  rw [← neg_eq_iff_eq_neg.mpr <| C_addPolynomial_slope h₁ h₂ hxy, span_singleton_neg,
    C_addPolynomial, _root_.map_mul, YClass]
  simp_rw [mul_comm <| XClass W x₁, mul_assoc, ← span_singleton_mul_span_singleton, ← mul_sup]
  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 <| mk W, sub_sub_sub_cancel_right,
    span_insert, ← span_singleton_mul_span_singleton, ← sup_rw, ← sup_mul, ← sup_mul]
  apply congr_arg (_ ∘ _)
  convert top_mul (_ : Ideal W.CoordinateRing)
  simp_rw [XClass, ← @Set.image_singleton _ _ <| mk W, ← map_span, ← Ideal.map_sup,
    eq_top_iff_one, mem_map_iff_of_surjective _ AdjoinRoot.mk_surjective, ← span_insert,
    mem_span_insert', mem_span_singleton']
  by_cases hx : x₁ = x₂
  · rcases hx, Yeq_of_Yne h₁ h₂ hx (hxy hx) with ⟨rfl, rfl⟩
    let y := (y₁ - W.negY x₁ y₁) ^ 2
    replace hxy := pow_ne_zero 2 (sub_ne_zero_of_ne <| hxy rfl)
    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 <| mk W, AdjoinRoot.mk_self, mul_zero,
        add_zero]⟩
    rw [polynomial, negPolynomial, ← mul_right_inj' <| C_ne_zero.mpr <| C_ne_zero.mpr hxy]
    simp only [mul_add, ← mul_assoc, ← C_mul, mul_inv_cancel hxy]
    linear_combination (norm := (rw [b₂, b₄, negY]; C_simp; ring1))
      -4 * congr_arg C (congr_arg C <| (W.equation_iff _ _).mp h₁)
  · replace hx := sub_ne_zero_of_ne hx
    refine ⟨_, ⟨⟨C <| C (x₁ - x₂)⁻¹, C <| C <| (x₁ - x₂)⁻¹ * -1, 0, ?_⟩, map_one _⟩⟩
    rw [← mul_right_inj' <| C_ne_zero.mpr <| C_ne_zero.mpr hx]
    simp only [← mul_assoc, mul_add, ← C_mul, mul_inv_cancel hx]
    

Proof state:
case neg
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₂
sup_rw : ∀ (a b c d : Ideal W.CoordinateRing), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
hx : x₁ - x₂ ≠ 0
⊢ C (C (x₁ - x₂)) * 0 * (Y - W.negPolynomial) = C (C (x₁ - x₂)) * 1 + C (C 1 * (Y - C x₁)) + C (C (1 * -1) * (Y - C x₂))

Next tactic:
C_simp
lemma XYIdeal_mul_XYIdeal {x₁ x₂ y₁ y₂ : F} (h₁ : W.equation x₁ y₁) (h₂ : W.equation x₂ y₂)
    (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) :
    XIdeal W (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂) * (XYIdeal W x₁ (C y₁) * XYIdeal W x₂ (C y₂)) =
      YIdeal W (linePolynomial x₁ y₁ <| W.slope x₁ x₂ y₁ y₂) *
        XYIdeal W (W.addX x₁ x₂ <| W.slope x₁ x₂ y₁ y₂)
          (C <| W.addY x₁ x₂ y₁ <| W.slope x₁ x₂ y₁ y₂) := by
  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]
  rw [XYIdeal_add_eq, XIdeal, mul_comm, XYIdeal_eq₁ W x₁ y₁ <| W.slope x₁ x₂ y₁ y₂, XYIdeal,
    XYIdeal_eq₂ h₁ h₂ hxy, XYIdeal, span_pair_mul_span_pair]
  simp_rw [span_insert, sup_rw, sup_mul, span_singleton_mul_span_singleton]
  rw [← neg_eq_iff_eq_neg.mpr <| C_addPolynomial_slope h₁ h₂ hxy, span_singleton_neg,
    C_addPolynomial, _root_.map_mul, YClass]
  simp_rw [mul_comm <| XClass W x₁, mul_assoc, ← span_singleton_mul_span_singleton, ← mul_sup]
  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 <| mk W, sub_sub_sub_cancel_right,
    span_insert, ← span_singleton_mul_span_singleton, ← sup_rw, ← sup_mul, ← sup_mul]
  apply congr_arg (_ ∘ _)
  convert top_mul (_ : Ideal W.CoordinateRing)
  simp_rw [XClass, ← @Set.image_singleton _ _ <| mk W, ← map_span, ← Ideal.map_sup,
    eq_top_iff_one, mem_map_iff_of_surjective _ AdjoinRoot.mk_surjective, ← span_insert,
    mem_span_insert', mem_span_singleton']
  by_cases hx : x₁ = x₂
  · rcases hx, Yeq_of_Yne h₁ h₂ hx (hxy hx) with ⟨rfl, rfl⟩
    let y := (y₁ - W.negY x₁ y₁) ^ 2
    replace hxy := pow_ne_zero 2 (sub_ne_zero_of_ne <| hxy rfl)
    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 <| mk W, AdjoinRoot.mk_self, mul_zero,
        add_zero]⟩
    rw [polynomial, negPolynomial, ← mul_right_inj' <| C_ne_zero.mpr <| C_ne_zero.mpr hxy]
    simp only [mul_add, ← mul_assoc, ← C_mul, mul_inv_cancel hxy]
    linear_combination (norm := (rw [b₂, b₄, negY]; C_simp; ring1))
      -4 * congr_arg C (congr_arg C <| (W.equation_iff _ _).mp h₁)
  · replace hx := sub_ne_zero_of_ne hx
    refine ⟨_, ⟨⟨C <| C (x₁ - x₂)⁻¹, C <| C <| (x₁ - x₂)⁻¹ * -1, 0, ?_⟩, map_one _⟩⟩
    rw [← mul_right_inj' <| C_ne_zero.mpr <| C_ne_zero.mpr hx]
    simp only [← mul_assoc, mul_add, ← C_mul, mul_inv_cancel hx]
    C_simp
    

Proof state:
case neg
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₂
sup_rw : ∀ (a b c d : Ideal W.CoordinateRing), a ⊔ (b ⊔ (c ⊔ d)) = a ⊔ d ⊔ b ⊔ c
hx : x₁ - x₂ ≠ 0
⊢ (C (C x₁) - C (C x₂)) * 0 * (Y - W.negPolynomial) =
    (C (C x₁) - C (C x₂)) * 1 + 1 * (C Y - C (C x₁)) + 1 * -1 * (C Y - C (C x₂))

Next tactic:
ring1
lemma mk_XYIdeal'_mul_mk_XYIdeal'_of_Yeq {x y : F} (h : W.nonsingular x y) :
    ClassGroup.mk (XYIdeal' <| nonsingular_neg h) * ClassGroup.mk (XYIdeal' h) = 1 := by
  

Proof state:
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x y : F
h : W.nonsingular x y
⊢ ClassGroup.mk (XYIdeal' (_ : W.nonsingular x (W.negY x y))) * ClassGroup.mk (XYIdeal' h) = 1

Next tactic:
rw [← _root_.map_mul]
lemma mk_XYIdeal'_mul_mk_XYIdeal'_of_Yeq {x y : F} (h : W.nonsingular x y) :
    ClassGroup.mk (XYIdeal' <| nonsingular_neg h) * ClassGroup.mk (XYIdeal' h) = 1 := by
  rw [← _root_.map_mul]
  

Proof state:
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x y : F
h : W.nonsingular x y
⊢ ClassGroup.mk (XYIdeal' (_ : W.nonsingular x (W.negY x y)) * XYIdeal' h) = 1

Next tactic:
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⟩
lemma mk_XYIdeal'_mul_mk_XYIdeal'_of_Yeq {x y : F} (h : W.nonsingular x y) :
    ClassGroup.mk (XYIdeal' <| nonsingular_neg h) * ClassGroup.mk (XYIdeal' h) = 1 := by
  rw [← _root_.map_mul]
  exact
    (ClassGroup.mk_eq_one_of_coe_ideal <| by 

Proof state:
R : Type u
inst✝¹ : CommRing R
W✝ : Affine R
F : Type u
inst✝ : Field F
W : Affine F
x y : F
h : W.nonsingular x y
⊢ ↑(XYIdeal' (_ : W.nonsingular x (W.negY x y)) * XYIdeal' h) = ↑(span {XClass W ?m.2445133})

Next tactic:
exact (FractionalIdeal.coeIdeal_mul _ _).symm.trans <|
      FractionalIdeal.coeIdeal_inj.mpr <| XYIdeal_neg_mul h
lemma mk_XYIdeal'_mul_mk_XYIdeal' {x₁ x₂ y₁ y₂ : F} (h₁ : W.nonsingular x₁ y₁)
    (h₂ : W.nonsingular x₂ y₂) (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) :
    ClassGroup.mk (XYIdeal' h₁) * ClassGroup.mk (XYIdeal' h₂) =
      ClassGroup.mk (XYIdeal' <| nonsingular_add h₁ h₂ hxy) := 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.nonsingular x₁ y₁
h₂ : W.nonsingular x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂
⊢ ClassGroup.mk (XYIdeal' h₁) * ClassGroup.mk (XYIdeal' h₂) =
    ClassGroup.mk
      (XYIdeal' (_ : W.nonsingular (W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂)) (W.addY x₁ x₂ y₁ (W.slope x₁ x₂ y₁ y₂))))

Next tactic:
rw [← _root_.map_mul]
lemma mk_XYIdeal'_mul_mk_XYIdeal' {x₁ x₂ y₁ y₂ : F} (h₁ : W.nonsingular x₁ y₁)
    (h₂ : W.nonsingular x₂ y₂) (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) :
    ClassGroup.mk (XYIdeal' h₁) * ClassGroup.mk (XYIdeal' h₂) =
      ClassGroup.mk (XYIdeal' <| nonsingular_add h₁ h₂ hxy) := by
  rw [← _root_.map_mul]
  

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.nonsingular x₁ y₁
h₂ : W.nonsingular x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂
⊢ ClassGroup.mk (XYIdeal' h₁ * XYIdeal' h₂) =
    ClassGroup.mk
      (XYIdeal' (_ : W.nonsingular (W.addX x₁ x₂ (W.slope x₁ x₂ y₁ y₂)) (W.addY x₁ x₂ y₁ (W.slope x₁ x₂ y₁ y₂))))

Next tactic:
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⟩
lemma mk_XYIdeal'_mul_mk_XYIdeal' {x₁ x₂ y₁ y₂ : F} (h₁ : W.nonsingular x₁ y₁)
    (h₂ : W.nonsingular x₂ y₂) (hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂) :
    ClassGroup.mk (XYIdeal' h₁) * ClassGroup.mk (XYIdeal' h₂) =
      ClassGroup.mk (XYIdeal' <| nonsingular_add h₁ h₂ hxy) := by
  rw [← _root_.map_mul]
  exact (ClassGroup.mk_eq_mk_of_coe_ideal (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.nonsingular x₁ y₁
h₂ : W.nonsingular x₂ y₂
hxy : x₁ = x₂ → y₁ ≠ W.negY x₂ y₂
⊢ ↑(XYIdeal' h₁ * XYIdeal' h₂) = ↑(XYIdeal W x₁ (C y₁) * XYIdeal W x₂ (C y₂))

Next tactic:
exact (FractionalIdeal.coeIdeal_mul _ _).symm
/-- The $R$-algebra isomorphism from $R[W] / \langle X - x, Y - y(X) \rangle$ to $R$ obtained by
evaluation at $y(X)$ and at $x$ provided that $W(x, y(x)) = 0$. -/
noncomputable def quotientXYIdealEquiv {x : R} {y : R[X]} (h : (W.polynomial.eval y).eval x = 0) :
    (W.CoordinateRing ⧸ XYIdeal W x y) ≃ₐ[R] R :=
  ((quotientEquivAlgOfEq R <| by
      

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
x : R
y : R[X]
h : eval x (eval y W.polynomial) = 0
⊢ XYIdeal W x y = Ideal.map (Quotient.mkₐ R (span {W.polynomial})) (span {C (Y - C x), Y - C y})

Next tactic:
simp only [XYIdeal, XClass, YClass, ← Set.image_pair, ← map_span]
/-- The $R$-algebra isomorphism from $R[W] / \langle X - x, Y - y(X) \rangle$ to $R$ obtained by
evaluation at $y(X)$ and at $x$ provided that $W(x, y(x)) = 0$. -/
noncomputable def quotientXYIdealEquiv {x : R} {y : R[X]} (h : (W.polynomial.eval y).eval x = 0) :
    (W.CoordinateRing ⧸ XYIdeal W x y) ≃ₐ[R] R :=
  ((quotientEquivAlgOfEq R <| by
      simp only [XYIdeal, XClass, YClass, ← Set.image_pair, ← map_span]; 

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
x : R
y : R[X]
h : eval x (eval y W.polynomial) = 0
⊢ Ideal.map (mk W) (span {C (Y - C x), Y - C y}) =
    Ideal.map (Quotient.mkₐ R (span {W.polynomial})) (span {C (Y - C x), Y - C y})

Next tactic:
rfl
/-- The basis $\{1, Y\}$ for the coordinate ring $R[W]$ over the polynomial ring $R[X]$. -/
protected noncomputable def basis : Basis (Fin 2) R[X] W.CoordinateRing := by
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
⊢ Basis (Fin 2) R[X] W.CoordinateRing

Next tactic:
classical exact (subsingleton_or_nontrivial R).by_cases (fun _ => default) fun _ =>
    (AdjoinRoot.powerBasis' W.monic_polynomial).basis.reindex <| finCongr W.natDegree_polynomial
/-- The basis $\{1, Y\}$ for the coordinate ring $R[W]$ over the polynomial ring $R[X]$. -/
protected noncomputable def basis : Basis (Fin 2) R[X] W.CoordinateRing := by
  classical 

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
⊢ Basis (Fin 2) R[X] W.CoordinateRing

Next tactic:
exact (subsingleton_or_nontrivial R).by_cases (fun _ => default) fun _ =>
    (AdjoinRoot.powerBasis' W.monic_polynomial).basis.reindex <| finCongr W.natDegree_polynomial
lemma basis_apply (n : Fin 2) :
    CoordinateRing.basis W n = (AdjoinRoot.powerBasis' W.monic_polynomial).gen ^ (n : ℕ) := by
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
n : Fin 2
⊢ (CoordinateRing.basis W) n = (AdjoinRoot.powerBasis' (_ : Monic W.polynomial)).gen ^ ↑n

Next tactic:
classical
  nontriviality R
  rw [CoordinateRing.basis, Or.by_cases, dif_neg <| not_subsingleton R, Basis.reindex_apply,
    PowerBasis.basis_eq_pow]
  rfl
lemma basis_apply (n : Fin 2) :
    CoordinateRing.basis W n = (AdjoinRoot.powerBasis' W.monic_polynomial).gen ^ (n : ℕ) := by
  classical
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
n : Fin 2
⊢ (CoordinateRing.basis W) n = (AdjoinRoot.powerBasis' (_ : Monic W.polynomial)).gen ^ ↑n

Next tactic:
nontriviality R
lemma basis_apply (n : Fin 2) :
    CoordinateRing.basis W n = (AdjoinRoot.powerBasis' W.monic_polynomial).gen ^ (n : ℕ) := by
  classical
  nontriviality R
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
n : Fin 2
✝ : Nontrivial R
⊢ (CoordinateRing.basis W) n = (AdjoinRoot.powerBasis' (_ : Monic W.polynomial)).gen ^ ↑n

Next tactic:
rw [CoordinateRing.basis, Or.by_cases, dif_neg <| not_subsingleton R, Basis.reindex_apply,
    PowerBasis.basis_eq_pow]
lemma basis_apply (n : Fin 2) :
    CoordinateRing.basis W n = (AdjoinRoot.powerBasis' W.monic_polynomial).gen ^ (n : ℕ) := by
  classical
  nontriviality R
  rw [CoordinateRing.basis, Or.by_cases, dif_neg <| not_subsingleton R, Basis.reindex_apply,
    PowerBasis.basis_eq_pow]
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
n : Fin 2
✝ : Nontrivial R
⊢ (AdjoinRoot.powerBasis' (_ : Monic W.polynomial)).gen ^ ↑((finCongr (_ : natDegree W.polynomial = 2)).symm n) =
    (AdjoinRoot.powerBasis' (_ : Monic W.polynomial)).gen ^ ↑n

Next tactic:
rfl
@[simp]
lemma basis_zero : CoordinateRing.basis W 0 = 1 := by
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
⊢ (CoordinateRing.basis W) 0 = 1

Next tactic:
simpa only [basis_apply] using pow_zero _
@[simp]
lemma basis_one : CoordinateRing.basis W 1 = mk W Y := by
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
⊢ (CoordinateRing.basis W) 1 = (mk W) Y

Next tactic:
simpa only [basis_apply] using pow_one _
lemma coe_basis : (CoordinateRing.basis W : Fin 2 → W.CoordinateRing) = ![1, mk W Y] := by
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
⊢ ⇑(CoordinateRing.basis W) = ![1, (mk W) Y]

Next tactic:
ext n
lemma coe_basis : (CoordinateRing.basis W : Fin 2 → W.CoordinateRing) = ![1, mk W Y] := by
  ext n
  

Proof state:
case h
R : Type u
inst✝ : CommRing R
W : Affine R
n : Fin 2
⊢ (CoordinateRing.basis W) n = Matrix.vecCons 1 ![(mk W) Y] n

Next tactic:
fin_cases n
lemma coe_basis : (CoordinateRing.basis W : Fin 2 → W.CoordinateRing) = ![1, mk W Y] := by
  ext n
  fin_cases n
  

Proof state:
case h.head
R : Type u
inst✝ : CommRing R
W : Affine R
⊢ (CoordinateRing.basis W) { val := 0, isLt := (_ : 0 < 2) } =
    Matrix.vecCons 1 ![(mk W) Y] { val := 0, isLt := (_ : 0 < 2) }
case h.tail.head
R : Type u
inst✝ : CommRing R
W : Affine R
⊢ (CoordinateRing.basis W) { val := 1, isLt := (_ : (fun a => a < 2) 1) } =
    Matrix.vecCons 1 ![(mk W) Y] { val := 1, isLt := (_ : (fun a => a < 2) 1) }

Next tactic:
exacts [basis_zero W, basis_one W]
lemma smul_basis_eq_zero {p q : R[X]} (hpq : p • (1 : W.CoordinateRing) + q • mk W Y = 0) :
    p = 0 ∧ q = 0 := by
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
p q : R[X]
hpq : p • 1 + q • (mk W) Y = 0
⊢ p = 0 ∧ q = 0

Next tactic:
have h := Fintype.linearIndependent_iff.mp (CoordinateRing.basis W).linearIndependent ![p, q]
lemma smul_basis_eq_zero {p q : R[X]} (hpq : p • (1 : W.CoordinateRing) + q • mk W Y = 0) :
    p = 0 ∧ q = 0 := by
  have h := Fintype.linearIndependent_iff.mp (CoordinateRing.basis W).linearIndependent ![p, q]
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
p q : R[X]
hpq : p • 1 + q • (mk W) Y = 0
h :
  (Finset.sum Finset.univ fun i => Matrix.vecCons p ![q] i • (CoordinateRing.basis W) i) = 0 →
    ∀ (i : Fin 2), Matrix.vecCons p ![q] i = 0
⊢ p = 0 ∧ q = 0

Next tactic:
erw [Fin.sum_univ_succ, basis_zero, Fin.sum_univ_one, basis_one] at h
lemma smul_basis_eq_zero {p q : R[X]} (hpq : p • (1 : W.CoordinateRing) + q • mk W Y = 0) :
    p = 0 ∧ q = 0 := by
  have h := Fintype.linearIndependent_iff.mp (CoordinateRing.basis W).linearIndependent ![p, q]
  erw [Fin.sum_univ_succ, basis_zero, Fin.sum_univ_one, basis_one] at h
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
p q : R[X]
hpq : p • 1 + q • (mk W) Y = 0
h :
  Matrix.vecCons p ![q] 0 • 1 + Matrix.vecCons p ![q] (Fin.succ 0) • (mk W) Y = 0 →
    ∀ (i : Fin 2), Matrix.vecCons p ![q] i = 0
⊢ p = 0 ∧ q = 0

Next tactic:
exact ⟨h hpq 0, h hpq 1⟩
lemma exists_smul_basis_eq (x : W.CoordinateRing) :
    ∃ p q : R[X], p • (1 : W.CoordinateRing) + q • mk W Y = x := by
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
x : W.CoordinateRing
⊢ ∃ p q, p • 1 + q • (mk W) Y = x

Next tactic:
have h := (CoordinateRing.basis W).sum_equivFun x
lemma exists_smul_basis_eq (x : W.CoordinateRing) :
    ∃ p q : R[X], p • (1 : W.CoordinateRing) + q • mk W Y = x := by
  have h := (CoordinateRing.basis W).sum_equivFun x
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
x : W.CoordinateRing
h : (Finset.sum Finset.univ fun i => (Basis.equivFun (CoordinateRing.basis W)) x i • (CoordinateRing.basis W) i) = x
⊢ ∃ p q, p • 1 + q • (mk W) Y = x

Next tactic:
erw [Fin.sum_univ_succ, Fin.sum_univ_one, basis_zero, basis_one] at h
lemma exists_smul_basis_eq (x : W.CoordinateRing) :
    ∃ p q : R[X], p • (1 : W.CoordinateRing) + q • mk W Y = x := by
  have h := (CoordinateRing.basis W).sum_equivFun x
  erw [Fin.sum_univ_succ, Fin.sum_univ_one, basis_zero, basis_one] at h
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
x : W.CoordinateRing
h :
  (Basis.equivFun (CoordinateRing.basis W)) x 0 • 1 +
      (Basis.equivFun (CoordinateRing.basis W)) x (Fin.succ 0) • (mk W) Y =
    x
⊢ ∃ p q, p • 1 + q • (mk W) Y = x

Next tactic:
exact ⟨_, _, h⟩
lemma smul_basis_mul_C (y : R[X]) (p q : R[X]) :
    (p • (1 : W.CoordinateRing) + q • mk W Y) * mk W (C y) =
      (p * y) • (1 : W.CoordinateRing) + (q * y) • mk W Y := by
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
y p q : R[X]
⊢ (p • 1 + q • (mk W) Y) * (mk W) (C y) = (p * y) • 1 + (q * y) • (mk W) Y

Next tactic:
simp only [smul, _root_.map_mul]
lemma smul_basis_mul_C (y : R[X]) (p q : R[X]) :
    (p • (1 : W.CoordinateRing) + q • mk W Y) * mk W (C y) =
      (p * y) • (1 : W.CoordinateRing) + (q * y) • mk W Y := by
  simp only [smul, _root_.map_mul]
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
y p q : R[X]
⊢ ((mk W) (C p) * 1 + (mk W) (C q) * (mk W) Y) * (mk W) (C y) =
    (mk W) (C p) * (mk W) (C y) * 1 + (mk W) (C q) * (mk W) (C y) * (mk W) Y

Next tactic:
ring1
lemma smul_basis_mul_Y (p q : R[X]) :
    (p • (1 : W.CoordinateRing) + q • mk W Y) * mk W Y =
      (q * (X ^ 3 + C W.a₂ * X ^ 2 + C W.a₄ * X + C W.a₆)) • (1 : W.CoordinateRing) +
        (p - q * (C W.a₁ * X + C W.a₃)) • mk W Y := by
  

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
p q : R[X]
⊢ (p • 1 + q • (mk W) Y) * (mk W) Y =
    (q * (Y ^ 3 + C W.a₂ * Y ^ 2 + C W.a₄ * Y + C W.a₆)) • 1 + (p - q * (C W.a₁ * Y + C W.a₃)) • (mk W) Y

Next tactic:
have Y_sq : mk W Y ^ 2 =
      mk W (C (X ^ 3 + C W.a₂ * X ^ 2 + C W.a₄ * X + C W.a₆) - C (C W.a₁ * X + C W.a₃) * Y) := by
    exact AdjoinRoot.mk_eq_mk.mpr ⟨1, by rw [polynomial]; ring1⟩
lemma smul_basis_mul_Y (p q : R[X]) :
    (p • (1 : W.CoordinateRing) + q • mk W Y) * mk W Y =
      (q * (X ^ 3 + C W.a₂ * X ^ 2 + C W.a₄ * X + C W.a₆)) • (1 : W.CoordinateRing) +
        (p - q * (C W.a₁ * X + C W.a₃)) • mk W Y := by
  have Y_sq : mk W Y ^ 2 =
      mk W (C (X ^ 3 + C W.a₂ * X ^ 2 + C W.a₄ * X + C W.a₆) - C (C W.a₁ * X + C W.a₃) * Y) := by
    

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
p q : R[X]
⊢ (mk W) Y ^ 2 = (mk W) (C (Y ^ 3 + C W.a₂ * Y ^ 2 + C W.a₄ * Y + C W.a₆) - C (C W.a₁ * Y + C W.a₃) * Y)

Next tactic:
exact AdjoinRoot.mk_eq_mk.mpr ⟨1, by rw [polynomial]; ring1⟩
lemma smul_basis_mul_Y (p q : R[X]) :
    (p • (1 : W.CoordinateRing) + q • mk W Y) * mk W Y =
      (q * (X ^ 3 + C W.a₂ * X ^ 2 + C W.a₄ * X + C W.a₆)) • (1 : W.CoordinateRing) +
        (p - q * (C W.a₁ * X + C W.a₃)) • mk W Y := by
  have Y_sq : mk W Y ^ 2 =
      mk W (C (X ^ 3 + C W.a₂ * X ^ 2 + C W.a₄ * X + C W.a₆) - C (C W.a₁ * X + C W.a₃) * Y) := by
    exact AdjoinRoot.mk_eq_mk.mpr ⟨1, by 

Proof state:
R : Type u
inst✝ : CommRing R
W : Affine R
p q : R[X]
⊢ (fun x => x ^ 2) Y - (C (Y ^ 3 + C W.a₂ * Y ^ 2 + C W.a₄ * Y + C W.a₆) - C (C W.a₁ * Y + C W.a₃) * Y) =
    W.polynomial * 1

Next tactic:
rw [polynomial]