File: Mathlib/Algebra/Polynomial/EraseLead.lean

full_name: Polynomial.eraseLead
code: /-- `eraseLead f` for a polynomial `f` is the polynomial obtained by
subtracting from `f` the leading term of `f`. -/
def eraseLead (f : R[X]) : R[X] 
goal: R[X]

full_name: Polynomial.eraseLead_support
code: theorem eraseLead_support (f : R[X]) : f.eraseLead.support = f.support.erase f.natDegree 
goal: f.eraseLead.support = f.support.erase f.natDegree

full_name: Polynomial.eraseLead_coeff
code: theorem eraseLead_coeff (i : ℕ) :
    f.eraseLead.coeff i = if i = f.natDegree then 0 else f.coeff i 
goal: f.eraseLead.coeff i = if i = f.natDegree then 0 else f.coeff i

full_name: Polynomial.eraseLead_coeff_natDegree
code: @[simp]
theorem eraseLead_coeff_natDegree : f.eraseLead.coeff f.natDegree = 0 
goal: f.eraseLead.coeff f.natDegree = 0

full_name: Polynomial.eraseLead_coeff_of_ne
code: theorem eraseLead_coeff_of_ne (i : ℕ) (hi : i ≠ f.natDegree) : f.eraseLead.coeff i = f.coeff i 
goal: f.eraseLead.coeff i = f.coeff i

full_name: Polynomial.eraseLead_zero
code: @[simp]
theorem eraseLead_zero : eraseLead (0 : R[X]) = 0 
goal: Polynomial.eraseLead 0 = 0

full_name: Polynomial.eraseLead_add_monomial_natDegree_leadingCoeff
code: @[simp]
theorem eraseLead_add_monomial_natDegree_leadingCoeff (f : R[X]) :
    f.eraseLead + monomial f.natDegree f.leadingCoeff = f 
goal: f.eraseLead + (Polynomial.monomial f.natDegree) f.leadingCoeff = f

full_name: Polynomial.eraseLead_add_C_mul_X_pow
code: @[simp]
theorem eraseLead_add_C_mul_X_pow (f : R[X]) :
    f.eraseLead + C f.leadingCoeff * X ^ f.natDegree = f 
goal: f.eraseLead + Polynomial.C f.leadingCoeff * Polynomial.X ^ f.natDegree = f

full_name: Polynomial.self_sub_monomial_natDegree_leadingCoeff
code: @[simp]
theorem self_sub_monomial_natDegree_leadingCoeff {R : Type*} [Ring R] (f : R[X]) :
    f - monomial f.natDegree f.leadingCoeff = f.eraseLead 
goal: f - (Polynomial.monomial f.natDegree) f.leadingCoeff = f.eraseLead

full_name: Polynomial.self_sub_C_mul_X_pow
code: @[simp]
theorem self_sub_C_mul_X_pow {R : Type*} [Ring R] (f : R[X]) :
    f - C f.leadingCoeff * X ^ f.natDegree = f.eraseLead 
goal: f - Polynomial.C f.leadingCoeff * Polynomial.X ^ f.natDegree = f.eraseLead

full_name: Polynomial.eraseLead_ne_zero
code: theorem eraseLead_ne_zero (f0 : 2 ≤ f.support.card) : eraseLead f ≠ 0 
goal: f.eraseLead ≠ 0

full_name: Polynomial.lt_natDegree_of_mem_eraseLead_support
code: theorem lt_natDegree_of_mem_eraseLead_support {a : ℕ} (h : a ∈ (eraseLead f).support) :
    a < f.natDegree 
goal: a < f.natDegree

full_name: Polynomial.ne_natDegree_of_mem_eraseLead_support
code: theorem ne_natDegree_of_mem_eraseLead_support {a : ℕ} (h : a ∈ (eraseLead f).support) :
    a ≠ f.natDegree 
goal: a ≠ f.natDegree

full_name: Polynomial.natDegree_not_mem_eraseLead_support
code: theorem natDegree_not_mem_eraseLead_support : f.natDegree ∉ (eraseLead f).support 
goal: f.natDegree ∉ f.eraseLead.support

full_name: Polynomial.eraseLead_support_card_lt
code: theorem eraseLead_support_card_lt (h : f ≠ 0) : (eraseLead f).support.card < f.support.card 
goal: f.eraseLead.support.card < f.support.card

full_name: Polynomial.card_support_eraseLead_add_one
code: theorem card_support_eraseLead_add_one (h : f ≠ 0) :
    f.eraseLead.support.card + 1 = f.support.card 
goal: f.eraseLead.support.card + 1 = f.support.card

full_name: Polynomial.card_support_eraseLead
code: @[simp]
theorem card_support_eraseLead : f.eraseLead.support.card = f.support.card - 1 
goal: f.eraseLead.support.card = f.support.card - 1

full_name: Polynomial.card_support_eraseLead'
code: theorem card_support_eraseLead' {c : ℕ} (fc : f.support.card = c + 1) :
    f.eraseLead.support.card = c 
goal: f.eraseLead.support.card = c

full_name: Polynomial.card_support_eq_one_of_eraseLead_eq_zero
code: theorem card_support_eq_one_of_eraseLead_eq_zero (h₀ : f ≠ 0) (h₁ : f.eraseLead = 0) :
    f.support.card = 1 
goal: f.support.card = 1

full_name: Polynomial.card_support_le_one_of_eraseLead_eq_zero
code: theorem card_support_le_one_of_eraseLead_eq_zero (h : f.eraseLead = 0) : f.support.card ≤ 1 
goal: f.support.card ≤ 1

full_name: Polynomial.eraseLead_monomial
code: @[simp]
theorem eraseLead_monomial (i : ℕ) (r : R) : eraseLead (monomial i r) = 0 
goal: ((Polynomial.monomial i) r).eraseLead = 0

full_name: Polynomial.eraseLead_C
code: @[simp]
theorem eraseLead_C (r : R) : eraseLead (C r) = 0 
goal: (Polynomial.C r).eraseLead = 0

full_name: Polynomial.eraseLead_X
code: @[simp]
theorem eraseLead_X : eraseLead (X : R[X]) = 0 
goal: Polynomial.X.eraseLead = 0

full_name: Polynomial.eraseLead_X_pow
code: @[simp]
theorem eraseLead_X_pow (n : ℕ) : eraseLead (X ^ n : R[X]) = 0 
goal: (Polynomial.X ^ n).eraseLead = 0

full_name: Polynomial.eraseLead_C_mul_X_pow
code: @[simp]
theorem eraseLead_C_mul_X_pow (r : R) (n : ℕ) : eraseLead (C r * X ^ n) = 0 
goal: (Polynomial.C r * Polynomial.X ^ n).eraseLead = 0

full_name: Polynomial.eraseLead_C_mul_X
code: @[simp] lemma eraseLead_C_mul_X (r : R) : eraseLead (C r * X) = 0 
goal: (Polynomial.C r * Polynomial.X).eraseLead = 0

full_name: Polynomial.eraseLead_add_of_natDegree_lt_left
code: theorem eraseLead_add_of_natDegree_lt_left {p q : R[X]} (pq : q.natDegree < p.natDegree) :
    (p + q).eraseLead = p.eraseLead + q 
goal: (p + q).eraseLead = p.eraseLead + q

full_name: Polynomial.eraseLead_add_of_natDegree_lt_right
code: theorem eraseLead_add_of_natDegree_lt_right {p q : R[X]} (pq : p.natDegree < q.natDegree) :
    (p + q).eraseLead = p + q.eraseLead 
goal: (p + q).eraseLead = p + q.eraseLead

full_name: Polynomial.eraseLead_degree_le
code: theorem eraseLead_degree_le : (eraseLead f).degree ≤ f.degree 
goal: f.eraseLead.degree ≤ f.degree

full_name: Polynomial.eraseLead_natDegree_le_aux
code: theorem eraseLead_natDegree_le_aux : (eraseLead f).natDegree ≤ f.natDegree 
goal: f.eraseLead.natDegree ≤ f.natDegree

full_name: Polynomial.eraseLead_natDegree_lt
code: theorem eraseLead_natDegree_lt (f0 : 2 ≤ f.support.card) : (eraseLead f).natDegree < f.natDegree 
goal: f.eraseLead.natDegree < f.natDegree

full_name: Polynomial.natDegree_pos_of_eraseLead_ne_zero
code: theorem natDegree_pos_of_eraseLead_ne_zero (h : f.eraseLead ≠ 0) : 0 < f.natDegree 
goal: 0 < f.natDegree

full_name: Polynomial.eraseLead_natDegree_lt_or_eraseLead_eq_zero
code: theorem eraseLead_natDegree_lt_or_eraseLead_eq_zero (f : R[X]) :
    (eraseLead f).natDegree < f.natDegree ∨ f.eraseLead = 0 
goal: f.eraseLead.natDegree < f.natDegree ∨ f.eraseLead = 0

full_name: Polynomial.eraseLead_natDegree_le
code: theorem eraseLead_natDegree_le (f : R[X]) : (eraseLead f).natDegree ≤ f.natDegree - 1 
goal: f.eraseLead.natDegree ≤ f.natDegree - 1

full_name: Polynomial.natDegree_eraseLead
code: lemma natDegree_eraseLead (h : f.nextCoeff ≠ 0) : f.eraseLead.natDegree = f.natDegree - 1 
goal: f.eraseLead.natDegree = f.natDegree - 1

full_name: Polynomial.natDegree_eraseLead_add_one
code: lemma natDegree_eraseLead_add_one (h : f.nextCoeff ≠ 0) :
    f.eraseLead.natDegree + 1 = f.natDegree 
goal: f.eraseLead.natDegree + 1 = f.natDegree

full_name: Polynomial.natDegree_eraseLead_le_of_nextCoeff_eq_zero
code: theorem natDegree_eraseLead_le_of_nextCoeff_eq_zero (h : f.nextCoeff = 0) :
    f.eraseLead.natDegree ≤ f.natDegree - 2 
goal: f.eraseLead.natDegree ≤ f.natDegree - 2

full_name: Polynomial.two_le_natDegree_of_nextCoeff_eraseLead
code: lemma two_le_natDegree_of_nextCoeff_eraseLead (hlead : f.eraseLead ≠ 0) (hnext : f.nextCoeff = 0) :
    2 ≤ f.natDegree 
goal: 2 ≤ f.natDegree

full_name: Polynomial.leadingCoeff_eraseLead_eq_nextCoeff
code: theorem leadingCoeff_eraseLead_eq_nextCoeff (h : f.nextCoeff ≠ 0) :
    f.eraseLead.leadingCoeff = f.nextCoeff 
goal: f.eraseLead.leadingCoeff = f.nextCoeff

full_name: Polynomial.nextCoeff_eq_zero_of_eraseLead_eq_zero
code: theorem nextCoeff_eq_zero_of_eraseLead_eq_zero (h : f.eraseLead = 0) : f.nextCoeff = 0 
goal: f.nextCoeff = 0

full_name: Polynomial.induction_with_natDegree_le
code: /-- An induction lemma for polynomials. It takes a natural number `N` as a parameter, that is
required to be at least as big as the `nat_degree` of the polynomial.  This is useful to prove
results where you want to change each term in a polynomial to something else depending on the
`nat_degree` of the polynomial itself and not on the specific `nat_degree` of each term. -/
theorem induction_with_natDegree_le (P : R[X] → Prop) (N : ℕ) (P_0 : P 0)
    (P_C_mul_pow : ∀ n : ℕ, ∀ r : R, r ≠ 0 → n ≤ N → P (C r * X ^ n))
    (P_C_add : ∀ f g : R[X], f.natDegree < g.natDegree → g.natDegree ≤ N → P f → P g → P (f + g)) :
    ∀ f : R[X], f.natDegree ≤ N → P f 
goal: f.natDegree ≤ N → P f

full_name: Polynomial.mono_map_natDegree_eq
code: /-- Let `φ : R[x] → S[x]` be an additive map, `k : ℕ` a bound, and `fu : ℕ → ℕ` a
"sufficiently monotone" map.  Assume also that
* `φ` maps to `0` all monomials of degree less than `k`,
* `φ` maps each monomial `m` in `R[x]` to a polynomial `φ m` of degree `fu (deg m)`.
Then, `φ` maps each polynomial `p` in `R[x]` to a polynomial of degree `fu (deg p)`. -/
theorem mono_map_natDegree_eq {S F : Type*} [Semiring S]
    [FunLike F R[X] S[X]] [AddMonoidHomClass F R[X] S[X]] {φ : F}
    {p : R[X]} (k : ℕ) (fu : ℕ → ℕ) (fu0 : ∀ {n}, n ≤ k → fu n = 0)
    (fc : ∀ {n m}, k ≤ n → n < m → fu n < fu m) (φ_k : ∀ {f : R[X]}, f.natDegree < k → φ f = 0)
    (φ_mon_nat : ∀ n c, c ≠ 0 → (φ (monomial n c)).natDegree = fu n) :
    (φ p).natDegree = fu p.natDegree 
goal: (φ p).natDegree = fu p.natDegree

full_name: Polynomial.map_natDegree_eq_sub
code: theorem map_natDegree_eq_sub {S F : Type*} [Semiring S]
    [FunLike F R[X] S[X]] [AddMonoidHomClass F R[X] S[X]] {φ : F}
    {p : R[X]} {k : ℕ} (φ_k : ∀ f : R[X], f.natDegree < k → φ f = 0)
    (φ_mon : ∀ n c, c ≠ 0 → (φ (monomial n c)).natDegree = n - k) :
    (φ p).natDegree = p.natDegree - k 
goal: (φ p).natDegree = p.natDegree - k

full_name: Polynomial.map_natDegree_eq_natDegree
code: theorem map_natDegree_eq_natDegree {S F : Type*} [Semiring S]
    [FunLike F R[X] S[X]] [AddMonoidHomClass F R[X] S[X]]
    {φ : F} (p) (φ_mon_nat : ∀ n c, c ≠ 0 → (φ (monomial n c)).natDegree = n) :
    (φ p).natDegree = p.natDegree 
goal: (φ p).natDegree = p.natDegree

full_name: Polynomial.card_support_eq'
code: theorem card_support_eq' {n : ℕ} (k : Fin n → ℕ) (x : Fin n → R) (hk : Function.Injective k)
    (hx : ∀ i, x i ≠ 0) : (∑ i, C (x i) * X ^ k i).support.card = n 
goal: (∑ i : Fin n, Polynomial.C (x i) * Polynomial.X ^ k i).support.card = n

full_name: Polynomial.card_support_eq
code: theorem card_support_eq {n : ℕ} :
    f.support.card = n ↔
      ∃ (k : Fin n → ℕ) (x : Fin n → R) (hk : StrictMono k) (hx : ∀ i, x i ≠ 0),
        f = ∑ i, C (x i) * X ^ k i 
goal: f.support.card = n ↔
  ∃ k x, ∃ (_ : StrictMono k) (_ : ∀ (i : Fin n), x i ≠ 0), f = ∑ i : Fin n, Polynomial.C (x i) * Polynomial.X ^ k i

full_name: Polynomial.card_support_eq_one
code: theorem card_support_eq_one : f.support.card = 1 ↔
    ∃ (k : ℕ) (x : R) (hx : x ≠ 0), f = C x * X ^ k 
goal: f.support.card = 1 ↔ ∃ k x, ∃ (_ : x ≠ 0), f = Polynomial.C x * Polynomial.X ^ k

full_name: Polynomial.card_support_eq_two
code: theorem card_support_eq_two :
    f.support.card = 2 ↔
      ∃ (k m : ℕ) (hkm : k < m) (x y : R) (hx : x ≠ 0) (hy : y ≠ 0),
        f = C x * X ^ k + C y * X ^ m 
goal: f.support.card = 2 ↔
  ∃ k m,
    ∃ (_ : k < m),
      ∃ x y, ∃ (_ : x ≠ 0) (_ : y ≠ 0), f = Polynomial.C x * Polynomial.X ^ k + Polynomial.C y * Polynomial.X ^ m

full_name: Polynomial.card_support_eq_three
code: theorem card_support_eq_three :
    f.support.card = 3 ↔
      ∃ (k m n : ℕ) (hkm : k < m) (hmn : m < n) (x y z : R) (hx : x ≠ 0) (hy : y ≠ 0) (hz : z ≠ 0),
        f = C x * X ^ k + C y * X ^ m + C z * X ^ n 
goal: f.support.card = 3 ↔
  ∃ k m n,
    ∃ (_ : k < m) (_ : m < n),
      ∃ x y z,
        ∃ (_ : x ≠ 0) (_ : y ≠ 0) (_ : z ≠ 0),
          f = Polynomial.C x * Polynomial.X ^ k + Polynomial.C y * Polynomial.X ^ m + Polynomial.C z * Polynomial.X ^ n