/-- Given a field `K` of characteristic `p` and a perfect ring `L` of the same characteristic,
any homomorphism `K →+* L` can be lifted to `PerfectClosure K p`. -/
noncomputable def lift (L : Type v) [CommSemiring L] [CharP L p] [PerfectRing L p] :
    (K →+* L) ≃ (PerfectClosure K p →+* L) where
  toFun f :=
    { toFun := by
        refine' fun e => liftOn e (fun x => (frobeniusEquiv L p).symm^[x.1] (f x.2)) _
        rintro - - ⟨n, x⟩
        simp [f.map_frobenius]
      map_one' := f.map_one
      map_zero' := f.map_zero
      map_mul' := by
        rintro ⟨n, x⟩ ⟨m, y⟩
        simp only [quot_mk_eq_mk, liftOn_mk, f.map_iterate_frobenius, mk_mul_mk, map_mul,
          iterate_map_mul]
        have := LeftInverse.iterate (frobeniusEquiv_symm_apply_frobenius L p)
        rw [iterate_add_apply, this _ _, add_comm, iterate_add_apply, this _ _]
      map_add' := by
        rintro ⟨n, x⟩ ⟨m, y⟩
        simp only [quot_mk_eq_mk, liftOn_mk, f.map_iterate_frobenius, mk_add_mk, map_add,
          iterate_map_add]
        have := LeftInverse.iterate (frobeniusEquiv_symm_apply_frobenius L p)
        rw [iterate_add_apply, this _ _, add_comm n, iterate_add_apply, this _ _] }
  invFun f := f.comp (of K p)
  left_inv f := by ext x; rfl
  right_inv f := by
    ext ⟨n, x⟩
    

Proof state:
case a.mk.mk
K : Type u
inst✝⁵ : Field K
p : ℕ
inst✝⁴ : Fact (Nat.Prime p)
inst✝³ : CharP K p
L : Type v
inst✝² : CommSemiring L
inst✝¹ : CharP L p
inst✝ : PerfectRing L p
f : PerfectClosure K p →+* L
x✝ : PerfectClosure K p
n : ℕ
x : K
⊢ ((fun f =>
          {
            toMonoidHom :=
              {
                toOneHom :=
                  {
                    toFun := fun e =>
                      liftOn e (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                        (_ :
                          ∀ (x y : ℕ × K),
                            R K p x y →
                              (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) x =
                                (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) y),
                    map_one' := (_ : f 1 = 1) },
                map_mul' :=
                  (_ :
                    ∀ (x y : PerfectClosure K p),
                      OneHom.toFun
                          {
                            toFun := fun e =>
                              liftOn e (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                (_ :
                                  ∀ (x y : ℕ × K),
                                    R K p x y →
                                      (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) x =
                                        (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) y),
                            map_one' := (_ : f 1 = 1) }
                          (x * y) =
                        OneHom.toFun
                            {
                              toFun := fun e =>
                                liftOn e (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                  (_ :
                                    ∀ (x y : ℕ × K),
                                      R K p x y →
                                        (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) x =
                                          (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) y),
                              map_one' := (_ : f 1 = 1) }
                            x *
                          OneHom.toFun
                            {
                              toFun := fun e =>
                                liftOn e (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                  (_ :
                                    ∀ (x y : ℕ × K),
                                      R K p x y →
                                        (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) x =
                                          (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) y),
                              map_one' := (_ : f 1 = 1) }
                            y) },
            map_zero' := (_ : f 0 = 0),
            map_add' :=
              (_ :
                ∀ (x y : PerfectClosure K p),
                  OneHom.toFun
                      (↑{
                          toOneHom :=
                            {
                              toFun := fun e =>
                                liftOn e (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                  (_ :
                                    ∀ (x y : ℕ × K),
                                      R K p x y →
                                        (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) x =
                                          (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) y),
                              map_one' := (_ : f 1 = 1) },
                          map_mul' :=
                            (_ :
                              ∀ (x y : PerfectClosure K p),
                                OneHom.toFun
                                    {
                                      toFun := fun e =>
                                        liftOn e (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                          (_ :
                                            ∀ (x y : ℕ × K),
                                              R K p x y →
                                                (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) x =
                                                  (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) y),
                                      map_one' := (_ : f 1 = 1) }
                                    (x * y) =
                                  OneHom.toFun
                                      {
                                        toFun := fun e =>
                                          liftOn e (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                            (_ :
                                              ∀ (x y : ℕ × K),
                                                R K p x y →
                                                  (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) x =
                                                    (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                                      y),
                                        map_one' := (_ : f 1 = 1) }
                                      x *
                                    OneHom.toFun
                                      {
                                        toFun := fun e =>
                                          liftOn e (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                            (_ :
                                              ∀ (x y : ℕ × K),
                                                R K p x y →
                                                  (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) x =
                                                    (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                                      y),
                                        map_one' := (_ : f 1 = 1) }
                                      y) })
                      (x + y) =
                    OneHom.toFun
                        (↑{
                            toOneHom :=
                              {
                                toFun := fun e =>
                                  liftOn e (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                    (_ :
                                      ∀ (x y : ℕ × K),
                                        R K p x y →
                                          (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) x =
                                            (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) y),
                                map_one' := (_ : f 1 = 1) },
                            map_mul' :=
                              (_ :
                                ∀ (x y : PerfectClosure K p),
                                  OneHom.toFun
                                      {
                                        toFun := fun e =>
                                          liftOn e (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                            (_ :
                                              ∀ (x y : ℕ × K),
                                                R K p x y →
                                                  (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) x =
                                                    (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                                      y),
                                        map_one' := (_ : f 1 = 1) }
                                      (x * y) =
                                    OneHom.toFun
                                        {
                                          toFun := fun e =>
                                            liftOn e (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                              (_ :
                                                ∀ (x y : ℕ × K),
                                                  R K p x y →
                                                    (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                                        x =
                                                      (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                                        y),
                                          map_one' := (_ : f 1 = 1) }
                                        x *
                                      OneHom.toFun
                                        {
                                          toFun := fun e =>
                                            liftOn e (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                              (_ :
                                                ∀ (x y : ℕ × K),
                                                  R K p x y →
                                                    (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                                        x =
                                                      (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                                        y),
                                          map_one' := (_ : f 1 = 1) }
                                        y) })
                        x +
                      OneHom.toFun
                        (↑{
                            toOneHom :=
                              {
                                toFun := fun e =>
                                  liftOn e (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                    (_ :
                                      ∀ (x y : ℕ × K),
                                        R K p x y →
                                          (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) x =
                                            (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) y),
                                map_one' := (_ : f 1 = 1) },
                            map_mul' :=
                              (_ :
                                ∀ (x y : PerfectClosure K p),
                                  OneHom.toFun
                                      {
                                        toFun := fun e =>
                                          liftOn e (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                            (_ :
                                              ∀ (x y : ℕ × K),
                                                R K p x y →
                                                  (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2)) x =
                                                    (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                                      y),
                                        map_one' := (_ : f 1 = 1) }
                                      (x * y) =
                                    OneHom.toFun
                                        {
                                          toFun := fun e =>
                                            liftOn e (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                              (_ :
                                                ∀ (x y : ℕ × K),
                                                  R K p x y →
                                                    (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                                        x =
                                                      (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                                        y),
                                          map_one' := (_ : f 1 = 1) }
                                        x *
                                      OneHom.toFun
                                        {
                                          toFun := fun e =>
                                            liftOn e (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                              (_ :
                                                ∀ (x y : ℕ × K),
                                                  R K p x y →
                                                    (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                                        x =
                                                      (fun x => (⇑(RingEquiv.symm (frobeniusEquiv L p)))^[x.1] (f x.2))
                                                        y),
                                          map_one' := (_ : f 1 = 1) }
                                        y) })
                        y) })
        ((fun f => RingHom.comp f (of K p)) f))
      (Quot.mk (R K p) (n, x)) =
    f (Quot.mk (R K p) (n, x))

Next tactic:
simp only [quot_mk_eq_mk, RingHom.comp_apply, RingHom.coe_mk, MonoidHom.coe_mk, OneHom.coe_mk,
      liftOn_mk]