l3lab/ntp-mathlib huggingface dataset:
/-- The order of the product of two formal power series over an integral domain
 is the sum of their orders.-/
theorem order_mul (φ ψ : R⟦X⟧) : order (φ * ψ) = order φ + order ψ := by
  classical
  simp_rw [order_eq_multiplicity_X]
  

Proof state:
R : Type u_1
inst✝¹ : CommRing R
inst✝ : IsDomain R
φ ψ : R⟦X⟧
⊢ multiplicity X (φ * ψ) = multiplicity X φ + multiplicity X ψ

Next tactic:
exact multiplicity.mul X_prime
@[simp, norm_cast]
theorem coe_monomial (n : ℕ) (a : R) :
    (monomial n a : PowerSeries R) = PowerSeries.monomial R n a := by
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ : R[X]
n : ℕ
a : R
⊢ ↑((monomial n) a) = (PowerSeries.monomial R n) a

Next tactic:
ext
@[simp, norm_cast]
theorem coe_monomial (n : ℕ) (a : R) :
    (monomial n a : PowerSeries R) = PowerSeries.monomial R n a := by
  ext
  

Proof state:
case h
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ : R[X]
n : ℕ
a : R
n✝ : ℕ
⊢ (PowerSeries.coeff R n✝) ↑((monomial n) a) = (PowerSeries.coeff R n✝) ((PowerSeries.monomial R n) a)

Next tactic:
simp [coeff_coe, PowerSeries.coeff_monomial, Polynomial.coeff_monomial, eq_comm]
@[simp, norm_cast]
theorem coe_one : ((1 : R[X]) : PowerSeries R) = 1 := by
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ : R[X]
⊢ ↑1 = 1

Next tactic:
have := coe_monomial 0 (1 : R)
@[simp, norm_cast]
theorem coe_one : ((1 : R[X]) : PowerSeries R) = 1 := by
  have := coe_monomial 0 (1 : R)
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ : R[X]
this : ↑((monomial 0) 1) = (PowerSeries.monomial R 0) 1
⊢ ↑1 = 1

Next tactic:
rwa [PowerSeries.monomial_zero_eq_C_apply] at this
@[simp, norm_cast]
theorem coe_add : ((φ + ψ : R[X]) : PowerSeries R) = φ + ψ := by
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ : R[X]
⊢ ↑(φ + ψ) = ↑φ + ↑ψ

Next tactic:
ext
@[simp, norm_cast]
theorem coe_add : ((φ + ψ : R[X]) : PowerSeries R) = φ + ψ := by
  ext
  

Proof state:
case h
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ : R[X]
n✝ : ℕ
⊢ (PowerSeries.coeff R n✝) ↑(φ + ψ) = (PowerSeries.coeff R n✝) (↑φ + ↑ψ)

Next tactic:
simp
@[simp, norm_cast]
theorem coe_mul : ((φ * ψ : R[X]) : PowerSeries R) = φ * ψ :=
  PowerSeries.ext fun n => by 

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ : R[X]
n : ℕ
⊢ (PowerSeries.coeff R n) ↑(φ * ψ) = (PowerSeries.coeff R n) (↑φ * ↑ψ)

Next tactic:
simp only [coeff_coe, PowerSeries.coeff_mul, coeff_mul]
@[simp, norm_cast]
theorem coe_C (a : R) : ((C a : R[X]) : PowerSeries R) = PowerSeries.C R a := by
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ : R[X]
a : R
⊢ ↑(C a) = (PowerSeries.C R) a

Next tactic:
have := coe_monomial 0 a
@[simp, norm_cast]
theorem coe_C (a : R) : ((C a : R[X]) : PowerSeries R) = PowerSeries.C R a := by
  have := coe_monomial 0 a
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ : R[X]
a : R
this : ↑((monomial 0) a) = (PowerSeries.monomial R 0) a
⊢ ↑(C a) = (PowerSeries.C R) a

Next tactic:
rwa [PowerSeries.monomial_zero_eq_C_apply] at this
set_option linter.deprecated false in
@[simp, norm_cast]
theorem coe_bit1 : ((bit1 φ : R[X]) : PowerSeries R) = bit1 (φ : PowerSeries R) := by
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ : R[X]
⊢ ↑(bit1 φ) = bit1 ↑φ

Next tactic:
rw [bit1, bit1, coe_add, coe_one, coe_bit0]
theorem coe_injective : Function.Injective (Coe.coe : R[X] → PowerSeries R) := fun x y h => by
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ x y : R[X]
h : Coe.coe x = Coe.coe y
⊢ x = y

Next tactic:
ext
theorem coe_injective : Function.Injective (Coe.coe : R[X] → PowerSeries R) := fun x y h => by
  ext
  

Proof state:
case a
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ x y : R[X]
h : Coe.coe x = Coe.coe y
n✝ : ℕ
⊢ coeff x n✝ = coeff y n✝

Next tactic:
simp_rw [← coeff_coe]
theorem coe_injective : Function.Injective (Coe.coe : R[X] → PowerSeries R) := fun x y h => by
  ext
  simp_rw [← coeff_coe]
  

Proof state:
case a
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ x y : R[X]
h : Coe.coe x = Coe.coe y
n✝ : ℕ
⊢ (PowerSeries.coeff R n✝) ↑x = (PowerSeries.coeff R n✝) ↑y

Next tactic:
congr
@[simp]
theorem coe_eq_zero_iff : (φ : PowerSeries R) = 0 ↔ φ = 0 := by 

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ : R[X]
⊢ ↑φ = 0 ↔ φ = 0

Next tactic:
rw [← coe_zero, coe_inj]
@[simp]
theorem coe_eq_one_iff : (φ : PowerSeries R) = 1 ↔ φ = 1 := by 

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ : R[X]
⊢ ↑φ = 1 ↔ φ = 1

Next tactic:
rw [← coe_one, coe_inj]
theorem eval₂_C_X_eq_coe : φ.eval₂ (PowerSeries.C R) PowerSeries.X = ↑φ := by
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ : R[X]
⊢ eval₂ (PowerSeries.C R) PowerSeries.X φ = ↑φ

Next tactic:
nth_rw 2 [← eval₂_C_X (p := φ)]
theorem eval₂_C_X_eq_coe : φ.eval₂ (PowerSeries.C R) PowerSeries.X = ↑φ := by
  nth_rw 2 [← eval₂_C_X (p := φ)]
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ : R[X]
⊢ eval₂ (PowerSeries.C R) PowerSeries.X φ = ↑(eval₂ C X φ)

Next tactic:
rw [← coeToPowerSeries.ringHom_apply, eval₂_eq_sum_range, eval₂_eq_sum_range, map_sum]
theorem eval₂_C_X_eq_coe : φ.eval₂ (PowerSeries.C R) PowerSeries.X = ↑φ := by
  nth_rw 2 [← eval₂_C_X (p := φ)]
  rw [← coeToPowerSeries.ringHom_apply, eval₂_eq_sum_range, eval₂_eq_sum_range, map_sum]
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ : R[X]
⊢ ∑ i in Finset.range (natDegree φ + 1), (PowerSeries.C R) (coeff φ i) * PowerSeries.X ^ i =
    ∑ x in Finset.range (natDegree φ + 1), coeToPowerSeries.ringHom (C (coeff φ x) * X ^ x)

Next tactic:
apply Finset.sum_congr rfl
theorem eval₂_C_X_eq_coe : φ.eval₂ (PowerSeries.C R) PowerSeries.X = ↑φ := by
  nth_rw 2 [← eval₂_C_X (p := φ)]
  rw [← coeToPowerSeries.ringHom_apply, eval₂_eq_sum_range, eval₂_eq_sum_range, map_sum]
  apply Finset.sum_congr rfl
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ : R[X]
⊢ ∀ x ∈ Finset.range (natDegree φ + 1),
    (PowerSeries.C R) (coeff φ x) * PowerSeries.X ^ x = coeToPowerSeries.ringHom (C (coeff φ x) * X ^ x)

Next tactic:
intros
theorem eval₂_C_X_eq_coe : φ.eval₂ (PowerSeries.C R) PowerSeries.X = ↑φ := by
  nth_rw 2 [← eval₂_C_X (p := φ)]
  rw [← coeToPowerSeries.ringHom_apply, eval₂_eq_sum_range, eval₂_eq_sum_range, map_sum]
  apply Finset.sum_congr rfl
  intros
  

Proof state:
σ : Type u_1
R : Type u_2
inst✝ : CommSemiring R
φ ψ : R[X]
x✝ : ℕ
a✝ : x✝ ∈ Finset.range (natDegree φ + 1)
⊢ (PowerSeries.C R) (coeff φ x✝) * PowerSeries.X ^ x✝ = coeToPowerSeries.ringHom (C (coeff φ x✝) * X ^ x✝)

Next tactic:
rw [map_mul, map_pow, coeToPowerSeries.ringHom_apply,
    coeToPowerSeries.ringHom_apply, coe_C, coe_X]
/-- The coercion from polynomials to power series
as an algebra homomorphism.
-/
def coeToPowerSeries.algHom : R[X] →ₐ[R] PowerSeries A :=
  { (PowerSeries.map (algebraMap R A)).comp coeToPowerSeries.ringHom with
    commutes' := fun r => by 

Proof state:
σ : Type u_1
R : Type u_2
inst✝² : CommSemiring R
φ ψ : R[X]
A : Type u_3
inst✝¹ : Semiring A
inst✝ : Algebra R A
src✝ : R[X] →+* PowerSeries A := RingHom.comp (PowerSeries.map (algebraMap R A)) ringHom
r : R
⊢ OneHom.toFun
      (↑↑{ toMonoidHom := ↑src✝, map_zero' := (_ : OneHom.toFun (↑↑src✝) 0 = 0),
            map_add' :=
              (_ : ∀ (x y : R[X]), OneHom.toFun (↑↑src✝) (x + y) = OneHom.toFun (↑↑src✝) x + OneHom.toFun (↑↑src✝) y) })
      ((algebraMap R R[X]) r) =
    (algebraMap R (PowerSeries A)) r

Next tactic:
simp [algebraMap_apply, PowerSeries.algebraMap_apply]
theorem trunc_trunc_of_le {n m} (f : R⟦X⟧) (hnm : n ≤ m := by rfl) :
    trunc n ↑(trunc m f) = trunc n f := by
  

Proof state:
R : Type u_1
inst✝ : CommSemiring R
n m : ℕ
f : R⟦X⟧
hnm : autoParam (n ≤ m) _auto✝
⊢ trunc n ↑(trunc m f) = trunc n f

Next tactic:
ext d
theorem trunc_trunc_of_le {n m} (f : R⟦X⟧) (hnm : n ≤ m := by rfl) :
    trunc n ↑(trunc m f) = trunc n f := by
  ext d
  

Proof state:
case a
R : Type u_1
inst✝ : CommSemiring R
n m : ℕ
f : R⟦X⟧
hnm : autoParam (n ≤ m) _auto✝
d : ℕ
⊢ Polynomial.coeff (trunc n ↑(trunc m f)) d = Polynomial.coeff (trunc n f) d

Next tactic:
rw [coeff_trunc, coeff_trunc, coeff_coe]
theorem trunc_trunc_of_le {n m} (f : R⟦X⟧) (hnm : n ≤ m := by rfl) :
    trunc n ↑(trunc m f) = trunc n f := by
  ext d
  rw [coeff_trunc, coeff_trunc, coeff_coe]
  

Proof state:
case a
R : Type u_1
inst✝ : CommSemiring R
n m : ℕ
f : R⟦X⟧
hnm : autoParam (n ≤ m) _auto✝
d : ℕ
⊢ (if d < n then Polynomial.coeff (trunc m f) d else 0) = if d < n then (coeff R d) f else 0

Next tactic:
split_ifs with h
theorem trunc_trunc_of_le {n m} (f : R⟦X⟧) (hnm : n ≤ m := by rfl) :
    trunc n ↑(trunc m f) = trunc n f := by
  ext d
  rw [coeff_trunc, coeff_trunc, coeff_coe]
  split_ifs with h
  · 

Proof state:
case pos
R : Type u_1
inst✝ : CommSemiring R
n m : ℕ
f : R⟦X⟧
hnm : autoParam (n ≤ m) _auto✝
d : ℕ
h : d < n
⊢ Polynomial.coeff (trunc m f) d = (coeff R d) f

Next tactic:
rw [coeff_trunc, if_pos <| lt_of_lt_of_le h hnm]
theorem trunc_trunc_of_le {n m} (f : R⟦X⟧) (hnm : n ≤ m := by rfl) :
    trunc n ↑(trunc m f) = trunc n f := by
  ext d
  rw [coeff_trunc, coeff_trunc, coeff_coe]
  split_ifs with h
  · rw [coeff_trunc, if_pos <| lt_of_lt_of_le h hnm]
  · 

Proof state:
case neg
R : Type u_1
inst✝ : CommSemiring R
n m : ℕ
f : R⟦X⟧
hnm : autoParam (n ≤ m) _auto✝
d : ℕ
h : ¬d < n
⊢ 0 = 0

Next tactic:
rfl
@[simp] theorem trunc_trunc_mul {n} (f g : R ⟦X⟧) :
    trunc n ((trunc n f) * g : R⟦X⟧) = trunc n (f * g) := by
  

Proof state:
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f g : R⟦X⟧
⊢ trunc n (↑(trunc n f) * g) = trunc n (f * g)

Next tactic:
ext m
@[simp] theorem trunc_trunc_mul {n} (f g : R ⟦X⟧) :
    trunc n ((trunc n f) * g : R⟦X⟧) = trunc n (f * g) := by
  ext m
  

Proof state:
case a
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f g : R⟦X⟧
m : ℕ
⊢ Polynomial.coeff (trunc n (↑(trunc n f) * g)) m = Polynomial.coeff (trunc n (f * g)) m

Next tactic:
rw [coeff_trunc, coeff_trunc]
@[simp] theorem trunc_trunc_mul {n} (f g : R ⟦X⟧) :
    trunc n ((trunc n f) * g : R⟦X⟧) = trunc n (f * g) := by
  ext m
  rw [coeff_trunc, coeff_trunc]
  

Proof state:
case a
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f g : R⟦X⟧
m : ℕ
⊢ (if m < n then (coeff R m) (↑(trunc n f) * g) else 0) = if m < n then (coeff R m) (f * g) else 0

Next tactic:
split_ifs with h
@[simp] theorem trunc_trunc_mul {n} (f g : R ⟦X⟧) :
    trunc n ((trunc n f) * g : R⟦X⟧) = trunc n (f * g) := by
  ext m
  rw [coeff_trunc, coeff_trunc]
  split_ifs with h
  · 

Proof state:
case pos
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f g : R⟦X⟧
m : ℕ
h : m < n
⊢ (coeff R m) (↑(trunc n f) * g) = (coeff R m) (f * g)

Next tactic:
rw [coeff_mul, coeff_mul, sum_congr rfl]
@[simp] theorem trunc_trunc_mul {n} (f g : R ⟦X⟧) :
    trunc n ((trunc n f) * g : R⟦X⟧) = trunc n (f * g) := by
  ext m
  rw [coeff_trunc, coeff_trunc]
  split_ifs with h
  · rw [coeff_mul, coeff_mul, sum_congr rfl]
    

Proof state:
case pos
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f g : R⟦X⟧
m : ℕ
h : m < n
⊢ ∀ x ∈ antidiagonal m, (coeff R x.1) ↑(trunc n f) * (coeff R x.2) g = (coeff R x.1) f * (coeff R x.2) g

Next tactic:
intro _ hab
@[simp] theorem trunc_trunc_mul {n} (f g : R ⟦X⟧) :
    trunc n ((trunc n f) * g : R⟦X⟧) = trunc n (f * g) := by
  ext m
  rw [coeff_trunc, coeff_trunc]
  split_ifs with h
  · rw [coeff_mul, coeff_mul, sum_congr rfl]
    intro _ hab
    

Proof state:
case pos
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f g : R⟦X⟧
m : ℕ
h : m < n
x✝ : ℕ × ℕ
hab : x✝ ∈ antidiagonal m
⊢ (coeff R x✝.1) ↑(trunc n f) * (coeff R x✝.2) g = (coeff R x✝.1) f * (coeff R x✝.2) g

Next tactic:
have ha := lt_of_le_of_lt (antidiagonal.fst_le hab) h
@[simp] theorem trunc_trunc_mul {n} (f g : R ⟦X⟧) :
    trunc n ((trunc n f) * g : R⟦X⟧) = trunc n (f * g) := by
  ext m
  rw [coeff_trunc, coeff_trunc]
  split_ifs with h
  · rw [coeff_mul, coeff_mul, sum_congr rfl]
    intro _ hab
    have ha := lt_of_le_of_lt (antidiagonal.fst_le hab) h
    

Proof state:
case pos
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f g : R⟦X⟧
m : ℕ
h : m < n
x✝ : ℕ × ℕ
hab : x✝ ∈ antidiagonal m
ha : x✝.1 < n
⊢ (coeff R x✝.1) ↑(trunc n f) * (coeff R x✝.2) g = (coeff R x✝.1) f * (coeff R x✝.2) g

Next tactic:
rw [coeff_coe, coeff_trunc, if_pos ha]
@[simp] theorem trunc_trunc_mul {n} (f g : R ⟦X⟧) :
    trunc n ((trunc n f) * g : R⟦X⟧) = trunc n (f * g) := by
  ext m
  rw [coeff_trunc, coeff_trunc]
  split_ifs with h
  · rw [coeff_mul, coeff_mul, sum_congr rfl]
    intro _ hab
    have ha := lt_of_le_of_lt (antidiagonal.fst_le hab) h
    rw [coeff_coe, coeff_trunc, if_pos ha]
  · 

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

Next tactic:
rfl
@[simp] theorem trunc_mul_trunc {n} (f g : R ⟦X⟧) :
    trunc n (f * (trunc n g) : R⟦X⟧) = trunc n (f * g) := by
  

Proof state:
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f g : R⟦X⟧
⊢ trunc n (f * ↑(trunc n g)) = trunc n (f * g)

Next tactic:
rw [mul_comm, trunc_trunc_mul, mul_comm]
theorem trunc_trunc_mul_trunc {n} (f g : R⟦X⟧) :
    trunc n (trunc n f * trunc n g : R⟦X⟧) = trunc n (f * g) := by
  

Proof state:
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f g : R⟦X⟧
⊢ trunc n (↑(trunc n f) * ↑(trunc n g)) = trunc n (f * g)

Next tactic:
rw [trunc_trunc_mul, trunc_mul_trunc]
@[simp] theorem trunc_trunc_pow (f : R⟦X⟧) (n a : ℕ) :
    trunc n ((trunc n f : R⟦X⟧) ^ a) = trunc n (f ^ a) := by
  

Proof state:
R : Type u_1
inst✝ : CommSemiring R
f : R⟦X⟧
n a : ℕ
⊢ trunc n (↑(trunc n f) ^ a) = trunc n (f ^ a)

Next tactic:
induction a with
  | zero =>
    rw [pow_zero, pow_zero]
  | succ a ih =>
    rw [pow_succ, pow_succ, trunc_trunc_mul, ← trunc_trunc_mul_trunc, ih, trunc_trunc_mul_trunc]
@[simp] theorem trunc_trunc_pow (f : R⟦X⟧) (n a : ℕ) :
    trunc n ((trunc n f : R⟦X⟧) ^ a) = trunc n (f ^ a) := by
  induction a with
  

Proof state:
case zero
R : Type u_1
inst✝ : CommSemiring R
f : R⟦X⟧
n : ℕ
⊢ trunc n (↑(trunc n f) ^ Nat.zero) = trunc n (f ^ Nat.zero)

Next tactic:
| zero =>
    rw [pow_zero, pow_zero]
@[simp] theorem trunc_trunc_pow (f : R⟦X⟧) (n a : ℕ) :
    trunc n ((trunc n f : R⟦X⟧) ^ a) = trunc n (f ^ a) := by
  induction a with
  | zero =>
    

Proof state:
case zero
R : Type u_1
inst✝ : CommSemiring R
f : R⟦X⟧
n : ℕ
⊢ trunc n (↑(trunc n f) ^ Nat.zero) = trunc n (f ^ Nat.zero)

Next tactic:
rw [pow_zero, pow_zero]
@[simp] theorem trunc_trunc_pow (f : R⟦X⟧) (n a : ℕ) :
    trunc n ((trunc n f : R⟦X⟧) ^ a) = trunc n (f ^ a) := by
  induction a with
  | zero =>
    rw [pow_zero, pow_zero]
  

Proof state:
case succ
R : Type u_1
inst✝ : CommSemiring R
f : R⟦X⟧
n a : ℕ
ih : trunc n (↑(trunc n f) ^ a) = trunc n (f ^ a)
⊢ trunc n (↑(trunc n f) ^ succ a) = trunc n (f ^ succ a)

Next tactic:
| succ a ih =>
    rw [pow_succ, pow_succ, trunc_trunc_mul, ← trunc_trunc_mul_trunc, ih, trunc_trunc_mul_trunc]
@[simp] theorem trunc_trunc_pow (f : R⟦X⟧) (n a : ℕ) :
    trunc n ((trunc n f : R⟦X⟧) ^ a) = trunc n (f ^ a) := by
  induction a with
  | zero =>
    rw [pow_zero, pow_zero]
  | succ a ih =>
    

Proof state:
case succ
R : Type u_1
inst✝ : CommSemiring R
f : R⟦X⟧
n a : ℕ
ih : trunc n (↑(trunc n f) ^ a) = trunc n (f ^ a)
⊢ trunc n (↑(trunc n f) ^ succ a) = trunc n (f ^ succ a)

Next tactic:
rw [pow_succ, pow_succ, trunc_trunc_mul, ← trunc_trunc_mul_trunc, ih, trunc_trunc_mul_trunc]
theorem trunc_coe_eq_self {n} {f : R[X]} (hn : natDegree f < n) : trunc n (f : R⟦X⟧) = f := by
  

Proof state:
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f : R[X]
hn : natDegree f < n
⊢ trunc n ↑f = f

Next tactic:
rw [← Polynomial.coe_inj]
theorem trunc_coe_eq_self {n} {f : R[X]} (hn : natDegree f < n) : trunc n (f : R⟦X⟧) = f := by
  rw [← Polynomial.coe_inj]
  

Proof state:
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f : R[X]
hn : natDegree f < n
⊢ ↑(trunc n ↑f) = ↑f

Next tactic:
ext m
theorem trunc_coe_eq_self {n} {f : R[X]} (hn : natDegree f < n) : trunc n (f : R⟦X⟧) = f := by
  rw [← Polynomial.coe_inj]
  ext m
  

Proof state:
case h
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f : R[X]
hn : natDegree f < n
m : ℕ
⊢ (coeff R m) ↑(trunc n ↑f) = (coeff R m) ↑f

Next tactic:
rw [coeff_coe, coeff_trunc]
theorem trunc_coe_eq_self {n} {f : R[X]} (hn : natDegree f < n) : trunc n (f : R⟦X⟧) = f := by
  rw [← Polynomial.coe_inj]
  ext m
  rw [coeff_coe, coeff_trunc]
  

Proof state:
case h
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f : R[X]
hn : natDegree f < n
m : ℕ
⊢ (if m < n then (coeff R m) ↑f else 0) = (coeff R m) ↑f

Next tactic:
split
theorem trunc_coe_eq_self {n} {f : R[X]} (hn : natDegree f < n) : trunc n (f : R⟦X⟧) = f := by
  rw [← Polynomial.coe_inj]
  ext m
  rw [coeff_coe, coeff_trunc]
  split
  

Proof state:
case h.inl
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f : R[X]
hn : natDegree f < n
m : ℕ
h✝ : m < n
⊢ (coeff R m) ↑f = (coeff R m) ↑f
case h.inr
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f : R[X]
hn : natDegree f < n
m : ℕ
h✝ : ¬m < n
⊢ 0 = (coeff R m) ↑f

Next tactic:
case inl h => rfl
theorem trunc_coe_eq_self {n} {f : R[X]} (hn : natDegree f < n) : trunc n (f : R⟦X⟧) = f := by
  rw [← Polynomial.coe_inj]
  ext m
  rw [coeff_coe, coeff_trunc]
  split
  

Proof state:
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f : R[X]
hn : natDegree f < n
m : ℕ
h : m < n
⊢ (coeff R m) ↑f = (coeff R m) ↑f

Next tactic:
case inl h => rfl
theorem trunc_coe_eq_self {n} {f : R[X]} (hn : natDegree f < n) : trunc n (f : R⟦X⟧) = f := by
  rw [← Polynomial.coe_inj]
  ext m
  rw [coeff_coe, coeff_trunc]
  split
  case inl h => 

Proof state:
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f : R[X]
hn : natDegree f < n
m : ℕ
h : m < n
⊢ (coeff R m) ↑f = (coeff R m) ↑f

Next tactic:
rfl
theorem trunc_coe_eq_self {n} {f : R[X]} (hn : natDegree f < n) : trunc n (f : R⟦X⟧) = f := by
  rw [← Polynomial.coe_inj]
  ext m
  rw [coeff_coe, coeff_trunc]
  split
  case inl h => rfl
  

Proof state:
case h.inr
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f : R[X]
hn : natDegree f < n
m : ℕ
h✝ : ¬m < n
⊢ 0 = (coeff R m) ↑f

Next tactic:
case inr h =>
    rw [not_lt] at h
    rw [coeff_coe]; symm
    exact coeff_eq_zero_of_natDegree_lt <| lt_of_lt_of_le hn h
theorem trunc_coe_eq_self {n} {f : R[X]} (hn : natDegree f < n) : trunc n (f : R⟦X⟧) = f := by
  rw [← Polynomial.coe_inj]
  ext m
  rw [coeff_coe, coeff_trunc]
  split
  case inl h => rfl
  

Proof state:
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f : R[X]
hn : natDegree f < n
m : ℕ
h : ¬m < n
⊢ 0 = (coeff R m) ↑f

Next tactic:
case inr h =>
    rw [not_lt] at h
    rw [coeff_coe]; symm
    exact coeff_eq_zero_of_natDegree_lt <| lt_of_lt_of_le hn h
theorem trunc_coe_eq_self {n} {f : R[X]} (hn : natDegree f < n) : trunc n (f : R⟦X⟧) = f := by
  rw [← Polynomial.coe_inj]
  ext m
  rw [coeff_coe, coeff_trunc]
  split
  case inl h => rfl
  case inr h =>
    

Proof state:
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f : R[X]
hn : natDegree f < n
m : ℕ
h : ¬m < n
⊢ 0 = (coeff R m) ↑f

Next tactic:
rw [not_lt] at h
theorem trunc_coe_eq_self {n} {f : R[X]} (hn : natDegree f < n) : trunc n (f : R⟦X⟧) = f := by
  rw [← Polynomial.coe_inj]
  ext m
  rw [coeff_coe, coeff_trunc]
  split
  case inl h => rfl
  case inr h =>
    rw [not_lt] at h
    

Proof state:
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f : R[X]
hn : natDegree f < n
m : ℕ
h : n ≤ m
⊢ 0 = (coeff R m) ↑f

Next tactic:
rw [coeff_coe]
theorem trunc_coe_eq_self {n} {f : R[X]} (hn : natDegree f < n) : trunc n (f : R⟦X⟧) = f := by
  rw [← Polynomial.coe_inj]
  ext m
  rw [coeff_coe, coeff_trunc]
  split
  case inl h => rfl
  case inr h =>
    rw [not_lt] at h
    rw [coeff_coe]; 

Proof state:
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f : R[X]
hn : natDegree f < n
m : ℕ
h : n ≤ m
⊢ 0 = Polynomial.coeff f m

Next tactic:
symm
theorem trunc_coe_eq_self {n} {f : R[X]} (hn : natDegree f < n) : trunc n (f : R⟦X⟧) = f := by
  rw [← Polynomial.coe_inj]
  ext m
  rw [coeff_coe, coeff_trunc]
  split
  case inl h => rfl
  case inr h =>
    rw [not_lt] at h
    rw [coeff_coe]; symm
    

Proof state:
R : Type u_1
inst✝ : CommSemiring R
n : ℕ
f : R[X]
hn : natDegree f < n
m : ℕ
h : n ≤ m
⊢ Polynomial.coeff f m = 0

Next tactic:
exact coeff_eq_zero_of_natDegree_lt <| lt_of_lt_of_le hn h
/-- The function `coeff n : R⟦X⟧ → R` is continuous. I.e. `coeff n f` depends only on a sufficiently
long truncation of the power series `f`.-/
theorem coeff_coe_trunc_of_lt {n m} {f : R⟦X⟧} (h : n < m) :
    coeff R n (trunc m f) = coeff R n f := by
  

Proof state:
R : Type u_1
inst✝ : CommSemiring R
n m : ℕ
f : R⟦X⟧
h : n < m
⊢ (coeff R n) ↑(trunc m f) = (coeff R n) f

Next tactic:
rwa [coeff_coe, coeff_trunc, if_pos]
/-- The `n`-th coefficient of `f*g` may be calculated
from the truncations of `f` and `g`.-/
theorem coeff_mul_eq_coeff_trunc_mul_trunc₂ {n a b} (f g) (ha : n < a) (hb : n < b) :
    coeff R n (f * g) = coeff R n (trunc a f * trunc b g) := by
  

Proof state:
R : Type u_1
inst✝ : CommSemiring R
n a b : ℕ
f g : R⟦X⟧
ha : n < a
hb : n < b
⊢ (coeff R n) (f * g) = (coeff R n) (↑(trunc a f) * ↑(trunc b g))

Next tactic:
symm
/-- The `n`-th coefficient of `f*g` may be calculated
from the truncations of `f` and `g`.-/
theorem coeff_mul_eq_coeff_trunc_mul_trunc₂ {n a b} (f g) (ha : n < a) (hb : n < b) :
    coeff R n (f * g) = coeff R n (trunc a f * trunc b g) := by
  symm
  

Proof state:
R : Type u_1
inst✝ : CommSemiring R
n a b : ℕ
f g : R⟦X⟧
ha : n < a
hb : n < b
⊢ (coeff R n) (↑(trunc a f) * ↑(trunc b g)) = (coeff R n) (f * g)

Next tactic:
rw [← coeff_coe_trunc_of_lt n.lt_succ_self, ← trunc_trunc_mul_trunc, trunc_trunc_of_le f ha,
    trunc_trunc_of_le g hb, trunc_trunc_mul_trunc, coeff_coe_trunc_of_lt n.lt_succ_self]
@[ext]
theorem Shrink.ext {α : Type v} [Small.{w} α] {x y : Shrink α}
    (w : (equivShrink _).symm x = (equivShrink _).symm y) : x = y := by
  

Proof state:
α : Type v
inst✝ : Small.{w, v} α
x y : Shrink.{w, v} α
w : (equivShrink α).symm x = (equivShrink α).symm y
⊢ x = y

Next tactic:
simpa using w
instance small_sigma {α} (β : α → Type*) [Small.{w} α] [∀ a, Small.{w} (β a)] :
    Small.{w} (Σa, β a) :=
  ⟨⟨Σa' : Shrink α, Shrink (β ((equivShrink α).symm a')),
      ⟨Equiv.sigmaCongr (equivShrink α) fun a => by 

Proof state:
α : Type ?u.1285
β : α → Type u_1
inst✝¹ : Small.{w, ?u.1285} α
inst✝ : ∀ (a : α), Small.{w, u_1} (β a)
a : α
⊢ β a ≃ Shrink.{w, u_1} (β ((equivShrink α).symm ((equivShrink α) a)))

Next tactic:
simpa using equivShrink (β a)
theorem not_small_type : ¬Small.{u} (Type max u v)
  | ⟨⟨S, ⟨e⟩⟩⟩ =>
    @Function.cantor_injective (Σα, e.symm α) (fun a => ⟨_, cast (e.3 _).symm a⟩) fun a b e => by
      

Proof state:
S : Type u
e✝ : Type (max u v) ≃ S
a b : Set ((α : S) × e✝.symm α)
e :
  (fun a =>
        { fst := Equiv.toFun e✝ (Set ((α : S) × e✝.symm α)),
          snd :=
            cast (_ : Set ((α : S) × e✝.symm α) = Equiv.invFun e✝ (Equiv.toFun e✝ (Set ((α : S) × e✝.symm α)))) a })
      a =
    (fun a =>
        { fst := Equiv.toFun e✝ (Set ((α : S) × e✝.symm α)),
          snd :=
            cast (_ : Set ((α : S) × e✝.symm α) = Equiv.invFun e✝ (Equiv.toFun e✝ (Set ((α : S) × e✝.symm α)))) a })
      b
⊢ a = b

Next tactic:
dsimp at e
theorem not_small_type : ¬Small.{u} (Type max u v)
  | ⟨⟨S, ⟨e⟩⟩⟩ =>
    @Function.cantor_injective (Σα, e.symm α) (fun a => ⟨_, cast (e.3 _).symm a⟩) fun a b e => by
      dsimp at e
      

Proof state:
S : Type u
e✝ : Type (max u v) ≃ S
a b : Set ((α : S) × e✝.symm α)
e :
  { fst := e✝ (Set ((α : S) × e✝.symm α)),
      snd := cast (_ : Set ((α : S) × e✝.symm α) = e✝.symm (e✝ (Set ((α : S) × e✝.symm α)))) a } =
    { fst := e✝ (Set ((α : S) × e✝.symm α)),
      snd := cast (_ : Set ((α : S) × e✝.symm α) = e✝.symm (e✝ (Set ((α : S) × e✝.symm α)))) b }
⊢ a = b

Next tactic:
injection e with h₁ h₂
theorem not_small_type : ¬Small.{u} (Type max u v)
  | ⟨⟨S, ⟨e⟩⟩⟩ =>
    @Function.cantor_injective (Σα, e.symm α) (fun a => ⟨_, cast (e.3 _).symm a⟩) fun a b e => by
      dsimp at e
      injection e with h₁ h₂
      

Proof state:
S : Type u
e : Type (max u v) ≃ S
a b : Set ((α : S) × e.symm α)
h₁ : e (Set ((α : S) × e.symm α)) = e (Set ((α : S) × e.symm α))
h₂ :
  cast (_ : Set ((α : S) × e.symm α) = e.symm (e (Set ((α : S) × e.symm α)))) a =
    cast (_ : Set ((α : S) × e.symm α) = e.symm (e (Set ((α : S) × e.symm α)))) b
⊢ a = b

Next tactic:
simpa using h₂