[GOAL]
R : Type u_1
inst✝ : Semiring R
p : ℕ
x y : R
hp : Nat.Prime p
h : Commute x y
n : ℕ
⊢ (x + y) ^ p ^ n =
    x ^ p ^ n + y ^ p ^ n + ↑p * ∑ k in Ioo 0 (p ^ n), x ^ k * y ^ (p ^ n - k) * ↑(Nat.choose (p ^ n) k / p)
[PROOFSTEP]
trans x ^ p ^ n + y ^ p ^ n + ∑ k in Ioo 0 (p ^ n), x ^ k * y ^ (p ^ n - k) * (p ^ n).choose k
[GOAL]
R : Type u_1
inst✝ : Semiring R
p : ℕ
x y : R
hp : Nat.Prime p
h : Commute x y
n : ℕ
⊢ (x + y) ^ p ^ n = x ^ p ^ n + y ^ p ^ n + ∑ k in Ioo 0 (p ^ n), x ^ k * y ^ (p ^ n - k) * ↑(Nat.choose (p ^ n) k)
[PROOFSTEP]
simp_rw [h.add_pow, ← Nat.Ico_zero_eq_range, Nat.Ico_succ_right, Icc_eq_cons_Ico (zero_le _), Finset.sum_cons,
  Ico_eq_cons_Ioo (pow_pos hp.pos _), Finset.sum_cons, tsub_self, tsub_zero, pow_zero, Nat.choose_zero_right,
  Nat.choose_self, Nat.cast_one, mul_one, one_mul, ← add_assoc]
[GOAL]
R : Type u_1
inst✝ : Semiring R
p : ℕ
x y : R
hp : Nat.Prime p
h : Commute x y
n : ℕ
⊢ x ^ p ^ n + y ^ p ^ n + ∑ k in Ioo 0 (p ^ n), x ^ k * y ^ (p ^ n - k) * ↑(Nat.choose (p ^ n) k) =
    x ^ p ^ n + y ^ p ^ n + ↑p * ∑ k in Ioo 0 (p ^ n), x ^ k * y ^ (p ^ n - k) * ↑(Nat.choose (p ^ n) k / p)
[PROOFSTEP]
congr 1
[GOAL]
case e_a
R : Type u_1
inst✝ : Semiring R
p : ℕ
x y : R
hp : Nat.Prime p
h : Commute x y
n : ℕ
⊢ ∑ k in Ioo 0 (p ^ n), x ^ k * y ^ (p ^ n - k) * ↑(Nat.choose (p ^ n) k) =
    ↑p * ∑ k in Ioo 0 (p ^ n), x ^ k * y ^ (p ^ n - k) * ↑(Nat.choose (p ^ n) k / p)
[PROOFSTEP]
simp_rw [Finset.mul_sum, Nat.cast_comm, mul_assoc _ _ (p : R), ← Nat.cast_mul]
[GOAL]
case e_a
R : Type u_1
inst✝ : Semiring R
p : ℕ
x y : R
hp : Nat.Prime p
h : Commute x y
n : ℕ
⊢ ∑ k in Ioo 0 (p ^ n), x ^ k * y ^ (p ^ n - k) * ↑(Nat.choose (p ^ n) k) =
    ∑ x_1 in Ioo 0 (p ^ n), x ^ x_1 * y ^ (p ^ n - x_1) * ↑(Nat.choose (p ^ n) x_1 / p * p)
[PROOFSTEP]
refine' Finset.sum_congr rfl fun i hi => _
[GOAL]
case e_a
R : Type u_1
inst✝ : Semiring R
p : ℕ
x y : R
hp : Nat.Prime p
h : Commute x y
n i : ℕ
hi : i ∈ Ioo 0 (p ^ n)
⊢ x ^ i * y ^ (p ^ n - i) * ↑(Nat.choose (p ^ n) i) = x ^ i * y ^ (p ^ n - i) * ↑(Nat.choose (p ^ n) i / p * p)
[PROOFSTEP]
rw [mem_Ioo] at hi
[GOAL]
case e_a
R : Type u_1
inst✝ : Semiring R
p : ℕ
x y : R
hp : Nat.Prime p
h : Commute x y
n i : ℕ
hi : 0 < i ∧ i < p ^ n
⊢ x ^ i * y ^ (p ^ n - i) * ↑(Nat.choose (p ^ n) i) = x ^ i * y ^ (p ^ n - i) * ↑(Nat.choose (p ^ n) i / p * p)
[PROOFSTEP]
rw [Nat.div_mul_cancel (hp.dvd_choose_pow hi.1.ne' hi.2.ne)]
[GOAL]
R : Type u_1
inst✝ : Semiring R
p : ℕ
x y : R
hp : Nat.Prime p
h : Commute x y
⊢ (x + y) ^ p = x ^ p + y ^ p + ↑p * ∑ k in Ioo 0 p, x ^ k * y ^ (p - k) * ↑(Nat.choose p k / p)
[PROOFSTEP]
simpa using h.add_pow_prime_pow_eq hp 1
[GOAL]
R : Type u_1
inst✝¹ : AddGroupWithOne R
inst✝ : Fintype R
⊢ ↑(Fintype.card R) = 0
[PROOFSTEP]
rw [← nsmul_one, card_nsmul_eq_zero]
[GOAL]
R✝ : Type u_1
R : Type u_2
inst✝ : Semiring R
n : ℕ
⊢ ↑n = 0 ↔ addOrderOf 1 ∣ n
[PROOFSTEP]
rw [← Nat.smul_one_eq_coe, addOrderOf_dvd_iff_nsmul_eq_zero]
[GOAL]
R : Type u_1
inst✝¹ : AddGroupWithOne R
p : ℕ
inst✝ : CharP R p
a : ℤ
⊢ ↑a = 0 ↔ ↑p ∣ a
[PROOFSTEP]
rcases lt_trichotomy a 0 with (h | rfl | h)
[GOAL]
case inl
R : Type u_1
inst✝¹ : AddGroupWithOne R
p : ℕ
inst✝ : CharP R p
a : ℤ
h : a < 0
⊢ ↑a = 0 ↔ ↑p ∣ a
[PROOFSTEP]
rw [← neg_eq_zero, ← Int.cast_neg, ← dvd_neg]
[GOAL]
case inl
R : Type u_1
inst✝¹ : AddGroupWithOne R
p : ℕ
inst✝ : CharP R p
a : ℤ
h : a < 0
⊢ ↑(-a) = 0 ↔ ↑p ∣ -a
[PROOFSTEP]
lift -a to ℕ using neg_nonneg.mpr (le_of_lt h) with b
[GOAL]
case inl.intro
R : Type u_1
inst✝¹ : AddGroupWithOne R
p : ℕ
inst✝ : CharP R p
a : ℤ
h : a < 0
b : ℕ
⊢ ↑↑b = 0 ↔ ↑p ∣ ↑b
[PROOFSTEP]
rw [Int.cast_ofNat, CharP.cast_eq_zero_iff R p, Int.coe_nat_dvd]
[GOAL]
case inr.inl
R : Type u_1
inst✝¹ : AddGroupWithOne R
p : ℕ
inst✝ : CharP R p
⊢ ↑0 = 0 ↔ ↑p ∣ 0
[PROOFSTEP]
simp only [Int.cast_zero, eq_self_iff_true, dvd_zero]
[GOAL]
case inr.inr
R : Type u_1
inst✝¹ : AddGroupWithOne R
p : ℕ
inst✝ : CharP R p
a : ℤ
h : 0 < a
⊢ ↑a = 0 ↔ ↑p ∣ a
[PROOFSTEP]
lift a to ℕ using le_of_lt h with b
[GOAL]
case inr.inr.intro
R : Type u_1
inst✝¹ : AddGroupWithOne R
p : ℕ
inst✝ : CharP R p
a : ℤ
b : ℕ
h✝ h : 0 < ↑b
⊢ ↑↑b = 0 ↔ ↑p ∣ ↑b
[PROOFSTEP]
rw [Int.cast_ofNat, CharP.cast_eq_zero_iff R p, Int.coe_nat_dvd]
[GOAL]
R : Type u_1
inst✝¹ : AddGroupWithOne R
p : ℕ
inst✝ : CharP R p
a b : ℤ
⊢ ↑a = ↑b ↔ a ≡ b [ZMOD ↑p]
[PROOFSTEP]
rw [eq_comm, ← sub_eq_zero, ← Int.cast_sub, CharP.int_cast_eq_zero_iff R p, Int.modEq_iff_dvd]
[GOAL]
R : Type u_1
inst✝¹ : AddGroupWithOne R
p : ℕ
inst✝ : CharP R p
a b : ℕ
⊢ ↑a = ↑b ↔ a ≡ b [MOD p]
[PROOFSTEP]
rw [← Int.cast_ofNat, ← Int.cast_ofNat b]
[GOAL]
R : Type u_1
inst✝¹ : AddGroupWithOne R
p : ℕ
inst✝ : CharP R p
a b : ℕ
⊢ ↑↑a = ↑↑b ↔ a ≡ b [MOD p]
[PROOFSTEP]
exact (CharP.intCast_eq_intCast _ _).trans Int.coe_nat_modEq_iff
[GOAL]
R : Type u_1
inst✝¹ : AddMonoidWithOne R
inst✝ : CharZero R
x : ℕ
⊢ ↑x = 0 ↔ 0 ∣ x
[PROOFSTEP]
rw [zero_dvd_iff, ← Nat.cast_zero, Nat.cast_inj]
[GOAL]
R : Type u_1
inst✝ : NonAssocSemiring R
this : DecidableEq R := Classical.decEq R
H : ∀ (p : ℕ), ↑p = 0 → p = 0
x : ℕ
⊢ ↑x = 0 ↔ 0 ∣ x
[PROOFSTEP]
rw [zero_dvd_iff]
[GOAL]
R : Type u_1
inst✝ : NonAssocSemiring R
this : DecidableEq R := Classical.decEq R
H : ∀ (p : ℕ), ↑p = 0 → p = 0
x : ℕ
⊢ ↑x = 0 ↔ x = 0
[PROOFSTEP]
exact ⟨H x, by rintro rfl; simp⟩
[GOAL]
R : Type u_1
inst✝ : NonAssocSemiring R
this : DecidableEq R := Classical.decEq R
H : ∀ (p : ℕ), ↑p = 0 → p = 0
x : ℕ
⊢ x = 0 → ↑x = 0
[PROOFSTEP]
rintro rfl
[GOAL]
R : Type u_1
inst✝ : NonAssocSemiring R
this : DecidableEq R := Classical.decEq R
H : ∀ (p : ℕ), ↑p = 0 → p = 0
⊢ ↑0 = 0
[PROOFSTEP]
simp
[GOAL]
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
[PROOFSTEP]
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
[GOAL]
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
[PROOFSTEP]
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]
[GOAL]
R : Type u_1
inst✝ : NonAssocSemiring R
⊢ ∀ (x : ℕ), ↑x = 0 ↔ ringChar R ∣ x
[PROOFSTEP]
letI : CharP R (ringChar R) := (Classical.choose_spec (CharP.exists_unique R)).1
[GOAL]
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
[PROOFSTEP]
exact CharP.cast_eq_zero_iff R (ringChar R)
[GOAL]
R : Type u_1
inst✝ : NonAssocSemiring R
⊢ ↑(ringChar R) = 0
[PROOFSTEP]
rw [ringChar.spec]
[GOAL]
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
[PROOFSTEP]
let ⟨r, hr⟩ := h.exists_add_pow_prime_eq hp.out
[GOAL]
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
[PROOFSTEP]
simp [hr]
[GOAL]
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
[PROOFSTEP]
let ⟨r, hr⟩ := h.exists_add_pow_prime_pow_eq hp.out n
[GOAL]
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
[PROOFSTEP]
simp [hr]
[GOAL]
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
[PROOFSTEP]
rw [eq_sub_iff_add_eq, ← add_pow_char_of_commute _ _ _ (Commute.sub_left h rfl)]
[GOAL]
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
[PROOFSTEP]
simp
[GOAL]
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
[PROOFSTEP]
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
[GOAL]
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
[PROOFSTEP]
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
[GOAL]
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
[PROOFSTEP]

| zero => simp
[GOAL]
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
[PROOFSTEP]
simp
[GOAL]
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
[PROOFSTEP]

| 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
[GOAL]
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
[PROOFSTEP]
rw [pow_succ', pow_mul, pow_mul, pow_mul, n_ih]
[GOAL]
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
[PROOFSTEP]
apply sub_pow_char_of_commute
[GOAL]
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)
[PROOFSTEP]
apply Commute.pow_pow h
[GOAL]
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
⊢ -1 ≠ 1
[PROOFSTEP]
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
[GOAL]
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
this : 2 ≠ 0
⊢ -1 ≠ 1
[PROOFSTEP]
intro h
[GOAL]
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
this : 2 ≠ 0
h : -1 = 1
⊢ False
[PROOFSTEP]
symm at h
[GOAL]
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
this : 2 ≠ 0
h : 1 = -1
⊢ False
[PROOFSTEP]
rw [← sub_eq_zero, sub_neg_eq_add] at h
[GOAL]
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
this : 2 ≠ 0
h✝ : 1 = -1
h : 1 + 1 = 0
⊢ False
[PROOFSTEP]
norm_num at h
[GOAL]
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
this : 2 ≠ 0
h✝ : 1 = -1
h : 2 = 0
⊢ False
[PROOFSTEP]
exact this h
[GOAL]
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
⊢ 2 ≠ 0
[PROOFSTEP]
intro h
[GOAL]
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
h : 2 = 0
⊢ False
[PROOFSTEP]
rw [show (2 : R) = (2 : ℕ) by norm_cast] at h
[GOAL]
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
h : 2 = 0
⊢ 2 = ↑2
[PROOFSTEP]
norm_cast
[GOAL]
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
h : ↑2 = 0
⊢ False
[PROOFSTEP]
have := (CharP.cast_eq_zero_iff R p 2).mp h
[GOAL]
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
h : ↑2 = 0
this : p ∣ 2
⊢ False
[PROOFSTEP]
have := Nat.le_of_dvd (by decide) this
[GOAL]
R : Type u_1
inst✝² : Ring R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (2 < p)
h : ↑2 = 0
this : p ∣ 2
⊢ 0 < 2
[PROOFSTEP]
decide
[GOAL]
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
[PROOFSTEP]
rw [fact_iff] at *
[GOAL]
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
[PROOFSTEP]
linarith
[GOAL]
R : Type u_1
inst✝² : CommRing R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (Nat.Prime p)
⊢ (-1) ^ p = -1
[PROOFSTEP]
rw [eq_neg_iff_add_eq_zero]
[GOAL]
R : Type u_1
inst✝² : CommRing R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (Nat.Prime p)
⊢ (-1) ^ p + 1 = 0
[PROOFSTEP]
nth_rw 2 [← one_pow p]
[GOAL]
R : Type u_1
inst✝² : CommRing R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (Nat.Prime p)
⊢ (-1) ^ p + 1 ^ p = 0
[PROOFSTEP]
rw [← add_pow_char, add_left_neg, zero_pow (Fact.out (p := Nat.Prime p)).pos]
[GOAL]
R : Type u_1
inst✝² : CommRing R
p n : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (Nat.Prime p)
⊢ (-1) ^ p ^ n = -1
[PROOFSTEP]
rw [eq_neg_iff_add_eq_zero]
[GOAL]
R : Type u_1
inst✝² : CommRing R
p n : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (Nat.Prime p)
⊢ (-1) ^ p ^ n + 1 = 0
[PROOFSTEP]
nth_rw 2 [← one_pow (p ^ n)]
[GOAL]
R : Type u_1
inst✝² : CommRing R
p n : ℕ
inst✝¹ : CharP R p
inst✝ : Fact (Nat.Prime p)
⊢ (-1) ^ p ^ n + 1 ^ p ^ n = 0
[PROOFSTEP]
rw [← add_pow_char_pow, add_left_neg, zero_pow (pow_pos (Fact.out (p := Nat.Prime p)).pos _)]
[GOAL]
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
[PROOFSTEP]
simp only [charP_iff, ← f.injective.eq_iff, map_natCast f, f.map_zero]
[GOAL]
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
[PROOFSTEP]
induction n with
| zero => simp
| succ n n_ih => rw [Function.iterate_succ', pow_succ', pow_mul, Function.comp_apply, frobenius_def, n_ih]
[GOAL]
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
[PROOFSTEP]
induction n with
| zero => simp
| succ n n_ih => rw [Function.iterate_succ', pow_succ', pow_mul, Function.comp_apply, frobenius_def, n_ih]
[GOAL]
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
[PROOFSTEP]

| zero => simp
[GOAL]
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
[PROOFSTEP]
simp
[GOAL]
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
[PROOFSTEP]

| succ n n_ih => rw [Function.iterate_succ', pow_succ', pow_mul, Function.comp_apply, frobenius_def, n_ih]
[GOAL]
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
[PROOFSTEP]
rw [Function.iterate_succ', pow_succ', pow_mul, Function.comp_apply, frobenius_def, n_ih]
[GOAL]
R : Type u_1
inst✝³ : CommRing R
inst✝² : IsReduced R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP R p
x h : R
H : ↑(frobenius R p) x = ↑(frobenius R p) h
⊢ x = h
[PROOFSTEP]
rw [← sub_eq_zero] at H ⊢
[GOAL]
R : Type u_1
inst✝³ : CommRing R
inst✝² : IsReduced R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP R p
x h : R
H✝ : ↑(frobenius R p) x = ↑(frobenius R p) h
H : ↑(frobenius R p) x - ↑(frobenius R p) h = 0
⊢ x - h = 0
[PROOFSTEP]
rw [← frobenius_sub] at H
[GOAL]
R : Type u_1
inst✝³ : CommRing R
inst✝² : IsReduced R
p : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP R p
x h : R
H✝ : ↑(frobenius R p) x = ↑(frobenius R p) h
H : ↑(frobenius R p) (x - h) = 0
⊢ x - h = 0
[PROOFSTEP]
exact IsReduced.eq_zero _ ⟨_, H⟩
[GOAL]
R✝ : Type u_1
R : Type u_2
inst✝³ : Finite R
inst✝² : CommRing R
inst✝¹ : IsReduced R
inst✝ : CharP R 2
a : R
⊢ IsSquare a
[PROOFSTEP]
cases nonempty_fintype R
[GOAL]
case intro
R✝ : Type u_1
R : Type u_2
inst✝³ : Finite R
inst✝² : CommRing R
inst✝¹ : IsReduced R
inst✝ : CharP R 2
a : R
val✝ : Fintype R
⊢ IsSquare a
[PROOFSTEP]
exact
  Exists.imp (fun b h => pow_two b ▸ Eq.symm h)
    (((Fintype.bijective_iff_injective_and_card _).mpr ⟨frobenius_inj R 2, rfl⟩).surjective a)
[GOAL]
R : Type u_1
inst✝¹ : NonAssocRing R
p : ℕ
inst✝ : CharP R p
k : ℕ
⊢ ↑k = ↑(k % p + p * (k / p))
[PROOFSTEP]
rw [Nat.mod_add_div]
[GOAL]
R : Type u_1
inst✝¹ : NonAssocRing R
p : ℕ
inst✝ : CharP R p
k : ℕ
⊢ ↑(k % p + p * (k / p)) = ↑(k % p)
[PROOFSTEP]
simp [cast_eq_zero]
[GOAL]
R : Type u_1
inst✝² : NonAssocRing R
p : ℕ
inst✝¹ : CharP R p
inst✝ : Finite R
⊢ p ≠ 0
[PROOFSTEP]
rintro rfl
[GOAL]
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : Finite R
inst✝ : CharP R 0
⊢ False
[PROOFSTEP]
haveI : CharZero R := charP_to_charZero R
[GOAL]
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : Finite R
inst✝ : CharP R 0
this : CharZero R
⊢ False
[PROOFSTEP]
cases nonempty_fintype R
[GOAL]
case intro
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : Finite R
inst✝ : CharP R 0
this : CharZero R
val✝ : Fintype R
⊢ False
[PROOFSTEP]
exact absurd Nat.cast_injective (not_injective_infinite_finite ((↑) : ℕ → R))
[GOAL]
R : Type u_1
inst✝¹ inst✝ : NonAssocRing R
⊢ ringChar R = 0 ↔ CharZero R
[PROOFSTEP]
rw [ringChar.eq_iff, charP_zero_iff_charZero]
[GOAL]
R : Type u_1
inst✝³ : CommRing R
inst✝² : IsReduced R
p k m : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP R p
x : R
⊢ x ^ (p ^ k * m) = 1 ↔ x ^ m = 1
[PROOFSTEP]
induction' k with k hk
[GOAL]
case zero
R : Type u_1
inst✝³ : CommRing R
inst✝² : IsReduced R
p m : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP R p
x : R
⊢ x ^ (p ^ Nat.zero * m) = 1 ↔ x ^ m = 1
[PROOFSTEP]
rw [pow_zero, one_mul]
[GOAL]
case succ
R : Type u_1
inst✝³ : CommRing R
inst✝² : IsReduced R
p m : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP R p
x : R
k : ℕ
hk : x ^ (p ^ k * m) = 1 ↔ x ^ m = 1
⊢ x ^ (p ^ Nat.succ k * m) = 1 ↔ x ^ m = 1
[PROOFSTEP]
refine' ⟨fun h => _, fun h => _⟩
[GOAL]
case succ.refine'_1
R : Type u_1
inst✝³ : CommRing R
inst✝² : IsReduced R
p m : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP R p
x : R
k : ℕ
hk : x ^ (p ^ k * m) = 1 ↔ x ^ m = 1
h : x ^ (p ^ Nat.succ k * m) = 1
⊢ x ^ m = 1
[PROOFSTEP]
rw [pow_succ, mul_assoc, pow_mul', ← frobenius_def, ← frobenius_one p] at h
[GOAL]
case succ.refine'_1
R : Type u_1
inst✝³ : CommRing R
inst✝² : IsReduced R
p m : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP R p
x : R
k : ℕ
hk : x ^ (p ^ k * m) = 1 ↔ x ^ m = 1
h✝ : ↑(frobenius R p) (x ^ (p ^ k * m)) = 1
h : ↑(frobenius R p) (x ^ (p ^ k * m)) = ↑(frobenius R p) 1
⊢ x ^ m = 1
[PROOFSTEP]
exact hk.1 (frobenius_inj R p h)
[GOAL]
case succ.refine'_2
R : Type u_1
inst✝³ : CommRing R
inst✝² : IsReduced R
p m : ℕ
inst✝¹ : Fact (Nat.Prime p)
inst✝ : CharP R p
x : R
k : ℕ
hk : x ^ (p ^ k * m) = 1 ↔ x ^ m = 1
h : x ^ m = 1
⊢ x ^ (p ^ Nat.succ k * m) = 1
[PROOFSTEP]
rw [pow_mul', h, one_pow]
[GOAL]
R : Type u_1
inst✝¹ : NonAssocSemiring R
inst✝ : Nontrivial R
p : ℕ
hc : CharP R p
hp : p = 1
⊢ 1 = 0
[PROOFSTEP]
simpa using (cast_eq_zero_iff R p 1).mpr (hp ▸ dvd_refl p)
[GOAL]
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
[PROOFSTEP]
rw [‹e = p›] at hmul
[GOAL]
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 * p
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
[PROOFSTEP]
rw [one_mul]
[GOAL]
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 * p
this✝³ : ↑p = 0
this✝² : ↑d * ↑e = 0
he : ↑e = 0
this✝¹ : p ∣ e
this✝ : e ∣ p
this : e = p
h₀ : 0 < p
⊢ d * p = p
[PROOFSTEP]
exact Eq.symm hmul
[GOAL]
R : Type u_1
inst✝¹ : NonAssocSemiring R
inst✝ : CharP R 1
r : R
⊢ r = 1 * r
[PROOFSTEP]
rw [one_mul]
[GOAL]
R : Type u_1
inst✝¹ : NonAssocSemiring R
inst✝ : CharP R 1
r : R
⊢ 1 * r = ↑1 * r
[PROOFSTEP]
rw [Nat.cast_one]
[GOAL]
R : Type u_1
inst✝¹ : NonAssocSemiring R
inst✝ : CharP R 1
r : R
⊢ ↑1 * r = 0 * r
[PROOFSTEP]
rw [CharP.cast_eq_zero]
[GOAL]
R : Type u_1
inst✝¹ : NonAssocSemiring R
inst✝ : CharP R 1
r : R
⊢ 0 * r = 0
[PROOFSTEP]
rw [zero_mul]
[GOAL]
R : Type u_1
inst✝¹ : NonAssocSemiring R
inst✝ : CharP R 1
this : ∀ (r : R), r = 0
a b : R
⊢ a = b
[PROOFSTEP]
rw [this a, this b]
[GOAL]
R : Type u_1
inst✝¹ : NonAssocSemiring R
inst✝ : Nontrivial R
⊢ ringChar R ≠ 1
[PROOFSTEP]
intro h
[GOAL]
R : Type u_1
inst✝¹ : NonAssocSemiring R
inst✝ : Nontrivial R
h : ringChar R = 1
⊢ False
[PROOFSTEP]
apply zero_ne_one' R
[GOAL]
R : Type u_1
inst✝¹ : NonAssocSemiring R
inst✝ : Nontrivial R
h : ringChar R = 1
⊢ 0 = 1
[PROOFSTEP]
symm
[GOAL]
R : Type u_1
inst✝¹ : NonAssocSemiring R
inst✝ : Nontrivial R
h : ringChar R = 1
⊢ 1 = 0
[PROOFSTEP]
rw [← Nat.cast_one, ringChar.spec, h]
[GOAL]
R : Type u_1
inst✝ : NonAssocSemiring R
v : ℕ
hv : v ≠ 1
hr : CharP R v
h : ↑1 = 0
⊢ v = 1
[PROOFSTEP]
rwa [CharP.cast_eq_zero_iff _ v, Nat.dvd_one] at h
[GOAL]
R✝ : Type u_1
R : Type u_2
inst✝¹ : NonAssocSemiring R
inst✝ : Nontrivial R
hR : ringChar R ≠ 2
⊢ 2 ≠ 0
[PROOFSTEP]
rw [Ne.def, (by norm_cast : (2 : R) = (2 : ℕ)), ringChar.spec, Nat.dvd_prime Nat.prime_two]
[GOAL]
R✝ : Type u_1
R : Type u_2
inst✝¹ : NonAssocSemiring R
inst✝ : Nontrivial R
hR : ringChar R ≠ 2
⊢ 2 = ↑2
[PROOFSTEP]
norm_cast
[GOAL]
R✝ : Type u_1
R : Type u_2
inst✝¹ : NonAssocSemiring R
inst✝ : Nontrivial R
hR : ringChar R ≠ 2
⊢ ¬(ringChar R = 1 ∨ ringChar R = 2)
[PROOFSTEP]
exact mt (or_iff_left hR).mp CharP.ringChar_ne_one
[GOAL]
R : Type u_1
inst✝¹ : NonAssocRing R
inst✝ : Fintype R
n : ℕ
hn : Fintype.card R = n
hR : ∀ (i : ℕ), i < n → ↑i = 0 → i = 0
⊢ ∀ (x : ℕ), ↑x = 0 ↔ n ∣ x
[PROOFSTEP]
have H : (n : R) = 0 := by rw [← hn, CharP.cast_card_eq_zero]
[GOAL]
R : Type u_1
inst✝¹ : NonAssocRing R
inst✝ : Fintype R
n : ℕ
hn : Fintype.card R = n
hR : ∀ (i : ℕ), i < n → ↑i = 0 → i = 0
⊢ ↑n = 0
[PROOFSTEP]
rw [← hn, CharP.cast_card_eq_zero]
[GOAL]
R : Type u_1
inst✝¹ : NonAssocRing R
inst✝ : Fintype R
n : ℕ
hn : Fintype.card R = n
hR : ∀ (i : ℕ), i < n → ↑i = 0 → i = 0
H : ↑n = 0
⊢ ∀ (x : ℕ), ↑x = 0 ↔ n ∣ x
[PROOFSTEP]
intro k
[GOAL]
R : Type u_1
inst✝¹ : NonAssocRing R
inst✝ : Fintype R
n : ℕ
hn : Fintype.card R = n
hR : ∀ (i : ℕ), i < n → ↑i = 0 → i = 0
H : ↑n = 0
k : ℕ
⊢ ↑k = 0 ↔ n ∣ k
[PROOFSTEP]
constructor
[GOAL]
case mp
R : Type u_1
inst✝¹ : NonAssocRing R
inst✝ : Fintype R
n : ℕ
hn : Fintype.card R = n
hR : ∀ (i : ℕ), i < n → ↑i = 0 → i = 0
H : ↑n = 0
k : ℕ
⊢ ↑k = 0 → n ∣ k
[PROOFSTEP]
intro h
[GOAL]
case mp
R : Type u_1
inst✝¹ : NonAssocRing R
inst✝ : Fintype R
n : ℕ
hn : Fintype.card R = n
hR : ∀ (i : ℕ), i < n → ↑i = 0 → i = 0
H : ↑n = 0
k : ℕ
h : ↑k = 0
⊢ n ∣ k
[PROOFSTEP]
rw [← Nat.mod_add_div k n, Nat.cast_add, Nat.cast_mul, H, zero_mul, add_zero] at h
[GOAL]
case mp
R : Type u_1
inst✝¹ : NonAssocRing R
inst✝ : Fintype R
n : ℕ
hn : Fintype.card R = n
hR : ∀ (i : ℕ), i < n → ↑i = 0 → i = 0
H : ↑n = 0
k : ℕ
h : ↑(k % n) = 0
⊢ n ∣ k
[PROOFSTEP]
rw [Nat.dvd_iff_mod_eq_zero]
[GOAL]
case mp
R : Type u_1
inst✝¹ : NonAssocRing R
inst✝ : Fintype R
n : ℕ
hn : Fintype.card R = n
hR : ∀ (i : ℕ), i < n → ↑i = 0 → i = 0
H : ↑n = 0
k : ℕ
h : ↑(k % n) = 0
⊢ k % n = 0
[PROOFSTEP]
apply hR _ (Nat.mod_lt _ _) h
[GOAL]
R : Type u_1
inst✝¹ : NonAssocRing R
inst✝ : Fintype R
n : ℕ
hn : Fintype.card R = n
hR : ∀ (i : ℕ), i < n → ↑i = 0 → i = 0
H : ↑n = 0
k : ℕ
h : ↑(k % n) = 0
⊢ n > 0
[PROOFSTEP]
rw [← hn, gt_iff_lt, Fintype.card_pos_iff]
[GOAL]
R : Type u_1
inst✝¹ : NonAssocRing R
inst✝ : Fintype R
n : ℕ
hn : Fintype.card R = n
hR : ∀ (i : ℕ), i < n → ↑i = 0 → i = 0
H : ↑n = 0
k : ℕ
h : ↑(k % n) = 0
⊢ Nonempty R
[PROOFSTEP]
exact ⟨0⟩
[GOAL]
case mpr
R : Type u_1
inst✝¹ : NonAssocRing R
inst✝ : Fintype R
n : ℕ
hn : Fintype.card R = n
hR : ∀ (i : ℕ), i < n → ↑i = 0 → i = 0
H : ↑n = 0
k : ℕ
⊢ n ∣ k → ↑k = 0
[PROOFSTEP]
rintro ⟨k, rfl⟩
[GOAL]
case mpr.intro
R : Type u_1
inst✝¹ : NonAssocRing R
inst✝ : Fintype R
n : ℕ
hn : Fintype.card R = n
hR : ∀ (i : ℕ), i < n → ↑i = 0 → i = 0
H : ↑n = 0
k : ℕ
⊢ ↑(n * k) = 0
[PROOFSTEP]
rw [Nat.cast_mul, H, zero_mul]
[GOAL]
R✝ : Type u_1
inst✝³ : NonAssocRing R✝
inst✝² : Fintype R✝
n✝ : ℕ
R : Type u_2
inst✝¹ : Ring R
inst✝ : Fintype R
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
hn : Fintype.card R = p ^ n
hR : ∀ (i : ℕ), i ≤ n → ↑p ^ i = 0 → i = n
⊢ CharP R (p ^ n)
[PROOFSTEP]
obtain ⟨c, hc⟩ := CharP.exists R
[GOAL]
case intro
R✝ : Type u_1
inst✝³ : NonAssocRing R✝
inst✝² : Fintype R✝
n✝ : ℕ
R : Type u_2
inst✝¹ : Ring R
inst✝ : Fintype R
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
hn : Fintype.card R = p ^ n
hR : ∀ (i : ℕ), i ≤ n → ↑p ^ i = 0 → i = n
c : ℕ
hc : CharP R c
⊢ CharP R (p ^ n)
[PROOFSTEP]
have hcpn : c ∣ p ^ n := by rw [← CharP.cast_eq_zero_iff R c, ← hn, CharP.cast_card_eq_zero]
[GOAL]
R✝ : Type u_1
inst✝³ : NonAssocRing R✝
inst✝² : Fintype R✝
n✝ : ℕ
R : Type u_2
inst✝¹ : Ring R
inst✝ : Fintype R
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
hn : Fintype.card R = p ^ n
hR : ∀ (i : ℕ), i ≤ n → ↑p ^ i = 0 → i = n
c : ℕ
hc : CharP R c
⊢ c ∣ p ^ n
[PROOFSTEP]
rw [← CharP.cast_eq_zero_iff R c, ← hn, CharP.cast_card_eq_zero]
[GOAL]
case intro
R✝ : Type u_1
inst✝³ : NonAssocRing R✝
inst✝² : Fintype R✝
n✝ : ℕ
R : Type u_2
inst✝¹ : Ring R
inst✝ : Fintype R
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
hn : Fintype.card R = p ^ n
hR : ∀ (i : ℕ), i ≤ n → ↑p ^ i = 0 → i = n
c : ℕ
hc : CharP R c
hcpn : c ∣ p ^ n
⊢ CharP R (p ^ n)
[PROOFSTEP]
obtain ⟨i, hi, hc⟩ : ∃ i ≤ n, c = p ^ i := by rwa [Nat.dvd_prime_pow hp.1] at hcpn
[GOAL]
R✝ : Type u_1
inst✝³ : NonAssocRing R✝
inst✝² : Fintype R✝
n✝ : ℕ
R : Type u_2
inst✝¹ : Ring R
inst✝ : Fintype R
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
hn : Fintype.card R = p ^ n
hR : ∀ (i : ℕ), i ≤ n → ↑p ^ i = 0 → i = n
c : ℕ
hc : CharP R c
hcpn : c ∣ p ^ n
⊢ ∃ i, i ≤ n ∧ c = p ^ i
[PROOFSTEP]
rwa [Nat.dvd_prime_pow hp.1] at hcpn
[GOAL]
case intro.intro.intro
R✝ : Type u_1
inst✝³ : NonAssocRing R✝
inst✝² : Fintype R✝
n✝ : ℕ
R : Type u_2
inst✝¹ : Ring R
inst✝ : Fintype R
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
hn : Fintype.card R = p ^ n
hR : ∀ (i : ℕ), i ≤ n → ↑p ^ i = 0 → i = n
c : ℕ
hc✝ : CharP R c
hcpn : c ∣ p ^ n
i : ℕ
hi : i ≤ n
hc : c = p ^ i
⊢ CharP R (p ^ n)
[PROOFSTEP]
obtain rfl : i = n := by
  apply hR i hi
  rw [← Nat.cast_pow, ← hc, CharP.cast_eq_zero]
[GOAL]
R✝ : Type u_1
inst✝³ : NonAssocRing R✝
inst✝² : Fintype R✝
n✝ : ℕ
R : Type u_2
inst✝¹ : Ring R
inst✝ : Fintype R
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
hn : Fintype.card R = p ^ n
hR : ∀ (i : ℕ), i ≤ n → ↑p ^ i = 0 → i = n
c : ℕ
hc✝ : CharP R c
hcpn : c ∣ p ^ n
i : ℕ
hi : i ≤ n
hc : c = p ^ i
⊢ i = n
[PROOFSTEP]
apply hR i hi
[GOAL]
R✝ : Type u_1
inst✝³ : NonAssocRing R✝
inst✝² : Fintype R✝
n✝ : ℕ
R : Type u_2
inst✝¹ : Ring R
inst✝ : Fintype R
p : ℕ
hp : Fact (Nat.Prime p)
n : ℕ
hn : Fintype.card R = p ^ n
hR : ∀ (i : ℕ), i ≤ n → ↑p ^ i = 0 → i = n
c : ℕ
hc✝ : CharP R c
hcpn : c ∣ p ^ n
i : ℕ
hi : i ≤ n
hc : c = p ^ i
⊢ ↑p ^ i = 0
[PROOFSTEP]
rw [← Nat.cast_pow, ← hc, CharP.cast_eq_zero]
[GOAL]
case intro.intro.intro
R✝ : Type u_1
inst✝³ : NonAssocRing R✝
inst✝² : Fintype R✝
n : ℕ
R : Type u_2
inst✝¹ : Ring R
inst✝ : Fintype R
p : ℕ
hp : Fact (Nat.Prime p)
c : ℕ
hc✝ : CharP R c
i : ℕ
hc : c = p ^ i
hn : Fintype.card R = p ^ i
hR : ∀ (i_1 : ℕ), i_1 ≤ i → ↑p ^ i_1 = 0 → i_1 = i
hcpn : c ∣ p ^ i
hi : i ≤ i
⊢ CharP R (p ^ i)
[PROOFSTEP]
rwa [← hc]
[GOAL]
R : Type u_1
S : Type v
inst✝³ : AddMonoidWithOne R
inst✝² : AddMonoidWithOne S
p q : ℕ
inst✝¹ : CharP R p
inst✝ : CharP S q
⊢ ∀ (x : ℕ), ↑x = 0 ↔ lcm p q ∣ x
[PROOFSTEP]
simp [Prod.ext_iff, CharP.cast_eq_zero_iff R p, CharP.cast_eq_zero_iff S q, Nat.lcm_dvd_iff]
[GOAL]
R : Type u_1
S : Type v
inst✝³ : AddMonoidWithOne R
inst✝² : AddMonoidWithOne S
p q : ℕ
inst✝¹ : CharP R p
inst✝ : CharP S p
⊢ CharP (R × S) p
[PROOFSTEP]
convert Nat.lcm.charP R S p p
[GOAL]
case h.e'_3
R : Type u_1
S : Type v
inst✝³ : AddMonoidWithOne R
inst✝² : AddMonoidWithOne S
p q : ℕ
inst✝¹ : CharP R p
inst✝ : CharP S p
⊢ p = Nat.lcm p p
[PROOFSTEP]
simp
[GOAL]
R✝ : Type u_1
R : Type u_2
inst✝¹ : NonAssocRing R
inst✝ : Nontrivial R
hR : ringChar R ≠ 2
⊢ Set.InjOn Int.cast {0, 1, -1}
[PROOFSTEP]
rintro _ (rfl | rfl | rfl) _ (rfl | rfl | rfl) h
[GOAL]
case inl.inl
R✝ : Type u_1
R : Type u_2
inst✝¹ : NonAssocRing R
inst✝ : Nontrivial R
hR : ringChar R ≠ 2
h : ↑0 = ↑0
⊢ 0 = 0
[PROOFSTEP]
simp only [cast_neg, cast_one, cast_zero, neg_eq_zero, one_ne_zero, zero_ne_one, zero_eq_neg] at h ⊢
[GOAL]
case inl.inr.inl
R✝ : Type u_1
R : Type u_2
inst✝¹ : NonAssocRing R
inst✝ : Nontrivial R
hR : ringChar R ≠ 2
h : ↑0 = ↑1
⊢ 0 = 1
[PROOFSTEP]
simp only [cast_neg, cast_one, cast_zero, neg_eq_zero, one_ne_zero, zero_ne_one, zero_eq_neg] at h ⊢
[GOAL]
case inl.inr.inr
R✝ : Type u_1
R : Type u_2
inst✝¹ : NonAssocRing R
inst✝ : Nontrivial R
hR : ringChar R ≠ 2
h : ↑0 = ↑(-1)
⊢ 0 = -1
[PROOFSTEP]
simp only [cast_neg, cast_one, cast_zero, neg_eq_zero, one_ne_zero, zero_ne_one, zero_eq_neg] at h ⊢
[GOAL]
case inr.inl.inl
R✝ : Type u_1
R : Type u_2
inst✝¹ : NonAssocRing R
inst✝ : Nontrivial R
hR : ringChar R ≠ 2
h : ↑1 = ↑0
⊢ 1 = 0
[PROOFSTEP]
simp only [cast_neg, cast_one, cast_zero, neg_eq_zero, one_ne_zero, zero_ne_one, zero_eq_neg] at h ⊢
[GOAL]
case inr.inl.inr.inl
R✝ : Type u_1
R : Type u_2
inst✝¹ : NonAssocRing R
inst✝ : Nontrivial R
hR : ringChar R ≠ 2
h : ↑1 = ↑1
⊢ 1 = 1
[PROOFSTEP]
simp only [cast_neg, cast_one, cast_zero, neg_eq_zero, one_ne_zero, zero_ne_one, zero_eq_neg] at h ⊢
[GOAL]
case inr.inl.inr.inr
R✝ : Type u_1
R : Type u_2
inst✝¹ : NonAssocRing R
inst✝ : Nontrivial R
hR : ringChar R ≠ 2
h : ↑1 = ↑(-1)
⊢ 1 = -1
[PROOFSTEP]
simp only [cast_neg, cast_one, cast_zero, neg_eq_zero, one_ne_zero, zero_ne_one, zero_eq_neg] at h ⊢
[GOAL]
case inr.inr.inl
R✝ : Type u_1
R : Type u_2
inst✝¹ : NonAssocRing R
inst✝ : Nontrivial R
hR : ringChar R ≠ 2
h : ↑(-1) = ↑0
⊢ -1 = 0
[PROOFSTEP]
simp only [cast_neg, cast_one, cast_zero, neg_eq_zero, one_ne_zero, zero_ne_one, zero_eq_neg] at h ⊢
[GOAL]
case inr.inr.inr.inl
R✝ : Type u_1
R : Type u_2
inst✝¹ : NonAssocRing R
inst✝ : Nontrivial R
hR : ringChar R ≠ 2
h : ↑(-1) = ↑1
⊢ -1 = 1
[PROOFSTEP]
simp only [cast_neg, cast_one, cast_zero, neg_eq_zero, one_ne_zero, zero_ne_one, zero_eq_neg] at h ⊢
[GOAL]
case inr.inr.inr.inr
R✝ : Type u_1
R : Type u_2
inst✝¹ : NonAssocRing R
inst✝ : Nontrivial R
hR : ringChar R ≠ 2
h : ↑(-1) = ↑(-1)
⊢ -1 = -1
[PROOFSTEP]
simp only [cast_neg, cast_one, cast_zero, neg_eq_zero, one_ne_zero, zero_ne_one, zero_eq_neg] at h ⊢
[GOAL]
case inr.inl.inr.inr
R✝ : Type u_1
R : Type u_2
inst✝¹ : NonAssocRing R
inst✝ : Nontrivial R
hR : ringChar R ≠ 2
h : 1 = -1
⊢ False
[PROOFSTEP]
exact (Ring.neg_one_ne_one_of_char_ne_two hR).symm h
[GOAL]
case inr.inr.inr.inl
R✝ : Type u_1
R : Type u_2
inst✝¹ : NonAssocRing R
inst✝ : Nontrivial R
hR : ringChar R ≠ 2
h : -1 = 1
⊢ False
[PROOFSTEP]
exact (Ring.neg_one_ne_one_of_char_ne_two hR) h
[GOAL]
R : Type u_1
inst✝¹ : AddMonoidWithOne R
r : R
n p✝ : ℕ
a : ℕ+
p : ℕ
inst✝ : CharP R p
k : ℕ
h : NeZero ↑k
⊢ ¬p ∣ k
[PROOFSTEP]
rwa [← CharP.cast_eq_zero_iff R p k, ← Ne.def, ← neZero_iff]
[GOAL]
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : Nontrivial R
⊢ CharZero R ↔ ∀ (p : ℕ), Nat.Prime p → ↑p ≠ 0
[PROOFSTEP]
refine ⟨fun h p hp => by simp [hp.ne_zero], fun h => ?_⟩
[GOAL]
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : Nontrivial R
h : CharZero R
p : ℕ
hp : Nat.Prime p
⊢ ↑p ≠ 0
[PROOFSTEP]
simp [hp.ne_zero]
[GOAL]
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : Nontrivial R
h : ∀ (p : ℕ), Nat.Prime p → ↑p ≠ 0
⊢ CharZero R
[PROOFSTEP]
let p := ringChar R
[GOAL]
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : Nontrivial R
h : ∀ (p : ℕ), Nat.Prime p → ↑p ≠ 0
p : ℕ := ringChar R
⊢ CharZero R
[PROOFSTEP]
cases CharP.char_is_prime_or_zero R p with
| inl hp => simpa using h p hp
| inr h =>
  haveI : CharP R 0 := h ▸ inferInstance
  exact CharP.charP_to_charZero R
[GOAL]
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : Nontrivial R
h : ∀ (p : ℕ), Nat.Prime p → ↑p ≠ 0
p : ℕ := ringChar R
x✝ : Nat.Prime p ∨ p = 0
⊢ CharZero R
[PROOFSTEP]
cases CharP.char_is_prime_or_zero R p with
| inl hp => simpa using h p hp
| inr h =>
  haveI : CharP R 0 := h ▸ inferInstance
  exact CharP.charP_to_charZero R
[GOAL]
case inl
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : Nontrivial R
h : ∀ (p : ℕ), Nat.Prime p → ↑p ≠ 0
p : ℕ := ringChar R
hp : Nat.Prime p
⊢ CharZero R
[PROOFSTEP]

| inl hp => simpa using h p hp
[GOAL]
case inl
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : Nontrivial R
h : ∀ (p : ℕ), Nat.Prime p → ↑p ≠ 0
p : ℕ := ringChar R
hp : Nat.Prime p
⊢ CharZero R
[PROOFSTEP]
simpa using h p hp
[GOAL]
case inr
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : Nontrivial R
h✝ : ∀ (p : ℕ), Nat.Prime p → ↑p ≠ 0
p : ℕ := ringChar R
h : p = 0
⊢ CharZero R
[PROOFSTEP]

| inr h =>
  haveI : CharP R 0 := h ▸ inferInstance
  exact CharP.charP_to_charZero R
[GOAL]
case inr
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : Nontrivial R
h✝ : ∀ (p : ℕ), Nat.Prime p → ↑p ≠ 0
p : ℕ := ringChar R
h : p = 0
⊢ CharZero R
[PROOFSTEP]
haveI : CharP R 0 := h ▸ inferInstance
[GOAL]
case inr
R : Type u_1
inst✝² : NonAssocRing R
inst✝¹ : NoZeroDivisors R
inst✝ : Nontrivial R
h✝ : ∀ (p : ℕ), Nat.Prime p → ↑p ≠ 0
p : ℕ := ringChar R
h : p = 0
this : CharP R 0
⊢ CharZero R
[PROOFSTEP]
exact CharP.charP_to_charZero R


[GOAL]
α✝ : Type u_1
β : Type u_2
inst✝² : Preorder α✝
inst✝¹ : Preorder β
s✝ t : Set α✝
α : Type u_3
inst✝ : PartialOrder α
s : Set α
hs : ∀ (x : α), x ∈ s → ∀ (y : α), y ∈ s → x < y → Ioo x y ⊆ s
⊢ OrdConnected s
[PROOFSTEP]
rw [ordConnected_iff]
[GOAL]
α✝ : Type u_1
β : Type u_2
inst✝² : Preorder α✝
inst✝¹ : Preorder β
s✝ t : Set α✝
α : Type u_3
inst✝ : PartialOrder α
s : Set α
hs : ∀ (x : α), x ∈ s → ∀ (y : α), y ∈ s → x < y → Ioo x y ⊆ s
⊢ ∀ (x : α), x ∈ s → ∀ (y : α), y ∈ s → x ≤ y → Icc x y ⊆ s
[PROOFSTEP]
intro x hx y hy hxy
[GOAL]
α✝ : Type u_1
β : Type u_2
inst✝² : Preorder α✝
inst✝¹ : Preorder β
s✝ t : Set α✝
α : Type u_3
inst✝ : PartialOrder α
s : Set α
hs : ∀ (x : α), x ∈ s → ∀ (y : α), y ∈ s → x < y → Ioo x y ⊆ s
x : α
hx : x ∈ s
y : α
hy : y ∈ s
hxy : x ≤ y
⊢ Icc x y ⊆ s
[PROOFSTEP]
rcases eq_or_lt_of_le hxy with (rfl | hxy')
[GOAL]
case inl
α✝ : Type u_1
β : Type u_2
inst✝² : Preorder α✝
inst✝¹ : Preorder β
s✝ t : Set α✝
α : Type u_3
inst✝ : PartialOrder α
s : Set α
hs : ∀ (x : α), x ∈ s → ∀ (y : α), y ∈ s → x < y → Ioo x y ⊆ s
x : α
hx hy : x ∈ s
hxy : x ≤ x
⊢ Icc x x ⊆ s
[PROOFSTEP]
simpa
[GOAL]
case inr
α✝ : Type u_1
β : Type u_2
inst✝² : Preorder α✝
inst✝¹ : Preorder β
s✝ t : Set α✝
α : Type u_3
inst✝ : PartialOrder α
s : Set α
hs : ∀ (x : α), x ∈ s → ∀ (y : α), y ∈ s → x < y → Ioo x y ⊆ s
x : α
hx : x ∈ s
y : α
hy : y ∈ s
hxy : x ≤ y
hxy' : x < y
⊢ Icc x y ⊆ s
[PROOFSTEP]
rw [← Ioc_insert_left hxy, ← Ioo_insert_right hxy']
[GOAL]
case inr
α✝ : Type u_1
β : Type u_2
inst✝² : Preorder α✝
inst✝¹ : Preorder β
s✝ t : Set α✝
α : Type u_3
inst✝ : PartialOrder α
s : Set α
hs : ∀ (x : α), x ∈ s → ∀ (y : α), y ∈ s → x < y → Ioo x y ⊆ s
x : α
hx : x ∈ s
y : α
hy : y ∈ s
hxy : x ≤ y
hxy' : x < y
⊢ insert x (insert y (Ioo x y)) ⊆ s
[PROOFSTEP]
exact insert_subset_iff.2 ⟨hx, insert_subset_iff.2 ⟨hy, hs x hx y hy hxy'⟩⟩
[GOAL]
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : Preorder β
s✝ t s : Set α
h : OrdConnected (↑ofDual ⁻¹' s)
⊢ OrdConnected s
[PROOFSTEP]
simpa only [ordConnected_def] using h.dual
[GOAL]
α✝ : Type u_1
β : Type u_2
inst✝² : Preorder α✝
inst✝¹ : Preorder β
s t : Set α✝
α : Type u_3
inst✝ : PartialOrder α
a : α
⊢ OrdConnected {a}
[PROOFSTEP]
rw [← Icc_self]
[GOAL]
α✝ : Type u_1
β : Type u_2
inst✝² : Preorder α✝
inst✝¹ : Preorder β
s t : Set α✝
α : Type u_3
inst✝ : PartialOrder α
a : α
⊢ OrdConnected (Icc a a)
[PROOFSTEP]
exact ordConnected_Icc
[GOAL]
α : Type u_1
β : Type u_2
inst✝² : Preorder α
inst✝¹ : Preorder β
s✝ t : Set α
E : Type u_3
inst✝ : OrderIsoClass E α β
e : E
s : Set α
hs : OrdConnected s
⊢ OrdConnected (↑e '' s)
[PROOFSTEP]
erw [(e : α ≃o β).image_eq_preimage]
[GOAL]
α : Type u_1
β : Type u_2
inst✝² : Preorder α
inst✝¹ : Preorder β
s✝ t : Set α
E : Type u_3
inst✝ : OrderIsoClass E α β
e : E
s : Set α
hs : OrdConnected s
⊢ OrdConnected (↑(OrderIso.symm ↑e) ⁻¹' s)
[PROOFSTEP]
apply ordConnected_preimage (e : α ≃o β).symm
[GOAL]
α : Type u_1
β : Type u_2
inst✝² : Preorder α
inst✝¹ : Preorder β
s t : Set α
E : Type u_3
inst✝ : OrderIsoClass E α β
e : E
⊢ OrdConnected (range ↑e)
[PROOFSTEP]
simp_rw [← image_univ]
[GOAL]
α : Type u_1
β : Type u_2
inst✝² : Preorder α
inst✝¹ : Preorder β
s t : Set α
E : Type u_3
inst✝ : OrderIsoClass E α β
e : E
⊢ OrdConnected (↑e '' univ)
[PROOFSTEP]
exact ordConnected_image (e : α ≃o β)
[GOAL]
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : Preorder β
s✝ t s : Set α
⊢ OrdConnected (↑ofDual ⁻¹' s) ↔ OrdConnected s
[PROOFSTEP]
simp_rw [ordConnected_def, toDual.surjective.forall, dual_Icc, Subtype.forall']
[GOAL]
α : Type u_1
β : Type u_2
inst✝¹ : Preorder α
inst✝ : Preorder β
s✝ t s : Set α
⊢ (∀ (x x_1 : { a // ↑toDual a ∈ ↑ofDual ⁻¹' s }), ↑ofDual ⁻¹' Icc ↑x_1 ↑x ⊆ ↑ofDual ⁻¹' s) ↔
    ∀ (x x_1 : { a // a ∈ s }), Icc ↑x ↑x_1 ⊆ s
[PROOFSTEP]
exact forall_swap
[GOAL]
α : Type u_1
inst✝ : PartialOrder α
s : Set α
hs : IsAntichain (fun x x_1 => x ≤ x_1) s
x : α
hx : x ∈ s
y : α
hy : y ∈ s
z : α
hz : z ∈ Icc x y
⊢ z ∈ s
[PROOFSTEP]
obtain rfl := hs.eq hx hy (hz.1.trans hz.2)
[GOAL]
α : Type u_1
inst✝ : PartialOrder α
s : Set α
hs : IsAntichain (fun x x_1 => x ≤ x_1) s
x : α
hx : x ∈ s
z : α
hy : x ∈ s
hz : z ∈ Icc x x
⊢ z ∈ s
[PROOFSTEP]
rw [Icc_self, mem_singleton_iff] at hz
[GOAL]
α : Type u_1
inst✝ : PartialOrder α
s : Set α
hs : IsAntichain (fun x x_1 => x ≤ x_1) s
x : α
hx : x ∈ s
z : α
hy : x ∈ s
hz : z = x
⊢ z ∈ s
[PROOFSTEP]
rwa [hz]
[GOAL]
α : Type u_1
inst✝ : LinearOrder α
s : Set α
x : α
h : ∀ (y : α), y ∈ s → [[x, y]] ⊆ s
y : α
hy : y ∈ s
z : α
hz : z ∈ s
⊢ [[y, x]] ∪ [[x, z]] = [[x, y]] ∪ [[x, z]]
[PROOFSTEP]
rw [uIcc_comm]
[GOAL]
α : Type u_1
inst✝ : LinearOrder α
s : Set α
x : α
hx : x ∈ s
⊢ OrdConnected s ↔ ∀ ⦃y : α⦄, y ∈ s → [[y, x]] ⊆ s
[PROOFSTEP]
simp_rw [ordConnected_iff_uIcc_subset_left hx, uIcc_comm]


[GOAL]
R : Type u
inst✝ : Ring R
ι : Type v
Z : ι → ModuleCatMax R
s : Cone (Discrete.functor Z)
j : Discrete ι
⊢ (fun s => LinearMap.pi fun j => NatTrans.app s.π { as := j }) s ≫ NatTrans.app (productCone Z).π j =
    NatTrans.app s.π j
[PROOFSTEP]
cases j
[GOAL]
case mk
R : Type u
inst✝ : Ring R
ι : Type v
Z : ι → ModuleCatMax R
s : Cone (Discrete.functor Z)
as✝ : ι
⊢ (fun s => LinearMap.pi fun j => NatTrans.app s.π { as := j }) s ≫ NatTrans.app (productCone Z).π { as := as✝ } =
    NatTrans.app s.π { as := as✝ }
[PROOFSTEP]
aesop
[GOAL]
R : Type u
inst✝ : Ring R
ι : Type v
Z : ι → ModuleCatMax R
s : Cone (Discrete.functor Z)
m : s.pt ⟶ (productCone Z).pt
w : ∀ (j : Discrete ι), m ≫ NatTrans.app (productCone Z).π j = NatTrans.app s.π j
⊢ m = (fun s => LinearMap.pi fun j => NatTrans.app s.π { as := j }) s
[PROOFSTEP]
ext x
[GOAL]
case h
R : Type u
inst✝ : Ring R
ι : Type v
Z : ι → ModuleCatMax R
s : Cone (Discrete.functor Z)
m : s.pt ⟶ (productCone Z).pt
w : ∀ (j : Discrete ι), m ≫ NatTrans.app (productCone Z).π j = NatTrans.app s.π j
x : ↑s.pt
⊢ ↑m x = ↑((fun s => LinearMap.pi fun j => NatTrans.app s.π { as := j }) s) x
[PROOFSTEP]
funext i
[GOAL]
case h.h
R : Type u
inst✝ : Ring R
ι : Type v
Z : ι → ModuleCatMax R
s : Cone (Discrete.functor Z)
m : s.pt ⟶ (productCone Z).pt
w : ∀ (j : Discrete ι), m ≫ NatTrans.app (productCone Z).π j = NatTrans.app s.π j
x : ↑s.pt
i : ι
⊢ ↑m x i = ↑((fun s => LinearMap.pi fun j => NatTrans.app s.π { as := j }) s) x i
[PROOFSTEP]
exact LinearMap.congr_fun (w ⟨i⟩) x


[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : IsBezout R
x y : R
⊢ Submodule.IsPrincipal (Ideal.span {x, y})
[PROOFSTEP]
classical exact isPrincipal_of_FG (Ideal.span { x, y }) ⟨{ x, y }, by simp⟩
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : IsBezout R
x y : R
⊢ Submodule.IsPrincipal (Ideal.span {x, y})
[PROOFSTEP]
exact isPrincipal_of_FG (Ideal.span { x, y }) ⟨{ x, y }, by simp⟩
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : IsBezout R
x y : R
⊢ Ideal.span ↑{x, y} = Ideal.span {x, y}
[PROOFSTEP]
simp
[GOAL]
R : Type u
inst✝ : CommRing R
⊢ IsBezout R ↔ ∀ (x y : R), Submodule.IsPrincipal (Ideal.span {x, y})
[PROOFSTEP]
classical
constructor
· intro H x y; infer_instance
· intro H
  constructor
  apply Submodule.fg_induction
  · exact fun _ => ⟨⟨_, rfl⟩⟩
  · rintro _ _ ⟨⟨x, rfl⟩⟩ ⟨⟨y, rfl⟩⟩; rw [← Submodule.span_insert]; exact H _ _
[GOAL]
R : Type u
inst✝ : CommRing R
⊢ IsBezout R ↔ ∀ (x y : R), Submodule.IsPrincipal (Ideal.span {x, y})
[PROOFSTEP]
constructor
[GOAL]
case mp
R : Type u
inst✝ : CommRing R
⊢ IsBezout R → ∀ (x y : R), Submodule.IsPrincipal (Ideal.span {x, y})
[PROOFSTEP]
intro H x y
[GOAL]
case mp
R : Type u
inst✝ : CommRing R
H : IsBezout R
x y : R
⊢ Submodule.IsPrincipal (Ideal.span {x, y})
[PROOFSTEP]
infer_instance
[GOAL]
case mpr
R : Type u
inst✝ : CommRing R
⊢ (∀ (x y : R), Submodule.IsPrincipal (Ideal.span {x, y})) → IsBezout R
[PROOFSTEP]
intro H
[GOAL]
case mpr
R : Type u
inst✝ : CommRing R
H : ∀ (x y : R), Submodule.IsPrincipal (Ideal.span {x, y})
⊢ IsBezout R
[PROOFSTEP]
constructor
[GOAL]
case mpr.isPrincipal_of_FG
R : Type u
inst✝ : CommRing R
H : ∀ (x y : R), Submodule.IsPrincipal (Ideal.span {x, y})
⊢ ∀ (I : Ideal R), Ideal.FG I → Submodule.IsPrincipal I
[PROOFSTEP]
apply Submodule.fg_induction
[GOAL]
case mpr.isPrincipal_of_FG.h₁
R : Type u
inst✝ : CommRing R
H : ∀ (x y : R), Submodule.IsPrincipal (Ideal.span {x, y})
⊢ ∀ (x : R), Submodule.IsPrincipal (Submodule.span R {x})
[PROOFSTEP]
exact fun _ => ⟨⟨_, rfl⟩⟩
[GOAL]
case mpr.isPrincipal_of_FG.h₂
R : Type u
inst✝ : CommRing R
H : ∀ (x y : R), Submodule.IsPrincipal (Ideal.span {x, y})
⊢ ∀ (M₁ M₂ : Submodule R R), Submodule.IsPrincipal M₁ → Submodule.IsPrincipal M₂ → Submodule.IsPrincipal (M₁ ⊔ M₂)
[PROOFSTEP]
rintro _ _ ⟨⟨x, rfl⟩⟩ ⟨⟨y, rfl⟩⟩
[GOAL]
case mpr.isPrincipal_of_FG.h₂.mk.intro.mk.intro
R : Type u
inst✝ : CommRing R
H : ∀ (x y : R), Submodule.IsPrincipal (Ideal.span {x, y})
x y : R
⊢ Submodule.IsPrincipal (Submodule.span R {x} ⊔ Submodule.span R {y})
[PROOFSTEP]
rw [← Submodule.span_insert]
[GOAL]
case mpr.isPrincipal_of_FG.h₂.mk.intro.mk.intro
R : Type u
inst✝ : CommRing R
H : ∀ (x y : R), Submodule.IsPrincipal (Ideal.span {x, y})
x y : R
⊢ Submodule.IsPrincipal (Submodule.span R {x, y})
[PROOFSTEP]
exact H _ _
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : IsBezout R
x y : R
⊢ x ∈ {x, y}
[PROOFSTEP]
simp
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : IsBezout R
x y : R
⊢ y ∈ {x, y}
[PROOFSTEP]
simp
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : IsBezout R
x y z : R
hx : z ∣ x
hy : z ∣ y
⊢ z ∣ gcd x y
[PROOFSTEP]
rw [← Ideal.span_singleton_le_span_singleton] at hx hy ⊢
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : IsBezout R
x y z : R
hx : Ideal.span {x} ≤ Ideal.span {z}
hy : Ideal.span {y} ≤ Ideal.span {z}
⊢ Ideal.span {gcd x y} ≤ Ideal.span {z}
[PROOFSTEP]
rw [span_gcd, Ideal.span_insert, sup_le_iff]
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : IsBezout R
x y z : R
hx : Ideal.span {x} ≤ Ideal.span {z}
hy : Ideal.span {y} ≤ Ideal.span {z}
⊢ Ideal.span {x} ≤ Ideal.span {z} ∧ Ideal.span {y} ≤ Ideal.span {z}
[PROOFSTEP]
exact ⟨hx, hy⟩
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : IsBezout R
x y : R
⊢ gcd x y ∈ Ideal.span {x, y}
[PROOFSTEP]
rw [← span_gcd]
[GOAL]
R : Type u
inst✝¹ : CommRing R
inst✝ : IsBezout R
x y : R
⊢ gcd x y ∈ Ideal.span {gcd x y}
[PROOFSTEP]
apply Ideal.subset_span
[GOAL]
case a
R : Type u
inst✝¹ : CommRing R
inst✝ : IsBezout R
x y : R
⊢ gcd x y ∈ {gcd x y}
[PROOFSTEP]
simp
[GOAL]
R : Type u
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : IsBezout R
⊢ IsIntegrallyClosed R
[PROOFSTEP]
classical exact GCDMonoid.toIsIntegrallyClosed
[GOAL]
R : Type u
inst✝² : CommRing R
inst✝¹ : IsDomain R
inst✝ : IsBezout R
⊢ IsIntegrallyClosed R
[PROOFSTEP]
exact GCDMonoid.toIsIntegrallyClosed
[GOAL]
R : Type u
inst✝² : CommRing R
S : Type v
inst✝¹ : CommRing S
f : R →+* S
hf : Function.Surjective ↑f
inst✝ : IsBezout R
⊢ IsBezout S
[PROOFSTEP]
rw [iff_span_pair_isPrincipal]
[GOAL]
R : Type u
inst✝² : CommRing R
S : Type v
inst✝¹ : CommRing S
f : R →+* S
hf : Function.Surjective ↑f
inst✝ : IsBezout R
⊢ ∀ (x y : S), Submodule.IsPrincipal (Ideal.span {x, y})
[PROOFSTEP]
intro x y
[GOAL]
R : Type u
inst✝² : CommRing R
S : Type v
inst✝¹ : CommRing S
f : R →+* S
hf : Function.Surjective ↑f
inst✝ : IsBezout R
x y : S
⊢ Submodule.IsPrincipal (Ideal.span {x, y})
[PROOFSTEP]
obtain ⟨⟨x, rfl⟩, ⟨y, rfl⟩⟩ := hf x, hf y
[GOAL]
case intro.intro
R : Type u
inst✝² : CommRing R
S : Type v
inst✝¹ : CommRing S
f : R →+* S
hf : Function.Surjective ↑f
inst✝ : IsBezout R
x y : R
⊢ Submodule.IsPrincipal (Ideal.span {↑f x, ↑f y})
[PROOFSTEP]
use f (gcd x y)
[GOAL]
case h
R : Type u
inst✝² : CommRing R
S : Type v
inst✝¹ : CommRing S
f : R →+* S
hf : Function.Surjective ↑f
inst✝ : IsBezout R
x y : R
⊢ Ideal.span {↑f x, ↑f y} = Submodule.span S {↑f (gcd x y)}
[PROOFSTEP]
trans Ideal.map f (Ideal.span {gcd x y})
[GOAL]
R : Type u
inst✝² : CommRing R
S : Type v
inst✝¹ : CommRing S
f : R →+* S
hf : Function.Surjective ↑f
inst✝ : IsBezout R
x y : R
⊢ Ideal.span {↑f x, ↑f y} = Ideal.map f (Ideal.span {gcd x y})
[PROOFSTEP]
rw [span_gcd, Ideal.map_span, Set.image_insert_eq, Set.image_singleton]
[GOAL]
R : Type u
inst✝² : CommRing R
S : Type v
inst✝¹ : CommRing S
f : R →+* S
hf : Function.Surjective ↑f
inst✝ : IsBezout R
x y : R
⊢ Ideal.map f (Ideal.span {gcd x y}) = Submodule.span S {↑f (gcd x y)}
[PROOFSTEP]
rw [Ideal.map_span, Set.image_singleton]
[GOAL]
R : Type u
inst✝² : CommRing R
S : Type v
inst✝¹ : CommRing S
f : R →+* S
hf : Function.Surjective ↑f
inst✝ : IsBezout R
x y : R
⊢ Ideal.span {↑f (gcd x y)} = Submodule.span S {↑f (gcd x y)}
[PROOFSTEP]
rfl
[GOAL]
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
⊢ List.TFAE [IsNoetherianRing R, IsPrincipalIdealRing R, UniqueFactorizationMonoid R, WfDvdMonoid R]
[PROOFSTEP]
classical
tfae_have 1 → 2
· intro H; exact ⟨fun I => isPrincipal_of_FG _ (IsNoetherian.noetherian _)⟩
tfae_have 2 → 3
· intro; infer_instance
tfae_have 3 → 4
· intro; infer_instance
tfae_have 4 → 1
· rintro ⟨h⟩
  rw [isNoetherianRing_iff, isNoetherian_iff_fg_wellFounded]
  apply RelEmbedding.wellFounded _ h
  have : ∀ I : { J : Ideal R // J.FG }, ∃ x : R, (I : Ideal R) = Ideal.span { x } := fun ⟨I, hI⟩ =>
    (IsBezout.isPrincipal_of_FG I hI).1
  choose f hf using this
  exact
    { toFun := f
      inj' := fun x y e => by ext1; rw [hf, hf, e]
      map_rel_iff' := by
        dsimp
        intro a b
        rw [← Ideal.span_singleton_lt_span_singleton, ← hf, ← hf]
        rfl }
tfae_finish
[GOAL]
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
⊢ List.TFAE [IsNoetherianRing R, IsPrincipalIdealRing R, UniqueFactorizationMonoid R, WfDvdMonoid R]
[PROOFSTEP]
tfae_have 1 → 2
[GOAL]
case tfae_1_to_2
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
⊢ IsNoetherianRing R → IsPrincipalIdealRing R
[PROOFSTEP]
intro H
[GOAL]
case tfae_1_to_2
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
H : IsNoetherianRing R
⊢ IsPrincipalIdealRing R
[PROOFSTEP]
exact ⟨fun I => isPrincipal_of_FG _ (IsNoetherian.noetherian _)⟩
[GOAL]
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
⊢ List.TFAE [IsNoetherianRing R, IsPrincipalIdealRing R, UniqueFactorizationMonoid R, WfDvdMonoid R]
[PROOFSTEP]
tfae_have 2 → 3
[GOAL]
case tfae_2_to_3
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
⊢ IsPrincipalIdealRing R → UniqueFactorizationMonoid R
[PROOFSTEP]
intro
[GOAL]
case tfae_2_to_3
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
✝ : IsPrincipalIdealRing R
⊢ UniqueFactorizationMonoid R
[PROOFSTEP]
infer_instance
[GOAL]
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
tfae_2_to_3 : IsPrincipalIdealRing R → UniqueFactorizationMonoid R
⊢ List.TFAE [IsNoetherianRing R, IsPrincipalIdealRing R, UniqueFactorizationMonoid R, WfDvdMonoid R]
[PROOFSTEP]
tfae_have 3 → 4
[GOAL]
case tfae_3_to_4
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
tfae_2_to_3 : IsPrincipalIdealRing R → UniqueFactorizationMonoid R
⊢ UniqueFactorizationMonoid R → WfDvdMonoid R
[PROOFSTEP]
intro
[GOAL]
case tfae_3_to_4
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
tfae_2_to_3 : IsPrincipalIdealRing R → UniqueFactorizationMonoid R
✝ : UniqueFactorizationMonoid R
⊢ WfDvdMonoid R
[PROOFSTEP]
infer_instance
[GOAL]
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
tfae_2_to_3 : IsPrincipalIdealRing R → UniqueFactorizationMonoid R
tfae_3_to_4 : UniqueFactorizationMonoid R → WfDvdMonoid R
⊢ List.TFAE [IsNoetherianRing R, IsPrincipalIdealRing R, UniqueFactorizationMonoid R, WfDvdMonoid R]
[PROOFSTEP]
tfae_have 4 → 1
[GOAL]
case tfae_4_to_1
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
tfae_2_to_3 : IsPrincipalIdealRing R → UniqueFactorizationMonoid R
tfae_3_to_4 : UniqueFactorizationMonoid R → WfDvdMonoid R
⊢ WfDvdMonoid R → IsNoetherianRing R
[PROOFSTEP]
rintro ⟨h⟩
[GOAL]
case tfae_4_to_1.mk
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
tfae_2_to_3 : IsPrincipalIdealRing R → UniqueFactorizationMonoid R
tfae_3_to_4 : UniqueFactorizationMonoid R → WfDvdMonoid R
h : WellFounded DvdNotUnit
⊢ IsNoetherianRing R
[PROOFSTEP]
rw [isNoetherianRing_iff, isNoetherian_iff_fg_wellFounded]
[GOAL]
case tfae_4_to_1.mk
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
tfae_2_to_3 : IsPrincipalIdealRing R → UniqueFactorizationMonoid R
tfae_3_to_4 : UniqueFactorizationMonoid R → WfDvdMonoid R
h : WellFounded DvdNotUnit
⊢ WellFounded fun x x_1 => x > x_1
[PROOFSTEP]
apply RelEmbedding.wellFounded _ h
[GOAL]
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
tfae_2_to_3 : IsPrincipalIdealRing R → UniqueFactorizationMonoid R
tfae_3_to_4 : UniqueFactorizationMonoid R → WfDvdMonoid R
h : WellFounded DvdNotUnit
⊢ (fun x x_1 => x > x_1) ↪r DvdNotUnit
[PROOFSTEP]
have : ∀ I : { J : Ideal R // J.FG }, ∃ x : R, (I : Ideal R) = Ideal.span { x } := fun ⟨I, hI⟩ =>
  (IsBezout.isPrincipal_of_FG I hI).1
[GOAL]
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
tfae_2_to_3 : IsPrincipalIdealRing R → UniqueFactorizationMonoid R
tfae_3_to_4 : UniqueFactorizationMonoid R → WfDvdMonoid R
h : WellFounded DvdNotUnit
this : ∀ (I : { J // Ideal.FG J }), ∃ x, ↑I = Ideal.span {x}
⊢ (fun x x_1 => x > x_1) ↪r DvdNotUnit
[PROOFSTEP]
choose f hf using this
[GOAL]
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
tfae_2_to_3 : IsPrincipalIdealRing R → UniqueFactorizationMonoid R
tfae_3_to_4 : UniqueFactorizationMonoid R → WfDvdMonoid R
h : WellFounded DvdNotUnit
f : { J // Ideal.FG J } → R
hf : ∀ (I : { J // Ideal.FG J }), ↑I = Ideal.span {f I}
⊢ (fun x x_1 => x > x_1) ↪r DvdNotUnit
[PROOFSTEP]
exact
  { toFun := f
    inj' := fun x y e => by ext1; rw [hf, hf, e]
    map_rel_iff' := by
      dsimp
      intro a b
      rw [← Ideal.span_singleton_lt_span_singleton, ← hf, ← hf]
      rfl }
[GOAL]
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
tfae_2_to_3 : IsPrincipalIdealRing R → UniqueFactorizationMonoid R
tfae_3_to_4 : UniqueFactorizationMonoid R → WfDvdMonoid R
h : WellFounded DvdNotUnit
f : { J // Ideal.FG J } → R
hf : ∀ (I : { J // Ideal.FG J }), ↑I = Ideal.span {f I}
x y : { N // Submodule.FG N }
e : f x = f y
⊢ x = y
[PROOFSTEP]
ext1
[GOAL]
case a
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
tfae_2_to_3 : IsPrincipalIdealRing R → UniqueFactorizationMonoid R
tfae_3_to_4 : UniqueFactorizationMonoid R → WfDvdMonoid R
h : WellFounded DvdNotUnit
f : { J // Ideal.FG J } → R
hf : ∀ (I : { J // Ideal.FG J }), ↑I = Ideal.span {f I}
x y : { N // Submodule.FG N }
e : f x = f y
⊢ ↑x = ↑y
[PROOFSTEP]
rw [hf, hf, e]
[GOAL]
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
tfae_2_to_3 : IsPrincipalIdealRing R → UniqueFactorizationMonoid R
tfae_3_to_4 : UniqueFactorizationMonoid R → WfDvdMonoid R
h : WellFounded DvdNotUnit
f : { J // Ideal.FG J } → R
hf : ∀ (I : { J // Ideal.FG J }), ↑I = Ideal.span {f I}
⊢ ∀ {a b : { N // Submodule.FG N }},
    DvdNotUnit (↑{ toFun := f, inj' := (_ : ∀ (x y : { N // Submodule.FG N }), f x = f y → x = y) } a)
        (↑{ toFun := f, inj' := (_ : ∀ (x y : { N // Submodule.FG N }), f x = f y → x = y) } b) ↔
      a > b
[PROOFSTEP]
dsimp
[GOAL]
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
tfae_2_to_3 : IsPrincipalIdealRing R → UniqueFactorizationMonoid R
tfae_3_to_4 : UniqueFactorizationMonoid R → WfDvdMonoid R
h : WellFounded DvdNotUnit
f : { J // Ideal.FG J } → R
hf : ∀ (I : { J // Ideal.FG J }), ↑I = Ideal.span {f I}
⊢ ∀ {a b : { N // Submodule.FG N }}, DvdNotUnit (f a) (f b) ↔ a > b
[PROOFSTEP]
intro a b
[GOAL]
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
tfae_2_to_3 : IsPrincipalIdealRing R → UniqueFactorizationMonoid R
tfae_3_to_4 : UniqueFactorizationMonoid R → WfDvdMonoid R
h : WellFounded DvdNotUnit
f : { J // Ideal.FG J } → R
hf : ∀ (I : { J // Ideal.FG J }), ↑I = Ideal.span {f I}
a b : { N // Submodule.FG N }
⊢ DvdNotUnit (f a) (f b) ↔ a > b
[PROOFSTEP]
rw [← Ideal.span_singleton_lt_span_singleton, ← hf, ← hf]
[GOAL]
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
tfae_2_to_3 : IsPrincipalIdealRing R → UniqueFactorizationMonoid R
tfae_3_to_4 : UniqueFactorizationMonoid R → WfDvdMonoid R
h : WellFounded DvdNotUnit
f : { J // Ideal.FG J } → R
hf : ∀ (I : { J // Ideal.FG J }), ↑I = Ideal.span {f I}
a b : { N // Submodule.FG N }
⊢ ↑b < ↑a ↔ a > b
[PROOFSTEP]
rfl
[GOAL]
R : Type u
inst✝² : CommRing R
inst✝¹ : IsBezout R
inst✝ : IsDomain R
tfae_1_to_2 : IsNoetherianRing R → IsPrincipalIdealRing R
tfae_2_to_3 : IsPrincipalIdealRing R → UniqueFactorizationMonoid R
tfae_3_to_4 : UniqueFactorizationMonoid R → WfDvdMonoid R
tfae_4_to_1 : WfDvdMonoid R → IsNoetherianRing R
⊢ List.TFAE [IsNoetherianRing R, IsPrincipalIdealRing R, UniqueFactorizationMonoid R, WfDvdMonoid R]
[PROOFSTEP]
tfae_finish


[GOAL]
α : Type u_1
β : α → Type u_2
inst✝ : DecidableEq α
s t : Multiset α
a : α
n : ℕ
⊢ ↑toDFinsupp (replicate n a) = DFinsupp.single a n
[PROOFSTEP]
ext i
[GOAL]
case h
α : Type u_1
β : α → Type u_2
inst✝ : DecidableEq α
s t : Multiset α
a : α
n : ℕ
i : α
⊢ ↑(↑toDFinsupp (replicate n a)) i = ↑(DFinsupp.single a n) i
[PROOFSTEP]
dsimp [toDFinsupp]
[GOAL]
case h
α : Type u_1
β : α → Type u_2
inst✝ : DecidableEq α
s t : Multiset α
a : α
n : ℕ
i : α
⊢ count i (replicate n a) = ↑(DFinsupp.single a n) i
[PROOFSTEP]
simp [count_replicate, eq_comm]
[GOAL]
α : Type u_1
β : α → Type u_2
inst✝ : DecidableEq α
s t : Multiset α
a : α
⊢ ↑toDFinsupp {a} = DFinsupp.single a 1
[PROOFSTEP]
rw [← replicate_one, toDFinsupp_replicate]
[GOAL]
α : Type u_1
β : α → Type u_2
inst✝ : DecidableEq α
s t : Multiset α
⊢ AddMonoidHom.comp DFinsupp.toMultiset toDFinsupp = AddMonoidHom.id (Multiset α)
[PROOFSTEP]
ext
[GOAL]
case h.a
α : Type u_1
β : α → Type u_2
inst✝ : DecidableEq α
s t : Multiset α
x✝ a✝ : α
⊢ count a✝ (↑(AddMonoidHom.comp DFinsupp.toMultiset toDFinsupp) {x✝}) = count a✝ (↑(AddMonoidHom.id (Multiset α)) {x✝})
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
β : α → Type u_2
inst✝ : DecidableEq α
s t : Multiset α
⊢ AddMonoidHom.comp toDFinsupp DFinsupp.toMultiset = AddMonoidHom.id (Π₀ (x : α), ℕ)
[PROOFSTEP]
ext
[GOAL]
case H.a.h
α : Type u_1
β : α → Type u_2
inst✝ : DecidableEq α
s t : Multiset α
x✝ i✝ : α
⊢ ↑(↑(AddMonoidHom.comp (AddMonoidHom.comp toDFinsupp DFinsupp.toMultiset) (DFinsupp.singleAddHom (fun i => ℕ) x✝)) 1)
      i✝ =
    ↑(↑(AddMonoidHom.comp (AddMonoidHom.id (Π₀ (x : α), ℕ)) (DFinsupp.singleAddHom (fun i => ℕ) x✝)) 1) i✝
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
β : α → Type u_2
inst✝ : DecidableEq α
s t : Multiset α
⊢ ↑toDFinsupp s ≤ ↑toDFinsupp t ↔ s ≤ t
[PROOFSTEP]
simp [Multiset.le_iff_count, DFinsupp.le_def]
[GOAL]
α : Type u_1
β : α → Type u_2
inst✝ : DecidableEq α
s✝ t✝ s t : Multiset α
⊢ ↑toDFinsupp (s ∩ t) = ↑toDFinsupp s ⊓ ↑toDFinsupp t
[PROOFSTEP]
ext i
[GOAL]
case h
α : Type u_1
β : α → Type u_2
inst✝ : DecidableEq α
s✝ t✝ s t : Multiset α
i : α
⊢ ↑(↑toDFinsupp (s ∩ t)) i = ↑(↑toDFinsupp s ⊓ ↑toDFinsupp t) i
[PROOFSTEP]
simp [inf_eq_min]
[GOAL]
α : Type u_1
β : α → Type u_2
inst✝ : DecidableEq α
s✝ t✝ s t : Multiset α
⊢ ↑toDFinsupp (s ∪ t) = ↑toDFinsupp s ⊔ ↑toDFinsupp t
[PROOFSTEP]
ext i
[GOAL]
case h
α : Type u_1
β : α → Type u_2
inst✝ : DecidableEq α
s✝ t✝ s t : Multiset α
i : α
⊢ ↑(↑toDFinsupp (s ∪ t)) i = ↑(↑toDFinsupp s ⊔ ↑toDFinsupp t) i
[PROOFSTEP]
simp [sup_eq_max]
[GOAL]
α : Type u_1
β : α → Type u_2
inst✝ : DecidableEq α
f g : Π₀ (_a : α), ℕ
⊢ ↑toMultiset f ≤ ↑toMultiset g ↔ f ≤ g
[PROOFSTEP]
simp_rw [← Multiset.toDFinsupp_le_toDFinsupp, toMultiset_toDFinsupp]
[GOAL]
α : Type u_1
β : α → Type u_2
inst✝ : DecidableEq α
f g : Π₀ (_a : α), ℕ
⊢ ↑toMultiset f < ↑toMultiset g ↔ f < g
[PROOFSTEP]
simp_rw [← Multiset.toDFinsupp_lt_toDFinsupp, toMultiset_toDFinsupp]
[GOAL]
α : Type u_1
β : α → Type u_2
inst✝ : DecidableEq α
f g : Π₀ (_a : α), ℕ
⊢ ↑Multiset.toDFinsupp (↑toMultiset (f ⊓ g)) = ↑Multiset.toDFinsupp (↑toMultiset f ∩ ↑toMultiset g)
[PROOFSTEP]
simp
[GOAL]
α : Type u_1
β : α → Type u_2
inst✝ : DecidableEq α
f g : Π₀ (_a : α), ℕ
⊢ ↑Multiset.toDFinsupp (↑toMultiset (f ⊔ g)) = ↑Multiset.toDFinsupp (↑toMultiset f ∪ ↑toMultiset g)
[PROOFSTEP]
simp


[GOAL]
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
n : ℕ
hnil : IsNilpotent r
⊢ IsNilpotent (↑C r * X ^ n)
[PROOFSTEP]
refine' Commute.isNilpotent_mul_left (commute_X_pow _ _).symm _
[GOAL]
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
n : ℕ
hnil : IsNilpotent r
⊢ IsNilpotent (↑C r)
[PROOFSTEP]
obtain ⟨m, hm⟩ := hnil
[GOAL]
case intro
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
n m : ℕ
hm : r ^ m = 0
⊢ IsNilpotent (↑C r)
[PROOFSTEP]
refine' ⟨m, _⟩
[GOAL]
case intro
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
n m : ℕ
hm : r ^ m = 0
⊢ ↑C r ^ m = 0
[PROOFSTEP]
rw [← C_pow, hm, C_0]
[GOAL]
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
n : ℕ
hnil : IsNilpotent r
⊢ IsNilpotent (X ^ n * ↑C r)
[PROOFSTEP]
rw [commute_X_pow]
[GOAL]
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
n : ℕ
hnil : IsNilpotent r
⊢ IsNilpotent (↑C r * X ^ n)
[PROOFSTEP]
exact isNilpotent_C_mul_pow_X_of_isNilpotent n hnil
[GOAL]
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
n k : ℕ
⊢ ↑(monomial n) r ^ k = 0 ↔ r ^ k = 0
[PROOFSTEP]
simp
[GOAL]
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
k : ℕ
⊢ ↑C r ^ k = 0 ↔ r ^ k = 0
[PROOFSTEP]
simpa only [← C_pow] using C_eq_zero
[GOAL]
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
⊢ IsNilpotent (X * P) ↔ IsNilpotent P
[PROOFSTEP]
refine' ⟨fun h ↦ _, _⟩
[GOAL]
case refine'_1
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
h : IsNilpotent (X * P)
⊢ IsNilpotent P
[PROOFSTEP]
rwa [Commute.isNilpotent_mul_right_iff (commute_X P) (by simp)] at h
[GOAL]
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
h : IsNilpotent (X * P)
⊢ X ∈ nonZeroDivisorsRight R[X]
[PROOFSTEP]
simp
[GOAL]
case refine'_2
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
⊢ IsNilpotent P → IsNilpotent (X * P)
[PROOFSTEP]
rintro ⟨k, hk⟩
[GOAL]
case refine'_2.intro
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
k : ℕ
hk : P ^ k = 0
⊢ IsNilpotent (X * P)
[PROOFSTEP]
exact ⟨k, by simp [(commute_X P).mul_pow, hk]⟩
[GOAL]
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
k : ℕ
hk : P ^ k = 0
⊢ (X * P) ^ k = 0
[PROOFSTEP]
simp [(commute_X P).mul_pow, hk]
[GOAL]
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
⊢ IsNilpotent (P * X) ↔ IsNilpotent P
[PROOFSTEP]
rw [← commute_X P]
[GOAL]
R : Type u_1
r : R
inst✝ : Semiring R
P : R[X]
⊢ IsNilpotent (X * P) ↔ IsNilpotent P
[PROOFSTEP]
exact isNilpotent_X_mul_iff
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
⊢ IsNilpotent P ↔ ∀ (i : ℕ), IsNilpotent (coeff P i)
[PROOFSTEP]
refine' ⟨P.recOnHorner (by simp) (fun p r hp₀ _ hp hpr i ↦ _) (fun p _ hnp hpX i ↦ _), fun h ↦ _⟩
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
⊢ IsNilpotent 0 → ∀ (i : ℕ), IsNilpotent (coeff 0 i)
[PROOFSTEP]
simp
[GOAL]
case refine'_1
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
h : ∀ (i : ℕ), IsNilpotent (coeff P i)
⊢ IsNilpotent P
[PROOFSTEP]
rw [← sum_monomial_eq P]
[GOAL]
case refine'_1
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
h : ∀ (i : ℕ), IsNilpotent (coeff P i)
⊢ IsNilpotent (sum P fun n a => ↑(monomial n) a)
[PROOFSTEP]
exact isNilpotent_sum (fun i _ ↦ by simpa only [isNilpotent_monomial_iff] using h i)
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
h : ∀ (i : ℕ), IsNilpotent (coeff P i)
i : ℕ
x✝ : i ∈ support P
⊢ IsNilpotent ((fun n a => ↑(monomial n) a) i (coeff P i))
[PROOFSTEP]
simpa only [isNilpotent_monomial_iff] using h i
[GOAL]
case refine'_2
R : Type u_1
r✝ : R
inst✝ : CommRing R
P p : R[X]
r : R
hp₀ : coeff p 0 = 0
x✝ : r ≠ 0
hp : IsNilpotent p → ∀ (i : ℕ), IsNilpotent (coeff p i)
hpr : IsNilpotent (p + ↑C r)
i : ℕ
⊢ IsNilpotent (coeff (p + ↑C r) i)
[PROOFSTEP]
have hr : IsNilpotent (C r) := by
  obtain ⟨k, hk⟩ := hpr
  replace hp : eval 0 p = 0 := by rwa [coeff_zero_eq_aeval_zero] at hp₀
  refine' isNilpotent_C_iff.mpr ⟨k, _⟩
  simpa [coeff_zero_eq_aeval_zero, hp] using congr_arg (fun q ↦ coeff q 0) hk
[GOAL]
R : Type u_1
r✝ : R
inst✝ : CommRing R
P p : R[X]
r : R
hp₀ : coeff p 0 = 0
x✝ : r ≠ 0
hp : IsNilpotent p → ∀ (i : ℕ), IsNilpotent (coeff p i)
hpr : IsNilpotent (p + ↑C r)
i : ℕ
⊢ IsNilpotent (↑C r)
[PROOFSTEP]
obtain ⟨k, hk⟩ := hpr
[GOAL]
case intro
R : Type u_1
r✝ : R
inst✝ : CommRing R
P p : R[X]
r : R
hp₀ : coeff p 0 = 0
x✝ : r ≠ 0
hp : IsNilpotent p → ∀ (i : ℕ), IsNilpotent (coeff p i)
i k : ℕ
hk : (p + ↑C r) ^ k = 0
⊢ IsNilpotent (↑C r)
[PROOFSTEP]
replace hp : eval 0 p = 0 := by rwa [coeff_zero_eq_aeval_zero] at hp₀
[GOAL]
R : Type u_1
r✝ : R
inst✝ : CommRing R
P p : R[X]
r : R
hp₀ : coeff p 0 = 0
x✝ : r ≠ 0
hp : IsNilpotent p → ∀ (i : ℕ), IsNilpotent (coeff p i)
i k : ℕ
hk : (p + ↑C r) ^ k = 0
⊢ eval 0 p = 0
[PROOFSTEP]
rwa [coeff_zero_eq_aeval_zero] at hp₀
[GOAL]
case intro
R : Type u_1
r✝ : R
inst✝ : CommRing R
P p : R[X]
r : R
hp₀ : coeff p 0 = 0
x✝ : r ≠ 0
i k : ℕ
hk : (p + ↑C r) ^ k = 0
hp : eval 0 p = 0
⊢ IsNilpotent (↑C r)
[PROOFSTEP]
refine' isNilpotent_C_iff.mpr ⟨k, _⟩
[GOAL]
case intro
R : Type u_1
r✝ : R
inst✝ : CommRing R
P p : R[X]
r : R
hp₀ : coeff p 0 = 0
x✝ : r ≠ 0
i k : ℕ
hk : (p + ↑C r) ^ k = 0
hp : eval 0 p = 0
⊢ r ^ k = 0
[PROOFSTEP]
simpa [coeff_zero_eq_aeval_zero, hp] using congr_arg (fun q ↦ coeff q 0) hk
[GOAL]
case refine'_2
R : Type u_1
r✝ : R
inst✝ : CommRing R
P p : R[X]
r : R
hp₀ : coeff p 0 = 0
x✝ : r ≠ 0
hp : IsNilpotent p → ∀ (i : ℕ), IsNilpotent (coeff p i)
hpr : IsNilpotent (p + ↑C r)
i : ℕ
hr : IsNilpotent (↑C r)
⊢ IsNilpotent (coeff (p + ↑C r) i)
[PROOFSTEP]
cases' i with i
[GOAL]
case refine'_2.zero
R : Type u_1
r✝ : R
inst✝ : CommRing R
P p : R[X]
r : R
hp₀ : coeff p 0 = 0
x✝ : r ≠ 0
hp : IsNilpotent p → ∀ (i : ℕ), IsNilpotent (coeff p i)
hpr : IsNilpotent (p + ↑C r)
hr : IsNilpotent (↑C r)
⊢ IsNilpotent (coeff (p + ↑C r) Nat.zero)
case refine'_2.succ
R : Type u_1
r✝ : R
inst✝ : CommRing R
P p : R[X]
r : R
hp₀ : coeff p 0 = 0
x✝ : r ≠ 0
hp : IsNilpotent p → ∀ (i : ℕ), IsNilpotent (coeff p i)
hpr : IsNilpotent (p + ↑C r)
hr : IsNilpotent (↑C r)
i : ℕ
⊢ IsNilpotent (coeff (p + ↑C r) (Nat.succ i))
[PROOFSTEP]
simpa [hp₀] using hr
[GOAL]
case refine'_2.succ
R : Type u_1
r✝ : R
inst✝ : CommRing R
P p : R[X]
r : R
hp₀ : coeff p 0 = 0
x✝ : r ≠ 0
hp : IsNilpotent p → ∀ (i : ℕ), IsNilpotent (coeff p i)
hpr : IsNilpotent (p + ↑C r)
hr : IsNilpotent (↑C r)
i : ℕ
⊢ IsNilpotent (coeff (p + ↑C r) (Nat.succ i))
[PROOFSTEP]
simp only [coeff_add, coeff_C_succ, add_zero]
[GOAL]
case refine'_2.succ
R : Type u_1
r✝ : R
inst✝ : CommRing R
P p : R[X]
r : R
hp₀ : coeff p 0 = 0
x✝ : r ≠ 0
hp : IsNilpotent p → ∀ (i : ℕ), IsNilpotent (coeff p i)
hpr : IsNilpotent (p + ↑C r)
hr : IsNilpotent (↑C r)
i : ℕ
⊢ IsNilpotent (coeff p (Nat.succ i))
[PROOFSTEP]
apply hp
[GOAL]
case refine'_2.succ.a
R : Type u_1
r✝ : R
inst✝ : CommRing R
P p : R[X]
r : R
hp₀ : coeff p 0 = 0
x✝ : r ≠ 0
hp : IsNilpotent p → ∀ (i : ℕ), IsNilpotent (coeff p i)
hpr : IsNilpotent (p + ↑C r)
hr : IsNilpotent (↑C r)
i : ℕ
⊢ IsNilpotent p
[PROOFSTEP]
simpa using Commute.isNilpotent_sub (Commute.all _ _) hpr hr
[GOAL]
case refine'_3
R : Type u_1
r : R
inst✝ : CommRing R
P p : R[X]
x✝ : p ≠ 0
hnp : IsNilpotent p → ∀ (i : ℕ), IsNilpotent (coeff p i)
hpX : IsNilpotent (p * X)
i : ℕ
⊢ IsNilpotent (coeff (p * X) i)
[PROOFSTEP]
cases' i with i
[GOAL]
case refine'_3.zero
R : Type u_1
r : R
inst✝ : CommRing R
P p : R[X]
x✝ : p ≠ 0
hnp : IsNilpotent p → ∀ (i : ℕ), IsNilpotent (coeff p i)
hpX : IsNilpotent (p * X)
⊢ IsNilpotent (coeff (p * X) Nat.zero)
case refine'_3.succ
R : Type u_1
r : R
inst✝ : CommRing R
P p : R[X]
x✝ : p ≠ 0
hnp : IsNilpotent p → ∀ (i : ℕ), IsNilpotent (coeff p i)
hpX : IsNilpotent (p * X)
i : ℕ
⊢ IsNilpotent (coeff (p * X) (Nat.succ i))
[PROOFSTEP]
simp
[GOAL]
case refine'_3.succ
R : Type u_1
r : R
inst✝ : CommRing R
P p : R[X]
x✝ : p ≠ 0
hnp : IsNilpotent p → ∀ (i : ℕ), IsNilpotent (coeff p i)
hpX : IsNilpotent (p * X)
i : ℕ
⊢ IsNilpotent (coeff (p * X) (Nat.succ i))
[PROOFSTEP]
simpa using hnp (isNilpotent_mul_X_iff.mp hpX) i
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
⊢ IsNilpotent (reverse P) ↔ IsNilpotent P
[PROOFSTEP]
simp only [Polynomial.isNilpotent_iff, coeff_reverse]
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
⊢ (∀ (i : ℕ), IsNilpotent (coeff P (↑(revAt (natDegree P)) i))) ↔ ∀ (i : ℕ), IsNilpotent (coeff P i)
[PROOFSTEP]
refine' ⟨fun h i ↦ _, fun h i ↦ _⟩
[GOAL]
case refine'_1
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
h : ∀ (i : ℕ), IsNilpotent (coeff P (↑(revAt (natDegree P)) i))
i : ℕ
⊢ IsNilpotent (coeff P i)
[PROOFSTEP]
cases' le_or_lt i P.natDegree with hi hi
[GOAL]
case refine'_2
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
h : ∀ (i : ℕ), IsNilpotent (coeff P i)
i : ℕ
⊢ IsNilpotent (coeff P (↑(revAt (natDegree P)) i))
[PROOFSTEP]
cases' le_or_lt i P.natDegree with hi hi
[GOAL]
case refine'_1.inl
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
h : ∀ (i : ℕ), IsNilpotent (coeff P (↑(revAt (natDegree P)) i))
i : ℕ
hi : i ≤ natDegree P
⊢ IsNilpotent (coeff P i)
[PROOFSTEP]
simpa [tsub_tsub_cancel_of_le hi] using h (P.natDegree - i)
[GOAL]
case refine'_1.inr
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
h : ∀ (i : ℕ), IsNilpotent (coeff P (↑(revAt (natDegree P)) i))
i : ℕ
hi : natDegree P < i
⊢ IsNilpotent (coeff P i)
[PROOFSTEP]
simp [coeff_eq_zero_of_natDegree_lt hi]
[GOAL]
case refine'_2.inl
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
h : ∀ (i : ℕ), IsNilpotent (coeff P i)
i : ℕ
hi : i ≤ natDegree P
⊢ IsNilpotent (coeff P (↑(revAt (natDegree P)) i))
[PROOFSTEP]
simpa only [hi, revAt_le] using h (P.natDegree - i)
[GOAL]
case refine'_2.inr
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
h : ∀ (i : ℕ), IsNilpotent (coeff P i)
i : ℕ
hi : natDegree P < i
⊢ IsNilpotent (coeff P (↑(revAt (natDegree P)) i))
[PROOFSTEP]
simpa only [revAt_eq_self_of_lt hi] using h i
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
⊢ IsUnit P
[PROOFSTEP]
induction' h : P.natDegree using Nat.strong_induction_on with k hind generalizing P
[GOAL]
case h
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
⊢ IsUnit P
[PROOFSTEP]
by_cases hdeg : P.natDegree = 0
[GOAL]
case pos
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
hdeg : natDegree P = 0
⊢ IsUnit P
case neg
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
hdeg : ¬natDegree P = 0
⊢ IsUnit P
[PROOFSTEP]
{ rw [eq_C_of_natDegree_eq_zero hdeg]
  exact hunit.map C
}
[GOAL]
case pos
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
hdeg : natDegree P = 0
⊢ IsUnit P
[PROOFSTEP]
rw [eq_C_of_natDegree_eq_zero hdeg]
[GOAL]
case pos
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
hdeg : natDegree P = 0
⊢ IsUnit (↑C (coeff P 0))
[PROOFSTEP]
exact hunit.map C
[GOAL]
case neg
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
hdeg : ¬natDegree P = 0
⊢ IsUnit P
[PROOFSTEP]
set P₁ := P.eraseLead with hP₁
[GOAL]
case neg
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
hdeg : ¬natDegree P = 0
P₁ : R[X] := eraseLead P
hP₁ : P₁ = eraseLead P
⊢ IsUnit P
[PROOFSTEP]
suffices IsUnit P₁ by
  rw [← eraseLead_add_monomial_natDegree_leadingCoeff P, ← C_mul_X_pow_eq_monomial]
  obtain ⟨Q, hQ⟩ := this
  rw [← hP₁, ← hQ]
  refine'
    Commute.IsNilpotent.add_isUnit (isNilpotent_C_mul_pow_X_of_isNilpotent _ (hnil _ hdeg))
      ((Commute.all _ _).mul_left (Commute.all _ _))
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
hdeg : ¬natDegree P = 0
P₁ : R[X] := eraseLead P
hP₁ : P₁ = eraseLead P
this : IsUnit P₁
⊢ IsUnit P
[PROOFSTEP]
rw [← eraseLead_add_monomial_natDegree_leadingCoeff P, ← C_mul_X_pow_eq_monomial]
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
hdeg : ¬natDegree P = 0
P₁ : R[X] := eraseLead P
hP₁ : P₁ = eraseLead P
this : IsUnit P₁
⊢ IsUnit (eraseLead P + ↑C (leadingCoeff P) * X ^ natDegree P)
[PROOFSTEP]
obtain ⟨Q, hQ⟩ := this
[GOAL]
case intro
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
hdeg : ¬natDegree P = 0
P₁ : R[X] := eraseLead P
hP₁ : P₁ = eraseLead P
Q : R[X]ˣ
hQ : ↑Q = P₁
⊢ IsUnit (eraseLead P + ↑C (leadingCoeff P) * X ^ natDegree P)
[PROOFSTEP]
rw [← hP₁, ← hQ]
[GOAL]
case intro
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
hdeg : ¬natDegree P = 0
P₁ : R[X] := eraseLead P
hP₁ : P₁ = eraseLead P
Q : R[X]ˣ
hQ : ↑Q = P₁
⊢ IsUnit (↑Q + ↑C (leadingCoeff P) * X ^ natDegree P)
[PROOFSTEP]
refine'
  Commute.IsNilpotent.add_isUnit (isNilpotent_C_mul_pow_X_of_isNilpotent _ (hnil _ hdeg))
    ((Commute.all _ _).mul_left (Commute.all _ _))
[GOAL]
case neg
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
hdeg : ¬natDegree P = 0
P₁ : R[X] := eraseLead P
hP₁ : P₁ = eraseLead P
⊢ IsUnit P₁
[PROOFSTEP]
have hdeg₂ := lt_of_le_of_lt P.eraseLead_natDegree_le (Nat.sub_lt (Nat.pos_of_ne_zero hdeg) zero_lt_one)
[GOAL]
case neg
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
hdeg : ¬natDegree P = 0
P₁ : R[X] := eraseLead P
hP₁ : P₁ = eraseLead P
hdeg₂ : natDegree (eraseLead P) < natDegree P
⊢ IsUnit P₁
[PROOFSTEP]
refine' hind P₁.natDegree _ _ (fun i hi => _) rfl
[GOAL]
case neg.refine'_1
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
hdeg : ¬natDegree P = 0
P₁ : R[X] := eraseLead P
hP₁ : P₁ = eraseLead P
hdeg₂ : natDegree (eraseLead P) < natDegree P
⊢ natDegree P₁ < k
[PROOFSTEP]
simp_rw [← h, hdeg₂]
[GOAL]
case neg.refine'_2
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
hdeg : ¬natDegree P = 0
P₁ : R[X] := eraseLead P
hP₁ : P₁ = eraseLead P
hdeg₂ : natDegree (eraseLead P) < natDegree P
⊢ IsUnit (coeff P₁ 0)
[PROOFSTEP]
simp_rw [eraseLead_coeff_of_ne _ (Ne.symm hdeg), hunit]
[GOAL]
case neg.refine'_3
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
hdeg : ¬natDegree P = 0
P₁ : R[X] := eraseLead P
hP₁ : P₁ = eraseLead P
hdeg₂ : natDegree (eraseLead P) < natDegree P
i : ℕ
hi : i ≠ 0
⊢ IsNilpotent (coeff P₁ i)
[PROOFSTEP]
by_cases H : i ≤ P₁.natDegree
[GOAL]
case pos
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
hdeg : ¬natDegree P = 0
P₁ : R[X] := eraseLead P
hP₁ : P₁ = eraseLead P
hdeg₂ : natDegree (eraseLead P) < natDegree P
i : ℕ
hi : i ≠ 0
H : i ≤ natDegree P₁
⊢ IsNilpotent (coeff P₁ i)
case neg
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
hdeg : ¬natDegree P = 0
P₁ : R[X] := eraseLead P
hP₁ : P₁ = eraseLead P
hdeg₂ : natDegree (eraseLead P) < natDegree P
i : ℕ
hi : i ≠ 0
H : ¬i ≤ natDegree P₁
⊢ IsNilpotent (coeff P₁ i)
[PROOFSTEP]
simp_rw [eraseLead_coeff_of_ne _ (ne_of_lt (lt_of_le_of_lt H hdeg₂)), hnil i hi]
[GOAL]
case neg
R : Type u_1
r : R
inst✝ : CommRing R
P✝ : R[X]
hunit✝ : IsUnit (coeff P✝ 0)
hnil✝ : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P✝ i)
x✝ : ℕ
h✝ : natDegree P✝ = x✝
k : ℕ
hind :
  ∀ (m : ℕ),
    m < k → ∀ {P : R[X]}, IsUnit (coeff P 0) → (∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)) → natDegree P = m → IsUnit P
P : R[X]
hunit : IsUnit (coeff P 0)
hnil : ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
h : natDegree P = k
hdeg : ¬natDegree P = 0
P₁ : R[X] := eraseLead P
hP₁ : P₁ = eraseLead P
hdeg₂ : natDegree (eraseLead P) < natDegree P
i : ℕ
hi : i ≠ 0
H : ¬i ≤ natDegree P₁
⊢ IsNilpotent (coeff P₁ i)
[PROOFSTEP]
simp_rw [coeff_eq_zero_of_natDegree_lt (lt_of_not_ge H), IsNilpotent.zero]
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
⊢ IsUnit (coeff P 0) ∧ ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
[PROOFSTEP]
obtain ⟨Q, hQ⟩ := IsUnit.exists_right_inv hunit
[GOAL]
case intro
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
⊢ IsUnit (coeff P 0) ∧ ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
[PROOFSTEP]
constructor
[GOAL]
case intro.left
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
⊢ IsUnit (coeff P 0)
[PROOFSTEP]
refine' isUnit_of_mul_eq_one _ (Q.coeff 0) _
[GOAL]
case intro.left
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
⊢ coeff P 0 * coeff Q 0 = 1
[PROOFSTEP]
have h := (mul_coeff_zero P Q).symm
[GOAL]
case intro.left
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
h : coeff P 0 * coeff Q 0 = coeff (P * Q) 0
⊢ coeff P 0 * coeff Q 0 = 1
[PROOFSTEP]
rwa [hQ, coeff_one_zero] at h
[GOAL]
case intro.right
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
⊢ ∀ (i : ℕ), i ≠ 0 → IsNilpotent (coeff P i)
[PROOFSTEP]
intros n hn
[GOAL]
case intro.right
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
n : ℕ
hn : n ≠ 0
⊢ IsNilpotent (coeff P n)
[PROOFSTEP]
rw [nilpotent_iff_mem_prime]
[GOAL]
case intro.right
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
n : ℕ
hn : n ≠ 0
⊢ ∀ (J : Ideal R), Ideal.IsPrime J → coeff P n ∈ J
[PROOFSTEP]
intros I hI
[GOAL]
case intro.right
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
n : ℕ
hn : n ≠ 0
I : Ideal R
hI : Ideal.IsPrime I
⊢ coeff P n ∈ I
[PROOFSTEP]
let f := mapRingHom (Ideal.Quotient.mk I)
[GOAL]
case intro.right
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
n : ℕ
hn : n ≠ 0
I : Ideal R
hI : Ideal.IsPrime I
f : R[X] →+* (R ⧸ I)[X] := mapRingHom (Ideal.Quotient.mk I)
⊢ coeff P n ∈ I
[PROOFSTEP]
have hPQ : degree (f P) = 0 ∧ degree (f Q) = 0 := by
  rw [← Nat.WithBot.add_eq_zero_iff, ← degree_mul, ← _root_.map_mul, hQ, map_one, degree_one]
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
n : ℕ
hn : n ≠ 0
I : Ideal R
hI : Ideal.IsPrime I
f : R[X] →+* (R ⧸ I)[X] := mapRingHom (Ideal.Quotient.mk I)
⊢ degree (↑f P) = 0 ∧ degree (↑f Q) = 0
[PROOFSTEP]
rw [← Nat.WithBot.add_eq_zero_iff, ← degree_mul, ← _root_.map_mul, hQ, map_one, degree_one]
[GOAL]
case intro.right
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
n : ℕ
hn : n ≠ 0
I : Ideal R
hI : Ideal.IsPrime I
f : R[X] →+* (R ⧸ I)[X] := mapRingHom (Ideal.Quotient.mk I)
hPQ : degree (↑f P) = 0 ∧ degree (↑f Q) = 0
⊢ coeff P n ∈ I
[PROOFSTEP]
have hcoeff : (f P).coeff n = 0 := by
  refine' coeff_eq_zero_of_degree_lt _
  rw [hPQ.1]
  exact (@WithBot.coe_pos _ _ _ n).2 (Ne.bot_lt hn)
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
n : ℕ
hn : n ≠ 0
I : Ideal R
hI : Ideal.IsPrime I
f : R[X] →+* (R ⧸ I)[X] := mapRingHom (Ideal.Quotient.mk I)
hPQ : degree (↑f P) = 0 ∧ degree (↑f Q) = 0
⊢ coeff (↑f P) n = 0
[PROOFSTEP]
refine' coeff_eq_zero_of_degree_lt _
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
n : ℕ
hn : n ≠ 0
I : Ideal R
hI : Ideal.IsPrime I
f : R[X] →+* (R ⧸ I)[X] := mapRingHom (Ideal.Quotient.mk I)
hPQ : degree (↑f P) = 0 ∧ degree (↑f Q) = 0
⊢ degree (↑f P) < ↑n
[PROOFSTEP]
rw [hPQ.1]
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
n : ℕ
hn : n ≠ 0
I : Ideal R
hI : Ideal.IsPrime I
f : R[X] →+* (R ⧸ I)[X] := mapRingHom (Ideal.Quotient.mk I)
hPQ : degree (↑f P) = 0 ∧ degree (↑f Q) = 0
⊢ 0 < ↑n
[PROOFSTEP]
exact (@WithBot.coe_pos _ _ _ n).2 (Ne.bot_lt hn)
[GOAL]
case intro.right
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
n : ℕ
hn : n ≠ 0
I : Ideal R
hI : Ideal.IsPrime I
f : R[X] →+* (R ⧸ I)[X] := mapRingHom (Ideal.Quotient.mk I)
hPQ : degree (↑f P) = 0 ∧ degree (↑f Q) = 0
hcoeff : coeff (↑f P) n = 0
⊢ coeff P n ∈ I
[PROOFSTEP]
rw [coe_mapRingHom, coeff_map, ← RingHom.mem_ker, Ideal.mk_ker] at hcoeff
[GOAL]
case intro.right
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
hunit : IsUnit P
Q : R[X]
hQ : P * Q = 1
n : ℕ
hn : n ≠ 0
I : Ideal R
hI : Ideal.IsPrime I
f : R[X] →+* (R ⧸ I)[X] := mapRingHom (Ideal.Quotient.mk I)
hPQ : degree (↑f P) = 0 ∧ degree (↑f Q) = 0
hcoeff : coeff P n ∈ I
⊢ coeff P n ∈ I
[PROOFSTEP]
exact hcoeff
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
⊢ IsUnit (↑C r + X * P) ↔ IsUnit r ∧ IsNilpotent P
[PROOFSTEP]
have : ∀ i, coeff (C r + X * P) (i + 1) = coeff P i := by simp
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
⊢ ∀ (i : ℕ), coeff (↑C r + X * P) (i + 1) = coeff P i
[PROOFSTEP]
simp
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
this : ∀ (i : ℕ), coeff (↑C r + X * P) (i + 1) = coeff P i
⊢ IsUnit (↑C r + X * P) ↔ IsUnit r ∧ IsNilpotent P
[PROOFSTEP]
simp_rw [isUnit_iff_coeff_isUnit_isNilpotent, Nat.forall_ne_zero_iff, this]
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
this : ∀ (i : ℕ), coeff (↑C r + X * P) (i + 1) = coeff P i
⊢ (IsUnit (coeff (↑C r + X * P) 0) ∧ ∀ (i : ℕ), IsNilpotent (coeff P i)) ↔ IsUnit r ∧ IsNilpotent P
[PROOFSTEP]
simp only [coeff_add, coeff_C_zero, mul_coeff_zero, coeff_X_zero, zero_mul, add_zero, and_congr_right_iff, ←
  Polynomial.isNilpotent_iff]
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
⊢ IsUnit P ↔ IsUnit (eval 0 P) ∧ IsNilpotent (P /ₘ X)
[PROOFSTEP]
suffices : P = C (eval 0 P) + X * (P /ₘ X)
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
this : P = ↑C (eval 0 P) + X * (P /ₘ X)
⊢ IsUnit P ↔ IsUnit (eval 0 P) ∧ IsNilpotent (P /ₘ X)
[PROOFSTEP]
conv_lhs => rw [this]; simp
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
this : P = ↑C (eval 0 P) + X * (P /ₘ X)
| IsUnit P
[PROOFSTEP]
rw [this]; simp
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
this : P = ↑C (eval 0 P) + X * (P /ₘ X)
| IsUnit P
[PROOFSTEP]
rw [this]; simp
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
this : P = ↑C (eval 0 P) + X * (P /ₘ X)
| IsUnit P
[PROOFSTEP]
rw [this]
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
this : P = ↑C (eval 0 P) + X * (P /ₘ X)
| IsUnit (↑C (eval 0 P) + X * (P /ₘ X))
[PROOFSTEP]
simp
[GOAL]
case this
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
⊢ P = ↑C (eval 0 P) + X * (P /ₘ X)
[PROOFSTEP]
conv_lhs => rw [← modByMonic_add_div P monic_X]
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
| P
[PROOFSTEP]
rw [← modByMonic_add_div P monic_X]
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
| P
[PROOFSTEP]
rw [← modByMonic_add_div P monic_X]
[GOAL]
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
| P
[PROOFSTEP]
rw [← modByMonic_add_div P monic_X]
[GOAL]
case this
R : Type u_1
r : R
inst✝ : CommRing R
P : R[X]
⊢ P %ₘ X + X * (P /ₘ X) = ↑C (eval 0 P) + X * (P /ₘ X)
[PROOFSTEP]
simp [modByMonic_X]