l3lab/ntp-mathlib huggingface dataset:
/-- Every ideal of the product ring is of the form `I × J`, where `I` and `J` can be explicitly
    given as the image under the projection maps. -/
theorem ideal_prod_eq (I : Ideal (R × S)) :
    I = Ideal.prod (map (RingHom.fst R S) I : Ideal R) (map (RingHom.snd R S) I) := by
  apply Ideal.ext
  rintro ⟨r, s⟩
  rw [mem_prod, mem_map_iff_of_surjective (RingHom.fst R S) Prod.fst_surjective,
    mem_map_iff_of_surjective (RingHom.snd R S) Prod.snd_surjective]
  

Proof state:
case h.mk
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal (R × S)
r : R
s : S
⊢ (r, s) ∈ I ↔ (∃ x ∈ I, (RingHom.fst R S) x = r) ∧ ∃ x ∈ I, (RingHom.snd R S) x = s

Next tactic:
refine' ⟨fun h => ⟨⟨_, ⟨h, rfl⟩⟩, ⟨_, ⟨h, rfl⟩⟩⟩, _⟩
/-- Every ideal of the product ring is of the form `I × J`, where `I` and `J` can be explicitly
    given as the image under the projection maps. -/
theorem ideal_prod_eq (I : Ideal (R × S)) :
    I = Ideal.prod (map (RingHom.fst R S) I : Ideal R) (map (RingHom.snd R S) I) := by
  apply Ideal.ext
  rintro ⟨r, s⟩
  rw [mem_prod, mem_map_iff_of_surjective (RingHom.fst R S) Prod.fst_surjective,
    mem_map_iff_of_surjective (RingHom.snd R S) Prod.snd_surjective]
  refine' ⟨fun h => ⟨⟨_, ⟨h, rfl⟩⟩, ⟨_, ⟨h, rfl⟩⟩⟩, _⟩
  

Proof state:
case h.mk
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal (R × S)
r : R
s : S
⊢ ((∃ x ∈ I, (RingHom.fst R S) x = r) ∧ ∃ x ∈ I, (RingHom.snd R S) x = s) → (r, s) ∈ I

Next tactic:
rintro ⟨⟨⟨r, s'⟩, ⟨h₁, rfl⟩⟩, ⟨⟨r', s⟩, ⟨h₂, rfl⟩⟩⟩
/-- Every ideal of the product ring is of the form `I × J`, where `I` and `J` can be explicitly
    given as the image under the projection maps. -/
theorem ideal_prod_eq (I : Ideal (R × S)) :
    I = Ideal.prod (map (RingHom.fst R S) I : Ideal R) (map (RingHom.snd R S) I) := by
  apply Ideal.ext
  rintro ⟨r, s⟩
  rw [mem_prod, mem_map_iff_of_surjective (RingHom.fst R S) Prod.fst_surjective,
    mem_map_iff_of_surjective (RingHom.snd R S) Prod.snd_surjective]
  refine' ⟨fun h => ⟨⟨_, ⟨h, rfl⟩⟩, ⟨_, ⟨h, rfl⟩⟩⟩, _⟩
  rintro ⟨⟨⟨r, s'⟩, ⟨h₁, rfl⟩⟩, ⟨⟨r', s⟩, ⟨h₂, rfl⟩⟩⟩
  

Proof state:
case h.mk.intro.intro.mk.intro.intro.mk.intro
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal (R × S)
r : R
s' : S
h₁ : (r, s') ∈ I
r' : R
s : S
h₂ : (r', s) ∈ I
⊢ ((RingHom.fst R S) (r, s'), (RingHom.snd R S) (r', s)) ∈ I

Next tactic:
simpa using I.add_mem (I.mul_mem_left (1, 0) h₁) (I.mul_mem_left (0, 1) h₂)
@[simp]
theorem map_fst_prod (I : Ideal R) (J : Ideal S) : map (RingHom.fst R S) (prod I J) = I := by
  

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J✝ J' : Ideal S
I : Ideal R
J : Ideal S
⊢ map (RingHom.fst R S) (prod I J) = I

Next tactic:
ext x
@[simp]
theorem map_fst_prod (I : Ideal R) (J : Ideal S) : map (RingHom.fst R S) (prod I J) = I := by
  ext x
  

Proof state:
case h
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J✝ J' : Ideal S
I : Ideal R
J : Ideal S
x : R
⊢ x ∈ map (RingHom.fst R S) (prod I J) ↔ x ∈ I

Next tactic:
rw [mem_map_iff_of_surjective (RingHom.fst R S) Prod.fst_surjective]
@[simp]
theorem map_fst_prod (I : Ideal R) (J : Ideal S) : map (RingHom.fst R S) (prod I J) = I := by
  ext x
  rw [mem_map_iff_of_surjective (RingHom.fst R S) Prod.fst_surjective]
  

Proof state:
case h
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J✝ J' : Ideal S
I : Ideal R
J : Ideal S
x : R
⊢ (∃ x_1 ∈ prod I J, (RingHom.fst R S) x_1 = x) ↔ x ∈ I

Next tactic:
exact
    ⟨by
      rintro ⟨x, ⟨h, rfl⟩⟩
      exact h.1, fun h => ⟨⟨x, 0⟩, ⟨⟨h, Ideal.zero_mem _⟩, rfl⟩⟩⟩
@[simp]
theorem map_fst_prod (I : Ideal R) (J : Ideal S) : map (RingHom.fst R S) (prod I J) = I := by
  ext x
  rw [mem_map_iff_of_surjective (RingHom.fst R S) Prod.fst_surjective]
  exact
    ⟨by
      

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J✝ J' : Ideal S
I : Ideal R
J : Ideal S
x : R
⊢ (∃ x_1 ∈ prod I J, (RingHom.fst R S) x_1 = x) → x ∈ I

Next tactic:
rintro ⟨x, ⟨h, rfl⟩⟩
@[simp]
theorem map_fst_prod (I : Ideal R) (J : Ideal S) : map (RingHom.fst R S) (prod I J) = I := by
  ext x
  rw [mem_map_iff_of_surjective (RingHom.fst R S) Prod.fst_surjective]
  exact
    ⟨by
      rintro ⟨x, ⟨h, rfl⟩⟩
      

Proof state:
case intro.intro
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J✝ J' : Ideal S
I : Ideal R
J : Ideal S
x : R × S
h : x ∈ prod I J
⊢ (RingHom.fst R S) x ∈ I

Next tactic:
exact h.1
@[simp]
theorem map_snd_prod (I : Ideal R) (J : Ideal S) : map (RingHom.snd R S) (prod I J) = J := by
  

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J✝ J' : Ideal S
I : Ideal R
J : Ideal S
⊢ map (RingHom.snd R S) (prod I J) = J

Next tactic:
ext x
@[simp]
theorem map_snd_prod (I : Ideal R) (J : Ideal S) : map (RingHom.snd R S) (prod I J) = J := by
  ext x
  

Proof state:
case h
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J✝ J' : Ideal S
I : Ideal R
J : Ideal S
x : S
⊢ x ∈ map (RingHom.snd R S) (prod I J) ↔ x ∈ J

Next tactic:
rw [mem_map_iff_of_surjective (RingHom.snd R S) Prod.snd_surjective]
@[simp]
theorem map_snd_prod (I : Ideal R) (J : Ideal S) : map (RingHom.snd R S) (prod I J) = J := by
  ext x
  rw [mem_map_iff_of_surjective (RingHom.snd R S) Prod.snd_surjective]
  

Proof state:
case h
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J✝ J' : Ideal S
I : Ideal R
J : Ideal S
x : S
⊢ (∃ x_1 ∈ prod I J, (RingHom.snd R S) x_1 = x) ↔ x ∈ J

Next tactic:
exact
    ⟨by
      rintro ⟨x, ⟨h, rfl⟩⟩
      exact h.2, fun h => ⟨⟨0, x⟩, ⟨⟨Ideal.zero_mem _, h⟩, rfl⟩⟩⟩
@[simp]
theorem map_snd_prod (I : Ideal R) (J : Ideal S) : map (RingHom.snd R S) (prod I J) = J := by
  ext x
  rw [mem_map_iff_of_surjective (RingHom.snd R S) Prod.snd_surjective]
  exact
    ⟨by
      

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J✝ J' : Ideal S
I : Ideal R
J : Ideal S
x : S
⊢ (∃ x_1 ∈ prod I J, (RingHom.snd R S) x_1 = x) → x ∈ J

Next tactic:
rintro ⟨x, ⟨h, rfl⟩⟩
@[simp]
theorem map_snd_prod (I : Ideal R) (J : Ideal S) : map (RingHom.snd R S) (prod I J) = J := by
  ext x
  rw [mem_map_iff_of_surjective (RingHom.snd R S) Prod.snd_surjective]
  exact
    ⟨by
      rintro ⟨x, ⟨h, rfl⟩⟩
      

Proof state:
case intro.intro
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J✝ J' : Ideal S
I : Ideal R
J : Ideal S
x : R × S
h : x ∈ prod I J
⊢ (RingHom.snd R S) x ∈ J

Next tactic:
exact h.2
@[simp]
theorem map_prodComm_prod :
    map ((RingEquiv.prodComm : R × S ≃+* S × R) : R × S →+* S × R) (prod I J) = prod J I := by
  

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I I' : Ideal R
J J' : Ideal S
⊢ map (↑RingEquiv.prodComm) (prod I J) = prod J I

Next tactic:
refine' Trans.trans (ideal_prod_eq _) _
@[simp]
theorem map_prodComm_prod :
    map ((RingEquiv.prodComm : R × S ≃+* S × R) : R × S →+* S × R) (prod I J) = prod J I := by
  refine' Trans.trans (ideal_prod_eq _) _
  

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I I' : Ideal R
J J' : Ideal S
⊢ prod (map (RingHom.fst S R) (map (↑RingEquiv.prodComm) (prod I J)))
      (map (RingHom.snd S R) (map (↑RingEquiv.prodComm) (prod I J))) =
    prod J I

Next tactic:
simp [map_map]
/-- Ideals of `R × S` are in one-to-one correspondence with pairs of ideals of `R` and ideals of
    `S`. -/
def idealProdEquiv : Ideal (R × S) ≃ Ideal R × Ideal S
    where
  toFun I := ⟨map (RingHom.fst R S) I, map (RingHom.snd R S) I⟩
  invFun I := prod I.1 I.2
  left_inv I := (ideal_prod_eq I).symm
  right_inv := fun ⟨I, J⟩ => by 

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J✝ J' : Ideal S
x✝ : Ideal R × Ideal S
I : Ideal R
J : Ideal S
⊢ (fun I => (map (RingHom.fst R S) I, map (RingHom.snd R S) I)) ((fun I => prod I.1 I.2) (I, J)) = (I, J)

Next tactic:
simp
theorem prod.ext_iff {I I' : Ideal R} {J J' : Ideal S} :
    prod I J = prod I' J' ↔ I = I' ∧ J = J' := by
  

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I'✝ : Ideal R
J✝ J'✝ : Ideal S
I I' : Ideal R
J J' : Ideal S
⊢ prod I J = prod I' J' ↔ I = I' ∧ J = J'

Next tactic:
simp only [← idealProdEquiv_symm_apply, idealProdEquiv.symm.injective.eq_iff, Prod.mk.inj_iff]
theorem isPrime_of_isPrime_prod_top {I : Ideal R} (h : (Ideal.prod I (⊤ : Ideal S)).IsPrime) :
    I.IsPrime := by
  

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal R
h : IsPrime (prod I ⊤)
⊢ IsPrime I

Next tactic:
constructor
theorem isPrime_of_isPrime_prod_top {I : Ideal R} (h : (Ideal.prod I (⊤ : Ideal S)).IsPrime) :
    I.IsPrime := by
  constructor
  · 

Proof state:
case ne_top'
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal R
h : IsPrime (prod I ⊤)
⊢ I ≠ ⊤

Next tactic:
contrapose! h
theorem isPrime_of_isPrime_prod_top {I : Ideal R} (h : (Ideal.prod I (⊤ : Ideal S)).IsPrime) :
    I.IsPrime := by
  constructor
  · contrapose! h
    

Proof state:
case ne_top'
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal R
h : I = ⊤
⊢ ¬IsPrime (prod I ⊤)

Next tactic:
rw [h, prod_top_top, isPrime_iff]
theorem isPrime_of_isPrime_prod_top {I : Ideal R} (h : (Ideal.prod I (⊤ : Ideal S)).IsPrime) :
    I.IsPrime := by
  constructor
  · contrapose! h
    rw [h, prod_top_top, isPrime_iff]
    

Proof state:
case ne_top'
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal R
h : I = ⊤
⊢ ¬(⊤ ≠ ⊤ ∧ ∀ {x y : R × S}, x * y ∈ ⊤ → x ∈ ⊤ ∨ y ∈ ⊤)

Next tactic:
simp [isPrime_iff, h]
theorem isPrime_of_isPrime_prod_top {I : Ideal R} (h : (Ideal.prod I (⊤ : Ideal S)).IsPrime) :
    I.IsPrime := by
  constructor
  · contrapose! h
    rw [h, prod_top_top, isPrime_iff]
    simp [isPrime_iff, h]
  · 

Proof state:
case mem_or_mem'
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal R
h : IsPrime (prod I ⊤)
⊢ ∀ {x y : R}, x * y ∈ I → x ∈ I ∨ y ∈ I

Next tactic:
intro x y hxy
theorem isPrime_of_isPrime_prod_top {I : Ideal R} (h : (Ideal.prod I (⊤ : Ideal S)).IsPrime) :
    I.IsPrime := by
  constructor
  · contrapose! h
    rw [h, prod_top_top, isPrime_iff]
    simp [isPrime_iff, h]
  · intro x y hxy
    

Proof state:
case mem_or_mem'
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal R
h : IsPrime (prod I ⊤)
x y : R
hxy : x * y ∈ I
⊢ x ∈ I ∨ y ∈ I

Next tactic:
have : (⟨x, 1⟩ : R × S) * ⟨y, 1⟩ ∈ prod I ⊤ := by
      rw [Prod.mk_mul_mk, mul_one, mem_prod]
      exact ⟨hxy, trivial⟩
theorem isPrime_of_isPrime_prod_top {I : Ideal R} (h : (Ideal.prod I (⊤ : Ideal S)).IsPrime) :
    I.IsPrime := by
  constructor
  · contrapose! h
    rw [h, prod_top_top, isPrime_iff]
    simp [isPrime_iff, h]
  · intro x y hxy
    have : (⟨x, 1⟩ : R × S) * ⟨y, 1⟩ ∈ prod I ⊤ := by
      

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal R
h : IsPrime (prod I ⊤)
x y : R
hxy : x * y ∈ I
⊢ (x, 1) * (y, 1) ∈ prod I ⊤

Next tactic:
rw [Prod.mk_mul_mk, mul_one, mem_prod]
theorem isPrime_of_isPrime_prod_top {I : Ideal R} (h : (Ideal.prod I (⊤ : Ideal S)).IsPrime) :
    I.IsPrime := by
  constructor
  · contrapose! h
    rw [h, prod_top_top, isPrime_iff]
    simp [isPrime_iff, h]
  · intro x y hxy
    have : (⟨x, 1⟩ : R × S) * ⟨y, 1⟩ ∈ prod I ⊤ := by
      rw [Prod.mk_mul_mk, mul_one, mem_prod]
      

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal R
h : IsPrime (prod I ⊤)
x y : R
hxy : x * y ∈ I
⊢ x * y ∈ I ∧ 1 ∈ ⊤

Next tactic:
exact ⟨hxy, trivial⟩
theorem isPrime_of_isPrime_prod_top {I : Ideal R} (h : (Ideal.prod I (⊤ : Ideal S)).IsPrime) :
    I.IsPrime := by
  constructor
  · contrapose! h
    rw [h, prod_top_top, isPrime_iff]
    simp [isPrime_iff, h]
  · intro x y hxy
    have : (⟨x, 1⟩ : R × S) * ⟨y, 1⟩ ∈ prod I ⊤ := by
      rw [Prod.mk_mul_mk, mul_one, mem_prod]
      exact ⟨hxy, trivial⟩
    

Proof state:
case mem_or_mem'
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal R
h : IsPrime (prod I ⊤)
x y : R
hxy : x * y ∈ I
this : (x, 1) * (y, 1) ∈ prod I ⊤
⊢ x ∈ I ∨ y ∈ I

Next tactic:
simpa using h.mem_or_mem this
theorem isPrime_of_isPrime_prod_top' {I : Ideal S} (h : (Ideal.prod (⊤ : Ideal R) I).IsPrime) :
    I.IsPrime := by
  

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' I : Ideal S
h : IsPrime (prod ⊤ I)
⊢ IsPrime I

Next tactic:
apply @isPrime_of_isPrime_prod_top _ R
theorem isPrime_of_isPrime_prod_top' {I : Ideal S} (h : (Ideal.prod (⊤ : Ideal R) I).IsPrime) :
    I.IsPrime := by
  apply @isPrime_of_isPrime_prod_top _ R
  

Proof state:
case h
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' I : Ideal S
h : IsPrime (prod ⊤ I)
⊢ IsPrime (prod I ⊤)

Next tactic:
rw [← map_prodComm_prod]
theorem isPrime_of_isPrime_prod_top' {I : Ideal S} (h : (Ideal.prod (⊤ : Ideal R) I).IsPrime) :
    I.IsPrime := by
  apply @isPrime_of_isPrime_prod_top _ R
  rw [← map_prodComm_prod]
  

Proof state:
case h
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' I : Ideal S
h : IsPrime (prod ⊤ I)
⊢ IsPrime (map (↑RingEquiv.prodComm) (prod ⊤ I))

Next tactic:
exact map_isPrime_of_equiv _
theorem isPrime_ideal_prod_top {I : Ideal R} [h : I.IsPrime] : (prod I (⊤ : Ideal S)).IsPrime := by
  

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal R
h : IsPrime I
⊢ IsPrime (prod I ⊤)

Next tactic:
constructor
theorem isPrime_ideal_prod_top {I : Ideal R} [h : I.IsPrime] : (prod I (⊤ : Ideal S)).IsPrime := by
  constructor
  · 

Proof state:
case ne_top'
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal R
h : IsPrime I
⊢ prod I ⊤ ≠ ⊤

Next tactic:
rcases h with ⟨h, -⟩
theorem isPrime_ideal_prod_top {I : Ideal R} [h : I.IsPrime] : (prod I (⊤ : Ideal S)).IsPrime := by
  constructor
  · rcases h with ⟨h, -⟩
    

Proof state:
case ne_top'.mk
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal R
h : I ≠ ⊤
⊢ prod I ⊤ ≠ ⊤

Next tactic:
contrapose! h
theorem isPrime_ideal_prod_top {I : Ideal R} [h : I.IsPrime] : (prod I (⊤ : Ideal S)).IsPrime := by
  constructor
  · rcases h with ⟨h, -⟩
    contrapose! h
    

Proof state:
case ne_top'.mk
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal R
h : prod I ⊤ = ⊤
⊢ I = ⊤

Next tactic:
rw [← prod_top_top, prod.ext_iff] at h
theorem isPrime_ideal_prod_top {I : Ideal R} [h : I.IsPrime] : (prod I (⊤ : Ideal S)).IsPrime := by
  constructor
  · rcases h with ⟨h, -⟩
    contrapose! h
    rw [← prod_top_top, prod.ext_iff] at h
    

Proof state:
case ne_top'.mk
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal R
h : I = ⊤ ∧ ⊤ = ⊤
⊢ I = ⊤

Next tactic:
exact h.1
theorem isPrime_ideal_prod_top {I : Ideal R} [h : I.IsPrime] : (prod I (⊤ : Ideal S)).IsPrime := by
  constructor
  · rcases h with ⟨h, -⟩
    contrapose! h
    rw [← prod_top_top, prod.ext_iff] at h
    exact h.1
  

Proof state:
case mem_or_mem'
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal R
h : IsPrime I
⊢ ∀ {x y : R × S}, x * y ∈ prod I ⊤ → x ∈ prod I ⊤ ∨ y ∈ prod I ⊤

Next tactic:
rintro ⟨r₁, s₁⟩ ⟨r₂, s₂⟩ ⟨h₁, _⟩
theorem isPrime_ideal_prod_top {I : Ideal R} [h : I.IsPrime] : (prod I (⊤ : Ideal S)).IsPrime := by
  constructor
  · rcases h with ⟨h, -⟩
    contrapose! h
    rw [← prod_top_top, prod.ext_iff] at h
    exact h.1
  rintro ⟨r₁, s₁⟩ ⟨r₂, s₂⟩ ⟨h₁, _⟩
  

Proof state:
case mem_or_mem'.mk.mk.intro
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal R
h : IsPrime I
r₁ : R
s₁ : S
r₂ : R
s₂ : S
h₁ : ((r₁, s₁) * (r₂, s₂)).1 ∈ I
right✝ : ((r₁, s₁) * (r₂, s₂)).2 ∈ ⊤
⊢ (r₁, s₁) ∈ prod I ⊤ ∨ (r₂, s₂) ∈ prod I ⊤

Next tactic:
cases' h.mem_or_mem h₁ with h h
theorem isPrime_ideal_prod_top {I : Ideal R} [h : I.IsPrime] : (prod I (⊤ : Ideal S)).IsPrime := by
  constructor
  · rcases h with ⟨h, -⟩
    contrapose! h
    rw [← prod_top_top, prod.ext_iff] at h
    exact h.1
  rintro ⟨r₁, s₁⟩ ⟨r₂, s₂⟩ ⟨h₁, _⟩
  cases' h.mem_or_mem h₁ with h h
  · 

Proof state:
case mem_or_mem'.mk.mk.intro.inl
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal R
h✝ : IsPrime I
r₁ : R
s₁ : S
r₂ : R
s₂ : S
h₁ : ((r₁, s₁) * (r₂, s₂)).1 ∈ I
right✝ : ((r₁, s₁) * (r₂, s₂)).2 ∈ ⊤
h : (r₁, s₁).1 ∈ I
⊢ (r₁, s₁) ∈ prod I ⊤ ∨ (r₂, s₂) ∈ prod I ⊤

Next tactic:
exact Or.inl ⟨h, trivial⟩
theorem isPrime_ideal_prod_top {I : Ideal R} [h : I.IsPrime] : (prod I (⊤ : Ideal S)).IsPrime := by
  constructor
  · rcases h with ⟨h, -⟩
    contrapose! h
    rw [← prod_top_top, prod.ext_iff] at h
    exact h.1
  rintro ⟨r₁, s₁⟩ ⟨r₂, s₂⟩ ⟨h₁, _⟩
  cases' h.mem_or_mem h₁ with h h
  · exact Or.inl ⟨h, trivial⟩
  · 

Proof state:
case mem_or_mem'.mk.mk.intro.inr
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal R
h✝ : IsPrime I
r₁ : R
s₁ : S
r₂ : R
s₂ : S
h₁ : ((r₁, s₁) * (r₂, s₂)).1 ∈ I
right✝ : ((r₁, s₁) * (r₂, s₂)).2 ∈ ⊤
h : (r₂, s₂).1 ∈ I
⊢ (r₁, s₁) ∈ prod I ⊤ ∨ (r₂, s₂) ∈ prod I ⊤

Next tactic:
exact Or.inr ⟨h, trivial⟩
theorem isPrime_ideal_prod_top' {I : Ideal S} [h : I.IsPrime] : (prod (⊤ : Ideal R) I).IsPrime := by
  

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' I : Ideal S
h : IsPrime I
⊢ IsPrime (prod ⊤ I)

Next tactic:
letI : IsPrime (prod I (⊤ : Ideal R)) := isPrime_ideal_prod_top
theorem isPrime_ideal_prod_top' {I : Ideal S} [h : I.IsPrime] : (prod (⊤ : Ideal R) I).IsPrime := by
  letI : IsPrime (prod I (⊤ : Ideal R)) := isPrime_ideal_prod_top
  

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' I : Ideal S
h : IsPrime I
this : IsPrime (prod I ⊤) := isPrime_ideal_prod_top
⊢ IsPrime (prod ⊤ I)

Next tactic:
rw [← map_prodComm_prod]
theorem isPrime_ideal_prod_top' {I : Ideal S} [h : I.IsPrime] : (prod (⊤ : Ideal R) I).IsPrime := by
  letI : IsPrime (prod I (⊤ : Ideal R)) := isPrime_ideal_prod_top
  rw [← map_prodComm_prod]
  

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' I : Ideal S
h : IsPrime I
this : IsPrime (prod I ⊤) := isPrime_ideal_prod_top
⊢ IsPrime (map (↑RingEquiv.prodComm) (prod I ⊤))

Next tactic:
apply map_isPrime_of_equiv _
theorem ideal_prod_prime_aux {I : Ideal R} {J : Ideal S} :
    (Ideal.prod I J).IsPrime → I = ⊤ ∨ J = ⊤ := by
  

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J✝ J' : Ideal S
I : Ideal R
J : Ideal S
⊢ IsPrime (prod I J) → I = ⊤ ∨ J = ⊤

Next tactic:
contrapose!
theorem ideal_prod_prime_aux {I : Ideal R} {J : Ideal S} :
    (Ideal.prod I J).IsPrime → I = ⊤ ∨ J = ⊤ := by
  contrapose!
  

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J✝ J' : Ideal S
I : Ideal R
J : Ideal S
⊢ I ≠ ⊤ ∧ J ≠ ⊤ → ¬IsPrime (prod I J)

Next tactic:
simp only [ne_top_iff_one, isPrime_iff, not_and, not_forall, not_or]
theorem ideal_prod_prime_aux {I : Ideal R} {J : Ideal S} :
    (Ideal.prod I J).IsPrime → I = ⊤ ∨ J = ⊤ := by
  contrapose!
  simp only [ne_top_iff_one, isPrime_iff, not_and, not_forall, not_or]
  

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J✝ J' : Ideal S
I : Ideal R
J : Ideal S
⊢ 1 ∉ I ∧ 1 ∉ J → 1 ∉ prod I J → ∃ x x_1, ∃ (_ : x * x_1 ∈ prod I J), x ∉ prod I J ∧ x_1 ∉ prod I J

Next tactic:
exact fun ⟨hI, hJ⟩ _ => ⟨⟨0, 1⟩, ⟨1, 0⟩, by simp, by simp [hJ], by simp [hI]⟩
theorem ideal_prod_prime_aux {I : Ideal R} {J : Ideal S} :
    (Ideal.prod I J).IsPrime → I = ⊤ ∨ J = ⊤ := by
  contrapose!
  simp only [ne_top_iff_one, isPrime_iff, not_and, not_forall, not_or]
  exact fun ⟨hI, hJ⟩ _ => ⟨⟨0, 1⟩, ⟨1, 0⟩, by 

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J✝ J' : Ideal S
I : Ideal R
J : Ideal S
x✝¹ : 1 ∉ I ∧ 1 ∉ J
x✝ : 1 ∉ prod I J
hI : 1 ∉ I
hJ : 1 ∉ J
⊢ (0, 1) * (1, 0) ∈ prod I J

Next tactic:
simp
theorem ideal_prod_prime_aux {I : Ideal R} {J : Ideal S} :
    (Ideal.prod I J).IsPrime → I = ⊤ ∨ J = ⊤ := by
  contrapose!
  simp only [ne_top_iff_one, isPrime_iff, not_and, not_forall, not_or]
  exact fun ⟨hI, hJ⟩ _ => ⟨⟨0, 1⟩, ⟨1, 0⟩, by simp, by 

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J✝ J' : Ideal S
I : Ideal R
J : Ideal S
x✝¹ : 1 ∉ I ∧ 1 ∉ J
x✝ : 1 ∉ prod I J
hI : 1 ∉ I
hJ : 1 ∉ J
⊢ (0, 1) ∉ prod I J

Next tactic:
simp [hJ]
theorem ideal_prod_prime_aux {I : Ideal R} {J : Ideal S} :
    (Ideal.prod I J).IsPrime → I = ⊤ ∨ J = ⊤ := by
  contrapose!
  simp only [ne_top_iff_one, isPrime_iff, not_and, not_forall, not_or]
  exact fun ⟨hI, hJ⟩ _ => ⟨⟨0, 1⟩, ⟨1, 0⟩, by simp, by simp [hJ], by 

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J✝ J' : Ideal S
I : Ideal R
J : Ideal S
x✝¹ : 1 ∉ I ∧ 1 ∉ J
x✝ : 1 ∉ prod I J
hI : 1 ∉ I
hJ : 1 ∉ J
⊢ (1, 0) ∉ prod I J

Next tactic:
simp [hI]
/-- Classification of prime ideals in product rings: the prime ideals of `R × S` are precisely the
    ideals of the form `p × S` or `R × p`, where `p` is a prime ideal of `R` or `S`. -/
theorem ideal_prod_prime (I : Ideal (R × S)) :
    I.IsPrime ↔
      (∃ p : Ideal R, p.IsPrime ∧ I = Ideal.prod p ⊤) ∨
        ∃ p : Ideal S, p.IsPrime ∧ I = Ideal.prod ⊤ p := by
  

Proof state:
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal (R × S)
⊢ IsPrime I ↔ (∃ p, IsPrime p ∧ I = prod p ⊤) ∨ ∃ p, IsPrime p ∧ I = prod ⊤ p

Next tactic:
constructor
/-- Classification of prime ideals in product rings: the prime ideals of `R × S` are precisely the
    ideals of the form `p × S` or `R × p`, where `p` is a prime ideal of `R` or `S`. -/
theorem ideal_prod_prime (I : Ideal (R × S)) :
    I.IsPrime ↔
      (∃ p : Ideal R, p.IsPrime ∧ I = Ideal.prod p ⊤) ∨
        ∃ p : Ideal S, p.IsPrime ∧ I = Ideal.prod ⊤ p := by
  constructor
  · 

Proof state:
case mp
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal (R × S)
⊢ IsPrime I → (∃ p, IsPrime p ∧ I = prod p ⊤) ∨ ∃ p, IsPrime p ∧ I = prod ⊤ p

Next tactic:
rw [ideal_prod_eq I]
/-- Classification of prime ideals in product rings: the prime ideals of `R × S` are precisely the
    ideals of the form `p × S` or `R × p`, where `p` is a prime ideal of `R` or `S`. -/
theorem ideal_prod_prime (I : Ideal (R × S)) :
    I.IsPrime ↔
      (∃ p : Ideal R, p.IsPrime ∧ I = Ideal.prod p ⊤) ∨
        ∃ p : Ideal S, p.IsPrime ∧ I = Ideal.prod ⊤ p := by
  constructor
  · rw [ideal_prod_eq I]
    

Proof state:
case mp
R : Type u
S : Type v
inst✝¹ : Semiring R
inst✝ : Semiring S
I✝ I' : Ideal R
J J' : Ideal S
I : Ideal (R × S)
⊢ IsPrime (prod (map (RingHom.fst R S) I) (map (RingHom.snd R S) I)) →
    (∃ p, IsPrime p ∧ prod (map (RingHom.fst R S) I) (map (RingHom.snd R S) I) = prod p ⊤) ∨
      ∃ p, IsPrime p ∧ prod (map (RingHom.fst R S) I) (map (RingHom.snd R S) I) = prod ⊤ p

Next tactic:
intro hI