l3lab/ntp-mathlib huggingface dataset:
theorem CharP.exists [NonAssocSemiring R] : ∃ p, CharP R p :=
  letI := Classical.decEq R
  by_cases
    (fun H : ∀ p : ℕ, (p : R) = 0 → p = 0 =>
      ⟨0, ⟨fun x => by rw [zero_dvd_iff]; exact ⟨H x, by rintro rfl; simp⟩⟩⟩)
    fun H =>
    ⟨Nat.find (not_forall.1 H),
      ⟨fun x =>
        ⟨fun H1 =>
          Nat.dvd_of_mod_eq_zero
            (by_contradiction fun H2 =>
              Nat.find_min (not_forall.1 H)
                (Nat.mod_lt x <|
                  Nat.pos_of_ne_zero <| not_of_not_imp <| Nat.find_spec (not_forall.1 H))
                (not_imp_of_and_not
                  ⟨by
                    

Proof state:
R : Type u_1
inst✝ : NonAssocSemiring R
this : DecidableEq R := Classical.decEq R
H : ¬∀ (p : ℕ), ↑p = 0 → p = 0
x : ℕ
H1 : ↑x = 0
H2 : ¬x % Nat.find (_ : ∃ x, ¬(↑x = 0 → x = 0)) = 0
⊢ ↑(x % Nat.find (_ : ∃ x, ¬(↑x = 0 → x = 0))) = 0

Next tactic:
rwa [← Nat.mod_add_div x (Nat.find (not_forall.1 H)), Nat.cast_add,
                      Nat.cast_mul,
                      of_not_not (not_not_of_not_imp <| Nat.find_spec (not_forall.1 H)),
                      zero_mul, add_zero] at H1
theorem CharP.exists [NonAssocSemiring R] : ∃ p, CharP R p :=
  letI := Classical.decEq R
  by_cases
    (fun H : ∀ p : ℕ, (p : R) = 0 → p = 0 =>
      ⟨0, ⟨fun x => by rw [zero_dvd_iff]; exact ⟨H x, by rintro rfl; simp⟩⟩⟩)
    fun H =>
    ⟨Nat.find (not_forall.1 H),
      ⟨fun x =>
        ⟨fun H1 =>
          Nat.dvd_of_mod_eq_zero
            (by_contradiction fun H2 =>
              Nat.find_min (not_forall.1 H)
                (Nat.mod_lt x <|
                  Nat.pos_of_ne_zero <| not_of_not_imp <| Nat.find_spec (not_forall.1 H))
                (not_imp_of_and_not
                  ⟨by
                    rwa [← Nat.mod_add_div x (Nat.find (not_forall.1 H)), Nat.cast_add,
                      Nat.cast_mul,
                      of_not_not (not_not_of_not_imp <| Nat.find_spec (not_forall.1 H)),
                      zero_mul, add_zero] at H1,
                    H2⟩)),
          fun H1 => by
          

Proof state:
R : Type u_1
inst✝ : NonAssocSemiring R
this : DecidableEq R := Classical.decEq R
H : ¬∀ (p : ℕ), ↑p = 0 → p = 0
x : ℕ
H1 : Nat.find (_ : ∃ x, ¬(↑x = 0 → x = 0)) ∣ x
⊢ ↑x = 0

Next tactic:
rw [← Nat.mul_div_cancel' H1, Nat.cast_mul,
            of_not_not (not_not_of_not_imp <| Nat.find_spec (not_forall.1 H)),
            zero_mul]
theorem spec : ∀ x : ℕ, (x : R) = 0 ↔ ringChar R ∣ x := by
  

Proof state:
R : Type u_1
inst✝ : NonAssocSemiring R
⊢ ∀ (x : ℕ), ↑x = 0 ↔ ringChar R ∣ x

Next tactic:
letI : CharP R (ringChar R) := (Classical.choose_spec (CharP.exists_unique R)).1
theorem spec : ∀ x : ℕ, (x : R) = 0 ↔ ringChar R ∣ x := by
  letI : CharP R (ringChar R) := (Classical.choose_spec (CharP.exists_unique R)).1
  

Proof state:
R : Type u_1
inst✝ : NonAssocSemiring R
this : CharP R (ringChar R) := (Classical.choose_spec (CharP.exists_unique R)).left
⊢ ∀ (x : ℕ), ↑x = 0 ↔ ringChar R ∣ x

Next tactic:
exact CharP.cast_eq_zero_iff R (ringChar R)
theorem Nat.cast_ringChar : (ringChar R : R) = 0 := by 

Proof state:
R : Type u_1
inst✝ : NonAssocSemiring R
⊢ ↑(ringChar R) = 0

Next tactic:
rw [ringChar.spec]
theorem add_pow_char_of_commute [Semiring R] {p : ℕ} [hp : Fact p.Prime] [CharP R p] (x y : R)
    (h : Commute x y) : (x + y) ^ p = x ^ p + y ^ p := by
  

Proof state:
R : Type u_1
inst✝¹ : Semiring R
p : ℕ
hp : Fact (Nat.Prime p)
inst✝ : CharP R p
x y : R
h : Commute x y
⊢ (x + y) ^ p = x ^ p + y ^ p

Next tactic:
let ⟨r, hr⟩ := h.exists_add_pow_prime_eq hp.out
theorem add_pow_char_of_commute [Semiring R] {p : ℕ} [hp : Fact p.Prime] [CharP R p] (x y : R)
    (h : Commute x y) : (x + y) ^ p = x ^ p + y ^ p := by
  let ⟨r, hr⟩ := h.exists_add_pow_prime_eq hp.out
  

Proof state:
R : Type u_1
inst✝¹ : Semiring R
p : ℕ
hp : Fact (Nat.Prime p)
inst✝ : CharP R p
x y : R
h : Commute x y
r : R
hr : (x + y) ^ p = x ^ p + y ^ p + ↑p * r
⊢ (x + y) ^ p = x ^ p + y ^ p

Next tactic:
simp [hr]
theorem add_pow_char_pow_of_commute [Semiring R] {p n : ℕ} [hp : Fact p.Prime] [CharP R p]
    (x y : R) (h : Commute x y) : (x + y) ^ p ^ n = x ^ p ^ n + y ^ p ^ n := by
  

Proof state:
R : Type u_1
inst✝¹ : Semiring R
p n : ℕ
hp : Fact (Nat.Prime p)
inst✝ : CharP R p
x y : R
h : Commute x y
⊢ (x + y) ^ p ^ n = x ^ p ^ n + y ^ p ^ n

Next tactic:
let ⟨r, hr⟩ := h.exists_add_pow_prime_pow_eq hp.out n
theorem add_pow_char_pow_of_commute [Semiring R] {p n : ℕ} [hp : Fact p.Prime] [CharP R p]
    (x y : R) (h : Commute x y) : (x + y) ^ p ^ n = x ^ p ^ n + y ^ p ^ n := by
  let ⟨r, hr⟩ := h.exists_add_pow_prime_pow_eq hp.out n
  

Proof state:
R : Type u_1
inst✝¹ : Semiring R
p n : ℕ
hp : Fact (Nat.Prime p)
inst✝ : CharP R p
x y : R
h : Commute x y
r : R
hr : (x + y) ^ p ^ n = x ^ p ^ n + y ^ p ^ n + ↑p * r
⊢ (x + y) ^ p ^ n = x ^ p ^ n + y ^ p ^ n

Next tactic:
simp [hr]
theorem sub_pow_char_of_commute [Ring R] {p : ℕ} [Fact p.Prime] [CharP R p] (x y : R)
    (h : Commute x y) : (x - y) ^ p = x ^ p - y ^ p := by
  

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP R p
x y : R
h : Commute x y
⊢ (x - y) ^ p = x ^ p - y ^ p

Next tactic:
rw [eq_sub_iff_add_eq, ← add_pow_char_of_commute _ _ _ (Commute.sub_left h rfl)]
theorem sub_pow_char_of_commute [Ring R] {p : ℕ} [Fact p.Prime] [CharP R p] (x y : R)
    (h : Commute x y) : (x - y) ^ p = x ^ p - y ^ p := by
  rw [eq_sub_iff_add_eq, ← add_pow_char_of_commute _ _ _ (Commute.sub_left h rfl)]
  

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP R p
x y : R
h : Commute x y
⊢ (x - y + y) ^ p = x ^ p

Next tactic:
simp
theorem sub_pow_char_pow_of_commute [Ring R] {p : ℕ} [Fact p.Prime] [CharP R p] {n : ℕ} (x y : R)
    (h : Commute x y) : (x - y) ^ p ^ n = x ^ p ^ n - y ^ p ^ n := by
  

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP R p
n : ℕ
x y : R
h : Commute x y
⊢ (x - y) ^ p ^ n = x ^ p ^ n - y ^ p ^ n

Next tactic:
induction n with
  | zero => simp
  | succ n n_ih =>
      rw [pow_succ', pow_mul, pow_mul, pow_mul, n_ih]
      apply sub_pow_char_of_commute; apply Commute.pow_pow h
theorem sub_pow_char_pow_of_commute [Ring R] {p : ℕ} [Fact p.Prime] [CharP R p] {n : ℕ} (x y : R)
    (h : Commute x y) : (x - y) ^ p ^ n = x ^ p ^ n - y ^ p ^ n := by
  induction n with
  

Proof state:
case zero
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP R p
x y : R
h : Commute x y
⊢ (x - y) ^ p ^ Nat.zero = x ^ p ^ Nat.zero - y ^ p ^ Nat.zero

Next tactic:
| zero => simp
theorem sub_pow_char_pow_of_commute [Ring R] {p : ℕ} [Fact p.Prime] [CharP R p] {n : ℕ} (x y : R)
    (h : Commute x y) : (x - y) ^ p ^ n = x ^ p ^ n - y ^ p ^ n := by
  induction n with
  | zero => 

Proof state:
case zero
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP R p
x y : R
h : Commute x y
⊢ (x - y) ^ p ^ Nat.zero = x ^ p ^ Nat.zero - y ^ p ^ Nat.zero

Next tactic:
simp
theorem sub_pow_char_pow_of_commute [Ring R] {p : ℕ} [Fact p.Prime] [CharP R p] {n : ℕ} (x y : R)
    (h : Commute x y) : (x - y) ^ p ^ n = x ^ p ^ n - y ^ p ^ n := by
  induction n with
  | zero => simp
  

Proof state:
case succ
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP R p
x y : R
h : Commute x y
n : ℕ
n_ih : (x - y) ^ p ^ n = x ^ p ^ n - y ^ p ^ n
⊢ (x - y) ^ p ^ Nat.succ n = x ^ p ^ Nat.succ n - y ^ p ^ Nat.succ n

Next tactic:
| succ n n_ih =>
      rw [pow_succ', pow_mul, pow_mul, pow_mul, n_ih]
      apply sub_pow_char_of_commute; apply Commute.pow_pow h
theorem sub_pow_char_pow_of_commute [Ring R] {p : ℕ} [Fact p.Prime] [CharP R p] {n : ℕ} (x y : R)
    (h : Commute x y) : (x - y) ^ p ^ n = x ^ p ^ n - y ^ p ^ n := by
  induction n with
  | zero => simp
  | succ n n_ih =>
      

Proof state:
case succ
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP R p
x y : R
h : Commute x y
n : ℕ
n_ih : (x - y) ^ p ^ n = x ^ p ^ n - y ^ p ^ n
⊢ (x - y) ^ p ^ Nat.succ n = x ^ p ^ Nat.succ n - y ^ p ^ Nat.succ n

Next tactic:
rw [pow_succ', pow_mul, pow_mul, pow_mul, n_ih]
theorem sub_pow_char_pow_of_commute [Ring R] {p : ℕ} [Fact p.Prime] [CharP R p] {n : ℕ} (x y : R)
    (h : Commute x y) : (x - y) ^ p ^ n = x ^ p ^ n - y ^ p ^ n := by
  induction n with
  | zero => simp
  | succ n n_ih =>
      rw [pow_succ', pow_mul, pow_mul, pow_mul, n_ih]
      

Proof state:
case succ
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP R p
x y : R
h : Commute x y
n : ℕ
n_ih : (x - y) ^ p ^ n = x ^ p ^ n - y ^ p ^ n
⊢ (x ^ p ^ n - y ^ p ^ n) ^ p = (x ^ p ^ n) ^ p - (y ^ p ^ n) ^ p

Next tactic:
apply sub_pow_char_of_commute
theorem sub_pow_char_pow_of_commute [Ring R] {p : ℕ} [Fact p.Prime] [CharP R p] {n : ℕ} (x y : R)
    (h : Commute x y) : (x - y) ^ p ^ n = x ^ p ^ n - y ^ p ^ n := by
  induction n with
  | zero => simp
  | succ n n_ih =>
      rw [pow_succ', pow_mul, pow_mul, pow_mul, n_ih]
      apply sub_pow_char_of_commute; 

Proof state:
case succ.h
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP R p
x y : R
h : Commute x y
n : ℕ
n_ih : (x - y) ^ p ^ n = x ^ p ^ n - y ^ p ^ n
⊢ Commute (x ^ p ^ n) (y ^ p ^ n)

Next tactic:
apply Commute.pow_pow h
theorem CharP.neg_one_ne_one [Ring R] (p : ℕ) [CharP R p] [Fact (2 < p)] : (-1 : R) ≠ (1 : R) := by
  

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
⊢ -1 ≠ 1

Next tactic:
suffices (2 : R) ≠ 0 by
    intro h
    symm at h
    rw [← sub_eq_zero, sub_neg_eq_add] at h
    norm_num at h
    exact this h
theorem CharP.neg_one_ne_one [Ring R] (p : ℕ) [CharP R p] [Fact (2 < p)] : (-1 : R) ≠ (1 : R) := by
  suffices (2 : R) ≠ 0 by
    

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
this : 2 ≠ 0
⊢ -1 ≠ 1

Next tactic:
intro h
theorem CharP.neg_one_ne_one [Ring R] (p : ℕ) [CharP R p] [Fact (2 < p)] : (-1 : R) ≠ (1 : R) := by
  suffices (2 : R) ≠ 0 by
    intro h
    

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
this : 2 ≠ 0
h : -1 = 1
⊢ False

Next tactic:
symm at h
theorem CharP.neg_one_ne_one [Ring R] (p : ℕ) [CharP R p] [Fact (2 < p)] : (-1 : R) ≠ (1 : R) := by
  suffices (2 : R) ≠ 0 by
    intro h
    symm at h
    

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
this : 2 ≠ 0
h : 1 = -1
⊢ False

Next tactic:
rw [← sub_eq_zero, sub_neg_eq_add] at h
theorem CharP.neg_one_ne_one [Ring R] (p : ℕ) [CharP R p] [Fact (2 < p)] : (-1 : R) ≠ (1 : R) := by
  suffices (2 : R) ≠ 0 by
    intro h
    symm at h
    rw [← sub_eq_zero, sub_neg_eq_add] at h
    

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
this : 2 ≠ 0
h : 1 + 1 = 0
⊢ False

Next tactic:
norm_num at h
theorem CharP.neg_one_ne_one [Ring R] (p : ℕ) [CharP R p] [Fact (2 < p)] : (-1 : R) ≠ (1 : R) := by
  suffices (2 : R) ≠ 0 by
    intro h
    symm at h
    rw [← sub_eq_zero, sub_neg_eq_add] at h
    norm_num at h
    

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
this : 2 ≠ 0
h : 2 = 0
⊢ False

Next tactic:
exact this h
theorem CharP.neg_one_ne_one [Ring R] (p : ℕ) [CharP R p] [Fact (2 < p)] : (-1 : R) ≠ (1 : R) := by
  suffices (2 : R) ≠ 0 by
    intro h
    symm at h
    rw [← sub_eq_zero, sub_neg_eq_add] at h
    norm_num at h
    exact this h
    -- porting note: this could probably be golfed
  

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
⊢ 2 ≠ 0

Next tactic:
intro h
theorem CharP.neg_one_ne_one [Ring R] (p : ℕ) [CharP R p] [Fact (2 < p)] : (-1 : R) ≠ (1 : R) := by
  suffices (2 : R) ≠ 0 by
    intro h
    symm at h
    rw [← sub_eq_zero, sub_neg_eq_add] at h
    norm_num at h
    exact this h
    -- porting note: this could probably be golfed
  intro h
  

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
h : 2 = 0
⊢ False

Next tactic:
rw [show (2 : R) = (2 : ℕ) by norm_cast] at h
theorem CharP.neg_one_ne_one [Ring R] (p : ℕ) [CharP R p] [Fact (2 < p)] : (-1 : R) ≠ (1 : R) := by
  suffices (2 : R) ≠ 0 by
    intro h
    symm at h
    rw [← sub_eq_zero, sub_neg_eq_add] at h
    norm_num at h
    exact this h
    -- porting note: this could probably be golfed
  intro h
  rw [show (2 : R) = (2 : ℕ) by 

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
h : 2 = 0
⊢ 2 = ↑2

Next tactic:
norm_cast
theorem CharP.neg_one_ne_one [Ring R] (p : ℕ) [CharP R p] [Fact (2 < p)] : (-1 : R) ≠ (1 : R) := by
  suffices (2 : R) ≠ 0 by
    intro h
    symm at h
    rw [← sub_eq_zero, sub_neg_eq_add] at h
    norm_num at h
    exact this h
    -- porting note: this could probably be golfed
  intro h
  rw [show (2 : R) = (2 : ℕ) by norm_cast] at h
  

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
h : ↑2 = 0
⊢ False

Next tactic:
have := (CharP.cast_eq_zero_iff R p 2).mp h
theorem CharP.neg_one_ne_one [Ring R] (p : ℕ) [CharP R p] [Fact (2 < p)] : (-1 : R) ≠ (1 : R) := by
  suffices (2 : R) ≠ 0 by
    intro h
    symm at h
    rw [← sub_eq_zero, sub_neg_eq_add] at h
    norm_num at h
    exact this h
    -- porting note: this could probably be golfed
  intro h
  rw [show (2 : R) = (2 : ℕ) by norm_cast] at h
  have := (CharP.cast_eq_zero_iff R p 2).mp h
  

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
h : ↑2 = 0
this : p ∣ 2
⊢ False

Next tactic:
have := Nat.le_of_dvd (by decide) this
theorem CharP.neg_one_ne_one [Ring R] (p : ℕ) [CharP R p] [Fact (2 < p)] : (-1 : R) ≠ (1 : R) := by
  suffices (2 : R) ≠ 0 by
    intro h
    symm at h
    rw [← sub_eq_zero, sub_neg_eq_add] at h
    norm_num at h
    exact this h
    -- porting note: this could probably be golfed
  intro h
  rw [show (2 : R) = (2 : ℕ) by norm_cast] at h
  have := (CharP.cast_eq_zero_iff R p 2).mp h
  have := Nat.le_of_dvd (by 

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
h : ↑2 = 0
this : p ∣ 2
⊢ 0 < 2

Next tactic:
decide
theorem CharP.neg_one_ne_one [Ring R] (p : ℕ) [CharP R p] [Fact (2 < p)] : (-1 : R) ≠ (1 : R) := by
  suffices (2 : R) ≠ 0 by
    intro h
    symm at h
    rw [← sub_eq_zero, sub_neg_eq_add] at h
    norm_num at h
    exact this h
    -- porting note: this could probably be golfed
  intro h
  rw [show (2 : R) = (2 : ℕ) by norm_cast] at h
  have := (CharP.cast_eq_zero_iff R p 2).mp h
  have := Nat.le_of_dvd (by decide) this
  

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
h : ↑2 = 0
this✝ : p ∣ 2
this : p ≤ 2
⊢ False

Next tactic:
rw [fact_iff] at *
theorem CharP.neg_one_ne_one [Ring R] (p : ℕ) [CharP R p] [Fact (2 < p)] : (-1 : R) ≠ (1 : R) := by
  suffices (2 : R) ≠ 0 by
    intro h
    symm at h
    rw [← sub_eq_zero, sub_neg_eq_add] at h
    norm_num at h
    exact this h
    -- porting note: this could probably be golfed
  intro h
  rw [show (2 : R) = (2 : ℕ) by norm_cast] at h
  have := (CharP.cast_eq_zero_iff R p 2).mp h
  have := Nat.le_of_dvd (by decide) this
  rw [fact_iff] at *
  

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : 2 < p
h : ↑2 = 0
this✝ : p ∣ 2
this : p ≤ 2
⊢ False

Next tactic:
linarith
theorem CharP.neg_one_pow_char [Ring R] (p : ℕ) [CharP R p] [Fact p.Prime] :
    (-1 : R) ^ p = -1 := by
  

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (Nat.Prime p)
⊢ (-1) ^ p = -1

Next tactic:
rw [eq_neg_iff_add_eq_zero]
theorem CharP.neg_one_pow_char [Ring R] (p : ℕ) [CharP R p] [Fact p.Prime] :
    (-1 : R) ^ p = -1 := by
  rw [eq_neg_iff_add_eq_zero]
  

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (Nat.Prime p)
⊢ (-1) ^ p + 1 = 0

Next tactic:
nth_rw 2 [← one_pow p]
theorem CharP.neg_one_pow_char [Ring R] (p : ℕ) [CharP R p] [Fact p.Prime] :
    (-1 : R) ^ p = -1 := by
  rw [eq_neg_iff_add_eq_zero]
  nth_rw 2 [← one_pow p]
  

Proof state:
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (Nat.Prime p)
⊢ (-1) ^ p + 1 ^ p = 0

Next tactic:
rw [← add_pow_char_of_commute R _ _ (Commute.one_right _), add_left_neg,
    zero_pow (Fact.out (p := Nat.Prime p)).pos]
theorem CharP.neg_one_pow_char_pow [Ring R] (p n : ℕ) [CharP R p] [Fact p.Prime] :
    (-1 : R) ^ p ^ n = -1 := by
  

Proof state:
R : Type u_1
inst✝² : Ring R
p n : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (Nat.Prime p)
⊢ (-1) ^ p ^ n = -1

Next tactic:
rw [eq_neg_iff_add_eq_zero]
theorem CharP.neg_one_pow_char_pow [Ring R] (p n : ℕ) [CharP R p] [Fact p.Prime] :
    (-1 : R) ^ p ^ n = -1 := by
  rw [eq_neg_iff_add_eq_zero]
  

Proof state:
R : Type u_1
inst✝² : Ring R
p n : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (Nat.Prime p)
⊢ (-1) ^ p ^ n + 1 = 0

Next tactic:
nth_rw 2 [← one_pow (p ^ n)]
theorem CharP.neg_one_pow_char_pow [Ring R] (p n : ℕ) [CharP R p] [Fact p.Prime] :
    (-1 : R) ^ p ^ n = -1 := by
  rw [eq_neg_iff_add_eq_zero]
  nth_rw 2 [← one_pow (p ^ n)]
  

Proof state:
R : Type u_1
inst✝² : Ring R
p n : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (Nat.Prime p)
⊢ (-1) ^ p ^ n + 1 ^ p ^ n = 0

Next tactic:
rw [← add_pow_char_pow_of_commute R _ _ (Commute.one_right _), add_left_neg,
    zero_pow (pow_pos (Fact.out (p := Nat.Prime p)).pos _)]
theorem RingHom.charP_iff_charP {K L : Type*} [DivisionRing K] [Semiring L] [Nontrivial L]
    (f : K →+* L) (p : ℕ) : CharP K p ↔ CharP L p := by
  

Proof state:
R : Type u_1
K : Type u_2
L : Type u_3
inst✝² : DivisionRing K
inst✝¹ : Semiring L
inst✝ : Nontrivial L
f : K →+* L
p : ℕ
⊢ CharP K p ↔ CharP L p

Next tactic:
simp only [charP_iff, ← f.injective.eq_iff, map_natCast f, f.map_zero]
theorem iterate_frobenius (n : ℕ) : (frobenius R p)^[n] x = x ^ p ^ n := by
  

Proof state:
R : Type u_1
inst✝⁴ : CommSemiring R
S : Type v
inst✝³ : CommSemiring S
f : R →* S
g : R →+* S
p : ℕ
inst✝² : Fact (Nat.Prime p)
inst✝¹ : CharP R p
inst✝ : CharP S p
x y : R
n : ℕ
⊢ (⇑(frobenius R p))^[n] x = x ^ p ^ n

Next tactic:
induction n with
  | zero => simp
  | succ n n_ih =>
      rw [Function.iterate_succ', pow_succ', pow_mul, Function.comp_apply, frobenius_def, n_ih]
theorem iterate_frobenius (n : ℕ) : (frobenius R p)^[n] x = x ^ p ^ n := by
  induction n with
  

Proof state:
case zero
R : Type u_1
inst✝⁴ : CommSemiring R
S : Type v
inst✝³ : CommSemiring S
f : R →* S
g : R →+* S
p : ℕ
inst✝² : Fact (Nat.Prime p)
inst✝¹ : CharP R p
inst✝ : CharP S p
x y : R
⊢ (⇑(frobenius R p))^[Nat.zero] x = x ^ p ^ Nat.zero

Next tactic:
| zero => simp
theorem iterate_frobenius (n : ℕ) : (frobenius R p)^[n] x = x ^ p ^ n := by
  induction n with
  | zero => 

Proof state:
case zero
R : Type u_1
inst✝⁴ : CommSemiring R
S : Type v
inst✝³ : CommSemiring S
f : R →* S
g : R →+* S
p : ℕ
inst✝² : Fact (Nat.Prime p)
inst✝¹ : CharP R p
inst✝ : CharP S p
x y : R
⊢ (⇑(frobenius R p))^[Nat.zero] x = x ^ p ^ Nat.zero

Next tactic:
simp
theorem iterate_frobenius (n : ℕ) : (frobenius R p)^[n] x = x ^ p ^ n := by
  induction n with
  | zero => simp
  

Proof state:
case succ
R : Type u_1
inst✝⁴ : CommSemiring R
S : Type v
inst✝³ : CommSemiring S
f : R →* S
g : R →+* S
p : ℕ
inst✝² : Fact (Nat.Prime p)
inst✝¹ : CharP R p
inst✝ : CharP S p
x y : R
n : ℕ
n_ih : (⇑(frobenius R p))^[n] x = x ^ p ^ n
⊢ (⇑(frobenius R p))^[Nat.succ n] x = x ^ p ^ Nat.succ n

Next tactic:
| succ n n_ih =>
      rw [Function.iterate_succ', pow_succ', pow_mul, Function.comp_apply, frobenius_def, n_ih]
theorem iterate_frobenius (n : ℕ) : (frobenius R p)^[n] x = x ^ p ^ n := by
  induction n with
  | zero => simp
  | succ n n_ih =>
      

Proof state:
case succ
R : Type u_1
inst✝⁴ : CommSemiring R
S : Type v
inst✝³ : CommSemiring S
f : R →* S
g : R →+* S
p : ℕ
inst✝² : Fact (Nat.Prime p)
inst✝¹ : CharP R p
inst✝ : CharP S p
x y : R
n : ℕ
n_ih : (⇑(frobenius R p))^[n] x = x ^ p ^ n
⊢ (⇑(frobenius R p))^[Nat.succ n] x = x ^ p ^ Nat.succ n

Next tactic:
rw [Function.iterate_succ', pow_succ', pow_mul, Function.comp_apply, frobenius_def, n_ih]
theorem cast_eq_mod (p : ℕ) [CharP R p] (k : ℕ) : (k : R) = (k % p : ℕ) :=
  calc
    (k : R) = ↑(k % p + p * (k / p)) := by 

Proof state:
R : Type u_1
inst✝¹ : NonAssocRing R
p : ℕ
inst✝ : CharP R p
k : ℕ
⊢ ↑k = ↑(k % p + p * (k / p))

Next tactic:
rw [Nat.mod_add_div]
theorem cast_eq_mod (p : ℕ) [CharP R p] (k : ℕ) : (k : R) = (k % p : ℕ) :=
  calc
    (k : R) = ↑(k % p + p * (k / p)) := by rw [Nat.mod_add_div]
    _ = ↑(k % p) := by 

Proof state:
R : Type u_1
inst✝¹ : NonAssocRing R
p : ℕ
inst✝ : CharP R p
k : ℕ
⊢ ↑(k % p + p * (k / p)) = ↑(k % p)

Next tactic:
simp [cast_eq_zero]
/-- The characteristic of a finite ring cannot be zero. -/
theorem char_ne_zero_of_finite (p : ℕ) [CharP R p] [Finite R] : p ≠ 0 := by
  

Proof state:
R : Type u_1
inst✝² : NonAssocRing R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Finite R
⊢ p ≠ 0

Next tactic:
rintro rfl
/-- The characteristic of a finite ring cannot be zero. -/
theorem char_ne_zero_of_finite (p : ℕ) [CharP R p] [Finite R] : p ≠ 0 := by
  rintro rfl
  

Proof state:
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : Finite R
inst✝ : CharP R 0
⊢ False

Next tactic:
haveI : CharZero R := charP_to_charZero R
/-- The characteristic of a finite ring cannot be zero. -/
theorem char_ne_zero_of_finite (p : ℕ) [CharP R p] [Finite R] : p ≠ 0 := by
  rintro rfl
  haveI : CharZero R := charP_to_charZero R
  

Proof state:
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : Finite R
inst✝ : CharP R 0
this : CharZero R
⊢ False

Next tactic:
cases nonempty_fintype R
/-- The characteristic of a finite ring cannot be zero. -/
theorem char_ne_zero_of_finite (p : ℕ) [CharP R p] [Finite R] : p ≠ 0 := by
  rintro rfl
  haveI : CharZero R := charP_to_charZero R
  cases nonempty_fintype R
  

Proof state:
case intro
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : Finite R
inst✝ : CharP R 0
this : CharZero R
val✝ : Fintype R
⊢ False

Next tactic:
exact absurd Nat.cast_injective (not_injective_infinite_finite ((↑) : ℕ → R))
theorem ringChar_zero_iff_CharZero [NonAssocRing R] : ringChar R = 0 ↔ CharZero R := by
  

Proof state:
R : Type u_1
inst✝¹ inst✝ : NonAssocRing R
⊢ ringChar R = 0 ↔ CharZero R

Next tactic:
rw [ringChar.eq_iff, charP_zero_iff_charZero]
theorem char_ne_one [Nontrivial R] (p : ℕ) [hc : CharP R p] : p ≠ 1 := fun hp : p = 1 =>
  have : (1 : R) = 0 := by 

Proof state:
R : Type u_1
inst✝¹ : NonAssocSemiring R
inst✝ : Nontrivial R
p : ℕ
hc : CharP R p
hp : p = 1
⊢ 1 = 0

Next tactic:
simpa using (cast_eq_zero_iff R p 1).mpr (hp ▸ dvd_refl p)
theorem char_is_prime_of_two_le (p : ℕ) [hc : CharP R p] (hp : 2 ≤ p) : Nat.Prime p :=
  suffices ∀ (d) (_ : d ∣ p), d = 1 ∨ d = p from Nat.prime_def_lt''.mpr ⟨hp, this⟩
  fun (d : ℕ) (hdvd : ∃ e, p = d * e) =>
  let ⟨e, hmul⟩ := hdvd
  have : (p : R) = 0 := (cast_eq_zero_iff R p p).mpr (dvd_refl p)
  have : (d : R) * e = 0 := @Nat.cast_mul R _ d e ▸ hmul ▸ this
  Or.elim (eq_zero_or_eq_zero_of_mul_eq_zero this)
    (fun hd : (d : R) = 0 =>
      have : p ∣ d := (cast_eq_zero_iff R p d).mp hd
      show d = 1 ∨ d = p from Or.inr (this.antisymm' ⟨e, hmul⟩))
    fun he : (e : R) = 0 =>
    have : p ∣ e := (cast_eq_zero_iff R p e).mp he
    have : e ∣ p := dvd_of_mul_left_eq d (Eq.symm hmul)
    have : e = p := ‹e ∣ p›.antisymm ‹p ∣ e›
    have h₀ : 0 < p := two_pos.trans_le hp
    have : d * p = 1 * p := by 

Proof state:
R : Type u_1
inst✝¹ : NonAssocSemiring R
inst✝ : NoZeroDivisors R
p : ℕ
hc : CharP R p
hp : 2 ≤ p
d : ℕ
hdvd : ∃ e, p = d * e
e : ℕ
hmul : p = d * e
this✝³ : ↑p = 0
this✝² : ↑d * ↑e = 0
he : ↑e = 0
this✝¹ : p ∣ e
this✝ : e ∣ p
this : e = p
h₀ : 0 < p
⊢ d * p = 1 * p

Next tactic:
rw [‹e = p›] at hmul