l3lab/ntp-mathlib huggingface dataset:
@[elab_as_elim]
protected theorem induction_on {M : R[T;T⁻¹] → Prop} (p : R[T;T⁻¹]) (h_C : ∀ a, M (C a))
    (h_add : ∀ {p q}, M p → M q → M (p + q))
    (h_C_mul_T : ∀ (n : ℕ) (a : R), M (C a * T n) → M (C a * T (n + 1)))
    (h_C_mul_T_Z : ∀ (n : ℕ) (a : R), M (C a * T (-n)) → M (C a * T (-n - 1))) : M p := by
  have A : ∀ {n : ℤ} {a : R}, M (C a * T n) := by
    intro n a
    refine Int.induction_on n ?_ ?_ ?_
    · simpa only [T_zero, mul_one] using h_C a
    · exact fun m => h_C_mul_T m a
    · exact fun m => h_C_mul_T_Z m a
  have B : ∀ s : Finset ℤ, M (s.sum fun n : ℤ => C (p.toFun n) * T n) := by
    apply Finset.induction
    · convert h_C 0
      simp only [Finset.sum_empty, _root_.map_zero]
    · intro n s ns ih
      rw [Finset.sum_insert ns]
      exact h_add A ih
  convert B p.support
  ext a
  simp_rw [← single_eq_C_mul_T]
  -- Porting note: did not make progress in `simp_rw`
  rw [Finset.sum_apply']
  simp_rw [Finsupp.single_apply, Finset.sum_ite_eq']
  

Proof state:
case h.e'_1.h
R : Type u_1
inst✝ : Semiring R
M : R[T;T⁻¹] → Prop
p : R[T;T⁻¹]
h_C : ∀ (a : R), M (C a)
h_add : ∀ {p q : R[T;T⁻¹]}, M p → M q → M (p + q)
h_C_mul_T : ∀ (n : ℕ) (a : R), M (C a * T ↑n) → M (C a * T (↑n + 1))
h_C_mul_T_Z : ∀ (n : ℕ) (a : R), M (C a * T (-↑n)) → M (C a * T (-↑n - 1))
A : ∀ {n : ℤ} {a : R}, M (C a * T n)
B : ∀ (s : Finset ℤ), M (∑ n in s, C (toFun p n) * T n)
a : ℤ
⊢ p a = if a ∈ p.support then toFun p a else 0

Next tactic:
split_ifs with h
@[elab_as_elim]
protected theorem induction_on {M : R[T;T⁻¹] → Prop} (p : R[T;T⁻¹]) (h_C : ∀ a, M (C a))
    (h_add : ∀ {p q}, M p → M q → M (p + q))
    (h_C_mul_T : ∀ (n : ℕ) (a : R), M (C a * T n) → M (C a * T (n + 1)))
    (h_C_mul_T_Z : ∀ (n : ℕ) (a : R), M (C a * T (-n)) → M (C a * T (-n - 1))) : M p := by
  have A : ∀ {n : ℤ} {a : R}, M (C a * T n) := by
    intro n a
    refine Int.induction_on n ?_ ?_ ?_
    · simpa only [T_zero, mul_one] using h_C a
    · exact fun m => h_C_mul_T m a
    · exact fun m => h_C_mul_T_Z m a
  have B : ∀ s : Finset ℤ, M (s.sum fun n : ℤ => C (p.toFun n) * T n) := by
    apply Finset.induction
    · convert h_C 0
      simp only [Finset.sum_empty, _root_.map_zero]
    · intro n s ns ih
      rw [Finset.sum_insert ns]
      exact h_add A ih
  convert B p.support
  ext a
  simp_rw [← single_eq_C_mul_T]
  -- Porting note: did not make progress in `simp_rw`
  rw [Finset.sum_apply']
  simp_rw [Finsupp.single_apply, Finset.sum_ite_eq']
  split_ifs with h
  · 

Proof state:
case pos
R : Type u_1
inst✝ : Semiring R
M : R[T;T⁻¹] → Prop
p : R[T;T⁻¹]
h_C : ∀ (a : R), M (C a)
h_add : ∀ {p q : R[T;T⁻¹]}, M p → M q → M (p + q)
h_C_mul_T : ∀ (n : ℕ) (a : R), M (C a * T ↑n) → M (C a * T (↑n + 1))
h_C_mul_T_Z : ∀ (n : ℕ) (a : R), M (C a * T (-↑n)) → M (C a * T (-↑n - 1))
A : ∀ {n : ℤ} {a : R}, M (C a * T n)
B : ∀ (s : Finset ℤ), M (∑ n in s, C (toFun p n) * T n)
a : ℤ
h : a ∈ p.support
⊢ p a = toFun p a

Next tactic:
rfl
@[elab_as_elim]
protected theorem induction_on {M : R[T;T⁻¹] → Prop} (p : R[T;T⁻¹]) (h_C : ∀ a, M (C a))
    (h_add : ∀ {p q}, M p → M q → M (p + q))
    (h_C_mul_T : ∀ (n : ℕ) (a : R), M (C a * T n) → M (C a * T (n + 1)))
    (h_C_mul_T_Z : ∀ (n : ℕ) (a : R), M (C a * T (-n)) → M (C a * T (-n - 1))) : M p := by
  have A : ∀ {n : ℤ} {a : R}, M (C a * T n) := by
    intro n a
    refine Int.induction_on n ?_ ?_ ?_
    · simpa only [T_zero, mul_one] using h_C a
    · exact fun m => h_C_mul_T m a
    · exact fun m => h_C_mul_T_Z m a
  have B : ∀ s : Finset ℤ, M (s.sum fun n : ℤ => C (p.toFun n) * T n) := by
    apply Finset.induction
    · convert h_C 0
      simp only [Finset.sum_empty, _root_.map_zero]
    · intro n s ns ih
      rw [Finset.sum_insert ns]
      exact h_add A ih
  convert B p.support
  ext a
  simp_rw [← single_eq_C_mul_T]
  -- Porting note: did not make progress in `simp_rw`
  rw [Finset.sum_apply']
  simp_rw [Finsupp.single_apply, Finset.sum_ite_eq']
  split_ifs with h
  · rfl
  · 

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
M : R[T;T⁻¹] → Prop
p : R[T;T⁻¹]
h_C : ∀ (a : R), M (C a)
h_add : ∀ {p q : R[T;T⁻¹]}, M p → M q → M (p + q)
h_C_mul_T : ∀ (n : ℕ) (a : R), M (C a * T ↑n) → M (C a * T (↑n + 1))
h_C_mul_T_Z : ∀ (n : ℕ) (a : R), M (C a * T (-↑n)) → M (C a * T (-↑n - 1))
A : ∀ {n : ℤ} {a : R}, M (C a * T n)
B : ∀ (s : Finset ℤ), M (∑ n in s, C (toFun p n) * T n)
a : ℤ
h : a ∉ p.support
⊢ p a = 0

Next tactic:
exact Finsupp.not_mem_support_iff.mp h
/-- To prove something about Laurent polynomials, it suffices to show that
* the condition is closed under taking sums, and
* it holds for monomials.
-/
@[elab_as_elim]
protected theorem induction_on' {M : R[T;T⁻¹] → Prop} (p : R[T;T⁻¹])
    (h_add : ∀ p q, M p → M q → M (p + q)) (h_C_mul_T : ∀ (n : ℤ) (a : R), M (C a * T n)) :
    M p := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
M : R[T;T⁻¹] → Prop
p : R[T;T⁻¹]
h_add : ∀ (p q : R[T;T⁻¹]), M p → M q → M (p + q)
h_C_mul_T : ∀ (n : ℤ) (a : R), M (C a * T n)
⊢ M p

Next tactic:
refine' p.induction_on (fun a => _) (fun {p q} => h_add p q) _ _
/-- To prove something about Laurent polynomials, it suffices to show that
* the condition is closed under taking sums, and
* it holds for monomials.
-/
@[elab_as_elim]
protected theorem induction_on' {M : R[T;T⁻¹] → Prop} (p : R[T;T⁻¹])
    (h_add : ∀ p q, M p → M q → M (p + q)) (h_C_mul_T : ∀ (n : ℤ) (a : R), M (C a * T n)) :
    M p := by
  refine' p.induction_on (fun a => _) (fun {p q} => h_add p q) _ _ <;>
      

Proof state:
case refine'_1
R : Type u_1
inst✝ : Semiring R
M : R[T;T⁻¹] → Prop
p : R[T;T⁻¹]
h_add : ∀ (p q : R[T;T⁻¹]), M p → M q → M (p + q)
h_C_mul_T : ∀ (n : ℤ) (a : R), M (C a * T n)
a : R
⊢ M (C a)

Next tactic:
try exact fun n f _ => h_C_mul_T _ f
/-- To prove something about Laurent polynomials, it suffices to show that
* the condition is closed under taking sums, and
* it holds for monomials.
-/
@[elab_as_elim]
protected theorem induction_on' {M : R[T;T⁻¹] → Prop} (p : R[T;T⁻¹])
    (h_add : ∀ p q, M p → M q → M (p + q)) (h_C_mul_T : ∀ (n : ℤ) (a : R), M (C a * T n)) :
    M p := by
  refine' p.induction_on (fun a => _) (fun {p q} => h_add p q) _ _ <;>
      try 

Proof state:
case refine'_1
R : Type u_1
inst✝ : Semiring R
M : R[T;T⁻¹] → Prop
p : R[T;T⁻¹]
h_add : ∀ (p q : R[T;T⁻¹]), M p → M q → M (p + q)
h_C_mul_T : ∀ (n : ℤ) (a : R), M (C a * T n)
a : R
⊢ M (C a)

Next tactic:
exact fun n f _ => h_C_mul_T _ f
/-- To prove something about Laurent polynomials, it suffices to show that
* the condition is closed under taking sums, and
* it holds for monomials.
-/
@[elab_as_elim]
protected theorem induction_on' {M : R[T;T⁻¹] → Prop} (p : R[T;T⁻¹])
    (h_add : ∀ p q, M p → M q → M (p + q)) (h_C_mul_T : ∀ (n : ℤ) (a : R), M (C a * T n)) :
    M p := by
  refine' p.induction_on (fun a => _) (fun {p q} => h_add p q) _ _ <;>
      

Proof state:
case refine'_2
R : Type u_1
inst✝ : Semiring R
M : R[T;T⁻¹] → Prop
p : R[T;T⁻¹]
h_add : ∀ (p q : R[T;T⁻¹]), M p → M q → M (p + q)
h_C_mul_T : ∀ (n : ℤ) (a : R), M (C a * T n)
⊢ ∀ (n : ℕ) (a : R), M (C a * T ↑n) → M (C a * T (↑n + 1))

Next tactic:
try exact fun n f _ => h_C_mul_T _ f
/-- To prove something about Laurent polynomials, it suffices to show that
* the condition is closed under taking sums, and
* it holds for monomials.
-/
@[elab_as_elim]
protected theorem induction_on' {M : R[T;T⁻¹] → Prop} (p : R[T;T⁻¹])
    (h_add : ∀ p q, M p → M q → M (p + q)) (h_C_mul_T : ∀ (n : ℤ) (a : R), M (C a * T n)) :
    M p := by
  refine' p.induction_on (fun a => _) (fun {p q} => h_add p q) _ _ <;>
      try 

Proof state:
case refine'_2
R : Type u_1
inst✝ : Semiring R
M : R[T;T⁻¹] → Prop
p : R[T;T⁻¹]
h_add : ∀ (p q : R[T;T⁻¹]), M p → M q → M (p + q)
h_C_mul_T : ∀ (n : ℤ) (a : R), M (C a * T n)
⊢ ∀ (n : ℕ) (a : R), M (C a * T ↑n) → M (C a * T (↑n + 1))

Next tactic:
exact fun n f _ => h_C_mul_T _ f
/-- To prove something about Laurent polynomials, it suffices to show that
* the condition is closed under taking sums, and
* it holds for monomials.
-/
@[elab_as_elim]
protected theorem induction_on' {M : R[T;T⁻¹] → Prop} (p : R[T;T⁻¹])
    (h_add : ∀ p q, M p → M q → M (p + q)) (h_C_mul_T : ∀ (n : ℤ) (a : R), M (C a * T n)) :
    M p := by
  refine' p.induction_on (fun a => _) (fun {p q} => h_add p q) _ _ <;>
      

Proof state:
case refine'_3
R : Type u_1
inst✝ : Semiring R
M : R[T;T⁻¹] → Prop
p : R[T;T⁻¹]
h_add : ∀ (p q : R[T;T⁻¹]), M p → M q → M (p + q)
h_C_mul_T : ∀ (n : ℤ) (a : R), M (C a * T n)
⊢ ∀ (n : ℕ) (a : R), M (C a * T (-↑n)) → M (C a * T (-↑n - 1))

Next tactic:
try exact fun n f _ => h_C_mul_T _ f
/-- To prove something about Laurent polynomials, it suffices to show that
* the condition is closed under taking sums, and
* it holds for monomials.
-/
@[elab_as_elim]
protected theorem induction_on' {M : R[T;T⁻¹] → Prop} (p : R[T;T⁻¹])
    (h_add : ∀ p q, M p → M q → M (p + q)) (h_C_mul_T : ∀ (n : ℤ) (a : R), M (C a * T n)) :
    M p := by
  refine' p.induction_on (fun a => _) (fun {p q} => h_add p q) _ _ <;>
      try 

Proof state:
case refine'_3
R : Type u_1
inst✝ : Semiring R
M : R[T;T⁻¹] → Prop
p : R[T;T⁻¹]
h_add : ∀ (p q : R[T;T⁻¹]), M p → M q → M (p + q)
h_C_mul_T : ∀ (n : ℤ) (a : R), M (C a * T n)
⊢ ∀ (n : ℕ) (a : R), M (C a * T (-↑n)) → M (C a * T (-↑n - 1))

Next tactic:
exact fun n f _ => h_C_mul_T _ f
/-- To prove something about Laurent polynomials, it suffices to show that
* the condition is closed under taking sums, and
* it holds for monomials.
-/
@[elab_as_elim]
protected theorem induction_on' {M : R[T;T⁻¹] → Prop} (p : R[T;T⁻¹])
    (h_add : ∀ p q, M p → M q → M (p + q)) (h_C_mul_T : ∀ (n : ℤ) (a : R), M (C a * T n)) :
    M p := by
  refine' p.induction_on (fun a => _) (fun {p q} => h_add p q) _ _ <;>
      try exact fun n f _ => h_C_mul_T _ f
  

Proof state:
case refine'_1
R : Type u_1
inst✝ : Semiring R
M : R[T;T⁻¹] → Prop
p : R[T;T⁻¹]
h_add : ∀ (p q : R[T;T⁻¹]), M p → M q → M (p + q)
h_C_mul_T : ∀ (n : ℤ) (a : R), M (C a * T n)
a : R
⊢ M (C a)

Next tactic:
convert h_C_mul_T 0 a
/-- To prove something about Laurent polynomials, it suffices to show that
* the condition is closed under taking sums, and
* it holds for monomials.
-/
@[elab_as_elim]
protected theorem induction_on' {M : R[T;T⁻¹] → Prop} (p : R[T;T⁻¹])
    (h_add : ∀ p q, M p → M q → M (p + q)) (h_C_mul_T : ∀ (n : ℤ) (a : R), M (C a * T n)) :
    M p := by
  refine' p.induction_on (fun a => _) (fun {p q} => h_add p q) _ _ <;>
      try exact fun n f _ => h_C_mul_T _ f
  convert h_C_mul_T 0 a
  

Proof state:
case h.e'_1
R : Type u_1
inst✝ : Semiring R
M : R[T;T⁻¹] → Prop
p : R[T;T⁻¹]
h_add : ∀ (p q : R[T;T⁻¹]), M p → M q → M (p + q)
h_C_mul_T : ∀ (n : ℤ) (a : R), M (C a * T n)
a : R
⊢ C a = C a * T 0

Next tactic:
exact (mul_one _).symm
theorem commute_T (n : ℤ) (f : R[T;T⁻¹]) : Commute (T n) f :=
  f.induction_on' (fun p q Tp Tq => Commute.add_right Tp Tq) fun m a =>
    show T n * _ = _ by
      

Proof state:
R : Type u_1
inst✝ : Semiring R
n : ℤ
f : R[T;T⁻¹]
m : ℤ
a : R
⊢ T n * (C a * T m) = C a * T m * T n

Next tactic:
rw [T, T, ← single_eq_C, single_mul_single, single_mul_single, single_mul_single]
theorem commute_T (n : ℤ) (f : R[T;T⁻¹]) : Commute (T n) f :=
  f.induction_on' (fun p q Tp Tq => Commute.add_right Tp Tq) fun m a =>
    show T n * _ = _ by
      rw [T, T, ← single_eq_C, single_mul_single, single_mul_single, single_mul_single]
      

Proof state:
R : Type u_1
inst✝ : Semiring R
n : ℤ
f : R[T;T⁻¹]
m : ℤ
a : R
⊢ AddMonoidAlgebra.single (n + (0 + m)) (1 * (a * 1)) = AddMonoidAlgebra.single (0 + m + n) (a * 1 * 1)

Next tactic:
simp [add_comm]
@[simp]
theorem trunc_C_mul_T (n : ℤ) (r : R) : trunc (C r * T n) = ite (0 ≤ n) (monomial n.toNat r) 0 := by
  -- Porting note: added. Should move elsewhere after the port.
  

Proof state:
R : Type u_1
inst✝ : Semiring R
n : ℤ
r : R
⊢ trunc (C r * T n) = if 0 ≤ n then (monomial (Int.toNat n)) r else 0

Next tactic:
have : Function.Injective Int.ofNat := fun x y h => Int.ofNat_inj.mp h
@[simp]
theorem trunc_C_mul_T (n : ℤ) (r : R) : trunc (C r * T n) = ite (0 ≤ n) (monomial n.toNat r) 0 := by
  -- Porting note: added. Should move elsewhere after the port.
  have : Function.Injective Int.ofNat := fun x y h => Int.ofNat_inj.mp h
  

Proof state:
R : Type u_1
inst✝ : Semiring R
n : ℤ
r : R
this : Injective Int.ofNat
⊢ trunc (C r * T n) = if 0 ≤ n then (monomial (Int.toNat n)) r else 0

Next tactic:
apply (toFinsuppIso R).injective
@[simp]
theorem trunc_C_mul_T (n : ℤ) (r : R) : trunc (C r * T n) = ite (0 ≤ n) (monomial n.toNat r) 0 := by
  -- Porting note: added. Should move elsewhere after the port.
  have : Function.Injective Int.ofNat := fun x y h => Int.ofNat_inj.mp h
  apply (toFinsuppIso R).injective
  

Proof state:
case a
R : Type u_1
inst✝ : Semiring R
n : ℤ
r : R
this : Injective Int.ofNat
⊢ (toFinsuppIso R) (trunc (C r * T n)) = (toFinsuppIso R) (if 0 ≤ n then (monomial (Int.toNat n)) r else 0)

Next tactic:
rw [← single_eq_C_mul_T, trunc, AddMonoidHom.coe_comp, Function.comp_apply]
@[simp]
theorem trunc_C_mul_T (n : ℤ) (r : R) : trunc (C r * T n) = ite (0 ≤ n) (monomial n.toNat r) 0 := by
  -- Porting note: added. Should move elsewhere after the port.
  have : Function.Injective Int.ofNat := fun x y h => Int.ofNat_inj.mp h
  apply (toFinsuppIso R).injective
  rw [← single_eq_C_mul_T, trunc, AddMonoidHom.coe_comp, Function.comp_apply]
  -- Porting note: was `rw`
  

Proof state:
case a
R : Type u_1
inst✝ : Semiring R
n : ℤ
r : R
this : Injective Int.ofNat
⊢ (toFinsuppIso R)
      ((RingEquiv.toAddMonoidHom (RingEquiv.symm (toFinsuppIso R)))
        ((comapDomain.addMonoidHom (_ : ∀ (x x_1 : ℕ), Int.ofNat x = Int.ofNat x_1 → x = x_1)) fun₀ | n => r)) =
    (toFinsuppIso R) (if 0 ≤ n then (monomial (Int.toNat n)) r else 0)

Next tactic:
erw [comapDomain.addMonoidHom_apply this]
@[simp]
theorem trunc_C_mul_T (n : ℤ) (r : R) : trunc (C r * T n) = ite (0 ≤ n) (monomial n.toNat r) 0 := by
  -- Porting note: added. Should move elsewhere after the port.
  have : Function.Injective Int.ofNat := fun x y h => Int.ofNat_inj.mp h
  apply (toFinsuppIso R).injective
  rw [← single_eq_C_mul_T, trunc, AddMonoidHom.coe_comp, Function.comp_apply]
  -- Porting note: was `rw`
  erw [comapDomain.addMonoidHom_apply this]
  

Proof state:
case a
R : Type u_1
inst✝ : Semiring R
n : ℤ
r : R
this : Injective Int.ofNat
⊢ comapDomain Int.ofNat (fun₀ | n => r) (_ : Set.InjOn Int.ofNat (Int.ofNat ⁻¹' ↑(fun₀ | n => r).support)) =
    (toFinsuppIso R) (if 0 ≤ n then (monomial (Int.toNat n)) r else 0)

Next tactic:
rw [toFinsuppIso_apply]
@[simp]
theorem trunc_C_mul_T (n : ℤ) (r : R) : trunc (C r * T n) = ite (0 ≤ n) (monomial n.toNat r) 0 := by
  -- Porting note: added. Should move elsewhere after the port.
  have : Function.Injective Int.ofNat := fun x y h => Int.ofNat_inj.mp h
  apply (toFinsuppIso R).injective
  rw [← single_eq_C_mul_T, trunc, AddMonoidHom.coe_comp, Function.comp_apply]
  -- Porting note: was `rw`
  erw [comapDomain.addMonoidHom_apply this]
  rw [toFinsuppIso_apply]
  -- Porting note: rewrote proof below relative to mathlib3.
  

Proof state:
case a
R : Type u_1
inst✝ : Semiring R
n : ℤ
r : R
this : Injective Int.ofNat
⊢ comapDomain Int.ofNat (fun₀ | n => r) (_ : Set.InjOn Int.ofNat (Int.ofNat ⁻¹' ↑(fun₀ | n => r).support)) =
    (if 0 ≤ n then (monomial (Int.toNat n)) r else 0).toFinsupp

Next tactic:
by_cases n0 : 0 ≤ n
@[simp]
theorem trunc_C_mul_T (n : ℤ) (r : R) : trunc (C r * T n) = ite (0 ≤ n) (monomial n.toNat r) 0 := by
  -- Porting note: added. Should move elsewhere after the port.
  have : Function.Injective Int.ofNat := fun x y h => Int.ofNat_inj.mp h
  apply (toFinsuppIso R).injective
  rw [← single_eq_C_mul_T, trunc, AddMonoidHom.coe_comp, Function.comp_apply]
  -- Porting note: was `rw`
  erw [comapDomain.addMonoidHom_apply this]
  rw [toFinsuppIso_apply]
  -- Porting note: rewrote proof below relative to mathlib3.
  by_cases n0 : 0 ≤ n
  · 

Proof state:
case pos
R : Type u_1
inst✝ : Semiring R
n : ℤ
r : R
this : Injective Int.ofNat
n0 : 0 ≤ n
⊢ comapDomain Int.ofNat (fun₀ | n => r) (_ : Set.InjOn Int.ofNat (Int.ofNat ⁻¹' ↑(fun₀ | n => r).support)) =
    (if 0 ≤ n then (monomial (Int.toNat n)) r else 0).toFinsupp

Next tactic:
lift n to ℕ using n0
@[simp]
theorem trunc_C_mul_T (n : ℤ) (r : R) : trunc (C r * T n) = ite (0 ≤ n) (monomial n.toNat r) 0 := by
  -- Porting note: added. Should move elsewhere after the port.
  have : Function.Injective Int.ofNat := fun x y h => Int.ofNat_inj.mp h
  apply (toFinsuppIso R).injective
  rw [← single_eq_C_mul_T, trunc, AddMonoidHom.coe_comp, Function.comp_apply]
  -- Porting note: was `rw`
  erw [comapDomain.addMonoidHom_apply this]
  rw [toFinsuppIso_apply]
  -- Porting note: rewrote proof below relative to mathlib3.
  by_cases n0 : 0 ≤ n
  · lift n to ℕ using n0
    

Proof state:
case pos.intro
R : Type u_1
inst✝ : Semiring R
r : R
this : Injective Int.ofNat
n : ℕ
⊢ comapDomain Int.ofNat (fun₀ | ↑n => r) (_ : Set.InjOn Int.ofNat (Int.ofNat ⁻¹' ↑(fun₀ | ↑n => r).support)) =
    (if 0 ≤ ↑n then (monomial (Int.toNat ↑n)) r else 0).toFinsupp

Next tactic:
erw [comapDomain_single]
@[simp]
theorem trunc_C_mul_T (n : ℤ) (r : R) : trunc (C r * T n) = ite (0 ≤ n) (monomial n.toNat r) 0 := by
  -- Porting note: added. Should move elsewhere after the port.
  have : Function.Injective Int.ofNat := fun x y h => Int.ofNat_inj.mp h
  apply (toFinsuppIso R).injective
  rw [← single_eq_C_mul_T, trunc, AddMonoidHom.coe_comp, Function.comp_apply]
  -- Porting note: was `rw`
  erw [comapDomain.addMonoidHom_apply this]
  rw [toFinsuppIso_apply]
  -- Porting note: rewrote proof below relative to mathlib3.
  by_cases n0 : 0 ≤ n
  · lift n to ℕ using n0
    erw [comapDomain_single]
    

Proof state:
case pos.intro
R : Type u_1
inst✝ : Semiring R
r : R
this : Injective Int.ofNat
n : ℕ
⊢ (fun₀ | n => r) = (if 0 ≤ ↑n then (monomial (Int.toNat ↑n)) r else 0).toFinsupp

Next tactic:
simp only [Nat.cast_nonneg, Int.toNat_ofNat, ite_true, toFinsupp_monomial]
@[simp]
theorem trunc_C_mul_T (n : ℤ) (r : R) : trunc (C r * T n) = ite (0 ≤ n) (monomial n.toNat r) 0 := by
  -- Porting note: added. Should move elsewhere after the port.
  have : Function.Injective Int.ofNat := fun x y h => Int.ofNat_inj.mp h
  apply (toFinsuppIso R).injective
  rw [← single_eq_C_mul_T, trunc, AddMonoidHom.coe_comp, Function.comp_apply]
  -- Porting note: was `rw`
  erw [comapDomain.addMonoidHom_apply this]
  rw [toFinsuppIso_apply]
  -- Porting note: rewrote proof below relative to mathlib3.
  by_cases n0 : 0 ≤ n
  · lift n to ℕ using n0
    erw [comapDomain_single]
    simp only [Nat.cast_nonneg, Int.toNat_ofNat, ite_true, toFinsupp_monomial]
  · 

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
n : ℤ
r : R
this : Injective Int.ofNat
n0 : ¬0 ≤ n
⊢ comapDomain Int.ofNat (fun₀ | n => r) (_ : Set.InjOn Int.ofNat (Int.ofNat ⁻¹' ↑(fun₀ | n => r).support)) =
    (if 0 ≤ n then (monomial (Int.toNat n)) r else 0).toFinsupp

Next tactic:
lift -n to ℕ using (neg_pos.mpr (not_le.mp n0)).le with m
@[simp]
theorem trunc_C_mul_T (n : ℤ) (r : R) : trunc (C r * T n) = ite (0 ≤ n) (monomial n.toNat r) 0 := by
  -- Porting note: added. Should move elsewhere after the port.
  have : Function.Injective Int.ofNat := fun x y h => Int.ofNat_inj.mp h
  apply (toFinsuppIso R).injective
  rw [← single_eq_C_mul_T, trunc, AddMonoidHom.coe_comp, Function.comp_apply]
  -- Porting note: was `rw`
  erw [comapDomain.addMonoidHom_apply this]
  rw [toFinsuppIso_apply]
  -- Porting note: rewrote proof below relative to mathlib3.
  by_cases n0 : 0 ≤ n
  · lift n to ℕ using n0
    erw [comapDomain_single]
    simp only [Nat.cast_nonneg, Int.toNat_ofNat, ite_true, toFinsupp_monomial]
  · lift -n to ℕ using (neg_pos.mpr (not_le.mp n0)).le with m
    

Proof state:
case neg.intro
R : Type u_1
inst✝ : Semiring R
n : ℤ
r : R
this : Injective Int.ofNat
n0 : ¬0 ≤ n
m : ℕ
⊢ comapDomain Int.ofNat (fun₀ | n => r) (_ : Set.InjOn Int.ofNat (Int.ofNat ⁻¹' ↑(fun₀ | n => r).support)) =
    (if 0 ≤ n then (monomial (Int.toNat n)) r else 0).toFinsupp

Next tactic:
rw [toFinsupp_inj, if_neg n0]
@[simp]
theorem trunc_C_mul_T (n : ℤ) (r : R) : trunc (C r * T n) = ite (0 ≤ n) (monomial n.toNat r) 0 := by
  -- Porting note: added. Should move elsewhere after the port.
  have : Function.Injective Int.ofNat := fun x y h => Int.ofNat_inj.mp h
  apply (toFinsuppIso R).injective
  rw [← single_eq_C_mul_T, trunc, AddMonoidHom.coe_comp, Function.comp_apply]
  -- Porting note: was `rw`
  erw [comapDomain.addMonoidHom_apply this]
  rw [toFinsuppIso_apply]
  -- Porting note: rewrote proof below relative to mathlib3.
  by_cases n0 : 0 ≤ n
  · lift n to ℕ using n0
    erw [comapDomain_single]
    simp only [Nat.cast_nonneg, Int.toNat_ofNat, ite_true, toFinsupp_monomial]
  · lift -n to ℕ using (neg_pos.mpr (not_le.mp n0)).le with m
    rw [toFinsupp_inj, if_neg n0]
    

Proof state:
case neg.intro
R : Type u_1
inst✝ : Semiring R
n : ℤ
r : R
this : Injective Int.ofNat
n0 : ¬0 ≤ n
m : ℕ
⊢ {
      toFinsupp :=
        comapDomain Int.ofNat (fun₀ | n => r) (_ : Set.InjOn Int.ofNat (Int.ofNat ⁻¹' ↑(fun₀ | n => r).support)) } =
    0

Next tactic:
ext a
@[simp]
theorem trunc_C_mul_T (n : ℤ) (r : R) : trunc (C r * T n) = ite (0 ≤ n) (monomial n.toNat r) 0 := by
  -- Porting note: added. Should move elsewhere after the port.
  have : Function.Injective Int.ofNat := fun x y h => Int.ofNat_inj.mp h
  apply (toFinsuppIso R).injective
  rw [← single_eq_C_mul_T, trunc, AddMonoidHom.coe_comp, Function.comp_apply]
  -- Porting note: was `rw`
  erw [comapDomain.addMonoidHom_apply this]
  rw [toFinsuppIso_apply]
  -- Porting note: rewrote proof below relative to mathlib3.
  by_cases n0 : 0 ≤ n
  · lift n to ℕ using n0
    erw [comapDomain_single]
    simp only [Nat.cast_nonneg, Int.toNat_ofNat, ite_true, toFinsupp_monomial]
  · lift -n to ℕ using (neg_pos.mpr (not_le.mp n0)).le with m
    rw [toFinsupp_inj, if_neg n0]
    ext a
    

Proof state:
case neg.intro.a
R : Type u_1
inst✝ : Semiring R
n : ℤ
r : R
this : Injective Int.ofNat
n0 : ¬0 ≤ n
m a : ℕ
⊢ coeff
      {
        toFinsupp :=
          comapDomain Int.ofNat (fun₀ | n => r) (_ : Set.InjOn Int.ofNat (Int.ofNat ⁻¹' ↑(fun₀ | n => r).support)) }
      a =
    coeff 0 a

Next tactic:
have := ((not_le.mp n0).trans_le (Int.ofNat_zero_le a)).ne
@[simp]
theorem trunc_C_mul_T (n : ℤ) (r : R) : trunc (C r * T n) = ite (0 ≤ n) (monomial n.toNat r) 0 := by
  -- Porting note: added. Should move elsewhere after the port.
  have : Function.Injective Int.ofNat := fun x y h => Int.ofNat_inj.mp h
  apply (toFinsuppIso R).injective
  rw [← single_eq_C_mul_T, trunc, AddMonoidHom.coe_comp, Function.comp_apply]
  -- Porting note: was `rw`
  erw [comapDomain.addMonoidHom_apply this]
  rw [toFinsuppIso_apply]
  -- Porting note: rewrote proof below relative to mathlib3.
  by_cases n0 : 0 ≤ n
  · lift n to ℕ using n0
    erw [comapDomain_single]
    simp only [Nat.cast_nonneg, Int.toNat_ofNat, ite_true, toFinsupp_monomial]
  · lift -n to ℕ using (neg_pos.mpr (not_le.mp n0)).le with m
    rw [toFinsupp_inj, if_neg n0]
    ext a
    have := ((not_le.mp n0).trans_le (Int.ofNat_zero_le a)).ne
    

Proof state:
case neg.intro.a
R : Type u_1
inst✝ : Semiring R
n : ℤ
r : R
this✝ : Injective Int.ofNat
n0 : ¬0 ≤ n
m a : ℕ
this : n ≠ ↑a
⊢ coeff
      {
        toFinsupp :=
          comapDomain Int.ofNat (fun₀ | n => r) (_ : Set.InjOn Int.ofNat (Int.ofNat ⁻¹' ↑(fun₀ | n => r).support)) }
      a =
    coeff 0 a

Next tactic:
simp only [coeff_ofFinsupp, comapDomain_apply, Int.ofNat_eq_coe, coeff_zero,
      single_eq_of_ne this]
@[simp]
theorem leftInverse_trunc_toLaurent :
    Function.LeftInverse (trunc : R[T;T⁻¹] → R[X]) Polynomial.toLaurent := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
⊢ LeftInverse ⇑trunc ⇑toLaurent

Next tactic:
refine' fun f => f.induction_on' _ _
@[simp]
theorem leftInverse_trunc_toLaurent :
    Function.LeftInverse (trunc : R[T;T⁻¹] → R[X]) Polynomial.toLaurent := by
  refine' fun f => f.induction_on' _ _
  · 

Proof state:
case refine'_1
R : Type u_1
inst✝ : Semiring R
f : R[X]
⊢ ∀ (p q : R[X]), trunc (toLaurent p) = p → trunc (toLaurent q) = q → trunc (toLaurent (p + q)) = p + q

Next tactic:
intro f g hf hg