l3lab/ntp-mathlib huggingface dataset:
theorem sinh_sub_id_strictMono : StrictMono fun x => sinh x - x := by
  -- Porting note: `by simp; abel` was just `by simp` in mathlib3.
  refine' strictMono_of_odd_strictMonoOn_nonneg (fun x => by simp; abel) _
  refine' (convex_Ici _).strictMonoOn_of_deriv_pos _ fun x hx => _
  · exact (continuous_sinh.sub continuous_id).continuousOn
  · rw [interior_Ici, mem_Ioi] at hx
    

Proof state:
case refine'_2
x✝ y z x : ℝ
hx : 0 < x
⊢ 0 < deriv (fun x => sinh x - x) x

Next tactic:
rw [deriv_sub, deriv_sinh, deriv_id'', sub_pos, one_lt_cosh]
theorem sinh_sub_id_strictMono : StrictMono fun x => sinh x - x := by
  -- Porting note: `by simp; abel` was just `by simp` in mathlib3.
  refine' strictMono_of_odd_strictMonoOn_nonneg (fun x => by simp; abel) _
  refine' (convex_Ici _).strictMonoOn_of_deriv_pos _ fun x hx => _
  · exact (continuous_sinh.sub continuous_id).continuousOn
  · rw [interior_Ici, mem_Ioi] at hx
    rw [deriv_sub, deriv_sinh, deriv_id'', sub_pos, one_lt_cosh]
    

Proof state:
case refine'_2
x✝ y z x : ℝ
hx : 0 < x
⊢ x ≠ 0
case refine'_2.hf
x✝ y z x : ℝ
hx : 0 < x
⊢ DifferentiableAt ℝ (fun x => sinh x) x
case refine'_2.hg x✝ y z x : ℝ hx : 0 < x ⊢ DifferentiableAt ℝ (fun x => x) x

Next tactic:
exacts [hx.ne', differentiableAt_sinh, differentiableAt_id]
@[simp]
theorem self_le_sinh_iff : x ≤ sinh x ↔ 0 ≤ x :=
  calc
    x ≤ sinh x ↔ sinh 0 - 0 ≤ sinh x - x := by 

Proof state:
x y z : ℝ
⊢ x ≤ sinh x ↔ sinh 0 - 0 ≤ sinh x - x

Next tactic:
simp
@[simp]
theorem sinh_le_self_iff : sinh x ≤ x ↔ x ≤ 0 :=
  calc
    sinh x ≤ x ↔ sinh x - x ≤ sinh 0 - 0 := by 

Proof state:
x y z : ℝ
⊢ sinh x ≤ x ↔ sinh x - x ≤ sinh 0 - 0

Next tactic:
simp
protected theorem apply {x : α} (hx : IsFixedPt f x) : IsFixedPt f (f x) := by 

Proof state:
α : Type u
β : Type v
f fa g : α → α
x✝ y : α
fb : β → β
m n k : ℕ
e : Perm α
x : α
hx : IsFixedPt f x
⊢ IsFixedPt f (f x)

Next tactic:
convert hx
theorem preimage_iterate {s : Set α} (h : IsFixedPt (Set.preimage f) s) (n : ℕ) :
    IsFixedPt (Set.preimage f^[n]) s := by
  

Proof state:
α : Type u
β : Type v
f fa g : α → α
x y : α
fb : β → β
m n✝ k : ℕ
e : Perm α
s : Set α
h : IsFixedPt (Set.preimage f) s
n : ℕ
⊢ IsFixedPt (Set.preimage f^[n]) s

Next tactic:
rw [Set.preimage_iterate_eq]
theorem preimage_iterate {s : Set α} (h : IsFixedPt (Set.preimage f) s) (n : ℕ) :
    IsFixedPt (Set.preimage f^[n]) s := by
  rw [Set.preimage_iterate_eq]
  

Proof state:
α : Type u
β : Type v
f fa g : α → α
x y : α
fb : β → β
m n✝ k : ℕ
e : Perm α
s : Set α
h : IsFixedPt (Set.preimage f) s
n : ℕ
⊢ IsFixedPt (Set.preimage f)^[n] s

Next tactic:
exact h.iterate n
protected theorem perm_pow (h : IsFixedPt e x) (n : ℕ) : IsFixedPt (⇑(e ^ n)) x := by
  

Proof state:
α : Type u
β : Type v
f fa g : α → α
x y : α
fb : β → β
m n✝ k : ℕ
e : Perm α
h : IsFixedPt (⇑e) x
n : ℕ
⊢ IsFixedPt (⇑(e ^ n)) x

Next tactic:
rw [Equiv.Perm.coe_pow]
protected theorem perm_pow (h : IsFixedPt e x) (n : ℕ) : IsFixedPt (⇑(e ^ n)) x := by
  rw [Equiv.Perm.coe_pow]
  

Proof state:
α : Type u
β : Type v
f fa g : α → α
x y : α
fb : β → β
m n✝ k : ℕ
e : Perm α
h : IsFixedPt (⇑e) x
n : ℕ
⊢ IsFixedPt (⇑e)^[n] x

Next tactic:
exact h.iterate _
theorem mem_fixedPoints_iff {α : Type*} {f : α → α} {x : α} : x ∈ fixedPoints f ↔ f x = x := by
  

Proof state:
α✝ : Type u
β : Type v
f✝ fa g : α✝ → α✝
x✝ y : α✝
fb : β → β
m n k : ℕ
e : Perm α✝
α : Type u_1
f : α → α
x : α
⊢ x ∈ fixedPoints f ↔ f x = x

Next tactic:
rfl
@[simp]
theorem fixedPoints_id : fixedPoints (@id α) = Set.univ :=
  Set.ext fun _ => by 

Proof state:
α : Type u
β : Type v
f fa g : α → α
x y : α
fb : β → β
m n k : ℕ
e : Perm α
x✝ : α
⊢ x✝ ∈ fixedPoints id ↔ x✝ ∈ Set.univ

Next tactic:
simpa using isFixedPt_id _
/-- If self-maps `f` and `g` commute, then they are inverse of each other on the set of fixed points
of `f ∘ g`. This is a particular case of `Function.invOn_fixedPoints_comp`. -/
theorem Commute.invOn_fixedPoints_comp (h : Commute f g) :
    Set.InvOn f g (fixedPoints <| f ∘ g) (fixedPoints <| f ∘ g) := by
  

Proof state:
α : Type u
β : Type v
f fa g : α → α
x y : α
fb : β → β
m n k : ℕ
e : Perm α
h : Function.Commute f g
⊢ Set.InvOn f g (fixedPoints (f ∘ g)) (fixedPoints (f ∘ g))

Next tactic:
simpa only [h.comp_eq] using Function.invOn_fixedPoints_comp f g
/-- If self-maps `f` and `g` commute, then `f` is bijective on the set of fixed points of `f ∘ g`.
This is a particular case of `Function.bijOn_fixedPoints_comp`. -/
theorem Commute.left_bijOn_fixedPoints_comp (h : Commute f g) :
    Set.BijOn f (fixedPoints <| f ∘ g) (fixedPoints <| f ∘ g) := by
  

Proof state:
α : Type u
β : Type v
f fa g : α → α
x y : α
fb : β → β
m n k : ℕ
e : Perm α
h : Function.Commute f g
⊢ Set.BijOn f (fixedPoints (f ∘ g)) (fixedPoints (f ∘ g))

Next tactic:
simpa only [h.comp_eq] using bijOn_fixedPoints_comp g f
/-- If self-maps `f` and `g` commute, then `g` is bijective on the set of fixed points of `f ∘ g`.
This is a particular case of `Function.bijOn_fixedPoints_comp`. -/
theorem Commute.right_bijOn_fixedPoints_comp (h : Commute f g) :
    Set.BijOn g (fixedPoints <| f ∘ g) (fixedPoints <| f ∘ g) := by
  

Proof state:
α : Type u
β : Type v
f fa g : α → α
x y : α
fb : β → β
m n k : ℕ
e : Perm α
h : Function.Commute f g
⊢ Set.BijOn g (fixedPoints (f ∘ g)) (fixedPoints (f ∘ g))

Next tactic:
simpa only [h.comp_eq] using bijOn_fixedPoints_comp f g
@[ext]
lemma ext {x y : RelSeries r} (length_eq : x.length = y.length)
    (toFun_eq : x.toFun = y.toFun ∘ Fin.cast (by 

Proof state:
α : Type u_1
r : Rel α α
x y : RelSeries r
length_eq : x.length = y.length
⊢ x.length + 1 = y.length + 1

Next tactic:
rw [length_eq]
@[ext]
lemma ext {x y : RelSeries r} (length_eq : x.length = y.length)
    (toFun_eq : x.toFun = y.toFun ∘ Fin.cast (by rw [length_eq])) : x = y := by
  

Proof state:
α : Type u_1
r : Rel α α
x y : RelSeries r
length_eq : x.length = y.length
toFun_eq : x.toFun = y.toFun ∘ Fin.cast (_ : x.length + 1 = y.length + 1)
⊢ x = y

Next tactic:
rcases x with ⟨nx, fx⟩
@[ext]
lemma ext {x y : RelSeries r} (length_eq : x.length = y.length)
    (toFun_eq : x.toFun = y.toFun ∘ Fin.cast (by rw [length_eq])) : x = y := by
  rcases x with ⟨nx, fx⟩
  

Proof state:
case mk
α : Type u_1
r : Rel α α
y : RelSeries r
nx : ℕ
fx : Fin (nx + 1) → α
step✝ : ∀ (i : Fin nx), r (fx (Fin.castSucc i)) (fx (Fin.succ i))
length_eq : { length := nx, toFun := fx, step := step✝ }.length = y.length
toFun_eq :
  { length := nx, toFun := fx, step := step✝ }.toFun =
    y.toFun ∘ Fin.cast (_ : { length := nx, toFun := fx, step := step✝ }.length + 1 = y.length + 1)
⊢ { length := nx, toFun := fx, step := step✝ } = y

Next tactic:
dsimp only at length_eq toFun_eq
@[ext]
lemma ext {x y : RelSeries r} (length_eq : x.length = y.length)
    (toFun_eq : x.toFun = y.toFun ∘ Fin.cast (by rw [length_eq])) : x = y := by
  rcases x with ⟨nx, fx⟩
  dsimp only at length_eq toFun_eq
  

Proof state:
case mk
α : Type u_1
r : Rel α α
y : RelSeries r
nx : ℕ
fx : Fin (nx + 1) → α
step✝ : ∀ (i : Fin nx), r (fx (Fin.castSucc i)) (fx (Fin.succ i))
length_eq : nx = y.length
toFun_eq : fx = y.toFun ∘ Fin.cast (_ : nx + 1 = y.length + 1)
⊢ { length := nx, toFun := fx, step := step✝ } = y

Next tactic:
subst length_eq toFun_eq
@[ext]
lemma ext {x y : RelSeries r} (length_eq : x.length = y.length)
    (toFun_eq : x.toFun = y.toFun ∘ Fin.cast (by rw [length_eq])) : x = y := by
  rcases x with ⟨nx, fx⟩
  dsimp only at length_eq toFun_eq
  subst length_eq toFun_eq
  

Proof state:
case mk
α : Type u_1
r : Rel α α
y : RelSeries r
step✝ :
  ∀ (i : Fin y.length),
    r ((y.toFun ∘ Fin.cast (_ : y.length + 1 = y.length + 1)) (Fin.castSucc i))
      ((y.toFun ∘ Fin.cast (_ : y.length + 1 = y.length + 1)) (Fin.succ i))
⊢ { length := y.length, toFun := y.toFun ∘ Fin.cast (_ : y.length + 1 = y.length + 1), step := step✝ } = y

Next tactic:
rfl
lemma toList_chain' (x : RelSeries r) : x.toList.Chain' r := by
  

Proof state:
α : Type u_1
r : Rel α α
x : RelSeries r
⊢ List.Chain' r (toList x)

Next tactic:
rw [List.chain'_iff_get]
lemma toList_chain' (x : RelSeries r) : x.toList.Chain' r := by
  rw [List.chain'_iff_get]
  

Proof state:
α : Type u_1
r : Rel α α
x : RelSeries r
⊢ ∀ (i : ℕ) (h : i < List.length (toList x) - 1),
    r (List.get (toList x) { val := i, isLt := (_ : i < List.length (toList x)) })
      (List.get (toList x) { val := i + 1, isLt := (_ : Nat.succ i < List.length (toList x)) })

Next tactic:
intros i h
lemma toList_chain' (x : RelSeries r) : x.toList.Chain' r := by
  rw [List.chain'_iff_get]
  intros i h
  

Proof state:
α : Type u_1
r : Rel α α
x : RelSeries r
i : ℕ
h : i < List.length (toList x) - 1
⊢ r (List.get (toList x) { val := i, isLt := (_ : i < List.length (toList x)) })
    (List.get (toList x) { val := i + 1, isLt := (_ : Nat.succ i < List.length (toList x)) })

Next tactic:
convert x.step ⟨i, by simpa using h⟩
lemma toList_chain' (x : RelSeries r) : x.toList.Chain' r := by
  rw [List.chain'_iff_get]
  intros i h
  convert x.step ⟨i, by 

Proof state:
α : Type u_1
r : Rel α α
x : RelSeries r
i : ℕ
h : i < List.length (toList x) - 1
⊢ i < x.length

Next tactic:
simpa using h
lemma toList_chain' (x : RelSeries r) : x.toList.Chain' r := by
  rw [List.chain'_iff_get]
  intros i h
  convert x.step ⟨i, by simpa using h⟩ <;> 

Proof state:
case h.e'_1
α : Type u_1
r : Rel α α
x : RelSeries r
i : ℕ
h : i < List.length (toList x) - 1
⊢ List.get (toList x) { val := i, isLt := (_ : i < List.length (toList x)) } =
    toFun x (Fin.castSucc { val := i, isLt := (_ : i < x.length) })

Next tactic:
apply List.get_ofFn
lemma toList_chain' (x : RelSeries r) : x.toList.Chain' r := by
  rw [List.chain'_iff_get]
  intros i h
  convert x.step ⟨i, by simpa using h⟩ <;> 

Proof state:
case h.e'_2
α : Type u_1
r : Rel α α
x : RelSeries r
i : ℕ
h : i < List.length (toList x) - 1
⊢ List.get (toList x) { val := i + 1, isLt := (_ : Nat.succ i < List.length (toList x)) } =
    toFun x (Fin.succ { val := i, isLt := (_ : i < x.length) })

Next tactic:
apply List.get_ofFn
/-- Relation series of `r` and nonempty list of `α` satisfying `r`-chain condition bijectively
corresponds to each other.-/
protected def Equiv : RelSeries r ≃ {x : List α | x ≠ [] ∧ x.Chain' r} where
  toFun x := ⟨_, x.toList_ne_empty, x.toList_chain'⟩
  invFun x := fromListChain' _ x.2.1 x.2.2
  left_inv x := ext (by 

Proof state:
α : Type u_1
r : Rel α α
x : RelSeries r
⊢ ((fun x => fromListChain' ↑x (_ : ↑x ≠ []) (_ : List.Chain' r ↑x))
        ((fun x => { val := toList x, property := (_ : toList x ≠ [] ∧ List.Chain' r (toList x)) }) x)).length =
    x.length

Next tactic:
simp
/-- Relation series of `r` and nonempty list of `α` satisfying `r`-chain condition bijectively
corresponds to each other.-/
protected def Equiv : RelSeries r ≃ {x : List α | x ≠ [] ∧ x.Chain' r} where
  toFun x := ⟨_, x.toList_ne_empty, x.toList_chain'⟩
  invFun x := fromListChain' _ x.2.1 x.2.2
  left_inv x := ext (by simp) <| by 

Proof state:
α : Type u_1
r : Rel α α
x : RelSeries r
⊢ ((fun x => fromListChain' ↑x (_ : ↑x ≠ []) (_ : List.Chain' r ↑x))
        ((fun x => { val := toList x, property := (_ : toList x ≠ [] ∧ List.Chain' r (toList x)) }) x)).toFun =
    x.toFun ∘
      Fin.cast
        (_ :
          ((fun x => fromListChain' ↑x (_ : ↑x ≠ []) (_ : List.Chain' r ↑x))
                  ((fun x => { val := toList x, property := (_ : toList x ≠ [] ∧ List.Chain' r (toList x)) })
                    x)).length +
              1 =
            x.length + 1)

Next tactic:
ext
/-- Relation series of `r` and nonempty list of `α` satisfying `r`-chain condition bijectively
corresponds to each other.-/
protected def Equiv : RelSeries r ≃ {x : List α | x ≠ [] ∧ x.Chain' r} where
  toFun x := ⟨_, x.toList_ne_empty, x.toList_chain'⟩
  invFun x := fromListChain' _ x.2.1 x.2.2
  left_inv x := ext (by simp) <| by ext; 

Proof state:
case h
α : Type u_1
r : Rel α α
x : RelSeries r
x✝ :
  Fin
    (((fun x => fromListChain' ↑x (_ : ↑x ≠ []) (_ : List.Chain' r ↑x))
          ((fun x => { val := toList x, property := (_ : toList x ≠ [] ∧ List.Chain' r (toList x)) }) x)).length +
      1)
⊢ toFun
      ((fun x => fromListChain' ↑x (_ : ↑x ≠ []) (_ : List.Chain' r ↑x))
        ((fun x => { val := toList x, property := (_ : toList x ≠ [] ∧ List.Chain' r (toList x)) }) x))
      x✝ =
    (x.toFun ∘
        Fin.cast
          (_ :
            ((fun x => fromListChain' ↑x (_ : ↑x ≠ []) (_ : List.Chain' r ↑x))
                    ((fun x => { val := toList x, property := (_ : toList x ≠ [] ∧ List.Chain' r (toList x)) })
                      x)).length +
                1 =
              x.length + 1))
      x✝

Next tactic:
apply List.get_ofFn
/-- Relation series of `r` and nonempty list of `α` satisfying `r`-chain condition bijectively
corresponds to each other.-/
protected def Equiv : RelSeries r ≃ {x : List α | x ≠ [] ∧ x.Chain' r} where
  toFun x := ⟨_, x.toList_ne_empty, x.toList_chain'⟩
  invFun x := fromListChain' _ x.2.1 x.2.2
  left_inv x := ext (by simp) <| by ext; apply List.get_ofFn
  right_inv x := by
    

Proof state:
α : Type u_1
r : Rel α α
x : ↑{x | x ≠ [] ∧ List.Chain' r x}
⊢ (fun x => { val := toList x, property := (_ : toList x ≠ [] ∧ List.Chain' r (toList x)) })
      ((fun x => fromListChain' ↑x (_ : ↑x ≠ []) (_ : List.Chain' r ↑x)) x) =
    x

Next tactic:
refine Subtype.ext (List.ext_get ?_ <| fun n hn1 _ => List.get_ofFn _ _)
/-- Relation series of `r` and nonempty list of `α` satisfying `r`-chain condition bijectively
corresponds to each other.-/
protected def Equiv : RelSeries r ≃ {x : List α | x ≠ [] ∧ x.Chain' r} where
  toFun x := ⟨_, x.toList_ne_empty, x.toList_chain'⟩
  invFun x := fromListChain' _ x.2.1 x.2.2
  left_inv x := ext (by simp) <| by ext; apply List.get_ofFn
  right_inv x := by
    refine Subtype.ext (List.ext_get ?_ <| fun n hn1 _ => List.get_ofFn _ _)
    

Proof state:
α : Type u_1
r : Rel α α
x : ↑{x | x ≠ [] ∧ List.Chain' r x}
⊢ List.length
      ↑((fun x => { val := toList x, property := (_ : toList x ≠ [] ∧ List.Chain' r (toList x)) })
          ((fun x => fromListChain' ↑x (_ : ↑x ≠ []) (_ : List.Chain' r ↑x)) x)) =
    List.length ↑x

Next tactic:
simp [Nat.succ_pred_eq_of_pos <| List.length_pos.mpr x.2.1]
lemma isNilpotent_C_mul_pow_X_of_isNilpotent (n : ℕ) (hnil : IsNilpotent r) :
    IsNilpotent ((C r) * X ^ n) := by
  

Proof state:
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
n : ℕ
hnil : IsNilpotent r
⊢ IsNilpotent (C r * X ^ n)

Next tactic:
refine' Commute.isNilpotent_mul_left (commute_X_pow _ _).symm _
lemma isNilpotent_C_mul_pow_X_of_isNilpotent (n : ℕ) (hnil : IsNilpotent r) :
    IsNilpotent ((C r) * X ^ n) := by
  refine' Commute.isNilpotent_mul_left (commute_X_pow _ _).symm _
  

Proof state:
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
n : ℕ
hnil : IsNilpotent r
⊢ IsNilpotent (C r)

Next tactic:
obtain ⟨m, hm⟩ := hnil
lemma isNilpotent_C_mul_pow_X_of_isNilpotent (n : ℕ) (hnil : IsNilpotent r) :
    IsNilpotent ((C r) * X ^ n) := by
  refine' Commute.isNilpotent_mul_left (commute_X_pow _ _).symm _
  obtain ⟨m, hm⟩ := hnil
  

Proof state:
case intro
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
n m : ℕ
hm : r ^ m = 0
⊢ IsNilpotent (C r)

Next tactic:
refine' ⟨m, _⟩
lemma isNilpotent_C_mul_pow_X_of_isNilpotent (n : ℕ) (hnil : IsNilpotent r) :
    IsNilpotent ((C r) * X ^ n) := by
  refine' Commute.isNilpotent_mul_left (commute_X_pow _ _).symm _
  obtain ⟨m, hm⟩ := hnil
  refine' ⟨m, _⟩
  

Proof state:
case intro
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
n m : ℕ
hm : r ^ m = 0
⊢ C r ^ m = 0

Next tactic:
rw [← C_pow, hm, C_0]
lemma isNilpotent_pow_X_mul_C_of_isNilpotent (n : ℕ) (hnil : IsNilpotent r) :
    IsNilpotent (X ^ n * (C r)) := by
  

Proof state:
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
n : ℕ
hnil : IsNilpotent r
⊢ IsNilpotent (X ^ n * C r)

Next tactic:
rw [commute_X_pow]
lemma isNilpotent_pow_X_mul_C_of_isNilpotent (n : ℕ) (hnil : IsNilpotent r) :
    IsNilpotent (X ^ n * (C r)) := by
  rw [commute_X_pow]
  

Proof state:
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
n : ℕ
hnil : IsNilpotent r
⊢ IsNilpotent (C r * X ^ n)

Next tactic:
exact isNilpotent_C_mul_pow_X_of_isNilpotent n hnil
@[simp] lemma isNilpotent_monomial_iff {n : ℕ} :
    IsNilpotent (monomial (R := R) n r) ↔ IsNilpotent r :=
  exists_congr fun k ↦ by 

Proof state:
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
n k : ℕ
⊢ (monomial n) r ^ k = 0 ↔ r ^ k = 0

Next tactic:
simp
@[simp] lemma isNilpotent_C_iff :
    IsNilpotent (C r) ↔ IsNilpotent r :=
  exists_congr fun k ↦ by 

Proof state:
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
k : ℕ
⊢ C r ^ k = 0 ↔ r ^ k = 0

Next tactic:
simpa only [← C_pow] using C_eq_zero
@[simp] lemma isNilpotent_X_mul_iff :
    IsNilpotent (X * P) ↔ IsNilpotent P := by
  

Proof state:
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
⊢ IsNilpotent (X * P) ↔ IsNilpotent P

Next tactic:
refine' ⟨fun h ↦ _, _⟩
@[simp] lemma isNilpotent_X_mul_iff :
    IsNilpotent (X * P) ↔ IsNilpotent P := by
  refine' ⟨fun h ↦ _, _⟩
  · 

Proof state:
case refine'_1
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
h : IsNilpotent (X * P)
⊢ IsNilpotent P

Next tactic:
rwa [Commute.isNilpotent_mul_right_iff (commute_X P) (by simp)] at h
@[simp] lemma isNilpotent_X_mul_iff :
    IsNilpotent (X * P) ↔ IsNilpotent P := by
  refine' ⟨fun h ↦ _, _⟩
  · rwa [Commute.isNilpotent_mul_right_iff (commute_X P) (by 

Proof state:
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
h : IsNilpotent (X * P)
⊢ X ∈ nonZeroDivisorsRight R[X]

Next tactic:
simp
@[simp] lemma isNilpotent_X_mul_iff :
    IsNilpotent (X * P) ↔ IsNilpotent P := by
  refine' ⟨fun h ↦ _, _⟩
  · rwa [Commute.isNilpotent_mul_right_iff (commute_X P) (by simp)] at h
  · 

Proof state:
case refine'_2
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
⊢ IsNilpotent P → IsNilpotent (X * P)

Next tactic:
rintro ⟨k, hk⟩
@[simp] lemma isNilpotent_X_mul_iff :
    IsNilpotent (X * P) ↔ IsNilpotent P := by
  refine' ⟨fun h ↦ _, _⟩
  · rwa [Commute.isNilpotent_mul_right_iff (commute_X P) (by simp)] at h
  · rintro ⟨k, hk⟩
    

Proof state:
case refine'_2.intro
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
k : ℕ
hk : P ^ k = 0
⊢ IsNilpotent (X * P)

Next tactic:
exact ⟨k, by simp [(commute_X P).mul_pow, hk]⟩
@[simp] lemma isNilpotent_X_mul_iff :
    IsNilpotent (X * P) ↔ IsNilpotent P := by
  refine' ⟨fun h ↦ _, _⟩
  · rwa [Commute.isNilpotent_mul_right_iff (commute_X P) (by simp)] at h
  · rintro ⟨k, hk⟩
    exact ⟨k, by 

Proof state:
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
k : ℕ
hk : P ^ k = 0
⊢ (X * P) ^ k = 0

Next tactic:
simp [(commute_X P).mul_pow, hk]
@[simp] lemma isNilpotent_mul_X_iff :
    IsNilpotent (P * X) ↔ IsNilpotent P := by
  

Proof state:
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
⊢ IsNilpotent (P * X) ↔ IsNilpotent P

Next tactic:
rw [← commute_X P]
@[simp] lemma isNilpotent_mul_X_iff :
    IsNilpotent (P * X) ↔ IsNilpotent P := by
  rw [← commute_X P]
  

Proof state:
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
⊢ IsNilpotent (X * P) ↔ IsNilpotent P

Next tactic:
exact isNilpotent_X_mul_iff
protected lemma isNilpotent_iff :
    IsNilpotent P ↔ ∀ i, IsNilpotent (coeff P i) := by
  

Proof state:
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
⊢ IsNilpotent P ↔ ∀ (i : ℕ), IsNilpotent (coeff P i)

Next tactic:
refine' ⟨P.recOnHorner (by simp) (fun p r hp₀ _ hp hpr i ↦ _) (fun p _ hnp hpX i ↦ _), fun h ↦ _⟩
protected lemma isNilpotent_iff :
    IsNilpotent P ↔ ∀ i, IsNilpotent (coeff P i) := by
  refine' ⟨P.recOnHorner (by 

Proof state:
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
⊢ IsNilpotent 0 → ∀ (i : ℕ), IsNilpotent (coeff 0 i)

Next tactic:
simp
protected lemma isNilpotent_iff :
    IsNilpotent P ↔ ∀ i, IsNilpotent (coeff P i) := by
  refine' ⟨P.recOnHorner (by simp) (fun p r hp₀ _ hp hpr i ↦ _) (fun p _ hnp hpX i ↦ _), fun h ↦ _⟩
  · 

Proof state:
case refine'_1
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
h : ∀ (i : ℕ), IsNilpotent (coeff P i)
⊢ IsNilpotent P

Next tactic:
rw [← sum_monomial_eq P]
protected lemma isNilpotent_iff :
    IsNilpotent P ↔ ∀ i, IsNilpotent (coeff P i) := by
  refine' ⟨P.recOnHorner (by simp) (fun p r hp₀ _ hp hpr i ↦ _) (fun p _ hnp hpX i ↦ _), fun h ↦ _⟩
  · rw [← sum_monomial_eq P]
    

Proof state:
case refine'_1
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
h : ∀ (i : ℕ), IsNilpotent (coeff P i)
⊢ IsNilpotent (sum P fun n a => (monomial n) a)

Next tactic:
exact isNilpotent_sum (fun i _ ↦ by simpa only [isNilpotent_monomial_iff] using h i)
protected lemma isNilpotent_iff :
    IsNilpotent P ↔ ∀ i, IsNilpotent (coeff P i) := by
  refine' ⟨P.recOnHorner (by simp) (fun p r hp₀ _ hp hpr i ↦ _) (fun p _ hnp hpX i ↦ _), fun h ↦ _⟩
  · rw [← sum_monomial_eq P]
    exact isNilpotent_sum (fun i _ ↦ by 

Proof state:
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
h : ∀ (i : ℕ), IsNilpotent (coeff P i)
i : ℕ
x✝ : i ∈ support P
⊢ IsNilpotent ((fun n a => (monomial n) a) i (coeff P i))

Next tactic:
simpa only [isNilpotent_monomial_iff] using h i
protected lemma isNilpotent_iff :
    IsNilpotent P ↔ ∀ i, IsNilpotent (coeff P i) := by
  refine' ⟨P.recOnHorner (by simp) (fun p r hp₀ _ hp hpr i ↦ _) (fun p _ hnp hpX i ↦ _), fun h ↦ _⟩
  · rw [← sum_monomial_eq P]
    exact isNilpotent_sum (fun i _ ↦ by simpa only [isNilpotent_monomial_iff] using h i)
  · 

Proof state:
case refine'_2
R : Type u_1
r✝ : R
inst✝ : CommRing R
P p : R[X]
r : R
hp₀ : coeff p 0 = 0
x✝ : r ≠ 0
hp : IsNilpotent p → ∀ (i : ℕ), IsNilpotent (coeff p i)
hpr : IsNilpotent (p + C r)
i : ℕ
⊢ IsNilpotent (coeff (p + C r) i)

Next tactic:
have hr : IsNilpotent (C r) := by
      obtain ⟨k, hk⟩ := hpr
      replace hp : eval 0 p = 0 := by rwa [coeff_zero_eq_aeval_zero] at hp₀
      refine' isNilpotent_C_iff.mpr ⟨k, _⟩
      simpa [coeff_zero_eq_aeval_zero, hp] using congr_arg (fun q ↦ coeff q 0) hk
protected lemma isNilpotent_iff :
    IsNilpotent P ↔ ∀ i, IsNilpotent (coeff P i) := by
  refine' ⟨P.recOnHorner (by simp) (fun p r hp₀ _ hp hpr i ↦ _) (fun p _ hnp hpX i ↦ _), fun h ↦ _⟩
  · rw [← sum_monomial_eq P]
    exact isNilpotent_sum (fun i _ ↦ by simpa only [isNilpotent_monomial_iff] using h i)
  · have hr : IsNilpotent (C r) := by
      

Proof state:
R : Type u_1
r✝ : R
inst✝ : CommRing R
P p : R[X]
r : R
hp₀ : coeff p 0 = 0
x✝ : r ≠ 0
hp : IsNilpotent p → ∀ (i : ℕ), IsNilpotent (coeff p i)
hpr : IsNilpotent (p + C r)
i : ℕ
⊢ IsNilpotent (C r)

Next tactic:
obtain ⟨k, hk⟩ := hpr
protected lemma isNilpotent_iff :
    IsNilpotent P ↔ ∀ i, IsNilpotent (coeff P i) := by
  refine' ⟨P.recOnHorner (by simp) (fun p r hp₀ _ hp hpr i ↦ _) (fun p _ hnp hpX i ↦ _), fun h ↦ _⟩
  · rw [← sum_monomial_eq P]
    exact isNilpotent_sum (fun i _ ↦ by simpa only [isNilpotent_monomial_iff] using h i)
  · have hr : IsNilpotent (C r) := by
      obtain ⟨k, hk⟩ := hpr
      

Proof state:
case intro
R : Type u_1
r✝ : R
inst✝ : CommRing R
P p : R[X]
r : R
hp₀ : coeff p 0 = 0
x✝ : r ≠ 0
hp : IsNilpotent p → ∀ (i : ℕ), IsNilpotent (coeff p i)
i k : ℕ
hk : (p + C r) ^ k = 0
⊢ IsNilpotent (C r)

Next tactic:
replace hp : eval 0 p = 0 := by rwa [coeff_zero_eq_aeval_zero] at hp₀
protected lemma isNilpotent_iff :
    IsNilpotent P ↔ ∀ i, IsNilpotent (coeff P i) := by
  refine' ⟨P.recOnHorner (by simp) (fun p r hp₀ _ hp hpr i ↦ _) (fun p _ hnp hpX i ↦ _), fun h ↦ _⟩
  · rw [← sum_monomial_eq P]
    exact isNilpotent_sum (fun i _ ↦ by simpa only [isNilpotent_monomial_iff] using h i)
  · have hr : IsNilpotent (C r) := by
      obtain ⟨k, hk⟩ := hpr
      replace hp : eval 0 p = 0 := by 

Proof state:
R : Type u_1
r✝ : R
inst✝ : CommRing R
P p : R[X]
r : R
hp₀ : coeff p 0 = 0
x✝ : r ≠ 0
hp : IsNilpotent p → ∀ (i : ℕ), IsNilpotent (coeff p i)
i k : ℕ
hk : (p + C r) ^ k = 0
⊢ eval 0 p = 0

Next tactic:
rwa [coeff_zero_eq_aeval_zero] at hp₀
protected lemma isNilpotent_iff :
    IsNilpotent P ↔ ∀ i, IsNilpotent (coeff P i) := by
  refine' ⟨P.recOnHorner (by simp) (fun p r hp₀ _ hp hpr i ↦ _) (fun p _ hnp hpX i ↦ _), fun h ↦ _⟩
  · rw [← sum_monomial_eq P]
    exact isNilpotent_sum (fun i _ ↦ by simpa only [isNilpotent_monomial_iff] using h i)
  · have hr : IsNilpotent (C r) := by
      obtain ⟨k, hk⟩ := hpr
      replace hp : eval 0 p = 0 := by rwa [coeff_zero_eq_aeval_zero] at hp₀
      

Proof state:
case intro
R : Type u_1
r✝ : R
inst✝ : CommRing R
P p : R[X]
r : R
hp₀ : coeff p 0 = 0
x✝ : r ≠ 0
i k : ℕ
hk : (p + C r) ^ k = 0
hp : eval 0 p = 0
⊢ IsNilpotent (C r)

Next tactic:
refine' isNilpotent_C_iff.mpr ⟨k, _⟩