l3lab/ntp-mathlib huggingface dataset:
/-- `ContinuousMultilinearMap.pi` as an `Equiv`. -/
@[simps]
def piEquiv {ι' : Type*} {M' : ι' → Type*} [∀ i, AddCommMonoid (M' i)]
    [∀ i, TopologicalSpace (M' i)] [∀ i, Module R (M' i)] :
    (∀ i, ContinuousMultilinearMap R M₁ (M' i)) ≃ ContinuousMultilinearMap R M₁ (∀ i, M' i) where
  toFun := ContinuousMultilinearMap.pi
  invFun f i := (ContinuousLinearMap.proj i : _ →L[R] M' i).compContinuousMultilinearMap f
  left_inv f := by
    ext
    

Proof state:
case h.H
R : Type u
ι : Type v
n : ℕ
M : Fin (Nat.succ n) → Type w
M₁ : ι → Type w₁
M₁' : ι → Type w₁'
M₂ : Type w₂
M₃ : Type w₃
M₄ : Type w₄
inst✝²¹ : Semiring R
inst✝²⁰ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝¹⁹ : (i : ι) → AddCommMonoid (M₁ i)
inst✝¹⁸ : (i : ι) → AddCommMonoid (M₁' i)
inst✝¹⁷ : AddCommMonoid M₂
inst✝¹⁶ : AddCommMonoid M₃
inst✝¹⁵ : AddCommMonoid M₄
inst✝¹⁴ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝¹³ : (i : ι) → Module R (M₁ i)
inst✝¹² : (i : ι) → Module R (M₁' i)
inst✝¹¹ : Module R M₂
inst✝¹⁰ : Module R M₃
inst✝⁹ : Module R M₄
inst✝⁸ : (i : Fin (Nat.succ n)) → TopologicalSpace (M i)
inst✝⁷ : (i : ι) → TopologicalSpace (M₁ i)
inst✝⁶ : (i : ι) → TopologicalSpace (M₁' i)
inst✝⁵ : TopologicalSpace M₂
inst✝⁴ : TopologicalSpace M₃
inst✝³ : TopologicalSpace M₄
f✝ f' : ContinuousMultilinearMap R M₁ M₂
ι' : Type u_1
M' : ι' → Type u_2
inst✝² : (i : ι') → AddCommMonoid (M' i)
inst✝¹ : (i : ι') → TopologicalSpace (M' i)
inst✝ : (i : ι') → Module R (M' i)
f : (i : ι') → ContinuousMultilinearMap R M₁ (M' i)
x✝¹ : ι'
x✝ : (i : ι) → M₁ i
⊢ ((fun f i => ContinuousLinearMap.compContinuousMultilinearMap (ContinuousLinearMap.proj i) f) (pi f) x✝¹) x✝ =
    (f x✝¹) x✝

Next tactic:
rfl
/-- `ContinuousMultilinearMap.pi` as an `Equiv`. -/
@[simps]
def piEquiv {ι' : Type*} {M' : ι' → Type*} [∀ i, AddCommMonoid (M' i)]
    [∀ i, TopologicalSpace (M' i)] [∀ i, Module R (M' i)] :
    (∀ i, ContinuousMultilinearMap R M₁ (M' i)) ≃ ContinuousMultilinearMap R M₁ (∀ i, M' i) where
  toFun := ContinuousMultilinearMap.pi
  invFun f i := (ContinuousLinearMap.proj i : _ →L[R] M' i).compContinuousMultilinearMap f
  left_inv f := by
    ext
    rfl
  right_inv f := by
    

Proof state:
R : Type u
ι : Type v
n : ℕ
M : Fin (Nat.succ n) → Type w
M₁ : ι → Type w₁
M₁' : ι → Type w₁'
M₂ : Type w₂
M₃ : Type w₃
M₄ : Type w₄
inst✝²¹ : Semiring R
inst✝²⁰ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝¹⁹ : (i : ι) → AddCommMonoid (M₁ i)
inst✝¹⁸ : (i : ι) → AddCommMonoid (M₁' i)
inst✝¹⁷ : AddCommMonoid M₂
inst✝¹⁶ : AddCommMonoid M₃
inst✝¹⁵ : AddCommMonoid M₄
inst✝¹⁴ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝¹³ : (i : ι) → Module R (M₁ i)
inst✝¹² : (i : ι) → Module R (M₁' i)
inst✝¹¹ : Module R M₂
inst✝¹⁰ : Module R M₃
inst✝⁹ : Module R M₄
inst✝⁸ : (i : Fin (Nat.succ n)) → TopologicalSpace (M i)
inst✝⁷ : (i : ι) → TopologicalSpace (M₁ i)
inst✝⁶ : (i : ι) → TopologicalSpace (M₁' i)
inst✝⁵ : TopologicalSpace M₂
inst✝⁴ : TopologicalSpace M₃
inst✝³ : TopologicalSpace M₄
f✝ f' : ContinuousMultilinearMap R M₁ M₂
ι' : Type u_1
M' : ι' → Type u_2
inst✝² : (i : ι') → AddCommMonoid (M' i)
inst✝¹ : (i : ι') → TopologicalSpace (M' i)
inst✝ : (i : ι') → Module R (M' i)
f : ContinuousMultilinearMap R M₁ ((i : ι') → M' i)
⊢ pi ((fun f i => ContinuousLinearMap.compContinuousMultilinearMap (ContinuousLinearMap.proj i) f) f) = f

Next tactic:
ext
/-- `ContinuousMultilinearMap.pi` as an `Equiv`. -/
@[simps]
def piEquiv {ι' : Type*} {M' : ι' → Type*} [∀ i, AddCommMonoid (M' i)]
    [∀ i, TopologicalSpace (M' i)] [∀ i, Module R (M' i)] :
    (∀ i, ContinuousMultilinearMap R M₁ (M' i)) ≃ ContinuousMultilinearMap R M₁ (∀ i, M' i) where
  toFun := ContinuousMultilinearMap.pi
  invFun f i := (ContinuousLinearMap.proj i : _ →L[R] M' i).compContinuousMultilinearMap f
  left_inv f := by
    ext
    rfl
  right_inv f := by
    ext
    

Proof state:
case H.h
R : Type u
ι : Type v
n : ℕ
M : Fin (Nat.succ n) → Type w
M₁ : ι → Type w₁
M₁' : ι → Type w₁'
M₂ : Type w₂
M₃ : Type w₃
M₄ : Type w₄
inst✝²¹ : Semiring R
inst✝²⁰ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝¹⁹ : (i : ι) → AddCommMonoid (M₁ i)
inst✝¹⁸ : (i : ι) → AddCommMonoid (M₁' i)
inst✝¹⁷ : AddCommMonoid M₂
inst✝¹⁶ : AddCommMonoid M₃
inst✝¹⁵ : AddCommMonoid M₄
inst✝¹⁴ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝¹³ : (i : ι) → Module R (M₁ i)
inst✝¹² : (i : ι) → Module R (M₁' i)
inst✝¹¹ : Module R M₂
inst✝¹⁰ : Module R M₃
inst✝⁹ : Module R M₄
inst✝⁸ : (i : Fin (Nat.succ n)) → TopologicalSpace (M i)
inst✝⁷ : (i : ι) → TopologicalSpace (M₁ i)
inst✝⁶ : (i : ι) → TopologicalSpace (M₁' i)
inst✝⁵ : TopologicalSpace M₂
inst✝⁴ : TopologicalSpace M₃
inst✝³ : TopologicalSpace M₄
f✝ f' : ContinuousMultilinearMap R M₁ M₂
ι' : Type u_1
M' : ι' → Type u_2
inst✝² : (i : ι') → AddCommMonoid (M' i)
inst✝¹ : (i : ι') → TopologicalSpace (M' i)
inst✝ : (i : ι') → Module R (M' i)
f : ContinuousMultilinearMap R M₁ ((i : ι') → M' i)
x✝¹ : (i : ι) → M₁ i
x✝ : ι'
⊢ (pi ((fun f i => ContinuousLinearMap.compContinuousMultilinearMap (ContinuousLinearMap.proj i) f) f)) x✝¹ x✝ =
    f x✝¹ x✝

Next tactic:
rfl
/-- An equivalence of the index set defines an equivalence between the spaces of continuous
multilinear maps. In case of normed spaces, this is a linear isometric equivalence, see
`ContinuousMultilinearMap.domDomCongrₗᵢ`. -/
@[simps]
def domDomCongrEquiv {ι' : Type*} (e : ι ≃ ι') :
    ContinuousMultilinearMap R (fun _ : ι => M₂) M₃ ≃
      ContinuousMultilinearMap R (fun _ : ι' => M₂) M₃ where
  toFun := domDomCongr e
  invFun := domDomCongr e.symm
  left_inv _ := ext fun _ => by 

Proof state:
R : Type u
ι : Type v
n : ℕ
M : Fin (Nat.succ n) → Type w
M₁ : ι → Type w₁
M₁' : ι → Type w₁'
M₂ : Type w₂
M₃ : Type w₃
M₄ : Type w₄
inst✝¹⁸ : Semiring R
inst✝¹⁷ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝¹⁶ : (i : ι) → AddCommMonoid (M₁ i)
inst✝¹⁵ : (i : ι) → AddCommMonoid (M₁' i)
inst✝¹⁴ : AddCommMonoid M₂
inst✝¹³ : AddCommMonoid M₃
inst✝¹² : AddCommMonoid M₄
inst✝¹¹ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝¹⁰ : (i : ι) → Module R (M₁ i)
inst✝⁹ : (i : ι) → Module R (M₁' i)
inst✝⁸ : Module R M₂
inst✝⁷ : Module R M₃
inst✝⁶ : Module R M₄
inst✝⁵ : (i : Fin (Nat.succ n)) → TopologicalSpace (M i)
inst✝⁴ : (i : ι) → TopologicalSpace (M₁ i)
inst✝³ : (i : ι) → TopologicalSpace (M₁' i)
inst✝² : TopologicalSpace M₂
inst✝¹ : TopologicalSpace M₃
inst✝ : TopologicalSpace M₄
f f' : ContinuousMultilinearMap R M₁ M₂
ι' : Type u_1
e : ι ≃ ι'
x✝¹ : ContinuousMultilinearMap R (fun x => M₂) M₃
x✝ : ι → M₂
⊢ (domDomCongr e.symm (domDomCongr e x✝¹)) x✝ = x✝¹ x✝

Next tactic:
simp
/-- An equivalence of the index set defines an equivalence between the spaces of continuous
multilinear maps. In case of normed spaces, this is a linear isometric equivalence, see
`ContinuousMultilinearMap.domDomCongrₗᵢ`. -/
@[simps]
def domDomCongrEquiv {ι' : Type*} (e : ι ≃ ι') :
    ContinuousMultilinearMap R (fun _ : ι => M₂) M₃ ≃
      ContinuousMultilinearMap R (fun _ : ι' => M₂) M₃ where
  toFun := domDomCongr e
  invFun := domDomCongr e.symm
  left_inv _ := ext fun _ => by simp
  right_inv _ := ext fun _ => by 

Proof state:
R : Type u
ι : Type v
n : ℕ
M : Fin (Nat.succ n) → Type w
M₁ : ι → Type w₁
M₁' : ι → Type w₁'
M₂ : Type w₂
M₃ : Type w₃
M₄ : Type w₄
inst✝¹⁸ : Semiring R
inst✝¹⁷ : (i : Fin (Nat.succ n)) → AddCommMonoid (M i)
inst✝¹⁶ : (i : ι) → AddCommMonoid (M₁ i)
inst✝¹⁵ : (i : ι) → AddCommMonoid (M₁' i)
inst✝¹⁴ : AddCommMonoid M₂
inst✝¹³ : AddCommMonoid M₃
inst✝¹² : AddCommMonoid M₄
inst✝¹¹ : (i : Fin (Nat.succ n)) → Module R (M i)
inst✝¹⁰ : (i : ι) → Module R (M₁ i)
inst✝⁹ : (i : ι) → Module R (M₁' i)
inst✝⁸ : Module R M₂
inst✝⁷ : Module R M₃
inst✝⁶ : Module R M₄
inst✝⁵ : (i : Fin (Nat.succ n)) → TopologicalSpace (M i)
inst✝⁴ : (i : ι) → TopologicalSpace (M₁ i)
inst✝³ : (i : ι) → TopologicalSpace (M₁' i)
inst✝² : TopologicalSpace M₂
inst✝¹ : TopologicalSpace M₃
inst✝ : TopologicalSpace M₄
f f' : ContinuousMultilinearMap R M₁ M₂
ι' : Type u_1
e : ι ≃ ι'
x✝¹ : ContinuousMultilinearMap R (fun x => M₂) M₃
x✝ : ι' → M₂
⊢ (domDomCongr e (domDomCongr e.symm x✝¹)) x✝ = x✝¹ x✝

Next tactic:
simp
/-- The continuous multilinear map on `A^n`, where `A` is a normed algebra over `𝕜`, associating to
`m` the product of all the `m i`.

See also: `ContinuousMultilinearMap.mkPiAlgebra`. -/
protected def mkPiAlgebraFin : A[×n]→L[R] A where
  cont := by
    

Proof state:
R : Type u
ι : Type v
n : ℕ
M : Fin (Nat.succ n) → Type w
M₁ : ι → Type w₁
M₁' : ι → Type w₁'
M₂ : Type w₂
M₃ : Type w₃
M₄ : Type w₄
A : Type u_1
inst✝⁴ : CommSemiring R
inst✝³ : Semiring A
inst✝² : Algebra R A
inst✝¹ : TopologicalSpace A
inst✝ : ContinuousMul A
⊢ Continuous (MultilinearMap.mkPiAlgebraFin R n A).toFun

Next tactic:
change Continuous fun m => (List.ofFn m).prod
/-- The continuous multilinear map on `A^n`, where `A` is a normed algebra over `𝕜`, associating to
`m` the product of all the `m i`.

See also: `ContinuousMultilinearMap.mkPiAlgebra`. -/
protected def mkPiAlgebraFin : A[×n]→L[R] A where
  cont := by
    change Continuous fun m => (List.ofFn m).prod
    

Proof state:
R : Type u
ι : Type v
n : ℕ
M : Fin (Nat.succ n) → Type w
M₁ : ι → Type w₁
M₁' : ι → Type w₁'
M₂ : Type w₂
M₃ : Type w₃
M₄ : Type w₄
A : Type u_1
inst✝⁴ : CommSemiring R
inst✝³ : Semiring A
inst✝² : Algebra R A
inst✝¹ : TopologicalSpace A
inst✝ : ContinuousMul A
⊢ Continuous fun m => List.prod (List.ofFn m)

Next tactic:
simp_rw [List.ofFn_eq_map]
/-- The continuous multilinear map on `A^n`, where `A` is a normed algebra over `𝕜`, associating to
`m` the product of all the `m i`.

See also: `ContinuousMultilinearMap.mkPiAlgebra`. -/
protected def mkPiAlgebraFin : A[×n]→L[R] A where
  cont := by
    change Continuous fun m => (List.ofFn m).prod
    simp_rw [List.ofFn_eq_map]
    

Proof state:
R : Type u
ι : Type v
n : ℕ
M : Fin (Nat.succ n) → Type w
M₁ : ι → Type w₁
M₁' : ι → Type w₁'
M₂ : Type w₂
M₃ : Type w₃
M₄ : Type w₄
A : Type u_1
inst✝⁴ : CommSemiring R
inst✝³ : Semiring A
inst✝² : Algebra R A
inst✝¹ : TopologicalSpace A
inst✝ : ContinuousMul A
⊢ Continuous fun m => List.prod (List.map m (List.finRange n))

Next tactic:
exact continuous_list_prod _ fun i _ => continuous_apply _
/--
Upgrade a Witt vector `A` whose first entry `A.coeff 0` is a unit to be, itself, a unit in `𝕎 k`.
-/
def mkUnit {a : Units k} {A : 𝕎 k} (hA : A.coeff 0 = a) : Units (𝕎 k) :=
  Units.mkOfMulEqOne A (@WittVector.mk' p _ (inverseCoeff a A)) (by
    

Proof state:
p : ℕ
hp : Fact (Nat.Prime p)
k : Type u_1
inst✝¹ : CommRing k
inst✝ : CharP k p
a : kˣ
A : 𝕎 k
hA : coeff A 0 = ↑a
⊢ A * { coeff := inverseCoeff a A } = 1

Next tactic:
ext n
/--
Upgrade a Witt vector `A` whose first entry `A.coeff 0` is a unit to be, itself, a unit in `𝕎 k`.
-/
def mkUnit {a : Units k} {A : 𝕎 k} (hA : A.coeff 0 = a) : Units (𝕎 k) :=
  Units.mkOfMulEqOne A (@WittVector.mk' p _ (inverseCoeff a A)) (by
    ext n
    

Proof state:
case h
p : ℕ
hp : Fact (Nat.Prime p)
k : Type u_1
inst✝¹ : CommRing k
inst✝ : CharP k p
a : kˣ
A : 𝕎 k
hA : coeff A 0 = ↑a
n : ℕ
⊢ coeff (A * { coeff := inverseCoeff a A }) n = coeff 1 n

Next tactic:
induction' n with n _
/--
Upgrade a Witt vector `A` whose first entry `A.coeff 0` is a unit to be, itself, a unit in `𝕎 k`.
-/
def mkUnit {a : Units k} {A : 𝕎 k} (hA : A.coeff 0 = a) : Units (𝕎 k) :=
  Units.mkOfMulEqOne A (@WittVector.mk' p _ (inverseCoeff a A)) (by
    ext n
    induction' n with n _
    · 

Proof state:
case h.zero
p : ℕ
hp : Fact (Nat.Prime p)
k : Type u_1
inst✝¹ : CommRing k
inst✝ : CharP k p
a : kˣ
A : 𝕎 k
hA : coeff A 0 = ↑a
⊢ coeff (A * { coeff := inverseCoeff a A }) Nat.zero = coeff 1 Nat.zero

Next tactic:
simp [WittVector.mul_coeff_zero, inverseCoeff, hA]
/--
Upgrade a Witt vector `A` whose first entry `A.coeff 0` is a unit to be, itself, a unit in `𝕎 k`.
-/
def mkUnit {a : Units k} {A : 𝕎 k} (hA : A.coeff 0 = a) : Units (𝕎 k) :=
  Units.mkOfMulEqOne A (@WittVector.mk' p _ (inverseCoeff a A)) (by
    ext n
    induction' n with n _
    · simp [WittVector.mul_coeff_zero, inverseCoeff, hA]
    

Proof state:
case h.succ
p : ℕ
hp : Fact (Nat.Prime p)
k : Type u_1
inst✝¹ : CommRing k
inst✝ : CharP k p
a : kˣ
A : 𝕎 k
hA : coeff A 0 = ↑a
n : ℕ
n_ih✝ : coeff (A * { coeff := inverseCoeff a A }) n = coeff 1 n
⊢ coeff (A * { coeff := inverseCoeff a A }) (Nat.succ n) = coeff 1 (Nat.succ n)

Next tactic:
let H_coeff := A.coeff (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) +
      nthRemainder p n (truncateFun (n + 1) A) fun i : Fin (n + 1) => inverseCoeff a A i
/--
Upgrade a Witt vector `A` whose first entry `A.coeff 0` is a unit to be, itself, a unit in `𝕎 k`.
-/
def mkUnit {a : Units k} {A : 𝕎 k} (hA : A.coeff 0 = a) : Units (𝕎 k) :=
  Units.mkOfMulEqOne A (@WittVector.mk' p _ (inverseCoeff a A)) (by
    ext n
    induction' n with n _
    · simp [WittVector.mul_coeff_zero, inverseCoeff, hA]
    let H_coeff := A.coeff (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) +
      nthRemainder p n (truncateFun (n + 1) A) fun i : Fin (n + 1) => inverseCoeff a A i
    

Proof state:
case h.succ
p : ℕ
hp : Fact (Nat.Prime p)
k : Type u_1
inst✝¹ : CommRing k
inst✝ : CharP k p
a : kˣ
A : 𝕎 k
hA : coeff A 0 = ↑a
n : ℕ
n_ih✝ : coeff (A * { coeff := inverseCoeff a A }) n = coeff 1 n
H_coeff : k :=
  coeff A (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) + nthRemainder p n (truncateFun (n + 1) A) fun i => inverseCoeff a A ↑i
⊢ coeff (A * { coeff := inverseCoeff a A }) (Nat.succ n) = coeff 1 (Nat.succ n)

Next tactic:
have H := Units.mul_inv (a ^ p ^ (n + 1))
/--
Upgrade a Witt vector `A` whose first entry `A.coeff 0` is a unit to be, itself, a unit in `𝕎 k`.
-/
def mkUnit {a : Units k} {A : 𝕎 k} (hA : A.coeff 0 = a) : Units (𝕎 k) :=
  Units.mkOfMulEqOne A (@WittVector.mk' p _ (inverseCoeff a A)) (by
    ext n
    induction' n with n _
    · simp [WittVector.mul_coeff_zero, inverseCoeff, hA]
    let H_coeff := A.coeff (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) +
      nthRemainder p n (truncateFun (n + 1) A) fun i : Fin (n + 1) => inverseCoeff a A i
    have H := Units.mul_inv (a ^ p ^ (n + 1))
    

Proof state:
case h.succ
p : ℕ
hp : Fact (Nat.Prime p)
k : Type u_1
inst✝¹ : CommRing k
inst✝ : CharP k p
a : kˣ
A : 𝕎 k
hA : coeff A 0 = ↑a
n : ℕ
n_ih✝ : coeff (A * { coeff := inverseCoeff a A }) n = coeff 1 n
H_coeff : k :=
  coeff A (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) + nthRemainder p n (truncateFun (n + 1) A) fun i => inverseCoeff a A ↑i
H : ↑(a ^ p ^ (n + 1)) * ↑(a ^ p ^ (n + 1))⁻¹ = 1
⊢ coeff (A * { coeff := inverseCoeff a A }) (Nat.succ n) = coeff 1 (Nat.succ n)

Next tactic:
linear_combination (norm := skip) -H_coeff * H
/--
Upgrade a Witt vector `A` whose first entry `A.coeff 0` is a unit to be, itself, a unit in `𝕎 k`.
-/
def mkUnit {a : Units k} {A : 𝕎 k} (hA : A.coeff 0 = a) : Units (𝕎 k) :=
  Units.mkOfMulEqOne A (@WittVector.mk' p _ (inverseCoeff a A)) (by
    ext n
    induction' n with n _
    · simp [WittVector.mul_coeff_zero, inverseCoeff, hA]
    let H_coeff := A.coeff (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) +
      nthRemainder p n (truncateFun (n + 1) A) fun i : Fin (n + 1) => inverseCoeff a A i
    have H := Units.mul_inv (a ^ p ^ (n + 1))
    linear_combination (norm := 

Proof state:
case a
p : ℕ
hp : Fact (Nat.Prime p)
k : Type u_1
inst✝¹ : CommRing k
inst✝ : CharP k p
a : kˣ
A : 𝕎 k
hA : coeff A 0 = ↑a
n : ℕ
n_ih✝ : coeff (A * { coeff := inverseCoeff a A }) n = coeff 1 n
H_coeff : k :=
  coeff A (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) + nthRemainder p n (truncateFun (n + 1) A) fun i => inverseCoeff a A ↑i
H : ↑(a ^ p ^ (n + 1)) * ↑(a ^ p ^ (n + 1))⁻¹ = 1
⊢ coeff (A * { coeff := inverseCoeff a A }) (Nat.succ n) - coeff 1 (Nat.succ n) -
      (-H_coeff * (↑(a ^ p ^ (n + 1)) * ↑(a ^ p ^ (n + 1))⁻¹) - -H_coeff * 1) =
    0

Next tactic:
skip
/--
Upgrade a Witt vector `A` whose first entry `A.coeff 0` is a unit to be, itself, a unit in `𝕎 k`.
-/
def mkUnit {a : Units k} {A : 𝕎 k} (hA : A.coeff 0 = a) : Units (𝕎 k) :=
  Units.mkOfMulEqOne A (@WittVector.mk' p _ (inverseCoeff a A)) (by
    ext n
    induction' n with n _
    · simp [WittVector.mul_coeff_zero, inverseCoeff, hA]
    let H_coeff := A.coeff (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) +
      nthRemainder p n (truncateFun (n + 1) A) fun i : Fin (n + 1) => inverseCoeff a A i
    have H := Units.mul_inv (a ^ p ^ (n + 1))
    linear_combination (norm := skip) -H_coeff * H
    

Proof state:
case a
p : ℕ
hp : Fact (Nat.Prime p)
k : Type u_1
inst✝¹ : CommRing k
inst✝ : CharP k p
a : kˣ
A : 𝕎 k
hA : coeff A 0 = ↑a
n : ℕ
n_ih✝ : coeff (A * { coeff := inverseCoeff a A }) n = coeff 1 n
H_coeff : k :=
  coeff A (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) + nthRemainder p n (truncateFun (n + 1) A) fun i => inverseCoeff a A ↑i
H : ↑(a ^ p ^ (n + 1)) * ↑(a ^ p ^ (n + 1))⁻¹ = 1
⊢ coeff (A * { coeff := inverseCoeff a A }) (Nat.succ n) - coeff 1 (Nat.succ n) -
      (-H_coeff * (↑(a ^ p ^ (n + 1)) * ↑(a ^ p ^ (n + 1))⁻¹) - -H_coeff * 1) =
    0

Next tactic:
have ha : (a : k) ^ p ^ (n + 1) = ↑(a ^ p ^ (n + 1)) := by norm_cast
/--
Upgrade a Witt vector `A` whose first entry `A.coeff 0` is a unit to be, itself, a unit in `𝕎 k`.
-/
def mkUnit {a : Units k} {A : 𝕎 k} (hA : A.coeff 0 = a) : Units (𝕎 k) :=
  Units.mkOfMulEqOne A (@WittVector.mk' p _ (inverseCoeff a A)) (by
    ext n
    induction' n with n _
    · simp [WittVector.mul_coeff_zero, inverseCoeff, hA]
    let H_coeff := A.coeff (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) +
      nthRemainder p n (truncateFun (n + 1) A) fun i : Fin (n + 1) => inverseCoeff a A i
    have H := Units.mul_inv (a ^ p ^ (n + 1))
    linear_combination (norm := skip) -H_coeff * H
    have ha : (a : k) ^ p ^ (n + 1) = ↑(a ^ p ^ (n + 1)) := by 

Proof state:
p : ℕ
hp : Fact (Nat.Prime p)
k : Type u_1
inst✝¹ : CommRing k
inst✝ : CharP k p
a : kˣ
A : 𝕎 k
hA : coeff A 0 = ↑a
n : ℕ
n_ih✝ : coeff (A * { coeff := inverseCoeff a A }) n = coeff 1 n
H_coeff : k :=
  coeff A (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) + nthRemainder p n (truncateFun (n + 1) A) fun i => inverseCoeff a A ↑i
H : ↑(a ^ p ^ (n + 1)) * ↑(a ^ p ^ (n + 1))⁻¹ = 1
⊢ ↑a ^ p ^ (n + 1) = ↑(a ^ p ^ (n + 1))

Next tactic:
norm_cast
/--
Upgrade a Witt vector `A` whose first entry `A.coeff 0` is a unit to be, itself, a unit in `𝕎 k`.
-/
def mkUnit {a : Units k} {A : 𝕎 k} (hA : A.coeff 0 = a) : Units (𝕎 k) :=
  Units.mkOfMulEqOne A (@WittVector.mk' p _ (inverseCoeff a A)) (by
    ext n
    induction' n with n _
    · simp [WittVector.mul_coeff_zero, inverseCoeff, hA]
    let H_coeff := A.coeff (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) +
      nthRemainder p n (truncateFun (n + 1) A) fun i : Fin (n + 1) => inverseCoeff a A i
    have H := Units.mul_inv (a ^ p ^ (n + 1))
    linear_combination (norm := skip) -H_coeff * H
    have ha : (a : k) ^ p ^ (n + 1) = ↑(a ^ p ^ (n + 1)) := by norm_cast
    

Proof state:
case a
p : ℕ
hp : Fact (Nat.Prime p)
k : Type u_1
inst✝¹ : CommRing k
inst✝ : CharP k p
a : kˣ
A : 𝕎 k
hA : coeff A 0 = ↑a
n : ℕ
n_ih✝ : coeff (A * { coeff := inverseCoeff a A }) n = coeff 1 n
H_coeff : k :=
  coeff A (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) + nthRemainder p n (truncateFun (n + 1) A) fun i => inverseCoeff a A ↑i
H : ↑(a ^ p ^ (n + 1)) * ↑(a ^ p ^ (n + 1))⁻¹ = 1
ha : ↑a ^ p ^ (n + 1) = ↑(a ^ p ^ (n + 1))
⊢ coeff (A * { coeff := inverseCoeff a A }) (Nat.succ n) - coeff 1 (Nat.succ n) -
      (-H_coeff * (↑(a ^ p ^ (n + 1)) * ↑(a ^ p ^ (n + 1))⁻¹) - -H_coeff * 1) =
    0

Next tactic:
have ha_inv : (↑a⁻¹ : k) ^ p ^ (n + 1) = ↑(a ^ p ^ (n + 1))⁻¹ := by norm_cast; norm_num
/--
Upgrade a Witt vector `A` whose first entry `A.coeff 0` is a unit to be, itself, a unit in `𝕎 k`.
-/
def mkUnit {a : Units k} {A : 𝕎 k} (hA : A.coeff 0 = a) : Units (𝕎 k) :=
  Units.mkOfMulEqOne A (@WittVector.mk' p _ (inverseCoeff a A)) (by
    ext n
    induction' n with n _
    · simp [WittVector.mul_coeff_zero, inverseCoeff, hA]
    let H_coeff := A.coeff (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) +
      nthRemainder p n (truncateFun (n + 1) A) fun i : Fin (n + 1) => inverseCoeff a A i
    have H := Units.mul_inv (a ^ p ^ (n + 1))
    linear_combination (norm := skip) -H_coeff * H
    have ha : (a : k) ^ p ^ (n + 1) = ↑(a ^ p ^ (n + 1)) := by norm_cast
    have ha_inv : (↑a⁻¹ : k) ^ p ^ (n + 1) = ↑(a ^ p ^ (n + 1))⁻¹ := by 

Proof state:
p : ℕ
hp : Fact (Nat.Prime p)
k : Type u_1
inst✝¹ : CommRing k
inst✝ : CharP k p
a : kˣ
A : 𝕎 k
hA : coeff A 0 = ↑a
n : ℕ
n_ih✝ : coeff (A * { coeff := inverseCoeff a A }) n = coeff 1 n
H_coeff : k :=
  coeff A (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) + nthRemainder p n (truncateFun (n + 1) A) fun i => inverseCoeff a A ↑i
H : ↑(a ^ p ^ (n + 1)) * ↑(a ^ p ^ (n + 1))⁻¹ = 1
ha : ↑a ^ p ^ (n + 1) = ↑(a ^ p ^ (n + 1))
⊢ ↑a⁻¹ ^ p ^ (n + 1) = ↑(a ^ p ^ (n + 1))⁻¹

Next tactic:
norm_cast
/--
Upgrade a Witt vector `A` whose first entry `A.coeff 0` is a unit to be, itself, a unit in `𝕎 k`.
-/
def mkUnit {a : Units k} {A : 𝕎 k} (hA : A.coeff 0 = a) : Units (𝕎 k) :=
  Units.mkOfMulEqOne A (@WittVector.mk' p _ (inverseCoeff a A)) (by
    ext n
    induction' n with n _
    · simp [WittVector.mul_coeff_zero, inverseCoeff, hA]
    let H_coeff := A.coeff (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) +
      nthRemainder p n (truncateFun (n + 1) A) fun i : Fin (n + 1) => inverseCoeff a A i
    have H := Units.mul_inv (a ^ p ^ (n + 1))
    linear_combination (norm := skip) -H_coeff * H
    have ha : (a : k) ^ p ^ (n + 1) = ↑(a ^ p ^ (n + 1)) := by norm_cast
    have ha_inv : (↑a⁻¹ : k) ^ p ^ (n + 1) = ↑(a ^ p ^ (n + 1))⁻¹ := by norm_cast; 

Proof state:
p : ℕ
hp : Fact (Nat.Prime p)
k : Type u_1
inst✝¹ : CommRing k
inst✝ : CharP k p
a : kˣ
A : 𝕎 k
hA : coeff A 0 = ↑a
n : ℕ
n_ih✝ : coeff (A * { coeff := inverseCoeff a A }) n = coeff 1 n
H_coeff : k :=
  coeff A (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) + nthRemainder p n (truncateFun (n + 1) A) fun i => inverseCoeff a A ↑i
H : ↑(a ^ p ^ (n + 1)) * ↑(a ^ p ^ (n + 1))⁻¹ = 1
ha : ↑a ^ p ^ (n + 1) = ↑(a ^ p ^ (n + 1))
⊢ a⁻¹ ^ p ^ (n + 1) = (a ^ p ^ (n + 1))⁻¹

Next tactic:
norm_num
/--
Upgrade a Witt vector `A` whose first entry `A.coeff 0` is a unit to be, itself, a unit in `𝕎 k`.
-/
def mkUnit {a : Units k} {A : 𝕎 k} (hA : A.coeff 0 = a) : Units (𝕎 k) :=
  Units.mkOfMulEqOne A (@WittVector.mk' p _ (inverseCoeff a A)) (by
    ext n
    induction' n with n _
    · simp [WittVector.mul_coeff_zero, inverseCoeff, hA]
    let H_coeff := A.coeff (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) +
      nthRemainder p n (truncateFun (n + 1) A) fun i : Fin (n + 1) => inverseCoeff a A i
    have H := Units.mul_inv (a ^ p ^ (n + 1))
    linear_combination (norm := skip) -H_coeff * H
    have ha : (a : k) ^ p ^ (n + 1) = ↑(a ^ p ^ (n + 1)) := by norm_cast
    have ha_inv : (↑a⁻¹ : k) ^ p ^ (n + 1) = ↑(a ^ p ^ (n + 1))⁻¹ := by norm_cast; norm_num
    

Proof state:
case a
p : ℕ
hp : Fact (Nat.Prime p)
k : Type u_1
inst✝¹ : CommRing k
inst✝ : CharP k p
a : kˣ
A : 𝕎 k
hA : coeff A 0 = ↑a
n : ℕ
n_ih✝ : coeff (A * { coeff := inverseCoeff a A }) n = coeff 1 n
H_coeff : k :=
  coeff A (n + 1) * ↑(a⁻¹ ^ p ^ (n + 1)) + nthRemainder p n (truncateFun (n + 1) A) fun i => inverseCoeff a A ↑i
H : ↑(a ^ p ^ (n + 1)) * ↑(a ^ p ^ (n + 1))⁻¹ = 1
ha : ↑a ^ p ^ (n + 1) = ↑(a ^ p ^ (n + 1))
ha_inv : ↑a⁻¹ ^ p ^ (n + 1) = ↑(a ^ p ^ (n + 1))⁻¹
⊢ coeff (A * { coeff := inverseCoeff a A }) (Nat.succ n) - coeff 1 (Nat.succ n) -
      (-H_coeff * (↑(a ^ p ^ (n + 1)) * ↑(a ^ p ^ (n + 1))⁻¹) - -H_coeff * 1) =
    0

Next tactic:
simp only [nthRemainder_spec, inverseCoeff, succNthValUnits, hA,
      one_coeff_eq_of_pos, Nat.succ_pos', ha_inv, ha, inv_pow]