theorem Ideal.IsHomogeneous.isPrime_of_homogeneous_mem_or_mem {I : Ideal A} (hI : I.IsHomogeneous 𝒜)
    (I_ne_top : I ≠ ⊤)
    (homogeneous_mem_or_mem :
      ∀ {x y : A}, Homogeneous 𝒜 x → Homogeneous 𝒜 y → x * y ∈ I → x ∈ I ∨ y ∈ I) :
    Ideal.IsPrime I :=
  ⟨I_ne_top, by
    intro x y hxy
    by_contra! rid
    obtain ⟨rid₁, rid₂⟩ := rid
    classical
      /-
        The idea of the proof is the following :
        since `x * y ∈ I` and `I` homogeneous, then `proj i (x * y) ∈ I` for any `i : ι`.
        Then consider two sets `{i ∈ x.support | xᵢ ∉ I}` and `{j ∈ y.support | yⱼ ∉ J}`;
        let `max₁, max₂` be the maximum of the two sets, then `proj (max₁ + max₂) (x * y) ∈ I`.
        Then, `proj max₁ x ∉ I` and `proj max₂ j ∉ I`
        but `proj i x ∈ I` for all `max₁ < i` and `proj j y ∈ I` for all `max₂ < j`.
        `  proj (max₁ + max₂) (x * y)`
        `= ∑ {(i, j) ∈ supports | i + j = max₁ + max₂}, xᵢ * yⱼ`
        `= proj max₁ x * proj max₂ y`
        `  + ∑ {(i, j) ∈ supports \ {(max₁, max₂)} | i + j = max₁ + max₂}, xᵢ * yⱼ`.
        This is a contradiction, because both `proj (max₁ + max₂) (x * y) ∈ I` and the sum on the
        right hand side is in `I` however `proj max₁ x * proj max₂ y` is not in `I`.
        -/
      set set₁ := (decompose 𝒜 x).support.filter (fun i => proj 𝒜 i x ∉ I) with set₁_eq
      set set₂ := (decompose 𝒜 y).support.filter (fun i => proj 𝒜 i y ∉ I) with set₂_eq
      have nonempty :
        ∀ x : A, x ∉ I → ((decompose 𝒜 x).support.filter (fun i => proj 𝒜 i x ∉ I)).Nonempty := by
        intro x hx
        rw [filter_nonempty_iff]
        contrapose! hx
        simp_rw [proj_apply] at hx
        rw [← sum_support_decompose 𝒜 x]
        exact Ideal.sum_mem _ hx
      set max₁ := set₁.max' (nonempty x rid₁)
      set max₂ := set₂.max' (nonempty y rid₂)
      have mem_max₁ : max₁ ∈ set₁ := max'_mem set₁ (nonempty x rid₁)
      have mem_max₂ : max₂ ∈ set₂ := max'_mem set₂ (nonempty y rid₂)
      replace hxy : proj 𝒜 (max₁ + max₂) (x * y) ∈ I := hI _ hxy
      have mem_I : proj 𝒜 max₁ x * proj 𝒜 max₂ y ∈ I := by
        set antidiag :=
          ((decompose 𝒜 x).support ×ˢ (decompose 𝒜 y).support).filter (fun z : ι × ι =>
            z.1 + z.2 = max₁ + max₂) with ha
        have mem_antidiag : (max₁, max₂) ∈ antidiag := by
          simp only [add_sum_erase, mem_filter, mem_product]
          exact ⟨⟨mem_of_mem_filter _ mem_max₁, mem_of_mem_filter _ mem_max₂⟩, trivial⟩
        have eq_add_sum :=
          calc
            proj 𝒜 (max₁ + max₂) (x * y) = ∑ ij in antidiag, proj 𝒜 ij.1 x * proj 𝒜 ij.2 y := by
              simp_rw [ha, proj_apply, DirectSum.decompose_mul, DirectSum.coe_mul_apply 𝒜]
            _ =
                proj 𝒜 max₁ x * proj 𝒜 max₂ y +
                  ∑ ij in antidiag.erase (max₁, max₂), proj 𝒜 ij.1 x * proj 𝒜 ij.2 y :=
              (add_sum_erase _ _ mem_antidiag).symm
        rw [eq_sub_of_add_eq eq_add_sum.symm]
        refine' Ideal.sub_mem _ hxy (Ideal.sum_mem _ fun z H => _)
        rcases z with ⟨i, j⟩
        simp only [mem_erase, Prod.mk.inj_iff, Ne.def, mem_filter, mem_product] at H
        rcases H with ⟨H₁, ⟨H₂, H₃⟩, H₄⟩
        have max_lt : max₁ < i ∨ max₂ < j := by
          rcases lt_trichotomy max₁ i with (h | rfl | h)
          · exact Or.inl h
          · refine' False.elim (H₁ ⟨rfl, add_left_cancel H₄⟩)
          · apply Or.inr
            have := add_lt_add_right h j
            rw [H₄] at this
            exact lt_of_add_lt_add_left this
        cases' max_lt with max_lt max_lt
        · -- in this case `max₁ < i`, then `xᵢ ∈ I`; for otherwise `i ∈ set₁` then `i ≤ max₁`.
          have not_mem : i ∉ set₁ := fun h =>
            lt_irrefl _ ((max'_lt_iff set₁ (nonempty x rid₁)).mp max_lt i h)
          rw [set₁_eq] at not_mem
          simp only [not_and, Classical.not_not, Ne.def, mem_filter] at not_mem
          exact Ideal.mul_mem_right _ I (not_mem H₂)
        · -- in this case `max₂ < j`, then `yⱼ ∈ I`; for otherwise `j ∈ set₂`, then `j ≤ max₂`.
          have not_mem : j ∉ set₂ := fun h =>
            lt_irrefl _ ((max'_lt_iff set₂ (nonempty y rid₂)).mp max_lt j h)
          rw [set₂_eq] at not_mem
          simp only [not_and, Classical.not_not, Ne.def, mem_filter] at not_mem
          

Proof state:
case mk.intro.intro.intro.inr
ι : Type u_1
σ : Type u_2
A : Type u_3
inst✝⁴ : CommRing A
inst✝³ : LinearOrderedCancelAddCommMonoid ι
inst✝² : SetLike σ A
inst✝¹ : AddSubmonoidClass σ A
𝒜 : ι → σ
inst✝ : GradedRing 𝒜
I : Ideal A
hI : IsHomogeneous 𝒜 I
I_ne_top : I ≠ ⊤
homogeneous_mem_or_mem : ∀ {x y : A}, Homogeneous 𝒜 x → Homogeneous 𝒜 y → x * y ∈ I → x ∈ I ∨ y ∈ I
x y : A
rid₁ : x ∉ I
rid₂ : y ∉ I
set₁ : Finset ι := filter (fun i => (proj 𝒜 i) x ∉ I) (DFinsupp.support ((decompose 𝒜) x))
set₁_eq : set₁ = filter (fun i => (proj 𝒜 i) x ∉ I) (DFinsupp.support ((decompose 𝒜) x))
set₂ : Finset ι := filter (fun i => (proj 𝒜 i) y ∉ I) (DFinsupp.support ((decompose 𝒜) y))
set₂_eq : set₂ = filter (fun i => (proj 𝒜 i) y ∉ I) (DFinsupp.support ((decompose 𝒜) y))
nonempty : ∀ x ∉ I, Finset.Nonempty (filter (fun i => (proj 𝒜 i) x ∉ I) (DFinsupp.support ((decompose 𝒜) x)))
max₁ : ι := max' set₁ (_ : Finset.Nonempty (filter (fun i => (proj 𝒜 i) x ∉ I) (DFinsupp.support ((decompose 𝒜) x))))
max₂ : ι := max' set₂ (_ : Finset.Nonempty (filter (fun i => (proj 𝒜 i) y ∉ I) (DFinsupp.support ((decompose 𝒜) y))))
mem_max₁ : max₁ ∈ set₁
mem_max₂ : max₂ ∈ set₂
hxy : (proj 𝒜 (max₁ + max₂)) (x * y) ∈ I
antidiag : Finset (ι × ι) :=
  filter (fun z => z.1 + z.2 = max₁ + max₂) (DFinsupp.support ((decompose 𝒜) x) ×ˢ DFinsupp.support ((decompose 𝒜) y))
ha :
  antidiag =
    filter (fun z => z.1 + z.2 = max₁ + max₂) (DFinsupp.support ((decompose 𝒜) x) ×ˢ DFinsupp.support ((decompose 𝒜) y))
mem_antidiag : (max₁, max₂) ∈ antidiag
eq_add_sum :
  (proj 𝒜 (max₁ + max₂)) (x * y) =
    (proj 𝒜 max₁) x * (proj 𝒜 max₂) y + ∑ ij in erase antidiag (max₁, max₂), (proj 𝒜 ij.1) x * (proj 𝒜 ij.2) y
i j : ι
H₁ :
  ¬(i =
        max' (filter (fun i => (proj 𝒜 i) x ∉ I) (DFinsupp.support ((decompose 𝒜) x)))
          (_ : Finset.Nonempty (filter (fun i => (proj 𝒜 i) x ∉ I) (DFinsupp.support ((decompose 𝒜) x)))) ∧
      j =
        max' (filter (fun i => (proj 𝒜 i) y ∉ I) (DFinsupp.support ((decompose 𝒜) y)))
          (_ : Finset.Nonempty (filter (fun i => (proj 𝒜 i) y ∉ I) (DFinsupp.support ((decompose 𝒜) y)))))
H₄ :
  i + j =
    max' (filter (fun i => (proj 𝒜 i) x ∉ I) (DFinsupp.support ((decompose 𝒜) x)))
        (_ : Finset.Nonempty (filter (fun i => (proj 𝒜 i) x ∉ I) (DFinsupp.support ((decompose 𝒜) x)))) +
      max' (filter (fun i => (proj 𝒜 i) y ∉ I) (DFinsupp.support ((decompose 𝒜) y)))
        (_ : Finset.Nonempty (filter (fun i => (proj 𝒜 i) y ∉ I) (DFinsupp.support ((decompose 𝒜) y))))
H₂ : i ∈ DFinsupp.support ((decompose 𝒜) x)
H₃ : j ∈ DFinsupp.support ((decompose 𝒜) y)
max_lt : max₂ < j
not_mem : j ∈ DFinsupp.support ((decompose 𝒜) y) → (proj 𝒜 j) y ∈ I
⊢ (proj 𝒜 (i, j).1) x * (proj 𝒜 (i, j).2) y ∈ I

Next tactic:
exact Ideal.mul_mem_left I _ (not_mem H₃)