l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem trunc_C (n) (a : R) : trunc (n + 1) (C R a) = Polynomial.C a :=
  Polynomial.ext fun m => by
    rw [coeff_trunc, coeff_C, Polynomial.coeff_C]
    split_ifs with H <;> 

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
n : ℕ
a : R
m : ℕ
H : ¬m < n + 1
h✝ : ¬m = 0
⊢ 0 = 0

Next tactic:
first |rfl|try simp_all
@[simp]
theorem trunc_C (n) (a : R) : trunc (n + 1) (C R a) = Polynomial.C a :=
  Polynomial.ext fun m => by
    rw [coeff_trunc, coeff_C, Polynomial.coeff_C]
    split_ifs with H <;> first |

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
n : ℕ
a : R
m : ℕ
H : ¬m < n + 1
h✝ : ¬m = 0
⊢ 0 = 0

Next tactic:
rfl
@[simp]
theorem trunc_add (n) (φ ψ : R⟦X⟧) : trunc n (φ + ψ) = trunc n φ + trunc n ψ :=
  Polynomial.ext fun m => by
    

Proof state:
R : Type u_1
inst✝ : Semiring R
n : ℕ
φ ψ : R⟦X⟧
m : ℕ
⊢ Polynomial.coeff (trunc n (φ + ψ)) m = Polynomial.coeff (trunc n φ + trunc n ψ) m

Next tactic:
simp only [coeff_trunc, AddMonoidHom.map_add, Polynomial.coeff_add]
@[simp]
theorem trunc_add (n) (φ ψ : R⟦X⟧) : trunc n (φ + ψ) = trunc n φ + trunc n ψ :=
  Polynomial.ext fun m => by
    simp only [coeff_trunc, AddMonoidHom.map_add, Polynomial.coeff_add]
    

Proof state:
R : Type u_1
inst✝ : Semiring R
n : ℕ
φ ψ : R⟦X⟧
m : ℕ
⊢ (if m < n then (coeff R m) (φ + ψ) else 0) = (if m < n then (coeff R m) φ else 0) + if m < n then (coeff R m) ψ else 0

Next tactic:
split_ifs with H
@[simp]
theorem trunc_add (n) (φ ψ : R⟦X⟧) : trunc n (φ + ψ) = trunc n φ + trunc n ψ :=
  Polynomial.ext fun m => by
    simp only [coeff_trunc, AddMonoidHom.map_add, Polynomial.coeff_add]
    split_ifs with H
    · 

Proof state:
case pos
R : Type u_1
inst✝ : Semiring R
n : ℕ
φ ψ : R⟦X⟧
m : ℕ
H : m < n
⊢ (coeff R m) (φ + ψ) = (coeff R m) φ + (coeff R m) ψ

Next tactic:
rfl
@[simp]
theorem trunc_add (n) (φ ψ : R⟦X⟧) : trunc n (φ + ψ) = trunc n φ + trunc n ψ :=
  Polynomial.ext fun m => by
    simp only [coeff_trunc, AddMonoidHom.map_add, Polynomial.coeff_add]
    split_ifs with H
    · rfl
    · 

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
n : ℕ
φ ψ : R⟦X⟧
m : ℕ
H : ¬m < n
⊢ 0 = 0 + 0

Next tactic:
rw [zero_add]
theorem trunc_succ (f : R⟦X⟧) (n : ℕ) :
    trunc n.succ f = trunc n f + Polynomial.monomial n (coeff R n f) := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
f : R⟦X⟧
n : ℕ
⊢ trunc (succ n) f = trunc n f + (Polynomial.monomial n) ((coeff R n) f)

Next tactic:
rw [trunc, Ico_zero_eq_range, sum_range_succ, trunc, Ico_zero_eq_range]
theorem natDegree_trunc_lt (f : R⟦X⟧) (n) : (trunc (n + 1) f).natDegree < n + 1 := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
f : R⟦X⟧
n : ℕ
⊢ natDegree (trunc (n + 1) f) < n + 1

Next tactic:
rw [lt_succ_iff, natDegree_le_iff_coeff_eq_zero]
theorem natDegree_trunc_lt (f : R⟦X⟧) (n) : (trunc (n + 1) f).natDegree < n + 1 := by
  rw [lt_succ_iff, natDegree_le_iff_coeff_eq_zero]
  

Proof state:
R : Type u_1
inst✝ : Semiring R
f : R⟦X⟧
n : ℕ
⊢ ∀ (N : ℕ), n < N → Polynomial.coeff (trunc (n + 1) f) N = 0

Next tactic:
intros
theorem natDegree_trunc_lt (f : R⟦X⟧) (n) : (trunc (n + 1) f).natDegree < n + 1 := by
  rw [lt_succ_iff, natDegree_le_iff_coeff_eq_zero]
  intros
  

Proof state:
R : Type u_1
inst✝ : Semiring R
f : R⟦X⟧
n N✝ : ℕ
a✝ : n < N✝
⊢ Polynomial.coeff (trunc (n + 1) f) N✝ = 0

Next tactic:
rw [coeff_trunc]
theorem natDegree_trunc_lt (f : R⟦X⟧) (n) : (trunc (n + 1) f).natDegree < n + 1 := by
  rw [lt_succ_iff, natDegree_le_iff_coeff_eq_zero]
  intros
  rw [coeff_trunc]
  

Proof state:
R : Type u_1
inst✝ : Semiring R
f : R⟦X⟧
n N✝ : ℕ
a✝ : n < N✝
⊢ (if N✝ < n + 1 then (coeff R N✝) f else 0) = 0

Next tactic:
split_ifs with h
theorem natDegree_trunc_lt (f : R⟦X⟧) (n) : (trunc (n + 1) f).natDegree < n + 1 := by
  rw [lt_succ_iff, natDegree_le_iff_coeff_eq_zero]
  intros
  rw [coeff_trunc]
  split_ifs with h
  · 

Proof state:
case pos
R : Type u_1
inst✝ : Semiring R
f : R⟦X⟧
n N✝ : ℕ
a✝ : n < N✝
h : N✝ < n + 1
⊢ (coeff R N✝) f = 0

Next tactic:
rw [lt_succ, ← not_lt] at h
theorem natDegree_trunc_lt (f : R⟦X⟧) (n) : (trunc (n + 1) f).natDegree < n + 1 := by
  rw [lt_succ_iff, natDegree_le_iff_coeff_eq_zero]
  intros
  rw [coeff_trunc]
  split_ifs with h
  · rw [lt_succ, ← not_lt] at h
    

Proof state:
case pos
R : Type u_1
inst✝ : Semiring R
f : R⟦X⟧
n N✝ : ℕ
a✝ : n < N✝
h : ¬n < N✝
⊢ (coeff R N✝) f = 0

Next tactic:
contradiction
theorem natDegree_trunc_lt (f : R⟦X⟧) (n) : (trunc (n + 1) f).natDegree < n + 1 := by
  rw [lt_succ_iff, natDegree_le_iff_coeff_eq_zero]
  intros
  rw [coeff_trunc]
  split_ifs with h
  · rw [lt_succ, ← not_lt] at h
    contradiction
  · 

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
f : R⟦X⟧
n N✝ : ℕ
a✝ : n < N✝
h : ¬N✝ < n + 1
⊢ 0 = 0

Next tactic:
rfl
theorem degree_trunc_lt (f : R⟦X⟧) (n) : (trunc n f).degree < n := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
f : R⟦X⟧
n : ℕ
⊢ degree (trunc n f) < ↑n

Next tactic:
rw [degree_lt_iff_coeff_zero]
theorem degree_trunc_lt (f : R⟦X⟧) (n) : (trunc n f).degree < n := by
  rw [degree_lt_iff_coeff_zero]
  

Proof state:
R : Type u_1
inst✝ : Semiring R
f : R⟦X⟧
n : ℕ
⊢ ∀ (m : ℕ), n ≤ m → Polynomial.coeff (trunc n f) m = 0

Next tactic:
intros
theorem degree_trunc_lt (f : R⟦X⟧) (n) : (trunc n f).degree < n := by
  rw [degree_lt_iff_coeff_zero]
  intros
  

Proof state:
R : Type u_1
inst✝ : Semiring R
f : R⟦X⟧
n m✝ : ℕ
a✝ : n ≤ m✝
⊢ Polynomial.coeff (trunc n f) m✝ = 0

Next tactic:
rw [coeff_trunc]
theorem degree_trunc_lt (f : R⟦X⟧) (n) : (trunc n f).degree < n := by
  rw [degree_lt_iff_coeff_zero]
  intros
  rw [coeff_trunc]
  

Proof state:
R : Type u_1
inst✝ : Semiring R
f : R⟦X⟧
n m✝ : ℕ
a✝ : n ≤ m✝
⊢ (if m✝ < n then (coeff R m✝) f else 0) = 0

Next tactic:
split_ifs with h
theorem degree_trunc_lt (f : R⟦X⟧) (n) : (trunc n f).degree < n := by
  rw [degree_lt_iff_coeff_zero]
  intros
  rw [coeff_trunc]
  split_ifs with h
  · 

Proof state:
case pos
R : Type u_1
inst✝ : Semiring R
f : R⟦X⟧
n m✝ : ℕ
a✝ : n ≤ m✝
h : m✝ < n
⊢ (coeff R m✝) f = 0

Next tactic:
rw [← not_le] at h
theorem degree_trunc_lt (f : R⟦X⟧) (n) : (trunc n f).degree < n := by
  rw [degree_lt_iff_coeff_zero]
  intros
  rw [coeff_trunc]
  split_ifs with h
  · rw [← not_le] at h
    

Proof state:
case pos
R : Type u_1
inst✝ : Semiring R
f : R⟦X⟧
n m✝ : ℕ
a✝ : n ≤ m✝
h : ¬n ≤ m✝
⊢ (coeff R m✝) f = 0

Next tactic:
contradiction
theorem degree_trunc_lt (f : R⟦X⟧) (n) : (trunc n f).degree < n := by
  rw [degree_lt_iff_coeff_zero]
  intros
  rw [coeff_trunc]
  split_ifs with h
  · rw [← not_le] at h
    contradiction
  · 

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
f : R⟦X⟧
n m✝ : ℕ
a✝ : n ≤ m✝
h : ¬m✝ < n
⊢ 0 = 0

Next tactic:
rfl
theorem eval₂_trunc_eq_sum_range {S : Type*} [Semiring S] (s : S) (G : R →+* S) (n) (f : R⟦X⟧) :
    (trunc n f).eval₂ G s = ∑ i in range n, G (coeff R i f) * s ^ i := by
  

Proof state:
R : Type u_1
inst✝¹ : Semiring R
S : Type u_2
inst✝ : Semiring S
s : S
G : R →+* S
n : ℕ
f : R⟦X⟧
⊢ eval₂ G s (trunc n f) = ∑ i in range n, G ((coeff R i) f) * s ^ i

Next tactic:
cases n with
  | zero =>
    rw [trunc_zero', range_zero, sum_empty, eval₂_zero]
  | succ n =>
    have := natDegree_trunc_lt f n
    rw [eval₂_eq_sum_range' (hn := this)]
    apply sum_congr rfl
    intro _ h
    rw [mem_range] at h
    congr
    rw [coeff_trunc, if_pos h]
theorem eval₂_trunc_eq_sum_range {S : Type*} [Semiring S] (s : S) (G : R →+* S) (n) (f : R⟦X⟧) :
    (trunc n f).eval₂ G s = ∑ i in range n, G (coeff R i f) * s ^ i := by
  cases n with
  

Proof state:
case zero
R : Type u_1
inst✝¹ : Semiring R
S : Type u_2
inst✝ : Semiring S
s : S
G : R →+* S
f : R⟦X⟧
⊢ eval₂ G s (trunc Nat.zero f) = ∑ i in range Nat.zero, G ((coeff R i) f) * s ^ i

Next tactic:
| zero =>
    rw [trunc_zero', range_zero, sum_empty, eval₂_zero]
theorem eval₂_trunc_eq_sum_range {S : Type*} [Semiring S] (s : S) (G : R →+* S) (n) (f : R⟦X⟧) :
    (trunc n f).eval₂ G s = ∑ i in range n, G (coeff R i f) * s ^ i := by
  cases n with
  | zero =>
    

Proof state:
case zero
R : Type u_1
inst✝¹ : Semiring R
S : Type u_2
inst✝ : Semiring S
s : S
G : R →+* S
f : R⟦X⟧
⊢ eval₂ G s (trunc Nat.zero f) = ∑ i in range Nat.zero, G ((coeff R i) f) * s ^ i

Next tactic:
rw [trunc_zero', range_zero, sum_empty, eval₂_zero]
theorem eval₂_trunc_eq_sum_range {S : Type*} [Semiring S] (s : S) (G : R →+* S) (n) (f : R⟦X⟧) :
    (trunc n f).eval₂ G s = ∑ i in range n, G (coeff R i f) * s ^ i := by
  cases n with
  | zero =>
    rw [trunc_zero', range_zero, sum_empty, eval₂_zero]
  

Proof state:
case succ
R : Type u_1
inst✝¹ : Semiring R
S : Type u_2
inst✝ : Semiring S
s : S
G : R →+* S
f : R⟦X⟧
n : ℕ
⊢ eval₂ G s (trunc (succ n) f) = ∑ i in range (succ n), G ((coeff R i) f) * s ^ i

Next tactic:
| succ n =>
    have := natDegree_trunc_lt f n
    rw [eval₂_eq_sum_range' (hn := this)]
    apply sum_congr rfl
    intro _ h
    rw [mem_range] at h
    congr
    rw [coeff_trunc, if_pos h]
theorem eval₂_trunc_eq_sum_range {S : Type*} [Semiring S] (s : S) (G : R →+* S) (n) (f : R⟦X⟧) :
    (trunc n f).eval₂ G s = ∑ i in range n, G (coeff R i f) * s ^ i := by
  cases n with
  | zero =>
    rw [trunc_zero', range_zero, sum_empty, eval₂_zero]
  | succ n =>
    

Proof state:
case succ
R : Type u_1
inst✝¹ : Semiring R
S : Type u_2
inst✝ : Semiring S
s : S
G : R →+* S
f : R⟦X⟧
n : ℕ
⊢ eval₂ G s (trunc (succ n) f) = ∑ i in range (succ n), G ((coeff R i) f) * s ^ i

Next tactic:
have := natDegree_trunc_lt f n
theorem eval₂_trunc_eq_sum_range {S : Type*} [Semiring S] (s : S) (G : R →+* S) (n) (f : R⟦X⟧) :
    (trunc n f).eval₂ G s = ∑ i in range n, G (coeff R i f) * s ^ i := by
  cases n with
  | zero =>
    rw [trunc_zero', range_zero, sum_empty, eval₂_zero]
  | succ n =>
    have := natDegree_trunc_lt f n
    

Proof state:
case succ
R : Type u_1
inst✝¹ : Semiring R
S : Type u_2
inst✝ : Semiring S
s : S
G : R →+* S
f : R⟦X⟧
n : ℕ
this : natDegree (trunc (n + 1) f) < n + 1
⊢ eval₂ G s (trunc (succ n) f) = ∑ i in range (succ n), G ((coeff R i) f) * s ^ i

Next tactic:
rw [eval₂_eq_sum_range' (hn := this)]
theorem eval₂_trunc_eq_sum_range {S : Type*} [Semiring S] (s : S) (G : R →+* S) (n) (f : R⟦X⟧) :
    (trunc n f).eval₂ G s = ∑ i in range n, G (coeff R i f) * s ^ i := by
  cases n with
  | zero =>
    rw [trunc_zero', range_zero, sum_empty, eval₂_zero]
  | succ n =>
    have := natDegree_trunc_lt f n
    rw [eval₂_eq_sum_range' (hn := this)]
    

Proof state:
case succ
R : Type u_1
inst✝¹ : Semiring R
S : Type u_2
inst✝ : Semiring S
s : S
G : R →+* S
f : R⟦X⟧
n : ℕ
this : natDegree (trunc (n + 1) f) < n + 1
⊢ ∑ i in range (n + 1), G (Polynomial.coeff (trunc (n + 1) f) i) * s ^ i =
    ∑ i in range (succ n), G ((coeff R i) f) * s ^ i

Next tactic:
apply sum_congr rfl
theorem eval₂_trunc_eq_sum_range {S : Type*} [Semiring S] (s : S) (G : R →+* S) (n) (f : R⟦X⟧) :
    (trunc n f).eval₂ G s = ∑ i in range n, G (coeff R i f) * s ^ i := by
  cases n with
  | zero =>
    rw [trunc_zero', range_zero, sum_empty, eval₂_zero]
  | succ n =>
    have := natDegree_trunc_lt f n
    rw [eval₂_eq_sum_range' (hn := this)]
    apply sum_congr rfl
    

Proof state:
case succ
R : Type u_1
inst✝¹ : Semiring R
S : Type u_2
inst✝ : Semiring S
s : S
G : R →+* S
f : R⟦X⟧
n : ℕ
this : natDegree (trunc (n + 1) f) < n + 1
⊢ ∀ x ∈ range (n + 1), G (Polynomial.coeff (trunc (n + 1) f) x) * s ^ x = G ((coeff R x) f) * s ^ x

Next tactic:
intro _ h
theorem eval₂_trunc_eq_sum_range {S : Type*} [Semiring S] (s : S) (G : R →+* S) (n) (f : R⟦X⟧) :
    (trunc n f).eval₂ G s = ∑ i in range n, G (coeff R i f) * s ^ i := by
  cases n with
  | zero =>
    rw [trunc_zero', range_zero, sum_empty, eval₂_zero]
  | succ n =>
    have := natDegree_trunc_lt f n
    rw [eval₂_eq_sum_range' (hn := this)]
    apply sum_congr rfl
    intro _ h
    

Proof state:
case succ
R : Type u_1
inst✝¹ : Semiring R
S : Type u_2
inst✝ : Semiring S
s : S
G : R →+* S
f : R⟦X⟧
n : ℕ
this : natDegree (trunc (n + 1) f) < n + 1
x✝ : ℕ
h : x✝ ∈ range (n + 1)
⊢ G (Polynomial.coeff (trunc (n + 1) f) x✝) * s ^ x✝ = G ((coeff R x✝) f) * s ^ x✝

Next tactic:
rw [mem_range] at h
theorem eval₂_trunc_eq_sum_range {S : Type*} [Semiring S] (s : S) (G : R →+* S) (n) (f : R⟦X⟧) :
    (trunc n f).eval₂ G s = ∑ i in range n, G (coeff R i f) * s ^ i := by
  cases n with
  | zero =>
    rw [trunc_zero', range_zero, sum_empty, eval₂_zero]
  | succ n =>
    have := natDegree_trunc_lt f n
    rw [eval₂_eq_sum_range' (hn := this)]
    apply sum_congr rfl
    intro _ h
    rw [mem_range] at h
    

Proof state:
case succ
R : Type u_1
inst✝¹ : Semiring R
S : Type u_2
inst✝ : Semiring S
s : S
G : R →+* S
f : R⟦X⟧
n : ℕ
this : natDegree (trunc (n + 1) f) < n + 1
x✝ : ℕ
h : x✝ < n + 1
⊢ G (Polynomial.coeff (trunc (n + 1) f) x✝) * s ^ x✝ = G ((coeff R x✝) f) * s ^ x✝

Next tactic:
congr
theorem eval₂_trunc_eq_sum_range {S : Type*} [Semiring S] (s : S) (G : R →+* S) (n) (f : R⟦X⟧) :
    (trunc n f).eval₂ G s = ∑ i in range n, G (coeff R i f) * s ^ i := by
  cases n with
  | zero =>
    rw [trunc_zero', range_zero, sum_empty, eval₂_zero]
  | succ n =>
    have := natDegree_trunc_lt f n
    rw [eval₂_eq_sum_range' (hn := this)]
    apply sum_congr rfl
    intro _ h
    rw [mem_range] at h
    congr
    

Proof state:
case succ.e_a.h.e_6.h
R : Type u_1
inst✝¹ : Semiring R
S : Type u_2
inst✝ : Semiring S
s : S
G : R →+* S
f : R⟦X⟧
n : ℕ
this : natDegree (trunc (n + 1) f) < n + 1
x✝ : ℕ
h : x✝ < n + 1
⊢ Polynomial.coeff (trunc (n + 1) f) x✝ = (coeff R x✝) f

Next tactic:
rw [coeff_trunc, if_pos h]
@[simp] theorem trunc_X (n) : trunc (n + 2) X = (Polynomial.X : R[X]) := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
n : ℕ
⊢ trunc (n + 2) X = Polynomial.X

Next tactic:
ext d
@[simp] theorem trunc_X (n) : trunc (n + 2) X = (Polynomial.X : R[X]) := by
  ext d
  

Proof state:
case a
R : Type u_1
inst✝ : Semiring R
n d : ℕ
⊢ Polynomial.coeff (trunc (n + 2) X) d = Polynomial.coeff Polynomial.X d

Next tactic:
rw [coeff_trunc, coeff_X]
@[simp] theorem trunc_X (n) : trunc (n + 2) X = (Polynomial.X : R[X]) := by
  ext d
  rw [coeff_trunc, coeff_X]
  

Proof state:
case a
R : Type u_1
inst✝ : Semiring R
n d : ℕ
⊢ (if d < n + 2 then if d = 1 then 1 else 0 else 0) = Polynomial.coeff Polynomial.X d

Next tactic:
split_ifs with h₁ h₂
@[simp] theorem trunc_X (n) : trunc (n + 2) X = (Polynomial.X : R[X]) := by
  ext d
  rw [coeff_trunc, coeff_X]
  split_ifs with h₁ h₂
  · 

Proof state:
case pos
R : Type u_1
inst✝ : Semiring R
n d : ℕ
h₁ : d < n + 2
h₂ : d = 1
⊢ 1 = Polynomial.coeff Polynomial.X d

Next tactic:
rw [h₂, coeff_X_one]
@[simp] theorem trunc_X (n) : trunc (n + 2) X = (Polynomial.X : R[X]) := by
  ext d
  rw [coeff_trunc, coeff_X]
  split_ifs with h₁ h₂
  · rw [h₂, coeff_X_one]
  · 

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
n d : ℕ
h₁ : d < n + 2
h₂ : ¬d = 1
⊢ 0 = Polynomial.coeff Polynomial.X d

Next tactic:
rw [coeff_X_of_ne_one h₂]
@[simp] theorem trunc_X (n) : trunc (n + 2) X = (Polynomial.X : R[X]) := by
  ext d
  rw [coeff_trunc, coeff_X]
  split_ifs with h₁ h₂
  · rw [h₂, coeff_X_one]
  · rw [coeff_X_of_ne_one h₂]
  · 

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
n d : ℕ
h₁ : ¬d < n + 2
⊢ 0 = Polynomial.coeff Polynomial.X d

Next tactic:
rw [coeff_X_of_ne_one]
@[simp] theorem trunc_X (n) : trunc (n + 2) X = (Polynomial.X : R[X]) := by
  ext d
  rw [coeff_trunc, coeff_X]
  split_ifs with h₁ h₂
  · rw [h₂, coeff_X_one]
  · rw [coeff_X_of_ne_one h₂]
  · rw [coeff_X_of_ne_one]
    

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
n d : ℕ
h₁ : ¬d < n + 2
⊢ d ≠ 1

Next tactic:
intro hd
@[simp] theorem trunc_X (n) : trunc (n + 2) X = (Polynomial.X : R[X]) := by
  ext d
  rw [coeff_trunc, coeff_X]
  split_ifs with h₁ h₂
  · rw [h₂, coeff_X_one]
  · rw [coeff_X_of_ne_one h₂]
  · rw [coeff_X_of_ne_one]
    intro hd
    

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
n d : ℕ
h₁ : ¬d < n + 2
hd : d = 1
⊢ False

Next tactic:
apply h₁
@[simp] theorem trunc_X (n) : trunc (n + 2) X = (Polynomial.X : R[X]) := by
  ext d
  rw [coeff_trunc, coeff_X]
  split_ifs with h₁ h₂
  · rw [h₂, coeff_X_one]
  · rw [coeff_X_of_ne_one h₂]
  · rw [coeff_X_of_ne_one]
    intro hd
    apply h₁
    

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
n d : ℕ
h₁ : ¬d < n + 2
hd : d = 1
⊢ d < n + 2

Next tactic:
rw [hd]
@[simp] theorem trunc_X (n) : trunc (n + 2) X = (Polynomial.X : R[X]) := by
  ext d
  rw [coeff_trunc, coeff_X]
  split_ifs with h₁ h₂
  · rw [h₂, coeff_X_one]
  · rw [coeff_X_of_ne_one h₂]
  · rw [coeff_X_of_ne_one]
    intro hd
    apply h₁
    rw [hd]
    

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
n d : ℕ
h₁ : ¬d < n + 2
hd : d = 1
⊢ 1 < n + 2

Next tactic:
exact n.one_lt_succ_succ
lemma trunc_X_of {n : ℕ} (hn : 2 ≤ n) : trunc n X = (Polynomial.X : R[X]) := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
n : ℕ
hn : 2 ≤ n
⊢ trunc n X = Polynomial.X

Next tactic:
cases n with
  | zero => contradiction
  | succ n =>
    cases n with
    | zero => contradiction
    | succ n => exact trunc_X n
lemma trunc_X_of {n : ℕ} (hn : 2 ≤ n) : trunc n X = (Polynomial.X : R[X]) := by
  cases n with
  

Proof state:
case zero
R : Type u_1
inst✝ : Semiring R
hn : 2 ≤ Nat.zero
⊢ trunc Nat.zero X = Polynomial.X

Next tactic:
| zero => contradiction
lemma trunc_X_of {n : ℕ} (hn : 2 ≤ n) : trunc n X = (Polynomial.X : R[X]) := by
  cases n with
  | zero => 

Proof state:
case zero
R : Type u_1
inst✝ : Semiring R
hn : 2 ≤ Nat.zero
⊢ trunc Nat.zero X = Polynomial.X

Next tactic:
contradiction
lemma trunc_X_of {n : ℕ} (hn : 2 ≤ n) : trunc n X = (Polynomial.X : R[X]) := by
  cases n with
  | zero => contradiction
  

Proof state:
case succ
R : Type u_1
inst✝ : Semiring R
n : ℕ
hn : 2 ≤ succ n
⊢ trunc (succ n) X = Polynomial.X

Next tactic:
| succ n =>
    cases n with
    | zero => contradiction
    | succ n => exact trunc_X n
lemma trunc_X_of {n : ℕ} (hn : 2 ≤ n) : trunc n X = (Polynomial.X : R[X]) := by
  cases n with
  | zero => contradiction
  | succ n =>
    

Proof state:
case succ
R : Type u_1
inst✝ : Semiring R
n : ℕ
hn : 2 ≤ succ n
⊢ trunc (succ n) X = Polynomial.X

Next tactic:
cases n with
    | zero => contradiction
    | succ n => exact trunc_X n
lemma trunc_X_of {n : ℕ} (hn : 2 ≤ n) : trunc n X = (Polynomial.X : R[X]) := by
  cases n with
  | zero => contradiction
  | succ n =>
    cases n with
    

Proof state:
case succ.zero
R : Type u_1
inst✝ : Semiring R
hn : 2 ≤ succ Nat.zero
⊢ trunc (succ Nat.zero) X = Polynomial.X

Next tactic:
| zero => contradiction
lemma trunc_X_of {n : ℕ} (hn : 2 ≤ n) : trunc n X = (Polynomial.X : R[X]) := by
  cases n with
  | zero => contradiction
  | succ n =>
    cases n with
    | zero => 

Proof state:
case succ.zero
R : Type u_1
inst✝ : Semiring R
hn : 2 ≤ succ Nat.zero
⊢ trunc (succ Nat.zero) X = Polynomial.X

Next tactic:
contradiction
lemma trunc_X_of {n : ℕ} (hn : 2 ≤ n) : trunc n X = (Polynomial.X : R[X]) := by
  cases n with
  | zero => contradiction
  | succ n =>
    cases n with
    | zero => contradiction
    

Proof state:
case succ.succ
R : Type u_1
inst✝ : Semiring R
n : ℕ
hn : 2 ≤ succ (succ n)
⊢ trunc (succ (succ n)) X = Polynomial.X

Next tactic:
| succ n => exact trunc_X n
lemma trunc_X_of {n : ℕ} (hn : 2 ≤ n) : trunc n X = (Polynomial.X : R[X]) := by
  cases n with
  | zero => contradiction
  | succ n =>
    cases n with
    | zero => contradiction
    | succ n => 

Proof state:
case succ.succ
R : Type u_1
inst✝ : Semiring R
n : ℕ
hn : 2 ≤ succ (succ n)
⊢ trunc (succ (succ n)) X = Polynomial.X

Next tactic:
exact trunc_X n
theorem coeff_inv_aux (n : ℕ) (a : R) (φ : R⟦X⟧) :
    coeff R n (inv.aux a φ) =
      if n = 0 then a
      else
        -a *
          ∑ x in antidiagonal n,
            if x.2 < n then coeff R x.1 φ * coeff R x.2 (inv.aux a φ) else 0 := by
  -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
  

Proof state:
R : Type u_1
inst✝ : Ring R
n : ℕ
a : R
φ : R⟦X⟧
⊢ (coeff R n) (inv.aux a φ) =
    if n = 0 then a
    else -a * ∑ x in antidiagonal n, if x.2 < n then (coeff R x.1) φ * (coeff R x.2) (inv.aux a φ) else 0

Next tactic:
erw [coeff, inv.aux, MvPowerSeries.coeff_inv_aux]
theorem coeff_inv_aux (n : ℕ) (a : R) (φ : R⟦X⟧) :
    coeff R n (inv.aux a φ) =
      if n = 0 then a
      else
        -a *
          ∑ x in antidiagonal n,
            if x.2 < n then coeff R x.1 φ * coeff R x.2 (inv.aux a φ) else 0 := by
  -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
  erw [coeff, inv.aux, MvPowerSeries.coeff_inv_aux]
  

Proof state:
R : Type u_1
inst✝ : Ring R
n : ℕ
a : R
φ : R⟦X⟧
⊢ (if (fun₀ | () => n) = 0 then a
    else
      -a *
        ∑ x in antidiagonal fun₀ | () => n,
          if x.2 < fun₀ | () => n then
            (MvPowerSeries.coeff R x.1) φ * (MvPowerSeries.coeff R x.2) (MvPowerSeries.inv.aux a φ)
          else 0) =
    if n = 0 then a
    else -a * ∑ x in antidiagonal n, if x.2 < n then (coeff R x.1) φ * (coeff R x.2) (MvPowerSeries.inv.aux a φ) else 0

Next tactic:
simp only [Finsupp.single_eq_zero]
theorem coeff_inv_aux (n : ℕ) (a : R) (φ : R⟦X⟧) :
    coeff R n (inv.aux a φ) =
      if n = 0 then a
      else
        -a *
          ∑ x in antidiagonal n,
            if x.2 < n then coeff R x.1 φ * coeff R x.2 (inv.aux a φ) else 0 := by
  -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
  erw [coeff, inv.aux, MvPowerSeries.coeff_inv_aux]
  simp only [Finsupp.single_eq_zero]
  

Proof state:
R : Type u_1
inst✝ : Ring R
n : ℕ
a : R
φ : R⟦X⟧
⊢ (if n = 0 then a
    else
      -a *
        ∑ x in antidiagonal fun₀ | () => n,
          if x.2 < fun₀ | () => n then
            (MvPowerSeries.coeff R x.1) φ * (MvPowerSeries.coeff R x.2) (MvPowerSeries.inv.aux a φ)
          else 0) =
    if n = 0 then a
    else -a * ∑ x in antidiagonal n, if x.2 < n then (coeff R x.1) φ * (coeff R x.2) (MvPowerSeries.inv.aux a φ) else 0

Next tactic:
split_ifs
theorem coeff_inv_aux (n : ℕ) (a : R) (φ : R⟦X⟧) :
    coeff R n (inv.aux a φ) =
      if n = 0 then a
      else
        -a *
          ∑ x in antidiagonal n,
            if x.2 < n then coeff R x.1 φ * coeff R x.2 (inv.aux a φ) else 0 := by
  -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
  erw [coeff, inv.aux, MvPowerSeries.coeff_inv_aux]
  simp only [Finsupp.single_eq_zero]
  split_ifs; · 

Proof state:
case pos
R : Type u_1
inst✝ : Ring R
n : ℕ
a : R
φ : R⟦X⟧
h✝ : n = 0
⊢ a = a

Next tactic:
rfl
theorem coeff_inv_aux (n : ℕ) (a : R) (φ : R⟦X⟧) :
    coeff R n (inv.aux a φ) =
      if n = 0 then a
      else
        -a *
          ∑ x in antidiagonal n,
            if x.2 < n then coeff R x.1 φ * coeff R x.2 (inv.aux a φ) else 0 := by
  -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
  erw [coeff, inv.aux, MvPowerSeries.coeff_inv_aux]
  simp only [Finsupp.single_eq_zero]
  split_ifs; · rfl
  

Proof state:
case neg
R : Type u_1
inst✝ : Ring R
n : ℕ
a : R
φ : R⟦X⟧
h✝ : ¬n = 0
⊢ (-a *
      ∑ x in antidiagonal fun₀ | () => n,
        if x.2 < fun₀ | () => n then
          (MvPowerSeries.coeff R x.1) φ * (MvPowerSeries.coeff R x.2) (MvPowerSeries.inv.aux a φ)
        else 0) =
    -a * ∑ x in antidiagonal n, if x.2 < n then (coeff R x.1) φ * (coeff R x.2) (MvPowerSeries.inv.aux a φ) else 0

Next tactic:
congr 1
theorem coeff_inv_aux (n : ℕ) (a : R) (φ : R⟦X⟧) :
    coeff R n (inv.aux a φ) =
      if n = 0 then a
      else
        -a *
          ∑ x in antidiagonal n,
            if x.2 < n then coeff R x.1 φ * coeff R x.2 (inv.aux a φ) else 0 := by
  -- This used to be `rw`, but we need `erw` after leanprover/lean4#2644
  erw [coeff, inv.aux, MvPowerSeries.coeff_inv_aux]
  simp only [Finsupp.single_eq_zero]
  split_ifs; · rfl
  congr 1
  

Proof state:
case neg.e_a
R : Type u_1
inst✝ : Ring R
n : ℕ
a : R
φ : R⟦X⟧
h✝ : ¬n = 0
⊢ (∑ x in antidiagonal fun₀ | () => n,
      if x.2 < fun₀ | () => n then
        (MvPowerSeries.coeff R x.1) φ * (MvPowerSeries.coeff R x.2) (MvPowerSeries.inv.aux a φ)
      else 0) =
    ∑ x in antidiagonal n, if x.2 < n then (coeff R x.1) φ * (coeff R x.2) (MvPowerSeries.inv.aux a φ) else 0

Next tactic:
symm