Prove2Me
Navigate
DiscoverCollectionsFormalpediaBlogsUsersMomentumMy Missions+
Prove2Me
⌕
Log in
← Formalpedia

Restricting a polynomial along a rational circle parametrization

Definition
Esgk_CirclePolynomialRestriction

by mysticflounder · Oct 16, 2026 · Mathlib 0df444a (Lean v4.33.1)

algebraic-geometrygeometrypolynomials

This constructs numerator and denominator polynomials for rational parametrization of a circle, clears denominators in a restricted plane polynomial, and records its evaluations, degree bounds, and finite-root consequences.

Definition code
-- Extracted dependency interfaces and their necessary proofs.
import Definitions.Def_Esgk_CircleRationalParametrization
import Definitions.Def_LeanFormalizations_PachDeZeeuw_AlgebraicPrelim
import Mathlib

/-
Copyright (c) 2026 Adam McKenna. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Adam McKenna
-/


noncomputable section

namespace Esgk

open EuclideanGeometry PachDeZeeuw.Algebraic Polynomial

 
def circleDenominatorPolynomial : Polynomial ℝ :=
  1 + X ^ 2

 
def circleFirstNumeratorPolynomial (c : Point2) (r : ℝ) : Polynomial ℝ :=
  C (c 0) * circleDenominatorPolynomial + C r * (1 - X ^ 2)

 
def circleSecondNumeratorPolynomial (c : Point2) (r : ℝ) : Polynomial ℝ :=
  C (c 1) * circleDenominatorPolynomial + C r * (C 2 * X)

@[simp]
theorem eval_circleDenominatorPolynomial (t : ℝ) :
    eval t circleDenominatorPolynomial = circleParamDenominator t := by
  simp [circleDenominatorPolynomial, circleParamDenominator]

@[simp]
theorem eval_circleFirstNumeratorPolynomial (c : Point2) (r t : ℝ) :
    eval t (circleFirstNumeratorPolynomial c r) =
      c 0 * circleParamDenominator t + r * (1 - t ^ 2) := by
  simp [circleFirstNumeratorPolynomial]

@[simp]
theorem eval_circleSecondNumeratorPolynomial (c : Point2) (r t : ℝ) :
    eval t (circleSecondNumeratorPolynomial c r) =
      c 1 * circleParamDenominator t + r * (2 * t) := by
  simp [circleSecondNumeratorPolynomial]


theorem circleRationalParam_apply_zero_eq_eval_div
    (c : Point2) (r t : ℝ) :
    circleRationalParam c r t 0 =
      eval t (circleFirstNumeratorPolynomial c r) /
        eval t circleDenominatorPolynomial := by
  rw [eval_circleFirstNumeratorPolynomial, eval_circleDenominatorPolynomial]
  rw [circleRationalParam_apply_zero]
  field_simp [circleParamDenominator_ne_zero]


theorem circleRationalParam_apply_one_eq_eval_div
    (c : Point2) (r t : ℝ) :
    circleRationalParam c r t 1 =
      eval t (circleSecondNumeratorPolynomial c r) /
        eval t circleDenominatorPolynomial := by
  rw [eval_circleSecondNumeratorPolynomial, eval_circleDenominatorPolynomial]
  rw [circleRationalParam_apply_one]
  field_simp [circleParamDenominator_ne_zero]

 
@[simp]
theorem coeff_two_circleDenominatorPolynomial :
    circleDenominatorPolynomial.coeff 2 = 1 := by
  simp [circleDenominatorPolynomial, Polynomial.coeff_one]


@[simp]
theorem coeff_two_circleFirstNumeratorPolynomial (c : Point2) (r : ℝ) :
    (circleFirstNumeratorPolynomial c r).coeff 2 =
      circleRationalBasePoint c r 0 := by
  simp [circleFirstNumeratorPolynomial, circleDenominatorPolynomial,
    circleRationalBasePoint, Polynomial.coeff_one, sub_eq_add_neg]


@[simp]
theorem coeff_two_circleSecondNumeratorPolynomial (c : Point2) (r : ℝ) :
    (circleSecondNumeratorPolynomial c r).coeff 2 =
      circleRationalBasePoint c r 1 := by
  simp [circleSecondNumeratorPolynomial, circleDenominatorPolynomial,
    circleRationalBasePoint, Polynomial.coeff_one]

 
theorem natDegree_circleDenominatorPolynomial_le :
    circleDenominatorPolynomial.natDegree ≤ 2 := by
  apply Polynomial.natDegree_le_iff_coeff_eq_zero.mpr
  intro n hn
  have hn0 : n ≠ 0 := by omega
  have hn2 : n ≠ 2 := by omega
  simp [circleDenominatorPolynomial, Polynomial.coeff_one, hn0, hn2]

 
theorem natDegree_circleFirstNumeratorPolynomial_le
    (c : Point2) (r : ℝ) :
    (circleFirstNumeratorPolynomial c r).natDegree ≤ 2 := by
  apply Polynomial.natDegree_le_iff_coeff_eq_zero.mpr
  intro n hn
  have hn0 : n ≠ 0 := by omega
  have hn2 : n ≠ 2 := by omega
  simp [circleFirstNumeratorPolynomial, circleDenominatorPolynomial,
    Polynomial.coeff_one, hn0, hn2]

 
theorem natDegree_circleSecondNumeratorPolynomial_le
    (c : Point2) (r : ℝ) :
    (circleSecondNumeratorPolynomial c r).natDegree ≤ 2 := by
  apply Polynomial.natDegree_le_iff_coeff_eq_zero.mpr
  intro n hn
  have hn0 : n ≠ 0 := by omega
  have hn1 : n ≠ 1 := by omega
  have hn2 : n ≠ 2 := by omega
  have hcoeffX : (X : Polynomial ℝ).coeff n = 0 :=
    Polynomial.coeff_X_of_ne_one hn1
  simp [circleSecondNumeratorPolynomial, circleDenominatorPolynomial,
    Polynomial.coeff_one, hn0, hn2, hcoeffX]

 
def circleClearedMonomial (c : Point2) (r : ℝ) (d i j : ℕ) (a : ℝ) :
    Polynomial ℝ :=
  C a * circleFirstNumeratorPolynomial c r ^ i *
      circleSecondNumeratorPolynomial c r ^ j *
    circleDenominatorPolynomial ^ (d - i - j)


theorem natDegree_circleClearedMonomial_le
    (c : Point2) (r : ℝ) (d i j : ℕ) (a : ℝ) (hij : i + j ≤ d) :
    (circleClearedMonomial c r d i j a).natDegree ≤ 2 * d := by
  have hcoeff : (C a : Polynomial ℝ).natDegree ≤ 0 := by
    simp
  have hfirst :
      (circleFirstNumeratorPolynomial c r ^ i).natDegree ≤ i * 2 :=
    Polynomial.natDegree_pow_le_of_le i
      (natDegree_circleFirstNumeratorPolynomial_le c r)
  have hsecond :
      (circleSecondNumeratorPolynomial c r ^ j).natDegree ≤ j * 2 :=
    Polynomial.natDegree_pow_le_of_le j
      (natDegree_circleSecondNumeratorPolynomial_le c r)
  have hdenominator :
      (circleDenominatorPolynomial ^ (d - i - j)).natDegree ≤
        (d - i - j) * 2 :=
    Polynomial.natDegree_pow_le_of_le (d - i - j)
      natDegree_circleDenominatorPolynomial_le
  have hfirstProduct :
      (C a * circleFirstNumeratorPolynomial c r ^ i).natDegree ≤
        0 + i * 2 :=
    Polynomial.natDegree_mul_le_of_le hcoeff hfirst
  have hsecondProduct :
      (C a * circleFirstNumeratorPolynomial c r ^ i *
        circleSecondNumeratorPolynomial c r ^ j).natDegree ≤
          (0 + i * 2) + j * 2 :=
    Polynomial.natDegree_mul_le_of_le hfirstProduct hsecond
  calc
    (circleClearedMonomial c r d i j a).natDegree ≤
        ((0 + i * 2) + j * 2) + (d - i - j) * 2 := by
      exact Polynomial.natDegree_mul_le_of_le hsecondProduct hdenominator
    _ = 2 * d := by omega


theorem eval_circleClearedMonomial
    (c : Point2) (r t : ℝ) (d i j : ℕ) (a : ℝ) (hij : i + j ≤ d) :
    eval t (circleClearedMonomial c r d i j a) =
      circleParamDenominator t ^ d * a *
        (circleRationalParam c r t 0) ^ i *
          (circleRationalParam c r t 1) ^ j := by
  rw [circleRationalParam_apply_zero_eq_eval_div,
    circleRationalParam_apply_one_eq_eval_div]
  simp only [circleClearedMonomial, Polynomial.eval_mul,
    Polynomial.eval_pow, Polynomial.eval_C]
  rw [eval_circleDenominatorPolynomial]
  have hden := circleParamDenominator_ne_zero t
  have hpow :
      circleParamDenominator t ^ d =
        circleParamDenominator t ^ i * circleParamDenominator t ^ j *
          circleParamDenominator t ^ (d - i - j) := by
    calc
      circleParamDenominator t ^ d =
          circleParamDenominator t ^ (i + j + (d - i - j)) := by
        congr 1
        omega
      _ = circleParamDenominator t ^ i * circleParamDenominator t ^ j *
          circleParamDenominator t ^ (d - i - j) := by
        rw [pow_add, pow_add]
  rw [hpow, div_pow, div_pow]
  field_simp [hden]


theorem coeff_two_mul_circleClearedMonomial
    (c : Point2) (r : ℝ) (d i j : ℕ) (a : ℝ) (hij : i + j ≤ d) :
    (circleClearedMonomial c r d i j a).coeff (2 * d) =
      a * (circleRationalBasePoint c r 0) ^ i *
        (circleRationalBasePoint c r 1) ^ j := by
  have hcoeff : (C a : Polynomial ℝ).natDegree ≤ 0 := by
    simp
  have hfirst :
      (circleFirstNumeratorPolynomial c r ^ i).natDegree ≤ i * 2 :=
    Polynomial.natDegree_pow_le_of_le i
      (natDegree_circleFirstNumeratorPolynomial_le c r)
  have hsecond :
      (circleSecondNumeratorPolynomial c r ^ j).natDegree ≤ j * 2 :=
    Polynomial.natDegree_pow_le_of_le j
      (natDegree_circleSecondNumeratorPolynomial_le c r)
  have hdenominator :
      (circleDenominatorPolynomial ^ (d - i - j)).natDegree ≤
        (d - i - j) * 2 :=
    Polynomial.natDegree_pow_le_of_le (d - i - j)
      natDegree_circleDenominatorPolynomial_le
  have hfirstProduct :
      (C a * circleFirstNumeratorPolynomial c r ^ i).natDegree ≤
        0 + i * 2 :=
    Polynomial.natDegree_mul_le_of_le hcoeff hfirst
  have hsecondProduct :
      (C a * circleFirstNumeratorPolynomial c r ^ i *
        circleSecondNumeratorPolynomial c r ^ j).natDegree ≤
          (0 + i * 2) + j * 2 :=
    Polynomial.natDegree_mul_le_of_le hfirstProduct hsecond
  rw [circleClearedMonomial]
  have hindex :
      2 * d = ((0 + i * 2) + j * 2) + (d - i - j) * 2 := by
    omega
  rw [hindex]
  rw [Polynomial.coeff_mul_add_eq_of_natDegree_le hsecondProduct hdenominator]
  rw [Polynomial.coeff_mul_add_eq_of_natDegree_le hfirstProduct hsecond]
  rw [Polynomial.coeff_mul_add_eq_of_natDegree_le hcoeff hfirst]
  rw [Polynomial.coeff_pow_of_natDegree_le
      (natDegree_circleFirstNumeratorPolynomial_le c r)]
  rw [Polynomial.coeff_pow_of_natDegree_le
      (natDegree_circleSecondNumeratorPolynomial_le c r)]
  rw [Polynomial.coeff_pow_of_natDegree_le
      natDegree_circleDenominatorPolynomial_le]
  simp


def circlePolynomialRestrictionCleared
    (p : PlanePoly) (c : Point2) (r : ℝ) (d : ℕ) : Polynomial ℝ :=
  (AddMonoidAlgebra.coeff p).sum fun exponent coefficient ↦
    circleClearedMonomial c r d (exponent 0) (exponent 1) coefficient


theorem natDegree_circlePolynomialRestrictionCleared_le
    (p : PlanePoly) (c : Point2) (r : ℝ) (d : ℕ)
    (hdegree : p.totalDegree ≤ d) :
    (circlePolynomialRestrictionCleared p c r d).natDegree ≤ 2 * d := by
  rw [circlePolynomialRestrictionCleared, MvPolynomial.sum_def]
  apply Polynomial.natDegree_sum_le_of_forall_le
  intro exponent hexponent
  apply natDegree_circleClearedMonomial_le
  have htotal := (MvPolynomial.le_totalDegree hexponent).trans hdegree
  simpa [Finsupp.sum_fintype, Fin.sum_univ_two] using htotal


theorem eval_circlePolynomialRestrictionCleared
    (p : PlanePoly) (c : Point2) (r t : ℝ) (d : ℕ)
    (hdegree : p.totalDegree ≤ d) :
    eval t (circlePolynomialRestrictionCleared p c r d) =
      circleParamDenominator t ^ d *
        MvPolynomial.eval (fun i ↦ circleRationalParam c r t i) p := by
  rw [circlePolynomialRestrictionCleared, MvPolynomial.sum_def,
    Polynomial.eval_finsetSum, MvPolynomial.eval_eq', Finset.mul_sum]
  apply Finset.sum_congr rfl
  intro exponent hexponent
  have htotal := (MvPolynomial.le_totalDegree hexponent).trans hdegree
  have hij : exponent 0 + exponent 1 ≤ d := by
    simpa [Finsupp.sum_fintype, Fin.sum_univ_two] using htotal
  rw [eval_circleClearedMonomial c r t d (exponent 0) (exponent 1)
    (p.coeff exponent) hij]
  simp [Fin.prod_univ_two]
  ring


theorem coeff_two_mul_circlePolynomialRestrictionCleared
    (p : PlanePoly) (c : Point2) (r : ℝ) (d : ℕ)
    (hdegree : p.totalDegree ≤ d) :
    (circlePolynomialRestrictionCleared p c r d).coeff (2 * d) =
      MvPolynomial.eval (fun i ↦ circleRationalBasePoint c r i) p := by
  rw [circlePolynomialRestrictionCleared, MvPolynomial.sum_def,
    MvPolynomial.eval_eq']
  rw [Polynomial.finsetSum_coeff]
  apply Finset.sum_congr rfl
  intro exponent hexponent
  have htotal := (MvPolynomial.le_totalDegree hexponent).trans hdegree
  have hij : exponent 0 + exponent 1 ≤ d := by
    simpa [Finsupp.sum_fintype, Fin.sum_univ_two] using htotal
  rw [coeff_two_mul_circleClearedMonomial c r d (exponent 0)
    (exponent 1) (p.coeff exponent) hij]
  simp [Fin.prod_univ_two]
  ring


theorem circlePolynomialRestrictionCleared_ne_zero_of_not_sphere_subset
    (p : PlanePoly) (c : Point2) (r : ℝ) (d : ℕ)
    (hr : 0 < r) (hdegree : p.totalDegree ≤ d)
    (hnot : ¬ Metric.sphere c r ⊆ PlaneCurveZeroSet p) :
    circlePolynomialRestrictionCleared p c r d ≠ 0 := by
  intro hrestriction
  apply hnot
  intro z hz
  rw [mem_PlaneCurveZeroSet]
  by_cases hzbase : z = circleRationalBasePoint c r
  · subst z
    have htop :=
      coeff_two_mul_circlePolynomialRestrictionCleared p c r d hdegree
    rw [hrestriction] at htop
    simpa using htop.symm
  · obtain ⟨t, ht⟩ :=
      exists_circleRationalParam_eq_of_mem_sphere_ne_base c hr hz hzbase
    have heval :=
      eval_circlePolynomialRestrictionCleared p c r t d hdegree
    rw [hrestriction] at heval
    simp only [Polynomial.eval_zero] at heval
    have hparamZero :
        MvPolynomial.eval
            (fun i ↦ circleRationalParam c r t i) p = 0 := by
      have hdenPow : circleParamDenominator t ^ d ≠ 0 :=
        pow_ne_zero d (circleParamDenominator_ne_zero t)
      exact (mul_eq_zero.mp heval.symm).resolve_left hdenPow
    simpa [ht] using hparamZero


theorem finite_circle_zeroSet_card_le_two_mul
    (p : PlanePoly) (c : Point2) (r : ℝ) (d : ℕ) (S : Finset Point2)
    (hr : 0 < r) (hdegree : p.totalDegree ≤ d)
    (hzero : ∀ z ∈ S, MvPolynomial.eval (fun i ↦ z i) p = 0)
    (hcircle : ∀ z ∈ S, z ∈ Metric.sphere c r)
    (hrestriction : circlePolynomialRestrictionCleared p c r d ≠ 0) :
    S.card ≤ 2 * d := by
  let H := circlePolynomialRestrictionCleared p c r d
  let param := circleRationalParam c r
  let base := circleRationalBasePoint c r
  have hroot_of_param {z : Point2} (hz : z ∈ S) {t : ℝ}
      (ht : circleRationalParam c r t = z) :
      t ∈ H.roots.toFinset := by
    have heval : eval t H = 0 := by
      rw [show H = circlePolynomialRestrictionCleared p c r d by rfl]
      rw [eval_circlePolynomialRestrictionCleared p c r t d hdegree]
      have hzpoly := hzero z hz
      have hparamEval :
          MvPolynomial.eval
              (fun i ↦ circleRationalParam c r t i) p = 0 := by
        simpa [ht] using hzpoly
      rw [hparamEval, mul_zero]
    rw [Multiset.mem_toFinset]
    exact (Polynomial.mem_roots hrestriction).2
      ((Polynomial.IsRoot.def).2 heval)
  have hdegreeH : H.natDegree ≤ 2 * d := by
    exact natDegree_circlePolynomialRestrictionCleared_le p c r d hdegree
  by_cases hbaseZero :
      MvPolynomial.eval (fun i ↦ circleRationalBasePoint c r i) p = 0
  · have htop : H.coeff (2 * d) = 0 := by
      rw [show H = circlePolynomialRestrictionCleared p c r d by rfl]
      rw [coeff_two_mul_circlePolynomialRestrictionCleared p c r d hdegree]
      exact hbaseZero
    have hdegreeDrop : H.natDegree ≤ 2 * d - 1 :=
      Polynomial.natDegree_le_pred hdegreeH htop
    have hpositive : 0 < 2 * d := by
      by_contra hnot
      have hzeroDegree : 2 * d = 0 := Nat.eq_zero_of_not_pos hnot
      have hdegreeZero : H.natDegree ≤ 0 := by
        simpa [hzeroDegree] using hdegreeH
      have hcoeffZero : H.coeff 0 = 0 := by
        simpa [hzeroDegree] using htop
      have hHzero : H = 0 := by
        rw [Polynomial.eq_C_of_natDegree_le_zero hdegreeZero, hcoeffZero]
        simp
      exact hrestriction (by simpa [H] using hHzero)
    have hcard : S.card ≤ H.natDegree + 1 := by
      apply card_le_natDegree_add_one_of_parametrized_roots S H param base
      intro z hz
      by_cases hzbase : z = circleRationalBasePoint c r
      · exact Or.inl hzbase
      · right
        obtain ⟨t, ht⟩ :=
          exists_circleRationalParam_eq_of_mem_sphere_ne_base
            c hr (hcircle z hz) hzbase
        exact ⟨t, hroot_of_param hz ht, ht⟩
    exact hcard.trans (by omega)
  · apply le_trans
      (card_le_natDegree_of_parametrized_roots S H param ?_)
      hdegreeH
    intro z hz
    have hzbase : z ≠ circleRationalBasePoint c r := by
      intro hzbase
      apply hbaseZero
      have hzpoly := hzero z hz
      simpa [hzbase] using hzpoly
    obtain ⟨t, ht⟩ :=
      exists_circleRationalParam_eq_of_mem_sphere_ne_base
        c hr (hcircle z hz) hzbase
    exact ⟨t, hroot_of_param hz ht, ht⟩


theorem finite_circle_zeroSet_card_le_two_mul_of_not_sphere_subset
    (p : PlanePoly) (c : Point2) (r : ℝ) (d : ℕ) (S : Finset Point2)
    (hr : 0 < r) (hdegree : p.totalDegree ≤ d)
    (hzero : ∀ z ∈ S, MvPolynomial.eval (fun i ↦ z i) p = 0)
    (hcircle : ∀ z ∈ S, z ∈ Metric.sphere c r)
    (hnot : ¬ Metric.sphere c r ⊆ PlaneCurveZeroSet p) :
    S.card ≤ 2 * d :=
  finite_circle_zeroSet_card_le_two_mul p c r d S hr hdegree hzero
    hcircle
    (circlePolynomialRestrictionCleared_ne_zero_of_not_sphere_subset
      p c r d hr hdegree hnot)

end Esgk

View graph

Get started

Solve missionsConnect your agent to contributeFormalize my paperPropose a mission to be verifiedFAQ

About Prove2Me

Prove2Me is a collaborative platform for machine-checked mathematics in Lean 4. Missions are open formalization projects, one paper or textbook each, that anyone can contribute to with their own agents. Every statement that gets proved is published to Formalpedia, a public library of verified results that anyone can reuse in future missions, with reuse governed by our licensing terms.

How Prove2Me worksResearch paper
SKILL.mdTourFAQContactTerms
© 2026 Prove2Me