l3lab/ntp-mathlib huggingface dataset:
theorem cast_descFactorial {n p : ℕ} (h : n ≤ p) :
    (descFactorial (p - 1) n : ZMod p) = (-1) ^ n * n ! := by
  rw [descFactorial_eq_prod_range, ← prod_range_add_one_eq_factorial]
  

Proof state:
n p : ℕ
h : n ≤ p
⊢ ↑(Finset.prod (range n) fun i => p - 1 - i) = (-1) ^ n * ↑(Finset.prod (range n) fun x => x + 1)

Next tactic:
simp only [cast_prod]
theorem cast_descFactorial {n p : ℕ} (h : n ≤ p) :
    (descFactorial (p - 1) n : ZMod p) = (-1) ^ n * n ! := by
  rw [descFactorial_eq_prod_range, ← prod_range_add_one_eq_factorial]
  simp only [cast_prod]
  

Proof state:
n p : ℕ
h : n ≤ p
⊢ (Finset.prod (range n) fun i => ↑(p - 1 - i)) = (-1) ^ n * Finset.prod (range n) fun i => ↑(i + 1)

Next tactic:
nth_rw 2 [← card_range n]
theorem cast_descFactorial {n p : ℕ} (h : n ≤ p) :
    (descFactorial (p - 1) n : ZMod p) = (-1) ^ n * n ! := by
  rw [descFactorial_eq_prod_range, ← prod_range_add_one_eq_factorial]
  simp only [cast_prod]
  nth_rw 2 [← card_range n]
  

Proof state:
n p : ℕ
h : n ≤ p
⊢ (Finset.prod (range n) fun i => ↑(p - 1 - i)) = (-1) ^ Finset.card (range n) * Finset.prod (range n) fun i => ↑(i + 1)

Next tactic:
rw [pow_card_mul_prod]
theorem cast_descFactorial {n p : ℕ} (h : n ≤ p) :
    (descFactorial (p - 1) n : ZMod p) = (-1) ^ n * n ! := by
  rw [descFactorial_eq_prod_range, ← prod_range_add_one_eq_factorial]
  simp only [cast_prod]
  nth_rw 2 [← card_range n]
  rw [pow_card_mul_prod]
  

Proof state:
n p : ℕ
h : n ≤ p
⊢ (Finset.prod (range n) fun i => ↑(p - 1 - i)) = Finset.prod (range n) fun a => -1 * ↑(a + 1)

Next tactic:
refine prod_congr rfl ?_
theorem cast_descFactorial {n p : ℕ} (h : n ≤ p) :
    (descFactorial (p - 1) n : ZMod p) = (-1) ^ n * n ! := by
  rw [descFactorial_eq_prod_range, ← prod_range_add_one_eq_factorial]
  simp only [cast_prod]
  nth_rw 2 [← card_range n]
  rw [pow_card_mul_prod]
  refine prod_congr rfl ?_
  

Proof state:
n p : ℕ
h : n ≤ p
⊢ ∀ x ∈ range n, ↑(p - 1 - x) = -1 * ↑(x + 1)

Next tactic:
intro x hx
theorem cast_descFactorial {n p : ℕ} (h : n ≤ p) :
    (descFactorial (p - 1) n : ZMod p) = (-1) ^ n * n ! := by
  rw [descFactorial_eq_prod_range, ← prod_range_add_one_eq_factorial]
  simp only [cast_prod]
  nth_rw 2 [← card_range n]
  rw [pow_card_mul_prod]
  refine prod_congr rfl ?_
  intro x hx
  

Proof state:
n p : ℕ
h : n ≤ p
x : ℕ
hx : x ∈ range n
⊢ ↑(p - 1 - x) = -1 * ↑(x + 1)

Next tactic:
rw [← tsub_add_eq_tsub_tsub_swap, Nat.cast_sub <| Nat.lt_of_lt_of_le (List.mem_range.mp hx) h,
     CharP.cast_eq_zero, zero_sub, cast_succ, neg_add_rev, mul_add, neg_mul, one_mul,
     mul_one, add_comm]
theorem Ideal.exists_minimalPrimes_le [J.IsPrime] (e : I ≤ J) : ∃ p ∈ I.minimalPrimes, p ≤ J := by
  

Proof state:
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J : Ideal R
inst✝ : IsPrime J
e : I ≤ J
⊢ ∃ p ∈ Ideal.minimalPrimes I, p ≤ J

Next tactic:
suffices
    ∃ m ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ OrderDual.ofDual p },
      OrderDual.toDual J ≤ m ∧ ∀ z ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ p }, m ≤ z → z = m by
    obtain ⟨p, h₁, h₂, h₃⟩ := this
    simp_rw [← @eq_comm _ p] at h₃
    exact ⟨p, ⟨h₁, fun a b c => le_of_eq (h₃ a b c)⟩, h₂⟩
theorem Ideal.exists_minimalPrimes_le [J.IsPrime] (e : I ≤ J) : ∃ p ∈ I.minimalPrimes, p ≤ J := by
  suffices
    ∃ m ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ OrderDual.ofDual p },
      OrderDual.toDual J ≤ m ∧ ∀ z ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ p }, m ≤ z → z = m by
    

Proof state:
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J : Ideal R
inst✝ : IsPrime J
e : I ≤ J
this :
  ∃ m ∈ {p | IsPrime p ∧ I ≤ OrderDual.ofDual p}, OrderDual.toDual J ≤ m ∧ ∀ z ∈ {p | IsPrime p ∧ I ≤ p}, m ≤ z → z = m
⊢ ∃ p ∈ Ideal.minimalPrimes I, p ≤ J

Next tactic:
obtain ⟨p, h₁, h₂, h₃⟩ := this
theorem Ideal.exists_minimalPrimes_le [J.IsPrime] (e : I ≤ J) : ∃ p ∈ I.minimalPrimes, p ≤ J := by
  suffices
    ∃ m ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ OrderDual.ofDual p },
      OrderDual.toDual J ≤ m ∧ ∀ z ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ p }, m ≤ z → z = m by
    obtain ⟨p, h₁, h₂, h₃⟩ := this
    

Proof state:
case intro.intro.intro
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J : Ideal R
inst✝ : IsPrime J
e : I ≤ J
p : (Ideal R)ᵒᵈ
h₁ : p ∈ {p | IsPrime p ∧ I ≤ OrderDual.ofDual p}
h₂ : OrderDual.toDual J ≤ p
h₃ : ∀ z ∈ {p | IsPrime p ∧ I ≤ p}, p ≤ z → z = p
⊢ ∃ p ∈ Ideal.minimalPrimes I, p ≤ J

Next tactic:
simp_rw [← @eq_comm _ p] at h₃
theorem Ideal.exists_minimalPrimes_le [J.IsPrime] (e : I ≤ J) : ∃ p ∈ I.minimalPrimes, p ≤ J := by
  suffices
    ∃ m ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ OrderDual.ofDual p },
      OrderDual.toDual J ≤ m ∧ ∀ z ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ p }, m ≤ z → z = m by
    obtain ⟨p, h₁, h₂, h₃⟩ := this
    simp_rw [← @eq_comm _ p] at h₃
    

Proof state:
case intro.intro.intro
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J : Ideal R
inst✝ : IsPrime J
e : I ≤ J
p : (Ideal R)ᵒᵈ
h₁ : p ∈ {p | IsPrime p ∧ I ≤ OrderDual.ofDual p}
h₂ : OrderDual.toDual J ≤ p
h₃ : ∀ z ∈ {p | IsPrime p ∧ I ≤ p}, p ≤ z → p = z
⊢ ∃ p ∈ Ideal.minimalPrimes I, p ≤ J

Next tactic:
exact ⟨p, ⟨h₁, fun a b c => le_of_eq (h₃ a b c)⟩, h₂⟩
theorem Ideal.exists_minimalPrimes_le [J.IsPrime] (e : I ≤ J) : ∃ p ∈ I.minimalPrimes, p ≤ J := by
  suffices
    ∃ m ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ OrderDual.ofDual p },
      OrderDual.toDual J ≤ m ∧ ∀ z ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ p }, m ≤ z → z = m by
    obtain ⟨p, h₁, h₂, h₃⟩ := this
    simp_rw [← @eq_comm _ p] at h₃
    exact ⟨p, ⟨h₁, fun a b c => le_of_eq (h₃ a b c)⟩, h₂⟩
  

Proof state:
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J : Ideal R
inst✝ : IsPrime J
e : I ≤ J
⊢ ∃ m ∈ {p | IsPrime p ∧ I ≤ OrderDual.ofDual p}, OrderDual.toDual J ≤ m ∧ ∀ z ∈ {p | IsPrime p ∧ I ≤ p}, m ≤ z → z = m

Next tactic:
apply zorn_nonempty_partialOrder₀
theorem Ideal.exists_minimalPrimes_le [J.IsPrime] (e : I ≤ J) : ∃ p ∈ I.minimalPrimes, p ≤ J := by
  suffices
    ∃ m ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ OrderDual.ofDual p },
      OrderDual.toDual J ≤ m ∧ ∀ z ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ p }, m ≤ z → z = m by
    obtain ⟨p, h₁, h₂, h₃⟩ := this
    simp_rw [← @eq_comm _ p] at h₃
    exact ⟨p, ⟨h₁, fun a b c => le_of_eq (h₃ a b c)⟩, h₂⟩
  apply zorn_nonempty_partialOrder₀
  

Proof state:
case ih
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J : Ideal R
inst✝ : IsPrime J
e : I ≤ J
⊢ ∀ c ⊆ {p | IsPrime p ∧ I ≤ OrderDual.ofDual p},
    IsChain (fun x x_1 => x ≤ x_1) c → ∀ y ∈ c, ∃ ub ∈ {p | IsPrime p ∧ I ≤ OrderDual.ofDual p}, ∀ z ∈ c, z ≤ ub
case hxs
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J : Ideal R
inst✝ : IsPrime J
e : I ≤ J
⊢ OrderDual.toDual J ∈ {p | IsPrime p ∧ I ≤ OrderDual.ofDual p}

Next tactic:
swap
theorem Ideal.exists_minimalPrimes_le [J.IsPrime] (e : I ≤ J) : ∃ p ∈ I.minimalPrimes, p ≤ J := by
  suffices
    ∃ m ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ OrderDual.ofDual p },
      OrderDual.toDual J ≤ m ∧ ∀ z ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ p }, m ≤ z → z = m by
    obtain ⟨p, h₁, h₂, h₃⟩ := this
    simp_rw [← @eq_comm _ p] at h₃
    exact ⟨p, ⟨h₁, fun a b c => le_of_eq (h₃ a b c)⟩, h₂⟩
  apply zorn_nonempty_partialOrder₀
  swap
  · 

Proof state:
case hxs
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J : Ideal R
inst✝ : IsPrime J
e : I ≤ J
⊢ OrderDual.toDual J ∈ {p | IsPrime p ∧ I ≤ OrderDual.ofDual p}

Next tactic:
refine' ⟨show J.IsPrime by infer_instance, e⟩
theorem Ideal.exists_minimalPrimes_le [J.IsPrime] (e : I ≤ J) : ∃ p ∈ I.minimalPrimes, p ≤ J := by
  suffices
    ∃ m ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ OrderDual.ofDual p },
      OrderDual.toDual J ≤ m ∧ ∀ z ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ p }, m ≤ z → z = m by
    obtain ⟨p, h₁, h₂, h₃⟩ := this
    simp_rw [← @eq_comm _ p] at h₃
    exact ⟨p, ⟨h₁, fun a b c => le_of_eq (h₃ a b c)⟩, h₂⟩
  apply zorn_nonempty_partialOrder₀
  swap
  · refine' ⟨show J.IsPrime by 

Proof state:
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J : Ideal R
inst✝ : IsPrime J
e : I ≤ J
⊢ IsPrime J

Next tactic:
infer_instance
theorem Ideal.exists_minimalPrimes_le [J.IsPrime] (e : I ≤ J) : ∃ p ∈ I.minimalPrimes, p ≤ J := by
  suffices
    ∃ m ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ OrderDual.ofDual p },
      OrderDual.toDual J ≤ m ∧ ∀ z ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ p }, m ≤ z → z = m by
    obtain ⟨p, h₁, h₂, h₃⟩ := this
    simp_rw [← @eq_comm _ p] at h₃
    exact ⟨p, ⟨h₁, fun a b c => le_of_eq (h₃ a b c)⟩, h₂⟩
  apply zorn_nonempty_partialOrder₀
  swap
  · refine' ⟨show J.IsPrime by infer_instance, e⟩
  

Proof state:
case ih
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J : Ideal R
inst✝ : IsPrime J
e : I ≤ J
⊢ ∀ c ⊆ {p | IsPrime p ∧ I ≤ OrderDual.ofDual p},
    IsChain (fun x x_1 => x ≤ x_1) c → ∀ y ∈ c, ∃ ub ∈ {p | IsPrime p ∧ I ≤ OrderDual.ofDual p}, ∀ z ∈ c, z ≤ ub

Next tactic:
rintro (c : Set (Ideal R)) hc hc' J' hJ'
theorem Ideal.exists_minimalPrimes_le [J.IsPrime] (e : I ≤ J) : ∃ p ∈ I.minimalPrimes, p ≤ J := by
  suffices
    ∃ m ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ OrderDual.ofDual p },
      OrderDual.toDual J ≤ m ∧ ∀ z ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ p }, m ≤ z → z = m by
    obtain ⟨p, h₁, h₂, h₃⟩ := this
    simp_rw [← @eq_comm _ p] at h₃
    exact ⟨p, ⟨h₁, fun a b c => le_of_eq (h₃ a b c)⟩, h₂⟩
  apply zorn_nonempty_partialOrder₀
  swap
  · refine' ⟨show J.IsPrime by infer_instance, e⟩
  rintro (c : Set (Ideal R)) hc hc' J' hJ'
  

Proof state:
case ih
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J : Ideal R
inst✝ : IsPrime J
e : I ≤ J
c : Set (Ideal R)
hc : c ⊆ {p | IsPrime p ∧ I ≤ OrderDual.ofDual p}
hc' : IsChain (fun x x_1 => x ≤ x_1) c
J' : (Ideal R)ᵒᵈ
hJ' : J' ∈ c
⊢ ∃ ub ∈ {p | IsPrime p ∧ I ≤ OrderDual.ofDual p}, ∀ z ∈ c, z ≤ ub

Next tactic:
refine'
    ⟨OrderDual.toDual (sInf c),
      ⟨Ideal.sInf_isPrime_of_isChain ⟨J', hJ'⟩ hc'.symm fun x hx => (hc hx).1, _⟩, _⟩
theorem Ideal.exists_minimalPrimes_le [J.IsPrime] (e : I ≤ J) : ∃ p ∈ I.minimalPrimes, p ≤ J := by
  suffices
    ∃ m ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ OrderDual.ofDual p },
      OrderDual.toDual J ≤ m ∧ ∀ z ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ p }, m ≤ z → z = m by
    obtain ⟨p, h₁, h₂, h₃⟩ := this
    simp_rw [← @eq_comm _ p] at h₃
    exact ⟨p, ⟨h₁, fun a b c => le_of_eq (h₃ a b c)⟩, h₂⟩
  apply zorn_nonempty_partialOrder₀
  swap
  · refine' ⟨show J.IsPrime by infer_instance, e⟩
  rintro (c : Set (Ideal R)) hc hc' J' hJ'
  refine'
    ⟨OrderDual.toDual (sInf c),
      ⟨Ideal.sInf_isPrime_of_isChain ⟨J', hJ'⟩ hc'.symm fun x hx => (hc hx).1, _⟩, _⟩
  · 

Proof state:
case ih.refine'_1
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J : Ideal R
inst✝ : IsPrime J
e : I ≤ J
c : Set (Ideal R)
hc : c ⊆ {p | IsPrime p ∧ I ≤ OrderDual.ofDual p}
hc' : IsChain (fun x x_1 => x ≤ x_1) c
J' : (Ideal R)ᵒᵈ
hJ' : J' ∈ c
⊢ I ≤ OrderDual.ofDual (OrderDual.toDual (sInf c))

Next tactic:
rw [OrderDual.ofDual_toDual, le_sInf_iff]
theorem Ideal.exists_minimalPrimes_le [J.IsPrime] (e : I ≤ J) : ∃ p ∈ I.minimalPrimes, p ≤ J := by
  suffices
    ∃ m ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ OrderDual.ofDual p },
      OrderDual.toDual J ≤ m ∧ ∀ z ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ p }, m ≤ z → z = m by
    obtain ⟨p, h₁, h₂, h₃⟩ := this
    simp_rw [← @eq_comm _ p] at h₃
    exact ⟨p, ⟨h₁, fun a b c => le_of_eq (h₃ a b c)⟩, h₂⟩
  apply zorn_nonempty_partialOrder₀
  swap
  · refine' ⟨show J.IsPrime by infer_instance, e⟩
  rintro (c : Set (Ideal R)) hc hc' J' hJ'
  refine'
    ⟨OrderDual.toDual (sInf c),
      ⟨Ideal.sInf_isPrime_of_isChain ⟨J', hJ'⟩ hc'.symm fun x hx => (hc hx).1, _⟩, _⟩
  · rw [OrderDual.ofDual_toDual, le_sInf_iff]
    

Proof state:
case ih.refine'_1
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J : Ideal R
inst✝ : IsPrime J
e : I ≤ J
c : Set (Ideal R)
hc : c ⊆ {p | IsPrime p ∧ I ≤ OrderDual.ofDual p}
hc' : IsChain (fun x x_1 => x ≤ x_1) c
J' : (Ideal R)ᵒᵈ
hJ' : J' ∈ c
⊢ ∀ b ∈ c, I ≤ b

Next tactic:
exact fun _ hx => (hc hx).2
theorem Ideal.exists_minimalPrimes_le [J.IsPrime] (e : I ≤ J) : ∃ p ∈ I.minimalPrimes, p ≤ J := by
  suffices
    ∃ m ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ OrderDual.ofDual p },
      OrderDual.toDual J ≤ m ∧ ∀ z ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ p }, m ≤ z → z = m by
    obtain ⟨p, h₁, h₂, h₃⟩ := this
    simp_rw [← @eq_comm _ p] at h₃
    exact ⟨p, ⟨h₁, fun a b c => le_of_eq (h₃ a b c)⟩, h₂⟩
  apply zorn_nonempty_partialOrder₀
  swap
  · refine' ⟨show J.IsPrime by infer_instance, e⟩
  rintro (c : Set (Ideal R)) hc hc' J' hJ'
  refine'
    ⟨OrderDual.toDual (sInf c),
      ⟨Ideal.sInf_isPrime_of_isChain ⟨J', hJ'⟩ hc'.symm fun x hx => (hc hx).1, _⟩, _⟩
  · rw [OrderDual.ofDual_toDual, le_sInf_iff]
    exact fun _ hx => (hc hx).2
  · 

Proof state:
case ih.refine'_2
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J : Ideal R
inst✝ : IsPrime J
e : I ≤ J
c : Set (Ideal R)
hc : c ⊆ {p | IsPrime p ∧ I ≤ OrderDual.ofDual p}
hc' : IsChain (fun x x_1 => x ≤ x_1) c
J' : (Ideal R)ᵒᵈ
hJ' : J' ∈ c
⊢ ∀ z ∈ c, z ≤ OrderDual.toDual (sInf c)

Next tactic:
rintro z hz
theorem Ideal.exists_minimalPrimes_le [J.IsPrime] (e : I ≤ J) : ∃ p ∈ I.minimalPrimes, p ≤ J := by
  suffices
    ∃ m ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ OrderDual.ofDual p },
      OrderDual.toDual J ≤ m ∧ ∀ z ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ p }, m ≤ z → z = m by
    obtain ⟨p, h₁, h₂, h₃⟩ := this
    simp_rw [← @eq_comm _ p] at h₃
    exact ⟨p, ⟨h₁, fun a b c => le_of_eq (h₃ a b c)⟩, h₂⟩
  apply zorn_nonempty_partialOrder₀
  swap
  · refine' ⟨show J.IsPrime by infer_instance, e⟩
  rintro (c : Set (Ideal R)) hc hc' J' hJ'
  refine'
    ⟨OrderDual.toDual (sInf c),
      ⟨Ideal.sInf_isPrime_of_isChain ⟨J', hJ'⟩ hc'.symm fun x hx => (hc hx).1, _⟩, _⟩
  · rw [OrderDual.ofDual_toDual, le_sInf_iff]
    exact fun _ hx => (hc hx).2
  · rintro z hz
    

Proof state:
case ih.refine'_2
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J : Ideal R
inst✝ : IsPrime J
e : I ≤ J
c : Set (Ideal R)
hc : c ⊆ {p | IsPrime p ∧ I ≤ OrderDual.ofDual p}
hc' : IsChain (fun x x_1 => x ≤ x_1) c
J' : (Ideal R)ᵒᵈ
hJ' : J' ∈ c
z : (Ideal R)ᵒᵈ
hz : z ∈ c
⊢ z ≤ OrderDual.toDual (sInf c)

Next tactic:
rw [OrderDual.le_toDual]
theorem Ideal.exists_minimalPrimes_le [J.IsPrime] (e : I ≤ J) : ∃ p ∈ I.minimalPrimes, p ≤ J := by
  suffices
    ∃ m ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ OrderDual.ofDual p },
      OrderDual.toDual J ≤ m ∧ ∀ z ∈ { p : (Ideal R)ᵒᵈ | Ideal.IsPrime p ∧ I ≤ p }, m ≤ z → z = m by
    obtain ⟨p, h₁, h₂, h₃⟩ := this
    simp_rw [← @eq_comm _ p] at h₃
    exact ⟨p, ⟨h₁, fun a b c => le_of_eq (h₃ a b c)⟩, h₂⟩
  apply zorn_nonempty_partialOrder₀
  swap
  · refine' ⟨show J.IsPrime by infer_instance, e⟩
  rintro (c : Set (Ideal R)) hc hc' J' hJ'
  refine'
    ⟨OrderDual.toDual (sInf c),
      ⟨Ideal.sInf_isPrime_of_isChain ⟨J', hJ'⟩ hc'.symm fun x hx => (hc hx).1, _⟩, _⟩
  · rw [OrderDual.ofDual_toDual, le_sInf_iff]
    exact fun _ hx => (hc hx).2
  · rintro z hz
    rw [OrderDual.le_toDual]
    

Proof state:
case ih.refine'_2
R : Type u_1
S : Type u_2
inst✝² : CommRing R
inst✝¹ : CommRing S
I J : Ideal R
inst✝ : IsPrime J
e : I ≤ J
c : Set (Ideal R)
hc : c ⊆ {p | IsPrime p ∧ I ≤ OrderDual.ofDual p}
hc' : IsChain (fun x x_1 => x ≤ x_1) c
J' : (Ideal R)ᵒᵈ
hJ' : J' ∈ c
z : (Ideal R)ᵒᵈ
hz : z ∈ c
⊢ sInf c ≤ OrderDual.ofDual z

Next tactic:
exact sInf_le hz
@[simp]
theorem Ideal.radical_minimalPrimes : I.radical.minimalPrimes = I.minimalPrimes := by
  

Proof state:
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J : Ideal R
⊢ Ideal.minimalPrimes (radical I) = Ideal.minimalPrimes I

Next tactic:
rw [Ideal.minimalPrimes, Ideal.minimalPrimes]
@[simp]
theorem Ideal.radical_minimalPrimes : I.radical.minimalPrimes = I.minimalPrimes := by
  rw [Ideal.minimalPrimes, Ideal.minimalPrimes]
  

Proof state:
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J : Ideal R
⊢ minimals (fun x x_1 => x ≤ x_1) {p | IsPrime p ∧ radical I ≤ p} =
    minimals (fun x x_1 => x ≤ x_1) {p | IsPrime p ∧ I ≤ p}

Next tactic:
congr
@[simp]
theorem Ideal.radical_minimalPrimes : I.radical.minimalPrimes = I.minimalPrimes := by
  rw [Ideal.minimalPrimes, Ideal.minimalPrimes]
  congr
  

Proof state:
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J : Ideal R
⊢ minimals (fun x x_1 => x ≤ x_1) {p | IsPrime p ∧ radical I ≤ p} =
    minimals (fun x x_1 => x ≤ x_1) {p | IsPrime p ∧ I ≤ p}

Next tactic:
ext p
@[simp]
theorem Ideal.radical_minimalPrimes : I.radical.minimalPrimes = I.minimalPrimes := by
  rw [Ideal.minimalPrimes, Ideal.minimalPrimes]
  congr
  ext p
  

Proof state:
case h
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J p : Ideal R
⊢ p ∈ minimals (fun x x_1 => x ≤ x_1) {p | IsPrime p ∧ radical I ≤ p} ↔
    p ∈ minimals (fun x x_1 => x ≤ x_1) {p | IsPrime p ∧ I ≤ p}

Next tactic:
refine' ⟨_, _⟩
@[simp]
theorem Ideal.radical_minimalPrimes : I.radical.minimalPrimes = I.minimalPrimes := by
  rw [Ideal.minimalPrimes, Ideal.minimalPrimes]
  congr
  ext p
  refine' ⟨_, _⟩ <;> 

Proof state:
case h.refine'_1
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J p : Ideal R
⊢ p ∈ minimals (fun x x_1 => x ≤ x_1) {p | IsPrime p ∧ radical I ≤ p} →
    p ∈ minimals (fun x x_1 => x ≤ x_1) {p | IsPrime p ∧ I ≤ p}

Next tactic:
rintro ⟨⟨a, ha⟩, b⟩
@[simp]
theorem Ideal.radical_minimalPrimes : I.radical.minimalPrimes = I.minimalPrimes := by
  rw [Ideal.minimalPrimes, Ideal.minimalPrimes]
  congr
  ext p
  refine' ⟨_, _⟩ <;> 

Proof state:
case h.refine'_2
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J p : Ideal R
⊢ p ∈ minimals (fun x x_1 => x ≤ x_1) {p | IsPrime p ∧ I ≤ p} →
    p ∈ minimals (fun x x_1 => x ≤ x_1) {p | IsPrime p ∧ radical I ≤ p}

Next tactic:
rintro ⟨⟨a, ha⟩, b⟩
@[simp]
theorem Ideal.radical_minimalPrimes : I.radical.minimalPrimes = I.minimalPrimes := by
  rw [Ideal.minimalPrimes, Ideal.minimalPrimes]
  congr
  ext p
  refine' ⟨_, _⟩ <;> rintro ⟨⟨a, ha⟩, b⟩
  · 

Proof state:
case h.refine'_1.intro.intro
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J p : Ideal R
b : ∀ ⦃b : Ideal R⦄, b ∈ {p | IsPrime p ∧ radical I ≤ p} → (fun x x_1 => x ≤ x_1) b p → (fun x x_1 => x ≤ x_1) p b
a : IsPrime p
ha : radical I ≤ p
⊢ p ∈ minimals (fun x x_1 => x ≤ x_1) {p | IsPrime p ∧ I ≤ p}

Next tactic:
refine' ⟨⟨a, a.radical_le_iff.1 ha⟩, _⟩
@[simp]
theorem Ideal.radical_minimalPrimes : I.radical.minimalPrimes = I.minimalPrimes := by
  rw [Ideal.minimalPrimes, Ideal.minimalPrimes]
  congr
  ext p
  refine' ⟨_, _⟩ <;> rintro ⟨⟨a, ha⟩, b⟩
  · refine' ⟨⟨a, a.radical_le_iff.1 ha⟩, _⟩
    · 

Proof state:
case h.refine'_1.intro.intro
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J p : Ideal R
b : ∀ ⦃b : Ideal R⦄, b ∈ {p | IsPrime p ∧ radical I ≤ p} → (fun x x_1 => x ≤ x_1) b p → (fun x x_1 => x ≤ x_1) p b
a : IsPrime p
ha : radical I ≤ p
⊢ ∀ ⦃b : Ideal R⦄, b ∈ {p | IsPrime p ∧ I ≤ p} → (fun x x_1 => x ≤ x_1) b p → (fun x x_1 => x ≤ x_1) p b

Next tactic:
simp only [Set.mem_setOf_eq, and_imp] at *
@[simp]
theorem Ideal.radical_minimalPrimes : I.radical.minimalPrimes = I.minimalPrimes := by
  rw [Ideal.minimalPrimes, Ideal.minimalPrimes]
  congr
  ext p
  refine' ⟨_, _⟩ <;> rintro ⟨⟨a, ha⟩, b⟩
  · refine' ⟨⟨a, a.radical_le_iff.1 ha⟩, _⟩
    · simp only [Set.mem_setOf_eq, and_imp] at *
      

Proof state:
case h.refine'_1.intro.intro
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J p : Ideal R
a : IsPrime p
ha : radical I ≤ p
b : ∀ ⦃b : Ideal R⦄, IsPrime b → radical I ≤ b → b ≤ p → p ≤ b
⊢ ∀ ⦃b : Ideal R⦄, IsPrime b → I ≤ b → b ≤ p → p ≤ b

Next tactic:
exact fun _ h2 h3 h4 => b h2 (h2.radical_le_iff.2 h3) h4
@[simp]
theorem Ideal.radical_minimalPrimes : I.radical.minimalPrimes = I.minimalPrimes := by
  rw [Ideal.minimalPrimes, Ideal.minimalPrimes]
  congr
  ext p
  refine' ⟨_, _⟩ <;> rintro ⟨⟨a, ha⟩, b⟩
  · refine' ⟨⟨a, a.radical_le_iff.1 ha⟩, _⟩
    · simp only [Set.mem_setOf_eq, and_imp] at *
      exact fun _ h2 h3 h4 => b h2 (h2.radical_le_iff.2 h3) h4
  · 

Proof state:
case h.refine'_2.intro.intro
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J p : Ideal R
b : ∀ ⦃b : Ideal R⦄, b ∈ {p | IsPrime p ∧ I ≤ p} → (fun x x_1 => x ≤ x_1) b p → (fun x x_1 => x ≤ x_1) p b
a : IsPrime p
ha : I ≤ p
⊢ p ∈ minimals (fun x x_1 => x ≤ x_1) {p | IsPrime p ∧ radical I ≤ p}

Next tactic:
refine' ⟨⟨a, a.radical_le_iff.2 ha⟩, _⟩
@[simp]
theorem Ideal.radical_minimalPrimes : I.radical.minimalPrimes = I.minimalPrimes := by
  rw [Ideal.minimalPrimes, Ideal.minimalPrimes]
  congr
  ext p
  refine' ⟨_, _⟩ <;> rintro ⟨⟨a, ha⟩, b⟩
  · refine' ⟨⟨a, a.radical_le_iff.1 ha⟩, _⟩
    · simp only [Set.mem_setOf_eq, and_imp] at *
      exact fun _ h2 h3 h4 => b h2 (h2.radical_le_iff.2 h3) h4
  · refine' ⟨⟨a, a.radical_le_iff.2 ha⟩, _⟩
    · 

Proof state:
case h.refine'_2.intro.intro
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J p : Ideal R
b : ∀ ⦃b : Ideal R⦄, b ∈ {p | IsPrime p ∧ I ≤ p} → (fun x x_1 => x ≤ x_1) b p → (fun x x_1 => x ≤ x_1) p b
a : IsPrime p
ha : I ≤ p
⊢ ∀ ⦃b : Ideal R⦄, b ∈ {p | IsPrime p ∧ radical I ≤ p} → (fun x x_1 => x ≤ x_1) b p → (fun x x_1 => x ≤ x_1) p b

Next tactic:
simp only [Set.mem_setOf_eq, and_imp] at *
@[simp]
theorem Ideal.radical_minimalPrimes : I.radical.minimalPrimes = I.minimalPrimes := by
  rw [Ideal.minimalPrimes, Ideal.minimalPrimes]
  congr
  ext p
  refine' ⟨_, _⟩ <;> rintro ⟨⟨a, ha⟩, b⟩
  · refine' ⟨⟨a, a.radical_le_iff.1 ha⟩, _⟩
    · simp only [Set.mem_setOf_eq, and_imp] at *
      exact fun _ h2 h3 h4 => b h2 (h2.radical_le_iff.2 h3) h4
  · refine' ⟨⟨a, a.radical_le_iff.2 ha⟩, _⟩
    · simp only [Set.mem_setOf_eq, and_imp] at *
      

Proof state:
case h.refine'_2.intro.intro
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J p : Ideal R
a : IsPrime p
ha : I ≤ p
b : ∀ ⦃b : Ideal R⦄, IsPrime b → I ≤ b → b ≤ p → p ≤ b
⊢ ∀ ⦃b : Ideal R⦄, IsPrime b → radical I ≤ b → b ≤ p → p ≤ b

Next tactic:
exact fun _ h2 h3 h4 => b h2 (h2.radical_le_iff.1 h3) h4
@[simp]
theorem Ideal.sInf_minimalPrimes : sInf I.minimalPrimes = I.radical := by
  

Proof state:
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J : Ideal R
⊢ sInf (Ideal.minimalPrimes I) = radical I

Next tactic:
rw [I.radical_eq_sInf]
@[simp]
theorem Ideal.sInf_minimalPrimes : sInf I.minimalPrimes = I.radical := by
  rw [I.radical_eq_sInf]
  

Proof state:
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J : Ideal R
⊢ sInf (Ideal.minimalPrimes I) = sInf {J | I ≤ J ∧ IsPrime J}

Next tactic:
apply le_antisymm
@[simp]
theorem Ideal.sInf_minimalPrimes : sInf I.minimalPrimes = I.radical := by
  rw [I.radical_eq_sInf]
  apply le_antisymm
  · 

Proof state:
case a
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J : Ideal R
⊢ sInf (Ideal.minimalPrimes I) ≤ sInf {J | I ≤ J ∧ IsPrime J}

Next tactic:
intro x hx
@[simp]
theorem Ideal.sInf_minimalPrimes : sInf I.minimalPrimes = I.radical := by
  rw [I.radical_eq_sInf]
  apply le_antisymm
  · intro x hx
    

Proof state:
case a
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J : Ideal R
x : R
hx : x ∈ sInf (Ideal.minimalPrimes I)
⊢ x ∈ sInf {J | I ≤ J ∧ IsPrime J}

Next tactic:
rw [Ideal.mem_sInf] at hx ⊢
@[simp]
theorem Ideal.sInf_minimalPrimes : sInf I.minimalPrimes = I.radical := by
  rw [I.radical_eq_sInf]
  apply le_antisymm
  · intro x hx
    rw [Ideal.mem_sInf] at hx ⊢
    

Proof state:
case a
R : Type u_1
S : Type u_2
inst✝¹ : CommRing R
inst✝ : CommRing S
I J : Ideal R
x : R
hx : ∀ ⦃I_1 : Ideal R⦄, I_1 ∈ Ideal.minimalPrimes I → x ∈ I_1
⊢ ∀ ⦃I_1 : Ideal R⦄, I_1 ∈ {J | I ≤ J ∧ IsPrime J} → x ∈ I_1

Next tactic:
rintro J ⟨e, hJ⟩