File: Mathlib/Algebra/Polynomial/Inductions.lean

full_name: Polynomial.divX
code: /-- `divX p` returns a polynomial `q` such that `q * X + C (p.coeff 0) = p`.
  It can be used in a semiring where the usual division algorithm is not possible -/
def divX (p : R[X]) : R[X] 
goal: R[X]

full_name: Polynomial.coeff_divX
code: @[simp]
theorem coeff_divX : (divX p).coeff n = p.coeff (n + 1) 
goal: p.divX.coeff n = p.coeff (n + 1)

full_name: Polynomial.divX_mul_X_add
code: theorem divX_mul_X_add (p : R[X]) : divX p * X + C (p.coeff 0) = p 
goal: p.divX * Polynomial.X + Polynomial.C (p.coeff 0) = p

full_name: Polynomial.X_mul_divX_add
code: @[simp]
theorem X_mul_divX_add (p : R[X]) : X * divX p + C (p.coeff 0) = p 
goal: Polynomial.X * p.divX + Polynomial.C (p.coeff 0) = p

full_name: Polynomial.divX_C
code: @[simp]
theorem divX_C (a : R) : divX (C a) = 0 
goal: (Polynomial.C a).divX = 0

full_name: Polynomial.divX_eq_zero_iff
code: theorem divX_eq_zero_iff : divX p = 0 ↔ p = C (p.coeff 0) 
goal: p.divX = 0 ↔ p = Polynomial.C (p.coeff 0)

full_name: Polynomial.divX_add
code: theorem divX_add : divX (p + q) = divX p + divX q 
goal: (p + q).divX = p.divX + q.divX

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

full_name: Polynomial.divX_one
code: @[simp]
theorem divX_one : divX (1 : R[X]) = 0 
goal: Polynomial.divX 1 = 0

full_name: Polynomial.divX_C_mul
code: @[simp]
theorem divX_C_mul : divX (C a * p) = C a * divX p 
goal: (Polynomial.C a * p).divX = Polynomial.C a * p.divX

full_name: Polynomial.divX_X_pow
code: theorem divX_X_pow : divX (X ^ n : R[X]) = if (n = 0) then 0 else X ^ (n - 1) 
goal: (Polynomial.X ^ n).divX = if n = 0 then 0 else Polynomial.X ^ (n - 1)

full_name: Polynomial.divX_hom
code: /-- `divX` as an additive homomorphism. -/
noncomputable
def divX_hom : R[X] →+ R[X] 
goal: R[X] →+ R[X]

full_name: Polynomial.divX_hom_toFun
code: @[simp] theorem divX_hom_toFun : divX_hom p = divX p 
goal: Polynomial.divX_hom p = p.divX

full_name: Polynomial.natDegree_divX_eq_natDegree_tsub_one
code: theorem natDegree_divX_eq_natDegree_tsub_one : p.divX.natDegree = p.natDegree - 1 
goal: p.divX.natDegree = p.natDegree - 1

full_name: Polynomial.natDegree_divX_le
code: theorem natDegree_divX_le : p.divX.natDegree ≤ p.natDegree 
goal: p.divX.natDegree ≤ p.natDegree

full_name: Polynomial.divX_C_mul_X_pow
code: theorem divX_C_mul_X_pow : divX (C a * X ^ n) = if n = 0 then 0 else C a * X ^ (n - 1) 
goal: (Polynomial.C a * Polynomial.X ^ n).divX = if n = 0 then 0 else Polynomial.C a * Polynomial.X ^ (n - 1)

full_name: Polynomial.degree_divX_lt
code: theorem degree_divX_lt (hp0 : p ≠ 0) : (divX p).degree < p.degree 
goal: p.divX.degree < p.degree

full_name: Polynomial.recOnHorner
code: /-- An induction principle for polynomials, valued in Sort* instead of Prop. -/
@[elab_as_elim]
noncomputable def recOnHorner {M : R[X] → Sort*} (p : R[X]) (M0 : M 0)
    (MC : ∀ p a, coeff p 0 = 0 → a ≠ 0 → M p → M (p + C a))
    (MX : ∀ p, p ≠ 0 → M p → M (p * X)) : M p 
goal: M p

full_name: Polynomial.degree_pos_induction_on
code: /-- A property holds for all polynomials of positive `degree` with coefficients in a semiring `R`
if it holds for
* `a * X`, with `a ∈ R`,
* `p * X`, with `p ∈ R[X]`,
* `p + a`, with `a ∈ R`, `p ∈ R[X]`,
with appropriate restrictions on each term.

See `natDegree_ne_zero_induction_on` for a similar statement involving no explicit multiplication.
 -/
@[elab_as_elim]
theorem degree_pos_induction_on {P : R[X] → Prop} (p : R[X]) (h0 : 0 < degree p)
    (hC : ∀ {a}, a ≠ 0 → P (C a * X)) (hX : ∀ {p}, 0 < degree p → P p → P (p * X))
    (hadd : ∀ {p} {a}, 0 < degree p → P p → P (p + C a)) : P p 
goal: P p

full_name: Polynomial.natDegree_ne_zero_induction_on
code: /-- A property holds for all polynomials of non-zero `natDegree` with coefficients in a
semiring `R` if it holds for
* `p + a`, with `a ∈ R`, `p ∈ R[X]`,
* `p + q`, with `p, q ∈ R[X]`,
* monomials with nonzero coefficient and non-zero exponent,
with appropriate restrictions on each term.
Note that multiplication is "hidden" in the assumption on monomials, so there is no explicit
multiplication in the statement.
See `degree_pos_induction_on` for a similar statement involving more explicit multiplications.
 -/
@[elab_as_elim]
theorem natDegree_ne_zero_induction_on {M : R[X] → Prop} {f : R[X]} (f0 : f.natDegree ≠ 0)
    (h_C_add : ∀ {a p}, M p → M (C a + p)) (h_add : ∀ {p q}, M p → M q → M (p + q))
    (h_monomial : ∀ {n : ℕ} {a : R}, a ≠ 0 → n ≠ 0 → M (monomial n a)) : M f 
goal: M f