l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem eval_one_map (f : R →+* S) (p : R[X]) : (p.map f).eval 1 = f (p.eval 1) := by
  -- Porting note: `apply` → `induction`
  induction p using Polynomial.induction_on' with
  

Proof state:
case h_add
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : Semiring R
p✝ q✝ r : R[X]
inst✝ : Semiring S
f✝ f : R →+* S
p q : R[X]
hp : eval 1 (map f p) = f (eval 1 p)
hq : eval 1 (map f q) = f (eval 1 q)
⊢ eval 1 (map f (p + q)) = f (eval 1 (p + q))

Next tactic:
| h_add p q hp hq =>
    simp only [hp, hq, Polynomial.map_add, RingHom.map_add, eval_add]
@[simp]
theorem eval_one_map (f : R →+* S) (p : R[X]) : (p.map f).eval 1 = f (p.eval 1) := by
  -- Porting note: `apply` → `induction`
  induction p using Polynomial.induction_on' with
  | h_add p q hp hq =>
    

Proof state:
case h_add
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : Semiring R
p✝ q✝ r : R[X]
inst✝ : Semiring S
f✝ f : R →+* S
p q : R[X]
hp : eval 1 (map f p) = f (eval 1 p)
hq : eval 1 (map f q) = f (eval 1 q)
⊢ eval 1 (map f (p + q)) = f (eval 1 (p + q))

Next tactic:
simp only [hp, hq, Polynomial.map_add, RingHom.map_add, eval_add]
@[simp]
theorem eval_one_map (f : R →+* S) (p : R[X]) : (p.map f).eval 1 = f (p.eval 1) := by
  -- Porting note: `apply` → `induction`
  induction p using Polynomial.induction_on' with
  | h_add p q hp hq =>
    simp only [hp, hq, Polynomial.map_add, RingHom.map_add, eval_add]
  

Proof state:
case h_monomial
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p q r✝ : R[X]
inst✝ : Semiring S
f✝ f : R →+* S
n : ℕ
r : R
⊢ eval 1 (map f ((monomial n) r)) = f (eval 1 ((monomial n) r))

Next tactic:
| h_monomial n r =>
    simp only [one_pow, mul_one, eval_monomial, map_monomial]
@[simp]
theorem eval_one_map (f : R →+* S) (p : R[X]) : (p.map f).eval 1 = f (p.eval 1) := by
  -- Porting note: `apply` → `induction`
  induction p using Polynomial.induction_on' with
  | h_add p q hp hq =>
    simp only [hp, hq, Polynomial.map_add, RingHom.map_add, eval_add]
  | h_monomial n r =>
    

Proof state:
case h_monomial
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p q r✝ : R[X]
inst✝ : Semiring S
f✝ f : R →+* S
n : ℕ
r : R
⊢ eval 1 (map f ((monomial n) r)) = f (eval 1 ((monomial n) r))

Next tactic:
simp only [one_pow, mul_one, eval_monomial, map_monomial]
@[simp]
theorem eval_nat_cast_map (f : R →+* S) (p : R[X]) (n : ℕ) :
    (p.map f).eval (n : S) = f (p.eval n) := by
  -- Porting note: `apply` → `induction`
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p✝ q r : R[X]
inst✝ : Semiring S
f✝ f : R →+* S
p : R[X]
n : ℕ
⊢ eval (↑n) (map f p) = f (eval (↑n) p)

Next tactic:
induction p using Polynomial.induction_on' with
  | h_add p q hp hq =>
    simp only [hp, hq, Polynomial.map_add, RingHom.map_add, eval_add]
  | h_monomial n r =>
    simp only [map_natCast f, eval_monomial, map_monomial, f.map_pow, f.map_mul]
@[simp]
theorem eval_nat_cast_map (f : R →+* S) (p : R[X]) (n : ℕ) :
    (p.map f).eval (n : S) = f (p.eval n) := by
  -- Porting note: `apply` → `induction`
  induction p using Polynomial.induction_on' with
  

Proof state:
case h_add
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p✝ q✝ r : R[X]
inst✝ : Semiring S
f✝ f : R →+* S
n : ℕ
p q : R[X]
hp : eval (↑n) (map f p) = f (eval (↑n) p)
hq : eval (↑n) (map f q) = f (eval (↑n) q)
⊢ eval (↑n) (map f (p + q)) = f (eval (↑n) (p + q))

Next tactic:
| h_add p q hp hq =>
    simp only [hp, hq, Polynomial.map_add, RingHom.map_add, eval_add]
@[simp]
theorem eval_nat_cast_map (f : R →+* S) (p : R[X]) (n : ℕ) :
    (p.map f).eval (n : S) = f (p.eval n) := by
  -- Porting note: `apply` → `induction`
  induction p using Polynomial.induction_on' with
  | h_add p q hp hq =>
    

Proof state:
case h_add
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p✝ q✝ r : R[X]
inst✝ : Semiring S
f✝ f : R →+* S
n : ℕ
p q : R[X]
hp : eval (↑n) (map f p) = f (eval (↑n) p)
hq : eval (↑n) (map f q) = f (eval (↑n) q)
⊢ eval (↑n) (map f (p + q)) = f (eval (↑n) (p + q))

Next tactic:
simp only [hp, hq, Polynomial.map_add, RingHom.map_add, eval_add]
@[simp]
theorem eval_nat_cast_map (f : R →+* S) (p : R[X]) (n : ℕ) :
    (p.map f).eval (n : S) = f (p.eval n) := by
  -- Porting note: `apply` → `induction`
  induction p using Polynomial.induction_on' with
  | h_add p q hp hq =>
    simp only [hp, hq, Polynomial.map_add, RingHom.map_add, eval_add]
  

Proof state:
case h_monomial
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n✝¹ : ℕ
inst✝¹ : Semiring R
p q r✝ : R[X]
inst✝ : Semiring S
f✝ f : R →+* S
n✝ n : ℕ
r : R
⊢ eval (↑n✝) (map f ((monomial n) r)) = f (eval (↑n✝) ((monomial n) r))

Next tactic:
| h_monomial n r =>
    simp only [map_natCast f, eval_monomial, map_monomial, f.map_pow, f.map_mul]
@[simp]
theorem eval_nat_cast_map (f : R →+* S) (p : R[X]) (n : ℕ) :
    (p.map f).eval (n : S) = f (p.eval n) := by
  -- Porting note: `apply` → `induction`
  induction p using Polynomial.induction_on' with
  | h_add p q hp hq =>
    simp only [hp, hq, Polynomial.map_add, RingHom.map_add, eval_add]
  | h_monomial n r =>
    

Proof state:
case h_monomial
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n✝¹ : ℕ
inst✝¹ : Semiring R
p q r✝ : R[X]
inst✝ : Semiring S
f✝ f : R →+* S
n✝ n : ℕ
r : R
⊢ eval (↑n✝) (map f ((monomial n) r)) = f (eval (↑n✝) ((monomial n) r))

Next tactic:
simp only [map_natCast f, eval_monomial, map_monomial, f.map_pow, f.map_mul]
@[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 : S) = f (p.eval i) := by
  -- Porting note: `apply` → `induction`
  

Proof state:
R✝ : Type u
S✝ : Type v
T : Type w
ι : Type y
a b : R✝
m n : ℕ
inst✝³ : Semiring R✝
p✝ q r : R✝[X]
inst✝² : Semiring S✝
f✝ : R✝ →+* S✝
R : Type u_1
S : Type u_2
inst✝¹ : Ring R
inst✝ : Ring S
f : R →+* S
p : R[X]
i : ℤ
⊢ eval (↑i) (map f p) = f (eval (↑i) p)

Next tactic:
induction p using Polynomial.induction_on' with
  | h_add p q hp hq =>
    simp only [hp, hq, Polynomial.map_add, RingHom.map_add, eval_add]
  | h_monomial n r =>
    simp only [map_intCast, eval_monomial, map_monomial, map_pow, map_mul]
@[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 : S) = f (p.eval i) := by
  -- Porting note: `apply` → `induction`
  induction p using Polynomial.induction_on' with
  

Proof state:
case h_add
R✝ : Type u
S✝ : Type v
T : Type w
ι : Type y
a b : R✝
m n : ℕ
inst✝³ : Semiring R✝
p✝ q✝ r : R✝[X]
inst✝² : Semiring S✝
f✝ : R✝ →+* S✝
R : Type u_1
S : Type u_2
inst✝¹ : Ring R
inst✝ : Ring S
f : R →+* S
i : ℤ
p q : R[X]
hp : eval (↑i) (map f p) = f (eval (↑i) p)
hq : eval (↑i) (map f q) = f (eval (↑i) q)
⊢ eval (↑i) (map f (p + q)) = f (eval (↑i) (p + q))

Next tactic:
| h_add p q hp hq =>
    simp only [hp, hq, Polynomial.map_add, RingHom.map_add, eval_add]
@[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 : S) = f (p.eval i) := by
  -- Porting note: `apply` → `induction`
  induction p using Polynomial.induction_on' with
  | h_add p q hp hq =>
    

Proof state:
case h_add
R✝ : Type u
S✝ : Type v
T : Type w
ι : Type y
a b : R✝
m n : ℕ
inst✝³ : Semiring R✝
p✝ q✝ r : R✝[X]
inst✝² : Semiring S✝
f✝ : R✝ →+* S✝
R : Type u_1
S : Type u_2
inst✝¹ : Ring R
inst✝ : Ring S
f : R →+* S
i : ℤ
p q : R[X]
hp : eval (↑i) (map f p) = f (eval (↑i) p)
hq : eval (↑i) (map f q) = f (eval (↑i) q)
⊢ eval (↑i) (map f (p + q)) = f (eval (↑i) (p + q))

Next tactic:
simp only [hp, hq, Polynomial.map_add, RingHom.map_add, eval_add]
@[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 : S) = f (p.eval i) := by
  -- Porting note: `apply` → `induction`
  induction p using Polynomial.induction_on' with
  | h_add p q hp hq =>
    simp only [hp, hq, Polynomial.map_add, RingHom.map_add, eval_add]
  

Proof state:
case h_monomial
R✝ : Type u
S✝ : Type v
T : Type w
ι : Type y
a b : R✝
m n✝ : ℕ
inst✝³ : Semiring R✝
p q r✝ : R✝[X]
inst✝² : Semiring S✝
f✝ : R✝ →+* S✝
R : Type u_1
S : Type u_2
inst✝¹ : Ring R
inst✝ : Ring S
f : R →+* S
i : ℤ
n : ℕ
r : R
⊢ eval (↑i) (map f ((monomial n) r)) = f (eval (↑i) ((monomial n) r))

Next tactic:
| h_monomial n r =>
    simp only [map_intCast, eval_monomial, map_monomial, map_pow, map_mul]
@[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 : S) = f (p.eval i) := by
  -- Porting note: `apply` → `induction`
  induction p using Polynomial.induction_on' with
  | h_add p q hp hq =>
    simp only [hp, hq, Polynomial.map_add, RingHom.map_add, eval_add]
  | h_monomial n r =>
    

Proof state:
case h_monomial
R✝ : Type u
S✝ : Type v
T : Type w
ι : Type y
a b : R✝
m n✝ : ℕ
inst✝³ : Semiring R✝
p q r✝ : R✝[X]
inst✝² : Semiring S✝
f✝ : R✝ →+* S✝
R : Type u_1
S : Type u_2
inst✝¹ : Ring R
inst✝ : Ring S
f : R →+* S
i : ℤ
n : ℕ
r : R
⊢ eval (↑i) (map f ((monomial n) r)) = f (eval (↑i) ((monomial n) r))

Next tactic:
simp only [map_intCast, eval_monomial, map_monomial, map_pow, map_mul]
theorem hom_eval₂ (x : S) : g (p.eval₂ f x) = p.eval₂ (g.comp f) (g x) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝² : Semiring R
p q r : R[X]
inst✝¹ : Semiring S
inst✝ : Semiring T
f : R →+* S
g : S →+* T
x : S
⊢ g (eval₂ f x p) = eval₂ (RingHom.comp g f) (g x) p

Next tactic:
rw [← eval₂_map, eval₂_at_apply, eval_map]
theorem eval₂_comp {x : S} : eval₂ f x (p.comp q) = eval₂ f (eval₂ f x q) p := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q : R[X]
x✝ : R
inst✝ : CommSemiring S
f : R →+* S
x : S
⊢ eval₂ f x (comp p q) = eval₂ f (eval₂ f x q) p

Next tactic:
rw [comp, p.as_sum_range]
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]; 

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q : R[X]
x✝ : R
inst✝ : CommSemiring S
f : R →+* S
x : S
⊢ eval₂ f x (eval₂ C q (∑ i in range (natDegree p + 1), (monomial i) (coeff p i))) =
    eval₂ f (eval₂ f x q) (∑ i in range (natDegree p + 1), (monomial i) (coeff p i))

Next tactic:
simp [eval₂_finset_sum, eval₂_pow]
@[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
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q : R[X]
x : R
inst✝ : CommSemiring S
f : R →+* S
k : ℕ
t : S
⊢ eval₂ f t ((comp p)^[k] q) = (fun x => eval₂ f x p)^[k] (eval₂ f t q)

Next tactic:
induction' k with k IH
@[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
  · 

Proof state:
case zero
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q : R[X]
x : R
inst✝ : CommSemiring S
f : R →+* S
t : S
⊢ eval₂ f t ((comp p)^[Nat.zero] q) = (fun x => eval₂ f x p)^[Nat.zero] (eval₂ f t q)

Next tactic:
simp
@[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
  · 

Proof state:
case succ
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q : R[X]
x : R
inst✝ : CommSemiring S
f : R →+* S
t : S
k : ℕ
IH : eval₂ f t ((comp p)^[k] q) = (fun x => eval₂ f x p)^[k] (eval₂ f t q)
⊢ eval₂ f t ((comp p)^[Nat.succ k] q) = (fun x => eval₂ f x p)^[Nat.succ k] (eval₂ f t q)

Next tactic:
rw [Function.iterate_succ_apply', Function.iterate_succ_apply', eval₂_comp, IH]
@[simp]
theorem eval_comp : (p.comp q).eval x = p.eval (q.eval x) := by
  -- Porting note: `apply` → `induction`
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : CommSemiring R
p q : R[X]
x : R
inst✝ : CommSemiring S
f : R →+* S
⊢ eval x (comp p q) = eval (eval x q) p

Next tactic:
induction p using Polynomial.induction_on' with
  | h_add r s hr hs =>
    simp [add_comp, hr, hs]
  | h_monomial n a =>
    simp
@[simp]
theorem eval_comp : (p.comp q).eval x = p.eval (q.eval x) := by
  -- Porting note: `apply` → `induction`
  induction p using Polynomial.induction_on' with
  

Proof state:
case h_add
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : CommSemiring R
p q : R[X]
x : R
inst✝ : CommSemiring S
f : R →+* S
r s : R[X]
hr : eval x (comp r q) = eval (eval x q) r
hs : eval x (comp s q) = eval (eval x q) s
⊢ eval x (comp (r + s) q) = eval (eval x q) (r + s)

Next tactic:
| h_add r s hr hs =>
    simp [add_comp, hr, hs]
@[simp]
theorem eval_comp : (p.comp q).eval x = p.eval (q.eval x) := by
  -- Porting note: `apply` → `induction`
  induction p using Polynomial.induction_on' with
  | h_add r s hr hs =>
    

Proof state:
case h_add
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : CommSemiring R
p q : R[X]
x : R
inst✝ : CommSemiring S
f : R →+* S
r s : R[X]
hr : eval x (comp r q) = eval (eval x q) r
hs : eval x (comp s q) = eval (eval x q) s
⊢ eval x (comp (r + s) q) = eval (eval x q) (r + s)

Next tactic:
simp [add_comp, hr, hs]
@[simp]
theorem eval_comp : (p.comp q).eval x = p.eval (q.eval x) := by
  -- Porting note: `apply` → `induction`
  induction p using Polynomial.induction_on' with
  | h_add r s hr hs =>
    simp [add_comp, hr, hs]
  

Proof state:
case h_monomial
R : Type u
S : Type v
T : Type w
ι : Type y
a✝ b : R
m n✝ : ℕ
inst✝¹ : CommSemiring R
p q : R[X]
x : R
inst✝ : CommSemiring S
f : R →+* S
n : ℕ
a : R
⊢ eval x (comp ((monomial n) a) q) = eval (eval x q) ((monomial n) a)

Next tactic:
| h_monomial n a =>
    simp
@[simp]
theorem eval_comp : (p.comp q).eval x = p.eval (q.eval x) := by
  -- Porting note: `apply` → `induction`
  induction p using Polynomial.induction_on' with
  | h_add r s hr hs =>
    simp [add_comp, hr, hs]
  | h_monomial n a =>
    

Proof state:
case h_monomial
R : Type u
S : Type v
T : Type w
ι : Type y
a✝ b : R
m n✝ : ℕ
inst✝¹ : CommSemiring R
p q : R[X]
x : R
inst✝ : CommSemiring S
f : R →+* S
n : ℕ
a : R
⊢ eval x (comp ((monomial n) a) q) = eval (eval x q) ((monomial n) a)

Next tactic:
simp
theorem root_mul_left_of_isRoot (p : R[X]) {q : R[X]} : IsRoot q a → IsRoot (p * q) a := fun H => by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : CommSemiring R
p✝ q✝ : R[X]
x : R
inst✝ : CommSemiring S
f : R →+* S
p q : R[X]
H : IsRoot q a
⊢ IsRoot (p * q) a

Next tactic:
rw [IsRoot, eval_mul, IsRoot.def.1 H, mul_zero]
theorem root_mul_right_of_isRoot {p : R[X]} (q : R[X]) : IsRoot p a → IsRoot (p * q) a := fun H =>
  by 

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : CommSemiring R
p✝ q✝ : R[X]
x : R
inst✝ : CommSemiring S
f : R →+* S
p q : R[X]
H : IsRoot p a
⊢ IsRoot (p * q) a

Next tactic:
rw [IsRoot, eval_mul, IsRoot.def.1 H, zero_mul]
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
  

Proof state:
R✝ : Type u
S : Type v
T : Type w
ι✝ : Type y
a b : R✝
m n : ℕ
inst✝³ : CommSemiring R✝
p✝ q : R✝[X]
x✝ : R✝
inst✝² : CommSemiring S
f : R✝ →+* S
R : Type u_2
inst✝¹ : CommRing R
inst✝ : IsDomain R
ι : Type u_1
s : Finset ι
p : ι → R[X]
x : R
⊢ IsRoot (∏ j in s, p j) x ↔ ∃ i ∈ s, IsRoot (p i) x

Next tactic:
simp only [IsRoot, eval_prod, Finset.prod_eq_zero_iff]
@[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 

Proof state:
R✝ : Type u
S : Type v
T : Type w
ι : Type y
a b : R✝
m n✝ : ℕ
inst✝² : CommSemiring R✝
p q : R✝[X]
x✝ : R✝
inst✝¹ : CommSemiring S
f : R✝ →+* S
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
x : R
⊢ eval x (∑ i in range n, X ^ i) = ∑ i in range n, x ^ i

Next tactic:
simp [eval_finset_sum]
theorem support_map_subset [Semiring R] [Semiring S] (f : R →+* S) (p : R[X]) :
    (map f p).support ⊆ p.support := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : Semiring R
inst✝ : Semiring S
f : R →+* S
p : R[X]
⊢ support (map f p) ⊆ support p

Next tactic:
intro x
theorem support_map_subset [Semiring R] [Semiring S] (f : R →+* S) (p : R[X]) :
    (map f p).support ⊆ p.support := by
  intro x
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : Semiring R
inst✝ : Semiring S
f : R →+* S
p : R[X]
x : ℕ
⊢ x ∈ support (map f p) → x ∈ support p

Next tactic:
contrapose!
theorem support_map_subset [Semiring R] [Semiring S] (f : R →+* S) (p : R[X]) :
    (map f p).support ⊆ p.support := by
  intro x
  contrapose!
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : Semiring R
inst✝ : Semiring S
f : R →+* S
p : R[X]
x : ℕ
⊢ x ∉ support p → x ∉ support (map f p)

Next tactic:
simp (config := { contextual := true })
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
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
f : R →+* S
hf : Function.Injective ⇑f
⊢ support (map f p) = support p

Next tactic:
simp_rw [Finset.ext_iff, mem_support_iff, coeff_map, ← map_zero f, hf.ne_iff,
    forall_const]
theorem IsRoot.map {f : R →+* S} {x : R} {p : R[X]} (h : IsRoot p x) : IsRoot (p.map f) (f x) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : CommSemiring R
inst✝ : CommSemiring S
f✝ f : R →+* S
x : R
p : R[X]
h : IsRoot p x
⊢ IsRoot (Polynomial.map f p) (f x)

Next tactic:
rw [IsRoot, eval_map, eval₂_hom, h.eq_zero, f.map_zero]
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
  

Proof state:
R✝ : Type u
S : Type v
T : Type w
ι : Type y
a b : R✝
m n : ℕ
inst✝² : CommSemiring R✝
inst✝¹ : CommSemiring S
f✝ : R✝ →+* S
R : Type u_1
inst✝ : CommRing R
f : R →+* S
x : R
p : R[X]
h : IsRoot (Polynomial.map f p) (f x)
hf : Function.Injective ⇑f
⊢ IsRoot p x

Next tactic:
rwa [IsRoot, ← (injective_iff_map_eq_zero' f).mp hf, ← eval₂_hom, ← eval_map]
@[simp]
theorem eval_int_cast {n : ℤ} {x : R} : (n : R[X]).eval x = n := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n✝ : ℕ
inst✝ : Ring R
p q r : R[X]
n : ℤ
x : R
⊢ eval x ↑n = ↑n

Next tactic:
simp only [← C_eq_int_cast, eval_C]
@[simp]
theorem eval₂_neg {S} [Ring S] (f : R →+* S) {x : S} : (-p).eval₂ f x = -p.eval₂ f x := by
  

Proof state:
R : Type u
S✝ : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : Ring R
p q r : R[X]
S : Type u_1
inst✝ : Ring S
f : R →+* S
x : S
⊢ eval₂ f x (-p) = -eval₂ f x p

Next tactic:
rw [eq_neg_iff_add_eq_zero, ← eval₂_add, add_left_neg, eval₂_zero]
@[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
  

Proof state:
R : Type u
S✝ : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝¹ : Ring R
p q r : R[X]
S : Type u_1
inst✝ : Ring S
f : R →+* S
x : S
⊢ eval₂ f x (p - q) = eval₂ f x p - eval₂ f x q

Next tactic:
rw [sub_eq_add_neg, eval₂_add, eval₂_neg, sub_eq_add_neg]
theorem root_X_sub_C : IsRoot (X - C a) b ↔ a = b := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Ring R
p q r : R[X]
⊢ IsRoot (X - C a) b ↔ a = b

Next tactic:
rw [IsRoot.def, eval_sub, eval_X, eval_C, sub_eq_zero, eq_comm]
@[simp]
theorem cast_int_comp (i : ℤ) : comp (i : R[X]) p = i := by 

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Ring R
p q r : R[X]
i : ℤ
⊢ comp (↑i) p = ↑i

Next tactic:
cases i
@[simp]
theorem cast_int_comp (i : ℤ) : comp (i : R[X]) p = i := by cases i <;> 

Proof state:
case ofNat
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Ring R
p q r : R[X]
a✝ : ℕ
⊢ comp (↑(Int.ofNat a✝)) p = ↑(Int.ofNat a✝)

Next tactic:
simp
@[simp]
theorem cast_int_comp (i : ℤ) : comp (i : R[X]) p = i := by cases i <;> 

Proof state:
case negSucc
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n : ℕ
inst✝ : Ring R
p q r : R[X]
a✝ : ℕ
⊢ comp (↑(Int.negSucc a✝)) p = ↑(Int.negSucc a✝)

Next tactic:
simp
@[simp]
theorem eval₂_at_int_cast {S : Type*} [Ring S] (f : R →+* S) (n : ℤ) :
    p.eval₂ f n = f (p.eval n) := by
  

Proof state:
R : Type u
S✝ : Type v
T : Type w
ι : Type y
a b : R
m n✝ : ℕ
inst✝¹ : Ring R
p q r : R[X]
S : Type u_1
inst✝ : Ring S
f : R →+* S
n : ℤ
⊢ eval₂ f (↑n) p = f (eval (↑n) p)

Next tactic:
convert eval₂_at_apply (p := p) f n
@[simp]
theorem eval₂_at_int_cast {S : Type*} [Ring S] (f : R →+* S) (n : ℤ) :
    p.eval₂ f n = f (p.eval n) := by
  convert eval₂_at_apply (p := p) f n
  

Proof state:
case h.e'_2.h.e'_6
R : Type u
S✝ : Type v
T : Type w
ι : Type y
a b : R
m n✝ : ℕ
inst✝¹ : Ring R
p q r : R[X]
S : Type u_1
inst✝ : Ring S
f : R →+* S
n : ℤ
⊢ ↑n = f ↑n

Next tactic:
simp
theorem mul_X_sub_int_cast_comp {n : ℕ} :
    (p * (X - (n : R[X]))).comp q = p.comp q * (q - n) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
a b : R
m n✝ : ℕ
inst✝ : Ring R
p q r : R[X]
n : ℕ
⊢ comp (p * (X - ↑n)) q = comp p q * (q - ↑n)

Next tactic:
rw [mul_sub, sub_comp, mul_X_comp, ← Nat.cast_comm, nat_cast_mul_comp, Nat.cast_comm, mul_sub]
instance smallList {α : Type v} [Small.{u} α] : Small.{u} (List α) := by
  

Proof state:
α : Type v
inst✝ : Small.{u, v} α
⊢ Small.{u, v} (List α)

Next tactic:
let e : (Σn, Vector α n) ≃ List α := Equiv.sigmaFiberEquiv List.length
instance smallList {α : Type v} [Small.{u} α] : Small.{u} (List α) := by
  let e : (Σn, Vector α n) ≃ List α := Equiv.sigmaFiberEquiv List.length
  

Proof state:
α : Type v
inst✝ : Small.{u, v} α
e : (n : ℕ) × Vector α n ≃ List α := Equiv.sigmaFiberEquiv List.length
⊢ Small.{u, v} (List α)

Next tactic:
exact small_of_surjective e.surjective
@[to_additive (attr := simp) zero_mem_addCentralizer]
theorem one_mem_centralizer [MulOneClass M] : (1 : M) ∈ centralizer S := by
  

Proof state:
M : Type u_1
S T : Set M
inst✝ : MulOneClass M
⊢ 1 ∈ centralizer S

Next tactic:
simp [mem_centralizer_iff]
@[simp]
theorem zero_mem_centralizer [MulZeroClass M] : (0 : M) ∈ centralizer S := by
  

Proof state:
M : Type u_1
S T : Set M
inst✝ : MulZeroClass M
⊢ 0 ∈ centralizer S

Next tactic:
simp [mem_centralizer_iff]
@[to_additive (attr := simp) add_mem_addCentralizer]
theorem mul_mem_centralizer [Semigroup M] (ha : a ∈ centralizer S) (hb : b ∈ centralizer S) :
    a * b ∈ centralizer S := fun g hg => by
  

Proof state:
M : Type u_1
S T : Set M
a b : M
inst✝ : Semigroup M
ha : a ∈ centralizer S
hb : b ∈ centralizer S
g : M
hg : g ∈ S
⊢ g * (a * b) = a * b * g

Next tactic:
rw [mul_assoc, ← hb g hg, ← mul_assoc, ha g hg, mul_assoc]
@[to_additive (attr := simp) neg_mem_addCentralizer]
theorem inv_mem_centralizer [Group M] (ha : a ∈ centralizer S) : a⁻¹ ∈ centralizer S :=
  fun g hg => by 

Proof state:
M : Type u_1
S T : Set M
a b : M
inst✝ : Group M
ha : a ∈ centralizer S
g : M
hg : g ∈ S
⊢ g * a⁻¹ = a⁻¹ * g

Next tactic:
rw [mul_inv_eq_iff_eq_mul, mul_assoc, eq_inv_mul_iff_mul_eq, ha g hg]
@[simp]
theorem add_mem_centralizer [Distrib M] (ha : a ∈ centralizer S) (hb : b ∈ centralizer S) :
    a + b ∈ centralizer S := fun c hc => by 

Proof state:
M : Type u_1
S T : Set M
a b : M
inst✝ : Distrib M
ha : a ∈ centralizer S
hb : b ∈ centralizer S
c : M
hc : c ∈ S
⊢ c * (a + b) = (a + b) * c

Next tactic:
rw [add_mul, mul_add, ha c hc, hb c hc]
@[simp]
theorem neg_mem_centralizer [Mul M] [HasDistribNeg M] (ha : a ∈ centralizer S) :
    -a ∈ centralizer S := fun c hc => by 

Proof state:
M : Type u_1
S T : Set M
a b : M
inst✝¹ : Mul M
inst✝ : HasDistribNeg M
ha : a ∈ centralizer S
c : M
hc : c ∈ S
⊢ c * -a = -a * c

Next tactic:
rw [mul_neg, ha c hc, neg_mul]
@[simp]
theorem inv_mem_centralizer₀ [GroupWithZero M] (ha : a ∈ centralizer S) : a⁻¹ ∈ centralizer S :=
  (eq_or_ne a 0).elim
    (fun h => by
      

Proof state:
M : Type u_1
S T : Set M
a b : M
inst✝ : GroupWithZero M
ha : a ∈ centralizer S
h : a = 0
⊢ a⁻¹ ∈ centralizer S

Next tactic:
rw [h, inv_zero]