l3lab/ntp-mathlib huggingface dataset:
/-- If two `MonoidHom`s agree on `-1` and the naturals then they are equal. -/
@[ext]
theorem ext_int {f g : ℤ →* M} (h_neg_one : f (-1) = g (-1))
    (h_nat : f.comp Int.ofNatHom.toMonoidHom = g.comp Int.ofNatHom.toMonoidHom) : f = g := by
  ext (x | x)
  · exact (FunLike.congr_fun h_nat x : _)
  · 

Proof state:
case h.negSucc
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
M : Type u_5
inst✝ : Monoid M
f g : ℤ →* M
h_neg_one : f (-1) = g (-1)
h_nat : comp f ↑ofNatHom = comp g ↑ofNatHom
x : ℕ
⊢ f -[x+1] = g -[x+1]

Next tactic:
rw [Int.negSucc_eq, ← neg_one_mul, f.map_mul, g.map_mul]
/-- If two `MonoidHom`s agree on `-1` and the naturals then they are equal. -/
@[ext]
theorem ext_int {f g : ℤ →* M} (h_neg_one : f (-1) = g (-1))
    (h_nat : f.comp Int.ofNatHom.toMonoidHom = g.comp Int.ofNatHom.toMonoidHom) : f = g := by
  ext (x | x)
  · exact (FunLike.congr_fun h_nat x : _)
  · rw [Int.negSucc_eq, ← neg_one_mul, f.map_mul, g.map_mul]
    

Proof state:
case h.negSucc
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
M : Type u_5
inst✝ : Monoid M
f g : ℤ →* M
h_neg_one : f (-1) = g (-1)
h_nat : comp f ↑ofNatHom = comp g ↑ofNatHom
x : ℕ
⊢ f (-1) * f (↑x + 1) = g (-1) * g (↑x + 1)

Next tactic:
congr 1
/-- If two `MonoidHom`s agree on `-1` and the naturals then they are equal. -/
@[ext]
theorem ext_int {f g : ℤ →* M} (h_neg_one : f (-1) = g (-1))
    (h_nat : f.comp Int.ofNatHom.toMonoidHom = g.comp Int.ofNatHom.toMonoidHom) : f = g := by
  ext (x | x)
  · exact (FunLike.congr_fun h_nat x : _)
  · rw [Int.negSucc_eq, ← neg_one_mul, f.map_mul, g.map_mul]
    congr 1
    

Proof state:
case h.negSucc.e_a
F : Type u_1
ι : Type u_2
α : Type u_3
β : Type u_4
M : Type u_5
inst✝ : Monoid M
f g : ℤ →* M
h_neg_one : f (-1) = g (-1)
h_nat : comp f ↑ofNatHom = comp g ↑ofNatHom
x : ℕ
⊢ f (↑x + 1) = g (↑x + 1)

Next tactic:
exact mod_cast (FunLike.congr_fun h_nat (x + 1) : _)
/-- The perfection of a ring `R` with characteristic `p`, as a subring,
defined to be the projective limit of `R` using the Frobenius maps `R → R`
indexed by the natural numbers, implemented as `{ f : ℕ → R | ∀ n, f (n + 1) ^ p = f n }`. -/
def Ring.perfectionSubring (R : Type u₁) [CommRing R] (p : ℕ) [hp : Fact p.Prime] [CharP R p] :
    Subring (ℕ → R) :=
  (Ring.perfectionSubsemiring R p).toSubring fun n => by
    

Proof state:
R : Type u₁
inst✝¹ : CommRing R
p : ℕ
hp : Fact (Nat.Prime p)
inst✝ : CharP R p
n : ℕ
⊢ (-1) (n + 1) ^ p = (-1) n

Next tactic:
simp_rw [← frobenius_def, Pi.neg_apply, Pi.one_apply, RingHom.map_neg, RingHom.map_one]
theorem coeff_pow_p (f : Ring.Perfection R p) (n : ℕ) : coeff R p (n + 1) (f ^ p) = coeff R p n f :=
  by 

Proof state:
R : Type u₁
inst✝¹ : CommSemiring R
p : ℕ
hp : Fact (Nat.Prime p)
inst✝ : CharP R p
f : Ring.Perfection R p
n : ℕ
⊢ (coeff R p (n + 1)) (f ^ p) = (coeff R p n) f

Next tactic:
rw [RingHom.map_pow]
theorem coeff_pow_p (f : Ring.Perfection R p) (n : ℕ) : coeff R p (n + 1) (f ^ p) = coeff R p n f :=
  by rw [RingHom.map_pow]; 

Proof state:
R : Type u₁
inst✝¹ : CommSemiring R
p : ℕ
hp : Fact (Nat.Prime p)
inst✝ : CharP R p
f : Ring.Perfection R p
n : ℕ
⊢ (coeff R p (n + 1)) f ^ p = (coeff R p n) f

Next tactic:
exact f.2 n
theorem coeff_frobenius (f : Ring.Perfection R p) (n : ℕ) :
    coeff R p (n + 1) (frobenius _ p f) = coeff R p n f := by 

Proof state:
R : Type u₁
inst✝¹ : CommSemiring R
p : ℕ
hp : Fact (Nat.Prime p)
inst✝ : CharP R p
f : Ring.Perfection R p
n : ℕ
⊢ (coeff R p (n + 1)) ((frobenius (Ring.Perfection R p) p) f) = (coeff R p n) f

Next tactic:
apply coeff_pow_p f n
theorem coeff_iterate_frobenius (f : Ring.Perfection R p) (n m : ℕ) :
    coeff R p (n + m) ((frobenius _ p)^[m] f) = coeff R p n f :=
  Nat.recOn m rfl fun m ih => by 

Proof state:
R : Type u₁
inst✝¹ : CommSemiring R
p : ℕ
hp : Fact (Nat.Prime p)
inst✝ : CharP R p
f : Ring.Perfection R p
n m✝ m : ℕ
ih : (coeff R p (n + m)) ((⇑(frobenius (Ring.Perfection R p) p))^[m] f) = (coeff R p n) f
⊢ (coeff R p (n + Nat.succ m)) ((⇑(frobenius (Ring.Perfection R p) p))^[Nat.succ m] f) = (coeff R p n) f

Next tactic:
erw [Function.iterate_succ_apply', coeff_frobenius, ih]
theorem pthRoot_frobenius : (pthRoot R p).comp (frobenius _ p) = RingHom.id _ :=
  RingHom.ext fun x =>
    ext fun n => by 

Proof state:
R : Type u₁
inst✝¹ : CommSemiring R
p : ℕ
hp : Fact (Nat.Prime p)
inst✝ : CharP R p
x : Ring.Perfection R p
n : ℕ
⊢ (coeff R p n) ((RingHom.comp (pthRoot R p) (frobenius (Ring.Perfection R p) p)) x) =
    (coeff R p n) ((RingHom.id (Ring.Perfection R p)) x)

Next tactic:
rw [RingHom.comp_apply, RingHom.id_apply, coeff_pthRoot, coeff_frobenius]
theorem frobenius_pthRoot : (frobenius _ p).comp (pthRoot R p) = RingHom.id _ :=
  RingHom.ext fun x =>
    ext fun n => by
      

Proof state:
R : Type u₁
inst✝¹ : CommSemiring R
p : ℕ
hp : Fact (Nat.Prime p)
inst✝ : CharP R p
x : Ring.Perfection R p
n : ℕ
⊢ (coeff R p n) ((RingHom.comp (frobenius (Ring.Perfection R p) p) (pthRoot R p)) x) =
    (coeff R p n) ((RingHom.id (Ring.Perfection R p)) x)

Next tactic:
rw [RingHom.comp_apply, RingHom.id_apply, RingHom.map_frobenius, coeff_pthRoot,
        ← @RingHom.map_frobenius (Ring.Perfection R p) _ R, coeff_frobenius]
theorem coeff_add_ne_zero {f : Ring.Perfection R p} {n : ℕ} (hfn : coeff R p n f ≠ 0) (k : ℕ) :
    coeff R p (n + k) f ≠ 0 :=
  Nat.recOn k hfn fun k ih h => ih <| by 

Proof state:
R : Type u₁
inst✝¹ : CommSemiring R
p : ℕ
hp : Fact (Nat.Prime p)
inst✝ : CharP R p
f : Ring.Perfection R p
n : ℕ
hfn : (coeff R p n) f ≠ 0
k✝ k : ℕ
ih : (coeff R p (n + k)) f ≠ 0
h : (coeff R p (n + Nat.succ k)) f = 0
⊢ (coeff R p (n + k)) f = 0

Next tactic:
erw [← coeff_pow_p, RingHom.map_pow, h, zero_pow hp.1.pos]
/-- Given rings `R` and `S` of characteristic `p`, with `R` being perfect,
any homomorphism `R →+* S` can be lifted to a homomorphism `R →+* Perfection S p`. -/
@[simps]
noncomputable def lift (R : Type u₁) [CommSemiring R] [CharP R p] [PerfectRing R p]
    (S : Type u₂) [CommSemiring S] [CharP S p] : (R →+* S) ≃ (R →+* Ring.Perfection S p) where
  toFun f :=
    { toFun := fun r => ⟨fun n => f (((frobeniusEquiv R p).symm : R →+* R)^[n] r),
        fun n => by 

Proof state:
R✝ : Type u₁
inst✝⁶ : CommSemiring R✝
p : ℕ
hp : Fact (Nat.Prime p)
inst✝⁵ : CharP R✝ p
R : Type u₁
inst✝⁴ : CommSemiring R
inst✝³ : CharP R p
inst✝² : PerfectRing R p
S : Type u₂
inst✝¹ : CommSemiring S
inst✝ : CharP S p
f : R →+* S
r : R
n : ℕ
⊢ (fun n => f ((⇑↑(RingEquiv.symm (frobeniusEquiv R p)))^[n] r)) (n + 1) ^ p =
    (fun n => f ((⇑↑(RingEquiv.symm (frobeniusEquiv R p)))^[n] r)) n

Next tactic:
erw [← f.map_pow, Function.iterate_succ_apply', frobeniusEquiv_symm_pow_p]
/-- Given rings `R` and `S` of characteristic `p`, with `R` being perfect,
any homomorphism `R →+* S` can be lifted to a homomorphism `R →+* Perfection S p`. -/
@[simps]
noncomputable def lift (R : Type u₁) [CommSemiring R] [CharP R p] [PerfectRing R p]
    (S : Type u₂) [CommSemiring S] [CharP S p] : (R →+* S) ≃ (R →+* Ring.Perfection S p) where
  toFun f :=
    { toFun := fun r => ⟨fun n => f (((frobeniusEquiv R p).symm : R →+* R)^[n] r),
        fun n => by erw [← f.map_pow, Function.iterate_succ_apply', frobeniusEquiv_symm_pow_p]⟩
      map_one' := ext fun n => (congr_arg f <| RingHom.iterate_map_one _ _).trans f.map_one
      map_mul' := fun x y =>
        ext fun n => (congr_arg f <| iterate_map_mul _ _ _ _).trans <| f.map_mul _ _
      map_zero' := ext fun n => (congr_arg f <| RingHom.iterate_map_zero _ _).trans f.map_zero
      map_add' := fun x y =>
        ext fun n => (congr_arg f <| iterate_map_add _ _ _ _).trans <| f.map_add _ _ }
  invFun := RingHom.comp <| coeff S p 0
  left_inv f := RingHom.ext fun r => rfl
  right_inv f := RingHom.ext fun r => ext fun n =>
    show coeff S p 0 (f (((frobeniusEquiv R p).symm)^[n] r)) = coeff S p n (f r) by
      

Proof state:
R✝ : Type u₁
inst✝⁶ : CommSemiring R✝
p : ℕ
hp : Fact (Nat.Prime p)
inst✝⁵ : CharP R✝ p
R : Type u₁
inst✝⁴ : CommSemiring R
inst✝³ : CharP R p
inst✝² : PerfectRing R p
S : Type u₂
inst✝¹ : CommSemiring S
inst✝ : CharP S p
f : R →+* Ring.Perfection S p
r : R
n : ℕ
⊢ (coeff S p 0) (f ((⇑(RingEquiv.symm (frobeniusEquiv R p)))^[n] r)) = (coeff S p n) (f r)

Next tactic:
rw [← coeff_iterate_frobenius _ 0 n, zero_add, ← RingHom.map_iterate_frobenius,
        Function.RightInverse.iterate (frobenius_apply_frobeniusEquiv_symm R p) n]
/-- A ring homomorphism `R →+* S` induces `Perfection R p →+* Perfection S p`. -/
@[simps]
def map (φ : R →+* S) : Ring.Perfection R p →+* Ring.Perfection S p where
  toFun f := ⟨fun n => φ (coeff R p n f), fun n => by 

Proof state:
R : Type u₁
inst✝³ : CommSemiring R
p : ℕ
hp : Fact (Nat.Prime p)
inst✝² : CharP R p
S : Type u₂
inst✝¹ : CommSemiring S
inst✝ : CharP S p
φ : R →+* S
f : Ring.Perfection R p
n : ℕ
⊢ (fun n => φ ((coeff R p n) f)) (n + 1) ^ p = (fun n => φ ((coeff R p n) f)) n

Next tactic:
rw [← φ.map_pow, coeff_pow_p']
/-- Create a `PerfectionMap` from an isomorphism to the perfection. -/
@[simps]
theorem mk' {f : P →+* R} (g : P ≃+* Ring.Perfection R p) (hfg : Perfection.lift p P R f = g) :
    PerfectionMap p f :=
  { injective := fun x y hxy =>
      g.injective <|
        (RingHom.ext_iff.1 hfg x).symm.trans <|
          Eq.symm <| (RingHom.ext_iff.1 hfg y).symm.trans <| Perfection.ext fun n => (hxy n).symm
    surjective := fun y hy =>
      let ⟨x, hx⟩ := g.surjective ⟨y, hy⟩
      ⟨x, fun n =>
        show Perfection.coeff R p n (Perfection.lift p P R f x) = Perfection.coeff R p n ⟨y, hy⟩ by
          

Proof state:
p : ℕ
inst✝⁵ : Fact (Nat.Prime p)
R : Type u₁
inst✝⁴ : CommSemiring R
inst✝³ : CharP R p
P : Type u₃
inst✝² : CommSemiring P
inst✝¹ : CharP P p
inst✝ : PerfectRing P p
f : P →+* R
g : P ≃+* Ring.Perfection R p
hfg : (Perfection.lift p P R) f = ↑g
y : ℕ → R
hy : ∀ (n : ℕ), y (n + 1) ^ p = y n
x : P
hx : g x = { val := y, property := hy }
n : ℕ
⊢ (Perfection.coeff R p n) (((Perfection.lift p P R) f) x) = (Perfection.coeff R p n) { val := y, property := hy }

Next tactic:
simp [hfg, hx]
/-- For a perfect ring, it itself is the perfection. -/
theorem id [PerfectRing R p] : PerfectionMap p (RingHom.id R) :=
  { injective := fun x y hxy => hxy 0
    surjective := fun f hf =>
      ⟨f 0, fun n =>
        show ((frobeniusEquiv R p).symm)^[n] (f 0) = f n from
          Nat.recOn n rfl fun n ih => injective_pow_p R p <| by
            

Proof state:
p : ℕ
inst✝⁶ : Fact (Nat.Prime p)
R : Type u₁
inst✝⁵ : CommSemiring R
inst✝⁴ : CharP R p
P : Type u₃
inst✝³ : CommSemiring P
inst✝² : CharP P p
inst✝¹ : PerfectRing P p
inst✝ : PerfectRing R p
f : ℕ → R
hf : ∀ (n : ℕ), f (n + 1) ^ p = f n
n✝ n : ℕ
ih : (⇑(RingEquiv.symm (frobeniusEquiv R p)))^[n] (f 0) = f n
⊢ (⇑(RingEquiv.symm (frobeniusEquiv R p)))^[Nat.succ n] (f 0) ^ p = f (Nat.succ n) ^ p

Next tactic:
rw [Function.iterate_succ_apply', frobeniusEquiv_symm_pow_p, ih, hf]
/-- Given rings `R` and `S` of characteristic `p`, with `R` being perfect,
any homomorphism `R →+* S` can be lifted to a homomorphism `R →+* P`,
where `P` is any perfection of `S`. -/
@[simps]
noncomputable def lift [PerfectRing R p] (S : Type u₂) [CommSemiring S] [CharP S p] (P : Type u₃)
    [CommSemiring P] [CharP P p] [PerfectRing P p] (π : P →+* S) (m : PerfectionMap p π) :
    (R →+* S) ≃ (R →+* P) where
  toFun f := RingHom.comp ↑m.equiv.symm <| Perfection.lift p R S f
  invFun f := π.comp f
  left_inv f := by
    

Proof state:
p : ℕ
inst✝¹¹ : Fact (Nat.Prime p)
R : Type u₁
inst✝¹⁰ : CommSemiring R
inst✝⁹ : CharP R p
P✝ : Type u₃
inst✝⁸ : CommSemiring P✝
inst✝⁷ : CharP P✝ p
inst✝⁶ : PerfectRing P✝ p
inst✝⁵ : PerfectRing R p
S : Type u₂
inst✝⁴ : CommSemiring S
inst✝³ : CharP S p
P : Type u₃
inst✝² : CommSemiring P
inst✝¹ : CharP P p
inst✝ : PerfectRing P p
π : P →+* S
m : PerfectionMap p π
f : R →+* S
⊢ (fun f => RingHom.comp π f) ((fun f => RingHom.comp (↑(RingEquiv.symm (equiv m))) ((Perfection.lift p R S) f)) f) = f

Next tactic:
simp_rw [← RingHom.comp_assoc, comp_symm_equiv']
/-- Given rings `R` and `S` of characteristic `p`, with `R` being perfect,
any homomorphism `R →+* S` can be lifted to a homomorphism `R →+* P`,
where `P` is any perfection of `S`. -/
@[simps]
noncomputable def lift [PerfectRing R p] (S : Type u₂) [CommSemiring S] [CharP S p] (P : Type u₃)
    [CommSemiring P] [CharP P p] [PerfectRing P p] (π : P →+* S) (m : PerfectionMap p π) :
    (R →+* S) ≃ (R →+* P) where
  toFun f := RingHom.comp ↑m.equiv.symm <| Perfection.lift p R S f
  invFun f := π.comp f
  left_inv f := by
    simp_rw [← RingHom.comp_assoc, comp_symm_equiv']
    

Proof state:
p : ℕ
inst✝¹¹ : Fact (Nat.Prime p)
R : Type u₁
inst✝¹⁰ : CommSemiring R
inst✝⁹ : CharP R p
P✝ : Type u₃
inst✝⁸ : CommSemiring P✝
inst✝⁷ : CharP P✝ p
inst✝⁶ : PerfectRing P✝ p
inst✝⁵ : PerfectRing R p
S : Type u₂
inst✝⁴ : CommSemiring S
inst✝³ : CharP S p
P : Type u₃
inst✝² : CommSemiring P
inst✝¹ : CharP P p
inst✝ : PerfectRing P p
π : P →+* S
m : PerfectionMap p π
f : R →+* S
⊢ RingHom.comp (Perfection.coeff S p 0) ((Perfection.lift p R S) f) = f

Next tactic:
exact (Perfection.lift p R S).symm_apply_apply f
/-- Given rings `R` and `S` of characteristic `p`, with `R` being perfect,
any homomorphism `R →+* S` can be lifted to a homomorphism `R →+* P`,
where `P` is any perfection of `S`. -/
@[simps]
noncomputable def lift [PerfectRing R p] (S : Type u₂) [CommSemiring S] [CharP S p] (P : Type u₃)
    [CommSemiring P] [CharP P p] [PerfectRing P p] (π : P →+* S) (m : PerfectionMap p π) :
    (R →+* S) ≃ (R →+* P) where
  toFun f := RingHom.comp ↑m.equiv.symm <| Perfection.lift p R S f
  invFun f := π.comp f
  left_inv f := by
    simp_rw [← RingHom.comp_assoc, comp_symm_equiv']
    exact (Perfection.lift p R S).symm_apply_apply f
  right_inv f := by
    

Proof state:
p : ℕ
inst✝¹¹ : Fact (Nat.Prime p)
R : Type u₁
inst✝¹⁰ : CommSemiring R
inst✝⁹ : CharP R p
P✝ : Type u₃
inst✝⁸ : CommSemiring P✝
inst✝⁷ : CharP P✝ p
inst✝⁶ : PerfectRing P✝ p
inst✝⁵ : PerfectRing R p
S : Type u₂
inst✝⁴ : CommSemiring S
inst✝³ : CharP S p
P : Type u₃
inst✝² : CommSemiring P
inst✝¹ : CharP P p
inst✝ : PerfectRing P p
π : P →+* S
m : PerfectionMap p π
f : R →+* P
⊢ (fun f => RingHom.comp (↑(RingEquiv.symm (equiv m))) ((Perfection.lift p R S) f)) ((fun f => RingHom.comp π f) f) = f

Next tactic:
exact RingHom.ext fun x => m.equiv.injective <| (m.equiv.apply_symm_apply _).trans
      <| show Perfection.lift p R S (π.comp f) x = RingHom.comp (↑m.equiv) f x from
        RingHom.ext_iff.1 (by rw [Equiv.apply_eq_iff_eq_symm_apply]; rfl) _
/-- Given rings `R` and `S` of characteristic `p`, with `R` being perfect,
any homomorphism `R →+* S` can be lifted to a homomorphism `R →+* P`,
where `P` is any perfection of `S`. -/
@[simps]
noncomputable def lift [PerfectRing R p] (S : Type u₂) [CommSemiring S] [CharP S p] (P : Type u₃)
    [CommSemiring P] [CharP P p] [PerfectRing P p] (π : P →+* S) (m : PerfectionMap p π) :
    (R →+* S) ≃ (R →+* P) where
  toFun f := RingHom.comp ↑m.equiv.symm <| Perfection.lift p R S f
  invFun f := π.comp f
  left_inv f := by
    simp_rw [← RingHom.comp_assoc, comp_symm_equiv']
    exact (Perfection.lift p R S).symm_apply_apply f
  right_inv f := by
    exact RingHom.ext fun x => m.equiv.injective <| (m.equiv.apply_symm_apply _).trans
      <| show Perfection.lift p R S (π.comp f) x = RingHom.comp (↑m.equiv) f x from
        RingHom.ext_iff.1 (by 

Proof state:
p : ℕ
inst✝¹¹ : Fact (Nat.Prime p)
R : Type u₁
inst✝¹⁰ : CommSemiring R
inst✝⁹ : CharP R p
P✝ : Type u₃
inst✝⁸ : CommSemiring P✝
inst✝⁷ : CharP P✝ p
inst✝⁶ : PerfectRing P✝ p
inst✝⁵ : PerfectRing R p
S : Type u₂
inst✝⁴ : CommSemiring S
inst✝³ : CharP S p
P : Type u₃
inst✝² : CommSemiring P
inst✝¹ : CharP P p
inst✝ : PerfectRing P p
π : P →+* S
m : PerfectionMap p π
f : R →+* P
x : R
⊢ (Perfection.lift p R S) (RingHom.comp π f) = RingHom.comp (↑(equiv m)) f

Next tactic:
rw [Equiv.apply_eq_iff_eq_symm_apply]
/-- Given rings `R` and `S` of characteristic `p`, with `R` being perfect,
any homomorphism `R →+* S` can be lifted to a homomorphism `R →+* P`,
where `P` is any perfection of `S`. -/
@[simps]
noncomputable def lift [PerfectRing R p] (S : Type u₂) [CommSemiring S] [CharP S p] (P : Type u₃)
    [CommSemiring P] [CharP P p] [PerfectRing P p] (π : P →+* S) (m : PerfectionMap p π) :
    (R →+* S) ≃ (R →+* P) where
  toFun f := RingHom.comp ↑m.equiv.symm <| Perfection.lift p R S f
  invFun f := π.comp f
  left_inv f := by
    simp_rw [← RingHom.comp_assoc, comp_symm_equiv']
    exact (Perfection.lift p R S).symm_apply_apply f
  right_inv f := by
    exact RingHom.ext fun x => m.equiv.injective <| (m.equiv.apply_symm_apply _).trans
      <| show Perfection.lift p R S (π.comp f) x = RingHom.comp (↑m.equiv) f x from
        RingHom.ext_iff.1 (by rw [Equiv.apply_eq_iff_eq_symm_apply]; 

Proof state:
p : ℕ
inst✝¹¹ : Fact (Nat.Prime p)
R : Type u₁
inst✝¹⁰ : CommSemiring R
inst✝⁹ : CharP R p
P✝ : Type u₃
inst✝⁸ : CommSemiring P✝
inst✝⁷ : CharP P✝ p
inst✝⁶ : PerfectRing P✝ p
inst✝⁵ : PerfectRing R p
S : Type u₂
inst✝⁴ : CommSemiring S
inst✝³ : CharP S p
P : Type u₃
inst✝² : CommSemiring P
inst✝¹ : CharP P p
inst✝ : PerfectRing P p
π : P →+* S
m : PerfectionMap p π
f : R →+* P
x : R
⊢ RingHom.comp π f = (Perfection.lift p R S).symm (RingHom.comp (↑(equiv m)) f)

Next tactic:
rfl
theorem map_eq_map (φ : R →+* S) : map p (of p R) (of p S) φ = Perfection.map p φ :=
  hom_ext _ (of p S) fun f => by 

Proof state:
p : ℕ
inst✝¹⁰ : Fact (Nat.Prime p)
R : Type u₁
inst✝⁹ : CommSemiring R
inst✝⁸ : CharP R p
P : Type u₃
inst✝⁷ : CommSemiring P
inst✝⁶ : CharP P p
inst✝⁵ : PerfectRing P p
S : Type u₂
inst✝⁴ : CommSemiring S
inst✝³ : CharP S p
Q : Type u₄
inst✝² : CommSemiring Q
inst✝¹ : CharP Q p
inst✝ : PerfectRing Q p
φ : R →+* S
f : Ring.Perfection R p
⊢ (Perfection.coeff S p 0)
      ((map p (_ : PerfectionMap p (Perfection.coeff R p 0)) (_ : PerfectionMap p (Perfection.coeff S p 0)) φ) f) =
    (Perfection.coeff S p 0) ((Perfection.map p φ) f)

Next tactic:
rw [map_map, Perfection.coeff_map]
theorem preVal_mk {x : O} (hx : (Ideal.Quotient.mk _ x : ModP K v O hv p) ≠ 0) :
    preVal K v O hv p (Ideal.Quotient.mk _ x) = v (algebraMap O K x) := by
  

Proof state:
K : Type u₁
inst✝² : Field K
v : Valuation K ℝ≥0
O : Type u₂
inst✝¹ : CommRing O
inst✝ : Algebra O K
hv : Valuation.Integers v O
p : ℕ
hp : Fact (Nat.Prime p)
hvp : Fact (v ↑p ≠ 1)
x : O
hx : (Ideal.Quotient.mk (Ideal.span {↑p})) x ≠ 0
⊢ preVal K v O hv p ((Ideal.Quotient.mk (Ideal.span {↑p})) x) = v ((algebraMap O K) x)

Next tactic:
obtain ⟨r, hr⟩ : ∃ (a : O), a * (p : O) = (Quotient.mk'' x).out' - x :=
    Ideal.mem_span_singleton'.1 <| Ideal.Quotient.eq.1 <| Quotient.sound' <| Quotient.mk_out' _
theorem preVal_mk {x : O} (hx : (Ideal.Quotient.mk _ x : ModP K v O hv p) ≠ 0) :
    preVal K v O hv p (Ideal.Quotient.mk _ x) = v (algebraMap O K x) := by
  obtain ⟨r, hr⟩ : ∃ (a : O), a * (p : O) = (Quotient.mk'' x).out' - x :=
    Ideal.mem_span_singleton'.1 <| Ideal.Quotient.eq.1 <| Quotient.sound' <| Quotient.mk_out' _
  

Proof state:
case intro
K : Type u₁
inst✝² : Field K
v : Valuation K ℝ≥0
O : Type u₂
inst✝¹ : CommRing O
inst✝ : Algebra O K
hv : Valuation.Integers v O
p : ℕ
hp : Fact (Nat.Prime p)
hvp : Fact (v ↑p ≠ 1)
x : O
hx : (Ideal.Quotient.mk (Ideal.span {↑p})) x ≠ 0
r : O
hr : r * ↑p = Quotient.out' (Quotient.mk'' x) - x
⊢ preVal K v O hv p ((Ideal.Quotient.mk (Ideal.span {↑p})) x) = v ((algebraMap O K) x)

Next tactic:
refine' (if_neg hx).trans (v.map_eq_of_sub_lt <| lt_of_not_le _)
theorem preVal_mk {x : O} (hx : (Ideal.Quotient.mk _ x : ModP K v O hv p) ≠ 0) :
    preVal K v O hv p (Ideal.Quotient.mk _ x) = v (algebraMap O K x) := by
  obtain ⟨r, hr⟩ : ∃ (a : O), a * (p : O) = (Quotient.mk'' x).out' - x :=
    Ideal.mem_span_singleton'.1 <| Ideal.Quotient.eq.1 <| Quotient.sound' <| Quotient.mk_out' _
  refine' (if_neg hx).trans (v.map_eq_of_sub_lt <| lt_of_not_le _)
  

Proof state:
case intro
K : Type u₁
inst✝² : Field K
v : Valuation K ℝ≥0
O : Type u₂
inst✝¹ : CommRing O
inst✝ : Algebra O K
hv : Valuation.Integers v O
p : ℕ
hp : Fact (Nat.Prime p)
hvp : Fact (v ↑p ≠ 1)
x : O
hx : (Ideal.Quotient.mk (Ideal.span {↑p})) x ≠ 0
r : O
hr : r * ↑p = Quotient.out' (Quotient.mk'' x) - x
⊢ ¬v ((algebraMap O K) x) ≤
      v ((algebraMap O K) (Quotient.out' ((Ideal.Quotient.mk (Ideal.span {↑p})) x)) - (algebraMap O K) x)

Next tactic:
erw [← RingHom.map_sub, ← hr, hv.le_iff_dvd]
theorem preVal_mk {x : O} (hx : (Ideal.Quotient.mk _ x : ModP K v O hv p) ≠ 0) :
    preVal K v O hv p (Ideal.Quotient.mk _ x) = v (algebraMap O K x) := by
  obtain ⟨r, hr⟩ : ∃ (a : O), a * (p : O) = (Quotient.mk'' x).out' - x :=
    Ideal.mem_span_singleton'.1 <| Ideal.Quotient.eq.1 <| Quotient.sound' <| Quotient.mk_out' _
  refine' (if_neg hx).trans (v.map_eq_of_sub_lt <| lt_of_not_le _)
  erw [← RingHom.map_sub, ← hr, hv.le_iff_dvd]
  

Proof state:
case intro
K : Type u₁
inst✝² : Field K
v : Valuation K ℝ≥0
O : Type u₂
inst✝¹ : CommRing O
inst✝ : Algebra O K
hv : Valuation.Integers v O
p : ℕ
hp : Fact (Nat.Prime p)
hvp : Fact (v ↑p ≠ 1)
x : O
hx : (Ideal.Quotient.mk (Ideal.span {↑p})) x ≠ 0
r : O
hr : r * ↑p = Quotient.out' (Quotient.mk'' x) - x
⊢ ¬r * ↑p ∣ x

Next tactic:
exact fun hprx =>
    hx (Ideal.Quotient.eq_zero_iff_mem.2 <| Ideal.mem_span_singleton.2 <| dvd_of_mul_left_dvd hprx)
theorem preVal_mul {x y : ModP K v O hv p} (hxy0 : x * y ≠ 0) :
    preVal K v O hv p (x * y) = preVal K v O hv p x * preVal K v O hv p y := by
  

Proof state:
K : Type u₁
inst✝² : Field K
v : Valuation K ℝ≥0
O : Type u₂
inst✝¹ : CommRing O
inst✝ : Algebra O K
hv : Valuation.Integers v O
p : ℕ
hp : Fact (Nat.Prime p)
hvp : Fact (v ↑p ≠ 1)
x y : ModP K v O hv p
hxy0 : x * y ≠ 0
⊢ preVal K v O hv p (x * y) = preVal K v O hv p x * preVal K v O hv p y

Next tactic:
have hx0 : x ≠ 0 := mt (by rintro rfl; rw [zero_mul]) hxy0
theorem preVal_mul {x y : ModP K v O hv p} (hxy0 : x * y ≠ 0) :
    preVal K v O hv p (x * y) = preVal K v O hv p x * preVal K v O hv p y := by
  have hx0 : x ≠ 0 := mt (by 

Proof state:
K : Type u₁
inst✝² : Field K
v : Valuation K ℝ≥0
O : Type u₂
inst✝¹ : CommRing O
inst✝ : Algebra O K
hv : Valuation.Integers v O
p : ℕ
hp : Fact (Nat.Prime p)
hvp : Fact (v ↑p ≠ 1)
x y : ModP K v O hv p
hxy0 : x * y ≠ 0
⊢ x = 0 → x * y = 0

Next tactic:
rintro rfl
theorem preVal_mul {x y : ModP K v O hv p} (hxy0 : x * y ≠ 0) :
    preVal K v O hv p (x * y) = preVal K v O hv p x * preVal K v O hv p y := by
  have hx0 : x ≠ 0 := mt (by rintro rfl; 

Proof state:
K : Type u₁
inst✝² : Field K
v : Valuation K ℝ≥0
O : Type u₂
inst✝¹ : CommRing O
inst✝ : Algebra O K
hv : Valuation.Integers v O
p : ℕ
hp : Fact (Nat.Prime p)
hvp : Fact (v ↑p ≠ 1)
y : ModP K v O hv p
hxy0 : 0 * y ≠ 0
⊢ 0 * y = 0

Next tactic:
rw [zero_mul]
theorem preVal_mul {x y : ModP K v O hv p} (hxy0 : x * y ≠ 0) :
    preVal K v O hv p (x * y) = preVal K v O hv p x * preVal K v O hv p y := by
  have hx0 : x ≠ 0 := mt (by rintro rfl; rw [zero_mul]) hxy0
  

Proof state:
K : Type u₁
inst✝² : Field K
v : Valuation K ℝ≥0
O : Type u₂
inst✝¹ : CommRing O
inst✝ : Algebra O K
hv : Valuation.Integers v O
p : ℕ
hp : Fact (Nat.Prime p)
hvp : Fact (v ↑p ≠ 1)
x y : ModP K v O hv p
hxy0 : x * y ≠ 0
hx0 : x ≠ 0
⊢ preVal K v O hv p (x * y) = preVal K v O hv p x * preVal K v O hv p y

Next tactic:
have hy0 : y ≠ 0 := mt (by rintro rfl; rw [mul_zero]) hxy0
theorem preVal_mul {x y : ModP K v O hv p} (hxy0 : x * y ≠ 0) :
    preVal K v O hv p (x * y) = preVal K v O hv p x * preVal K v O hv p y := by
  have hx0 : x ≠ 0 := mt (by rintro rfl; rw [zero_mul]) hxy0
  have hy0 : y ≠ 0 := mt (by 

Proof state:
K : Type u₁
inst✝² : Field K
v : Valuation K ℝ≥0
O : Type u₂
inst✝¹ : CommRing O
inst✝ : Algebra O K
hv : Valuation.Integers v O
p : ℕ
hp : Fact (Nat.Prime p)
hvp : Fact (v ↑p ≠ 1)
x y : ModP K v O hv p
hxy0 : x * y ≠ 0
hx0 : x ≠ 0
⊢ y = 0 → x * y = 0

Next tactic:
rintro rfl
theorem preVal_mul {x y : ModP K v O hv p} (hxy0 : x * y ≠ 0) :
    preVal K v O hv p (x * y) = preVal K v O hv p x * preVal K v O hv p y := by
  have hx0 : x ≠ 0 := mt (by rintro rfl; rw [zero_mul]) hxy0
  have hy0 : y ≠ 0 := mt (by rintro rfl; 

Proof state:
K : Type u₁
inst✝² : Field K
v : Valuation K ℝ≥0
O : Type u₂
inst✝¹ : CommRing O
inst✝ : Algebra O K
hv : Valuation.Integers v O
p : ℕ
hp : Fact (Nat.Prime p)
hvp : Fact (v ↑p ≠ 1)
x : ModP K v O hv p
hx0 : x ≠ 0
hxy0 : x * 0 ≠ 0
⊢ x * 0 = 0

Next tactic:
rw [mul_zero]