File: Mathlib/RingTheory/WittVector/Truncated.lean

full_name: _aux_Mathlib_RingTheory_WittVector_Truncated___macroRules_term𝕎_1
code: local notation "𝕎" => WittVector p
goal: Lean.Macro

full_name: _aux_Mathlib_RingTheory_WittVector_Truncated___unexpand_WittVector_1
code: local notation "𝕎" => WittVector p
goal: Lean.PrettyPrinter.Unexpander

full_name: TruncatedWittVector
code: /-- A truncated Witt vector over `R` is a vector of elements of `R`,
i.e., the first `n` coefficients of a Witt vector.
We will define operations on this type that are compatible with the (untruncated) Witt
vector operations.

`TruncatedWittVector p n R` takes a parameter `p : ℕ` that is not used in the definition.
In practice, this number `p` is assumed to be a prime number,
and under this assumption we construct a ring structure on `TruncatedWittVector p n R`.
(`TruncatedWittVector p₁ n R` and `TruncatedWittVector p₂ n R` are definitionally
equal as types but will have different ring operations.)
-/
@[nolint unusedArguments]
def TruncatedWittVector (_ : ℕ) (n : ℕ) (R : Type*) 
goal: ℕ → ℕ → Type u_2 → Type u_2

full_name: instInhabitedTruncatedWittVector
code: instance (p n : ℕ) (R : Type*) [Inhabited R] : Inhabited (TruncatedWittVector p n R) 
goal: Inhabited (TruncatedWittVector p n R)

full_name: TruncatedWittVector.mk
code: /-- Create a `TruncatedWittVector` from a vector `x`. -/
def mk (x : Fin n → R) : TruncatedWittVector p n R 
goal: TruncatedWittVector p n R

full_name: TruncatedWittVector.coeff
code: /-- `x.coeff i` is the `i`th entry of `x`. -/
def coeff (i : Fin n) (x : TruncatedWittVector p n R) : R 
goal: R

full_name: TruncatedWittVector.ext
code: @[ext]
theorem ext {x y : TruncatedWittVector p n R} (h : ∀ i, x.coeff i = y.coeff i) : x = y 
goal: x = y

full_name: TruncatedWittVector.ext_iff
code: theorem ext_iff {x y : TruncatedWittVector p n R} : x = y ↔ ∀ i, x.coeff i = y.coeff i 
goal: x = y ↔ ∀ (i : Fin n), TruncatedWittVector.coeff i x = TruncatedWittVector.coeff i y

full_name: TruncatedWittVector.coeff_mk
code: @[simp]
theorem coeff_mk (x : Fin n → R) (i : Fin n) : (mk p x).coeff i = x i 
goal: TruncatedWittVector.coeff i (TruncatedWittVector.mk p x) = x i

full_name: TruncatedWittVector.mk_coeff
code: @[simp]
theorem mk_coeff (x : TruncatedWittVector p n R) : (mk p fun i => x.coeff i) = x 
goal: (TruncatedWittVector.mk p fun i => TruncatedWittVector.coeff i x) = x

full_name: TruncatedWittVector.out
code: /-- We can turn a truncated Witt vector `x` into a Witt vector
by setting all coefficients after `x` to be 0.
-/
def out (x : TruncatedWittVector p n R) : 𝕎 R 
goal: 𝕎 R

full_name: TruncatedWittVector.coeff_out
code: @[simp]
theorem coeff_out (x : TruncatedWittVector p n R) (i : Fin n) : x.out.coeff i = x.coeff i 
goal: x.out.coeff ↑i = TruncatedWittVector.coeff i x

full_name: TruncatedWittVector.out_injective
code: theorem out_injective : Injective (@out p n R _) 
goal: Function.Injective TruncatedWittVector.out

full_name: WittVector.truncateFun
code: /-- `truncateFun n x` uses the first `n` entries of `x` to construct a `TruncatedWittVector`,
which has the same base `p` as `x`.
This function is bundled into a ring homomorphism in `WittVector.truncate` -/
def truncateFun (x : 𝕎 R) : TruncatedWittVector p n R 
goal: TruncatedWittVector p n R

full_name: WittVector.coeff_truncateFun
code: @[simp]
theorem coeff_truncateFun (x : 𝕎 R) (i : Fin n) : (truncateFun n x).coeff i = x.coeff i 
goal: TruncatedWittVector.coeff i (WittVector.truncateFun n x) = x.coeff ↑i

full_name: WittVector.out_truncateFun
code: @[simp]
theorem out_truncateFun (x : 𝕎 R) : (truncateFun n x).out = init n x 
goal: (WittVector.truncateFun n x).out = WittVector.init n x

full_name: TruncatedWittVector.truncateFun_out
code: @[simp]
theorem truncateFun_out (x : TruncatedWittVector p n R) : x.out.truncateFun n = x 
goal: WittVector.truncateFun n x.out = x

full_name: TruncatedWittVector.instZero
code: instance : Zero (TruncatedWittVector p n R) 
goal: Zero (TruncatedWittVector p n R)

full_name: TruncatedWittVector.instOne
code: instance : One (TruncatedWittVector p n R) 
goal: One (TruncatedWittVector p n R)

full_name: TruncatedWittVector.instNatCast
code: instance : NatCast (TruncatedWittVector p n R) 
goal: NatCast (TruncatedWittVector p n R)

full_name: TruncatedWittVector.instIntCast
code: instance : IntCast (TruncatedWittVector p n R) 
goal: IntCast (TruncatedWittVector p n R)

full_name: TruncatedWittVector.instAdd
code: instance : Add (TruncatedWittVector p n R) 
goal: Add (TruncatedWittVector p n R)

full_name: TruncatedWittVector.instMul
code: instance : Mul (TruncatedWittVector p n R) 
goal: Mul (TruncatedWittVector p n R)

full_name: TruncatedWittVector.instNeg
code: instance : Neg (TruncatedWittVector p n R) 
goal: Neg (TruncatedWittVector p n R)

full_name: TruncatedWittVector.instSub
code: instance : Sub (TruncatedWittVector p n R) 
goal: Sub (TruncatedWittVector p n R)

full_name: TruncatedWittVector.hasNatScalar
code: instance hasNatScalar : SMul ℕ (TruncatedWittVector p n R) 
goal: SMul ℕ (TruncatedWittVector p n R)

full_name: TruncatedWittVector.hasIntScalar
code: instance hasIntScalar : SMul ℤ (TruncatedWittVector p n R) 
goal: SMul ℤ (TruncatedWittVector p n R)

full_name: TruncatedWittVector.hasNatPow
code: instance hasNatPow : Pow (TruncatedWittVector p n R) ℕ 
goal: Pow (TruncatedWittVector p n R) ℕ

full_name: TruncatedWittVector.coeff_zero
code: @[simp]
theorem coeff_zero (i : Fin n) : (0 : TruncatedWittVector p n R).coeff i = 0 
goal: TruncatedWittVector.coeff i 0 = 0

full_name: _aux_Mathlib_RingTheory_WittVector_Truncated___macroRules_witt_truncateFun_tac_1
code: macro (name := witt_truncateFun_tac) "witt_truncateFun_tac" : tactic =>
  `(tactic|
    { show _ = WittVector.truncateFun n _
      apply TruncatedWittVector.out_injective
      iterate rw [WittVector.out_truncateFun]
      first
      | rw [WittVector.init_add]
      | rw [WittVector.init_mul]
      | rw [WittVector.init_neg]
      | rw [WittVector.init_sub]
      | rw [WittVector.init_nsmul]
      | rw [WittVector.init_zsmul]
      | rw [WittVector.init_pow]})
goal: Lean.Macro

full_name: witt_truncateFun_tac
code: macro (name := witt_truncateFun_tac) "witt_truncateFun_tac" : tactic =>
  `(tactic|
    { show _ = WittVector.truncateFun n _
      apply TruncatedWittVector.out_injective
      iterate rw [WittVector.out_truncateFun]
      first
      | rw [WittVector.init_add]
      | rw [WittVector.init_mul]
      | rw [WittVector.init_neg]
      | rw [WittVector.init_sub]
      | rw [WittVector.init_nsmul]
      | rw [WittVector.init_zsmul]
      | rw [WittVector.init_pow]})
goal: Lean.ParserDescr

full_name: WittVector.truncateFun_surjective
code: theorem truncateFun_surjective : Surjective (@truncateFun p n R) 
goal: Function.Surjective (WittVector.truncateFun n)

full_name: WittVector.truncateFun_zero
code: @[simp]
theorem truncateFun_zero : truncateFun n (0 : 𝕎 R) = 0 
goal: WittVector.truncateFun n 0 = 0

full_name: WittVector.truncateFun_one
code: @[simp]
theorem truncateFun_one : truncateFun n (1 : 𝕎 R) = 1 
goal: WittVector.truncateFun n 1 = 1

full_name: WittVector.truncateFun_add
code: @[simp]
theorem truncateFun_add (x y : 𝕎 R) :
    truncateFun n (x + y) = truncateFun n x + truncateFun n y 
goal: WittVector.truncateFun n (x + y) = WittVector.truncateFun n x + WittVector.truncateFun n y

full_name: WittVector.truncateFun_mul
code: @[simp]
theorem truncateFun_mul (x y : 𝕎 R) :
    truncateFun n (x * y) = truncateFun n x * truncateFun n y 
goal: WittVector.truncateFun n (x * y) = WittVector.truncateFun n x * WittVector.truncateFun n y

full_name: WittVector.truncateFun_neg
code: theorem truncateFun_neg (x : 𝕎 R) : truncateFun n (-x) = -truncateFun n x 
goal: WittVector.truncateFun n (-x) = -WittVector.truncateFun n x

full_name: WittVector.truncateFun_sub
code: theorem truncateFun_sub (x y : 𝕎 R) :
    truncateFun n (x - y) = truncateFun n x - truncateFun n y 
goal: WittVector.truncateFun n (x - y) = WittVector.truncateFun n x - WittVector.truncateFun n y

full_name: WittVector.truncateFun_nsmul
code: theorem truncateFun_nsmul (m : ℕ) (x : 𝕎 R) : truncateFun n (m • x) = m • truncateFun n x 
goal: WittVector.truncateFun n (m • x) = m • WittVector.truncateFun n x

full_name: WittVector.truncateFun_zsmul
code: theorem truncateFun_zsmul (m : ℤ) (x : 𝕎 R) : truncateFun n (m • x) = m • truncateFun n x 
goal: WittVector.truncateFun n (m • x) = m • WittVector.truncateFun n x

full_name: WittVector.truncateFun_pow
code: theorem truncateFun_pow (x : 𝕎 R) (m : ℕ) : truncateFun n (x ^ m) = truncateFun n x ^ m 
goal: WittVector.truncateFun n (x ^ m) = WittVector.truncateFun n x ^ m

full_name: WittVector.truncateFun_natCast
code: theorem truncateFun_natCast (m : ℕ) : truncateFun n (m : 𝕎 R) = m 
goal: WittVector.truncateFun n ↑m = ↑m

full_name: WittVector.truncateFun_intCast
code: theorem truncateFun_intCast (m : ℤ) : truncateFun n (m : 𝕎 R) = m 
goal: WittVector.truncateFun n ↑m = ↑m

full_name: TruncatedWittVector.instCommRing
code: instance instCommRing : CommRing (TruncatedWittVector p n R) 
goal: CommRing (TruncatedWittVector p n R)

full_name: WittVector.truncate
code: /-- `truncate n` is a ring homomorphism that truncates `x` to its first `n` entries
to obtain a `TruncatedWittVector`, which has the same base `p` as `x`. -/
noncomputable def truncate : 𝕎 R →+* TruncatedWittVector p n R 
goal: 𝕎 R →+* TruncatedWittVector p n R

full_name: WittVector.truncate_surjective
code: theorem truncate_surjective : Surjective (truncate n : 𝕎 R → TruncatedWittVector p n R) 
goal: Function.Surjective ⇑(WittVector.truncate n)

full_name: WittVector.coeff_truncate
code: @[simp]
theorem coeff_truncate (x : 𝕎 R) (i : Fin n) : (truncate n x).coeff i = x.coeff i 
goal: TruncatedWittVector.coeff i ((WittVector.truncate n) x) = x.coeff ↑i

full_name: WittVector.mem_ker_truncate
code: theorem mem_ker_truncate (x : 𝕎 R) :
    x ∈ RingHom.ker (@truncate p _ n R _) ↔ ∀ i < n, x.coeff i = 0 
goal: x ∈ RingHom.ker (WittVector.truncate n) ↔ ∀ i < n, x.coeff i = 0

full_name: WittVector.truncate_mk'
code: @[simp]
theorem truncate_mk' (f : ℕ → R) :
    truncate n (@mk' p _ f) = TruncatedWittVector.mk _ fun k => f k 
goal: (WittVector.truncate n) { coeff := f } = TruncatedWittVector.mk p fun k => f ↑k

full_name: TruncatedWittVector.truncate
code: /-- A ring homomorphism that truncates a truncated Witt vector of length `m` to
a truncated Witt vector of length `n`, for `n ≤ m`.
-/
def truncate {m : ℕ} (hm : n ≤ m) : TruncatedWittVector p m R →+* TruncatedWittVector p n R 
goal: TruncatedWittVector p m R →+* TruncatedWittVector p n R

full_name: TruncatedWittVector.truncate_comp_wittVector_truncate
code: @[simp]
theorem truncate_comp_wittVector_truncate {m : ℕ} (hm : n ≤ m) :
    (@truncate p _ n R _ m hm).comp (WittVector.truncate m) = WittVector.truncate n 
goal: (TruncatedWittVector.truncate hm).comp (WittVector.truncate m) = WittVector.truncate n

full_name: TruncatedWittVector.truncate_wittVector_truncate
code: @[simp]
theorem truncate_wittVector_truncate {m : ℕ} (hm : n ≤ m) (x : 𝕎 R) :
    truncate hm (WittVector.truncate m x) = WittVector.truncate n x 
goal: (TruncatedWittVector.truncate hm) ((WittVector.truncate m) x) = (WittVector.truncate n) x

full_name: TruncatedWittVector.truncate_truncate
code: @[simp]
theorem truncate_truncate {n₁ n₂ n₃ : ℕ} (h1 : n₁ ≤ n₂) (h2 : n₂ ≤ n₃)
    (x : TruncatedWittVector p n₃ R) :
    (truncate h1) (truncate h2 x) = truncate (h1.trans h2) x 
goal: (TruncatedWittVector.truncate h1) ((TruncatedWittVector.truncate h2) x) = (TruncatedWittVector.truncate ⋯) x

full_name: TruncatedWittVector.truncate_comp
code: @[simp]
theorem truncate_comp {n₁ n₂ n₃ : ℕ} (h1 : n₁ ≤ n₂) (h2 : n₂ ≤ n₃) :
    (@truncate p _ _ R _ _ h1).comp (truncate h2) = truncate (h1.trans h2) 
goal: (TruncatedWittVector.truncate h1).comp (TruncatedWittVector.truncate h2) = TruncatedWittVector.truncate ⋯

full_name: TruncatedWittVector.truncate_surjective
code: theorem truncate_surjective {m : ℕ} (hm : n ≤ m) : Surjective (@truncate p _ _ R _ _ hm) 
goal: Function.Surjective ⇑(TruncatedWittVector.truncate hm)

full_name: TruncatedWittVector.coeff_truncate
code: @[simp]
theorem coeff_truncate {m : ℕ} (hm : n ≤ m) (i : Fin n) (x : TruncatedWittVector p m R) :
    (truncate hm x).coeff i = x.coeff (Fin.castLE hm i) 
goal: TruncatedWittVector.coeff i ((TruncatedWittVector.truncate hm) x) = TruncatedWittVector.coeff (Fin.castLE hm i) x

full_name: TruncatedWittVector.instFintype
code: instance {R : Type*} [Fintype R] : Fintype (TruncatedWittVector p n R) 
goal: Fintype (TruncatedWittVector p n R)

full_name: TruncatedWittVector.card
code: theorem card {R : Type*} [Fintype R] :
    Fintype.card (TruncatedWittVector p n R) = Fintype.card R ^ n 
goal: Fintype.card (TruncatedWittVector p n R) = Fintype.card R ^ n

full_name: TruncatedWittVector.iInf_ker_truncate
code: theorem iInf_ker_truncate : ⨅ i : ℕ, RingHom.ker (@WittVector.truncate p _ i R _) = ⊥ 
goal: ⨅ i, RingHom.ker (WittVector.truncate i) = ⊥

full_name: WittVector.liftFun
code: /-- Given a family `fₖ : S → TruncatedWittVector p k R` and `s : S`, we produce a Witt vector by
defining the `k`th entry to be the final entry of `fₖ s`.
-/
def liftFun (s : S) : 𝕎 R 
goal: 𝕎 R

full_name: WittVector.truncate_liftFun
code: @[simp]
theorem truncate_liftFun (s : S) : WittVector.truncate n (liftFun f s) = f n s 
goal: (WittVector.truncate n) (WittVector.liftFun f s) = (f n) s

full_name: WittVector.lift
code: /--
Given compatible ring homs from `S` into `TruncatedWittVector n` for each `n`, we can lift these
to a ring hom `S → 𝕎 R`.

`lift` defines the universal property of `𝕎 R` as the inverse limit of `TruncatedWittVector n`.
-/
def lift : S →+* 𝕎 R 
goal: S →+* 𝕎 R

full_name: WittVector.truncate_lift
code: @[simp]
theorem truncate_lift (s : S) : WittVector.truncate n (lift _ f_compat s) = f n s 
goal: (WittVector.truncate n) ((WittVector.lift f f_compat) s) = (f n) s

full_name: WittVector.truncate_comp_lift
code: @[simp]
theorem truncate_comp_lift : (WittVector.truncate n).comp (lift _ f_compat) = f n 
goal: (WittVector.truncate n).comp (WittVector.lift f f_compat) = f n

full_name: WittVector.lift_unique
code: /-- The uniqueness part of the universal property of `𝕎 R`. -/
theorem lift_unique (g : S →+* 𝕎 R) (g_compat : ∀ k, (WittVector.truncate k).comp g = f k) :
    lift _ f_compat = g 
goal: WittVector.lift f f_compat = g

full_name: WittVector.liftEquiv
code: /-- The universal property of `𝕎 R` as projective limit of truncated Witt vector rings. -/
@[simps]
def liftEquiv : { f : ∀ k, S →+* TruncatedWittVector p k R // ∀ (k₁ k₂) (hk : k₁ ≤ k₂),
    (TruncatedWittVector.truncate hk).comp (f k₂) = f k₁ } ≃ (S →+* 𝕎 R) 
goal: { f // ∀ (k₁ k₂ : ℕ) (hk : k₁ ≤ k₂), (TruncatedWittVector.truncate hk).comp (f k₂) = f k₁ } ≃ (S →+* 𝕎 R)

full_name: WittVector.liftEquiv_symm_apply_coe
code: /-- The universal property of `𝕎 R` as projective limit of truncated Witt vector rings. -/
@[simps]
def liftEquiv : { f : ∀ k, S →+* TruncatedWittVector p k R // ∀ (k₁ k₂) (hk : k₁ ≤ k₂),
    (TruncatedWittVector.truncate hk).comp (f k₂) = f k₁ } ≃ (S →+* 𝕎 R) 
goal: ↑(WittVector.liftEquiv.symm g) k = (WittVector.truncate k).comp g

full_name: WittVector.liftEquiv_apply
code: /-- The universal property of `𝕎 R` as projective limit of truncated Witt vector rings. -/
@[simps]
def liftEquiv : { f : ∀ k, S →+* TruncatedWittVector p k R // ∀ (k₁ k₂) (hk : k₁ ≤ k₂),
    (TruncatedWittVector.truncate hk).comp (f k₂) = f k₁ } ≃ (S →+* 𝕎 R) 
goal: WittVector.liftEquiv f = WittVector.lift ↑f ⋯

full_name: WittVector.hom_ext
code: theorem hom_ext (g₁ g₂ : S →+* 𝕎 R) (h : ∀ k, (truncate k).comp g₁ = (truncate k).comp g₂) :
    g₁ = g₂ 
goal: g₁ = g₂