[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝² : Mul R
inst✝¹ : Add R
inst✝ : RightDistribClass R
a b c d : R
⊢ (a + b + c) * d = a * d + b * d + c * d
[PROOFSTEP]
simp [right_distrib]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝² : Add α
inst✝¹ : MulOneClass α
inst✝ : RightDistribClass α
a b : α
⊢ (a + 1) * b = a * b + b
[PROOFSTEP]
rw [add_mul, one_mul]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝² : Add α
inst✝¹ : MulOneClass α
inst✝ : LeftDistribClass α
a b : α
⊢ a * (b + 1) = a * b + a
[PROOFSTEP]
rw [mul_add, mul_one]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝² : Add α
inst✝¹ : MulOneClass α
inst✝ : RightDistribClass α
a b : α
⊢ (1 + a) * b = b + a * b
[PROOFSTEP]
rw [add_mul, one_mul]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝² : Add α
inst✝¹ : MulOneClass α
inst✝ : LeftDistribClass α
a b : α
⊢ a * (1 + b) = a + a * b
[PROOFSTEP]
rw [mul_add, mul_one]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonAssocSemiring α
n : α
⊢ 1 * n + 1 * n = n + n
[PROOFSTEP]
rw [one_mul]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonAssocSemiring α
n : α
⊢ n * 1 + n * 1 = n + n
[PROOFSTEP]
rw [mul_one]
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
R : Type x
α : Type u_1
inst✝¹ : Mul α
P : Prop
inst✝ : Decidable P
a b c : α
⊢ (a * if P then b else c) = if P then a * b else a * c
[PROOFSTEP]
split_ifs
[GOAL]
case pos
α✝ : Type u
β : Type v
γ : Type w
R : Type x
α : Type u_1
inst✝¹ : Mul α
P : Prop
inst✝ : Decidable P
a b c : α
h✝ : P
⊢ a * b = a * b
[PROOFSTEP]
rfl
[GOAL]
case neg
α✝ : Type u
β : Type v
γ : Type w
R : Type x
α : Type u_1
inst✝¹ : Mul α
P : Prop
inst✝ : Decidable P
a b c : α
h✝ : ¬P
⊢ a * c = a * c
[PROOFSTEP]
rfl
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
R : Type x
α : Type u_1
inst✝¹ : Mul α
P : Prop
inst✝ : Decidable P
a b c : α
⊢ (if P then a else b) * c = if P then a * c else b * c
[PROOFSTEP]
split_ifs
[GOAL]
case pos
α✝ : Type u
β : Type v
γ : Type w
R : Type x
α : Type u_1
inst✝¹ : Mul α
P : Prop
inst✝ : Decidable P
a b c : α
h✝ : P
⊢ a * c = a * c
[PROOFSTEP]
rfl
[GOAL]
case neg
α✝ : Type u
β : Type v
γ : Type w
R : Type x
α : Type u_1
inst✝¹ : Mul α
P : Prop
inst✝ : Decidable P
a b c : α
h✝ : ¬P
⊢ b * c = b * c
[PROOFSTEP]
rfl
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
R : Type x
α : Type u_1
inst✝¹ : MulZeroOneClass α
P : Prop
inst✝ : Decidable P
a : α
⊢ (a * if P then 1 else 0) = if P then a else 0
[PROOFSTEP]
simp
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
R : Type x
α : Type u_1
inst✝¹ : MulZeroOneClass α
P : Prop
inst✝ : Decidable P
a : α
⊢ (if P then 1 else 0) * a = if P then a else 0
[PROOFSTEP]
simp
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
R : Type x
α : Type u_1
inst✝¹ : MulZeroClass α
P : Prop
inst✝ : Decidable P
a b : α
⊢ (if P then a * b else 0) = (if P then a else 0) * b
[PROOFSTEP]
by_cases h : P
[GOAL]
case pos
α✝ : Type u
β : Type v
γ : Type w
R : Type x
α : Type u_1
inst✝¹ : MulZeroClass α
P : Prop
inst✝ : Decidable P
a b : α
h : P
⊢ (if P then a * b else 0) = (if P then a else 0) * b
[PROOFSTEP]
simp [h]
[GOAL]
case neg
α✝ : Type u
β : Type v
γ : Type w
R : Type x
α : Type u_1
inst✝¹ : MulZeroClass α
P : Prop
inst✝ : Decidable P
a b : α
h : ¬P
⊢ (if P then a * b else 0) = (if P then a else 0) * b
[PROOFSTEP]
simp [h]
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
R : Type x
α : Type u_1
inst✝¹ : MulZeroClass α
P : Prop
inst✝ : Decidable P
a b : α
⊢ (if P then a * b else 0) = a * if P then b else 0
[PROOFSTEP]
by_cases h : P
[GOAL]
case pos
α✝ : Type u
β : Type v
γ : Type w
R : Type x
α : Type u_1
inst✝¹ : MulZeroClass α
P : Prop
inst✝ : Decidable P
a b : α
h : P
⊢ (if P then a * b else 0) = a * if P then b else 0
[PROOFSTEP]
simp [h]
[GOAL]
case neg
α✝ : Type u
β : Type v
γ : Type w
R : Type x
α : Type u_1
inst✝¹ : MulZeroClass α
P : Prop
inst✝ : Decidable P
a b : α
h : ¬P
⊢ (if P then a * b else 0) = a * if P then b else 0
[PROOFSTEP]
simp [h]
[GOAL]
α✝ : Type u
β : Type v
γ : Type w
R : Type x
α : Type u_1
inst✝² : MulZeroClass α
P Q : Prop
inst✝¹ : Decidable P
inst✝ : Decidable Q
a b : α
⊢ (if P ∧ Q then a * b else 0) = (if P then a else 0) * if Q then b else 0
[PROOFSTEP]
simp only [← ite_and, ite_mul, mul_ite, mul_zero, zero_mul, and_comm]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : CommSemiring α
a✝ b✝ c a b : α
⊢ (a + b) * (a + b) = a * a + 2 * a * b + b * b
[PROOFSTEP]
simp only [two_mul, add_mul, mul_add, add_assoc, mul_comm b]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝¹ : Mul α
inst✝ : HasDistribNeg α
a b : α
⊢ -a * -b = a * b
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝¹ : Mul α
inst✝ : HasDistribNeg α
a b : α
⊢ -a * b = a * -b
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝¹ : MulOneClass α
inst✝ : HasDistribNeg α
a : α
⊢ -a = -1 * a
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝¹ : MulOneClass α
inst✝ : HasDistribNeg α
a : α
⊢ a * -1 = -a
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝¹ : MulOneClass α
inst✝ : HasDistribNeg α
a : α
⊢ -1 * a = -a
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝¹ : MulZeroClass α
inst✝ : HasDistribNeg α
src✝¹ : Zero α := inferInstanceAs (Zero α)
src✝ : InvolutiveNeg α := inferInstanceAs (InvolutiveNeg α)
⊢ -0 = 0
[PROOFSTEP]
rw [← zero_mul (0 : α), ← neg_mul, mul_zero, mul_zero]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonUnitalNonAssocRing α
a b : α
⊢ -a * b + a * b = 0
[PROOFSTEP]
rw [← right_distrib, add_left_neg, zero_mul]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonUnitalNonAssocRing α
a b : α
⊢ a * -b + a * b = 0
[PROOFSTEP]
rw [← left_distrib, add_left_neg, mul_zero]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonUnitalNonAssocRing α
a b c : α
⊢ a * (b - c) = a * b - a * c
[PROOFSTEP]
simpa only [sub_eq_add_neg, neg_mul_eq_mul_neg] using mul_add a b (-c)
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonUnitalNonAssocRing α
a b c : α
⊢ (a - b) * c = a * c - b * c
[PROOFSTEP]
simpa only [sub_eq_add_neg, neg_mul_eq_neg_mul] using add_mul a (-b) c
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonUnitalNonAssocRing α
a b c d e : α
⊢ a * e + c = b * e + d ↔ a * e + c = d + b * e
[PROOFSTEP]
simp [add_comm]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonUnitalNonAssocRing α
a b c d e : α
h : a * e + c = d + b * e
⊢ a * e + c - b * e = d
[PROOFSTEP]
rw [h]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonUnitalNonAssocRing α
a b c d e : α
h : a * e + c = d + b * e
⊢ d + b * e - b * e = d
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonUnitalNonAssocRing α
a b c d e : α
h : a * e + c - b * e = d
⊢ a * e + c = d + b * e
[PROOFSTEP]
rw [← h]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonUnitalNonAssocRing α
a b c d e : α
h : a * e + c - b * e = d
⊢ a * e + c = a * e + c - b * e + b * e
[PROOFSTEP]
simp
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonUnitalNonAssocRing α
a b c d e : α
⊢ a * e + c - b * e = d ↔ (a - b) * e + c = d
[PROOFSTEP]
simp [sub_mul, sub_add_eq_add_sub]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonUnitalNonAssocRing α
a b c d e : α
h : a * e + c = b * e + d
⊢ (a - b) * e + c = a * e + c - b * e
[PROOFSTEP]
simp [sub_mul, sub_add_eq_add_sub]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonUnitalNonAssocRing α
a b c d e : α
h : a * e + c = b * e + d
⊢ a * e + c - b * e = d
[PROOFSTEP]
rw [h]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonUnitalNonAssocRing α
a b c d e : α
h : a * e + c = b * e + d
⊢ b * e + d - b * e = d
[PROOFSTEP]
simp [@add_sub_cancel α]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonAssocRing α
a b : α
⊢ (a - 1) * b = a * b - b
[PROOFSTEP]
rw [sub_mul, one_mul]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonAssocRing α
a b : α
⊢ a * (b - 1) = a * b - a
[PROOFSTEP]
rw [mul_sub, mul_one]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonAssocRing α
a b : α
⊢ (1 - a) * b = b - a * b
[PROOFSTEP]
rw [sub_mul, one_mul]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : NonAssocRing α
a b : α
⊢ a * (1 - b) = a - a * b
[PROOFSTEP]
rw [mul_sub, mul_one]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : Ring α
a✝ b c d e : α
src✝ : Ring α := inst✝
a : α
⊢ 0 * a + 0 * a = 0 * a + 0
[PROOFSTEP]
rw [← add_mul, zero_add, add_zero]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : Ring α
a✝ b c d e : α
src✝ : Ring α := inst✝
a : α
⊢ a * 0 + a * 0 = a * 0 + 0
[PROOFSTEP]
rw [← mul_add, add_zero, add_zero]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : Ring α
a✝ b c d e : α
src✝ : Ring α := inst✝
a : α
⊢ 0 * a + 0 * a = 0 * a + 0
[PROOFSTEP]
rw [← add_mul, zero_add, add_zero]
[GOAL]
α : Type u
β : Type v
γ : Type w
R : Type x
inst✝ : Ring α
a✝ b c d e : α
src✝ : Ring α := inst✝
a : α
⊢ a * 0 + a * 0 = a * 0 + 0
[PROOFSTEP]
rw [← mul_add, add_zero, add_zero]


[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
P : ℕ → Prop
x : 𝕎 R
n : ℕ
⊢ coeff (select P x) n = ↑(aeval x.coeff) (selectPoly P n)
[PROOFSTEP]
dsimp [select, selectPoly]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
P : ℕ → Prop
x : 𝕎 R
n : ℕ
⊢ coeff (mk p fun n => if P n then coeff x n else 0) n = ↑(aeval x.coeff) (if P n then X n else 0)
[PROOFSTEP]
split_ifs with hi
[GOAL]
case pos
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
P : ℕ → Prop
x : 𝕎 R
n : ℕ
hi : P n
⊢ coeff (mk p fun n => if P n then coeff x n else 0) n = ↑(aeval x.coeff) (X n)
[PROOFSTEP]
rw [aeval_X, mk]
[GOAL]
case pos
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
P : ℕ → Prop
x : 𝕎 R
n : ℕ
hi : P n
⊢ coeff { coeff := fun n => if P n then coeff x n else 0 } n = coeff x n
[PROOFSTEP]
simp only [hi]
[GOAL]
case pos
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
P : ℕ → Prop
x : 𝕎 R
n : ℕ
hi : P n
⊢ (if True then coeff x n else 0) = coeff x n
[PROOFSTEP]
rfl
[GOAL]
case neg
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
P : ℕ → Prop
x : 𝕎 R
n : ℕ
hi : ¬P n
⊢ coeff (mk p fun n => if P n then coeff x n else 0) n = ↑(aeval x.coeff) 0
[PROOFSTEP]
rw [AlgHom.map_zero, mk]
[GOAL]
case neg
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
P : ℕ → Prop
x : 𝕎 R
n : ℕ
hi : ¬P n
⊢ coeff { coeff := fun n => if P n then coeff x n else 0 } n = 0
[PROOFSTEP]
simp only [hi]
[GOAL]
case neg
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
P : ℕ → Prop
x : 𝕎 R
n : ℕ
hi : ¬P n
⊢ (if False then coeff x n else 0) = 0
[PROOFSTEP]
rfl
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ P : ℕ → Prop
⊢ IsPoly p fun x x_1 x_2 => select P x_2
[PROOFSTEP]
use selectPoly P
[GOAL]
case h
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ P : ℕ → Prop
⊢ ∀ ⦃R : Type ?u.31994⦄ [inst : CommRing R] (x : 𝕎 R), (select P x).coeff = fun n => ↑(aeval x.coeff) (selectPoly P n)
[PROOFSTEP]
rintro R _Rcr x
[GOAL]
case h
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R✝ : Type u_1
inst✝ : CommRing R✝
P✝ P : ℕ → Prop
R : Type ?u.31994
_Rcr : CommRing R
x : 𝕎 R
⊢ (select P x).coeff = fun n => ↑(aeval x.coeff) (selectPoly P n)
[PROOFSTEP]
funext i
[GOAL]
case h.h
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R✝ : Type u_1
inst✝ : CommRing R✝
P✝ P : ℕ → Prop
R : Type ?u.31994
_Rcr : CommRing R
x : 𝕎 R
i : ℕ
⊢ coeff (select P x) i = ↑(aeval x.coeff) (selectPoly P i)
[PROOFSTEP]
apply coeff_select
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
P : ℕ → Prop
⊢ ∀ (x : 𝕎 R), select P x + select (fun i => ¬P i) x = x
[PROOFSTEP]
have : IsPoly p fun {R} [CommRing R] x ↦ select P x + select (fun i ↦ ¬P i) x := IsPoly₂.diag (hf := IsPoly₂.comp)
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
P : ℕ → Prop
this : IsPoly p fun {R} [CommRing R] x => select P x + select (fun i => ¬P i) x
⊢ ∀ (x : 𝕎 R), select P x + select (fun i => ¬P i) x = x
[PROOFSTEP]
ghost_calc x
[GOAL]
case refine_3
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
P : ℕ → Prop
this : IsPoly p fun {R} [CommRing R] x => select P x + select (fun i => ¬P i) x
R : Type u_1
R._inst : CommRing R
x : 𝕎 R
⊢ ∀ (n : ℕ), ↑(ghostComponent n) (select P x + select (fun i => ¬P i) x) = ↑(ghostComponent n) x
[PROOFSTEP]
intro n
[GOAL]
case refine_3
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
P : ℕ → Prop
this : IsPoly p fun {R} [CommRing R] x => select P x + select (fun i => ¬P i) x
R : Type u_1
R._inst : CommRing R
x : 𝕎 R
n : ℕ
⊢ ↑(ghostComponent n) (select P x + select (fun i => ¬P i) x) = ↑(ghostComponent n) x
[PROOFSTEP]
simp only [RingHom.map_add]
[GOAL]
case refine_3
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
P : ℕ → Prop
this : IsPoly p fun {R} [CommRing R] x => select P x + select (fun i => ¬P i) x
R : Type u_1
R._inst : CommRing R
x : 𝕎 R
n : ℕ
⊢ ↑(ghostComponent n) (select P x) + ↑(ghostComponent n) (select (fun i => ¬P i) x) = ↑(ghostComponent n) x
[PROOFSTEP]
suffices
  (bind₁ (selectPoly P)) (wittPolynomial p ℤ n) + (bind₁ (selectPoly fun i => ¬P i)) (wittPolynomial p ℤ n) =
    wittPolynomial p ℤ n
  by
  apply_fun aeval x.coeff at this
  simpa only [AlgHom.map_add, aeval_bind₁, ← coeff_select]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
P : ℕ → Prop
this✝ : IsPoly p fun {R} [CommRing R] x => select P x + select (fun i => ¬P i) x
R : Type u_1
R._inst : CommRing R
x : 𝕎 R
n : ℕ
this :
  ↑(bind₁ (selectPoly P)) (wittPolynomial p ℤ n) + ↑(bind₁ (selectPoly fun i => ¬P i)) (wittPolynomial p ℤ n) =
    wittPolynomial p ℤ n
⊢ ↑(ghostComponent n) (select P x) + ↑(ghostComponent n) (select (fun i => ¬P i) x) = ↑(ghostComponent n) x
[PROOFSTEP]
apply_fun aeval x.coeff at this
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
P : ℕ → Prop
this✝ : IsPoly p fun {R} [CommRing R] x => select P x + select (fun i => ¬P i) x
R : Type u_1
R._inst : CommRing R
x : 𝕎 R
n : ℕ
this :
  ↑(aeval x.coeff)
      (↑(bind₁ (selectPoly P)) (wittPolynomial p ℤ n) + ↑(bind₁ (selectPoly fun i => ¬P i)) (wittPolynomial p ℤ n)) =
    ↑(aeval x.coeff) (wittPolynomial p ℤ n)
⊢ ↑(ghostComponent n) (select P x) + ↑(ghostComponent n) (select (fun i => ¬P i) x) = ↑(ghostComponent n) x
[PROOFSTEP]
simpa only [AlgHom.map_add, aeval_bind₁, ← coeff_select]
[GOAL]
case refine_3
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
P : ℕ → Prop
this : IsPoly p fun {R} [CommRing R] x => select P x + select (fun i => ¬P i) x
R : Type u_1
R._inst : CommRing R
x : 𝕎 R
n : ℕ
⊢ ↑(bind₁ (selectPoly P)) (wittPolynomial p ℤ n) + ↑(bind₁ (selectPoly fun i => ¬P i)) (wittPolynomial p ℤ n) =
    wittPolynomial p ℤ n
[PROOFSTEP]
simp only [wittPolynomial_eq_sum_C_mul_X_pow, selectPoly, AlgHom.map_sum, AlgHom.map_pow, AlgHom.map_mul, bind₁_X_right,
  bind₁_C_right, ← Finset.sum_add_distrib, ← mul_add]
[GOAL]
case refine_3
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
P : ℕ → Prop
this : IsPoly p fun {R} [CommRing R] x => select P x + select (fun i => ¬P i) x
R : Type u_1
R._inst : CommRing R
x : 𝕎 R
n : ℕ
⊢ (Finset.sum (Finset.range (n + 1)) fun x =>
      ↑C (↑p ^ x) * ((if P x then X x else 0) ^ p ^ (n - x) + (if ¬P x then X x else 0) ^ p ^ (n - x))) =
    Finset.sum (Finset.range (n + 1)) fun x => ↑C (↑p ^ x) * X x ^ p ^ (n - x)
[PROOFSTEP]
apply Finset.sum_congr rfl
[GOAL]
case refine_3
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
P : ℕ → Prop
this : IsPoly p fun {R} [CommRing R] x => select P x + select (fun i => ¬P i) x
R : Type u_1
R._inst : CommRing R
x : 𝕎 R
n : ℕ
⊢ ∀ (x : ℕ),
    x ∈ Finset.range (n + 1) →
      ↑C (↑p ^ x) * ((if P x then X x else 0) ^ p ^ (n - x) + (if ¬P x then X x else 0) ^ p ^ (n - x)) =
        ↑C (↑p ^ x) * X x ^ p ^ (n - x)
[PROOFSTEP]
refine' fun m _ => mul_eq_mul_left_iff.mpr (Or.inl _)
[GOAL]
case refine_3
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
P : ℕ → Prop
this : IsPoly p fun {R} [CommRing R] x => select P x + select (fun i => ¬P i) x
R : Type u_1
R._inst : CommRing R
x : 𝕎 R
n m : ℕ
x✝ : m ∈ Finset.range (n + 1)
⊢ (if P m then X m else 0) ^ p ^ (n - m) + (if ¬P m then X m else 0) ^ p ^ (n - m) = X m ^ p ^ (n - m)
[PROOFSTEP]
rw [ite_pow, zero_pow (pow_pos hp.out.pos _)]
[GOAL]
case refine_3
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
P : ℕ → Prop
this : IsPoly p fun {R} [CommRing R] x => select P x + select (fun i => ¬P i) x
R : Type u_1
R._inst : CommRing R
x : 𝕎 R
n m : ℕ
x✝ : m ∈ Finset.range (n + 1)
⊢ (if P m then X m ^ p ^ (n - m) else 0) + (if ¬P m then X m else 0) ^ p ^ (n - m) = X m ^ p ^ (n - m)
[PROOFSTEP]
by_cases Pm : P m
[GOAL]
case pos
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
P : ℕ → Prop
this : IsPoly p fun {R} [CommRing R] x => select P x + select (fun i => ¬P i) x
R : Type u_1
R._inst : CommRing R
x : 𝕎 R
n m : ℕ
x✝ : m ∈ Finset.range (n + 1)
Pm : P m
⊢ (if P m then X m ^ p ^ (n - m) else 0) + (if ¬P m then X m else 0) ^ p ^ (n - m) = X m ^ p ^ (n - m)
[PROOFSTEP]
rw [if_pos Pm, if_neg _, zero_pow, add_zero]
[GOAL]
case pos
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
P : ℕ → Prop
this : IsPoly p fun {R} [CommRing R] x => select P x + select (fun i => ¬P i) x
R : Type u_1
R._inst : CommRing R
x : 𝕎 R
n m : ℕ
x✝ : m ∈ Finset.range (n + 1)
Pm : P m
⊢ 0 < p ^ (n - m)
[PROOFSTEP]
exact Fin.size_positive'
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
P : ℕ → Prop
this : IsPoly p fun {R} [CommRing R] x => select P x + select (fun i => ¬P i) x
R : Type u_1
R._inst : CommRing R
x : 𝕎 R
n m : ℕ
x✝ : m ∈ Finset.range (n + 1)
Pm : P m
⊢ ¬¬P m
[PROOFSTEP]
exact not_not_intro Pm
[GOAL]
case neg
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
P : ℕ → Prop
this : IsPoly p fun {R} [CommRing R] x => select P x + select (fun i => ¬P i) x
R : Type u_1
R._inst : CommRing R
x : 𝕎 R
n m : ℕ
x✝ : m ∈ Finset.range (n + 1)
Pm : ¬P m
⊢ (if P m then X m ^ p ^ (n - m) else 0) + (if ¬P m then X m else 0) ^ p ^ (n - m) = X m ^ p ^ (n - m)
[PROOFSTEP]
rwa [if_neg Pm, if_pos, zero_add]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
P : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
⊢ coeff (x + y) n = coeff x n + coeff y n
[PROOFSTEP]
let P : ℕ → Prop := fun n => y.coeff n = 0
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
⊢ coeff (x + y) n = coeff x n + coeff y n
[PROOFSTEP]
haveI : DecidablePred P := Classical.decPred P
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
⊢ coeff (x + y) n = coeff x n + coeff y n
[PROOFSTEP]
set z := mk p fun n => if P n then x.coeff n else y.coeff n
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
z : 𝕎 R := mk p fun n => if P n then coeff x n else coeff y n
⊢ coeff (x + y) n = coeff x n + coeff y n
[PROOFSTEP]
have hx : select P z = x := by
  ext1 n; rw [select, coeff_mk, coeff_mk]
  split_ifs with hn
  · rfl
  · rw [(h n).resolve_right hn]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
z : 𝕎 R := mk p fun n => if P n then coeff x n else coeff y n
⊢ select P z = x
[PROOFSTEP]
ext1 n
[GOAL]
case h
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
z : 𝕎 R := mk p fun n => if P n then coeff x n else coeff y n
n : ℕ
⊢ coeff (select P z) n = coeff x n
[PROOFSTEP]
rw [select, coeff_mk, coeff_mk]
[GOAL]
case h
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
z : 𝕎 R := mk p fun n => if P n then coeff x n else coeff y n
n : ℕ
⊢ (if P n then if P n then coeff x n else coeff y n else 0) = coeff x n
[PROOFSTEP]
split_ifs with hn
[GOAL]
case pos
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
z : 𝕎 R := mk p fun n => if P n then coeff x n else coeff y n
n : ℕ
hn : P n
⊢ coeff x n = coeff x n
[PROOFSTEP]
rfl
[GOAL]
case neg
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
z : 𝕎 R := mk p fun n => if P n then coeff x n else coeff y n
n : ℕ
hn : ¬P n
⊢ 0 = coeff x n
[PROOFSTEP]
rw [(h n).resolve_right hn]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
z : 𝕎 R := mk p fun n => if P n then coeff x n else coeff y n
hx : select P z = x
⊢ coeff (x + y) n = coeff x n + coeff y n
[PROOFSTEP]
have hy : select (fun i => ¬P i) z = y := by
  ext1 n; rw [select, coeff_mk, coeff_mk]
  split_ifs with hn
  · exact hn.symm
  · rfl
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
z : 𝕎 R := mk p fun n => if P n then coeff x n else coeff y n
hx : select P z = x
⊢ select (fun i => ¬P i) z = y
[PROOFSTEP]
ext1 n
[GOAL]
case h
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
z : 𝕎 R := mk p fun n => if P n then coeff x n else coeff y n
hx : select P z = x
n : ℕ
⊢ coeff (select (fun i => ¬P i) z) n = coeff y n
[PROOFSTEP]
rw [select, coeff_mk, coeff_mk]
[GOAL]
case h
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
z : 𝕎 R := mk p fun n => if P n then coeff x n else coeff y n
hx : select P z = x
n : ℕ
⊢ (if ¬P n then if P n then coeff x n else coeff y n else 0) = coeff y n
[PROOFSTEP]
split_ifs with hn
[GOAL]
case pos
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
z : 𝕎 R := mk p fun n => if P n then coeff x n else coeff y n
hx : select P z = x
n : ℕ
hn : P n
⊢ 0 = coeff y n
[PROOFSTEP]
exact hn.symm
[GOAL]
case neg
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
z : 𝕎 R := mk p fun n => if P n then coeff x n else coeff y n
hx : select P z = x
n : ℕ
hn : ¬P n
⊢ coeff y n = coeff y n
[PROOFSTEP]
rfl
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
z : 𝕎 R := mk p fun n => if P n then coeff x n else coeff y n
hx : select P z = x
hy : select (fun i => ¬P i) z = y
⊢ coeff (x + y) n = coeff x n + coeff y n
[PROOFSTEP]
calc
  (x + y).coeff n = z.coeff n := by rw [← hx, ← hy, select_add_select_not P z]
  _ = x.coeff n + y.coeff n := by
    simp [mk]
    split_ifs with y0
    · rw [y0, add_zero]
    · rw [h n |>.resolve_right y0, zero_add]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
z : 𝕎 R := mk p fun n => if P n then coeff x n else coeff y n
hx : select P z = x
hy : select (fun i => ¬P i) z = y
⊢ coeff (x + y) n = coeff z n
[PROOFSTEP]
rw [← hx, ← hy, select_add_select_not P z]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
z : 𝕎 R := mk p fun n => if P n then coeff x n else coeff y n
hx : select P z = x
hy : select (fun i => ¬P i) z = y
⊢ coeff z n = coeff x n + coeff y n
[PROOFSTEP]
simp [mk]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
z : 𝕎 R := mk p fun n => if P n then coeff x n else coeff y n
hx : select P z = x
hy : select (fun i => ¬P i) z = y
⊢ (if coeff y n = 0 then coeff x n else coeff y n) = coeff x n + coeff y n
[PROOFSTEP]
split_ifs with y0
[GOAL]
case pos
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
z : 𝕎 R := mk p fun n => if P n then coeff x n else coeff y n
hx : select P z = x
hy : select (fun i => ¬P i) z = y
y0 : coeff y n = 0
⊢ coeff x n = coeff x n + coeff y n
[PROOFSTEP]
rw [y0, add_zero]
[GOAL]
case neg
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
R : Type u_1
inst✝ : CommRing R
P✝ : ℕ → Prop
x y : 𝕎 R
h : ∀ (n : ℕ), coeff x n = 0 ∨ coeff y n = 0
P : ℕ → Prop := fun n => coeff y n = 0
this : DecidablePred P
z : 𝕎 R := mk p fun n => if P n then coeff x n else coeff y n
hx : select P z = x
hy : select (fun i => ¬P i) z = y
y0 : ¬coeff y n = 0
⊢ coeff y n = coeff x n + coeff y n
[PROOFSTEP]
rw [h n |>.resolve_right y0, zero_add]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
n : ℕ
⊢ init n x + tail n x = x
[PROOFSTEP]
simp only [init, tail, ← not_lt, select_add_select_not]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
n : ℕ
⊢ init n (init n x) = init n x
[PROOFSTEP]
rw [ext_iff]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
n : ℕ
⊢ ∀ (n_1 : ℕ), coeff (init n (init n x)) n_1 = coeff (init n x) n_1
[PROOFSTEP]
intro i
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
n i : ℕ
⊢ coeff (init n (init n x)) i = coeff (init n x) i
[PROOFSTEP]
simp only [WittVector.init, WittVector.select, WittVector.coeff_mk]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
n i : ℕ
⊢ (if i < n then if i < n then coeff x i else 0 else 0) = if i < n then coeff x i else 0
[PROOFSTEP]
by_cases hi : i < n
[GOAL]
case pos
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
n i : ℕ
hi : i < n
⊢ (if i < n then if i < n then coeff x i else 0 else 0) = if i < n then coeff x i else 0
[PROOFSTEP]
simp [hi]
[GOAL]
case neg
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
n i : ℕ
hi : ¬i < n
⊢ (if i < n then if i < n then coeff x i else 0 else 0) = if i < n then coeff x i else 0
[PROOFSTEP]
simp [hi]
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
x y : 𝕎 R
n : ℕ
⊢ init n (x + y) = init n (init n x + init n y)
[PROOFSTEP]
init_ring using wittAdd_vars
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
x y : 𝕎 R
n : ℕ
⊢ init n (x * y) = init n (init n x * init n y)
[PROOFSTEP]
init_ring using wittMul_vars
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
x : 𝕎 R
n : ℕ
⊢ init n (-x) = init n (-init n x)
[PROOFSTEP]
init_ring using wittNeg_vars
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
x y : 𝕎 R
n : ℕ
⊢ init n (x - y) = init n (init n x - init n y)
[PROOFSTEP]
init_ring using wittSub_vars
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
m : ℕ
x : 𝕎 R
n : ℕ
⊢ init n (m • x) = init n (m • init n x)
[PROOFSTEP]
init_ring using fun p [Fact (Nat.Prime p)] n => wittNSMul_vars p m n
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
m : ℤ
x : 𝕎 R
n : ℕ
⊢ init n (m • x) = init n (m • init n x)
[PROOFSTEP]
init_ring using fun p [Fact (Nat.Prime p)] n => wittZSMul_vars p m n
[GOAL]
p : ℕ
hp : Fact (Nat.Prime p)
n✝ : ℕ
R : Type u_1
inst✝ : CommRing R
m : ℕ
x : 𝕎 R
n : ℕ
⊢ init n (x ^ m) = init n (init n x ^ m)
[PROOFSTEP]
init_ring using fun p [Fact (Nat.Prime p)] n => wittPow_vars p m n