/-
Copyright (c) 2018 Chris Hughes. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Chris Hughes, Johannes Hölzl, Scott Morrison, Jens Wagemaker

! This file was ported from Lean 3 source module data.polynomial.eval
! leanprover-community/mathlib commit 728baa2f54e6062c5879a3e397ac6bac323e506f
! Please do not edit these lines, except to modify the commit id
! if you have ported upstream changes.
-/
import Mathbin.Data.Polynomial.Degree.Definitions
import Mathbin.Data.Polynomial.Induction

/-!
# Theory of univariate polynomials

> THIS FILE IS SYNCHRONIZED WITH MATHLIB4.
> Any changes to this file require a corresponding PR to mathlib4.

The main defs here are `eval₂`, `eval`, and `map`.
We give several lemmas about their interaction with each other and with module operations.
-/

noncomputable section

open Finset AddMonoidAlgebra

open BigOperators Polynomial

namespace Polynomial

universe u v w y

variable {R : Type u} {S : Type v} {T : Type w} {ι : Type y} {a b : R} {m n : ℕ}

section Semiring

variable [Semiring R] {p q r : R[X]}

section

variable [Semiring S]

variable (f : R →+* S) (x : S)

#print Polynomial.eval₂ /-
/-- Evaluate a polynomial `p` given a ring hom `f` from the scalar ring
  to the target and a value `x` for the variable in the target -/
irreducible_def eval₂ (p : R[X]) : S :=
  p.Sum fun e a => f a * x ^ e
#align polynomial.eval₂ Polynomial.eval₂
-/

/- warning: polynomial.eval₂_eq_sum -> Polynomial.eval₂_eq_sum is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] {f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)} {x : S}, Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p) (Polynomial.sum.{u1, u2} R _inst_1 S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) p (fun (e : Nat) (a : R) => HMul.hMul.{u2, u2, u2} S S S (instHMul.{u2} S (Distrib.toHasMul.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f a) (HPow.hPow.{u2, 0, u2} S Nat S (instHPow.{u2, 0} S Nat (Monoid.Pow.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))) x e)))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] {f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)} {x : S}, Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p) (Polynomial.sum.{u1, u2} R _inst_1 S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) p (fun (e : Nat) (a : R) => HMul.hMul.{u2, u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) S ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (instHMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (NonUnitalNonAssocSemiring.toMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2)))) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f a) (HPow.hPow.{u2, 0, u2} S Nat S (instHPow.{u2, 0} S Nat (Monoid.Pow.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))) x e)))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_eq_sum Polynomial.eval₂_eq_sumₓ'. -/
theorem eval₂_eq_sum {f : R →+* S} {x : S} : p.eval₂ f x = p.Sum fun e a => f a * x ^ e := by
  rw [eval₂]
#align polynomial.eval₂_eq_sum Polynomial.eval₂_eq_sum

/- warning: polynomial.eval₂_congr -> Polynomial.eval₂_congr is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_3 : Semiring.{u1} R] [_inst_4 : Semiring.{u2} S] {f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_3) (Semiring.toNonAssocSemiring.{u2} S _inst_4)} {g : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_3) (Semiring.toNonAssocSemiring.{u2} S _inst_4)} {s : S} {t : S} {φ : Polynomial.{u1} R _inst_3} {ψ : Polynomial.{u1} R _inst_3}, (Eq.{max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_3) (Semiring.toNonAssocSemiring.{u2} S _inst_4)) f g) -> (Eq.{succ u2} S s t) -> (Eq.{succ u1} (Polynomial.{u1} R _inst_3) φ ψ) -> (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_3 _inst_4 f s φ) (Polynomial.eval₂.{u1, u2} R S _inst_3 _inst_4 g t ψ))
but is expected to have type
  forall {R : Type.{u2}} {S : Type.{u1}} [_inst_3 : Semiring.{u2} R] [_inst_4 : Semiring.{u1} S] {f : RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_3) (Semiring.toNonAssocSemiring.{u1} S _inst_4)} {g : RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_3) (Semiring.toNonAssocSemiring.{u1} S _inst_4)} {s : S} {t : S} {φ : Polynomial.{u2} R _inst_3} {ψ : Polynomial.{u2} R _inst_3}, (Eq.{max (succ u2) (succ u1)} (RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_3) (Semiring.toNonAssocSemiring.{u1} S _inst_4)) f g) -> (Eq.{succ u1} S s t) -> (Eq.{succ u2} (Polynomial.{u2} R _inst_3) φ ψ) -> (Eq.{succ u1} S (Polynomial.eval₂.{u2, u1} R S _inst_3 _inst_4 f s φ) (Polynomial.eval₂.{u2, u1} R S _inst_3 _inst_4 g t ψ))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_congr Polynomial.eval₂_congrₓ'. -/
theorem eval₂_congr {R S : Type _} [Semiring R] [Semiring S] {f g : R →+* S} {s t : S}
    {φ ψ : R[X]} : f = g → s = t → φ = ψ → eval₂ f s φ = eval₂ g t ψ := by
  rintro rfl rfl rfl <;> rfl
#align polynomial.eval₂_congr Polynomial.eval₂_congr

/- warning: polynomial.eval₂_at_zero -> Polynomial.eval₂_at_zero is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f (OfNat.ofNat.{u2} S 0 (OfNat.mk.{u2} S 0 (Zero.zero.{u2} S (MulZeroClass.toHasZero.{u2} S (NonUnitalNonAssocSemiring.toMulZeroClass.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))))) p) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f (Polynomial.coeff.{u1} R _inst_1 p (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f (OfNat.ofNat.{u2} S 0 (Zero.toOfNat0.{u2} S (MonoidWithZero.toZero.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))) p) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f (Polynomial.coeff.{u1} R _inst_1 p (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_at_zero Polynomial.eval₂_at_zeroₓ'. -/
@[simp]
theorem eval₂_at_zero : p.eval₂ f 0 = f (coeff p 0) := by
  simp (config := { contextual := true }) only [eval₂_eq_sum, zero_pow_eq, mul_ite,
    MulZeroClass.mul_zero, mul_one, Sum, Classical.not_not, mem_support_iff, sum_ite_eq',
    ite_eq_left_iff, RingHom.map_zero, imp_true_iff, eq_self_iff_true]
#align polynomial.eval₂_at_zero Polynomial.eval₂_at_zero

/- warning: polynomial.eval₂_zero -> Polynomial.eval₂_zero is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (OfNat.ofNat.{u1} (Polynomial.{u1} R _inst_1) 0 (OfNat.mk.{u1} (Polynomial.{u1} R _inst_1) 0 (Zero.zero.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1))))) (OfNat.ofNat.{u2} S 0 (OfNat.mk.{u2} S 0 (Zero.zero.{u2} S (MulZeroClass.toHasZero.{u2} S (NonUnitalNonAssocSemiring.toMulZeroClass.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))))))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (OfNat.ofNat.{u1} (Polynomial.{u1} R _inst_1) 0 (Zero.toOfNat0.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1)))) (OfNat.ofNat.{u2} S 0 (Zero.toOfNat0.{u2} S (MonoidWithZero.toZero.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2))))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_zero Polynomial.eval₂_zeroₓ'. -/
@[simp]
theorem eval₂_zero : (0 : R[X]).eval₂ f x = 0 := by simp [eval₂_eq_sum]
#align polynomial.eval₂_zero Polynomial.eval₂_zero

/- warning: polynomial.eval₂_C -> Polynomial.eval₂_C is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} {a : R} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (Polynomial.C.{u1} R _inst_1) a)) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f a)
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} {a : R} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))))) (Polynomial.C.{u1} R _inst_1) a)) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f a)
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_C Polynomial.eval₂_Cₓ'. -/
@[simp]
theorem eval₂_C : (C a).eval₂ f x = f a := by simp [eval₂_eq_sum]
#align polynomial.eval₂_C Polynomial.eval₂_C

#print Polynomial.eval₂_X /-
@[simp]
theorem eval₂_X : X.eval₂ f x = x := by simp [eval₂_eq_sum]
#align polynomial.eval₂_X Polynomial.eval₂_X
-/

/- warning: polynomial.eval₂_monomial -> Polynomial.eval₂_monomial is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S) {n : Nat} {r : R}, Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (coeFn.{succ u1, succ u1} (LinearMap.{u1, u1, u1, u1} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1))) (fun (_x : LinearMap.{u1, u1, u1, u1} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (LinearMap.hasCoeToFun.{u1, u1, u1, u1} R R R (Polynomial.{u1} R _inst_1) _inst_1 _inst_1 (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1)) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (Polynomial.monomial.{u1} R _inst_1 n) r)) (HMul.hMul.{u2, u2, u2} S S S (instHMul.{u2} S (Distrib.toHasMul.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f r) (HPow.hPow.{u2, 0, u2} S Nat S (instHPow.{u2, 0} S Nat (Monoid.Pow.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))) x n))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S) {n : Nat} {r : R}, Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (FunLike.coe.{succ u1, succ u1, succ u1} (LinearMap.{u1, u1, u1, u1} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Module.LinearMap._hyg.6190 : R) => Polynomial.{u1} R _inst_1) _x) (LinearMap.instFunLikeLinearMap.{u1, u1, u1, u1} R R R (Polynomial.{u1} R _inst_1) _inst_1 _inst_1 (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1)) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (Polynomial.monomial.{u1} R _inst_1 n) r)) (HMul.hMul.{u2, u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) r) S ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) r) (instHMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) r) (NonUnitalNonAssocSemiring.toMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) r) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) r) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) r) _inst_2)))) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f r) (HPow.hPow.{u2, 0, u2} S Nat S (instHPow.{u2, 0} S Nat (Monoid.Pow.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))) x n))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_monomial Polynomial.eval₂_monomialₓ'. -/
@[simp]
theorem eval₂_monomial {n : ℕ} {r : R} : (monomial n r).eval₂ f x = f r * x ^ n := by
  simp [eval₂_eq_sum]
#align polynomial.eval₂_monomial Polynomial.eval₂_monomial

#print Polynomial.eval₂_X_pow /-
@[simp]
theorem eval₂_X_pow {n : ℕ} : (X ^ n).eval₂ f x = x ^ n :=
  by
  rw [X_pow_eq_monomial]
  convert eval₂_monomial f x
  simp
#align polynomial.eval₂_X_pow Polynomial.eval₂_X_pow
-/

/- warning: polynomial.eval₂_add -> Polynomial.eval₂_add is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {q : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (HAdd.hAdd.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHAdd.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.add'.{u1} R _inst_1)) p q)) (HAdd.hAdd.{u2, u2, u2} S S S (instHAdd.{u2} S (Distrib.toHasAdd.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x q))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {q : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (HAdd.hAdd.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHAdd.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.add'.{u1} R _inst_1)) p q)) (HAdd.hAdd.{u2, u2, u2} S S S (instHAdd.{u2} S (Distrib.toAdd.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x q))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_add Polynomial.eval₂_addₓ'. -/
@[simp]
theorem eval₂_add : (p + q).eval₂ f x = p.eval₂ f x + q.eval₂ f x :=
  by
  simp only [eval₂_eq_sum]
  apply sum_add_index <;> simp [add_mul]
#align polynomial.eval₂_add Polynomial.eval₂_add

#print Polynomial.eval₂_one /-
@[simp]
theorem eval₂_one : (1 : R[X]).eval₂ f x = 1 := by rw [← C_1, eval₂_C, f.map_one]
#align polynomial.eval₂_one Polynomial.eval₂_one
-/

/- warning: polynomial.eval₂_bit0 -> Polynomial.eval₂_bit0 is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (bit0.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.add'.{u1} R _inst_1) p)) (bit0.{u2} S (Distrib.toHasAdd.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (bit0.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.add'.{u1} R _inst_1) p)) (bit0.{u2} S (Distrib.toAdd.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_bit0 Polynomial.eval₂_bit0ₓ'. -/
@[simp]
theorem eval₂_bit0 : (bit0 p).eval₂ f x = bit0 (p.eval₂ f x) := by rw [bit0, eval₂_add, bit0]
#align polynomial.eval₂_bit0 Polynomial.eval₂_bit0

/- warning: polynomial.eval₂_bit1 -> Polynomial.eval₂_bit1 is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (bit1.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.hasOne.{u1} R _inst_1) (Polynomial.add'.{u1} R _inst_1) p)) (bit1.{u2} S (AddMonoidWithOne.toOne.{u2} S (AddCommMonoidWithOne.toAddMonoidWithOne.{u2} S (NonAssocSemiring.toAddCommMonoidWithOne.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (Distrib.toHasAdd.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (bit1.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.one.{u1} R _inst_1) (Polynomial.add'.{u1} R _inst_1) p)) (bit1.{u2} S (Semiring.toOne.{u2} S _inst_2) (Distrib.toAdd.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_bit1 Polynomial.eval₂_bit1ₓ'. -/
@[simp]
theorem eval₂_bit1 : (bit1 p).eval₂ f x = bit1 (p.eval₂ f x) := by
  rw [bit1, eval₂_add, eval₂_bit0, eval₂_one, bit1]
#align polynomial.eval₂_bit1 Polynomial.eval₂_bit1

/- warning: polynomial.eval₂_smul -> Polynomial.eval₂_smul is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (g : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (p : Polynomial.{u1} R _inst_1) (x : S) {s : R}, Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 g x (SMul.smul.{u1, u1} R (Polynomial.{u1} R _inst_1) (SMulZeroClass.toHasSmul.{u1, u1} R (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1) (Polynomial.smulZeroClass.{u1, u1} R _inst_1 R (SMulWithZero.toSmulZeroClass.{u1, u1} R R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (MulZeroClass.toSMulWithZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))))) s p)) (HMul.hMul.{u2, u2, u2} S S S (instHMul.{u2} S (Distrib.toHasMul.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) g s) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 g x p))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (g : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (p : Polynomial.{u1} R _inst_1) (x : S) {s : R}, Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 g x (HSMul.hSMul.{u1, u1, u1} R (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHSMul.{u1, u1} R (Polynomial.{u1} R _inst_1) (SMulZeroClass.toSMul.{u1, u1} R (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1) (Polynomial.smulZeroClass.{u1, u1} R _inst_1 R (SMulWithZero.toSMulZeroClass.{u1, u1} R R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)) (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)) (MulZeroClass.toSMulWithZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))))))) s p)) (HMul.hMul.{u2, u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) s) S ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) s) (instHMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) s) (NonUnitalNonAssocSemiring.toMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) s) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) s) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) s) _inst_2)))) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) g s) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 g x p))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_smul Polynomial.eval₂_smulₓ'. -/
@[simp]
theorem eval₂_smul (g : R →+* S) (p : R[X]) (x : S) {s : R} :
    eval₂ g x (s • p) = g s * eval₂ g x p :=
  by
  have A : p.nat_degree < p.nat_degree.succ := Nat.lt_succ_self _
  have B : (s • p).natDegree < p.nat_degree.succ := (nat_degree_smul_le _ _).trans_lt A
  rw [eval₂_eq_sum, eval₂_eq_sum, sum_over_range' _ _ _ A, sum_over_range' _ _ _ B] <;>
    simp [mul_sum, mul_assoc]
#align polynomial.eval₂_smul Polynomial.eval₂_smul

#print Polynomial.eval₂_C_X /-
@[simp]
theorem eval₂_C_X : eval₂ C X p = p :=
  Polynomial.induction_on' p (fun p q hp hq => by simp [hp, hq]) fun n x => by
    rw [eval₂_monomial, ← smul_X_eq_monomial, C_mul']
#align polynomial.eval₂_C_X Polynomial.eval₂_C_X
-/

#print Polynomial.eval₂AddMonoidHom /-
/-- `eval₂_add_monoid_hom (f : R →+* S) (x : S)` is the `add_monoid_hom` from
`R[X]` to `S` obtained by evaluating the pushforward of `p` along `f` at `x`. -/
@[simps]
def eval₂AddMonoidHom : R[X] →+ S where
  toFun := eval₂ f x
  map_zero' := eval₂_zero _ _
  map_add' _ _ := eval₂_add _ _
#align polynomial.eval₂_add_monoid_hom Polynomial.eval₂AddMonoidHom
-/

#print Polynomial.eval₂_nat_cast /-
@[simp]
theorem eval₂_nat_cast (n : ℕ) : (n : R[X]).eval₂ f x = n :=
  by
  induction' n with n ih
  · simp only [eval₂_zero, Nat.cast_zero]
  · rw [n.cast_succ, eval₂_add, ih, eval₂_one, n.cast_succ]
#align polynomial.eval₂_nat_cast Polynomial.eval₂_nat_cast
-/

variable [Semiring T]

#print Polynomial.eval₂_sum /-
theorem eval₂_sum (p : T[X]) (g : ℕ → T → R[X]) (x : S) :
    (p.Sum g).eval₂ f x = p.Sum fun n a => (g n a).eval₂ f x :=
  by
  let T : R[X] →+ S :=
    { toFun := eval₂ f x
      map_zero' := eval₂_zero _ _
      map_add' := fun p q => eval₂_add _ _ }
  have A : ∀ y, eval₂ f x y = T y := fun y => rfl
  simp only [A]
  rw [Sum, T.map_sum, Sum]
#align polynomial.eval₂_sum Polynomial.eval₂_sum
-/

/- warning: polynomial.eval₂_list_sum -> Polynomial.eval₂_list_sum is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (l : List.{u1} (Polynomial.{u1} R _inst_1)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (List.sum.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.add'.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1) l)) (List.sum.{u2} S (Distrib.toHasAdd.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (MulZeroClass.toHasZero.{u2} S (NonUnitalNonAssocSemiring.toMulZeroClass.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (List.map.{u1, u2} (Polynomial.{u1} R _inst_1) S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x) l))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (l : List.{u1} (Polynomial.{u1} R _inst_1)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (List.sum.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.add'.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1) l)) (List.sum.{u2} S (Distrib.toAdd.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (MonoidWithZero.toZero.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)) (List.map.{u1, u2} (Polynomial.{u1} R _inst_1) S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x) l))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_list_sum Polynomial.eval₂_list_sumₓ'. -/
theorem eval₂_list_sum (l : List R[X]) (x : S) : eval₂ f x l.Sum = (l.map (eval₂ f x)).Sum :=
  map_list_sum (eval₂AddMonoidHom f x) l
#align polynomial.eval₂_list_sum Polynomial.eval₂_list_sum

#print Polynomial.eval₂_multiset_sum /-
theorem eval₂_multiset_sum (s : Multiset R[X]) (x : S) :
    eval₂ f x s.Sum = (s.map (eval₂ f x)).Sum :=
  map_multiset_sum (eval₂AddMonoidHom f x) s
#align polynomial.eval₂_multiset_sum Polynomial.eval₂_multiset_sum
-/

#print Polynomial.eval₂_finset_sum /-
theorem eval₂_finset_sum (s : Finset ι) (g : ι → R[X]) (x : S) :
    (∑ i in s, g i).eval₂ f x = ∑ i in s, (g i).eval₂ f x :=
  map_sum (eval₂AddMonoidHom f x) _ _
#align polynomial.eval₂_finset_sum Polynomial.eval₂_finset_sum
-/

/- warning: polynomial.eval₂_of_finsupp -> Polynomial.eval₂_ofFinsupp is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] {f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)} {x : S} {p : AddMonoidAlgebra.{u1, 0} R Nat _inst_1}, Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (Polynomial.ofFinsupp.{u1} R _inst_1 p)) (coeFn.{max (succ u2) (succ u1), max (succ u1) (succ u2)} (AddMonoidHom.{u1, u2} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) S (AddMonoid.toAddZeroClass.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddCommMonoid.toAddMonoid.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddMonoidAlgebra.addCommMonoid.{0, u1} R Nat _inst_1))) (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))))) (fun (_x : AddMonoidHom.{u1, u2} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) S (AddMonoid.toAddZeroClass.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddCommMonoid.toAddMonoid.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddMonoidAlgebra.addCommMonoid.{0, u1} R Nat _inst_1))) (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))))) => (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) -> S) (AddMonoidHom.hasCoeToFun.{u1, u2} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) S (AddMonoid.toAddZeroClass.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddCommMonoid.toAddMonoid.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddMonoidAlgebra.addCommMonoid.{0, u1} R Nat _inst_1))) (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))))) (AddMonoidAlgebra.liftNC.{u1, 0, u2} R Nat S _inst_1 (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) ((fun (a : Sort.{max (succ u1) (succ u2)}) (b : Sort.{max (succ u2) (succ u1)}) [self : HasLiftT.{max (succ u1) (succ u2), max (succ u2) (succ u1)} a b] => self.0) (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (AddMonoidHom.{u1, u2} R S (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))))) (HasLiftT.mk.{max (succ u1) (succ u2), max (succ u2) (succ u1)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (AddMonoidHom.{u1, u2} R S (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))))) (CoeTCₓ.coe.{max (succ u1) (succ u2), max (succ u2) (succ u1)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (AddMonoidHom.{u1, u2} R S (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))))) (AddMonoidHom.hasCoeT.{u1, u2, max u1 u2} R S (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) (RingHomClass.toAddMonoidHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.ringHomClass.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)))))) f) (coeFn.{succ u2, succ u2} (MonoidHom.{0, u2} (Multiplicative.{0} Nat) S (Multiplicative.mulOneClass.{0} Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid)) (Monoid.toMulOneClass.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))) (fun (_x : MonoidHom.{0, u2} (Multiplicative.{0} Nat) S (Multiplicative.mulOneClass.{0} Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid)) (Monoid.toMulOneClass.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))) => (Multiplicative.{0} Nat) -> S) (MonoidHom.hasCoeToFun.{0, u2} (Multiplicative.{0} Nat) S (Multiplicative.mulOneClass.{0} Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid)) (Monoid.toMulOneClass.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))) (coeFn.{succ u2, succ u2} (Equiv.{succ u2, succ u2} S (MonoidHom.{0, u2} (Multiplicative.{0} Nat) S (Multiplicative.mulOneClass.{0} Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid)) (Monoid.toMulOneClass.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2))))) (fun (_x : Equiv.{succ u2, succ u2} S (MonoidHom.{0, u2} (Multiplicative.{0} Nat) S (Multiplicative.mulOneClass.{0} Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid)) (Monoid.toMulOneClass.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2))))) => S -> (MonoidHom.{0, u2} (Multiplicative.{0} Nat) S (Multiplicative.mulOneClass.{0} Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid)) (Monoid.toMulOneClass.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2))))) (Equiv.hasCoeToFun.{succ u2, succ u2} S (MonoidHom.{0, u2} (Multiplicative.{0} Nat) S (Multiplicative.mulOneClass.{0} Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid)) (Monoid.toMulOneClass.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2))))) (powersHom.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2))) x))) p)
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] {f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)} {x : S} {p : AddMonoidAlgebra.{u1, 0} R Nat _inst_1}, Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (Polynomial.ofFinsupp.{u1} R _inst_1 p)) (FunLike.coe.{max (succ u2) (succ u1), succ u1, succ u2} (AddMonoidHom.{u1, u2} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) S (AddMonoid.toAddZeroClass.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddCommMonoid.toAddMonoid.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddMonoidAlgebra.addCommMonoid.{u1, 0} R Nat _inst_1))) (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))))) (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (fun (_x : AddMonoidAlgebra.{u1, 0} R Nat _inst_1) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.403 : AddMonoidAlgebra.{u1, 0} R Nat _inst_1) => S) _x) (AddHomClass.toFunLike.{max u2 u1, u1, u2} (AddMonoidHom.{u1, u2} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) S (AddMonoid.toAddZeroClass.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddCommMonoid.toAddMonoid.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddMonoidAlgebra.addCommMonoid.{u1, 0} R Nat _inst_1))) (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))))) (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) S (AddZeroClass.toAdd.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddMonoid.toAddZeroClass.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddCommMonoid.toAddMonoid.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddMonoidAlgebra.addCommMonoid.{u1, 0} R Nat _inst_1)))) (AddZeroClass.toAdd.{u2} S (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))))) (AddMonoidHomClass.toAddHomClass.{max u2 u1, u1, u2} (AddMonoidHom.{u1, u2} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) S (AddMonoid.toAddZeroClass.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddCommMonoid.toAddMonoid.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddMonoidAlgebra.addCommMonoid.{u1, 0} R Nat _inst_1))) (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))))) (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) S (AddMonoid.toAddZeroClass.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddCommMonoid.toAddMonoid.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddMonoidAlgebra.addCommMonoid.{u1, 0} R Nat _inst_1))) (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) (AddMonoidHom.addMonoidHomClass.{u1, u2} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) S (AddMonoid.toAddZeroClass.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddCommMonoid.toAddMonoid.{u1} (AddMonoidAlgebra.{u1, 0} R Nat _inst_1) (AddMonoidAlgebra.addCommMonoid.{u1, 0} R Nat _inst_1))) (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))))))) (AddMonoidAlgebra.liftNC.{u1, 0, u2} R Nat S _inst_1 (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (AddMonoidHomClass.toAddMonoidHom.{u1, u2, max u1 u2} R S (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (AddMonoid.toAddZeroClass.{u2} S (AddCommMonoid.toAddMonoid.{u2} S (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) (RingHomClass.toAddMonoidHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))) f) (FunLike.coe.{succ u2, 1, succ u2} ((fun (x._@.Mathlib.Logic.Equiv.Defs._hyg.808 : S) => MonoidHom.{0, u2} (Multiplicative.{0} Nat) S (Multiplicative.mulOneClass.{0} Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid)) (Monoid.toMulOneClass.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))) x) (Multiplicative.{0} Nat) (fun (_x : Multiplicative.{0} Nat) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : Multiplicative.{0} Nat) => S) _x) (MulHomClass.toFunLike.{u2, 0, u2} ((fun (x._@.Mathlib.Logic.Equiv.Defs._hyg.808 : S) => MonoidHom.{0, u2} (Multiplicative.{0} Nat) S (Multiplicative.mulOneClass.{0} Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid)) (Monoid.toMulOneClass.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))) x) (Multiplicative.{0} Nat) S (MulOneClass.toMul.{0} (Multiplicative.{0} Nat) (Multiplicative.mulOneClass.{0} Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid))) (MulOneClass.toMul.{u2} S (Monoid.toMulOneClass.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))) (MonoidHomClass.toMulHomClass.{u2, 0, u2} ((fun (x._@.Mathlib.Logic.Equiv.Defs._hyg.808 : S) => MonoidHom.{0, u2} (Multiplicative.{0} Nat) S (Multiplicative.mulOneClass.{0} Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid)) (Monoid.toMulOneClass.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))) x) (Multiplicative.{0} Nat) S (Multiplicative.mulOneClass.{0} Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid)) (Monoid.toMulOneClass.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2))) (MonoidHom.monoidHomClass.{0, u2} (Multiplicative.{0} Nat) S (Multiplicative.mulOneClass.{0} Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid)) (Monoid.toMulOneClass.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))))) (FunLike.coe.{succ u2, succ u2, succ u2} (Equiv.{succ u2, succ u2} S (MonoidHom.{0, u2} (Multiplicative.{0} Nat) S (Multiplicative.mulOneClass.{0} Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid)) (Monoid.toMulOneClass.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2))))) S (fun (_x : S) => (fun (x._@.Mathlib.Logic.Equiv.Defs._hyg.808 : S) => MonoidHom.{0, u2} (Multiplicative.{0} Nat) S (Multiplicative.mulOneClass.{0} Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid)) (Monoid.toMulOneClass.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))) _x) (Equiv.instFunLikeEquiv.{succ u2, succ u2} S (MonoidHom.{0, u2} (Multiplicative.{0} Nat) S (Multiplicative.mulOneClass.{0} Nat (AddMonoid.toAddZeroClass.{0} Nat Nat.addMonoid)) (Monoid.toMulOneClass.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2))))) (powersHom.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2))) x))) p)
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_of_finsupp Polynomial.eval₂_ofFinsuppₓ'. -/
theorem eval₂_ofFinsupp {f : R →+* S} {x : S} {p : AddMonoidAlgebra R ℕ} :
    eval₂ f x (⟨p⟩ : R[X]) = liftNC (↑f) (powersHom S x) p :=
  by
  simp only [eval₂_eq_sum, Sum, to_finsupp_sum, support, coeff]
  rfl
#align polynomial.eval₂_of_finsupp Polynomial.eval₂_ofFinsupp

/- warning: polynomial.eval₂_mul_noncomm -> Polynomial.eval₂_mul_noncomm is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {q : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), (forall (k : Nat), Commute.{u2} S (Distrib.toHasMul.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f (Polynomial.coeff.{u1} R _inst_1 q k)) x) -> (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) p q)) (HMul.hMul.{u2, u2, u2} S S S (instHMul.{u2} S (Distrib.toHasMul.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x q)))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {q : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), (forall (k : Nat), Commute.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 q k)) (NonUnitalNonAssocSemiring.toMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 q k)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 q k)) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 q k)) _inst_2))) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f (Polynomial.coeff.{u1} R _inst_1 q k)) x) -> (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) p q)) (HMul.hMul.{u2, u2, u2} S S S (instHMul.{u2} S (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x q)))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_mul_noncomm Polynomial.eval₂_mul_noncommₓ'. -/
theorem eval₂_mul_noncomm (hf : ∀ k, Commute (f <| q.coeff k) x) :
    eval₂ f x (p * q) = eval₂ f x p * eval₂ f x q :=
  by
  rcases p with ⟨⟩; rcases q with ⟨⟩
  simp only [coeff] at hf
  simp only [← of_finsupp_mul, eval₂_of_finsupp]
  exact lift_nc_mul _ _ p q fun k n hn => (hf k).pow_right n
#align polynomial.eval₂_mul_noncomm Polynomial.eval₂_mul_noncomm

/- warning: polynomial.eval₂_mul_X -> Polynomial.eval₂_mul_X is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) p (Polynomial.X.{u1} R _inst_1))) (HMul.hMul.{u2, u2, u2} S S S (instHMul.{u2} S (Distrib.toHasMul.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p) x)
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) p (Polynomial.X.{u1} R _inst_1))) (HMul.hMul.{u2, u2, u2} S S S (instHMul.{u2} S (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p) x)
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_mul_X Polynomial.eval₂_mul_Xₓ'. -/
@[simp]
theorem eval₂_mul_X : eval₂ f x (p * X) = eval₂ f x p * x :=
  by
  refine' trans (eval₂_mul_noncomm _ _ fun k => _) (by rw [eval₂_X])
  rcases em (k = 1) with (rfl | hk)
  · simp
  · simp [coeff_X_of_ne_one hk]
#align polynomial.eval₂_mul_X Polynomial.eval₂_mul_X

/- warning: polynomial.eval₂_X_mul -> Polynomial.eval₂_X_mul is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) (Polynomial.X.{u1} R _inst_1) p)) (HMul.hMul.{u2, u2, u2} S S S (instHMul.{u2} S (Distrib.toHasMul.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p) x)
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) (Polynomial.X.{u1} R _inst_1) p)) (HMul.hMul.{u2, u2, u2} S S S (instHMul.{u2} S (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p) x)
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_X_mul Polynomial.eval₂_X_mulₓ'. -/
@[simp]
theorem eval₂_X_mul : eval₂ f x (X * p) = eval₂ f x p * x := by rw [X_mul, eval₂_mul_X]
#align polynomial.eval₂_X_mul Polynomial.eval₂_X_mul

/- warning: polynomial.eval₂_mul_C' -> Polynomial.eval₂_mul_C' is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} {a : R} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), (Commute.{u2} S (Distrib.toHasMul.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f a) x) -> (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) p (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (Polynomial.C.{u1} R _inst_1) a))) (HMul.hMul.{u2, u2, u2} S S S (instHMul.{u2} S (Distrib.toHasMul.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f a)))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} {a : R} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), (Commute.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (NonUnitalNonAssocSemiring.toMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2))) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f a) x) -> (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) a) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) p (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))))) (Polynomial.C.{u1} R _inst_1) a))) (HMul.hMul.{u2, u2, u2} S ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) S (instHMul.{u2} S (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f a)))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_mul_C' Polynomial.eval₂_mul_C'ₓ'. -/
theorem eval₂_mul_C' (h : Commute (f a) x) : eval₂ f x (p * C a) = eval₂ f x p * f a :=
  by
  rw [eval₂_mul_noncomm, eval₂_C]
  intro k
  by_cases hk : k = 0
  · simp only [hk, h, coeff_C_zero, coeff_C_ne_zero]
  · simp only [coeff_C_ne_zero hk, RingHom.map_zero, Commute.zero_left]
#align polynomial.eval₂_mul_C' Polynomial.eval₂_mul_C'

/- warning: polynomial.eval₂_list_prod_noncomm -> Polynomial.eval₂_list_prod_noncomm is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S) (ps : List.{u1} (Polynomial.{u1} R _inst_1)), (forall (p : Polynomial.{u1} R _inst_1), (Membership.Mem.{u1, u1} (Polynomial.{u1} R _inst_1) (List.{u1} (Polynomial.{u1} R _inst_1)) (List.hasMem.{u1} (Polynomial.{u1} R _inst_1)) p ps) -> (forall (k : Nat), Commute.{u2} S (Distrib.toHasMul.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f (Polynomial.coeff.{u1} R _inst_1 p k)) x)) -> (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (List.prod.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1) (Polynomial.hasOne.{u1} R _inst_1) ps)) (List.prod.{u2} S (Distrib.toHasMul.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (AddMonoidWithOne.toOne.{u2} S (AddCommMonoidWithOne.toAddMonoidWithOne.{u2} S (NonAssocSemiring.toAddCommMonoidWithOne.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (List.map.{u1, u2} (Polynomial.{u1} R _inst_1) S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x) ps)))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S) (ps : List.{u1} (Polynomial.{u1} R _inst_1)), (forall (p : Polynomial.{u1} R _inst_1), (Membership.mem.{u1, u1} (Polynomial.{u1} R _inst_1) (List.{u1} (Polynomial.{u1} R _inst_1)) (List.instMembershipList.{u1} (Polynomial.{u1} R _inst_1)) p ps) -> (forall (k : Nat), Commute.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 p k)) (NonUnitalNonAssocSemiring.toMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 p k)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 p k)) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 p k)) _inst_2))) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f (Polynomial.coeff.{u1} R _inst_1 p k)) x)) -> (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x (List.prod.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1) (Polynomial.one.{u1} R _inst_1) ps)) (List.prod.{u2} S (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (Semiring.toOne.{u2} S _inst_2) (List.map.{u1, u2} (Polynomial.{u1} R _inst_1) S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x) ps)))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_list_prod_noncomm Polynomial.eval₂_list_prod_noncommₓ'. -/
theorem eval₂_list_prod_noncomm (ps : List R[X])
    (hf : ∀ p ∈ ps, ∀ (k), Commute (f <| coeff p k) x) :
    eval₂ f x ps.Prod = (ps.map (Polynomial.eval₂ f x)).Prod :=
  by
  induction' ps using List.reverseRecOn with ps p ihp
  · simp
  · simp only [List.forall_mem_append, List.forall_mem_singleton] at hf
    simp [eval₂_mul_noncomm _ _ hf.2, ihp hf.1]
#align polynomial.eval₂_list_prod_noncomm Polynomial.eval₂_list_prod_noncomm

/- warning: polynomial.eval₂_ring_hom' -> Polynomial.eval₂RingHom' is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), (forall (a : R), Commute.{u2} S (Distrib.toHasMul.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f a) x) -> (RingHom.{u1, u2} (Polynomial.{u1} R _inst_1) S (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S _inst_2))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), (forall (a : R), Commute.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (NonUnitalNonAssocSemiring.toMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2))) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f a) x) -> (RingHom.{u1, u2} (Polynomial.{u1} R _inst_1) S (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S _inst_2))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_ring_hom' Polynomial.eval₂RingHom'ₓ'. -/
/-- `eval₂` as a `ring_hom` for noncommutative rings -/
def eval₂RingHom' (f : R →+* S) (x : S) (hf : ∀ a, Commute (f a) x) : R[X] →+* S
    where
  toFun := eval₂ f x
  map_add' _ _ := eval₂_add _ _
  map_zero' := eval₂_zero _ _
  map_mul' p q := eval₂_mul_noncomm f x fun k => hf <| coeff q k
  map_one' := eval₂_one _ _
#align polynomial.eval₂_ring_hom' Polynomial.eval₂RingHom'

end

/-!
We next prove that eval₂ is multiplicative
as long as target ring is commutative
(even if the source ring is not).
-/

section Eval₂

section

variable [Semiring S] (f : R →+* S) (x : S)

/- warning: polynomial.eval₂_eq_sum_range -> Polynomial.eval₂_eq_sum_range is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p) (Finset.sum.{u2, 0} S Nat (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (Polynomial.natDegree.{u1} R _inst_1 p) (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))) (fun (i : Nat) => HMul.hMul.{u2, u2, u2} S S S (instHMul.{u2} S (Distrib.toHasMul.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f (Polynomial.coeff.{u1} R _inst_1 p i)) (HPow.hPow.{u2, 0, u2} S Nat S (instHPow.{u2, 0} S Nat (Monoid.Pow.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))) x i)))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p) (Finset.sum.{u2, 0} S Nat (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (Polynomial.natDegree.{u1} R _inst_1 p) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (fun (i : Nat) => HMul.hMul.{u2, u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 p i)) S ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 p i)) (instHMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 p i)) (NonUnitalNonAssocSemiring.toMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 p i)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 p i)) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 p i)) _inst_2)))) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f (Polynomial.coeff.{u1} R _inst_1 p i)) (HPow.hPow.{u2, 0, u2} S Nat S (instHPow.{u2, 0} S Nat (Monoid.Pow.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))) x i)))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_eq_sum_range Polynomial.eval₂_eq_sum_rangeₓ'. -/
theorem eval₂_eq_sum_range :
    p.eval₂ f x = ∑ i in Finset.range (p.natDegree + 1), f (p.coeff i) * x ^ i :=
  trans (congr_arg _ p.as_sum_range) (trans (eval₂_finset_sum f _ _ x) (congr_arg _ (by simp)))
#align polynomial.eval₂_eq_sum_range Polynomial.eval₂_eq_sum_range

/- warning: polynomial.eval₂_eq_sum_range' -> Polynomial.eval₂_eq_sum_range' is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) {p : Polynomial.{u1} R _inst_1} {n : Nat}, (LT.lt.{0} Nat Nat.hasLt (Polynomial.natDegree.{u1} R _inst_1 p) n) -> (forall (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p) (Finset.sum.{u2, 0} S Nat (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (Finset.range n) (fun (i : Nat) => HMul.hMul.{u2, u2, u2} S S S (instHMul.{u2} S (Distrib.toHasMul.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f (Polynomial.coeff.{u1} R _inst_1 p i)) (HPow.hPow.{u2, 0, u2} S Nat S (instHPow.{u2, 0} S Nat (Monoid.Pow.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))) x i))))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) {p : Polynomial.{u1} R _inst_1} {n : Nat}, (LT.lt.{0} Nat instLTNat (Polynomial.natDegree.{u1} R _inst_1 p) n) -> (forall (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p) (Finset.sum.{u2, 0} S Nat (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (Finset.range n) (fun (i : Nat) => HMul.hMul.{u2, u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 p i)) S ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 p i)) (instHMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 p i)) (NonUnitalNonAssocSemiring.toMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 p i)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 p i)) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.coeff.{u1} R _inst_1 p i)) _inst_2)))) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f (Polynomial.coeff.{u1} R _inst_1 p i)) (HPow.hPow.{u2, 0, u2} S Nat S (instHPow.{u2, 0} S Nat (Monoid.Pow.{u2} S (MonoidWithZero.toMonoid.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))) x i))))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_eq_sum_range' Polynomial.eval₂_eq_sum_range'ₓ'. -/
theorem eval₂_eq_sum_range' (f : R →+* S) {p : R[X]} {n : ℕ} (hn : p.natDegree < n) (x : S) :
    eval₂ f x p = ∑ i in Finset.range n, f (p.coeff i) * x ^ i :=
  by
  rw [eval₂_eq_sum, p.sum_over_range' _ _ hn]
  intro i
  rw [f.map_zero, MulZeroClass.zero_mul]
#align polynomial.eval₂_eq_sum_range' Polynomial.eval₂_eq_sum_range'

end

section

variable [CommSemiring S] (f : R →+* S) (x : S)

/- warning: polynomial.eval₂_mul -> Polynomial.eval₂_mul is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {q : Polynomial.{u1} R _inst_1} [_inst_2 : CommSemiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) p q)) (HMul.hMul.{u2, u2, u2} S S S (instHMul.{u2} S (Distrib.toHasMul.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)))))) (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x p) (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x q))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {q : Polynomial.{u1} R _inst_1} [_inst_2 : CommSemiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) p q)) (HMul.hMul.{u2, u2, u2} S S S (instHMul.{u2} S (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))))) (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x p) (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x q))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_mul Polynomial.eval₂_mulₓ'. -/
@[simp]
theorem eval₂_mul : (p * q).eval₂ f x = p.eval₂ f x * q.eval₂ f x :=
  eval₂_mul_noncomm _ _ fun k => Commute.all _ _
#align polynomial.eval₂_mul Polynomial.eval₂_mul

/- warning: polynomial.eval₂_mul_eq_zero_of_left -> Polynomial.eval₂_mul_eq_zero_of_left is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : CommSemiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (x : S) (q : Polynomial.{u1} R _inst_1), (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x p) (OfNat.ofNat.{u2} S 0 (OfNat.mk.{u2} S 0 (Zero.zero.{u2} S (MulZeroClass.toHasZero.{u2} S (NonUnitalNonAssocSemiring.toMulZeroClass.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))))))))) -> (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) p q)) (OfNat.ofNat.{u2} S 0 (OfNat.mk.{u2} S 0 (Zero.zero.{u2} S (MulZeroClass.toHasZero.{u2} S (NonUnitalNonAssocSemiring.toMulZeroClass.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)))))))))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : CommSemiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (x : S) (q : Polynomial.{u1} R _inst_1), (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x p) (OfNat.ofNat.{u2} S 0 (Zero.toOfNat0.{u2} S (CommMonoidWithZero.toZero.{u2} S (CommSemiring.toCommMonoidWithZero.{u2} S _inst_2))))) -> (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) p q)) (OfNat.ofNat.{u2} S 0 (Zero.toOfNat0.{u2} S (CommMonoidWithZero.toZero.{u2} S (CommSemiring.toCommMonoidWithZero.{u2} S _inst_2)))))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_mul_eq_zero_of_left Polynomial.eval₂_mul_eq_zero_of_leftₓ'. -/
theorem eval₂_mul_eq_zero_of_left (q : R[X]) (hp : p.eval₂ f x = 0) : (p * q).eval₂ f x = 0 :=
  by
  rw [eval₂_mul f x]
  exact mul_eq_zero_of_left hp (q.eval₂ f x)
#align polynomial.eval₂_mul_eq_zero_of_left Polynomial.eval₂_mul_eq_zero_of_left

/- warning: polynomial.eval₂_mul_eq_zero_of_right -> Polynomial.eval₂_mul_eq_zero_of_right is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {q : Polynomial.{u1} R _inst_1} [_inst_2 : CommSemiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (x : S) (p : Polynomial.{u1} R _inst_1), (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x q) (OfNat.ofNat.{u2} S 0 (OfNat.mk.{u2} S 0 (Zero.zero.{u2} S (MulZeroClass.toHasZero.{u2} S (NonUnitalNonAssocSemiring.toMulZeroClass.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))))))))) -> (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) p q)) (OfNat.ofNat.{u2} S 0 (OfNat.mk.{u2} S 0 (Zero.zero.{u2} S (MulZeroClass.toHasZero.{u2} S (NonUnitalNonAssocSemiring.toMulZeroClass.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)))))))))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {q : Polynomial.{u1} R _inst_1} [_inst_2 : CommSemiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (x : S) (p : Polynomial.{u1} R _inst_1), (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x q) (OfNat.ofNat.{u2} S 0 (Zero.toOfNat0.{u2} S (CommMonoidWithZero.toZero.{u2} S (CommSemiring.toCommMonoidWithZero.{u2} S _inst_2))))) -> (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) p q)) (OfNat.ofNat.{u2} S 0 (Zero.toOfNat0.{u2} S (CommMonoidWithZero.toZero.{u2} S (CommSemiring.toCommMonoidWithZero.{u2} S _inst_2)))))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_mul_eq_zero_of_right Polynomial.eval₂_mul_eq_zero_of_rightₓ'. -/
theorem eval₂_mul_eq_zero_of_right (p : R[X]) (hq : q.eval₂ f x = 0) : (p * q).eval₂ f x = 0 :=
  by
  rw [eval₂_mul f x]
  exact mul_eq_zero_of_right (p.eval₂ f x) hq
#align polynomial.eval₂_mul_eq_zero_of_right Polynomial.eval₂_mul_eq_zero_of_right

#print Polynomial.eval₂RingHom /-
/-- `eval₂` as a `ring_hom` -/
def eval₂RingHom (f : R →+* S) (x : S) : R[X] →+* S :=
  { eval₂AddMonoidHom f x with
    map_one' := eval₂_one _ _
    map_mul' := fun _ _ => eval₂_mul _ _ }
#align polynomial.eval₂_ring_hom Polynomial.eval₂RingHom
-/

/- warning: polynomial.coe_eval₂_ring_hom -> Polynomial.coe_eval₂RingHom is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : CommSemiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (x : S), Eq.{max (succ u1) (succ u2)} ((Polynomial.{u1} R _inst_1) -> S) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} (Polynomial.{u1} R _inst_1) S (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (fun (_x : RingHom.{u1, u2} (Polynomial.{u1} R _inst_1) S (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) => (Polynomial.{u1} R _inst_1) -> S) (RingHom.hasCoeToFun.{u1, u2} (Polynomial.{u1} R _inst_1) S (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (Polynomial.eval₂RingHom.{u1, u2} R S _inst_1 _inst_2 f x)) (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x)
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : CommSemiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (x : S), Eq.{max (succ u1) (succ u2)} (forall (ᾰ : Polynomial.{u1} R _inst_1), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : Polynomial.{u1} R _inst_1) => S) ᾰ) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} (Polynomial.{u1} R _inst_1) S (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (Polynomial.{u1} R _inst_1) (fun (_x : Polynomial.{u1} R _inst_1) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : Polynomial.{u1} R _inst_1) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} (Polynomial.{u1} R _inst_1) S (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (Polynomial.{u1} R _inst_1) S (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} (Polynomial.{u1} R _inst_1) S (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (Polynomial.{u1} R _inst_1) S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} (Polynomial.{u1} R _inst_1) S (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (Polynomial.{u1} R _inst_1) S (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)) (RingHom.instRingHomClassRingHom.{u1, u2} (Polynomial.{u1} R _inst_1) S (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)))))) (Polynomial.eval₂RingHom.{u1, u2} R S _inst_1 _inst_2 f x)) (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x)
Case conversion may be inaccurate. Consider using '#align polynomial.coe_eval₂_ring_hom Polynomial.coe_eval₂RingHomₓ'. -/
@[simp]
theorem coe_eval₂RingHom (f : R →+* S) (x) : ⇑(eval₂RingHom f x) = eval₂ f x :=
  rfl
#align polynomial.coe_eval₂_ring_hom Polynomial.coe_eval₂RingHom

#print Polynomial.eval₂_pow /-
theorem eval₂_pow (n : ℕ) : (p ^ n).eval₂ f x = p.eval₂ f x ^ n :=
  (eval₂RingHom _ _).map_pow _ _
#align polynomial.eval₂_pow Polynomial.eval₂_pow
-/

#print Polynomial.eval₂_dvd /-
theorem eval₂_dvd : p ∣ q → eval₂ f x p ∣ eval₂ f x q :=
  (eval₂RingHom f x).map_dvd
#align polynomial.eval₂_dvd Polynomial.eval₂_dvd
-/

/- warning: polynomial.eval₂_eq_zero_of_dvd_of_eval₂_eq_zero -> Polynomial.eval₂_eq_zero_of_dvd_of_eval₂_eq_zero is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {q : Polynomial.{u1} R _inst_1} [_inst_2 : CommSemiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (x : S), (Dvd.Dvd.{u1} (Polynomial.{u1} R _inst_1) (semigroupDvd.{u1} (Polynomial.{u1} R _inst_1) (SemigroupWithZero.toSemigroup.{u1} (Polynomial.{u1} R _inst_1) (NonUnitalSemiring.toSemigroupWithZero.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonUnitalSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))))) p q) -> (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x p) (OfNat.ofNat.{u2} S 0 (OfNat.mk.{u2} S 0 (Zero.zero.{u2} S (MulZeroClass.toHasZero.{u2} S (NonUnitalNonAssocSemiring.toMulZeroClass.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))))))))) -> (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x q) (OfNat.ofNat.{u2} S 0 (OfNat.mk.{u2} S 0 (Zero.zero.{u2} S (MulZeroClass.toHasZero.{u2} S (NonUnitalNonAssocSemiring.toMulZeroClass.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)))))))))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {q : Polynomial.{u1} R _inst_1} [_inst_2 : CommSemiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (x : S), (Dvd.dvd.{u1} (Polynomial.{u1} R _inst_1) (semigroupDvd.{u1} (Polynomial.{u1} R _inst_1) (SemigroupWithZero.toSemigroup.{u1} (Polynomial.{u1} R _inst_1) (NonUnitalSemiring.toSemigroupWithZero.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonUnitalSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))))) p q) -> (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x p) (OfNat.ofNat.{u2} S 0 (Zero.toOfNat0.{u2} S (CommMonoidWithZero.toZero.{u2} S (CommSemiring.toCommMonoidWithZero.{u2} S _inst_2))))) -> (Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x q) (OfNat.ofNat.{u2} S 0 (Zero.toOfNat0.{u2} S (CommMonoidWithZero.toZero.{u2} S (CommSemiring.toCommMonoidWithZero.{u2} S _inst_2)))))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_eq_zero_of_dvd_of_eval₂_eq_zero Polynomial.eval₂_eq_zero_of_dvd_of_eval₂_eq_zeroₓ'. -/
theorem eval₂_eq_zero_of_dvd_of_eval₂_eq_zero (h : p ∣ q) (h0 : eval₂ f x p = 0) :
    eval₂ f x q = 0 :=
  zero_dvd_iff.mp (h0 ▸ eval₂_dvd f x h)
#align polynomial.eval₂_eq_zero_of_dvd_of_eval₂_eq_zero Polynomial.eval₂_eq_zero_of_dvd_of_eval₂_eq_zero

/- warning: polynomial.eval₂_list_prod -> Polynomial.eval₂_list_prod is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : CommSemiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (l : List.{u1} (Polynomial.{u1} R _inst_1)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x (List.prod.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1) (Polynomial.hasOne.{u1} R _inst_1) l)) (List.prod.{u2} S (Distrib.toHasMul.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))))) (AddMonoidWithOne.toOne.{u2} S (AddCommMonoidWithOne.toAddMonoidWithOne.{u2} S (NonAssocSemiring.toAddCommMonoidWithOne.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))))) (List.map.{u1, u2} (Polynomial.{u1} R _inst_1) S (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x) l))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : CommSemiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (l : List.{u1} (Polynomial.{u1} R _inst_1)) (x : S), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x (List.prod.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1) (Polynomial.one.{u1} R _inst_1) l)) (List.prod.{u2} S (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)))) (Semiring.toOne.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)) (List.map.{u1, u2} (Polynomial.{u1} R _inst_1) S (Polynomial.eval₂.{u1, u2} R S _inst_1 (CommSemiring.toSemiring.{u2} S _inst_2) f x) l))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_list_prod Polynomial.eval₂_list_prodₓ'. -/
theorem eval₂_list_prod (l : List R[X]) (x : S) : eval₂ f x l.Prod = (l.map (eval₂ f x)).Prod :=
  map_list_prod (eval₂RingHom f x) l
#align polynomial.eval₂_list_prod Polynomial.eval₂_list_prod

end

end Eval₂

section Eval

variable {x : R}

#print Polynomial.eval /-
/-- `eval x p` is the evaluation of the polynomial `p` at `x` -/
def eval : R → R[X] → R :=
  eval₂ (RingHom.id _)
#align polynomial.eval Polynomial.eval
-/

/- warning: polynomial.eval_eq_sum -> Polynomial.eval_eq_sum is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x p) (Polynomial.sum.{u1, u1} R _inst_1 R (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) p (fun (e : Nat) (a : R) => HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) a (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) x e)))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x p) (Polynomial.sum.{u1, u1} R _inst_1 R (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) p (fun (e : Nat) (a : R) => HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) a (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) x e)))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_eq_sum Polynomial.eval_eq_sumₓ'. -/
theorem eval_eq_sum : p.eval x = p.Sum fun e a => a * x ^ e :=
  by
  rw [eval, eval₂_eq_sum]
  rfl
#align polynomial.eval_eq_sum Polynomial.eval_eq_sum

/- warning: polynomial.eval_eq_sum_range -> Polynomial.eval_eq_sum_range is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} (x : R), Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x p) (Finset.sum.{u1, 0} R Nat (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) (Polynomial.natDegree.{u1} R _inst_1 p) (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))) (fun (i : Nat) => HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (Polynomial.coeff.{u1} R _inst_1 p i) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) x i)))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} (x : R), Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x p) (Finset.sum.{u1, 0} R Nat (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) (Polynomial.natDegree.{u1} R _inst_1 p) (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (fun (i : Nat) => HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (Polynomial.coeff.{u1} R _inst_1 p i) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) x i)))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_eq_sum_range Polynomial.eval_eq_sum_rangeₓ'. -/
theorem eval_eq_sum_range {p : R[X]} (x : R) :
    p.eval x = ∑ i in Finset.range (p.natDegree + 1), p.coeff i * x ^ i := by
  rw [eval_eq_sum, sum_over_range] <;> simp
#align polynomial.eval_eq_sum_range Polynomial.eval_eq_sum_range

/- warning: polynomial.eval_eq_sum_range' -> Polynomial.eval_eq_sum_range' is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {n : Nat}, (LT.lt.{0} Nat Nat.hasLt (Polynomial.natDegree.{u1} R _inst_1 p) n) -> (forall (x : R), Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x p) (Finset.sum.{u1, 0} R Nat (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (Finset.range n) (fun (i : Nat) => HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (Polynomial.coeff.{u1} R _inst_1 p i) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) x i))))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {n : Nat}, (LT.lt.{0} Nat instLTNat (Polynomial.natDegree.{u1} R _inst_1 p) n) -> (forall (x : R), Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x p) (Finset.sum.{u1, 0} R Nat (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (Finset.range n) (fun (i : Nat) => HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (Polynomial.coeff.{u1} R _inst_1 p i) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) x i))))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_eq_sum_range' Polynomial.eval_eq_sum_range'ₓ'. -/
theorem eval_eq_sum_range' {p : R[X]} {n : ℕ} (hn : p.natDegree < n) (x : R) :
    p.eval x = ∑ i in Finset.range n, p.coeff i * x ^ i := by
  rw [eval_eq_sum, p.sum_over_range' _ _ hn] <;> simp
#align polynomial.eval_eq_sum_range' Polynomial.eval_eq_sum_range'

/- warning: polynomial.eval₂_at_apply -> Polynomial.eval₂_at_apply is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {S : Type.{u2}} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (r : R), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f r) p) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f (Polynomial.eval.{u1} R _inst_1 r p))
but is expected to have type
  forall {R : Type.{u2}} [_inst_1 : Semiring.{u2} R] {p : Polynomial.{u2} R _inst_1} {S : Type.{u1}} [_inst_2 : Semiring.{u1} S] (f : RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)) (r : R), Eq.{succ u1} S (Polynomial.eval₂.{u2, u1} R S _inst_1 _inst_2 f (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u2} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (Semiring.toNonAssocSemiring.{u2} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (Semiring.toNonAssocSemiring.{u2} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2) (RingHom.instRingHomClassRingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2))))) f r) p) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u2} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (Semiring.toNonAssocSemiring.{u2} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (Semiring.toNonAssocSemiring.{u2} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2) (RingHom.instRingHomClassRingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2))))) f (Polynomial.eval.{u2} R _inst_1 r p))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_at_apply Polynomial.eval₂_at_applyₓ'. -/
@[simp]
theorem eval₂_at_apply {S : Type _} [Semiring S] (f : R →+* S) (r : R) :
    p.eval₂ f (f r) = f (p.eval r) :=
  by
  rw [eval₂_eq_sum, eval_eq_sum, Sum, Sum, f.map_sum]
  simp only [f.map_mul, f.map_pow]
#align polynomial.eval₂_at_apply Polynomial.eval₂_at_apply

/- warning: polynomial.eval₂_at_one -> Polynomial.eval₂_at_one is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {S : Type.{u2}} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f (OfNat.ofNat.{u2} S 1 (OfNat.mk.{u2} S 1 (One.one.{u2} S (AddMonoidWithOne.toOne.{u2} S (AddCommMonoidWithOne.toAddMonoidWithOne.{u2} S (NonAssocSemiring.toAddCommMonoidWithOne.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))))) p) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f (Polynomial.eval.{u1} R _inst_1 (OfNat.ofNat.{u1} R 1 (OfNat.mk.{u1} R 1 (One.one.{u1} R (AddMonoidWithOne.toOne.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))))) p))
but is expected to have type
  forall {R : Type.{u2}} [_inst_1 : Semiring.{u2} R] {p : Polynomial.{u2} R _inst_1} {S : Type.{u1}} [_inst_2 : Semiring.{u1} S] (f : RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)), Eq.{succ u1} S (Polynomial.eval₂.{u2, u1} R S _inst_1 _inst_2 f (OfNat.ofNat.{u1} S 1 (One.toOfNat1.{u1} S (Semiring.toOne.{u1} S _inst_2))) p) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u2} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (Semiring.toNonAssocSemiring.{u2} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (Semiring.toNonAssocSemiring.{u2} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2) (RingHom.instRingHomClassRingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2))))) f (Polynomial.eval.{u2} R _inst_1 (OfNat.ofNat.{u2} R 1 (One.toOfNat1.{u2} R (Semiring.toOne.{u2} R _inst_1))) p))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_at_one Polynomial.eval₂_at_oneₓ'. -/
@[simp]
theorem eval₂_at_one {S : Type _} [Semiring S] (f : R →+* S) : p.eval₂ f 1 = f (p.eval 1) :=
  by
  convert eval₂_at_apply f 1
  simp
#align polynomial.eval₂_at_one Polynomial.eval₂_at_one

/- warning: polynomial.eval₂_at_nat_cast -> Polynomial.eval₂_at_nat_cast is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {S : Type.{u2}} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (n : Nat), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f ((fun (a : Type) (b : Type.{u2}) [self : HasLiftT.{1, succ u2} a b] => self.0) Nat S (HasLiftT.mk.{1, succ u2} Nat S (CoeTCₓ.coe.{1, succ u2} Nat S (Nat.castCoe.{u2} S (AddMonoidWithOne.toNatCast.{u2} S (AddCommMonoidWithOne.toAddMonoidWithOne.{u2} S (NonAssocSemiring.toAddCommMonoidWithOne.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))))) n) p) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f (Polynomial.eval.{u1} R _inst_1 ((fun (a : Type) (b : Type.{u1}) [self : HasLiftT.{1, succ u1} a b] => self.0) Nat R (HasLiftT.mk.{1, succ u1} Nat R (CoeTCₓ.coe.{1, succ u1} Nat R (Nat.castCoe.{u1} R (AddMonoidWithOne.toNatCast.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))))) n) p))
but is expected to have type
  forall {R : Type.{u2}} [_inst_1 : Semiring.{u2} R] {p : Polynomial.{u2} R _inst_1} {S : Type.{u1}} [_inst_2 : Semiring.{u1} S] (f : RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)) (n : Nat), Eq.{succ u1} S (Polynomial.eval₂.{u2, u1} R S _inst_1 _inst_2 f (Nat.cast.{u1} S (Semiring.toNatCast.{u1} S _inst_2) n) p) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u2} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (Semiring.toNonAssocSemiring.{u2} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (Semiring.toNonAssocSemiring.{u2} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2) (RingHom.instRingHomClassRingHom.{u2, u1} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u1} S _inst_2))))) f (Polynomial.eval.{u2} R _inst_1 (Nat.cast.{u2} R (Semiring.toNatCast.{u2} R _inst_1) n) p))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_at_nat_cast Polynomial.eval₂_at_nat_castₓ'. -/
@[simp]
theorem eval₂_at_nat_cast {S : Type _} [Semiring S] (f : R →+* S) (n : ℕ) :
    p.eval₂ f n = f (p.eval n) := by
  convert eval₂_at_apply f n
  simp
#align polynomial.eval₂_at_nat_cast Polynomial.eval₂_at_nat_cast

/- warning: polynomial.eval_C -> Polynomial.eval_C is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {a : R} [_inst_1 : Semiring.{u1} R] {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (Polynomial.C.{u1} R _inst_1) a)) a
but is expected to have type
  forall {R : Type.{u1}} {a : R} [_inst_1 : Semiring.{u1} R] {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))))) (Polynomial.C.{u1} R _inst_1) a)) a
Case conversion may be inaccurate. Consider using '#align polynomial.eval_C Polynomial.eval_Cₓ'. -/
@[simp]
theorem eval_C : (C a).eval x = a :=
  eval₂_C _ _
#align polynomial.eval_C Polynomial.eval_C

#print Polynomial.eval_nat_cast /-
@[simp]
theorem eval_nat_cast {n : ℕ} : (n : R[X]).eval x = n := by simp only [← C_eq_nat_cast, eval_C]
#align polynomial.eval_nat_cast Polynomial.eval_nat_cast
-/

#print Polynomial.eval_X /-
@[simp]
theorem eval_X : X.eval x = x :=
  eval₂_X _ _
#align polynomial.eval_X Polynomial.eval_X
-/

/- warning: polynomial.eval_monomial -> Polynomial.eval_monomial is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {x : R} {n : Nat} {a : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (coeFn.{succ u1, succ u1} (LinearMap.{u1, u1, u1, u1} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1))) (fun (_x : LinearMap.{u1, u1, u1, u1} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (LinearMap.hasCoeToFun.{u1, u1, u1, u1} R R R (Polynomial.{u1} R _inst_1) _inst_1 _inst_1 (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1)) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (Polynomial.monomial.{u1} R _inst_1 n) a)) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) a (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) x n))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {x : R} {n : Nat} {a : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (FunLike.coe.{succ u1, succ u1, succ u1} (LinearMap.{u1, u1, u1, u1} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Module.LinearMap._hyg.6190 : R) => Polynomial.{u1} R _inst_1) _x) (LinearMap.instFunLikeLinearMap.{u1, u1, u1, u1} R R R (Polynomial.{u1} R _inst_1) _inst_1 _inst_1 (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1)) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (Polynomial.monomial.{u1} R _inst_1 n) a)) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) a (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) x n))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_monomial Polynomial.eval_monomialₓ'. -/
@[simp]
theorem eval_monomial {n a} : (monomial n a).eval x = a * x ^ n :=
  eval₂_monomial _ _
#align polynomial.eval_monomial Polynomial.eval_monomial

/- warning: polynomial.eval_zero -> Polynomial.eval_zero is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (OfNat.ofNat.{u1} (Polynomial.{u1} R _inst_1) 0 (OfNat.mk.{u1} (Polynomial.{u1} R _inst_1) 0 (Zero.zero.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1))))) (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))))))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (OfNat.ofNat.{u1} (Polynomial.{u1} R _inst_1) 0 (Zero.toOfNat0.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1)))) (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1))))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_zero Polynomial.eval_zeroₓ'. -/
@[simp]
theorem eval_zero : (0 : R[X]).eval x = 0 :=
  eval₂_zero _ _
#align polynomial.eval_zero Polynomial.eval_zero

/- warning: polynomial.eval_add -> Polynomial.eval_add is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {q : Polynomial.{u1} R _inst_1} {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (HAdd.hAdd.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHAdd.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.add'.{u1} R _inst_1)) p q)) (HAdd.hAdd.{u1, u1, u1} R R R (instHAdd.{u1} R (Distrib.toHasAdd.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (Polynomial.eval.{u1} R _inst_1 x p) (Polynomial.eval.{u1} R _inst_1 x q))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {q : Polynomial.{u1} R _inst_1} {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (HAdd.hAdd.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHAdd.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.add'.{u1} R _inst_1)) p q)) (HAdd.hAdd.{u1, u1, u1} R R R (instHAdd.{u1} R (Distrib.toAdd.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (Polynomial.eval.{u1} R _inst_1 x p) (Polynomial.eval.{u1} R _inst_1 x q))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_add Polynomial.eval_addₓ'. -/
@[simp]
theorem eval_add : (p + q).eval x = p.eval x + q.eval x :=
  eval₂_add _ _
#align polynomial.eval_add Polynomial.eval_add

#print Polynomial.eval_one /-
@[simp]
theorem eval_one : (1 : R[X]).eval x = 1 :=
  eval₂_one _ _
#align polynomial.eval_one Polynomial.eval_one
-/

/- warning: polynomial.eval_bit0 -> Polynomial.eval_bit0 is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (bit0.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.add'.{u1} R _inst_1) p)) (bit0.{u1} R (Distrib.toHasAdd.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (Polynomial.eval.{u1} R _inst_1 x p))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (bit0.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.add'.{u1} R _inst_1) p)) (bit0.{u1} R (Distrib.toAdd.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (Polynomial.eval.{u1} R _inst_1 x p))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_bit0 Polynomial.eval_bit0ₓ'. -/
@[simp]
theorem eval_bit0 : (bit0 p).eval x = bit0 (p.eval x) :=
  eval₂_bit0 _ _
#align polynomial.eval_bit0 Polynomial.eval_bit0

/- warning: polynomial.eval_bit1 -> Polynomial.eval_bit1 is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (bit1.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.hasOne.{u1} R _inst_1) (Polynomial.add'.{u1} R _inst_1) p)) (bit1.{u1} R (AddMonoidWithOne.toOne.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (Distrib.toHasAdd.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (Polynomial.eval.{u1} R _inst_1 x p))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (bit1.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.one.{u1} R _inst_1) (Polynomial.add'.{u1} R _inst_1) p)) (bit1.{u1} R (Semiring.toOne.{u1} R _inst_1) (Distrib.toAdd.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (Polynomial.eval.{u1} R _inst_1 x p))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_bit1 Polynomial.eval_bit1ₓ'. -/
@[simp]
theorem eval_bit1 : (bit1 p).eval x = bit1 (p.eval x) :=
  eval₂_bit1 _ _
#align polynomial.eval_bit1 Polynomial.eval_bit1

/- warning: polynomial.eval_smul -> Polynomial.eval_smul is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Monoid.{u2} S] [_inst_3 : DistribMulAction.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))] [_inst_4 : IsScalarTower.{u2, u1, u1} S R R (SMulZeroClass.toHasSmul.{u2, u1} S R (AddZeroClass.toHasZero.{u1} R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))))) (DistribSMul.toSmulZeroClass.{u2, u1} S R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (DistribMulAction.toDistribSMul.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) _inst_3))) (Mul.toSMul.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (SMulZeroClass.toHasSmul.{u2, u1} S R (AddZeroClass.toHasZero.{u1} R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))))) (DistribSMul.toSmulZeroClass.{u2, u1} S R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (DistribMulAction.toDistribSMul.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) _inst_3)))] (s : S) (p : Polynomial.{u1} R _inst_1) (x : R), Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (SMul.smul.{u2, u1} S (Polynomial.{u1} R _inst_1) (SMulZeroClass.toHasSmul.{u2, u1} S (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1) (Polynomial.smulZeroClass.{u1, u2} R _inst_1 S (DistribSMul.toSmulZeroClass.{u2, u1} S R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (DistribMulAction.toDistribSMul.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) _inst_3)))) s p)) (SMul.smul.{u2, u1} S R (SMulZeroClass.toHasSmul.{u2, u1} S R (AddZeroClass.toHasZero.{u1} R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))))) (DistribSMul.toSmulZeroClass.{u2, u1} S R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (DistribMulAction.toDistribSMul.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) _inst_3))) s (Polynomial.eval.{u1} R _inst_1 x p))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Monoid.{u2} S] [_inst_3 : DistribMulAction.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))] [_inst_4 : IsScalarTower.{u2, u1, u1} S R R (SMulZeroClass.toSMul.{u2, u1} S R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)) (DistribSMul.toSMulZeroClass.{u2, u1} S R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (DistribMulAction.toDistribSMul.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) _inst_3))) (SMulZeroClass.toSMul.{u1, u1} R R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)) (SMulWithZero.toSMulZeroClass.{u1, u1} R R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)) (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)) (MulZeroClass.toSMulWithZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))))) (SMulZeroClass.toSMul.{u2, u1} S R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)) (DistribSMul.toSMulZeroClass.{u2, u1} S R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (DistribMulAction.toDistribSMul.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) _inst_3)))] (s : S) (p : Polynomial.{u1} R _inst_1) (x : R), Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (HSMul.hSMul.{u2, u1, u1} S (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHSMul.{u2, u1} S (Polynomial.{u1} R _inst_1) (SMulZeroClass.toSMul.{u2, u1} S (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1) (Polynomial.smulZeroClass.{u1, u2} R _inst_1 S (DistribSMul.toSMulZeroClass.{u2, u1} S R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (DistribMulAction.toDistribSMul.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) _inst_3))))) s p)) (HSMul.hSMul.{u2, u1, u1} S R R (instHSMul.{u2, u1} S R (SMulZeroClass.toSMul.{u2, u1} S R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)) (DistribSMul.toSMulZeroClass.{u2, u1} S R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (DistribMulAction.toDistribSMul.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) _inst_3)))) s (Polynomial.eval.{u1} R _inst_1 x p))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_smul Polynomial.eval_smulₓ'. -/
@[simp]
theorem eval_smul [Monoid S] [DistribMulAction S R] [IsScalarTower S R R] (s : S) (p : R[X])
    (x : R) : (s • p).eval x = s • p.eval x := by
  rw [← smul_one_smul R s p, eval, eval₂_smul, RingHom.id_apply, smul_one_mul]
#align polynomial.eval_smul Polynomial.eval_smul

/- warning: polynomial.eval_C_mul -> Polynomial.eval_C_mul is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {a : R} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (Polynomial.C.{u1} R _inst_1) a) p)) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) a (Polynomial.eval.{u1} R _inst_1 x p))
but is expected to have type
  forall {R : Type.{u1}} {a : R} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (HMul.hMul.{u1, u1, u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) a) (Polynomial.{u1} R _inst_1) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) a) (instHMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) a) (Polynomial.mul'.{u1} R _inst_1)) (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))))) (Polynomial.C.{u1} R _inst_1) a) p)) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) a (Polynomial.eval.{u1} R _inst_1 x p))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_C_mul Polynomial.eval_C_mulₓ'. -/
@[simp]
theorem eval_C_mul : (C a * p).eval x = a * p.eval x :=
  by
  apply Polynomial.induction_on' p
  · intro p q ph qh
    simp only [mul_add, eval_add, ph, qh]
  · intro n b
    simp only [mul_assoc, C_mul_monomial, eval_monomial]
#align polynomial.eval_C_mul Polynomial.eval_C_mul

/- warning: polynomial.eval_monomial_one_add_sub -> Polynomial.eval_monomial_one_add_sub is a dubious translation:
lean 3 declaration is
  forall {S : Type.{u1}} [_inst_2 : CommRing.{u1} S] (d : Nat) (y : S), Eq.{succ u1} S (HSub.hSub.{u1, u1, u1} S S S (instHSub.{u1} S (SubNegMonoid.toHasSub.{u1} S (AddGroup.toSubNegMonoid.{u1} S (AddGroupWithOne.toAddGroup.{u1} S (AddCommGroupWithOne.toAddGroupWithOne.{u1} S (Ring.toAddCommGroupWithOne.{u1} S (CommRing.toRing.{u1} S _inst_2))))))) (Polynomial.eval.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (HAdd.hAdd.{u1, u1, u1} S S S (instHAdd.{u1} S (Distrib.toHasAdd.{u1} S (Ring.toDistrib.{u1} S (CommRing.toRing.{u1} S _inst_2)))) (OfNat.ofNat.{u1} S 1 (OfNat.mk.{u1} S 1 (One.one.{u1} S (AddMonoidWithOne.toOne.{u1} S (AddGroupWithOne.toAddMonoidWithOne.{u1} S (AddCommGroupWithOne.toAddGroupWithOne.{u1} S (Ring.toAddCommGroupWithOne.{u1} S (CommRing.toRing.{u1} S _inst_2)))))))) y) (coeFn.{succ u1, succ u1} (LinearMap.{u1, u1, u1, u1} S S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (RingHom.id.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))) S (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.semiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))))) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.module.{u1, u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (fun (_x : LinearMap.{u1, u1, u1, u1} S S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (RingHom.id.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))) S (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.semiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))))) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.module.{u1, u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) => S -> (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))) (LinearMap.hasCoeToFun.{u1, u1, u1, u1} S S S (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.semiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))))) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.module.{u1, u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))) (RingHom.id.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (Polynomial.monomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) d) (HAdd.hAdd.{u1, u1, u1} S S S (instHAdd.{u1} S (Distrib.toHasAdd.{u1} S (Ring.toDistrib.{u1} S (CommRing.toRing.{u1} S _inst_2)))) ((fun (a : Type) (b : Type.{u1}) [self : HasLiftT.{1, succ u1} a b] => self.0) Nat S (HasLiftT.mk.{1, succ u1} Nat S (CoeTCₓ.coe.{1, succ u1} Nat S (Nat.castCoe.{u1} S (AddMonoidWithOne.toNatCast.{u1} S (AddGroupWithOne.toAddMonoidWithOne.{u1} S (AddCommGroupWithOne.toAddGroupWithOne.{u1} S (Ring.toAddCommGroupWithOne.{u1} S (CommRing.toRing.{u1} S _inst_2)))))))) d) (OfNat.ofNat.{u1} S 1 (OfNat.mk.{u1} S 1 (One.one.{u1} S (AddMonoidWithOne.toOne.{u1} S (AddGroupWithOne.toAddMonoidWithOne.{u1} S (AddCommGroupWithOne.toAddGroupWithOne.{u1} S (Ring.toAddCommGroupWithOne.{u1} S (CommRing.toRing.{u1} S _inst_2))))))))))) (Polynomial.eval.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) y (coeFn.{succ u1, succ u1} (LinearMap.{u1, u1, u1, u1} S S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (RingHom.id.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))) S (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.semiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))))) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.module.{u1, u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (fun (_x : LinearMap.{u1, u1, u1, u1} S S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (RingHom.id.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))) S (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.semiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))))) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.module.{u1, u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) => S -> (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))) (LinearMap.hasCoeToFun.{u1, u1, u1, u1} S S S (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.semiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))))) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.module.{u1, u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))) (RingHom.id.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (Polynomial.monomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) d) (HAdd.hAdd.{u1, u1, u1} S S S (instHAdd.{u1} S (Distrib.toHasAdd.{u1} S (Ring.toDistrib.{u1} S (CommRing.toRing.{u1} S _inst_2)))) ((fun (a : Type) (b : Type.{u1}) [self : HasLiftT.{1, succ u1} a b] => self.0) Nat S (HasLiftT.mk.{1, succ u1} Nat S (CoeTCₓ.coe.{1, succ u1} Nat S (Nat.castCoe.{u1} S (AddMonoidWithOne.toNatCast.{u1} S (AddGroupWithOne.toAddMonoidWithOne.{u1} S (AddCommGroupWithOne.toAddGroupWithOne.{u1} S (Ring.toAddCommGroupWithOne.{u1} S (CommRing.toRing.{u1} S _inst_2)))))))) d) (OfNat.ofNat.{u1} S 1 (OfNat.mk.{u1} S 1 (One.one.{u1} S (AddMonoidWithOne.toOne.{u1} S (AddGroupWithOne.toAddMonoidWithOne.{u1} S (AddCommGroupWithOne.toAddGroupWithOne.{u1} S (Ring.toAddCommGroupWithOne.{u1} S (CommRing.toRing.{u1} S _inst_2)))))))))))) (Finset.sum.{u1, 0} S Nat (AddCommGroup.toAddCommMonoid.{u1} S (NonUnitalNonAssocRing.toAddCommGroup.{u1} S (NonAssocRing.toNonUnitalNonAssocRing.{u1} S (Ring.toNonAssocRing.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) d (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))) (fun (x_1 : Nat) => HMul.hMul.{u1, u1, u1} S S S (instHMul.{u1} S (Distrib.toHasMul.{u1} S (Ring.toDistrib.{u1} S (CommRing.toRing.{u1} S _inst_2)))) ((fun (a : Type) (b : Type.{u1}) [self : HasLiftT.{1, succ u1} a b] => self.0) Nat S (HasLiftT.mk.{1, succ u1} Nat S (CoeTCₓ.coe.{1, succ u1} Nat S (Nat.castCoe.{u1} S (AddMonoidWithOne.toNatCast.{u1} S (AddGroupWithOne.toAddMonoidWithOne.{u1} S (AddCommGroupWithOne.toAddGroupWithOne.{u1} S (Ring.toAddCommGroupWithOne.{u1} S (CommRing.toRing.{u1} S _inst_2)))))))) (Nat.choose (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat Nat.hasAdd) d (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne)))) x_1)) (HMul.hMul.{u1, u1, u1} S S S (instHMul.{u1} S (Distrib.toHasMul.{u1} S (Ring.toDistrib.{u1} S (CommRing.toRing.{u1} S _inst_2)))) ((fun (a : Type) (b : Type.{u1}) [self : HasLiftT.{1, succ u1} a b] => self.0) Nat S (HasLiftT.mk.{1, succ u1} Nat S (CoeTCₓ.coe.{1, succ u1} Nat S (Nat.castCoe.{u1} S (AddMonoidWithOne.toNatCast.{u1} S (AddGroupWithOne.toAddMonoidWithOne.{u1} S (AddCommGroupWithOne.toAddGroupWithOne.{u1} S (Ring.toAddCommGroupWithOne.{u1} S (CommRing.toRing.{u1} S _inst_2)))))))) x_1) (HPow.hPow.{u1, 0, u1} S Nat S (instHPow.{u1, 0} S Nat (Monoid.Pow.{u1} S (Ring.toMonoid.{u1} S (CommRing.toRing.{u1} S _inst_2)))) y (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat Nat.hasSub) x_1 (OfNat.ofNat.{0} Nat 1 (OfNat.mk.{0} Nat 1 (One.one.{0} Nat Nat.hasOne))))))))
but is expected to have type
  forall {S : Type.{u1}} [_inst_2 : CommRing.{u1} S] (d : Nat) (y : S), Eq.{succ u1} S (HSub.hSub.{u1, u1, u1} S S S (instHSub.{u1} S (Ring.toSub.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.eval.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (HAdd.hAdd.{u1, u1, u1} S S S (instHAdd.{u1} S (Distrib.toAdd.{u1} S (NonUnitalNonAssocSemiring.toDistrib.{u1} S (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} S (NonAssocRing.toNonUnitalNonAssocRing.{u1} S (Ring.toNonAssocRing.{u1} S (CommRing.toRing.{u1} S _inst_2))))))) (OfNat.ofNat.{u1} S 1 (One.toOfNat1.{u1} S (NonAssocRing.toOne.{u1} S (Ring.toNonAssocRing.{u1} S (CommRing.toRing.{u1} S _inst_2))))) y) (FunLike.coe.{succ u1, succ u1, succ u1} (LinearMap.{u1, u1, u1, u1} S S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (RingHom.id.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))) S (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.semiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))))) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.module.{u1, u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) S (fun (_x : S) => (fun (x._@.Mathlib.Algebra.Module.LinearMap._hyg.6190 : S) => Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) _x) (LinearMap.instFunLikeLinearMap.{u1, u1, u1, u1} S S S (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.semiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))))) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.module.{u1, u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))) (RingHom.id.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (Polynomial.monomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) d) (HAdd.hAdd.{u1, u1, u1} S S S (instHAdd.{u1} S (Distrib.toAdd.{u1} S (NonUnitalNonAssocSemiring.toDistrib.{u1} S (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} S (NonAssocRing.toNonUnitalNonAssocRing.{u1} S (Ring.toNonAssocRing.{u1} S (CommRing.toRing.{u1} S _inst_2))))))) (Nat.cast.{u1} S (NonAssocRing.toNatCast.{u1} S (Ring.toNonAssocRing.{u1} S (CommRing.toRing.{u1} S _inst_2))) d) (OfNat.ofNat.{u1} S 1 (One.toOfNat1.{u1} S (NonAssocRing.toOne.{u1} S (Ring.toNonAssocRing.{u1} S (CommRing.toRing.{u1} S _inst_2)))))))) (Polynomial.eval.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) y (FunLike.coe.{succ u1, succ u1, succ u1} (LinearMap.{u1, u1, u1, u1} S S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (RingHom.id.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))) S (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.semiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))))) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.module.{u1, u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) S (fun (_x : S) => (fun (x._@.Mathlib.Algebra.Module.LinearMap._hyg.6190 : S) => Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) _x) (LinearMap.instFunLikeLinearMap.{u1, u1, u1, u1} S S S (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.semiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))))) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Polynomial.module.{u1, u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) (Semiring.toModule.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))) (RingHom.id.{u1} S (Semiring.toNonAssocSemiring.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (Polynomial.monomial.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)) d) (HAdd.hAdd.{u1, u1, u1} S S S (instHAdd.{u1} S (Distrib.toAdd.{u1} S (NonUnitalNonAssocSemiring.toDistrib.{u1} S (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} S (NonAssocRing.toNonUnitalNonAssocRing.{u1} S (Ring.toNonAssocRing.{u1} S (CommRing.toRing.{u1} S _inst_2))))))) (Nat.cast.{u1} S (NonAssocRing.toNatCast.{u1} S (Ring.toNonAssocRing.{u1} S (CommRing.toRing.{u1} S _inst_2))) d) (OfNat.ofNat.{u1} S 1 (One.toOfNat1.{u1} S (NonAssocRing.toOne.{u1} S (Ring.toNonAssocRing.{u1} S (CommRing.toRing.{u1} S _inst_2))))))))) (Finset.sum.{u1, 0} S Nat (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} S (NonUnitalNonAssocRing.toNonUnitalNonAssocSemiring.{u1} S (NonAssocRing.toNonUnitalNonAssocRing.{u1} S (Ring.toNonAssocRing.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (Finset.range (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) d (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))) (fun (x_1 : Nat) => HMul.hMul.{u1, u1, u1} S S S (instHMul.{u1} S (NonUnitalNonAssocRing.toMul.{u1} S (NonAssocRing.toNonUnitalNonAssocRing.{u1} S (Ring.toNonAssocRing.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (Nat.cast.{u1} S (NonAssocRing.toNatCast.{u1} S (Ring.toNonAssocRing.{u1} S (CommRing.toRing.{u1} S _inst_2))) (Nat.choose (HAdd.hAdd.{0, 0, 0} Nat Nat Nat (instHAdd.{0} Nat instAddNat) d (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1))) x_1)) (HMul.hMul.{u1, u1, u1} S S S (instHMul.{u1} S (NonUnitalNonAssocRing.toMul.{u1} S (NonAssocRing.toNonUnitalNonAssocRing.{u1} S (Ring.toNonAssocRing.{u1} S (CommRing.toRing.{u1} S _inst_2))))) (Nat.cast.{u1} S (NonAssocRing.toNatCast.{u1} S (Ring.toNonAssocRing.{u1} S (CommRing.toRing.{u1} S _inst_2))) x_1) (HPow.hPow.{u1, 0, u1} S Nat S (instHPow.{u1, 0} S Nat (Monoid.Pow.{u1} S (MonoidWithZero.toMonoid.{u1} S (Semiring.toMonoidWithZero.{u1} S (Ring.toSemiring.{u1} S (CommRing.toRing.{u1} S _inst_2)))))) y (HSub.hSub.{0, 0, 0} Nat Nat Nat (instHSub.{0} Nat instSubNat) x_1 (OfNat.ofNat.{0} Nat 1 (instOfNatNat 1)))))))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_monomial_one_add_sub Polynomial.eval_monomial_one_add_subₓ'. -/
/-- A reformulation of the expansion of (1 + y)^d:
$$(d + 1) (1 + y)^d - (d + 1)y^d = \sum_{i = 0}^d {d + 1 \choose i} \cdot i \cdot y^{i - 1}.$$
-/
theorem eval_monomial_one_add_sub [CommRing S] (d : ℕ) (y : S) :
    eval (1 + y) (monomial d (d + 1 : S)) - eval y (monomial d (d + 1 : S)) =
      ∑ x_1 : ℕ in range (d + 1), ↑((d + 1).choose x_1) * (↑x_1 * y ^ (x_1 - 1)) :=
  by
  have cast_succ : (d + 1 : S) = ((d.succ : ℕ) : S) := by simp only [Nat.cast_succ]
  rw [cast_succ, eval_monomial, eval_monomial, add_comm, add_pow]
  conv_lhs =>
    congr
    congr
    skip
    apply_congr
    skip
    rw [one_pow, mul_one, mul_comm]
  rw [sum_range_succ, mul_add, Nat.choose_self, Nat.cast_one, one_mul, add_sub_cancel, mul_sum,
    sum_range_succ', Nat.cast_zero, MulZeroClass.zero_mul, MulZeroClass.mul_zero, add_zero]
  apply sum_congr rfl fun y hy => _
  rw [← mul_assoc, ← mul_assoc, ← Nat.cast_mul, Nat.succ_mul_choose_eq, Nat.cast_mul,
    Nat.add_sub_cancel]
#align polynomial.eval_monomial_one_add_sub Polynomial.eval_monomial_one_add_sub

#print Polynomial.leval /-
/-- `polynomial.eval` as linear map -/
@[simps]
def leval {R : Type _} [Semiring R] (r : R) : R[X] →ₗ[R] R
    where
  toFun f := f.eval r
  map_add' f g := eval_add
  map_smul' c f := eval_smul c f r
#align polynomial.leval Polynomial.leval
-/

/- warning: polynomial.eval_nat_cast_mul -> Polynomial.eval_nat_cast_mul is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {x : R} {n : Nat}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) ((fun (a : Type) (b : Type.{u1}) [self : HasLiftT.{1, succ u1} a b] => self.0) Nat (Polynomial.{u1} R _inst_1) (HasLiftT.mk.{1, succ u1} Nat (Polynomial.{u1} R _inst_1) (CoeTCₓ.coe.{1, succ u1} Nat (Polynomial.{u1} R _inst_1) (Nat.castCoe.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.natCast.{u1} R _inst_1)))) n) p)) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) ((fun (a : Type) (b : Type.{u1}) [self : HasLiftT.{1, succ u1} a b] => self.0) Nat R (HasLiftT.mk.{1, succ u1} Nat R (CoeTCₓ.coe.{1, succ u1} Nat R (Nat.castCoe.{u1} R (AddMonoidWithOne.toNatCast.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))))) n) (Polynomial.eval.{u1} R _inst_1 x p))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {x : R} {n : Nat}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) (Nat.cast.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.natCast.{u1} R _inst_1) n) p)) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (Nat.cast.{u1} R (Semiring.toNatCast.{u1} R _inst_1) n) (Polynomial.eval.{u1} R _inst_1 x p))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_nat_cast_mul Polynomial.eval_nat_cast_mulₓ'. -/
@[simp]
theorem eval_nat_cast_mul {n : ℕ} : ((n : R[X]) * p).eval x = n * p.eval x := by
  rw [← C_eq_nat_cast, eval_C_mul]
#align polynomial.eval_nat_cast_mul Polynomial.eval_nat_cast_mul

/- warning: polynomial.eval_mul_X -> Polynomial.eval_mul_X is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) p (Polynomial.X.{u1} R _inst_1))) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (Polynomial.eval.{u1} R _inst_1 x p) x)
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) p (Polynomial.X.{u1} R _inst_1))) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (Polynomial.eval.{u1} R _inst_1 x p) x)
Case conversion may be inaccurate. Consider using '#align polynomial.eval_mul_X Polynomial.eval_mul_Xₓ'. -/
@[simp]
theorem eval_mul_X : (p * X).eval x = p.eval x * x :=
  by
  apply Polynomial.induction_on' p
  · intro p q ph qh
    simp only [add_mul, eval_add, ph, qh]
  · intro n a
    simp only [← monomial_one_one_eq_X, monomial_mul_monomial, eval_monomial, mul_one, pow_succ',
      mul_assoc]
#align polynomial.eval_mul_X Polynomial.eval_mul_X

/- warning: polynomial.eval_mul_X_pow -> Polynomial.eval_mul_X_pow is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {x : R} {k : Nat}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) p (HPow.hPow.{u1, 0, u1} (Polynomial.{u1} R _inst_1) Nat (Polynomial.{u1} R _inst_1) (instHPow.{u1, 0} (Polynomial.{u1} R _inst_1) Nat (Monoid.Pow.{u1} (Polynomial.{u1} R _inst_1) (MonoidWithZero.toMonoid.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toMonoidWithZero.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))))) (Polynomial.X.{u1} R _inst_1) k))) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (Polynomial.eval.{u1} R _inst_1 x p) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) x k))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {x : R} {k : Nat}, Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) p (HPow.hPow.{u1, 0, u1} (Polynomial.{u1} R _inst_1) Nat (Polynomial.{u1} R _inst_1) (instHPow.{u1, 0} (Polynomial.{u1} R _inst_1) Nat (Monoid.Pow.{u1} (Polynomial.{u1} R _inst_1) (MonoidWithZero.toMonoid.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toMonoidWithZero.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))))) (Polynomial.X.{u1} R _inst_1) k))) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (Polynomial.eval.{u1} R _inst_1 x p) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) x k))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_mul_X_pow Polynomial.eval_mul_X_powₓ'. -/
@[simp]
theorem eval_mul_X_pow {k : ℕ} : (p * X ^ k).eval x = p.eval x * x ^ k :=
  by
  induction' k with k ih
  · simp
  · simp [pow_succ', ← mul_assoc, ih]
#align polynomial.eval_mul_X_pow Polynomial.eval_mul_X_pow

#print Polynomial.eval_sum /-
theorem eval_sum (p : R[X]) (f : ℕ → R → R[X]) (x : R) :
    (p.Sum f).eval x = p.Sum fun n a => (f n a).eval x :=
  eval₂_sum _ _ _ _
#align polynomial.eval_sum Polynomial.eval_sum
-/

#print Polynomial.eval_finset_sum /-
theorem eval_finset_sum (s : Finset ι) (g : ι → R[X]) (x : R) :
    (∑ i in s, g i).eval x = ∑ i in s, (g i).eval x :=
  eval₂_finset_sum _ _ _ _
#align polynomial.eval_finset_sum Polynomial.eval_finset_sum
-/

#print Polynomial.IsRoot /-
/-- `is_root p x` implies `x` is a root of `p`. The evaluation of `p` at `x` is zero -/
def IsRoot (p : R[X]) (a : R) : Prop :=
  p.eval a = 0
#align polynomial.is_root Polynomial.IsRoot
-/

instance [DecidableEq R] : Decidable (IsRoot p a) := by unfold is_root <;> infer_instance

/- warning: polynomial.is_root.def -> Polynomial.IsRoot.def is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {a : R} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1}, Iff (Polynomial.IsRoot.{u1} R _inst_1 p a) (Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 a p) (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))))))
but is expected to have type
  forall {R : Type.{u1}} {a : R} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1}, Iff (Polynomial.IsRoot.{u1} R _inst_1 p a) (Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 a p) (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))))
Case conversion may be inaccurate. Consider using '#align polynomial.is_root.def Polynomial.IsRoot.defₓ'. -/
@[simp]
theorem IsRoot.def : IsRoot p a ↔ p.eval a = 0 :=
  Iff.rfl
#align polynomial.is_root.def Polynomial.IsRoot.def

/- warning: polynomial.is_root.eq_zero -> Polynomial.IsRoot.eq_zero is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {x : R}, (Polynomial.IsRoot.{u1} R _inst_1 p x) -> (Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x p) (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))))))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {x : R}, (Polynomial.IsRoot.{u1} R _inst_1 p x) -> (Eq.{succ u1} R (Polynomial.eval.{u1} R _inst_1 x p) (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))))
Case conversion may be inaccurate. Consider using '#align polynomial.is_root.eq_zero Polynomial.IsRoot.eq_zeroₓ'. -/
theorem IsRoot.eq_zero (h : IsRoot p x) : eval x p = 0 :=
  h
#align polynomial.is_root.eq_zero Polynomial.IsRoot.eq_zero

/- warning: polynomial.coeff_zero_eq_eval_zero -> Polynomial.coeff_zero_eq_eval_zero is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] (p : Polynomial.{u1} R _inst_1), Eq.{succ u1} R (Polynomial.coeff.{u1} R _inst_1 p (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) (Polynomial.eval.{u1} R _inst_1 (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))))) p)
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] (p : Polynomial.{u1} R _inst_1), Eq.{succ u1} R (Polynomial.coeff.{u1} R _inst_1 p (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) (Polynomial.eval.{u1} R _inst_1 (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) p)
Case conversion may be inaccurate. Consider using '#align polynomial.coeff_zero_eq_eval_zero Polynomial.coeff_zero_eq_eval_zeroₓ'. -/
theorem coeff_zero_eq_eval_zero (p : R[X]) : coeff p 0 = p.eval 0 :=
  calc
    coeff p 0 = coeff p 0 * 0 ^ 0 := by simp
    _ = p.eval 0 := by
      symm
      rw [eval_eq_sum]
      exact
        Finset.sum_eq_single _ (fun b _ hb => by simp [zero_pow (Nat.pos_of_ne_zero hb)]) (by simp)

#align polynomial.coeff_zero_eq_eval_zero Polynomial.coeff_zero_eq_eval_zero

/- warning: polynomial.zero_is_root_of_coeff_zero_eq_zero -> Polynomial.zero_isRoot_of_coeff_zero_eq_zero is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1}, (Eq.{succ u1} R (Polynomial.coeff.{u1} R _inst_1 p (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))))))) -> (Polynomial.IsRoot.{u1} R _inst_1 p (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))))))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1}, (Eq.{succ u1} R (Polynomial.coeff.{u1} R _inst_1 p (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1))))) -> (Polynomial.IsRoot.{u1} R _inst_1 p (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))))
Case conversion may be inaccurate. Consider using '#align polynomial.zero_is_root_of_coeff_zero_eq_zero Polynomial.zero_isRoot_of_coeff_zero_eq_zeroₓ'. -/
theorem zero_isRoot_of_coeff_zero_eq_zero {p : R[X]} (hp : p.coeff 0 = 0) : IsRoot p 0 := by
  rwa [coeff_zero_eq_eval_zero] at hp
#align polynomial.zero_is_root_of_coeff_zero_eq_zero Polynomial.zero_isRoot_of_coeff_zero_eq_zero

#print Polynomial.IsRoot.dvd /-
theorem IsRoot.dvd {R : Type _} [CommSemiring R] {p q : R[X]} {x : R} (h : p.IsRoot x)
    (hpq : p ∣ q) : q.IsRoot x := by
  rwa [is_root, eval, eval₂_eq_zero_of_dvd_of_eval₂_eq_zero _ _ hpq]
#align polynomial.is_root.dvd Polynomial.IsRoot.dvd
-/

/- warning: polynomial.not_is_root_C -> Polynomial.not_isRoot_C is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] (r : R) (a : R), (Ne.{succ u1} R r (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))))))) -> (Not (Polynomial.IsRoot.{u1} R _inst_1 (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (Polynomial.C.{u1} R _inst_1) r) a))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] (r : R) (a : R), (Ne.{succ u1} R r (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1))))) -> (Not (Polynomial.IsRoot.{u1} R _inst_1 (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))))) (Polynomial.C.{u1} R _inst_1) r) a))
Case conversion may be inaccurate. Consider using '#align polynomial.not_is_root_C Polynomial.not_isRoot_Cₓ'. -/
theorem not_isRoot_C (r a : R) (hr : r ≠ 0) : ¬IsRoot (C r) a := by simpa using hr
#align polynomial.not_is_root_C Polynomial.not_isRoot_C

#print Polynomial.eval_surjective /-
theorem eval_surjective (x : R) : Function.Surjective <| eval x := fun y => ⟨C y, eval_C⟩
#align polynomial.eval_surjective Polynomial.eval_surjective
-/

end Eval

section Comp

#print Polynomial.comp /-
/-- The composition of polynomials as a polynomial. -/
def comp (p q : R[X]) : R[X] :=
  p.eval₂ C q
#align polynomial.comp Polynomial.comp
-/

/- warning: polynomial.comp_eq_sum_left -> Polynomial.comp_eq_sum_left is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {q : Polynomial.{u1} R _inst_1}, Eq.{succ u1} (Polynomial.{u1} R _inst_1) (Polynomial.comp.{u1} R _inst_1 p q) (Polynomial.sum.{u1, u1} R _inst_1 (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) p (fun (e : Nat) (a : R) => HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (Polynomial.C.{u1} R _inst_1) a) (HPow.hPow.{u1, 0, u1} (Polynomial.{u1} R _inst_1) Nat (Polynomial.{u1} R _inst_1) (instHPow.{u1, 0} (Polynomial.{u1} R _inst_1) Nat (Monoid.Pow.{u1} (Polynomial.{u1} R _inst_1) (MonoidWithZero.toMonoid.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toMonoidWithZero.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))))) q e)))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {q : Polynomial.{u1} R _inst_1}, Eq.{succ u1} (Polynomial.{u1} R _inst_1) (Polynomial.comp.{u1} R _inst_1 p q) (Polynomial.sum.{u1, u1} R _inst_1 (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) p (fun (e : Nat) (a : R) => HMul.hMul.{u1, u1, u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) a) (Polynomial.{u1} R _inst_1) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) a) (instHMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) a) (Polynomial.mul'.{u1} R _inst_1)) (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))))) (Polynomial.C.{u1} R _inst_1) a) (HPow.hPow.{u1, 0, u1} (Polynomial.{u1} R _inst_1) Nat (Polynomial.{u1} R _inst_1) (instHPow.{u1, 0} (Polynomial.{u1} R _inst_1) Nat (Monoid.Pow.{u1} (Polynomial.{u1} R _inst_1) (MonoidWithZero.toMonoid.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toMonoidWithZero.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))))) q e)))
Case conversion may be inaccurate. Consider using '#align polynomial.comp_eq_sum_left Polynomial.comp_eq_sum_leftₓ'. -/
theorem comp_eq_sum_left : p.comp q = p.Sum fun e a => C a * q ^ e := by rw [comp, eval₂_eq_sum]
#align polynomial.comp_eq_sum_left Polynomial.comp_eq_sum_left

#print Polynomial.comp_X /-
@[simp]
theorem comp_X : p.comp X = p :=
  by
  simp only [comp, eval₂, C_mul_X_pow_eq_monomial]
  exact sum_monomial_eq _
#align polynomial.comp_X Polynomial.comp_X
-/

#print Polynomial.X_comp /-
@[simp]
theorem X_comp : X.comp p = p :=
  eval₂_X _ _
#align polynomial.X_comp Polynomial.X_comp
-/

/- warning: polynomial.comp_C -> Polynomial.comp_C is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {a : R} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1}, Eq.{succ u1} (Polynomial.{u1} R _inst_1) (Polynomial.comp.{u1} R _inst_1 p (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (Polynomial.C.{u1} R _inst_1) a)) (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (Polynomial.C.{u1} R _inst_1) (Polynomial.eval.{u1} R _inst_1 a p))
but is expected to have type
  forall {R : Type.{u1}} {a : R} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1}, Eq.{succ u1} (Polynomial.{u1} R _inst_1) (Polynomial.comp.{u1} R _inst_1 p (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))))) (Polynomial.C.{u1} R _inst_1) a)) (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))))) (Polynomial.C.{u1} R _inst_1) (Polynomial.eval.{u1} R _inst_1 a p))
Case conversion may be inaccurate. Consider using '#align polynomial.comp_C Polynomial.comp_Cₓ'. -/
@[simp]
theorem comp_C : p.comp (C a) = C (p.eval a) := by simp [comp, (C : R →+* _).map_sum]
#align polynomial.comp_C Polynomial.comp_C

/- warning: polynomial.C_comp -> Polynomial.C_comp is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {a : R} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1}, Eq.{succ u1} (Polynomial.{u1} R _inst_1) (Polynomial.comp.{u1} R _inst_1 (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (Polynomial.C.{u1} R _inst_1) a) p) (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (Polynomial.C.{u1} R _inst_1) a)
but is expected to have type
  forall {R : Type.{u1}} {a : R} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1}, Eq.{succ u1} (Polynomial.{u1} R _inst_1) (Polynomial.comp.{u1} R _inst_1 (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))))) (Polynomial.C.{u1} R _inst_1) a) p) (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))))) (Polynomial.C.{u1} R _inst_1) a)
Case conversion may be inaccurate. Consider using '#align polynomial.C_comp Polynomial.C_compₓ'. -/
@[simp]
theorem C_comp : (C a).comp p = C a :=
  eval₂_C _ _
#align polynomial.C_comp Polynomial.C_comp

#print Polynomial.nat_cast_comp /-
@[simp]
theorem nat_cast_comp {n : ℕ} : (n : R[X]).comp p = n := by rw [← C_eq_nat_cast, C_comp]
#align polynomial.nat_cast_comp Polynomial.nat_cast_comp
-/

/- warning: polynomial.comp_zero -> Polynomial.comp_zero is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1}, Eq.{succ u1} (Polynomial.{u1} R _inst_1) (Polynomial.comp.{u1} R _inst_1 p (OfNat.ofNat.{u1} (Polynomial.{u1} R _inst_1) 0 (OfNat.mk.{u1} (Polynomial.{u1} R _inst_1) 0 (Zero.zero.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1))))) (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (Polynomial.C.{u1} R _inst_1) (Polynomial.eval.{u1} R _inst_1 (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))))) p))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1}, Eq.{succ u1} (Polynomial.{u1} R _inst_1) (Polynomial.comp.{u1} R _inst_1 p (OfNat.ofNat.{u1} (Polynomial.{u1} R _inst_1) 0 (Zero.toOfNat0.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1)))) (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))))) (Polynomial.C.{u1} R _inst_1) (Polynomial.eval.{u1} R _inst_1 (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) p))
Case conversion may be inaccurate. Consider using '#align polynomial.comp_zero Polynomial.comp_zeroₓ'. -/
@[simp]
theorem comp_zero : p.comp (0 : R[X]) = C (p.eval 0) := by rw [← C_0, comp_C]
#align polynomial.comp_zero Polynomial.comp_zero

#print Polynomial.zero_comp /-
@[simp]
theorem zero_comp : comp (0 : R[X]) p = 0 := by rw [← C_0, C_comp]
#align polynomial.zero_comp Polynomial.zero_comp
-/

/- warning: polynomial.comp_one -> Polynomial.comp_one is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1}, Eq.{succ u1} (Polynomial.{u1} R _inst_1) (Polynomial.comp.{u1} R _inst_1 p (OfNat.ofNat.{u1} (Polynomial.{u1} R _inst_1) 1 (OfNat.mk.{u1} (Polynomial.{u1} R _inst_1) 1 (One.one.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.hasOne.{u1} R _inst_1))))) (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (Polynomial.C.{u1} R _inst_1) (Polynomial.eval.{u1} R _inst_1 (OfNat.ofNat.{u1} R 1 (OfNat.mk.{u1} R 1 (One.one.{u1} R (AddMonoidWithOne.toOne.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))))) p))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1}, Eq.{succ u1} (Polynomial.{u1} R _inst_1) (Polynomial.comp.{u1} R _inst_1 p (OfNat.ofNat.{u1} (Polynomial.{u1} R _inst_1) 1 (One.toOfNat1.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.one.{u1} R _inst_1)))) (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))))) (Polynomial.C.{u1} R _inst_1) (Polynomial.eval.{u1} R _inst_1 (OfNat.ofNat.{u1} R 1 (One.toOfNat1.{u1} R (Semiring.toOne.{u1} R _inst_1))) p))
Case conversion may be inaccurate. Consider using '#align polynomial.comp_one Polynomial.comp_oneₓ'. -/
@[simp]
theorem comp_one : p.comp 1 = C (p.eval 1) := by rw [← C_1, comp_C]
#align polynomial.comp_one Polynomial.comp_one

#print Polynomial.one_comp /-
@[simp]
theorem one_comp : comp (1 : R[X]) p = 1 := by rw [← C_1, C_comp]
#align polynomial.one_comp Polynomial.one_comp
-/

#print Polynomial.add_comp /-
@[simp]
theorem add_comp : (p + q).comp r = p.comp r + q.comp r :=
  eval₂_add _ _
#align polynomial.add_comp Polynomial.add_comp
-/

/- warning: polynomial.monomial_comp -> Polynomial.monomial_comp is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {a : R} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} (n : Nat), Eq.{succ u1} (Polynomial.{u1} R _inst_1) (Polynomial.comp.{u1} R _inst_1 (coeFn.{succ u1, succ u1} (LinearMap.{u1, u1, u1, u1} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1))) (fun (_x : LinearMap.{u1, u1, u1, u1} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (LinearMap.hasCoeToFun.{u1, u1, u1, u1} R R R (Polynomial.{u1} R _inst_1) _inst_1 _inst_1 (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1)) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (Polynomial.monomial.{u1} R _inst_1 n) a) p) (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (Polynomial.C.{u1} R _inst_1) a) (HPow.hPow.{u1, 0, u1} (Polynomial.{u1} R _inst_1) Nat (Polynomial.{u1} R _inst_1) (instHPow.{u1, 0} (Polynomial.{u1} R _inst_1) Nat (Monoid.Pow.{u1} (Polynomial.{u1} R _inst_1) (MonoidWithZero.toMonoid.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toMonoidWithZero.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))))) p n))
but is expected to have type
  forall {R : Type.{u1}} {a : R} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} (n : Nat), Eq.{succ u1} (Polynomial.{u1} R _inst_1) (Polynomial.comp.{u1} R _inst_1 (FunLike.coe.{succ u1, succ u1, succ u1} (LinearMap.{u1, u1, u1, u1} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Module.LinearMap._hyg.6190 : R) => Polynomial.{u1} R _inst_1) _x) (LinearMap.instFunLikeLinearMap.{u1, u1, u1, u1} R R R (Polynomial.{u1} R _inst_1) _inst_1 _inst_1 (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1)) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (Polynomial.monomial.{u1} R _inst_1 n) a) p) (HMul.hMul.{u1, u1, u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) a) (Polynomial.{u1} R _inst_1) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) a) (instHMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) a) (Polynomial.mul'.{u1} R _inst_1)) (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))))) (Polynomial.C.{u1} R _inst_1) a) (HPow.hPow.{u1, 0, u1} (Polynomial.{u1} R _inst_1) Nat (Polynomial.{u1} R _inst_1) (instHPow.{u1, 0} (Polynomial.{u1} R _inst_1) Nat (Monoid.Pow.{u1} (Polynomial.{u1} R _inst_1) (MonoidWithZero.toMonoid.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toMonoidWithZero.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))))) p n))
Case conversion may be inaccurate. Consider using '#align polynomial.monomial_comp Polynomial.monomial_compₓ'. -/
@[simp]
theorem monomial_comp (n : ℕ) : (monomial n a).comp p = C a * p ^ n :=
  eval₂_monomial _ _
#align polynomial.monomial_comp Polynomial.monomial_comp

#print Polynomial.mul_X_comp /-
@[simp]
theorem mul_X_comp : (p * X).comp r = p.comp r * r :=
  by
  apply Polynomial.induction_on' p
  · intro p q hp hq
    simp only [hp, hq, add_mul, add_comp]
  · intro n b
    simp only [pow_succ', mul_assoc, monomial_mul_X, monomial_comp]
#align polynomial.mul_X_comp Polynomial.mul_X_comp
-/

#print Polynomial.X_pow_comp /-
@[simp]
theorem X_pow_comp {k : ℕ} : (X ^ k).comp p = p ^ k :=
  by
  induction' k with k ih
  · simp
  · simp [pow_succ', mul_X_comp, ih]
#align polynomial.X_pow_comp Polynomial.X_pow_comp
-/

#print Polynomial.mul_X_pow_comp /-
@[simp]
theorem mul_X_pow_comp {k : ℕ} : (p * X ^ k).comp r = p.comp r * r ^ k :=
  by
  induction' k with k ih
  · simp
  · simp [ih, pow_succ', ← mul_assoc, mul_X_comp]
#align polynomial.mul_X_pow_comp Polynomial.mul_X_pow_comp
-/

/- warning: polynomial.C_mul_comp -> Polynomial.C_mul_comp is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {a : R} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {r : Polynomial.{u1} R _inst_1}, Eq.{succ u1} (Polynomial.{u1} R _inst_1) (Polynomial.comp.{u1} R _inst_1 (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (Polynomial.C.{u1} R _inst_1) a) p) r) (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHMul.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.mul'.{u1} R _inst_1)) (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (Polynomial.C.{u1} R _inst_1) a) (Polynomial.comp.{u1} R _inst_1 p r))
but is expected to have type
  forall {R : Type.{u1}} {a : R} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {r : Polynomial.{u1} R _inst_1}, Eq.{succ u1} (Polynomial.{u1} R _inst_1) (Polynomial.comp.{u1} R _inst_1 (HMul.hMul.{u1, u1, u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) a) (Polynomial.{u1} R _inst_1) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) a) (instHMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) a) (Polynomial.mul'.{u1} R _inst_1)) (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))))) (Polynomial.C.{u1} R _inst_1) a) p) r) (HMul.hMul.{u1, u1, u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) a) (Polynomial.{u1} R _inst_1) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) a) (instHMul.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) a) (Polynomial.mul'.{u1} R _inst_1)) (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))))) (Polynomial.C.{u1} R _inst_1) a) (Polynomial.comp.{u1} R _inst_1 p r))
Case conversion may be inaccurate. Consider using '#align polynomial.C_mul_comp Polynomial.C_mul_compₓ'. -/
@[simp]
theorem C_mul_comp : (C a * p).comp r = C a * p.comp r :=
  by
  apply Polynomial.induction_on' p
  · intro p q hp hq
    simp [hp, hq, mul_add]
  · intro n b
    simp [mul_assoc]
#align polynomial.C_mul_comp Polynomial.C_mul_comp

#print Polynomial.nat_cast_mul_comp /-
@[simp]
theorem nat_cast_mul_comp {n : ℕ} : ((n : R[X]) * p).comp r = n * p.comp r := by
  rw [← C_eq_nat_cast, C_mul_comp, C_eq_nat_cast]
#align polynomial.nat_cast_mul_comp Polynomial.nat_cast_mul_comp
-/

#print Polynomial.mul_comp /-
@[simp]
theorem mul_comp {R : Type _} [CommSemiring R] (p q r : R[X]) :
    (p * q).comp r = p.comp r * q.comp r :=
  eval₂_mul _ _
#align polynomial.mul_comp Polynomial.mul_comp
-/

#print Polynomial.pow_comp /-
@[simp]
theorem pow_comp {R : Type _} [CommSemiring R] (p q : R[X]) (n : ℕ) :
    (p ^ n).comp q = p.comp q ^ n :=
  ((MonoidHom.mk fun r : R[X] => r.comp q) one_comp fun r s => mul_comp r s q).map_pow p n
#align polynomial.pow_comp Polynomial.pow_comp
-/

#print Polynomial.bit0_comp /-
@[simp]
theorem bit0_comp : comp (bit0 p : R[X]) q = bit0 (p.comp q) := by simp only [bit0, add_comp]
#align polynomial.bit0_comp Polynomial.bit0_comp
-/

#print Polynomial.bit1_comp /-
@[simp]
theorem bit1_comp : comp (bit1 p : R[X]) q = bit1 (p.comp q) := by
  simp only [bit1, add_comp, bit0_comp, one_comp]
#align polynomial.bit1_comp Polynomial.bit1_comp
-/

/- warning: polynomial.smul_comp -> Polynomial.smul_comp is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Monoid.{u2} S] [_inst_3 : DistribMulAction.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))] [_inst_4 : IsScalarTower.{u2, u1, u1} S R R (SMulZeroClass.toHasSmul.{u2, u1} S R (AddZeroClass.toHasZero.{u1} R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))))) (DistribSMul.toSmulZeroClass.{u2, u1} S R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (DistribMulAction.toDistribSMul.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) _inst_3))) (Mul.toSMul.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (SMulZeroClass.toHasSmul.{u2, u1} S R (AddZeroClass.toHasZero.{u1} R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))))) (DistribSMul.toSmulZeroClass.{u2, u1} S R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (DistribMulAction.toDistribSMul.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) _inst_3)))] (s : S) (p : Polynomial.{u1} R _inst_1) (q : Polynomial.{u1} R _inst_1), Eq.{succ u1} (Polynomial.{u1} R _inst_1) (Polynomial.comp.{u1} R _inst_1 (SMul.smul.{u2, u1} S (Polynomial.{u1} R _inst_1) (SMulZeroClass.toHasSmul.{u2, u1} S (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1) (Polynomial.smulZeroClass.{u1, u2} R _inst_1 S (DistribSMul.toSmulZeroClass.{u2, u1} S R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (DistribMulAction.toDistribSMul.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) _inst_3)))) s p) q) (SMul.smul.{u2, u1} S (Polynomial.{u1} R _inst_1) (SMulZeroClass.toHasSmul.{u2, u1} S (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1) (Polynomial.smulZeroClass.{u1, u2} R _inst_1 S (DistribSMul.toSmulZeroClass.{u2, u1} S R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (DistribMulAction.toDistribSMul.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) _inst_3)))) s (Polynomial.comp.{u1} R _inst_1 p q))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Monoid.{u2} S] [_inst_3 : DistribMulAction.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))] [_inst_4 : IsScalarTower.{u2, u1, u1} S R R (SMulZeroClass.toSMul.{u2, u1} S R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)) (DistribSMul.toSMulZeroClass.{u2, u1} S R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (DistribMulAction.toDistribSMul.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) _inst_3))) (SMulZeroClass.toSMul.{u1, u1} R R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)) (SMulWithZero.toSMulZeroClass.{u1, u1} R R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)) (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)) (MulZeroClass.toSMulWithZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))))) (SMulZeroClass.toSMul.{u2, u1} S R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)) (DistribSMul.toSMulZeroClass.{u2, u1} S R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (DistribMulAction.toDistribSMul.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) _inst_3)))] (s : S) (p : Polynomial.{u1} R _inst_1) (q : Polynomial.{u1} R _inst_1), Eq.{succ u1} (Polynomial.{u1} R _inst_1) (Polynomial.comp.{u1} R _inst_1 (HSMul.hSMul.{u2, u1, u1} S (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHSMul.{u2, u1} S (Polynomial.{u1} R _inst_1) (SMulZeroClass.toSMul.{u2, u1} S (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1) (Polynomial.smulZeroClass.{u1, u2} R _inst_1 S (DistribSMul.toSMulZeroClass.{u2, u1} S R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (DistribMulAction.toDistribSMul.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) _inst_3))))) s p) q) (HSMul.hSMul.{u2, u1, u1} S (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHSMul.{u2, u1} S (Polynomial.{u1} R _inst_1) (SMulZeroClass.toSMul.{u2, u1} S (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1) (Polynomial.smulZeroClass.{u1, u2} R _inst_1 S (DistribSMul.toSMulZeroClass.{u2, u1} S R (AddMonoid.toAddZeroClass.{u1} R (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (DistribMulAction.toDistribSMul.{u2, u1} S R _inst_2 (AddMonoidWithOne.toAddMonoid.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) _inst_3))))) s (Polynomial.comp.{u1} R _inst_1 p q))
Case conversion may be inaccurate. Consider using '#align polynomial.smul_comp Polynomial.smul_compₓ'. -/
@[simp]
theorem smul_comp [Monoid S] [DistribMulAction S R] [IsScalarTower S R R] (s : S) (p q : R[X]) :
    (s • p).comp q = s • p.comp q := by
  rw [← smul_one_smul R s p, comp, comp, eval₂_smul, ← smul_eq_C_mul, smul_assoc, one_smul]
#align polynomial.smul_comp Polynomial.smul_comp

#print Polynomial.comp_assoc /-
theorem comp_assoc {R : Type _} [CommSemiring R] (φ ψ χ : R[X]) :
    (φ.comp ψ).comp χ = φ.comp (ψ.comp χ) := by
  apply Polynomial.induction_on φ <;>
    · intros
      simp_all only [add_comp, mul_comp, C_comp, X_comp, pow_succ', ← mul_assoc]
#align polynomial.comp_assoc Polynomial.comp_assoc
-/

/- warning: polynomial.coeff_comp_degree_mul_degree -> Polynomial.coeff_comp_degree_mul_degree is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {q : Polynomial.{u1} R _inst_1}, (Ne.{1} Nat (Polynomial.natDegree.{u1} R _inst_1 q) (OfNat.ofNat.{0} Nat 0 (OfNat.mk.{0} Nat 0 (Zero.zero.{0} Nat Nat.hasZero)))) -> (Eq.{succ u1} R (Polynomial.coeff.{u1} R _inst_1 (Polynomial.comp.{u1} R _inst_1 p q) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat Nat.hasMul) (Polynomial.natDegree.{u1} R _inst_1 p) (Polynomial.natDegree.{u1} R _inst_1 q))) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))) (Polynomial.leadingCoeff.{u1} R _inst_1 p) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) (Polynomial.leadingCoeff.{u1} R _inst_1 q) (Polynomial.natDegree.{u1} R _inst_1 p))))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} {q : Polynomial.{u1} R _inst_1}, (Ne.{1} Nat (Polynomial.natDegree.{u1} R _inst_1 q) (OfNat.ofNat.{0} Nat 0 (instOfNatNat 0))) -> (Eq.{succ u1} R (Polynomial.coeff.{u1} R _inst_1 (Polynomial.comp.{u1} R _inst_1 p q) (HMul.hMul.{0, 0, 0} Nat Nat Nat (instHMul.{0} Nat instMulNat) (Polynomial.natDegree.{u1} R _inst_1 p) (Polynomial.natDegree.{u1} R _inst_1 q))) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (Polynomial.leadingCoeff.{u1} R _inst_1 p) (HPow.hPow.{u1, 0, u1} R Nat R (instHPow.{u1, 0} R Nat (Monoid.Pow.{u1} R (MonoidWithZero.toMonoid.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) (Polynomial.leadingCoeff.{u1} R _inst_1 q) (Polynomial.natDegree.{u1} R _inst_1 p))))
Case conversion may be inaccurate. Consider using '#align polynomial.coeff_comp_degree_mul_degree Polynomial.coeff_comp_degree_mul_degreeₓ'. -/
theorem coeff_comp_degree_mul_degree (hqd0 : natDegree q ≠ 0) :
    coeff (p.comp q) (natDegree p * natDegree q) = leadingCoeff p * leadingCoeff q ^ natDegree p :=
  by
  rw [comp, eval₂, coeff_sum]
  convert Finset.sum_eq_single p.nat_degree _ _
  · simp only [coeff_nat_degree, coeff_C_mul, coeff_pow_mul_nat_degree]
  · intro b hbs hbp
    refine' coeff_eq_zero_of_nat_degree_lt (nat_degree_mul_le.trans_lt _)
    rw [nat_degree_C, zero_add]
    refine' nat_degree_pow_le.trans_lt ((mul_lt_mul_right (pos_iff_ne_zero.mpr hqd0)).mpr _)
    exact lt_of_le_of_ne (le_nat_degree_of_mem_supp _ hbs) hbp
  · simp (config := { contextual := true })
#align polynomial.coeff_comp_degree_mul_degree Polynomial.coeff_comp_degree_mul_degree

end Comp

section Map

variable [Semiring S]

variable (f : R →+* S)

#print Polynomial.map /-
/-- `map f p` maps a polynomial `p` across a ring hom `f` -/
def map : R[X] → S[X] :=
  eval₂ (C.comp f) X
#align polynomial.map Polynomial.map
-/

/- warning: polynomial.map_C -> Polynomial.map_C is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} {a : R} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)), Eq.{succ u2} (Polynomial.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (Polynomial.C.{u1} R _inst_1) a)) (coeFn.{succ u2, succ u2} (RingHom.{u2, u2} S (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2))) (fun (_x : RingHom.{u2, u2} S (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2))) => S -> (Polynomial.{u2} S _inst_2)) (RingHom.hasCoeToFun.{u2, u2} S (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2))) (Polynomial.C.{u2} S _inst_2) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f a))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} {a : R} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)), Eq.{succ u2} (Polynomial.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R _inst_1) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))))) (Polynomial.C.{u1} R _inst_1) a)) (FunLike.coe.{succ u2, succ u2, succ u2} (RingHom.{u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Polynomial.semiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2))) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (fun (_x : (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) => Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) _x) (MulHomClass.toFunLike.{u2, u2, u2} (RingHom.{u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Polynomial.semiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2))) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (NonUnitalNonAssocSemiring.toMul.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2))) (NonUnitalNonAssocSemiring.toMul.{u2} (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Polynomial.semiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2)))) (NonUnitalRingHomClass.toMulHomClass.{u2, u2, u2} (RingHom.{u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Polynomial.semiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2))) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Polynomial.semiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2))) (RingHomClass.toNonUnitalRingHomClass.{u2, u2, u2} (RingHom.{u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Polynomial.semiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2))) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Polynomial.semiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2)) (RingHom.instRingHomClassRingHom.{u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Polynomial.semiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2)))))) (Polynomial.C.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f a))
Case conversion may be inaccurate. Consider using '#align polynomial.map_C Polynomial.map_Cₓ'. -/
@[simp]
theorem map_C : (C a).map f = C (f a) :=
  eval₂_C _ _
#align polynomial.map_C Polynomial.map_C

#print Polynomial.map_X /-
@[simp]
theorem map_X : X.map f = X :=
  eval₂_X _ _
#align polynomial.map_X Polynomial.map_X
-/

/- warning: polynomial.map_monomial -> Polynomial.map_monomial is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) {n : Nat} {a : R}, Eq.{succ u2} (Polynomial.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f (coeFn.{succ u1, succ u1} (LinearMap.{u1, u1, u1, u1} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1))) (fun (_x : LinearMap.{u1, u1, u1, u1} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1))) => R -> (Polynomial.{u1} R _inst_1)) (LinearMap.hasCoeToFun.{u1, u1, u1, u1} R R R (Polynomial.{u1} R _inst_1) _inst_1 _inst_1 (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1)) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (Polynomial.monomial.{u1} R _inst_1 n) a)) (coeFn.{succ u2, succ u2} (LinearMap.{u2, u2, u2, u2} S S _inst_2 _inst_2 (RingHom.id.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) S (Polynomial.{u2} S _inst_2) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} (Polynomial.{u2} S _inst_2) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2)))) (Semiring.toModule.{u2} S _inst_2) (Polynomial.module.{u2, u2} S _inst_2 S _inst_2 (Semiring.toModule.{u2} S _inst_2))) (fun (_x : LinearMap.{u2, u2, u2, u2} S S _inst_2 _inst_2 (RingHom.id.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) S (Polynomial.{u2} S _inst_2) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} (Polynomial.{u2} S _inst_2) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2)))) (Semiring.toModule.{u2} S _inst_2) (Polynomial.module.{u2, u2} S _inst_2 S _inst_2 (Semiring.toModule.{u2} S _inst_2))) => S -> (Polynomial.{u2} S _inst_2)) (LinearMap.hasCoeToFun.{u2, u2, u2, u2} S S S (Polynomial.{u2} S _inst_2) _inst_2 _inst_2 (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} (Polynomial.{u2} S _inst_2) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2)))) (Semiring.toModule.{u2} S _inst_2) (Polynomial.module.{u2, u2} S _inst_2 S _inst_2 (Semiring.toModule.{u2} S _inst_2)) (RingHom.id.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (Polynomial.monomial.{u2} S _inst_2 n) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f a))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) {n : Nat} {a : R}, Eq.{succ u2} (Polynomial.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f (FunLike.coe.{succ u1, succ u1, succ u1} (LinearMap.{u1, u1, u1, u1} R R _inst_1 _inst_1 (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) R (Polynomial.{u1} R _inst_1) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Module.LinearMap._hyg.6190 : R) => Polynomial.{u1} R _inst_1) _x) (LinearMap.instFunLikeLinearMap.{u1, u1, u1, u1} R R R (Polynomial.{u1} R _inst_1) _inst_1 _inst_1 (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (Semiring.toModule.{u1} R _inst_1) (Polynomial.module.{u1, u1} R _inst_1 R _inst_1 (Semiring.toModule.{u1} R _inst_1)) (RingHom.id.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (Polynomial.monomial.{u1} R _inst_1 n) a)) (FunLike.coe.{succ u2, succ u2, succ u2} (LinearMap.{u2, u2, u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2 _inst_2 (RingHom.id.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2)) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Polynomial.semiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2)))) (Semiring.toModule.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Polynomial.module.{u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2 ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2 (Semiring.toModule.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2))) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (fun (_x : (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) => (fun (x._@.Mathlib.Algebra.Module.LinearMap._hyg.6190 : (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) => Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) _x) (LinearMap.instFunLikeLinearMap.{u2, u2, u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) _inst_2 _inst_2 (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2))) (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Polynomial.semiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2)))) (Semiring.toModule.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2) (Polynomial.module.{u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2 ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2 (Semiring.toModule.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2)) (RingHom.id.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2))) (Polynomial.monomial.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) a) _inst_2 n) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f a))
Case conversion may be inaccurate. Consider using '#align polynomial.map_monomial Polynomial.map_monomialₓ'. -/
@[simp]
theorem map_monomial {n a} : (monomial n a).map f = monomial n (f a) :=
  by
  dsimp only [map]
  rw [eval₂_monomial, ← C_mul_X_pow_eq_monomial]; rfl
#align polynomial.map_monomial Polynomial.map_monomial

#print Polynomial.map_zero /-
@[simp]
protected theorem map_zero : (0 : R[X]).map f = 0 :=
  eval₂_zero _ _
#align polynomial.map_zero Polynomial.map_zero
-/

#print Polynomial.map_add /-
@[simp]
protected theorem map_add : (p + q).map f = p.map f + q.map f :=
  eval₂_add _ _
#align polynomial.map_add Polynomial.map_add
-/

#print Polynomial.map_one /-
@[simp]
protected theorem map_one : (1 : R[X]).map f = 1 :=
  eval₂_one _ _
#align polynomial.map_one Polynomial.map_one
-/

#print Polynomial.map_mul /-
@[simp]
protected theorem map_mul : (p * q).map f = p.map f * q.map f :=
  by
  rw [map, eval₂_mul_noncomm]
  exact fun k => (commute_X _).symm
#align polynomial.map_mul Polynomial.map_mul
-/

/- warning: polynomial.map_smul -> Polynomial.map_smul is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (r : R), Eq.{succ u2} (Polynomial.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f (SMul.smul.{u1, u1} R (Polynomial.{u1} R _inst_1) (SMulZeroClass.toHasSmul.{u1, u1} R (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1) (Polynomial.smulZeroClass.{u1, u1} R _inst_1 R (SMulWithZero.toSmulZeroClass.{u1, u1} R R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (MulZeroClass.toSMulWithZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))))) r p)) (SMul.smul.{u2, u2} S (Polynomial.{u2} S _inst_2) (SMulZeroClass.toHasSmul.{u2, u2} S (Polynomial.{u2} S _inst_2) (Polynomial.zero.{u2} S _inst_2) (Polynomial.smulZeroClass.{u2, u2} S _inst_2 S (SMulWithZero.toSmulZeroClass.{u2, u2} S S (MulZeroClass.toHasZero.{u2} S (NonUnitalNonAssocSemiring.toMulZeroClass.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (MulZeroClass.toHasZero.{u2} S (NonUnitalNonAssocSemiring.toMulZeroClass.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (MulZeroClass.toSMulWithZero.{u2} S (NonUnitalNonAssocSemiring.toMulZeroClass.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))))) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f r) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (r : R), Eq.{succ u2} (Polynomial.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f (HSMul.hSMul.{u1, u1, u1} R (Polynomial.{u1} R _inst_1) (Polynomial.{u1} R _inst_1) (instHSMul.{u1, u1} R (Polynomial.{u1} R _inst_1) (SMulZeroClass.toSMul.{u1, u1} R (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1) (Polynomial.smulZeroClass.{u1, u1} R _inst_1 R (SMulWithZero.toSMulZeroClass.{u1, u1} R R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)) (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)) (MulZeroClass.toSMulWithZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))))))) r p)) (HSMul.hSMul.{u2, u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) r) (Polynomial.{u2} S _inst_2) (Polynomial.{u2} S _inst_2) (instHSMul.{u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) r) (Polynomial.{u2} S _inst_2) (SMulZeroClass.toSMul.{u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) r) (Polynomial.{u2} S _inst_2) (Polynomial.zero.{u2} S _inst_2) (Polynomial.smulZeroClass.{u2, u2} S _inst_2 ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) r) (SMulWithZero.toSMulZeroClass.{u2, u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) r) S (MonoidWithZero.toZero.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) r) (Semiring.toMonoidWithZero.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) r) _inst_2)) (MonoidWithZero.toZero.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)) (MulZeroClass.toSMulWithZero.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) r) (NonUnitalNonAssocSemiring.toMulZeroClass.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) r) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) r) (Semiring.toNonAssocSemiring.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) r) _inst_2)))))))) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f r) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p))
Case conversion may be inaccurate. Consider using '#align polynomial.map_smul Polynomial.map_smulₓ'. -/
@[simp]
protected theorem map_smul (r : R) : (r • p).map f = f r • p.map f := by
  rw [map, eval₂_smul, RingHom.comp_apply, C_mul']
#align polynomial.map_smul Polynomial.map_smul

#print Polynomial.mapRingHom /-
-- `map` is a ring-hom unconditionally, and theoretically the definition could be replaced,
-- but this turns out not to be easy because `p.map f` does not resolve to `polynomial.map`
-- if `map` is a `ring_hom` instead of a plain function; the elaborator does not try to coerce
-- to a function before trying field (dot) notation (this may be technically infeasible);
-- the relevant code is (both lines): https://github.com/leanprover-community/
-- lean/blob/487ac5d7e9b34800502e1ddf3c7c806c01cf9d51/src/frontends/lean/elaborator.cpp#L1876-L1913
/-- `polynomial.map` as a `ring_hom`. -/
def mapRingHom (f : R →+* S) : R[X] →+* S[X]
    where
  toFun := Polynomial.map f
  map_add' _ _ := Polynomial.map_add f
  map_zero' := Polynomial.map_zero f
  map_mul' _ _ := Polynomial.map_mul f
  map_one' := Polynomial.map_one f
#align polynomial.map_ring_hom Polynomial.mapRingHom
-/

/- warning: polynomial.coe_map_ring_hom -> Polynomial.coe_mapRingHom is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)), Eq.{max (succ u1) (succ u2)} ((Polynomial.{u1} R _inst_1) -> (Polynomial.{u2} S _inst_2)) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2))) (fun (_x : RingHom.{u1, u2} (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2))) => (Polynomial.{u1} R _inst_1) -> (Polynomial.{u2} S _inst_2)) (RingHom.hasCoeToFun.{u1, u2} (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2))) (Polynomial.mapRingHom.{u1, u2} R S _inst_1 _inst_2 f)) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f)
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)), Eq.{max (succ u1) (succ u2)} (forall (ᾰ : Polynomial.{u1} R _inst_1), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : Polynomial.{u1} R _inst_1) => Polynomial.{u2} S _inst_2) ᾰ) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2))) (Polynomial.{u1} R _inst_1) (fun (_x : Polynomial.{u1} R _inst_1) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : Polynomial.{u1} R _inst_1) => Polynomial.{u2} S _inst_2) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2))) (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) (NonUnitalNonAssocSemiring.toMul.{u2} (Polynomial.{u2} S _inst_2) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2)))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2))) (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2))) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2))) (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2)) (RingHom.instRingHomClassRingHom.{u1, u2} (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2)))))) (Polynomial.mapRingHom.{u1, u2} R S _inst_1 _inst_2 f)) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f)
Case conversion may be inaccurate. Consider using '#align polynomial.coe_map_ring_hom Polynomial.coe_mapRingHomₓ'. -/
@[simp]
theorem coe_mapRingHom (f : R →+* S) : ⇑(mapRingHom f) = map f :=
  rfl
#align polynomial.coe_map_ring_hom Polynomial.coe_mapRingHom

#print Polynomial.map_nat_cast /-
-- This is protected to not clash with the global `map_nat_cast`.
@[simp]
protected theorem map_nat_cast (n : ℕ) : (n : R[X]).map f = n :=
  map_natCast (mapRingHom f) n
#align polynomial.map_nat_cast Polynomial.map_nat_cast
-/

#print Polynomial.map_bit0 /-
@[simp]
protected theorem map_bit0 : (bit0 p).map f = bit0 (p.map f) :=
  map_bit0 (mapRingHom f) p
#align polynomial.map_bit0 Polynomial.map_bit0
-/

#print Polynomial.map_bit1 /-
@[simp]
protected theorem map_bit1 : (bit1 p).map f = bit1 (p.map f) :=
  map_bit1 (mapRingHom f) p
#align polynomial.map_bit1 Polynomial.map_bit1
-/

#print Polynomial.map_dvd /-
--TODO rename to `map_dvd_map`
theorem map_dvd (f : R →+* S) {x y : R[X]} : x ∣ y → x.map f ∣ y.map f :=
  (mapRingHom f).map_dvd
#align polynomial.map_dvd Polynomial.map_dvd
-/

/- warning: polynomial.coeff_map -> Polynomial.coeff_map is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (n : Nat), Eq.{succ u2} S (Polynomial.coeff.{u2} S _inst_2 (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p) n) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f (Polynomial.coeff.{u1} R _inst_1 p n))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (n : Nat), Eq.{succ u2} S (Polynomial.coeff.{u2} S _inst_2 (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p) n) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f (Polynomial.coeff.{u1} R _inst_1 p n))
Case conversion may be inaccurate. Consider using '#align polynomial.coeff_map Polynomial.coeff_mapₓ'. -/
@[simp]
theorem coeff_map (n : ℕ) : coeff (p.map f) n = f (coeff p n) :=
  by
  rw [map, eval₂, coeff_sum, Sum]
  conv_rhs => rw [← sum_C_mul_X_pow_eq p, coeff_sum, Sum, RingHom.map_sum]
  refine' Finset.sum_congr rfl fun x hx => _
  simp [Function.comp, coeff_C_mul_X_pow, f.map_mul]
  split_ifs <;> simp [f.map_zero]
#align polynomial.coeff_map Polynomial.coeff_map

/- warning: polynomial.map_equiv -> Polynomial.mapEquiv is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S], (RingEquiv.{u1, u2} R S (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (Distrib.toHasAdd.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (Distrib.toHasMul.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))) (Distrib.toHasAdd.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) -> (RingEquiv.{u1, u2} (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (Polynomial.mul'.{u1} R _inst_1) (Polynomial.add'.{u1} R _inst_1) (Polynomial.mul'.{u2} S _inst_2) (Polynomial.add'.{u2} S _inst_2))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S], (RingEquiv.{u1, u2} R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (Distrib.toAdd.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)))) (Distrib.toAdd.{u2} S (NonUnitalNonAssocSemiring.toDistrib.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) -> (RingEquiv.{u1, u2} (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (Polynomial.mul'.{u1} R _inst_1) (Polynomial.mul'.{u2} S _inst_2) (Polynomial.add'.{u1} R _inst_1) (Polynomial.add'.{u2} S _inst_2))
Case conversion may be inaccurate. Consider using '#align polynomial.map_equiv Polynomial.mapEquivₓ'. -/
/-- If `R` and `S` are isomorphic, then so are their polynomial rings. -/
@[simps]
def mapEquiv (e : R ≃+* S) : R[X] ≃+* S[X] :=
  RingEquiv.ofHomInv (mapRingHom (e : R →+* S)) (mapRingHom (e.symm : S →+* R)) (by ext <;> simp)
    (by ext <;> simp)
#align polynomial.map_equiv Polynomial.mapEquiv

#print Polynomial.map_map /-
theorem map_map [Semiring T] (g : S →+* T) (p : R[X]) : (p.map f).map g = p.map (g.comp f) :=
  ext (by simp [coeff_map])
#align polynomial.map_map Polynomial.map_map
-/

#print Polynomial.map_id /-
@[simp]
theorem map_id : p.map (RingHom.id _) = p := by simp [Polynomial.ext_iff, coeff_map]
#align polynomial.map_id Polynomial.map_id
-/

#print Polynomial.eval₂_eq_eval_map /-
theorem eval₂_eq_eval_map {x : S} : p.eval₂ f x = (p.map f).eval x :=
  by
  apply Polynomial.induction_on' p
  · intro p q hp hq
    simp [hp, hq]
  · intro n r
    simp
#align polynomial.eval₂_eq_eval_map Polynomial.eval₂_eq_eval_map
-/

/- warning: polynomial.map_injective -> Polynomial.map_injective is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)), (Function.Injective.{succ u1, succ u2} R S (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f)) -> (Function.Injective.{succ u1, succ u2} (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)), (Function.Injective.{succ u1, succ u2} R S (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f)) -> (Function.Injective.{succ u1, succ u2} (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f))
Case conversion may be inaccurate. Consider using '#align polynomial.map_injective Polynomial.map_injectiveₓ'. -/
theorem map_injective (hf : Function.Injective f) : Function.Injective (map f) := fun p q h =>
  ext fun m => hf <| by rw [← coeff_map f, ← coeff_map f, h]
#align polynomial.map_injective Polynomial.map_injective

/- warning: polynomial.map_surjective -> Polynomial.map_surjective is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)), (Function.Surjective.{succ u1, succ u2} R S (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f)) -> (Function.Surjective.{succ u1, succ u2} (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)), (Function.Surjective.{succ u1, succ u2} R S (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f)) -> (Function.Surjective.{succ u1, succ u2} (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f))
Case conversion may be inaccurate. Consider using '#align polynomial.map_surjective Polynomial.map_surjectiveₓ'. -/
theorem map_surjective (hf : Function.Surjective f) : Function.Surjective (map f) := fun p =>
  Polynomial.induction_on' p
    (fun p q hp hq =>
      let ⟨p', hp'⟩ := hp
      let ⟨q', hq'⟩ := hq
      ⟨p' + q', by rw [Polynomial.map_add f, hp', hq']⟩)
    fun n s =>
    let ⟨r, hr⟩ := hf s
    ⟨monomial n r, by rw [map_monomial f, hr]⟩
#align polynomial.map_surjective Polynomial.map_surjective

#print Polynomial.degree_map_le /-
theorem degree_map_le (p : R[X]) : degree (p.map f) ≤ degree p :=
  by
  apply (degree_le_iff_coeff_zero _ _).2 fun m hm => _
  rw [degree_lt_iff_coeff_zero] at hm
  simp [hm m le_rfl]
#align polynomial.degree_map_le Polynomial.degree_map_le
-/

#print Polynomial.natDegree_map_le /-
theorem natDegree_map_le (p : R[X]) : natDegree (p.map f) ≤ natDegree p :=
  natDegree_le_natDegree (degree_map_le f p)
#align polynomial.nat_degree_map_le Polynomial.natDegree_map_le
-/

variable {f}

/- warning: polynomial.map_eq_zero_iff -> Polynomial.map_eq_zero_iff is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] {f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)}, (Function.Injective.{succ u1, succ u2} R S (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f)) -> (Iff (Eq.{succ u2} (Polynomial.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p) (OfNat.ofNat.{u2} (Polynomial.{u2} S _inst_2) 0 (OfNat.mk.{u2} (Polynomial.{u2} S _inst_2) 0 (Zero.zero.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.zero.{u2} S _inst_2))))) (Eq.{succ u1} (Polynomial.{u1} R _inst_1) p (OfNat.ofNat.{u1} (Polynomial.{u1} R _inst_1) 0 (OfNat.mk.{u1} (Polynomial.{u1} R _inst_1) 0 (Zero.zero.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1))))))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] {f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)}, (Function.Injective.{succ u1, succ u2} R S (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f)) -> (Iff (Eq.{succ u2} (Polynomial.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p) (OfNat.ofNat.{u2} (Polynomial.{u2} S _inst_2) 0 (Zero.toOfNat0.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.zero.{u2} S _inst_2)))) (Eq.{succ u1} (Polynomial.{u1} R _inst_1) p (OfNat.ofNat.{u1} (Polynomial.{u1} R _inst_1) 0 (Zero.toOfNat0.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1)))))
Case conversion may be inaccurate. Consider using '#align polynomial.map_eq_zero_iff Polynomial.map_eq_zero_iffₓ'. -/
protected theorem map_eq_zero_iff (hf : Function.Injective f) : p.map f = 0 ↔ p = 0 :=
  map_eq_zero_iff (mapRingHom f) (map_injective f hf)
#align polynomial.map_eq_zero_iff Polynomial.map_eq_zero_iff

/- warning: polynomial.map_ne_zero_iff -> Polynomial.map_ne_zero_iff is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] {f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)}, (Function.Injective.{succ u1, succ u2} R S (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f)) -> (Iff (Ne.{succ u2} (Polynomial.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p) (OfNat.ofNat.{u2} (Polynomial.{u2} S _inst_2) 0 (OfNat.mk.{u2} (Polynomial.{u2} S _inst_2) 0 (Zero.zero.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.zero.{u2} S _inst_2))))) (Ne.{succ u1} (Polynomial.{u1} R _inst_1) p (OfNat.ofNat.{u1} (Polynomial.{u1} R _inst_1) 0 (OfNat.mk.{u1} (Polynomial.{u1} R _inst_1) 0 (Zero.zero.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1))))))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] {f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)}, (Function.Injective.{succ u1, succ u2} R S (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f)) -> (Iff (Ne.{succ u2} (Polynomial.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p) (OfNat.ofNat.{u2} (Polynomial.{u2} S _inst_2) 0 (Zero.toOfNat0.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.zero.{u2} S _inst_2)))) (Ne.{succ u1} (Polynomial.{u1} R _inst_1) p (OfNat.ofNat.{u1} (Polynomial.{u1} R _inst_1) 0 (Zero.toOfNat0.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.zero.{u1} R _inst_1)))))
Case conversion may be inaccurate. Consider using '#align polynomial.map_ne_zero_iff Polynomial.map_ne_zero_iffₓ'. -/
protected theorem map_ne_zero_iff (hf : Function.Injective f) : p.map f ≠ 0 ↔ p ≠ 0 :=
  (Polynomial.map_eq_zero_iff hf).Not
#align polynomial.map_ne_zero_iff Polynomial.map_ne_zero_iff

/- warning: polynomial.map_monic_eq_zero_iff -> Polynomial.map_monic_eq_zero_iff is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] {f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)}, (Polynomial.Monic.{u1} R _inst_1 p) -> (Iff (Eq.{succ u2} (Polynomial.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p) (OfNat.ofNat.{u2} (Polynomial.{u2} S _inst_2) 0 (OfNat.mk.{u2} (Polynomial.{u2} S _inst_2) 0 (Zero.zero.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.zero.{u2} S _inst_2))))) (forall (x : R), Eq.{succ u2} S (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f x) (OfNat.ofNat.{u2} S 0 (OfNat.mk.{u2} S 0 (Zero.zero.{u2} S (MulZeroClass.toHasZero.{u2} S (NonUnitalNonAssocSemiring.toMulZeroClass.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))))))))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] {f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)}, (Polynomial.Monic.{u1} R _inst_1 p) -> (Iff (Eq.{succ u2} (Polynomial.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p) (OfNat.ofNat.{u2} (Polynomial.{u2} S _inst_2) 0 (Zero.toOfNat0.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.zero.{u2} S _inst_2)))) (forall (x : R), Eq.{succ u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) x) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f x) (OfNat.ofNat.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) x) 0 (Zero.toOfNat0.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) x) (MonoidWithZero.toZero.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) x) (Semiring.toMonoidWithZero.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) x) _inst_2))))))
Case conversion may be inaccurate. Consider using '#align polynomial.map_monic_eq_zero_iff Polynomial.map_monic_eq_zero_iffₓ'. -/
theorem map_monic_eq_zero_iff (hp : p.Monic) : p.map f = 0 ↔ ∀ x, f x = 0 :=
  ⟨fun hfp x =>
    calc
      f x = f x * f p.leadingCoeff := by simp only [mul_one, hp.leading_coeff, f.map_one]
      _ = f x * (p.map f).coeff p.natDegree := (congr_arg _ (coeff_map _ _).symm)
      _ = 0 := by simp only [hfp, MulZeroClass.mul_zero, coeff_zero]
      ,
    fun h => ext fun n => by simp only [h, coeff_map, coeff_zero]⟩
#align polynomial.map_monic_eq_zero_iff Polynomial.map_monic_eq_zero_iff

#print Polynomial.map_monic_ne_zero /-
theorem map_monic_ne_zero (hp : p.Monic) [Nontrivial S] : p.map f ≠ 0 := fun h =>
  f.map_one_ne_zero ((map_monic_eq_zero_iff hp).mp h _)
#align polynomial.map_monic_ne_zero Polynomial.map_monic_ne_zero
-/

/- warning: polynomial.degree_map_eq_of_leading_coeff_ne_zero -> Polynomial.degree_map_eq_of_leadingCoeff_ne_zero is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)), (Ne.{succ u2} S (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f (Polynomial.leadingCoeff.{u1} R _inst_1 p)) (OfNat.ofNat.{u2} S 0 (OfNat.mk.{u2} S 0 (Zero.zero.{u2} S (MulZeroClass.toHasZero.{u2} S (NonUnitalNonAssocSemiring.toMulZeroClass.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))))))) -> (Eq.{1} (WithBot.{0} Nat) (Polynomial.degree.{u2} S _inst_2 (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p)) (Polynomial.degree.{u1} R _inst_1 p))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)), (Ne.{succ u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.leadingCoeff.{u1} R _inst_1 p)) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f (Polynomial.leadingCoeff.{u1} R _inst_1 p)) (OfNat.ofNat.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.leadingCoeff.{u1} R _inst_1 p)) 0 (Zero.toOfNat0.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.leadingCoeff.{u1} R _inst_1 p)) (MonoidWithZero.toZero.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.leadingCoeff.{u1} R _inst_1 p)) (Semiring.toMonoidWithZero.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.leadingCoeff.{u1} R _inst_1 p)) _inst_2))))) -> (Eq.{1} (WithBot.{0} Nat) (Polynomial.degree.{u2} S _inst_2 (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p)) (Polynomial.degree.{u1} R _inst_1 p))
Case conversion may be inaccurate. Consider using '#align polynomial.degree_map_eq_of_leading_coeff_ne_zero Polynomial.degree_map_eq_of_leadingCoeff_ne_zeroₓ'. -/
theorem degree_map_eq_of_leadingCoeff_ne_zero (f : R →+* S) (hf : f (leadingCoeff p) ≠ 0) :
    degree (p.map f) = degree p :=
  le_antisymm (degree_map_le f _) <|
    by
    have hp0 : p ≠ 0 := leadingCoeff_ne_zero.mp fun hp0 => hf (trans (congr_arg _ hp0) f.map_zero)
    rw [degree_eq_nat_degree hp0]
    refine' le_degree_of_ne_zero _
    rw [coeff_map]
    exact hf
#align polynomial.degree_map_eq_of_leading_coeff_ne_zero Polynomial.degree_map_eq_of_leadingCoeff_ne_zero

/- warning: polynomial.nat_degree_map_of_leading_coeff_ne_zero -> Polynomial.natDegree_map_of_leadingCoeff_ne_zero is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)), (Ne.{succ u2} S (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f (Polynomial.leadingCoeff.{u1} R _inst_1 p)) (OfNat.ofNat.{u2} S 0 (OfNat.mk.{u2} S 0 (Zero.zero.{u2} S (MulZeroClass.toHasZero.{u2} S (NonUnitalNonAssocSemiring.toMulZeroClass.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))))))) -> (Eq.{1} Nat (Polynomial.natDegree.{u2} S _inst_2 (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p)) (Polynomial.natDegree.{u1} R _inst_1 p))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)), (Ne.{succ u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.leadingCoeff.{u1} R _inst_1 p)) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f (Polynomial.leadingCoeff.{u1} R _inst_1 p)) (OfNat.ofNat.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.leadingCoeff.{u1} R _inst_1 p)) 0 (Zero.toOfNat0.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.leadingCoeff.{u1} R _inst_1 p)) (MonoidWithZero.toZero.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.leadingCoeff.{u1} R _inst_1 p)) (Semiring.toMonoidWithZero.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.leadingCoeff.{u1} R _inst_1 p)) _inst_2))))) -> (Eq.{1} Nat (Polynomial.natDegree.{u2} S _inst_2 (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p)) (Polynomial.natDegree.{u1} R _inst_1 p))
Case conversion may be inaccurate. Consider using '#align polynomial.nat_degree_map_of_leading_coeff_ne_zero Polynomial.natDegree_map_of_leadingCoeff_ne_zeroₓ'. -/
theorem natDegree_map_of_leadingCoeff_ne_zero (f : R →+* S) (hf : f (leadingCoeff p) ≠ 0) :
    natDegree (p.map f) = natDegree p :=
  natDegree_eq_of_degree_eq (degree_map_eq_of_leadingCoeff_ne_zero f hf)
#align polynomial.nat_degree_map_of_leading_coeff_ne_zero Polynomial.natDegree_map_of_leadingCoeff_ne_zero

/- warning: polynomial.leading_coeff_map_of_leading_coeff_ne_zero -> Polynomial.leadingCoeff_map_of_leadingCoeff_ne_zero is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)), (Ne.{succ u2} S (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f (Polynomial.leadingCoeff.{u1} R _inst_1 p)) (OfNat.ofNat.{u2} S 0 (OfNat.mk.{u2} S 0 (Zero.zero.{u2} S (MulZeroClass.toHasZero.{u2} S (NonUnitalNonAssocSemiring.toMulZeroClass.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)))))))) -> (Eq.{succ u2} S (Polynomial.leadingCoeff.{u2} S _inst_2 (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p)) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f (Polynomial.leadingCoeff.{u1} R _inst_1 p)))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)), (Ne.{succ u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.leadingCoeff.{u1} R _inst_1 p)) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f (Polynomial.leadingCoeff.{u1} R _inst_1 p)) (OfNat.ofNat.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.leadingCoeff.{u1} R _inst_1 p)) 0 (Zero.toOfNat0.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.leadingCoeff.{u1} R _inst_1 p)) (MonoidWithZero.toZero.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.leadingCoeff.{u1} R _inst_1 p)) (Semiring.toMonoidWithZero.{u2} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) (Polynomial.leadingCoeff.{u1} R _inst_1 p)) _inst_2))))) -> (Eq.{succ u2} S (Polynomial.leadingCoeff.{u2} S _inst_2 (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p)) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f (Polynomial.leadingCoeff.{u1} R _inst_1 p)))
Case conversion may be inaccurate. Consider using '#align polynomial.leading_coeff_map_of_leading_coeff_ne_zero Polynomial.leadingCoeff_map_of_leadingCoeff_ne_zeroₓ'. -/
theorem leadingCoeff_map_of_leadingCoeff_ne_zero (f : R →+* S) (hf : f (leadingCoeff p) ≠ 0) :
    leadingCoeff (p.map f) = f (leadingCoeff p) :=
  by
  unfold leading_coeff
  rw [coeff_map, nat_degree_map_of_leading_coeff_ne_zero f hf]
#align polynomial.leading_coeff_map_of_leading_coeff_ne_zero Polynomial.leadingCoeff_map_of_leadingCoeff_ne_zero

variable (f)

#print Polynomial.mapRingHom_id /-
@[simp]
theorem mapRingHom_id : mapRingHom (RingHom.id R) = RingHom.id R[X] :=
  RingHom.ext fun x => map_id
#align polynomial.map_ring_hom_id Polynomial.mapRingHom_id
-/

#print Polynomial.mapRingHom_comp /-
@[simp]
theorem mapRingHom_comp [Semiring T] (f : S →+* T) (g : R →+* S) :
    (mapRingHom f).comp (mapRingHom g) = mapRingHom (f.comp g) :=
  RingHom.ext <| Polynomial.map_map g f
#align polynomial.map_ring_hom_comp Polynomial.mapRingHom_comp
-/

#print Polynomial.map_list_prod /-
protected theorem map_list_prod (L : List R[X]) : L.Prod.map f = (L.map <| map f).Prod :=
  Eq.symm <| List.prod_hom _ (mapRingHom f).toMonoidHom
#align polynomial.map_list_prod Polynomial.map_list_prod
-/

#print Polynomial.map_pow /-
@[simp]
protected theorem map_pow (n : ℕ) : (p ^ n).map f = p.map f ^ n :=
  (mapRingHom f).map_pow _ _
#align polynomial.map_pow Polynomial.map_pow
-/

/- warning: polynomial.mem_map_srange -> Polynomial.mem_map_rangeS is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) {p : Polynomial.{u2} S _inst_2}, Iff (Membership.Mem.{u2, u2} (Polynomial.{u2} S _inst_2) (Subsemiring.{u2} (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2))) (SetLike.hasMem.{u2, u2} (Subsemiring.{u2} (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2))) (Polynomial.{u2} S _inst_2) (Subsemiring.setLike.{u2} (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2)))) p (RingHom.rangeS.{u1, u2} (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2)) (Polynomial.mapRingHom.{u1, u2} R S _inst_1 _inst_2 f))) (forall (n : Nat), Membership.Mem.{u2, u2} S (Subsemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (SetLike.hasMem.{u2, u2} (Subsemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) S (Subsemiring.setLike.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (Polynomial.coeff.{u2} S _inst_2 p n) (RingHom.rangeS.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) f))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) {p : Polynomial.{u2} S _inst_2}, Iff (Membership.mem.{u2, u2} (Polynomial.{u2} S _inst_2) (Subsemiring.{u2} (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2))) (SetLike.instMembership.{u2, u2} (Subsemiring.{u2} (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2))) (Polynomial.{u2} S _inst_2) (Subsemiring.instSetLikeSubsemiring.{u2} (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2)))) p (RingHom.rangeS.{u1, u2} (Polynomial.{u1} R _inst_1) (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2)) (Polynomial.mapRingHom.{u1, u2} R S _inst_1 _inst_2 f))) (forall (n : Nat), Membership.mem.{u2, u2} S (Subsemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (SetLike.instMembership.{u2, u2} (Subsemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) S (Subsemiring.instSetLikeSubsemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (Polynomial.coeff.{u2} S _inst_2 p n) (RingHom.rangeS.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) f))
Case conversion may be inaccurate. Consider using '#align polynomial.mem_map_srange Polynomial.mem_map_rangeSₓ'. -/
theorem mem_map_rangeS {p : S[X]} : p ∈ (mapRingHom f).srange ↔ ∀ n, p.coeff n ∈ f.srange :=
  by
  constructor
  · rintro ⟨p, rfl⟩ n
    rw [coe_map_ring_hom, coeff_map]
    exact Set.mem_range_self _
  · intro h
    rw [p.as_sum_range_C_mul_X_pow]
    refine' (map_ring_hom f).srange.sum_mem _
    intro i hi
    rcases h i with ⟨c, hc⟩
    use C c * X ^ i
    rw [coe_map_ring_hom, Polynomial.map_mul, map_C, hc, Polynomial.map_pow, map_X]
#align polynomial.mem_map_srange Polynomial.mem_map_rangeS

/- warning: polynomial.mem_map_range -> Polynomial.mem_map_range is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_3 : Ring.{u1} R] [_inst_4 : Ring.{u2} S] (f : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_3)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_4))) {p : Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_4)}, Iff (Membership.Mem.{u2, u2} (Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_4)) (Subring.{u2} (Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_4)) (Polynomial.ring.{u2} S _inst_4)) (SetLike.hasMem.{u2, u2} (Subring.{u2} (Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_4)) (Polynomial.ring.{u2} S _inst_4)) (Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_4)) (Subring.setLike.{u2} (Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_4)) (Polynomial.ring.{u2} S _inst_4))) p (RingHom.range.{u1, u2} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_3)) (Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_4)) (Polynomial.ring.{u1} R _inst_3) (Polynomial.ring.{u2} S _inst_4) (Polynomial.mapRingHom.{u1, u2} R S (Ring.toSemiring.{u1} R _inst_3) (Ring.toSemiring.{u2} S _inst_4) f))) (forall (n : Nat), Membership.Mem.{u2, u2} S (Subring.{u2} S _inst_4) (SetLike.hasMem.{u2, u2} (Subring.{u2} S _inst_4) S (Subring.setLike.{u2} S _inst_4)) (Polynomial.coeff.{u2} S (Ring.toSemiring.{u2} S _inst_4) p n) (RingHom.range.{u1, u2} R S _inst_3 _inst_4 f))
but is expected to have type
  forall {R : Type.{u2}} {S : Type.{u1}} [_inst_3 : Ring.{u2} R] [_inst_4 : Ring.{u1} S] (f : RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_3)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) {p : Polynomial.{u1} S (Ring.toSemiring.{u1} S _inst_4)}, Iff (Membership.mem.{u1, u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S _inst_4)) (Subring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S _inst_4)) (Polynomial.ring.{u1} S _inst_4)) (SetLike.instMembership.{u1, u1} (Subring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S _inst_4)) (Polynomial.ring.{u1} S _inst_4)) (Polynomial.{u1} S (Ring.toSemiring.{u1} S _inst_4)) (Subring.instSetLikeSubring.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S _inst_4)) (Polynomial.ring.{u1} S _inst_4))) p (RingHom.range.{u2, u1} (Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_3)) (Polynomial.{u1} S (Ring.toSemiring.{u1} S _inst_4)) (Polynomial.ring.{u2} R _inst_3) (Polynomial.ring.{u1} S _inst_4) (Polynomial.mapRingHom.{u2, u1} R S (Ring.toSemiring.{u2} R _inst_3) (Ring.toSemiring.{u1} S _inst_4) f))) (forall (n : Nat), Membership.mem.{u1, u1} S (Subring.{u1} S _inst_4) (SetLike.instMembership.{u1, u1} (Subring.{u1} S _inst_4) S (Subring.instSetLikeSubring.{u1} S _inst_4)) (Polynomial.coeff.{u1} S (Ring.toSemiring.{u1} S _inst_4) p n) (RingHom.range.{u2, u1} R S _inst_3 _inst_4 f))
Case conversion may be inaccurate. Consider using '#align polynomial.mem_map_range Polynomial.mem_map_rangeₓ'. -/
theorem mem_map_range {R S : Type _} [Ring R] [Ring S] (f : R →+* S) {p : S[X]} :
    p ∈ (mapRingHom f).range ↔ ∀ n, p.coeff n ∈ f.range :=
  mem_map_rangeS f
#align polynomial.mem_map_range Polynomial.mem_map_range

#print Polynomial.eval₂_map /-
theorem eval₂_map [Semiring T] (g : S →+* T) (x : T) : (p.map f).eval₂ g x = p.eval₂ (g.comp f) x :=
  by rw [eval₂_eq_eval_map, eval₂_eq_eval_map, map_map]
#align polynomial.eval₂_map Polynomial.eval₂_map
-/

#print Polynomial.eval_map /-
theorem eval_map (x : S) : (p.map f).eval x = p.eval₂ f x :=
  (eval₂_eq_eval_map f).symm
#align polynomial.eval_map Polynomial.eval_map
-/

/- warning: polynomial.map_sum -> Polynomial.map_sum is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) {ι : Type.{u3}} (g : ι -> (Polynomial.{u1} R _inst_1)) (s : Finset.{u3} ι), Eq.{succ u2} (Polynomial.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f (Finset.sum.{u1, u3} (Polynomial.{u1} R _inst_1) ι (NonUnitalNonAssocSemiring.toAddCommMonoid.{u1} (Polynomial.{u1} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R _inst_1) (Polynomial.semiring.{u1} R _inst_1)))) s (fun (i : ι) => g i))) (Finset.sum.{u2, u3} (Polynomial.{u2} S _inst_2) ι (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} (Polynomial.{u2} S _inst_2) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} S _inst_2) (Polynomial.semiring.{u2} S _inst_2)))) s (fun (i : ι) => Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f (g i)))
but is expected to have type
  forall {R : Type.{u2}} {S : Type.{u3}} [_inst_1 : Semiring.{u2} R] [_inst_2 : Semiring.{u3} S] (f : RingHom.{u2, u3} R S (Semiring.toNonAssocSemiring.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u3} S _inst_2)) {ι : Type.{u1}} (g : ι -> (Polynomial.{u2} R _inst_1)) (s : Finset.{u1} ι), Eq.{succ u3} (Polynomial.{u3} S _inst_2) (Polynomial.map.{u2, u3} R S _inst_1 _inst_2 f (Finset.sum.{u2, u1} (Polynomial.{u2} R _inst_1) ι (NonUnitalNonAssocSemiring.toAddCommMonoid.{u2} (Polynomial.{u2} R _inst_1) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} (Polynomial.{u2} R _inst_1) (Semiring.toNonAssocSemiring.{u2} (Polynomial.{u2} R _inst_1) (Polynomial.semiring.{u2} R _inst_1)))) s (fun (i : ι) => g i))) (Finset.sum.{u3, u1} (Polynomial.{u3} S _inst_2) ι (NonUnitalNonAssocSemiring.toAddCommMonoid.{u3} (Polynomial.{u3} S _inst_2) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} (Polynomial.{u3} S _inst_2) (Semiring.toNonAssocSemiring.{u3} (Polynomial.{u3} S _inst_2) (Polynomial.semiring.{u3} S _inst_2)))) s (fun (i : ι) => Polynomial.map.{u2, u3} R S _inst_1 _inst_2 f (g i)))
Case conversion may be inaccurate. Consider using '#align polynomial.map_sum Polynomial.map_sumₓ'. -/
protected theorem map_sum {ι : Type _} (g : ι → R[X]) (s : Finset ι) :
    (∑ i in s, g i).map f = ∑ i in s, (g i).map f :=
  (mapRingHom f).map_sum _ _
#align polynomial.map_sum Polynomial.map_sum

#print Polynomial.map_comp /-
theorem map_comp (p q : R[X]) : map f (p.comp q) = (map f p).comp (map f q) :=
  Polynomial.induction_on p (by simp only [map_C, forall_const, C_comp, eq_self_iff_true])
    (by
      simp (config := { contextual := true }) only [Polynomial.map_add, add_comp, forall_const,
        imp_true_iff, eq_self_iff_true])
    (by
      simp (config := { contextual := true }) only [pow_succ', ← mul_assoc, comp, forall_const,
        eval₂_mul_X, imp_true_iff, eq_self_iff_true, map_X, Polynomial.map_mul])
#align polynomial.map_comp Polynomial.map_comp
-/

/- warning: polynomial.eval_zero_map -> Polynomial.eval_zero_map is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (p : Polynomial.{u1} R _inst_1), Eq.{succ u2} S (Polynomial.eval.{u2} S _inst_2 (OfNat.ofNat.{u2} S 0 (OfNat.mk.{u2} S 0 (Zero.zero.{u2} S (MulZeroClass.toHasZero.{u2} S (NonUnitalNonAssocSemiring.toMulZeroClass.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))))) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p)) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f (Polynomial.eval.{u1} R _inst_1 (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))))) p))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (p : Polynomial.{u1} R _inst_1), Eq.{succ u2} S (Polynomial.eval.{u2} S _inst_2 (OfNat.ofNat.{u2} S 0 (Zero.toOfNat0.{u2} S (MonoidWithZero.toZero.{u2} S (Semiring.toMonoidWithZero.{u2} S _inst_2)))) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p)) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f (Polynomial.eval.{u1} R _inst_1 (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (MonoidWithZero.toZero.{u1} R (Semiring.toMonoidWithZero.{u1} R _inst_1)))) p))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_zero_map Polynomial.eval_zero_mapₓ'. -/
@[simp]
theorem eval_zero_map (f : R →+* S) (p : R[X]) : (p.map f).eval 0 = f (p.eval 0) := by
  simp [← coeff_zero_eq_eval_zero]
#align polynomial.eval_zero_map Polynomial.eval_zero_map

/- warning: polynomial.eval_one_map -> Polynomial.eval_one_map is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (p : Polynomial.{u1} R _inst_1), Eq.{succ u2} S (Polynomial.eval.{u2} S _inst_2 (OfNat.ofNat.{u2} S 1 (OfNat.mk.{u2} S 1 (One.one.{u2} S (AddMonoidWithOne.toOne.{u2} S (AddCommMonoidWithOne.toAddMonoidWithOne.{u2} S (NonAssocSemiring.toAddCommMonoidWithOne.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))))) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p)) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f (Polynomial.eval.{u1} R _inst_1 (OfNat.ofNat.{u1} R 1 (OfNat.mk.{u1} R 1 (One.one.{u1} R (AddMonoidWithOne.toOne.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))))) p))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (p : Polynomial.{u1} R _inst_1), Eq.{succ u2} S (Polynomial.eval.{u2} S _inst_2 (OfNat.ofNat.{u2} S 1 (One.toOfNat1.{u2} S (Semiring.toOne.{u2} S _inst_2))) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p)) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f (Polynomial.eval.{u1} R _inst_1 (OfNat.ofNat.{u1} R 1 (One.toOfNat1.{u1} R (Semiring.toOne.{u1} R _inst_1))) p))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_one_map Polynomial.eval_one_mapₓ'. -/
@[simp]
theorem eval_one_map (f : R →+* S) (p : R[X]) : (p.map f).eval 1 = f (p.eval 1) :=
  by
  apply Polynomial.induction_on' p
  · intro p q hp hq
    simp only [hp, hq, Polynomial.map_add, RingHom.map_add, eval_add]
  · intro n r
    simp only [one_pow, mul_one, eval_monomial, map_monomial]
#align polynomial.eval_one_map Polynomial.eval_one_map

/- warning: polynomial.eval_nat_cast_map -> Polynomial.eval_nat_cast_map is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (p : Polynomial.{u1} R _inst_1) (n : Nat), Eq.{succ u2} S (Polynomial.eval.{u2} S _inst_2 ((fun (a : Type) (b : Type.{u2}) [self : HasLiftT.{1, succ u2} a b] => self.0) Nat S (HasLiftT.mk.{1, succ u2} Nat S (CoeTCₓ.coe.{1, succ u2} Nat S (Nat.castCoe.{u2} S (AddMonoidWithOne.toNatCast.{u2} S (AddCommMonoidWithOne.toAddMonoidWithOne.{u2} S (NonAssocSemiring.toAddCommMonoidWithOne.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))))))) n) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p)) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f (Polynomial.eval.{u1} R _inst_1 ((fun (a : Type) (b : Type.{u1}) [self : HasLiftT.{1, succ u1} a b] => self.0) Nat R (HasLiftT.mk.{1, succ u1} Nat R (CoeTCₓ.coe.{1, succ u1} Nat R (Nat.castCoe.{u1} R (AddMonoidWithOne.toNatCast.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))))))) n) p))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (p : Polynomial.{u1} R _inst_1) (n : Nat), Eq.{succ u2} S (Polynomial.eval.{u2} S _inst_2 (Nat.cast.{u2} S (Semiring.toNatCast.{u2} S _inst_2) n) (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p)) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f (Polynomial.eval.{u1} R _inst_1 (Nat.cast.{u1} R (Semiring.toNatCast.{u1} R _inst_1) n) p))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_nat_cast_map Polynomial.eval_nat_cast_mapₓ'. -/
@[simp]
theorem eval_nat_cast_map (f : R →+* S) (p : R[X]) (n : ℕ) : (p.map f).eval n = f (p.eval n) :=
  by
  apply Polynomial.induction_on' p
  · intro p q hp hq
    simp only [hp, hq, Polynomial.map_add, RingHom.map_add, eval_add]
  · intro n r
    simp only [map_natCast f, eval_monomial, map_monomial, f.map_pow, f.map_mul]
#align polynomial.eval_nat_cast_map Polynomial.eval_nat_cast_map

/- warning: polynomial.eval_int_cast_map -> Polynomial.eval_int_cast_map is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_3 : Ring.{u1} R] [_inst_4 : Ring.{u2} S] (f : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_3)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_4))) (p : Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_3)) (i : Int), Eq.{succ u2} S (Polynomial.eval.{u2} S (Ring.toSemiring.{u2} S _inst_4) ((fun (a : Type) (b : Type.{u2}) [self : HasLiftT.{1, succ u2} a b] => self.0) Int S (HasLiftT.mk.{1, succ u2} Int S (CoeTCₓ.coe.{1, succ u2} Int S (Int.castCoe.{u2} S (AddGroupWithOne.toHasIntCast.{u2} S (AddCommGroupWithOne.toAddGroupWithOne.{u2} S (Ring.toAddCommGroupWithOne.{u2} S _inst_4)))))) i) (Polynomial.map.{u1, u2} R S (Ring.toSemiring.{u1} R _inst_3) (Ring.toSemiring.{u2} S _inst_4) f p)) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_3)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_4))) (fun (_x : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_3)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_4))) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_3)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_4))) f (Polynomial.eval.{u1} R (Ring.toSemiring.{u1} R _inst_3) ((fun (a : Type) (b : Type.{u1}) [self : HasLiftT.{1, succ u1} a b] => self.0) Int R (HasLiftT.mk.{1, succ u1} Int R (CoeTCₓ.coe.{1, succ u1} Int R (Int.castCoe.{u1} R (AddGroupWithOne.toHasIntCast.{u1} R (AddCommGroupWithOne.toAddGroupWithOne.{u1} R (Ring.toAddCommGroupWithOne.{u1} R _inst_3)))))) i) p))
but is expected to have type
  forall {R : Type.{u2}} {S : Type.{u1}} [_inst_3 : Ring.{u2} R] [_inst_4 : Ring.{u1} S] (f : RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_3)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) (p : Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_3)) (i : Int), Eq.{succ u1} S (Polynomial.eval.{u1} S (Ring.toSemiring.{u1} S _inst_4) (Int.cast.{u1} S (Ring.toIntCast.{u1} S _inst_4) i) (Polynomial.map.{u2, u1} R S (Ring.toSemiring.{u2} R _inst_3) (Ring.toSemiring.{u1} S _inst_4) f p)) (FunLike.coe.{max (succ u2) (succ u1), succ u2, succ u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_3)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_3)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) R S (NonUnitalNonAssocSemiring.toMul.{u2} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_3)))) (NonUnitalNonAssocSemiring.toMul.{u1} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4)))) (NonUnitalRingHomClass.toMulHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_3)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} R (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_3))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} S (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) (RingHomClass.toNonUnitalRingHomClass.{max u2 u1, u2, u1} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_3)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4))) R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_3)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4)) (RingHom.instRingHomClassRingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_3)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_4)))))) f (Polynomial.eval.{u2} R (Ring.toSemiring.{u2} R _inst_3) (Int.cast.{u2} R (Ring.toIntCast.{u2} R _inst_3) i) p))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_int_cast_map Polynomial.eval_int_cast_mapₓ'. -/
@[simp]
theorem eval_int_cast_map {R S : Type _} [Ring R] [Ring S] (f : R →+* S) (p : R[X]) (i : ℤ) :
    (p.map f).eval i = f (p.eval i) :=
  by
  apply Polynomial.induction_on' p
  · intro p q hp hq
    simp only [hp, hq, Polynomial.map_add, RingHom.map_add, eval_add]
  · intro n r
    simp only [map_intCast, eval_monomial, map_monomial, map_pow, map_mul]
#align polynomial.eval_int_cast_map Polynomial.eval_int_cast_map

end Map

/-!
we have made `eval₂` irreducible from the start.

Perhaps we can make also `eval`, `comp`, and `map` irreducible too?
-/

section HomEval₂

variable [Semiring S] [Semiring T] (f : R →+* S) (g : S →+* T) (p)

/- warning: polynomial.hom_eval₂ -> Polynomial.hom_eval₂ is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} {T : Type.{u3}} [_inst_1 : Semiring.{u1} R] (p : Polynomial.{u1} R _inst_1) [_inst_2 : Semiring.{u2} S] [_inst_3 : Semiring.{u3} T] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (g : RingHom.{u2, u3} S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3)) (x : S), Eq.{succ u3} T (coeFn.{max (succ u2) (succ u3), max (succ u2) (succ u3)} (RingHom.{u2, u3} S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3)) (fun (_x : RingHom.{u2, u3} S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3)) => S -> T) (RingHom.hasCoeToFun.{u2, u3} S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3)) g (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p)) (Polynomial.eval₂.{u1, u3} R T _inst_1 _inst_3 (RingHom.comp.{u1, u2, u3} R S T (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3) g f) (coeFn.{max (succ u2) (succ u3), max (succ u2) (succ u3)} (RingHom.{u2, u3} S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3)) (fun (_x : RingHom.{u2, u3} S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3)) => S -> T) (RingHom.hasCoeToFun.{u2, u3} S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3)) g x) p)
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} {T : Type.{u3}} [_inst_1 : Semiring.{u1} R] (p : Polynomial.{u1} R _inst_1) [_inst_2 : Semiring.{u2} S] [_inst_3 : Semiring.{u3} T] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (g : RingHom.{u2, u3} S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3)) (x : S), Eq.{succ u3} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : S) => T) (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p)) (FunLike.coe.{max (succ u2) (succ u3), succ u2, succ u3} (RingHom.{u2, u3} S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3)) S (fun (_x : S) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : S) => T) _x) (MulHomClass.toFunLike.{max u2 u3, u2, u3} (RingHom.{u2, u3} S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3)) S T (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalNonAssocSemiring.toMul.{u3} T (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} T (Semiring.toNonAssocSemiring.{u3} T _inst_3))) (NonUnitalRingHomClass.toMulHomClass.{max u2 u3, u2, u3} (RingHom.{u2, u3} S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3)) S T (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} T (Semiring.toNonAssocSemiring.{u3} T _inst_3)) (RingHomClass.toNonUnitalRingHomClass.{max u2 u3, u2, u3} (RingHom.{u2, u3} S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3)) S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3) (RingHom.instRingHomClassRingHom.{u2, u3} S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3))))) g (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f x p)) (Polynomial.eval₂.{u1, u3} R T _inst_1 _inst_3 (RingHom.comp.{u1, u2, u3} R S T (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3) g f) (FunLike.coe.{max (succ u2) (succ u3), succ u2, succ u3} (RingHom.{u2, u3} S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3)) S (fun (_x : S) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : S) => T) _x) (MulHomClass.toFunLike.{max u2 u3, u2, u3} (RingHom.{u2, u3} S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3)) S T (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalNonAssocSemiring.toMul.{u3} T (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} T (Semiring.toNonAssocSemiring.{u3} T _inst_3))) (NonUnitalRingHomClass.toMulHomClass.{max u2 u3, u2, u3} (RingHom.{u2, u3} S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3)) S T (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u3} T (Semiring.toNonAssocSemiring.{u3} T _inst_3)) (RingHomClass.toNonUnitalRingHomClass.{max u2 u3, u2, u3} (RingHom.{u2, u3} S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3)) S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3) (RingHom.instRingHomClassRingHom.{u2, u3} S T (Semiring.toNonAssocSemiring.{u2} S _inst_2) (Semiring.toNonAssocSemiring.{u3} T _inst_3))))) g x) p)
Case conversion may be inaccurate. Consider using '#align polynomial.hom_eval₂ Polynomial.hom_eval₂ₓ'. -/
theorem hom_eval₂ (x : S) : g (p.eval₂ f x) = p.eval₂ (g.comp f) (g x) := by
  rw [← eval₂_map, eval₂_at_apply, eval_map]
#align polynomial.hom_eval₂ Polynomial.hom_eval₂

end HomEval₂

end Semiring

section CommSemiring

section Eval

section

variable [Semiring R] {p q : R[X]} {x : R} [Semiring S] (f : R →+* S)

/- warning: polynomial.eval₂_hom -> Polynomial.eval₂_hom is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : R), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f x) p) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f (Polynomial.eval.{u1} R _inst_1 x p))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] {p : Polynomial.{u1} R _inst_1} [_inst_2 : Semiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (x : R), Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S _inst_1 _inst_2 f (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f x) p) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f (Polynomial.eval.{u1} R _inst_1 x p))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_hom Polynomial.eval₂_homₓ'. -/
theorem eval₂_hom (x : R) : p.eval₂ f (f x) = f (p.eval x) :=
  RingHom.comp_id f ▸ (hom_eval₂ p (RingHom.id R) f x).symm
#align polynomial.eval₂_hom Polynomial.eval₂_hom

end

section

variable [Semiring R] {p q : R[X]} {x : R} [CommSemiring S] (f : R →+* S)

#print Polynomial.eval₂_comp /-
theorem eval₂_comp {x : S} : eval₂ f x (p.comp q) = eval₂ f (eval₂ f x q) p := by
  rw [comp, p.as_sum_range] <;> simp [eval₂_finset_sum, eval₂_pow]
#align polynomial.eval₂_comp Polynomial.eval₂_comp
-/

#print Polynomial.iterate_comp_eval₂ /-
@[simp]
theorem iterate_comp_eval₂ (k : ℕ) (t : S) :
    eval₂ f t ((p.comp^[k]) q) = ((fun x => eval₂ f x p)^[k]) (eval₂ f t q) :=
  by
  induction' k with k IH
  · simp
  · rw [Function.iterate_succ_apply', Function.iterate_succ_apply', eval₂_comp, IH]
#align polynomial.iterate_comp_eval₂ Polynomial.iterate_comp_eval₂
-/

end

section

variable [CommSemiring R] {p q : R[X]} {x : R} [CommSemiring S] (f : R →+* S)

/- warning: polynomial.eval_mul -> Polynomial.eval_mul is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommSemiring.{u1} R] {p : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)} {q : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)} {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (instHMul.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.mul'.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) p q)) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))))) (Polynomial.eval.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) x p) (Polynomial.eval.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) x q))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommSemiring.{u1} R] {p : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)} {q : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)} {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) x (HMul.hMul.{u1, u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (instHMul.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.mul'.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) p q)) (HMul.hMul.{u1, u1, u1} R R R (instHMul.{u1} R (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))) (Polynomial.eval.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) x p) (Polynomial.eval.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) x q))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_mul Polynomial.eval_mulₓ'. -/
@[simp]
theorem eval_mul : (p * q).eval x = p.eval x * q.eval x :=
  eval₂_mul _ _
#align polynomial.eval_mul Polynomial.eval_mul

#print Polynomial.evalRingHom /-
/-- `eval r`, regarded as a ring homomorphism from `R[X]` to `R`. -/
def evalRingHom : R → R[X] →+* R :=
  eval₂RingHom (RingHom.id _)
#align polynomial.eval_ring_hom Polynomial.evalRingHom
-/

/- warning: polynomial.coe_eval_ring_hom -> Polynomial.coe_evalRingHom is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommSemiring.{u1} R] (r : R), Eq.{succ u1} ((fun (_x : RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) R (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) => (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) -> R) (Polynomial.evalRingHom.{u1} R _inst_1 r)) (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) R (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (fun (_x : RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) R (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) => (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) -> R) (RingHom.hasCoeToFun.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) R (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Polynomial.evalRingHom.{u1} R _inst_1 r)) (Polynomial.eval.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) r)
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommSemiring.{u1} R] (r : R), Eq.{succ u1} (forall (a : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) => R) a) (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) R (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (fun (_x : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) => R) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) R (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) R (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) R (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) R (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) R (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (RingHom.instRingHomClassRingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) R (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))))) (Polynomial.evalRingHom.{u1} R _inst_1 r)) (Polynomial.eval.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) r)
Case conversion may be inaccurate. Consider using '#align polynomial.coe_eval_ring_hom Polynomial.coe_evalRingHomₓ'. -/
@[simp]
theorem coe_evalRingHom (r : R) : (evalRingHom r : R[X] → R) = eval r :=
  rfl
#align polynomial.coe_eval_ring_hom Polynomial.coe_evalRingHom

#print Polynomial.evalRingHom_zero /-
theorem evalRingHom_zero : evalRingHom 0 = constantCoeff :=
  FunLike.ext _ _ fun p => p.coeff_zero_eq_eval_zero.symm
#align polynomial.eval_ring_hom_zero Polynomial.evalRingHom_zero
-/

#print Polynomial.eval_pow /-
@[simp]
theorem eval_pow (n : ℕ) : (p ^ n).eval x = p.eval x ^ n :=
  eval₂_pow _ _ _
#align polynomial.eval_pow Polynomial.eval_pow
-/

#print Polynomial.eval_comp /-
@[simp]
theorem eval_comp : (p.comp q).eval x = p.eval (q.eval x) :=
  by
  apply Polynomial.induction_on' p
  · intro r s hr hs
    simp [add_comp, hr, hs]
  · intro n a
    simp
#align polynomial.eval_comp Polynomial.eval_comp
-/

@[simp]
theorem iterate_comp_eval :
    ∀ (k : ℕ) (t : R), ((p.comp^[k]) q).eval t = ((fun x => p.eval x)^[k]) (q.eval t) :=
  iterate_comp_eval₂ _
#align polynomial.iterate_comp_eval Polynomial.iterate_comp_eval

#print Polynomial.compRingHom /-
/-- `comp p`, regarded as a ring homomorphism from `R[X]` to itself. -/
def compRingHom : R[X] → R[X] →+* R[X] :=
  eval₂RingHom C
#align polynomial.comp_ring_hom Polynomial.compRingHom
-/

/- warning: polynomial.coe_comp_ring_hom -> Polynomial.coe_compRingHom is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommSemiring.{u1} R] (q : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)), Eq.{succ u1} ((fun (_x : RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) => (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) -> (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Polynomial.compRingHom.{u1} R _inst_1 q)) (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (fun (_x : RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) => (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) -> (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (RingHom.hasCoeToFun.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (Polynomial.compRingHom.{u1} R _inst_1 q)) (fun (p : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) => Polynomial.comp.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) p q)
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommSemiring.{u1} R] (q : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)), Eq.{succ u1} (forall (a : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)), (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) => Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) a) (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (fun (_x : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) => Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (RingHom.instRingHomClassRingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))))) (Polynomial.compRingHom.{u1} R _inst_1 q)) (fun (p : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) => Polynomial.comp.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) p q)
Case conversion may be inaccurate. Consider using '#align polynomial.coe_comp_ring_hom Polynomial.coe_compRingHomₓ'. -/
@[simp]
theorem coe_compRingHom (q : R[X]) : (compRingHom q : R[X] → R[X]) = fun p => comp p q :=
  rfl
#align polynomial.coe_comp_ring_hom Polynomial.coe_compRingHom

/- warning: polynomial.coe_comp_ring_hom_apply -> Polynomial.coe_compRingHom_apply is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommSemiring.{u1} R] (p : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (q : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)), Eq.{succ u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (fun (_x : RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) => (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) -> (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (RingHom.hasCoeToFun.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (Polynomial.compRingHom.{u1} R _inst_1 q) p) (Polynomial.comp.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) p q)
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommSemiring.{u1} R] (p : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (q : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)), Eq.{succ u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) => Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) p) (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (fun (_x : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) => Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (RingHom.instRingHomClassRingHom.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))))) (Polynomial.compRingHom.{u1} R _inst_1 q) p) (Polynomial.comp.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) p q)
Case conversion may be inaccurate. Consider using '#align polynomial.coe_comp_ring_hom_apply Polynomial.coe_compRingHom_applyₓ'. -/
theorem coe_compRingHom_apply (p q : R[X]) : (compRingHom q : R[X] → R[X]) p = comp p q :=
  rfl
#align polynomial.coe_comp_ring_hom_apply Polynomial.coe_compRingHom_apply

#print Polynomial.root_mul_left_of_isRoot /-
theorem root_mul_left_of_isRoot (p : R[X]) {q : R[X]} : IsRoot q a → IsRoot (p * q) a := fun H => by
  rw [is_root, eval_mul, is_root.def.1 H, MulZeroClass.mul_zero]
#align polynomial.root_mul_left_of_is_root Polynomial.root_mul_left_of_isRoot
-/

#print Polynomial.root_mul_right_of_isRoot /-
theorem root_mul_right_of_isRoot {p : R[X]} (q : R[X]) : IsRoot p a → IsRoot (p * q) a := fun H =>
  by rw [is_root, eval_mul, is_root.def.1 H, MulZeroClass.zero_mul]
#align polynomial.root_mul_right_of_is_root Polynomial.root_mul_right_of_isRoot
-/

#print Polynomial.eval₂_multiset_prod /-
theorem eval₂_multiset_prod (s : Multiset R[X]) (x : S) :
    eval₂ f x s.Prod = (s.map (eval₂ f x)).Prod :=
  map_multiset_prod (eval₂RingHom f x) s
#align polynomial.eval₂_multiset_prod Polynomial.eval₂_multiset_prod
-/

#print Polynomial.eval₂_finset_prod /-
theorem eval₂_finset_prod (s : Finset ι) (g : ι → R[X]) (x : S) :
    (∏ i in s, g i).eval₂ f x = ∏ i in s, (g i).eval₂ f x :=
  map_prod (eval₂RingHom f x) _ _
#align polynomial.eval₂_finset_prod Polynomial.eval₂_finset_prod
-/

/- warning: polynomial.eval_list_prod -> Polynomial.eval_list_prod is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommSemiring.{u1} R] (l : List.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (x : R), Eq.{succ u1} R (Polynomial.eval.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) x (List.prod.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.mul'.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.hasOne.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) l)) (List.prod.{u1} R (Distrib.toHasMul.{u1} R (NonUnitalNonAssocSemiring.toDistrib.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))) (AddMonoidWithOne.toOne.{u1} R (AddCommMonoidWithOne.toAddMonoidWithOne.{u1} R (NonAssocSemiring.toAddCommMonoidWithOne.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))) (List.map.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) R (Polynomial.eval.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) x) l))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommSemiring.{u1} R] (l : List.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (x : R), Eq.{succ u1} R (Polynomial.eval.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) x (List.prod.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.mul'.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.one.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) l)) (List.prod.{u1} R (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (Semiring.toOne.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (List.map.{u1, u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) R (Polynomial.eval.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) x) l))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_list_prod Polynomial.eval_list_prodₓ'. -/
/-- Polynomial evaluation commutes with `list.prod`
-/
theorem eval_list_prod (l : List R[X]) (x : R) : eval x l.Prod = (l.map (eval x)).Prod :=
  (evalRingHom x).map_list_prod l
#align polynomial.eval_list_prod Polynomial.eval_list_prod

#print Polynomial.eval_multiset_prod /-
/-- Polynomial evaluation commutes with `multiset.prod`
-/
theorem eval_multiset_prod (s : Multiset R[X]) (x : R) : eval x s.Prod = (s.map (eval x)).Prod :=
  (evalRingHom x).map_multiset_prod s
#align polynomial.eval_multiset_prod Polynomial.eval_multiset_prod
-/

/- warning: polynomial.eval_prod -> Polynomial.eval_prod is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommSemiring.{u1} R] {ι : Type.{u2}} (s : Finset.{u2} ι) (p : ι -> (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (x : R), Eq.{succ u1} R (Polynomial.eval.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) x (Finset.prod.{u1, u2} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) ι (CommSemiring.toCommMonoid.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.commSemiring.{u1} R _inst_1)) s (fun (j : ι) => p j))) (Finset.prod.{u1, u2} R ι (CommSemiring.toCommMonoid.{u1} R _inst_1) s (fun (j : ι) => Polynomial.eval.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) x (p j)))
but is expected to have type
  forall {R : Type.{u2}} [_inst_1 : CommSemiring.{u2} R] {ι : Type.{u1}} (s : Finset.{u1} ι) (p : ι -> (Polynomial.{u2} R (CommSemiring.toSemiring.{u2} R _inst_1))) (x : R), Eq.{succ u2} R (Polynomial.eval.{u2} R (CommSemiring.toSemiring.{u2} R _inst_1) x (Finset.prod.{u2, u1} (Polynomial.{u2} R (CommSemiring.toSemiring.{u2} R _inst_1)) ι (CommSemiring.toCommMonoid.{u2} (Polynomial.{u2} R (CommSemiring.toSemiring.{u2} R _inst_1)) (Polynomial.commSemiring.{u2} R _inst_1)) s (fun (j : ι) => p j))) (Finset.prod.{u2, u1} R ι (CommSemiring.toCommMonoid.{u2} R _inst_1) s (fun (j : ι) => Polynomial.eval.{u2} R (CommSemiring.toSemiring.{u2} R _inst_1) x (p j)))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_prod Polynomial.eval_prodₓ'. -/
/-- Polynomial evaluation commutes with `finset.prod`
-/
theorem eval_prod {ι : Type _} (s : Finset ι) (p : ι → R[X]) (x : R) :
    eval x (∏ j in s, p j) = ∏ j in s, eval x (p j) :=
  (evalRingHom x).map_prod _ _
#align polynomial.eval_prod Polynomial.eval_prod

#print Polynomial.list_prod_comp /-
theorem list_prod_comp (l : List R[X]) (q : R[X]) :
    l.Prod.comp q = (l.map fun p : R[X] => p.comp q).Prod :=
  map_list_prod (compRingHom q) _
#align polynomial.list_prod_comp Polynomial.list_prod_comp
-/

#print Polynomial.multiset_prod_comp /-
theorem multiset_prod_comp (s : Multiset R[X]) (q : R[X]) :
    s.Prod.comp q = (s.map fun p : R[X] => p.comp q).Prod :=
  map_multiset_prod (compRingHom q) _
#align polynomial.multiset_prod_comp Polynomial.multiset_prod_comp
-/

/- warning: polynomial.prod_comp -> Polynomial.prod_comp is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommSemiring.{u1} R] {ι : Type.{u2}} (s : Finset.{u2} ι) (p : ι -> (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (q : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)), Eq.{succ u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.comp.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) (Finset.prod.{u1, u2} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) ι (CommSemiring.toCommMonoid.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.commSemiring.{u1} R _inst_1)) s (fun (j : ι) => p j)) q) (Finset.prod.{u1, u2} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) ι (CommSemiring.toCommMonoid.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.commSemiring.{u1} R _inst_1)) s (fun (j : ι) => Polynomial.comp.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) (p j) q))
but is expected to have type
  forall {R : Type.{u2}} [_inst_1 : CommSemiring.{u2} R] {ι : Type.{u1}} (s : Finset.{u1} ι) (p : ι -> (Polynomial.{u2} R (CommSemiring.toSemiring.{u2} R _inst_1))) (q : Polynomial.{u2} R (CommSemiring.toSemiring.{u2} R _inst_1)), Eq.{succ u2} (Polynomial.{u2} R (CommSemiring.toSemiring.{u2} R _inst_1)) (Polynomial.comp.{u2} R (CommSemiring.toSemiring.{u2} R _inst_1) (Finset.prod.{u2, u1} (Polynomial.{u2} R (CommSemiring.toSemiring.{u2} R _inst_1)) ι (CommSemiring.toCommMonoid.{u2} (Polynomial.{u2} R (CommSemiring.toSemiring.{u2} R _inst_1)) (Polynomial.commSemiring.{u2} R _inst_1)) s (fun (j : ι) => p j)) q) (Finset.prod.{u2, u1} (Polynomial.{u2} R (CommSemiring.toSemiring.{u2} R _inst_1)) ι (CommSemiring.toCommMonoid.{u2} (Polynomial.{u2} R (CommSemiring.toSemiring.{u2} R _inst_1)) (Polynomial.commSemiring.{u2} R _inst_1)) s (fun (j : ι) => Polynomial.comp.{u2} R (CommSemiring.toSemiring.{u2} R _inst_1) (p j) q))
Case conversion may be inaccurate. Consider using '#align polynomial.prod_comp Polynomial.prod_compₓ'. -/
theorem prod_comp {ι : Type _} (s : Finset ι) (p : ι → R[X]) (q : R[X]) :
    (∏ j in s, p j).comp q = ∏ j in s, (p j).comp q :=
  map_prod (compRingHom q) _ _
#align polynomial.prod_comp Polynomial.prod_comp

/- warning: polynomial.is_root_prod -> Polynomial.isRoot_prod is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_3 : CommRing.{u1} R] [_inst_4 : IsDomain.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_3))] {ι : Type.{u2}} (s : Finset.{u2} ι) (p : ι -> (Polynomial.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_3)))) (x : R), Iff (Polynomial.IsRoot.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_3)) (Finset.prod.{u1, u2} (Polynomial.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_3))) ι (CommRing.toCommMonoid.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Polynomial.commRing.{u1} R _inst_3)) s (fun (j : ι) => p j)) x) (Exists.{succ u2} ι (fun (i : ι) => Exists.{0} (Membership.Mem.{u2, u2} ι (Finset.{u2} ι) (Finset.hasMem.{u2} ι) i s) (fun (H : Membership.Mem.{u2, u2} ι (Finset.{u2} ι) (Finset.hasMem.{u2} ι) i s) => Polynomial.IsRoot.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_3)) (p i) x)))
but is expected to have type
  forall {R : Type.{u2}} [_inst_3 : CommRing.{u2} R] [_inst_4 : IsDomain.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_3))] {ι : Type.{u1}} (s : Finset.{u1} ι) (p : ι -> (Polynomial.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_3)))) (x : R), Iff (Polynomial.IsRoot.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_3)) (Finset.prod.{u2, u1} (Polynomial.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_3))) ι (CommRing.toCommMonoid.{u2} (Polynomial.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_3))) (Polynomial.commRing.{u2} R _inst_3)) s (fun (j : ι) => p j)) x) (Exists.{succ u1} ι (fun (i : ι) => And (Membership.mem.{u1, u1} ι (Finset.{u1} ι) (Finset.instMembershipFinset.{u1} ι) i s) (Polynomial.IsRoot.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_3)) (p i) x)))
Case conversion may be inaccurate. Consider using '#align polynomial.is_root_prod Polynomial.isRoot_prodₓ'. -/
theorem isRoot_prod {R} [CommRing R] [IsDomain R] {ι : Type _} (s : Finset ι) (p : ι → R[X])
    (x : R) : IsRoot (∏ j in s, p j) x ↔ ∃ i ∈ s, IsRoot (p i) x := by
  simp only [is_root, eval_prod, Finset.prod_eq_zero_iff]
#align polynomial.is_root_prod Polynomial.isRoot_prod

#print Polynomial.eval_dvd /-
theorem eval_dvd : p ∣ q → eval x p ∣ eval x q :=
  eval₂_dvd _ _
#align polynomial.eval_dvd Polynomial.eval_dvd
-/

/- warning: polynomial.eval_eq_zero_of_dvd_of_eval_eq_zero -> Polynomial.eval_eq_zero_of_dvd_of_eval_eq_zero is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : CommSemiring.{u1} R] {p : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)} {q : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)} {x : R}, (Dvd.Dvd.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (semigroupDvd.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (SemigroupWithZero.toSemigroup.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (NonUnitalSemiring.toSemigroupWithZero.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (NonUnitalCommSemiring.toNonUnitalSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (CommSemiring.toNonUnitalCommSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.commSemiring.{u1} R _inst_1)))))) p q) -> (Eq.{succ u1} R (Polynomial.eval.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) x p) (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))))))))) -> (Eq.{succ u1} R (Polynomial.eval.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) x q) (OfNat.ofNat.{u1} R 0 (OfNat.mk.{u1} R 0 (Zero.zero.{u1} R (MulZeroClass.toHasZero.{u1} R (NonUnitalNonAssocSemiring.toMulZeroClass.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))))))))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : CommSemiring.{u1} R] {p : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)} {q : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)} {x : R}, (Dvd.dvd.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (semigroupDvd.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (SemigroupWithZero.toSemigroup.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (NonUnitalSemiring.toSemigroupWithZero.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (NonUnitalCommSemiring.toNonUnitalSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (CommSemiring.toNonUnitalCommSemiring.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.commSemiring.{u1} R _inst_1)))))) p q) -> (Eq.{succ u1} R (Polynomial.eval.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) x p) (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (CommMonoidWithZero.toZero.{u1} R (CommSemiring.toCommMonoidWithZero.{u1} R _inst_1))))) -> (Eq.{succ u1} R (Polynomial.eval.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) x q) (OfNat.ofNat.{u1} R 0 (Zero.toOfNat0.{u1} R (CommMonoidWithZero.toZero.{u1} R (CommSemiring.toCommMonoidWithZero.{u1} R _inst_1)))))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_eq_zero_of_dvd_of_eval_eq_zero Polynomial.eval_eq_zero_of_dvd_of_eval_eq_zeroₓ'. -/
theorem eval_eq_zero_of_dvd_of_eval_eq_zero : p ∣ q → eval x p = 0 → eval x q = 0 :=
  eval₂_eq_zero_of_dvd_of_eval₂_eq_zero _ _
#align polynomial.eval_eq_zero_of_dvd_of_eval_eq_zero Polynomial.eval_eq_zero_of_dvd_of_eval_eq_zero

#print Polynomial.eval_geom_sum /-
@[simp]
theorem eval_geom_sum {R} [CommSemiring R] {n : ℕ} {x : R} :
    eval x (∑ i in range n, X ^ i) = ∑ i in range n, x ^ i := by simp [eval_finset_sum]
#align polynomial.eval_geom_sum Polynomial.eval_geom_sum
-/

end

end Eval

section Map

#print Polynomial.support_map_subset /-
theorem support_map_subset [Semiring R] [Semiring S] (f : R →+* S) (p : R[X]) :
    (map f p).support ⊆ p.support := by
  intro x
  contrapose!
  simp (config := { contextual := true })
#align polynomial.support_map_subset Polynomial.support_map_subset
-/

/- warning: polynomial.support_map_of_injective -> Polynomial.support_map_of_injective is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (p : Polynomial.{u1} R _inst_1) {f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)}, (Function.Injective.{succ u1, succ u2} R S (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) f)) -> (Eq.{1} (Finset.{0} Nat) (Polynomial.support.{u2} S _inst_2 (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p)) (Polynomial.support.{u1} R _inst_1 p))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : Semiring.{u1} R] [_inst_2 : Semiring.{u2} S] (p : Polynomial.{u1} R _inst_1) {f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)}, (Function.Injective.{succ u1, succ u2} R S (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S _inst_2)) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2)) R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R _inst_1) (Semiring.toNonAssocSemiring.{u2} S _inst_2))))) f)) -> (Eq.{1} (Finset.{0} Nat) (Polynomial.support.{u2} S _inst_2 (Polynomial.map.{u1, u2} R S _inst_1 _inst_2 f p)) (Polynomial.support.{u1} R _inst_1 p))
Case conversion may be inaccurate. Consider using '#align polynomial.support_map_of_injective Polynomial.support_map_of_injectiveₓ'. -/
theorem support_map_of_injective [Semiring R] [Semiring S] (p : R[X]) {f : R →+* S}
    (hf : Function.Injective f) : (map f p).support = p.support := by
  simp_rw [Finset.ext_iff, mem_support_iff, coeff_map, ← map_zero f, hf.ne_iff, iff_self_iff,
    forall_const]
#align polynomial.support_map_of_injective Polynomial.support_map_of_injective

variable [CommSemiring R] [CommSemiring S] (f : R →+* S)

#print Polynomial.map_multiset_prod /-
protected theorem map_multiset_prod (m : Multiset R[X]) : m.Prod.map f = (m.map <| map f).Prod :=
  Eq.symm <| Multiset.prod_hom _ (mapRingHom f).toMonoidHom
#align polynomial.map_multiset_prod Polynomial.map_multiset_prod
-/

/- warning: polynomial.map_prod -> Polynomial.map_prod is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : CommSemiring.{u1} R] [_inst_2 : CommSemiring.{u2} S] (f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) {ι : Type.{u3}} (g : ι -> (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (s : Finset.{u3} ι), Eq.{succ u2} (Polynomial.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)) (Polynomial.map.{u1, u2} R S (CommSemiring.toSemiring.{u1} R _inst_1) (CommSemiring.toSemiring.{u2} S _inst_2) f (Finset.prod.{u1, u3} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) ι (CommSemiring.toCommMonoid.{u1} (Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Polynomial.commSemiring.{u1} R _inst_1)) s (fun (i : ι) => g i))) (Finset.prod.{u2, u3} (Polynomial.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)) ι (CommSemiring.toCommMonoid.{u2} (Polynomial.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)) (Polynomial.commSemiring.{u2} S _inst_2)) s (fun (i : ι) => Polynomial.map.{u1, u2} R S (CommSemiring.toSemiring.{u1} R _inst_1) (CommSemiring.toSemiring.{u2} S _inst_2) f (g i)))
but is expected to have type
  forall {R : Type.{u2}} {S : Type.{u3}} [_inst_1 : CommSemiring.{u2} R] [_inst_2 : CommSemiring.{u3} S] (f : RingHom.{u2, u3} R S (Semiring.toNonAssocSemiring.{u2} R (CommSemiring.toSemiring.{u2} R _inst_1)) (Semiring.toNonAssocSemiring.{u3} S (CommSemiring.toSemiring.{u3} S _inst_2))) {ι : Type.{u1}} (g : ι -> (Polynomial.{u2} R (CommSemiring.toSemiring.{u2} R _inst_1))) (s : Finset.{u1} ι), Eq.{succ u3} (Polynomial.{u3} S (CommSemiring.toSemiring.{u3} S _inst_2)) (Polynomial.map.{u2, u3} R S (CommSemiring.toSemiring.{u2} R _inst_1) (CommSemiring.toSemiring.{u3} S _inst_2) f (Finset.prod.{u2, u1} (Polynomial.{u2} R (CommSemiring.toSemiring.{u2} R _inst_1)) ι (CommSemiring.toCommMonoid.{u2} (Polynomial.{u2} R (CommSemiring.toSemiring.{u2} R _inst_1)) (Polynomial.commSemiring.{u2} R _inst_1)) s (fun (i : ι) => g i))) (Finset.prod.{u3, u1} (Polynomial.{u3} S (CommSemiring.toSemiring.{u3} S _inst_2)) ι (CommSemiring.toCommMonoid.{u3} (Polynomial.{u3} S (CommSemiring.toSemiring.{u3} S _inst_2)) (Polynomial.commSemiring.{u3} S _inst_2)) s (fun (i : ι) => Polynomial.map.{u2, u3} R S (CommSemiring.toSemiring.{u2} R _inst_1) (CommSemiring.toSemiring.{u3} S _inst_2) f (g i)))
Case conversion may be inaccurate. Consider using '#align polynomial.map_prod Polynomial.map_prodₓ'. -/
protected theorem map_prod {ι : Type _} (g : ι → R[X]) (s : Finset ι) :
    (∏ i in s, g i).map f = ∏ i in s, (g i).map f :=
  (mapRingHom f).map_prod _ _
#align polynomial.map_prod Polynomial.map_prod

/- warning: polynomial.is_root.map -> Polynomial.IsRoot.map is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : CommSemiring.{u1} R] [_inst_2 : CommSemiring.{u2} S] {f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))} {x : R} {p : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)}, (Polynomial.IsRoot.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) p x) -> (Polynomial.IsRoot.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S (CommSemiring.toSemiring.{u1} R _inst_1) (CommSemiring.toSemiring.{u2} S _inst_2) f p) (coeFn.{max (succ u1) (succ u2), max (succ u1) (succ u2)} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (fun (_x : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) => R -> S) (RingHom.hasCoeToFun.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) f x))
but is expected to have type
  forall {R : Type.{u1}} {S : Type.{u2}} [_inst_1 : CommSemiring.{u1} R] [_inst_2 : CommSemiring.{u2} S] {f : RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))} {x : R} {p : Polynomial.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)}, (Polynomial.IsRoot.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1) p x) -> (Polynomial.IsRoot.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S (CommSemiring.toSemiring.{u1} R _inst_1) (CommSemiring.toSemiring.{u2} S _inst_2) f p) (FunLike.coe.{max (succ u1) (succ u2), succ u1, succ u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)))) (NonUnitalRingHomClass.toMulHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (RingHomClass.toNonUnitalRingHomClass.{max u1 u2, u1, u2} (RingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R S (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)) (RingHom.instRingHomClassRingHom.{u1, u2} R S (Semiring.toNonAssocSemiring.{u1} R (CommSemiring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)))))) f x))
Case conversion may be inaccurate. Consider using '#align polynomial.is_root.map Polynomial.IsRoot.mapₓ'. -/
theorem IsRoot.map {f : R →+* S} {x : R} {p : R[X]} (h : IsRoot p x) : IsRoot (p.map f) (f x) := by
  rw [is_root, eval_map, eval₂_hom, h.eq_zero, f.map_zero]
#align polynomial.is_root.map Polynomial.IsRoot.map

/- warning: polynomial.is_root.of_map -> Polynomial.IsRoot.of_map is a dubious translation:
lean 3 declaration is
  forall {S : Type.{u1}} [_inst_2 : CommSemiring.{u1} S] {R : Type.{u2}} [_inst_3 : CommRing.{u2} R] {f : RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_3))) (Semiring.toNonAssocSemiring.{u1} S (CommSemiring.toSemiring.{u1} S _inst_2))} {x : R} {p : Polynomial.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_3))}, (Polynomial.IsRoot.{u1} S (CommSemiring.toSemiring.{u1} S _inst_2) (Polynomial.map.{u2, u1} R S (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_3)) (CommSemiring.toSemiring.{u1} S _inst_2) f p) (coeFn.{max (succ u2) (succ u1), max (succ u2) (succ u1)} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_3))) (Semiring.toNonAssocSemiring.{u1} S (CommSemiring.toSemiring.{u1} S _inst_2))) (fun (_x : RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_3))) (Semiring.toNonAssocSemiring.{u1} S (CommSemiring.toSemiring.{u1} S _inst_2))) => R -> S) (RingHom.hasCoeToFun.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_3))) (Semiring.toNonAssocSemiring.{u1} S (CommSemiring.toSemiring.{u1} S _inst_2))) f x)) -> (Function.Injective.{succ u2, succ u1} R S (coeFn.{max (succ u2) (succ u1), max (succ u2) (succ u1)} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_3))) (Semiring.toNonAssocSemiring.{u1} S (CommSemiring.toSemiring.{u1} S _inst_2))) (fun (_x : RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_3))) (Semiring.toNonAssocSemiring.{u1} S (CommSemiring.toSemiring.{u1} S _inst_2))) => R -> S) (RingHom.hasCoeToFun.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_3))) (Semiring.toNonAssocSemiring.{u1} S (CommSemiring.toSemiring.{u1} S _inst_2))) f)) -> (Polynomial.IsRoot.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_3)) p x)
but is expected to have type
  forall {S : Type.{u2}} [_inst_2 : CommSemiring.{u2} S] {R : Type.{u1}} [_inst_3 : CommRing.{u1} R] {f : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))} {x : R} {p : Polynomial.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_3))}, (Polynomial.IsRoot.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_3)) (CommSemiring.toSemiring.{u2} S _inst_2) f p) (FunLike.coe.{max (succ u2) (succ u1), succ u1, succ u2} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u2 u1, u1, u2} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)))) (NonUnitalRingHomClass.toMulHomClass.{max u2 u1, u1, u2} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3)))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (RingHomClass.toNonUnitalRingHomClass.{max u2 u1, u1, u2} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)) (RingHom.instRingHomClassRingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)))))) f x)) -> (Function.Injective.{succ u1, succ u2} R S (FunLike.coe.{max (succ u2) (succ u1), succ u1, succ u2} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u2 u1, u1, u2} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)))) (NonUnitalRingHomClass.toMulHomClass.{max u2 u1, u1, u2} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3)))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (RingHomClass.toNonUnitalRingHomClass.{max u2 u1, u1, u2} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)) (RingHom.instRingHomClassRingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)))))) f)) -> (Polynomial.IsRoot.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_3)) p x)
Case conversion may be inaccurate. Consider using '#align polynomial.is_root.of_map Polynomial.IsRoot.of_mapₓ'. -/
theorem IsRoot.of_map {R} [CommRing R] {f : R →+* S} {x : R} {p : R[X]} (h : IsRoot (p.map f) (f x))
    (hf : Function.Injective f) : IsRoot p x := by
  rwa [is_root, ← (injective_iff_map_eq_zero' f).mp hf, ← eval₂_hom, ← eval_map]
#align polynomial.is_root.of_map Polynomial.IsRoot.of_map

/- warning: polynomial.is_root_map_iff -> Polynomial.isRoot_map_iff is a dubious translation:
lean 3 declaration is
  forall {S : Type.{u1}} [_inst_2 : CommSemiring.{u1} S] {R : Type.{u2}} [_inst_3 : CommRing.{u2} R] {f : RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_3))) (Semiring.toNonAssocSemiring.{u1} S (CommSemiring.toSemiring.{u1} S _inst_2))} {x : R} {p : Polynomial.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_3))}, (Function.Injective.{succ u2, succ u1} R S (coeFn.{max (succ u2) (succ u1), max (succ u2) (succ u1)} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_3))) (Semiring.toNonAssocSemiring.{u1} S (CommSemiring.toSemiring.{u1} S _inst_2))) (fun (_x : RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_3))) (Semiring.toNonAssocSemiring.{u1} S (CommSemiring.toSemiring.{u1} S _inst_2))) => R -> S) (RingHom.hasCoeToFun.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_3))) (Semiring.toNonAssocSemiring.{u1} S (CommSemiring.toSemiring.{u1} S _inst_2))) f)) -> (Iff (Polynomial.IsRoot.{u1} S (CommSemiring.toSemiring.{u1} S _inst_2) (Polynomial.map.{u2, u1} R S (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_3)) (CommSemiring.toSemiring.{u1} S _inst_2) f p) (coeFn.{max (succ u2) (succ u1), max (succ u2) (succ u1)} (RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_3))) (Semiring.toNonAssocSemiring.{u1} S (CommSemiring.toSemiring.{u1} S _inst_2))) (fun (_x : RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_3))) (Semiring.toNonAssocSemiring.{u1} S (CommSemiring.toSemiring.{u1} S _inst_2))) => R -> S) (RingHom.hasCoeToFun.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R (CommRing.toRing.{u2} R _inst_3))) (Semiring.toNonAssocSemiring.{u1} S (CommSemiring.toSemiring.{u1} S _inst_2))) f x)) (Polynomial.IsRoot.{u2} R (Ring.toSemiring.{u2} R (CommRing.toRing.{u2} R _inst_3)) p x))
but is expected to have type
  forall {S : Type.{u2}} [_inst_2 : CommSemiring.{u2} S] {R : Type.{u1}} [_inst_3 : CommRing.{u1} R] {f : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))} {x : R} {p : Polynomial.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_3))}, (Function.Injective.{succ u1, succ u2} R S (FunLike.coe.{max (succ u2) (succ u1), succ u1, succ u2} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u2 u1, u1, u2} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)))) (NonUnitalRingHomClass.toMulHomClass.{max u2 u1, u1, u2} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3)))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (RingHomClass.toNonUnitalRingHomClass.{max u2 u1, u1, u2} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)) (RingHom.instRingHomClassRingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)))))) f)) -> (Iff (Polynomial.IsRoot.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_3)) (CommSemiring.toSemiring.{u2} S _inst_2) f p) (FunLike.coe.{max (succ u2) (succ u1), succ u1, succ u2} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => S) _x) (MulHomClass.toFunLike.{max u2 u1, u1, u2} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R S (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))))) (NonUnitalNonAssocSemiring.toMul.{u2} S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)))) (NonUnitalRingHomClass.toMulHomClass.{max u2 u1, u1, u2} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R S (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3)))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u2} S (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) (RingHomClass.toNonUnitalRingHomClass.{max u2 u1, u1, u2} (RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2))) R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)) (RingHom.instRingHomClassRingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R (CommRing.toRing.{u1} R _inst_3))) (Semiring.toNonAssocSemiring.{u2} S (CommSemiring.toSemiring.{u2} S _inst_2)))))) f x)) (Polynomial.IsRoot.{u1} R (Ring.toSemiring.{u1} R (CommRing.toRing.{u1} R _inst_3)) p x))
Case conversion may be inaccurate. Consider using '#align polynomial.is_root_map_iff Polynomial.isRoot_map_iffₓ'. -/
theorem isRoot_map_iff {R : Type _} [CommRing R] {f : R →+* S} {x : R} {p : R[X]}
    (hf : Function.Injective f) : IsRoot (p.map f) (f x) ↔ IsRoot p x :=
  ⟨fun h => h.of_map hf, fun h => h.map⟩
#align polynomial.is_root_map_iff Polynomial.isRoot_map_iff

end Map

end CommSemiring

section Ring

variable [Ring R] {p q r : R[X]}

/- warning: polynomial.C_neg -> Polynomial.C_neg is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {a : R} [_inst_1 : Ring.{u1} R], Eq.{succ u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) => R -> (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (Polynomial.C.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Neg.neg.{u1} R (SubNegMonoid.toHasNeg.{u1} R (AddGroup.toSubNegMonoid.{u1} R (AddGroupWithOne.toAddGroup.{u1} R (AddCommGroupWithOne.toAddGroupWithOne.{u1} R (Ring.toAddCommGroupWithOne.{u1} R _inst_1))))) a)) (Neg.neg.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.neg'.{u1} R _inst_1) (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) => R -> (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (Polynomial.C.{u1} R (Ring.toSemiring.{u1} R _inst_1)) a))
but is expected to have type
  forall {R : Type.{u1}} {a : R} [_inst_1 : Ring.{u1} R], Eq.{succ u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Neg.neg.{u1} R (Ring.toNeg.{u1} R _inst_1) a)) (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))))))) (Polynomial.C.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Neg.neg.{u1} R (Ring.toNeg.{u1} R _inst_1) a)) (Neg.neg.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) a) (Polynomial.neg'.{u1} R _inst_1) (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))))))) (Polynomial.C.{u1} R (Ring.toSemiring.{u1} R _inst_1)) a))
Case conversion may be inaccurate. Consider using '#align polynomial.C_neg Polynomial.C_negₓ'. -/
theorem C_neg : C (-a) = -C a :=
  RingHom.map_neg C a
#align polynomial.C_neg Polynomial.C_neg

/- warning: polynomial.C_sub -> Polynomial.C_sub is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {a : R} {b : R} [_inst_1 : Ring.{u1} R], Eq.{succ u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) => R -> (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (Polynomial.C.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (HSub.hSub.{u1, u1, u1} R R R (instHSub.{u1} R (SubNegMonoid.toHasSub.{u1} R (AddGroup.toSubNegMonoid.{u1} R (AddGroupWithOne.toAddGroup.{u1} R (AddCommGroupWithOne.toAddGroupWithOne.{u1} R (Ring.toAddCommGroupWithOne.{u1} R _inst_1)))))) a b)) (HSub.hSub.{u1, u1, u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (instHSub.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.sub.{u1} R _inst_1)) (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) => R -> (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (Polynomial.C.{u1} R (Ring.toSemiring.{u1} R _inst_1)) a) (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) => R -> (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (Polynomial.C.{u1} R (Ring.toSemiring.{u1} R _inst_1)) b))
but is expected to have type
  forall {R : Type.{u1}} {a : R} {b : R} [_inst_1 : Ring.{u1} R], Eq.{succ u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (HSub.hSub.{u1, u1, u1} R R R (instHSub.{u1} R (Ring.toSub.{u1} R _inst_1)) a b)) (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))))))) (Polynomial.C.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (HSub.hSub.{u1, u1, u1} R R R (instHSub.{u1} R (Ring.toSub.{u1} R _inst_1)) a b)) (HSub.hSub.{u1, u1, u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) a) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) b) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) a) (instHSub.{u1} ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) a) (Polynomial.sub.{u1} R _inst_1)) (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))))))) (Polynomial.C.{u1} R (Ring.toSemiring.{u1} R _inst_1)) a) (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))))))) (Polynomial.C.{u1} R (Ring.toSemiring.{u1} R _inst_1)) b))
Case conversion may be inaccurate. Consider using '#align polynomial.C_sub Polynomial.C_subₓ'. -/
theorem C_sub : C (a - b) = C a - C b :=
  RingHom.map_sub C a b
#align polynomial.C_sub Polynomial.C_sub

/- warning: polynomial.map_sub -> Polynomial.map_sub is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Ring.{u1} R] {p : Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)} {q : Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)} {S : Type.{u2}} [_inst_2 : Ring.{u2} S] (f : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_2))), Eq.{succ u2} (Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_2)) (Polynomial.map.{u1, u2} R S (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} S _inst_2) f (HSub.hSub.{u1, u1, u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (instHSub.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.sub.{u1} R _inst_1)) p q)) (HSub.hSub.{u2, u2, u2} (Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_2)) (Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_2)) (Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_2)) (instHSub.{u2} (Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_2)) (Polynomial.sub.{u2} S _inst_2)) (Polynomial.map.{u1, u2} R S (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} S _inst_2) f p) (Polynomial.map.{u1, u2} R S (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} S _inst_2) f q))
but is expected to have type
  forall {R : Type.{u2}} [_inst_1 : Ring.{u2} R] {p : Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_1)} {q : Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_1)} {S : Type.{u1}} [_inst_2 : Ring.{u1} S] (f : RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_2))), Eq.{succ u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S _inst_2)) (Polynomial.map.{u2, u1} R S (Ring.toSemiring.{u2} R _inst_1) (Ring.toSemiring.{u1} S _inst_2) f (HSub.hSub.{u2, u2, u2} (Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_1)) (Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_1)) (Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_1)) (instHSub.{u2} (Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_1)) (Polynomial.sub.{u2} R _inst_1)) p q)) (HSub.hSub.{u1, u1, u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S _inst_2)) (Polynomial.{u1} S (Ring.toSemiring.{u1} S _inst_2)) (Polynomial.{u1} S (Ring.toSemiring.{u1} S _inst_2)) (instHSub.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S _inst_2)) (Polynomial.sub.{u1} S _inst_2)) (Polynomial.map.{u2, u1} R S (Ring.toSemiring.{u2} R _inst_1) (Ring.toSemiring.{u1} S _inst_2) f p) (Polynomial.map.{u2, u1} R S (Ring.toSemiring.{u2} R _inst_1) (Ring.toSemiring.{u1} S _inst_2) f q))
Case conversion may be inaccurate. Consider using '#align polynomial.map_sub Polynomial.map_subₓ'. -/
@[simp]
protected theorem map_sub {S} [Ring S] (f : R →+* S) : (p - q).map f = p.map f - q.map f :=
  (mapRingHom f).map_sub p q
#align polynomial.map_sub Polynomial.map_sub

/- warning: polynomial.map_neg -> Polynomial.map_neg is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Ring.{u1} R] {p : Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)} {S : Type.{u2}} [_inst_2 : Ring.{u2} S] (f : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_2))), Eq.{succ u2} (Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_2)) (Polynomial.map.{u1, u2} R S (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} S _inst_2) f (Neg.neg.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.neg'.{u1} R _inst_1) p)) (Neg.neg.{u2} (Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_2)) (Polynomial.neg'.{u2} S _inst_2) (Polynomial.map.{u1, u2} R S (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} S _inst_2) f p))
but is expected to have type
  forall {R : Type.{u2}} [_inst_1 : Ring.{u2} R] {p : Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_1)} {S : Type.{u1}} [_inst_2 : Ring.{u1} S] (f : RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_2))), Eq.{succ u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S _inst_2)) (Polynomial.map.{u2, u1} R S (Ring.toSemiring.{u2} R _inst_1) (Ring.toSemiring.{u1} S _inst_2) f (Neg.neg.{u2} (Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_1)) (Polynomial.neg'.{u2} R _inst_1) p)) (Neg.neg.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S _inst_2)) (Polynomial.neg'.{u1} S _inst_2) (Polynomial.map.{u2, u1} R S (Ring.toSemiring.{u2} R _inst_1) (Ring.toSemiring.{u1} S _inst_2) f p))
Case conversion may be inaccurate. Consider using '#align polynomial.map_neg Polynomial.map_negₓ'. -/
@[simp]
protected theorem map_neg {S} [Ring S] (f : R →+* S) : (-p).map f = -p.map f :=
  (mapRingHom f).map_neg p
#align polynomial.map_neg Polynomial.map_neg

/- warning: polynomial.map_int_cast -> Polynomial.map_int_cast is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Ring.{u1} R] {S : Type.{u2}} [_inst_2 : Ring.{u2} S] (f : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_2))) (n : Int), Eq.{succ u2} (Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_2)) (Polynomial.map.{u1, u2} R S (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} S _inst_2) f ((fun (a : Type) (b : Type.{u1}) [self : HasLiftT.{1, succ u1} a b] => self.0) Int (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (HasLiftT.mk.{1, succ u1} Int (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (CoeTCₓ.coe.{1, succ u1} Int (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Int.castCoe.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.intCast.{u1} R _inst_1)))) n)) ((fun (a : Type) (b : Type.{u2}) [self : HasLiftT.{1, succ u2} a b] => self.0) Int (Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_2)) (HasLiftT.mk.{1, succ u2} Int (Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_2)) (CoeTCₓ.coe.{1, succ u2} Int (Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_2)) (Int.castCoe.{u2} (Polynomial.{u2} S (Ring.toSemiring.{u2} S _inst_2)) (Polynomial.intCast.{u2} S _inst_2)))) n)
but is expected to have type
  forall {R : Type.{u2}} [_inst_1 : Ring.{u2} R] {S : Type.{u1}} [_inst_2 : Ring.{u1} S] (f : RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_2))) (n : Int), Eq.{succ u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S _inst_2)) (Polynomial.map.{u2, u1} R S (Ring.toSemiring.{u2} R _inst_1) (Ring.toSemiring.{u1} S _inst_2) f (Int.cast.{u2} (Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_1)) (Polynomial.intCast.{u2} R _inst_1) n)) (Int.cast.{u1} (Polynomial.{u1} S (Ring.toSemiring.{u1} S _inst_2)) (Polynomial.intCast.{u1} S _inst_2) n)
Case conversion may be inaccurate. Consider using '#align polynomial.map_int_cast Polynomial.map_int_castₓ'. -/
@[simp]
theorem map_int_cast {S} [Ring S] (f : R →+* S) (n : ℤ) : map f ↑n = ↑n :=
  map_intCast (mapRingHom f) n
#align polynomial.map_int_cast Polynomial.map_int_cast

/- warning: polynomial.eval_int_cast -> Polynomial.eval_int_cast is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Ring.{u1} R] {n : Int} {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R (Ring.toSemiring.{u1} R _inst_1) x ((fun (a : Type) (b : Type.{u1}) [self : HasLiftT.{1, succ u1} a b] => self.0) Int (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (HasLiftT.mk.{1, succ u1} Int (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (CoeTCₓ.coe.{1, succ u1} Int (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Int.castCoe.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.intCast.{u1} R _inst_1)))) n)) ((fun (a : Type) (b : Type.{u1}) [self : HasLiftT.{1, succ u1} a b] => self.0) Int R (HasLiftT.mk.{1, succ u1} Int R (CoeTCₓ.coe.{1, succ u1} Int R (Int.castCoe.{u1} R (AddGroupWithOne.toHasIntCast.{u1} R (AddCommGroupWithOne.toAddGroupWithOne.{u1} R (Ring.toAddCommGroupWithOne.{u1} R _inst_1)))))) n)
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Ring.{u1} R] {n : Int} {x : R}, Eq.{succ u1} R (Polynomial.eval.{u1} R (Ring.toSemiring.{u1} R _inst_1) x (Int.cast.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.intCast.{u1} R _inst_1) n)) (Int.cast.{u1} R (Ring.toIntCast.{u1} R _inst_1) n)
Case conversion may be inaccurate. Consider using '#align polynomial.eval_int_cast Polynomial.eval_int_castₓ'. -/
@[simp]
theorem eval_int_cast {n : ℤ} {x : R} : (n : R[X]).eval x = n := by
  simp only [← C_eq_int_cast, eval_C]
#align polynomial.eval_int_cast Polynomial.eval_int_cast

/- warning: polynomial.eval₂_neg -> Polynomial.eval₂_neg is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Ring.{u1} R] {p : Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)} {S : Type.{u2}} [_inst_2 : Ring.{u2} S] (f : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_2))) {x : S}, Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} S _inst_2) f x (Neg.neg.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.neg'.{u1} R _inst_1) p)) (Neg.neg.{u2} S (SubNegMonoid.toHasNeg.{u2} S (AddGroup.toSubNegMonoid.{u2} S (AddGroupWithOne.toAddGroup.{u2} S (AddCommGroupWithOne.toAddGroupWithOne.{u2} S (Ring.toAddCommGroupWithOne.{u2} S _inst_2))))) (Polynomial.eval₂.{u1, u2} R S (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} S _inst_2) f x p))
but is expected to have type
  forall {R : Type.{u2}} [_inst_1 : Ring.{u2} R] {p : Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_1)} {S : Type.{u1}} [_inst_2 : Ring.{u1} S] (f : RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_2))) {x : S}, Eq.{succ u1} S (Polynomial.eval₂.{u2, u1} R S (Ring.toSemiring.{u2} R _inst_1) (Ring.toSemiring.{u1} S _inst_2) f x (Neg.neg.{u2} (Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_1)) (Polynomial.neg'.{u2} R _inst_1) p)) (Neg.neg.{u1} S (Ring.toNeg.{u1} S _inst_2) (Polynomial.eval₂.{u2, u1} R S (Ring.toSemiring.{u2} R _inst_1) (Ring.toSemiring.{u1} S _inst_2) f x p))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_neg Polynomial.eval₂_negₓ'. -/
@[simp]
theorem eval₂_neg {S} [Ring S] (f : R →+* S) {x : S} : (-p).eval₂ f x = -p.eval₂ f x := by
  rw [eq_neg_iff_add_eq_zero, ← eval₂_add, add_left_neg, eval₂_zero]
#align polynomial.eval₂_neg Polynomial.eval₂_neg

/- warning: polynomial.eval₂_sub -> Polynomial.eval₂_sub is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Ring.{u1} R] {p : Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)} {q : Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)} {S : Type.{u2}} [_inst_2 : Ring.{u2} S] (f : RingHom.{u1, u2} R S (NonAssocRing.toNonAssocSemiring.{u1} R (Ring.toNonAssocRing.{u1} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u2} S (Ring.toNonAssocRing.{u2} S _inst_2))) {x : S}, Eq.{succ u2} S (Polynomial.eval₂.{u1, u2} R S (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} S _inst_2) f x (HSub.hSub.{u1, u1, u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (instHSub.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.sub.{u1} R _inst_1)) p q)) (HSub.hSub.{u2, u2, u2} S S S (instHSub.{u2} S (SubNegMonoid.toHasSub.{u2} S (AddGroup.toSubNegMonoid.{u2} S (AddGroupWithOne.toAddGroup.{u2} S (AddCommGroupWithOne.toAddGroupWithOne.{u2} S (Ring.toAddCommGroupWithOne.{u2} S _inst_2)))))) (Polynomial.eval₂.{u1, u2} R S (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} S _inst_2) f x p) (Polynomial.eval₂.{u1, u2} R S (Ring.toSemiring.{u1} R _inst_1) (Ring.toSemiring.{u2} S _inst_2) f x q))
but is expected to have type
  forall {R : Type.{u2}} [_inst_1 : Ring.{u2} R] {p : Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_1)} {q : Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_1)} {S : Type.{u1}} [_inst_2 : Ring.{u1} S] (f : RingHom.{u2, u1} R S (NonAssocRing.toNonAssocSemiring.{u2} R (Ring.toNonAssocRing.{u2} R _inst_1)) (NonAssocRing.toNonAssocSemiring.{u1} S (Ring.toNonAssocRing.{u1} S _inst_2))) {x : S}, Eq.{succ u1} S (Polynomial.eval₂.{u2, u1} R S (Ring.toSemiring.{u2} R _inst_1) (Ring.toSemiring.{u1} S _inst_2) f x (HSub.hSub.{u2, u2, u2} (Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_1)) (Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_1)) (Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_1)) (instHSub.{u2} (Polynomial.{u2} R (Ring.toSemiring.{u2} R _inst_1)) (Polynomial.sub.{u2} R _inst_1)) p q)) (HSub.hSub.{u1, u1, u1} S S S (instHSub.{u1} S (Ring.toSub.{u1} S _inst_2)) (Polynomial.eval₂.{u2, u1} R S (Ring.toSemiring.{u2} R _inst_1) (Ring.toSemiring.{u1} S _inst_2) f x p) (Polynomial.eval₂.{u2, u1} R S (Ring.toSemiring.{u2} R _inst_1) (Ring.toSemiring.{u1} S _inst_2) f x q))
Case conversion may be inaccurate. Consider using '#align polynomial.eval₂_sub Polynomial.eval₂_subₓ'. -/
@[simp]
theorem eval₂_sub {S} [Ring S] (f : R →+* S) {x : S} :
    (p - q).eval₂ f x = p.eval₂ f x - q.eval₂ f x := by
  rw [sub_eq_add_neg, eval₂_add, eval₂_neg, sub_eq_add_neg]
#align polynomial.eval₂_sub Polynomial.eval₂_sub

/- warning: polynomial.eval_neg -> Polynomial.eval_neg is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Ring.{u1} R] (p : Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (x : R), Eq.{succ u1} R (Polynomial.eval.{u1} R (Ring.toSemiring.{u1} R _inst_1) x (Neg.neg.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.neg'.{u1} R _inst_1) p)) (Neg.neg.{u1} R (SubNegMonoid.toHasNeg.{u1} R (AddGroup.toSubNegMonoid.{u1} R (AddGroupWithOne.toAddGroup.{u1} R (AddCommGroupWithOne.toAddGroupWithOne.{u1} R (Ring.toAddCommGroupWithOne.{u1} R _inst_1))))) (Polynomial.eval.{u1} R (Ring.toSemiring.{u1} R _inst_1) x p))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Ring.{u1} R] (p : Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (x : R), Eq.{succ u1} R (Polynomial.eval.{u1} R (Ring.toSemiring.{u1} R _inst_1) x (Neg.neg.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.neg'.{u1} R _inst_1) p)) (Neg.neg.{u1} R (Ring.toNeg.{u1} R _inst_1) (Polynomial.eval.{u1} R (Ring.toSemiring.{u1} R _inst_1) x p))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_neg Polynomial.eval_negₓ'. -/
@[simp]
theorem eval_neg (p : R[X]) (x : R) : (-p).eval x = -p.eval x :=
  eval₂_neg _
#align polynomial.eval_neg Polynomial.eval_neg

/- warning: polynomial.eval_sub -> Polynomial.eval_sub is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} [_inst_1 : Ring.{u1} R] (p : Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (q : Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (x : R), Eq.{succ u1} R (Polynomial.eval.{u1} R (Ring.toSemiring.{u1} R _inst_1) x (HSub.hSub.{u1, u1, u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (instHSub.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.sub.{u1} R _inst_1)) p q)) (HSub.hSub.{u1, u1, u1} R R R (instHSub.{u1} R (SubNegMonoid.toHasSub.{u1} R (AddGroup.toSubNegMonoid.{u1} R (AddGroupWithOne.toAddGroup.{u1} R (AddCommGroupWithOne.toAddGroupWithOne.{u1} R (Ring.toAddCommGroupWithOne.{u1} R _inst_1)))))) (Polynomial.eval.{u1} R (Ring.toSemiring.{u1} R _inst_1) x p) (Polynomial.eval.{u1} R (Ring.toSemiring.{u1} R _inst_1) x q))
but is expected to have type
  forall {R : Type.{u1}} [_inst_1 : Ring.{u1} R] (p : Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (q : Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (x : R), Eq.{succ u1} R (Polynomial.eval.{u1} R (Ring.toSemiring.{u1} R _inst_1) x (HSub.hSub.{u1, u1, u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (instHSub.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.sub.{u1} R _inst_1)) p q)) (HSub.hSub.{u1, u1, u1} R R R (instHSub.{u1} R (Ring.toSub.{u1} R _inst_1)) (Polynomial.eval.{u1} R (Ring.toSemiring.{u1} R _inst_1) x p) (Polynomial.eval.{u1} R (Ring.toSemiring.{u1} R _inst_1) x q))
Case conversion may be inaccurate. Consider using '#align polynomial.eval_sub Polynomial.eval_subₓ'. -/
@[simp]
theorem eval_sub (p q : R[X]) (x : R) : (p - q).eval x = p.eval x - q.eval x :=
  eval₂_sub _
#align polynomial.eval_sub Polynomial.eval_sub

/- warning: polynomial.root_X_sub_C -> Polynomial.root_X_sub_C is a dubious translation:
lean 3 declaration is
  forall {R : Type.{u1}} {a : R} {b : R} [_inst_1 : Ring.{u1} R], Iff (Polynomial.IsRoot.{u1} R (Ring.toSemiring.{u1} R _inst_1) (HSub.hSub.{u1, u1, u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (instHSub.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.sub.{u1} R _inst_1)) (Polynomial.X.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (coeFn.{succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (fun (_x : RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) => R -> (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (RingHom.hasCoeToFun.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (Polynomial.C.{u1} R (Ring.toSemiring.{u1} R _inst_1)) a)) b) (Eq.{succ u1} R a b)
but is expected to have type
  forall {R : Type.{u1}} {a : R} {b : R} [_inst_1 : Ring.{u1} R], Iff (Polynomial.IsRoot.{u1} R (Ring.toSemiring.{u1} R _inst_1) (HSub.hSub.{u1, u1, u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) ((fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) a) (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (instHSub.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.sub.{u1} R _inst_1)) (Polynomial.X.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (FunLike.coe.{succ u1, succ u1, succ u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (fun (_x : R) => (fun (x._@.Mathlib.Algebra.Hom.Group._hyg.2391 : R) => Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) _x) (MulHomClass.toFunLike.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (NonUnitalNonAssocSemiring.toMul.{u1} R (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (NonUnitalNonAssocSemiring.toMul.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))))) (NonUnitalRingHomClass.toMulHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} R (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (NonAssocSemiring.toNonUnitalNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) (RingHomClass.toNonUnitalRingHomClass.{u1, u1, u1} (RingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)))) R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))) (RingHom.instRingHomClassRingHom.{u1, u1} R (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Semiring.toNonAssocSemiring.{u1} (Polynomial.{u1} R (Ring.toSemiring.{u1} R _inst_1)) (Polynomial.semiring.{u1} R (Ring.toSemiring.{u1} R _inst_1))))))) (Polynomial.C.{u1} R (Ring.toSemiring.{u1} R _inst_1)) a)) b) (Eq.{succ u1} R a b)
Case conversion may be inaccurate. Consider using '#align polynomial.root_X_sub_C Polynomial.root_X_sub_Cₓ'. -/
theorem root_X_sub_C : IsRoot (X - C a) b ↔ a = b := by
  rw [is_root.def, eval_sub, eval_X, eval_C, sub_eq_zero, eq_comm]
#align polynomial.root_X_sub_C Polynomial.root_X_sub_C

#print Polynomial.neg_comp /-
@[simp]
theorem neg_comp : (-p).comp q = -p.comp q :=
  eval₂_neg _
#align polynomial.neg_comp Polynomial.neg_comp
-/

#print Polynomial.sub_comp /-
@[simp]
theorem sub_comp : (p - q).comp r = p.comp r - q.comp r :=
  eval₂_sub _
#align polynomial.sub_comp Polynomial.sub_comp
-/

#print Polynomial.cast_int_comp /-
@[simp]
theorem cast_int_comp (i : ℤ) : comp (i : R[X]) p = i := by cases i <;> simp
#align polynomial.cast_int_comp Polynomial.cast_int_comp
-/

end Ring

end Polynomial