/-- If `R` has characteristic `p`, then there is a ring endomorphism
that raises `r : R` to the power `p`.
By applying `WittVector.map` to this endomorphism,
we obtain a ring endomorphism `frobenius R p : 𝕎 R →+* 𝕎 R`.

The underlying function of this morphism is `WittVector.frobeniusFun`.
-/
def frobenius : 𝕎 R →+* 𝕎 R where
  toFun := frobeniusFun
  map_zero' := by
    -- Porting note: removing the placeholders give an error
    refine IsPoly.ext (@IsPoly.comp p _ _ (frobeniusFun_isPoly p) WittVector.zeroIsPoly)
      (@IsPoly.comp p _ _ WittVector.zeroIsPoly
      (frobeniusFun_isPoly p)) ?_ _ 0
    simp only [Function.comp_apply, map_zero, forall_const]
    ghost_simp
  map_one' := by
    refine
      -- Porting note: removing the placeholders give an error
      IsPoly.ext (@IsPoly.comp p _ _ (frobeniusFun_isPoly p) WittVector.oneIsPoly)
        (@IsPoly.comp p _ _ WittVector.oneIsPoly (frobeniusFun_isPoly p)) ?_ _ 0
    simp only [Function.comp_apply, map_one, forall_const]
    ghost_simp
  map_add' := by ghost_calc _ _; 

Proof state:
case refine_3
p : ℕ
S : Type u_2
hp : Fact (Nat.Prime p)
inst✝ : CommRing S
R : Type u_1
R._inst : CommRing R
x✝ y✝ : 𝕎 R
⊢ ∀ (n : ℕ),
    (ghostComponent n)
        (OneHom.toFun
          (↑{
              toOneHom :=
                { toFun := frobeniusFun,
                  map_one' := (_ : (frobeniusFun ∘ fun x => 1) 0 = ((fun x => 1) ∘ frobeniusFun) 0) },
              map_mul' :=
                (_ :
                  ∀ (x y : 𝕎 R),
                    OneHom.toFun
                        { toFun := frobeniusFun,
                          map_one' := (_ : (frobeniusFun ∘ fun x => 1) 0 = ((fun x => 1) ∘ frobeniusFun) 0) }
                        (x * y) =
                      OneHom.toFun
                          { toFun := frobeniusFun,
                            map_one' := (_ : (frobeniusFun ∘ fun x => 1) 0 = ((fun x => 1) ∘ frobeniusFun) 0) }
                          x *
                        OneHom.toFun
                          { toFun := frobeniusFun,
                            map_one' := (_ : (frobeniusFun ∘ fun x => 1) 0 = ((fun x => 1) ∘ frobeniusFun) 0) }
                          y) })
          (x✝ + y✝)) =
      (ghostComponent n)
        (OneHom.toFun
            (↑{
                toOneHom :=
                  { toFun := frobeniusFun,
                    map_one' := (_ : (frobeniusFun ∘ fun x => 1) 0 = ((fun x => 1) ∘ frobeniusFun) 0) },
                map_mul' :=
                  (_ :
                    ∀ (x y : 𝕎 R),
                      OneHom.toFun
                          { toFun := frobeniusFun,
                            map_one' := (_ : (frobeniusFun ∘ fun x => 1) 0 = ((fun x => 1) ∘ frobeniusFun) 0) }
                          (x * y) =
                        OneHom.toFun
                            { toFun := frobeniusFun,
                              map_one' := (_ : (frobeniusFun ∘ fun x => 1) 0 = ((fun x => 1) ∘ frobeniusFun) 0) }
                            x *
                          OneHom.toFun
                            { toFun := frobeniusFun,
                              map_one' := (_ : (frobeniusFun ∘ fun x => 1) 0 = ((fun x => 1) ∘ frobeniusFun) 0) }
                            y) })
            x✝ +
          OneHom.toFun
            (↑{
                toOneHom :=
                  { toFun := frobeniusFun,
                    map_one' := (_ : (frobeniusFun ∘ fun x => 1) 0 = ((fun x => 1) ∘ frobeniusFun) 0) },
                map_mul' :=
                  (_ :
                    ∀ (x y : 𝕎 R),
                      OneHom.toFun
                          { toFun := frobeniusFun,
                            map_one' := (_ : (frobeniusFun ∘ fun x => 1) 0 = ((fun x => 1) ∘ frobeniusFun) 0) }
                          (x * y) =
                        OneHom.toFun
                            { toFun := frobeniusFun,
                              map_one' := (_ : (frobeniusFun ∘ fun x => 1) 0 = ((fun x => 1) ∘ frobeniusFun) 0) }
                            x *
                          OneHom.toFun
                            { toFun := frobeniusFun,
                              map_one' := (_ : (frobeniusFun ∘ fun x => 1) 0 = ((fun x => 1) ∘ frobeniusFun) 0) }
                            y) })
            y✝)

Next tactic:
ghost_simp