theorem DiscreteValuationRing.TFAE [IsNoetherianRing R] [LocalRing R] [IsDomain R]
    (h : ¬IsField R) :
    List.TFAE
      [DiscreteValuationRing R, ValuationRing R, IsDedekindDomain R,
        IsIntegrallyClosed R ∧ ∃! P : Ideal R, P ≠ ⊥ ∧ P.IsPrime, (maximalIdeal R).IsPrincipal,
        FiniteDimensional.finrank (ResidueField R) (CotangentSpace R) = 1,
        ∀ (I) (_ : I ≠ ⊥), ∃ n : ℕ, I = maximalIdeal R ^ n] := by
  have ne_bot := Ring.ne_bot_of_isMaximal_of_not_isField (maximalIdeal.isMaximal R) h
  classical
  rw [finrank_eq_one_iff']
  tfae_have 1 → 2
  · intro; infer_instance
  tfae_have 2 → 1
  · intro
    haveI := IsBezout.toGCDDomain R
    haveI : UniqueFactorizationMonoid R := ufm_of_gcd_of_wfDvdMonoid
    apply DiscreteValuationRing.of_ufd_of_unique_irreducible
    · obtain ⟨x, hx₁, hx₂⟩ := Ring.exists_not_isUnit_of_not_isField h
      obtain ⟨p, hp₁, -⟩ := WfDvdMonoid.exists_irreducible_factor hx₂ hx₁
      exact ⟨p, hp₁⟩
    · exact ValuationRing.unique_irreducible
  tfae_have 1 → 4
  · intro H
    exact ⟨inferInstance, ((DiscreteValuationRing.iff_pid_with_one_nonzero_prime R).mp H).2⟩
  tfae_have 4 → 3
  · rintro ⟨h₁, h₂⟩;
    exact { h₁ with
      maximalOfPrime := fun hI hI' => ExistsUnique.unique h₂ ⟨ne_bot, inferInstance⟩ ⟨hI, hI'⟩ ▸
        maximalIdeal.isMaximal R, }
  tfae_have 3 → 5
  · intro h; exact maximalIdeal_isPrincipal_of_isDedekindDomain R
  tfae_have 5 → 6
  · rintro ⟨x, hx⟩
    have : x ∈ maximalIdeal R := by rw [hx]; exact Submodule.subset_span (Set.mem_singleton x)
    let x' : maximalIdeal R := ⟨x, this⟩
    use Submodule.Quotient.mk x'
    constructor
    swap
    · intro e
      rw [Submodule.Quotient.mk_eq_zero] at e
      apply Ring.ne_bot_of_isMaximal_of_not_isField (maximalIdeal.isMaximal R) h
      apply Submodule.eq_bot_of_le_smul_of_le_jacobson_bot (maximalIdeal R)
      · exact ⟨{x}, (Finset.coe_singleton x).symm ▸ hx.symm⟩
      · conv_lhs => rw [hx]
        rw [Submodule.mem_smul_top_iff] at e
        rwa [Submodule.span_le, Set.singleton_subset_iff]
      · rw [LocalRing.jacobson_eq_maximalIdeal (⊥ : Ideal R) bot_ne_top]
    · refine' fun w => Quotient.inductionOn' w fun y => _
      obtain ⟨y, hy⟩ := y
      rw [hx, Submodule.mem_span_singleton] at hy
      obtain ⟨a, rfl⟩ := hy
      exact ⟨Ideal.Quotient.mk _ a, rfl⟩
  tfae_have 6 → 5
  · rintro ⟨x, hx, hx'⟩
    induction x using Quotient.inductionOn' with | h x => ?_
    use x
    apply le_antisymm
    swap; · rw [Submodule.span_le, Set.singleton_subset_iff]; exact x.prop
    have h₁ :
      (Ideal.span {(x : R)} : Ideal R) ⊔ maximalIdeal R ≤
        Ideal.span {(x : R)} ⊔ maximalIdeal R • maximalIdeal R := by
      refine' sup_le le_sup_left _
      rintro m hm
      obtain ⟨c, hc⟩ := hx' (Submodule.Quotient.mk ⟨m, hm⟩)
      induction c using Quotient.inductionOn' with | h c => ?_
      rw [← sub_sub_cancel (c * x) m]
      apply sub_mem _ _
      · refine' Ideal.mem_sup_left (Ideal.mem_span_singleton'.mpr ⟨c, rfl⟩)
      · have := (Submodule.Quotient.eq _).mp hc
        rw [Submodule.mem_smul_top_iff] at this
        exact Ideal.mem_sup_right this
    have h₂ : maximalIdeal R ≤ (⊥ : Ideal R).jacobson := by
      rw [LocalRing.jacobson_eq_maximalIdeal]
      exact bot_ne_top
    have :=
      Submodule.sup_smul_eq_sup_smul_of_le_smul_of_le_jacobson (IsNoetherian.noetherian _) h₂ h₁
    rw [Submodule.bot_smul, sup_bot_eq] at this
    rw [← sup_eq_left, eq_comm]
    exact le_sup_left.antisymm (h₁.trans <| le_of_eq this)
  tfae_have 5 → 7
  · exact exists_maximalIdeal_pow_eq_of_principal R h
  tfae_have 7 → 2
  · rw [ValuationRing.iff_ideal_total]
    intro H
    constructor
    intro I J
    -- `by_cases` should invoke `classical` by itself if it can't find a `Decidable` instance,
    -- however the `tfae` hypotheses trigger a looping instance search.
    -- See also:
    -- https://leanprover.zulipchat.com/#narrow/stream/113488-general/topic/.60by_cases.60.20trying.20to.20find.20a.20weird.20instance
    -- As a workaround, add the desired instance ourselves.
    let _ := Classical.decEq (Ideal R)
    by_cases hI : I = ⊥; · 

Proof state:
case pos
R : Type u_1
inst✝⁶ : CommRing R
K : Type u_2
inst✝⁵ : Field K
inst✝⁴ : Algebra R K
inst✝³ : IsFractionRing R K
inst✝² : IsNoetherianRing R
inst✝¹ : LocalRing R
inst✝ : IsDomain R
h : ¬IsField R
ne_bot : maximalIdeal R ≠ ⊥
tfae_1_to_2 : DiscreteValuationRing R → ValuationRing R
tfae_2_to_1 : ValuationRing R → DiscreteValuationRing R
tfae_1_to_4 : DiscreteValuationRing R → IsIntegrallyClosed R ∧ ∃! P, P ≠ ⊥ ∧ Ideal.IsPrime P
tfae_4_to_3 : (IsIntegrallyClosed R ∧ ∃! P, P ≠ ⊥ ∧ Ideal.IsPrime P) → IsDedekindDomain R
tfae_3_to_5 : IsDedekindDomain R → Submodule.IsPrincipal (maximalIdeal R)
tfae_5_to_6 : Submodule.IsPrincipal (maximalIdeal R) → ∃ v, ∃ (_ : v ≠ 0), ∀ (w : CotangentSpace R), ∃ c, c • v = w
tfae_6_to_5 : (∃ v, ∃ (_ : v ≠ 0), ∀ (w : CotangentSpace R), ∃ c, c • v = w) → Submodule.IsPrincipal (maximalIdeal R)
tfae_5_to_7 : Submodule.IsPrincipal (maximalIdeal R) → ∀ (I : Ideal R), I ≠ ⊥ → ∃ n, I = maximalIdeal R ^ n
H : ∀ (I : Ideal R), I ≠ ⊥ → ∃ n, I = maximalIdeal R ^ n
I J : Ideal R
x✝ : DecidableEq (Ideal R) := Classical.decEq (Ideal R)
hI : I = ⊥
⊢ I ≤ J ∨ J ≤ I

Next tactic:
subst hI