l3lab/ntp-mathlib huggingface dataset:
/-- The diagonal `λ x, f x x` of a polynomial function `f` is polynomial. -/
-- Porting note: made this an instance
instance IsPoly₂.diag {f} [hf : IsPoly₂ p f] : IsPoly p fun R _Rcr x => f x x := by
  obtain ⟨φ, hf⟩ := hf
  

Proof state:
case mk'.intro
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
f : ⦃R : Type ?u.374137⦄ → [inst : CommRing R] → 𝕎 R → 𝕎 R → 𝕎 R
φ : ℕ → MvPolynomial (Fin 2 × ℕ) ℤ
hf : ∀ ⦃R : Type ?u.374137⦄ [inst : CommRing R] (x y : 𝕎 R), (f x y).coeff = fun n => peval (φ n) ![x.coeff, y.coeff]
⊢ IsPoly p fun R _Rcr x => f x x

Next tactic:
refine' ⟨⟨fun n => bind₁ (uncurry ![X, X]) (φ n), _⟩⟩
/-- The diagonal `λ x, f x x` of a polynomial function `f` is polynomial. -/
-- Porting note: made this an instance
instance IsPoly₂.diag {f} [hf : IsPoly₂ p f] : IsPoly p fun R _Rcr x => f x x := by
  obtain ⟨φ, hf⟩ := hf
  refine' ⟨⟨fun n => bind₁ (uncurry ![X, X]) (φ n), _⟩⟩
  

Proof state:
case mk'.intro
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
f : ⦃R : Type ?u.374137⦄ → [inst : CommRing R] → 𝕎 R → 𝕎 R → 𝕎 R
φ : ℕ → MvPolynomial (Fin 2 × ℕ) ℤ
hf : ∀ ⦃R : Type ?u.374137⦄ [inst : CommRing R] (x y : 𝕎 R), (f x y).coeff = fun n => peval (φ n) ![x.coeff, y.coeff]
⊢ ∀ ⦃R : Type ?u.374137⦄ [inst : CommRing R] (x : 𝕎 R),
    (f x x).coeff = fun n => (aeval x.coeff) ((fun n => (bind₁ (uncurry ![X, X])) (φ n)) n)

Next tactic:
intros
/-- The diagonal `λ x, f x x` of a polynomial function `f` is polynomial. -/
-- Porting note: made this an instance
instance IsPoly₂.diag {f} [hf : IsPoly₂ p f] : IsPoly p fun R _Rcr x => f x x := by
  obtain ⟨φ, hf⟩ := hf
  refine' ⟨⟨fun n => bind₁ (uncurry ![X, X]) (φ n), _⟩⟩
  intros; 

Proof state:
case mk'.intro
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
f : ⦃R : Type ?u.374137⦄ → [inst : CommRing R] → 𝕎 R → 𝕎 R → 𝕎 R
φ : ℕ → MvPolynomial (Fin 2 × ℕ) ℤ
hf : ∀ ⦃R : Type ?u.374137⦄ [inst : CommRing R] (x y : 𝕎 R), (f x y).coeff = fun n => peval (φ n) ![x.coeff, y.coeff]
R✝ : Type ?u.374137
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
⊢ (f x✝ x✝).coeff = fun n => (aeval x✝.coeff) ((fun n => (bind₁ (uncurry ![X, X])) (φ n)) n)

Next tactic:
funext n
/-- The diagonal `λ x, f x x` of a polynomial function `f` is polynomial. -/
-- Porting note: made this an instance
instance IsPoly₂.diag {f} [hf : IsPoly₂ p f] : IsPoly p fun R _Rcr x => f x x := by
  obtain ⟨φ, hf⟩ := hf
  refine' ⟨⟨fun n => bind₁ (uncurry ![X, X]) (φ n), _⟩⟩
  intros; funext n
  

Proof state:
case mk'.intro.h
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
f : ⦃R : Type ?u.374137⦄ → [inst : CommRing R] → 𝕎 R → 𝕎 R → 𝕎 R
φ : ℕ → MvPolynomial (Fin 2 × ℕ) ℤ
hf : ∀ ⦃R : Type ?u.374137⦄ [inst : CommRing R] (x y : 𝕎 R), (f x y).coeff = fun n => peval (φ n) ![x.coeff, y.coeff]
R✝ : Type ?u.374137
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
n : ℕ
⊢ coeff (f x✝ x✝) n = (aeval x✝.coeff) ((fun n => (bind₁ (uncurry ![X, X])) (φ n)) n)

Next tactic:
simp (config := { unfoldPartialApp := true }) only [hf, peval, uncurry, aeval_bind₁]
/-- The diagonal `λ x, f x x` of a polynomial function `f` is polynomial. -/
-- Porting note: made this an instance
instance IsPoly₂.diag {f} [hf : IsPoly₂ p f] : IsPoly p fun R _Rcr x => f x x := by
  obtain ⟨φ, hf⟩ := hf
  refine' ⟨⟨fun n => bind₁ (uncurry ![X, X]) (φ n), _⟩⟩
  intros; funext n
  simp (config := { unfoldPartialApp := true }) only [hf, peval, uncurry, aeval_bind₁]
  

Proof state:
case mk'.intro.h
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
f : ⦃R : Type ?u.374137⦄ → [inst : CommRing R] → 𝕎 R → 𝕎 R → 𝕎 R
φ : ℕ → MvPolynomial (Fin 2 × ℕ) ℤ
hf : ∀ ⦃R : Type ?u.374137⦄ [inst : CommRing R] (x y : 𝕎 R), (f x y).coeff = fun n => peval (φ n) ![x.coeff, y.coeff]
R✝ : Type ?u.374137
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
n : ℕ
⊢ (aeval fun a => Matrix.vecCons x✝.coeff ![x✝.coeff] a.1 a.2) (φ n) =
    (aeval fun i => (aeval x✝.coeff) (Matrix.vecCons X ![X] i.1 i.2)) (φ n)

Next tactic:
apply eval₂Hom_congr rfl _ rfl
/-- The diagonal `λ x, f x x` of a polynomial function `f` is polynomial. -/
-- Porting note: made this an instance
instance IsPoly₂.diag {f} [hf : IsPoly₂ p f] : IsPoly p fun R _Rcr x => f x x := by
  obtain ⟨φ, hf⟩ := hf
  refine' ⟨⟨fun n => bind₁ (uncurry ![X, X]) (φ n), _⟩⟩
  intros; funext n
  simp (config := { unfoldPartialApp := true }) only [hf, peval, uncurry, aeval_bind₁]
  apply eval₂Hom_congr rfl _ rfl
  

Proof state:
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
f : ⦃R : Type ?u.374137⦄ → [inst : CommRing R] → 𝕎 R → 𝕎 R → 𝕎 R
φ : ℕ → MvPolynomial (Fin 2 × ℕ) ℤ
hf : ∀ ⦃R : Type ?u.374137⦄ [inst : CommRing R] (x y : 𝕎 R), (f x y).coeff = fun n => peval (φ n) ![x.coeff, y.coeff]
R✝ : Type ?u.374137
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
n : ℕ
⊢ (fun a => Matrix.vecCons x✝.coeff ![x✝.coeff] a.1 a.2) = fun i => (aeval x✝.coeff) (Matrix.vecCons X ![X] i.1 i.2)

Next tactic:
ext ⟨i, k⟩
/-- The diagonal `λ x, f x x` of a polynomial function `f` is polynomial. -/
-- Porting note: made this an instance
instance IsPoly₂.diag {f} [hf : IsPoly₂ p f] : IsPoly p fun R _Rcr x => f x x := by
  obtain ⟨φ, hf⟩ := hf
  refine' ⟨⟨fun n => bind₁ (uncurry ![X, X]) (φ n), _⟩⟩
  intros; funext n
  simp (config := { unfoldPartialApp := true }) only [hf, peval, uncurry, aeval_bind₁]
  apply eval₂Hom_congr rfl _ rfl
  ext ⟨i, k⟩;
  

Proof state:
case h.mk
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
f : ⦃R : Type ?u.374137⦄ → [inst : CommRing R] → 𝕎 R → 𝕎 R → 𝕎 R
φ : ℕ → MvPolynomial (Fin 2 × ℕ) ℤ
hf : ∀ ⦃R : Type ?u.374137⦄ [inst : CommRing R] (x y : 𝕎 R), (f x y).coeff = fun n => peval (φ n) ![x.coeff, y.coeff]
R✝ : Type ?u.374137
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
n : ℕ
i : Fin 2
k : ℕ
⊢ Matrix.vecCons x✝.coeff ![x✝.coeff] (i, k).1 (i, k).2 = (aeval x✝.coeff) (Matrix.vecCons X ![X] (i, k).1 (i, k).2)

Next tactic:
fin_cases i
/-- The diagonal `λ x, f x x` of a polynomial function `f` is polynomial. -/
-- Porting note: made this an instance
instance IsPoly₂.diag {f} [hf : IsPoly₂ p f] : IsPoly p fun R _Rcr x => f x x := by
  obtain ⟨φ, hf⟩ := hf
  refine' ⟨⟨fun n => bind₁ (uncurry ![X, X]) (φ n), _⟩⟩
  intros; funext n
  simp (config := { unfoldPartialApp := true }) only [hf, peval, uncurry, aeval_bind₁]
  apply eval₂Hom_congr rfl _ rfl
  ext ⟨i, k⟩;
  fin_cases i <;>
    

Proof state:
case h.mk.head
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
f : ⦃R : Type ?u.374137⦄ → [inst : CommRing R] → 𝕎 R → 𝕎 R → 𝕎 R
φ : ℕ → MvPolynomial (Fin 2 × ℕ) ℤ
hf : ∀ ⦃R : Type ?u.374137⦄ [inst : CommRing R] (x y : 𝕎 R), (f x y).coeff = fun n => peval (φ n) ![x.coeff, y.coeff]
R✝ : Type ?u.374137
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
n k : ℕ
⊢ Matrix.vecCons x✝.coeff ![x✝.coeff] ({ val := 0, isLt := (_ : 0 < 2) }, k).1
      ({ val := 0, isLt := (_ : 0 < 2) }, k).2 =
    (aeval x✝.coeff)
      (Matrix.vecCons X ![X] ({ val := 0, isLt := (_ : 0 < 2) }, k).1 ({ val := 0, isLt := (_ : 0 < 2) }, k).2)

Next tactic:
simp only [Matrix.head_cons, aeval_X, Matrix.cons_val_zero, Matrix.cons_val_one]
/-- The diagonal `λ x, f x x` of a polynomial function `f` is polynomial. -/
-- Porting note: made this an instance
instance IsPoly₂.diag {f} [hf : IsPoly₂ p f] : IsPoly p fun R _Rcr x => f x x := by
  obtain ⟨φ, hf⟩ := hf
  refine' ⟨⟨fun n => bind₁ (uncurry ![X, X]) (φ n), _⟩⟩
  intros; funext n
  simp (config := { unfoldPartialApp := true }) only [hf, peval, uncurry, aeval_bind₁]
  apply eval₂Hom_congr rfl _ rfl
  ext ⟨i, k⟩;
  fin_cases i <;>
    

Proof state:
case h.mk.tail.head
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
f : ⦃R : Type ?u.374137⦄ → [inst : CommRing R] → 𝕎 R → 𝕎 R → 𝕎 R
φ : ℕ → MvPolynomial (Fin 2 × ℕ) ℤ
hf : ∀ ⦃R : Type ?u.374137⦄ [inst : CommRing R] (x y : 𝕎 R), (f x y).coeff = fun n => peval (φ n) ![x.coeff, y.coeff]
R✝ : Type ?u.374137
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
n k : ℕ
⊢ Matrix.vecCons x✝.coeff ![x✝.coeff] ({ val := 1, isLt := (_ : (fun a => a < 2) 1) }, k).1
      ({ val := 1, isLt := (_ : (fun a => a < 2) 1) }, k).2 =
    (aeval x✝.coeff)
      (Matrix.vecCons X ![X] ({ val := 1, isLt := (_ : (fun a => a < 2) 1) }, k).1
        ({ val := 1, isLt := (_ : (fun a => a < 2) 1) }, k).2)

Next tactic:
simp only [Matrix.head_cons, aeval_X, Matrix.cons_val_zero, Matrix.cons_val_one]
/-- The diagonal `λ x, f x x` of a polynomial function `f` is polynomial. -/
-- Porting note: made this an instance
instance IsPoly₂.diag {f} [hf : IsPoly₂ p f] : IsPoly p fun R _Rcr x => f x x := by
  obtain ⟨φ, hf⟩ := hf
  refine' ⟨⟨fun n => bind₁ (uncurry ![X, X]) (φ n), _⟩⟩
  intros; funext n
  simp (config := { unfoldPartialApp := true }) only [hf, peval, uncurry, aeval_bind₁]
  apply eval₂Hom_congr rfl _ rfl
  ext ⟨i, k⟩;
  fin_cases i <;>
    simp only [Matrix.head_cons, aeval_X, Matrix.cons_val_zero, Matrix.cons_val_one] <;>
    --  porting note: the end of the proof was added in the port.
    

Proof state:
case h.mk.head
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
f : ⦃R : Type ?u.374137⦄ → [inst : CommRing R] → 𝕎 R → 𝕎 R → 𝕎 R
φ : ℕ → MvPolynomial (Fin 2 × ℕ) ℤ
hf : ∀ ⦃R : Type ?u.374137⦄ [inst : CommRing R] (x y : 𝕎 R), (f x y).coeff = fun n => peval (φ n) ![x.coeff, y.coeff]
R✝ : Type ?u.374137
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
n k : ℕ
⊢ Matrix.vecCons x✝.coeff ![x✝.coeff] { val := 0, isLt := (_ : 0 < 2) } k =
    (aeval x✝.coeff) (Matrix.vecCons X ![X] { val := 0, isLt := (_ : 0 < 2) } k)

Next tactic:
open Matrix in
    simp only [Fin.mk_zero, Fin.mk_one, cons_val', empty_val', cons_val_fin_one, cons_val_zero,
      aeval_X, head_fin_const, cons_val_one]
/-- The diagonal `λ x, f x x` of a polynomial function `f` is polynomial. -/
-- Porting note: made this an instance
instance IsPoly₂.diag {f} [hf : IsPoly₂ p f] : IsPoly p fun R _Rcr x => f x x := by
  obtain ⟨φ, hf⟩ := hf
  refine' ⟨⟨fun n => bind₁ (uncurry ![X, X]) (φ n), _⟩⟩
  intros; funext n
  simp (config := { unfoldPartialApp := true }) only [hf, peval, uncurry, aeval_bind₁]
  apply eval₂Hom_congr rfl _ rfl
  ext ⟨i, k⟩;
  fin_cases i <;>
    simp only [Matrix.head_cons, aeval_X, Matrix.cons_val_zero, Matrix.cons_val_one] <;>
    --  porting note: the end of the proof was added in the port.
    open Matrix in
    

Proof state:
case h.mk.head
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
f : ⦃R : Type ?u.374137⦄ → [inst : CommRing R] → 𝕎 R → 𝕎 R → 𝕎 R
φ : ℕ → MvPolynomial (Fin 2 × ℕ) ℤ
hf : ∀ ⦃R : Type ?u.374137⦄ [inst : CommRing R] (x y : 𝕎 R), (f x y).coeff = fun n => peval (φ n) ![x.coeff, y.coeff]
R✝ : Type ?u.374137
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
n k : ℕ
⊢ Matrix.vecCons x✝.coeff ![x✝.coeff] { val := 0, isLt := (_ : 0 < 2) } k =
    (aeval x✝.coeff) (Matrix.vecCons X ![X] { val := 0, isLt := (_ : 0 < 2) } k)

Next tactic:
simp only [Fin.mk_zero, Fin.mk_one, cons_val', empty_val', cons_val_fin_one, cons_val_zero,
      aeval_X, head_fin_const, cons_val_one]
/-- The diagonal `λ x, f x x` of a polynomial function `f` is polynomial. -/
-- Porting note: made this an instance
instance IsPoly₂.diag {f} [hf : IsPoly₂ p f] : IsPoly p fun R _Rcr x => f x x := by
  obtain ⟨φ, hf⟩ := hf
  refine' ⟨⟨fun n => bind₁ (uncurry ![X, X]) (φ n), _⟩⟩
  intros; funext n
  simp (config := { unfoldPartialApp := true }) only [hf, peval, uncurry, aeval_bind₁]
  apply eval₂Hom_congr rfl _ rfl
  ext ⟨i, k⟩;
  fin_cases i <;>
    simp only [Matrix.head_cons, aeval_X, Matrix.cons_val_zero, Matrix.cons_val_one] <;>
    --  porting note: the end of the proof was added in the port.
    

Proof state:
case h.mk.tail.head
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
f : ⦃R : Type ?u.374137⦄ → [inst : CommRing R] → 𝕎 R → 𝕎 R → 𝕎 R
φ : ℕ → MvPolynomial (Fin 2 × ℕ) ℤ
hf : ∀ ⦃R : Type ?u.374137⦄ [inst : CommRing R] (x y : 𝕎 R), (f x y).coeff = fun n => peval (φ n) ![x.coeff, y.coeff]
R✝ : Type ?u.374137
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
n k : ℕ
⊢ Matrix.vecCons x✝.coeff ![x✝.coeff] { val := 1, isLt := (_ : (fun a => a < 2) 1) } k =
    (aeval x✝.coeff) (Matrix.vecCons X ![X] { val := 1, isLt := (_ : (fun a => a < 2) 1) } k)

Next tactic:
open Matrix in
    simp only [Fin.mk_zero, Fin.mk_one, cons_val', empty_val', cons_val_fin_one, cons_val_zero,
      aeval_X, head_fin_const, cons_val_one]
/-- The diagonal `λ x, f x x` of a polynomial function `f` is polynomial. -/
-- Porting note: made this an instance
instance IsPoly₂.diag {f} [hf : IsPoly₂ p f] : IsPoly p fun R _Rcr x => f x x := by
  obtain ⟨φ, hf⟩ := hf
  refine' ⟨⟨fun n => bind₁ (uncurry ![X, X]) (φ n), _⟩⟩
  intros; funext n
  simp (config := { unfoldPartialApp := true }) only [hf, peval, uncurry, aeval_bind₁]
  apply eval₂Hom_congr rfl _ rfl
  ext ⟨i, k⟩;
  fin_cases i <;>
    simp only [Matrix.head_cons, aeval_X, Matrix.cons_val_zero, Matrix.cons_val_one] <;>
    --  porting note: the end of the proof was added in the port.
    open Matrix in
    

Proof state:
case h.mk.tail.head
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
f : ⦃R : Type ?u.374137⦄ → [inst : CommRing R] → 𝕎 R → 𝕎 R → 𝕎 R
φ : ℕ → MvPolynomial (Fin 2 × ℕ) ℤ
hf : ∀ ⦃R : Type ?u.374137⦄ [inst : CommRing R] (x y : 𝕎 R), (f x y).coeff = fun n => peval (φ n) ![x.coeff, y.coeff]
R✝ : Type ?u.374137
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
n k : ℕ
⊢ Matrix.vecCons x✝.coeff ![x✝.coeff] { val := 1, isLt := (_ : (fun a => a < 2) 1) } k =
    (aeval x✝.coeff) (Matrix.vecCons X ![X] { val := 1, isLt := (_ : (fun a => a < 2) 1) } k)

Next tactic:
simp only [Fin.mk_zero, Fin.mk_one, cons_val', empty_val', cons_val_fin_one, cons_val_zero,
      aeval_X, head_fin_const, cons_val_one]
/-- The additive negation is a polynomial function on Witt vectors. -/
-- Porting note: replaced `@[is_poly]` with `instance`.
instance negIsPoly [Fact p.Prime] : IsPoly p fun R _ => @Neg.neg (𝕎 R) _ :=
  ⟨⟨fun n => rename Prod.snd (wittNeg p n), by
      

Proof state:
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : Fact (Nat.Prime p)
⊢ ∀ ⦃R : Type ?u.397011⦄ [inst : CommRing R] (x : 𝕎 R),
    (-x).coeff = fun n => (aeval x.coeff) ((fun n => (rename Prod.snd) (wittNeg p n)) n)

Next tactic:
intros
/-- The additive negation is a polynomial function on Witt vectors. -/
-- Porting note: replaced `@[is_poly]` with `instance`.
instance negIsPoly [Fact p.Prime] : IsPoly p fun R _ => @Neg.neg (𝕎 R) _ :=
  ⟨⟨fun n => rename Prod.snd (wittNeg p n), by
      intros; 

Proof state:
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝³ : CommRing R
inst✝² : CommRing S
inst✝¹ : Fact (Nat.Prime p)
R✝ : Type ?u.397011
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
⊢ (-x✝).coeff = fun n => (aeval x✝.coeff) ((fun n => (rename Prod.snd) (wittNeg p n)) n)

Next tactic:
funext n
/-- The additive negation is a polynomial function on Witt vectors. -/
-- Porting note: replaced `@[is_poly]` with `instance`.
instance negIsPoly [Fact p.Prime] : IsPoly p fun R _ => @Neg.neg (𝕎 R) _ :=
  ⟨⟨fun n => rename Prod.snd (wittNeg p n), by
      intros; funext n
      

Proof state:
case h
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝³ : CommRing R
inst✝² : CommRing S
inst✝¹ : Fact (Nat.Prime p)
R✝ : Type ?u.397011
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
n : ℕ
⊢ coeff (-x✝) n = (aeval x✝.coeff) ((fun n => (rename Prod.snd) (wittNeg p n)) n)

Next tactic:
rw [neg_coeff, aeval_eq_eval₂Hom, eval₂Hom_rename]
/-- The additive negation is a polynomial function on Witt vectors. -/
-- Porting note: replaced `@[is_poly]` with `instance`.
instance negIsPoly [Fact p.Prime] : IsPoly p fun R _ => @Neg.neg (𝕎 R) _ :=
  ⟨⟨fun n => rename Prod.snd (wittNeg p n), by
      intros; funext n
      rw [neg_coeff, aeval_eq_eval₂Hom, eval₂Hom_rename]
      

Proof state:
case h
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝³ : CommRing R
inst✝² : CommRing S
inst✝¹ : Fact (Nat.Prime p)
R✝ : Type ?u.397011
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
n : ℕ
⊢ peval (wittNeg p n) ![x✝.coeff] = (eval₂Hom (algebraMap ℤ R✝) (x✝.coeff ∘ Prod.snd)) (wittNeg p n)

Next tactic:
apply eval₂Hom_congr rfl _ rfl
/-- The additive negation is a polynomial function on Witt vectors. -/
-- Porting note: replaced `@[is_poly]` with `instance`.
instance negIsPoly [Fact p.Prime] : IsPoly p fun R _ => @Neg.neg (𝕎 R) _ :=
  ⟨⟨fun n => rename Prod.snd (wittNeg p n), by
      intros; funext n
      rw [neg_coeff, aeval_eq_eval₂Hom, eval₂Hom_rename]
      apply eval₂Hom_congr rfl _ rfl
      

Proof state:
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝³ : CommRing R
inst✝² : CommRing S
inst✝¹ : Fact (Nat.Prime p)
R✝ : Type ?u.397011
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
n : ℕ
⊢ uncurry ![x✝.coeff] = x✝.coeff ∘ Prod.snd

Next tactic:
ext ⟨i, k⟩
/-- The additive negation is a polynomial function on Witt vectors. -/
-- Porting note: replaced `@[is_poly]` with `instance`.
instance negIsPoly [Fact p.Prime] : IsPoly p fun R _ => @Neg.neg (𝕎 R) _ :=
  ⟨⟨fun n => rename Prod.snd (wittNeg p n), by
      intros; funext n
      rw [neg_coeff, aeval_eq_eval₂Hom, eval₂Hom_rename]
      apply eval₂Hom_congr rfl _ rfl
      ext ⟨i, k⟩; 

Proof state:
case h.mk
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝³ : CommRing R
inst✝² : CommRing S
inst✝¹ : Fact (Nat.Prime p)
R✝ : Type ?u.397011
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
n : ℕ
i : Fin 1
k : ℕ
⊢ uncurry ![x✝.coeff] (i, k) = (x✝.coeff ∘ Prod.snd) (i, k)

Next tactic:
fin_cases i
/-- The additive negation is a polynomial function on Witt vectors. -/
-- Porting note: replaced `@[is_poly]` with `instance`.
instance negIsPoly [Fact p.Prime] : IsPoly p fun R _ => @Neg.neg (𝕎 R) _ :=
  ⟨⟨fun n => rename Prod.snd (wittNeg p n), by
      intros; funext n
      rw [neg_coeff, aeval_eq_eval₂Hom, eval₂Hom_rename]
      apply eval₂Hom_congr rfl _ rfl
      ext ⟨i, k⟩; fin_cases i; 

Proof state:
case h.mk.head
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝³ : CommRing R
inst✝² : CommRing S
inst✝¹ : Fact (Nat.Prime p)
R✝ : Type ?u.397011
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
n k : ℕ
⊢ uncurry ![x✝.coeff] ({ val := 0, isLt := (_ : 0 < 1) }, k) =
    (x✝.coeff ∘ Prod.snd) ({ val := 0, isLt := (_ : 0 < 1) }, k)

Next tactic:
rfl
/-- The function that is constantly zero on Witt vectors is a polynomial function. -/
instance zeroIsPoly [Fact p.Prime] : IsPoly p fun _ _ _ => 0 :=
  ⟨⟨0, by 

Proof state:
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : Fact (Nat.Prime p)
⊢ ∀ ⦃R : Type ?u.416847⦄ [inst : CommRing R] (x : 𝕎 R), 0.coeff = fun n => (aeval x.coeff) (OfNat.ofNat 0 n)

Next tactic:
intros
/-- The function that is constantly zero on Witt vectors is a polynomial function. -/
instance zeroIsPoly [Fact p.Prime] : IsPoly p fun _ _ _ => 0 :=
  ⟨⟨0, by intros; 

Proof state:
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝³ : CommRing R
inst✝² : CommRing S
inst✝¹ : Fact (Nat.Prime p)
R✝ : Type ?u.416847
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
⊢ 0.coeff = fun n => (aeval x✝.coeff) (OfNat.ofNat 0 n)

Next tactic:
funext n
/-- The function that is constantly zero on Witt vectors is a polynomial function. -/
instance zeroIsPoly [Fact p.Prime] : IsPoly p fun _ _ _ => 0 :=
  ⟨⟨0, by intros; funext n; 

Proof state:
case h
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝³ : CommRing R
inst✝² : CommRing S
inst✝¹ : Fact (Nat.Prime p)
R✝ : Type ?u.416847
inst✝ : CommRing R✝
x✝ : 𝕎 R✝
n : ℕ
⊢ coeff 0 n = (aeval x✝.coeff) (OfNat.ofNat 0 n)

Next tactic:
simp only [Pi.zero_apply, AlgHom.map_zero, zero_coeff]
@[simp]
theorem bind₁_zero_wittPolynomial [Fact p.Prime] (n : ℕ) :
    bind₁ (0 : ℕ → MvPolynomial ℕ R) (wittPolynomial p R n) = 0 := by
  

Proof state:
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
inst✝ : Fact (Nat.Prime p)
n : ℕ
⊢ (bind₁ 0) (wittPolynomial p R n) = 0

Next tactic:
rw [← aeval_eq_bind₁, aeval_zero, constantCoeff_wittPolynomial, RingHom.map_zero]
@[simp]
theorem bind₁_onePoly_wittPolynomial [hp : Fact p.Prime] (n : ℕ) :
    bind₁ onePoly (wittPolynomial p ℤ n) = 1 := by
  

Proof state:
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
hp : Fact (Nat.Prime p)
n : ℕ
⊢ (bind₁ onePoly) (wittPolynomial p ℤ n) = 1

Next tactic:
ext
@[simp]
theorem bind₁_onePoly_wittPolynomial [hp : Fact p.Prime] (n : ℕ) :
    bind₁ onePoly (wittPolynomial p ℤ n) = 1 := by
  ext  -- porting note: `ext` was not in the mathport output.
  

Proof state:
case a
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
hp : Fact (Nat.Prime p)
n : ℕ
m✝ : ℕ →₀ ℕ
⊢ MvPolynomial.coeff m✝ ((bind₁ onePoly) (wittPolynomial p ℤ n)) = MvPolynomial.coeff m✝ 1

Next tactic:
rw [wittPolynomial_eq_sum_C_mul_X_pow, AlgHom.map_sum, Finset.sum_eq_single 0]
@[simp]
theorem bind₁_onePoly_wittPolynomial [hp : Fact p.Prime] (n : ℕ) :
    bind₁ onePoly (wittPolynomial p ℤ n) = 1 := by
  ext  -- porting note: `ext` was not in the mathport output.
  rw [wittPolynomial_eq_sum_C_mul_X_pow, AlgHom.map_sum, Finset.sum_eq_single 0]
  · 

Proof state:
case a
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
hp : Fact (Nat.Prime p)
n : ℕ
m✝ : ℕ →₀ ℕ
⊢ MvPolynomial.coeff m✝ ((bind₁ onePoly) (C (↑p ^ 0) * X 0 ^ p ^ (n - 0))) = MvPolynomial.coeff m✝ 1

Next tactic:
simp only [onePoly, one_pow, one_mul, AlgHom.map_pow, C_1, pow_zero, bind₁_X_right, if_true,
      eq_self_iff_true]
@[simp]
theorem bind₁_onePoly_wittPolynomial [hp : Fact p.Prime] (n : ℕ) :
    bind₁ onePoly (wittPolynomial p ℤ n) = 1 := by
  ext  -- porting note: `ext` was not in the mathport output.
  rw [wittPolynomial_eq_sum_C_mul_X_pow, AlgHom.map_sum, Finset.sum_eq_single 0]
  · simp only [onePoly, one_pow, one_mul, AlgHom.map_pow, C_1, pow_zero, bind₁_X_right, if_true,
      eq_self_iff_true]
  · 

Proof state:
case a.h₀
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
hp : Fact (Nat.Prime p)
n : ℕ
m✝ : ℕ →₀ ℕ
⊢ ∀ b ∈ Finset.range (n + 1), b ≠ 0 → (bind₁ onePoly) (C (↑p ^ b) * X b ^ p ^ (n - b)) = 0

Next tactic:
intro i _hi hi0
@[simp]
theorem bind₁_onePoly_wittPolynomial [hp : Fact p.Prime] (n : ℕ) :
    bind₁ onePoly (wittPolynomial p ℤ n) = 1 := by
  ext  -- porting note: `ext` was not in the mathport output.
  rw [wittPolynomial_eq_sum_C_mul_X_pow, AlgHom.map_sum, Finset.sum_eq_single 0]
  · simp only [onePoly, one_pow, one_mul, AlgHom.map_pow, C_1, pow_zero, bind₁_X_right, if_true,
      eq_self_iff_true]
  · intro i _hi hi0
    

Proof state:
case a.h₀
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
hp : Fact (Nat.Prime p)
n : ℕ
m✝ : ℕ →₀ ℕ
i : ℕ
_hi : i ∈ Finset.range (n + 1)
hi0 : i ≠ 0
⊢ (bind₁ onePoly) (C (↑p ^ i) * X i ^ p ^ (n - i)) = 0

Next tactic:
simp only [onePoly, if_neg hi0, zero_pow (pow_pos hp.1.pos _), mul_zero,
      AlgHom.map_pow, bind₁_X_right, AlgHom.map_mul]
@[simp]
theorem bind₁_onePoly_wittPolynomial [hp : Fact p.Prime] (n : ℕ) :
    bind₁ onePoly (wittPolynomial p ℤ n) = 1 := by
  ext  -- porting note: `ext` was not in the mathport output.
  rw [wittPolynomial_eq_sum_C_mul_X_pow, AlgHom.map_sum, Finset.sum_eq_single 0]
  · simp only [onePoly, one_pow, one_mul, AlgHom.map_pow, C_1, pow_zero, bind₁_X_right, if_true,
      eq_self_iff_true]
  · intro i _hi hi0
    simp only [onePoly, if_neg hi0, zero_pow (pow_pos hp.1.pos _), mul_zero,
      AlgHom.map_pow, bind₁_X_right, AlgHom.map_mul]
  · 

Proof state:
case a.h₁
p : ℕ
R S : Type u
σ : Type u_1
idx : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
hp : Fact (Nat.Prime p)
n : ℕ
m✝ : ℕ →₀ ℕ
⊢ 0 ∉ Finset.range (n + 1) → (bind₁ onePoly) (C (↑p ^ 0) * X 0 ^ p ^ (n - 0)) = 0

Next tactic:
rw [Finset.mem_range]