File: Mathlib/RingTheory/WittVector/StructurePolynomial.lean

full_name: Witt._aux_Mathlib_RingTheory_WittVector_StructurePolynomial___macroRules_Witt_termW__1_1
code: @[inherit_doc]
scoped[Witt] notation "W_" => wittPolynomial p
goal: Lean.Macro

full_name: Witt._aux_Mathlib_RingTheory_WittVector_StructurePolynomial___unexpand_wittPolynomial_1
code: @[inherit_doc]
scoped[Witt] notation "W_" => wittPolynomial p
goal: Lean.PrettyPrinter.Unexpander

full_name: Witt._aux_Mathlib_RingTheory_WittVector_StructurePolynomial___macroRules_Witt_termW_1_1
code: @[inherit_doc]
scoped[Witt] notation "W" => wittPolynomial p _
goal: Lean.Macro

full_name: Witt._aux_Mathlib_RingTheory_WittVector_StructurePolynomial___unexpand_wittPolynomial_2
code: @[inherit_doc]
scoped[Witt] notation "W" => wittPolynomial p _
goal: Lean.PrettyPrinter.Unexpander

full_name: wittStructureRat
code: /-- `wittStructureRat Φ` is a family of polynomials `ℕ → MvPolynomial (idx × ℕ) ℚ`
that are uniquely characterised by the property that
```
bind₁ (wittStructureRat p Φ) (wittPolynomial p ℚ n) =
bind₁ (fun i ↦ (rename (prod.mk i) (wittPolynomial p ℚ n))) Φ
```
In other words: evaluating the `n`-th Witt polynomial on the family `wittStructureRat Φ`
is the same as evaluating `Φ` on the (appropriately renamed) `n`-th Witt polynomials.

See `wittStructureRat_prop` for this property,
and `wittStructureRat_existsUnique` for the fact that `wittStructureRat`
gives the unique family of polynomials with this property.

These polynomials turn out to have integral coefficients,
but it requires some effort to show this.
See `wittStructureInt` for the version with integral coefficients,
and `map_wittStructureInt` for the fact that it is equal to `wittStructureRat`
when mapped to polynomials over the rationals. -/
noncomputable def wittStructureRat (Φ : MvPolynomial idx ℚ) (n : ℕ) : MvPolynomial (idx × ℕ) ℚ 
goal: MvPolynomial (idx × ℕ) ℚ

full_name: wittStructureRat_prop
code: theorem wittStructureRat_prop (Φ : MvPolynomial idx ℚ) (n : ℕ) :
    bind₁ (wittStructureRat p Φ) (W_ ℚ n) = bind₁ (fun i => rename (Prod.mk i) (W_ ℚ n)) Φ 
goal: (MvPolynomial.bind₁ (wittStructureRat p Φ)) (W_ ℚ n) =
  (MvPolynomial.bind₁ fun i => (MvPolynomial.rename (Prod.mk i)) (W_ ℚ n)) Φ

full_name: wittStructureRat_existsUnique
code: theorem wittStructureRat_existsUnique (Φ : MvPolynomial idx ℚ) :
    ∃! φ : ℕ → MvPolynomial (idx × ℕ) ℚ,
      ∀ n : ℕ, bind₁ φ (W_ ℚ n) = bind₁ (fun i => rename (Prod.mk i) (W_ ℚ n)) Φ 
goal: ∃! φ,
  ∀ (n : ℕ),
    (MvPolynomial.bind₁ φ) (W_ ℚ n) = (MvPolynomial.bind₁ fun i => (MvPolynomial.rename (Prod.mk i)) (W_ ℚ n)) Φ

full_name: wittStructureRat_rec_aux
code: theorem wittStructureRat_rec_aux (Φ : MvPolynomial idx ℚ) (n : ℕ) :
    wittStructureRat p Φ n * C ((p : ℚ) ^ n) =
      bind₁ (fun b => rename (fun i => (b, i)) (W_ ℚ n)) Φ -
        ∑ i ∈ range n, C ((p : ℚ) ^ i) * wittStructureRat p Φ i ^ p ^ (n - i) 
goal: wittStructureRat p Φ n * MvPolynomial.C (↑p ^ n) =
  (MvPolynomial.bind₁ fun b => (MvPolynomial.rename fun i => (b, i)) (W_ ℚ n)) Φ -
    ∑ i ∈ Finset.range n, MvPolynomial.C (↑p ^ i) * wittStructureRat p Φ i ^ p ^ (n - i)

full_name: wittStructureRat_rec
code: /-- Write `wittStructureRat p φ n` in terms of `wittStructureRat p φ i` for `i < n`. -/
theorem wittStructureRat_rec (Φ : MvPolynomial idx ℚ) (n : ℕ) :
    wittStructureRat p Φ n =
      C (1 / (p : ℚ) ^ n) *
        (bind₁ (fun b => rename (fun i => (b, i)) (W_ ℚ n)) Φ -
          ∑ i ∈ range n, C ((p : ℚ) ^ i) * wittStructureRat p Φ i ^ p ^ (n - i)) 
goal: wittStructureRat p Φ n =
  MvPolynomial.C (1 / ↑p ^ n) *
    ((MvPolynomial.bind₁ fun b => (MvPolynomial.rename fun i => (b, i)) (W_ ℚ n)) Φ -
      ∑ i ∈ Finset.range n, MvPolynomial.C (↑p ^ i) * wittStructureRat p Φ i ^ p ^ (n - i))

full_name: wittStructureInt
code: /-- `wittStructureInt Φ` is a family of polynomials `ℕ → MvPolynomial (idx × ℕ) ℤ`
that are uniquely characterised by the property that
```
bind₁ (wittStructureInt p Φ) (wittPolynomial p ℤ n) =
bind₁ (fun i ↦ (rename (prod.mk i) (wittPolynomial p ℤ n))) Φ
```
In other words: evaluating the `n`-th Witt polynomial on the family `wittStructureInt Φ`
is the same as evaluating `Φ` on the (appropriately renamed) `n`-th Witt polynomials.

See `wittStructureInt_prop` for this property,
and `wittStructureInt_existsUnique` for the fact that `wittStructureInt`
gives the unique family of polynomials with this property. -/
noncomputable def wittStructureInt (Φ : MvPolynomial idx ℤ) (n : ℕ) : MvPolynomial (idx × ℕ) ℤ 
goal: MvPolynomial (idx × ℕ) ℤ

full_name: bind₁_rename_expand_wittPolynomial
code: theorem bind₁_rename_expand_wittPolynomial (Φ : MvPolynomial idx ℤ) (n : ℕ)
    (IH :
      ∀ m : ℕ,
        m < n + 1 →
          map (Int.castRingHom ℚ) (wittStructureInt p Φ m) =
            wittStructureRat p (map (Int.castRingHom ℚ) Φ) m) :
    bind₁ (fun b => rename (fun i => (b, i)) (expand p (W_ ℤ n))) Φ =
      bind₁ (fun i => expand p (wittStructureInt p Φ i)) (W_ ℤ n) 
goal: (MvPolynomial.bind₁ fun b => (MvPolynomial.rename fun i => (b, i)) ((MvPolynomial.expand p) (W_ ℤ n))) Φ =
  (MvPolynomial.bind₁ fun i => (MvPolynomial.expand p) (wittStructureInt p Φ i)) (W_ ℤ n)

full_name: C_p_pow_dvd_bind₁_rename_wittPolynomial_sub_sum
code: theorem C_p_pow_dvd_bind₁_rename_wittPolynomial_sub_sum (Φ : MvPolynomial idx ℤ) (n : ℕ)
    (IH :
      ∀ m : ℕ,
        m < n →
          map (Int.castRingHom ℚ) (wittStructureInt p Φ m) =
            wittStructureRat p (map (Int.castRingHom ℚ) Φ) m) :
    (C ((p ^ n :) : ℤ) : MvPolynomial (idx × ℕ) ℤ) ∣
      bind₁ (fun b : idx => rename (fun i => (b, i)) (wittPolynomial p ℤ n)) Φ -
        ∑ i ∈ range n, C ((p : ℤ) ^ i) * wittStructureInt p Φ i ^ p ^ (n - i) 
goal: MvPolynomial.C ↑(p ^ n) ∣
  (MvPolynomial.bind₁ fun b => (MvPolynomial.rename fun i => (b, i)) (W_ ℤ n)) Φ -
    ∑ i ∈ Finset.range n, MvPolynomial.C (↑p ^ i) * wittStructureInt p Φ i ^ p ^ (n - i)

full_name: map_wittStructureInt
code: @[simp]
theorem map_wittStructureInt (Φ : MvPolynomial idx ℤ) (n : ℕ) :
    map (Int.castRingHom ℚ) (wittStructureInt p Φ n) =
      wittStructureRat p (map (Int.castRingHom ℚ) Φ) n 
goal: (MvPolynomial.map (Int.castRingHom ℚ)) (wittStructureInt p Φ n) =
  wittStructureRat p ((MvPolynomial.map (Int.castRingHom ℚ)) Φ) n

full_name: wittStructureInt_prop
code: theorem wittStructureInt_prop (Φ : MvPolynomial idx ℤ) (n) :
    bind₁ (wittStructureInt p Φ) (wittPolynomial p ℤ n) =
      bind₁ (fun i => rename (Prod.mk i) (W_ ℤ n)) Φ 
goal: (MvPolynomial.bind₁ (wittStructureInt p Φ)) (W_ ℤ n) =
  (MvPolynomial.bind₁ fun i => (MvPolynomial.rename (Prod.mk i)) (W_ ℤ n)) Φ

full_name: eq_wittStructureInt
code: theorem eq_wittStructureInt (Φ : MvPolynomial idx ℤ) (φ : ℕ → MvPolynomial (idx × ℕ) ℤ)
    (h : ∀ n, bind₁ φ (wittPolynomial p ℤ n) = bind₁ (fun i => rename (Prod.mk i) (W_ ℤ n)) Φ) :
    φ = wittStructureInt p Φ 
goal: φ = wittStructureInt p Φ

full_name: wittStructureInt_existsUnique
code: theorem wittStructureInt_existsUnique (Φ : MvPolynomial idx ℤ) :
    ∃! φ : ℕ → MvPolynomial (idx × ℕ) ℤ,
      ∀ n : ℕ,
        bind₁ φ (wittPolynomial p ℤ n) = bind₁ (fun i : idx => rename (Prod.mk i) (W_ ℤ n)) Φ 
goal: ∃! φ,
  ∀ (n : ℕ),
    (MvPolynomial.bind₁ φ) (W_ ℤ n) = (MvPolynomial.bind₁ fun i => (MvPolynomial.rename (Prod.mk i)) (W_ ℤ n)) Φ

full_name: witt_structure_prop
code: theorem witt_structure_prop (Φ : MvPolynomial idx ℤ) (n) :
    aeval (fun i => map (Int.castRingHom R) (wittStructureInt p Φ i)) (wittPolynomial p ℤ n) =
      aeval (fun i => rename (Prod.mk i) (W n)) Φ 
goal: (MvPolynomial.aeval fun i => (MvPolynomial.map (Int.castRingHom R)) (wittStructureInt p Φ i)) (W_ ℤ n) =
  (MvPolynomial.aeval fun i => (MvPolynomial.rename (Prod.mk i)) (W_ R n)) Φ

full_name: wittStructureInt_rename
code: theorem wittStructureInt_rename {σ : Type*} (Φ : MvPolynomial idx ℤ) (f : idx → σ) (n : ℕ) :
    wittStructureInt p (rename f Φ) n = rename (Prod.map f id) (wittStructureInt p Φ n) 
goal: wittStructureInt p ((MvPolynomial.rename f) Φ) n = (MvPolynomial.rename (Prod.map f id)) (wittStructureInt p Φ n)

full_name: constantCoeff_wittStructureRat_zero
code: @[simp]
theorem constantCoeff_wittStructureRat_zero (Φ : MvPolynomial idx ℚ) :
    constantCoeff (wittStructureRat p Φ 0) = constantCoeff Φ 
goal: MvPolynomial.constantCoeff (wittStructureRat p Φ 0) = MvPolynomial.constantCoeff Φ

full_name: constantCoeff_wittStructureRat
code: theorem constantCoeff_wittStructureRat (Φ : MvPolynomial idx ℚ) (h : constantCoeff Φ = 0) (n : ℕ) :
    constantCoeff (wittStructureRat p Φ n) = 0 
goal: MvPolynomial.constantCoeff (wittStructureRat p Φ n) = 0

full_name: constantCoeff_wittStructureInt_zero
code: @[simp]
theorem constantCoeff_wittStructureInt_zero (Φ : MvPolynomial idx ℤ) :
    constantCoeff (wittStructureInt p Φ 0) = constantCoeff Φ 
goal: MvPolynomial.constantCoeff (wittStructureInt p Φ 0) = MvPolynomial.constantCoeff Φ

full_name: constantCoeff_wittStructureInt
code: theorem constantCoeff_wittStructureInt (Φ : MvPolynomial idx ℤ) (h : constantCoeff Φ = 0) (n : ℕ) :
    constantCoeff (wittStructureInt p Φ n) = 0 
goal: MvPolynomial.constantCoeff (wittStructureInt p Φ n) = 0

full_name: wittStructureRat_vars
code: theorem wittStructureRat_vars [Fintype idx] (Φ : MvPolynomial idx ℚ) (n : ℕ) :
    (wittStructureRat p Φ n).vars ⊆ Finset.univ ×ˢ Finset.range (n + 1) 
goal: (wittStructureRat p Φ n).vars ⊆ Finset.univ ×ˢ Finset.range (n + 1)

full_name: wittStructureInt_vars
code: theorem wittStructureInt_vars [Fintype idx] (Φ : MvPolynomial idx ℤ) (n : ℕ) :
    (wittStructureInt p Φ n).vars ⊆ Finset.univ ×ˢ Finset.range (n + 1) 
goal: (wittStructureInt p Φ n).vars ⊆ Finset.univ ×ˢ Finset.range (n + 1)