l3lab/ntp-mathlib huggingface dataset:
lemma NoZeroSMulDivisors.isReduced (R M : Type*)
    [MonoidWithZero R] [Zero M] [MulActionWithZero R M] [Nontrivial M] [NoZeroSMulDivisors R M] :
    IsReduced R := by
  refine ⟨fun x ⟨k, hk⟩ ↦ ?_⟩
  induction' k with k ih
  · rw [Nat.zero_eq, pow_zero] at hk
    exact eq_zero_of_zero_eq_one hk.symm x
  · obtain ⟨m : M, hm : m ≠ 0⟩ := exists_ne (0 : M)
    have : x ^ (k + 1) • m = 0 := by simp only [hk, zero_smul]
    rw [pow_succ, mul_smul] at this
    

Proof state:
case succ.intro
R✝ : Type u_1
S : Type u_2
x✝¹ y : R✝
R : Type u_3
M : Type u_4
inst✝⁴ : MonoidWithZero R
inst✝³ : Zero M
inst✝² : MulActionWithZero R M
inst✝¹ : Nontrivial M
inst✝ : NoZeroSMulDivisors R M
x : R
x✝ : IsNilpotent x
k : ℕ
ih : x ^ k = 0 → x = 0
hk : x ^ Nat.succ k = 0
m : M
hm : m ≠ 0
this : x • x ^ k • m = 0
⊢ x = 0

Next tactic:
rcases eq_zero_or_eq_zero_of_smul_eq_zero this with rfl | hx
lemma NoZeroSMulDivisors.isReduced (R M : Type*)
    [MonoidWithZero R] [Zero M] [MulActionWithZero R M] [Nontrivial M] [NoZeroSMulDivisors R M] :
    IsReduced R := by
  refine ⟨fun x ⟨k, hk⟩ ↦ ?_⟩
  induction' k with k ih
  · rw [Nat.zero_eq, pow_zero] at hk
    exact eq_zero_of_zero_eq_one hk.symm x
  · obtain ⟨m : M, hm : m ≠ 0⟩ := exists_ne (0 : M)
    have : x ^ (k + 1) • m = 0 := by simp only [hk, zero_smul]
    rw [pow_succ, mul_smul] at this
    rcases eq_zero_or_eq_zero_of_smul_eq_zero this with rfl | hx; 

Proof state:
case succ.intro.inl
R✝ : Type u_1
S : Type u_2
x y : R✝
R : Type u_3
M : Type u_4
inst✝⁴ : MonoidWithZero R
inst✝³ : Zero M
inst✝² : MulActionWithZero R M
inst✝¹ : Nontrivial M
inst✝ : NoZeroSMulDivisors R M
k : ℕ
m : M
hm : m ≠ 0
x✝ : IsNilpotent 0
ih : 0 ^ k = 0 → 0 = 0
hk : 0 ^ Nat.succ k = 0
this : 0 • 0 ^ k • m = 0
⊢ 0 = 0
case succ.intro.inr
R✝ : Type u_1
S : Type u_2
x✝¹ y : R✝
R : Type u_3
M : Type u_4
inst✝⁴ : MonoidWithZero R
inst✝³ : Zero M
inst✝² : MulActionWithZero R M
inst✝¹ : Nontrivial M
inst✝ : NoZeroSMulDivisors R M
x : R
x✝ : IsNilpotent x
k : ℕ
ih : x ^ k = 0 → x = 0
hk : x ^ Nat.succ k = 0
m : M
hm : m ≠ 0
this : x • x ^ k • m = 0
hx : x ^ k • m = 0
⊢ x = 0

Next tactic:
rfl
lemma NoZeroSMulDivisors.isReduced (R M : Type*)
    [MonoidWithZero R] [Zero M] [MulActionWithZero R M] [Nontrivial M] [NoZeroSMulDivisors R M] :
    IsReduced R := by
  refine ⟨fun x ⟨k, hk⟩ ↦ ?_⟩
  induction' k with k ih
  · rw [Nat.zero_eq, pow_zero] at hk
    exact eq_zero_of_zero_eq_one hk.symm x
  · obtain ⟨m : M, hm : m ≠ 0⟩ := exists_ne (0 : M)
    have : x ^ (k + 1) • m = 0 := by simp only [hk, zero_smul]
    rw [pow_succ, mul_smul] at this
    rcases eq_zero_or_eq_zero_of_smul_eq_zero this with rfl | hx; rfl
    

Proof state:
case succ.intro.inr
R✝ : Type u_1
S : Type u_2
x✝¹ y : R✝
R : Type u_3
M : Type u_4
inst✝⁴ : MonoidWithZero R
inst✝³ : Zero M
inst✝² : MulActionWithZero R M
inst✝¹ : Nontrivial M
inst✝ : NoZeroSMulDivisors R M
x : R
x✝ : IsNilpotent x
k : ℕ
ih : x ^ k = 0 → x = 0
hk : x ^ Nat.succ k = 0
m : M
hm : m ≠ 0
this : x • x ^ k • m = 0
hx : x ^ k • m = 0
⊢ x = 0

Next tactic:
exact ih <| (eq_zero_or_eq_zero_of_smul_eq_zero hx).resolve_right hm
@[simp]
theorem map_coe_finRange (n : ℕ) : ((finRange n) : List (Fin n)).map (Fin.val) = List.range n := by
  

Proof state:
α : Type u
n : ℕ
⊢ map Fin.val (finRange n) = range n

Next tactic:
simp_rw [finRange, map_pmap, pmap_eq_map]
@[simp]
theorem map_coe_finRange (n : ℕ) : ((finRange n) : List (Fin n)).map (Fin.val) = List.range n := by
  simp_rw [finRange, map_pmap, pmap_eq_map]
  

Proof state:
α : Type u
n : ℕ
⊢ map (fun a => a) (range n) = range n

Next tactic:
exact List.map_id _
theorem finRange_succ_eq_map (n : ℕ) : finRange n.succ = 0 :: (finRange n).map Fin.succ := by
  

Proof state:
α : Type u
n : ℕ
⊢ finRange (Nat.succ n) = 0 :: map Fin.succ (finRange n)

Next tactic:
apply map_injective_iff.mpr Fin.val_injective
theorem finRange_succ_eq_map (n : ℕ) : finRange n.succ = 0 :: (finRange n).map Fin.succ := by
  apply map_injective_iff.mpr Fin.val_injective
  

Proof state:
case a
α : Type u
n : ℕ
⊢ map Fin.val (finRange (Nat.succ n)) = map Fin.val (0 :: map Fin.succ (finRange n))

Next tactic:
rw [map_cons, map_coe_finRange, range_succ_eq_map, Fin.val_zero, ← map_coe_finRange, map_map,
    map_map]
theorem finRange_succ_eq_map (n : ℕ) : finRange n.succ = 0 :: (finRange n).map Fin.succ := by
  apply map_injective_iff.mpr Fin.val_injective
  rw [map_cons, map_coe_finRange, range_succ_eq_map, Fin.val_zero, ← map_coe_finRange, map_map,
    map_map]
  

Proof state:
case a
α : Type u
n : ℕ
⊢ 0 :: map (Nat.succ ∘ Fin.val) (finRange n) = 0 :: map (Fin.val ∘ Fin.succ) (finRange n)

Next tactic:
simp only [Function.comp, Fin.val_succ]
theorem finRange_succ (n : ℕ) :
    finRange n.succ = (finRange n |>.map Fin.castSucc |>.concat (.last _)) := by
  

Proof state:
α : Type u
n : ℕ
⊢ finRange (Nat.succ n) = concat (map Fin.castSucc (finRange n)) (Fin.last n)

Next tactic:
apply map_injective_iff.mpr Fin.val_injective
theorem finRange_succ (n : ℕ) :
    finRange n.succ = (finRange n |>.map Fin.castSucc |>.concat (.last _)) := by
  apply map_injective_iff.mpr Fin.val_injective
  

Proof state:
case a
α : Type u
n : ℕ
⊢ map Fin.val (finRange (Nat.succ n)) = map Fin.val (concat (map Fin.castSucc (finRange n)) (Fin.last n))

Next tactic:
simp [range_succ, Function.comp_def]
theorem ofFn_eq_pmap {α n} {f : Fin n → α} :
    ofFn f = pmap (fun i hi => f ⟨i, hi⟩) (range n) fun _ => mem_range.1 := by
  

Proof state:
α✝ : Type u
α : Type u_1
n : ℕ
f : Fin n → α
⊢ ofFn f = pmap (fun i hi => f { val := i, isLt := hi }) (range n) (_ : ∀ x ∈ range n, x < n)

Next tactic:
rw [pmap_eq_map_attach]
theorem ofFn_eq_pmap {α n} {f : Fin n → α} :
    ofFn f = pmap (fun i hi => f ⟨i, hi⟩) (range n) fun _ => mem_range.1 := by
  rw [pmap_eq_map_attach]
  

Proof state:
α✝ : Type u
α : Type u_1
n : ℕ
f : Fin n → α
⊢ ofFn f = map (fun x => f { val := ↑x, isLt := (_ : ↑x < n) }) (attach (range n))

Next tactic:
exact ext_get (by simp) fun i hi1 hi2 => by simp [get_ofFn f ⟨i, hi1⟩]
theorem ofFn_eq_pmap {α n} {f : Fin n → α} :
    ofFn f = pmap (fun i hi => f ⟨i, hi⟩) (range n) fun _ => mem_range.1 := by
  rw [pmap_eq_map_attach]
  exact ext_get (by 

Proof state:
α✝ : Type u
α : Type u_1
n : ℕ
f : Fin n → α
⊢ length (ofFn f) = length (map (fun x => f { val := ↑x, isLt := (_ : ↑x < n) }) (attach (range n)))

Next tactic:
simp
theorem ofFn_eq_pmap {α n} {f : Fin n → α} :
    ofFn f = pmap (fun i hi => f ⟨i, hi⟩) (range n) fun _ => mem_range.1 := by
  rw [pmap_eq_map_attach]
  exact ext_get (by simp) fun i hi1 hi2 => by 

Proof state:
α✝ : Type u
α : Type u_1
n : ℕ
f : Fin n → α
i : ℕ
hi1 : i < length (ofFn f)
hi2 : i < length (map (fun x => f { val := ↑x, isLt := (_ : ↑x < n) }) (attach (range n)))
⊢ get (ofFn f) { val := i, isLt := hi1 } =
    get (map (fun x => f { val := ↑x, isLt := (_ : ↑x < n) }) (attach (range n))) { val := i, isLt := hi2 }

Next tactic:
simp [get_ofFn f ⟨i, hi1⟩]
theorem ofFn_eq_map {α n} {f : Fin n → α} : ofFn f = (finRange n).map f := by
  

Proof state:
α✝ : Type u
α : Type u_1
n : ℕ
f : Fin n → α
⊢ ofFn f = map f (finRange n)

Next tactic:
rw [← ofFn_id, map_ofFn, Function.right_id]
theorem nodup_ofFn_ofInjective {α n} {f : Fin n → α} (hf : Function.Injective f) :
    Nodup (ofFn f) := by
  

Proof state:
α✝ : Type u
α : Type u_1
n : ℕ
f : Fin n → α
hf : Function.Injective f
⊢ Nodup (ofFn f)

Next tactic:
rw [ofFn_eq_pmap]
theorem nodup_ofFn_ofInjective {α n} {f : Fin n → α} (hf : Function.Injective f) :
    Nodup (ofFn f) := by
  rw [ofFn_eq_pmap]
  

Proof state:
α✝ : Type u
α : Type u_1
n : ℕ
f : Fin n → α
hf : Function.Injective f
⊢ Nodup (pmap (fun i hi => f { val := i, isLt := hi }) (range n) (_ : ∀ x ∈ range n, x < n))

Next tactic:
exact (nodup_range n).pmap fun _ _ _ _ H => Fin.veq_of_eq <| hf H
theorem nodup_ofFn {α n} {f : Fin n → α} : Nodup (ofFn f) ↔ Function.Injective f := by
  

Proof state:
α✝ : Type u
α : Type u_1
n : ℕ
f : Fin n → α
⊢ Nodup (ofFn f) ↔ Function.Injective f

Next tactic:
refine' ⟨_, nodup_ofFn_ofInjective⟩
theorem nodup_ofFn {α n} {f : Fin n → α} : Nodup (ofFn f) ↔ Function.Injective f := by
  refine' ⟨_, nodup_ofFn_ofInjective⟩
  

Proof state:
α✝ : Type u
α : Type u_1
n : ℕ
f : Fin n → α
⊢ Nodup (ofFn f) → Function.Injective f

Next tactic:
refine' Fin.consInduction _ (fun x₀ xs ih => _) f
theorem nodup_ofFn {α n} {f : Fin n → α} : Nodup (ofFn f) ↔ Function.Injective f := by
  refine' ⟨_, nodup_ofFn_ofInjective⟩
  refine' Fin.consInduction _ (fun x₀ xs ih => _) f
  · 

Proof state:
case refine'_1
α✝ : Type u
α : Type u_1
n : ℕ
f : Fin n → α
⊢ Nodup (ofFn Fin.elim0) → Function.Injective Fin.elim0

Next tactic:
intro _
theorem nodup_ofFn {α n} {f : Fin n → α} : Nodup (ofFn f) ↔ Function.Injective f := by
  refine' ⟨_, nodup_ofFn_ofInjective⟩
  refine' Fin.consInduction _ (fun x₀ xs ih => _) f
  · intro _
    

Proof state:
case refine'_1
α✝ : Type u
α : Type u_1
n : ℕ
f : Fin n → α
a✝ : Nodup (ofFn Fin.elim0)
⊢ Function.Injective Fin.elim0

Next tactic:
exact Function.injective_of_subsingleton _
theorem nodup_ofFn {α n} {f : Fin n → α} : Nodup (ofFn f) ↔ Function.Injective f := by
  refine' ⟨_, nodup_ofFn_ofInjective⟩
  refine' Fin.consInduction _ (fun x₀ xs ih => _) f
  · intro _
    exact Function.injective_of_subsingleton _
  · 

Proof state:
case refine'_2
α✝ : Type u
α : Type u_1
n : ℕ
f : Fin n → α
n✝ : ℕ
x₀ : α
xs : Fin n✝ → α
ih : Nodup (ofFn xs) → Function.Injective xs
⊢ Nodup (ofFn (Fin.cons x₀ xs)) → Function.Injective (Fin.cons x₀ xs)

Next tactic:
intro h
theorem nodup_ofFn {α n} {f : Fin n → α} : Nodup (ofFn f) ↔ Function.Injective f := by
  refine' ⟨_, nodup_ofFn_ofInjective⟩
  refine' Fin.consInduction _ (fun x₀ xs ih => _) f
  · intro _
    exact Function.injective_of_subsingleton _
  · intro h
    

Proof state:
case refine'_2
α✝ : Type u
α : Type u_1
n : ℕ
f : Fin n → α
n✝ : ℕ
x₀ : α
xs : Fin n✝ → α
ih : Nodup (ofFn xs) → Function.Injective xs
h : Nodup (ofFn (Fin.cons x₀ xs))
⊢ Function.Injective (Fin.cons x₀ xs)

Next tactic:
rw [Fin.cons_injective_iff]
theorem nodup_ofFn {α n} {f : Fin n → α} : Nodup (ofFn f) ↔ Function.Injective f := by
  refine' ⟨_, nodup_ofFn_ofInjective⟩
  refine' Fin.consInduction _ (fun x₀ xs ih => _) f
  · intro _
    exact Function.injective_of_subsingleton _
  · intro h
    rw [Fin.cons_injective_iff]
    

Proof state:
case refine'_2
α✝ : Type u
α : Type u_1
n : ℕ
f : Fin n → α
n✝ : ℕ
x₀ : α
xs : Fin n✝ → α
ih : Nodup (ofFn xs) → Function.Injective xs
h : Nodup (ofFn (Fin.cons x₀ xs))
⊢ x₀ ∉ Set.range xs ∧ Function.Injective xs

Next tactic:
simp_rw [ofFn_succ, Fin.cons_succ, nodup_cons, Fin.cons_zero, mem_ofFn] at h
theorem nodup_ofFn {α n} {f : Fin n → α} : Nodup (ofFn f) ↔ Function.Injective f := by
  refine' ⟨_, nodup_ofFn_ofInjective⟩
  refine' Fin.consInduction _ (fun x₀ xs ih => _) f
  · intro _
    exact Function.injective_of_subsingleton _
  · intro h
    rw [Fin.cons_injective_iff]
    simp_rw [ofFn_succ, Fin.cons_succ, nodup_cons, Fin.cons_zero, mem_ofFn] at h
    

Proof state:
case refine'_2
α✝ : Type u
α : Type u_1
n : ℕ
f : Fin n → α
n✝ : ℕ
x₀ : α
xs : Fin n✝ → α
ih : Nodup (ofFn xs) → Function.Injective xs
h : (x₀ ∉ Set.range fun i => xs i) ∧ Nodup (ofFn fun i => xs i)
⊢ x₀ ∉ Set.range xs ∧ Function.Injective xs

Next tactic:
exact h.imp_right ih
theorem Equiv.Perm.map_finRange_perm {n : ℕ} (σ : Equiv.Perm (Fin n)) :
    map σ (finRange n) ~ finRange n := by
  

Proof state:
n : ℕ
σ : Perm (Fin n)
⊢ map (⇑σ) (finRange n) ~ finRange n

Next tactic:
rw [perm_ext_iff_of_nodup ((nodup_finRange n).map σ.injective) <| nodup_finRange n]
theorem Equiv.Perm.map_finRange_perm {n : ℕ} (σ : Equiv.Perm (Fin n)) :
    map σ (finRange n) ~ finRange n := by
  rw [perm_ext_iff_of_nodup ((nodup_finRange n).map σ.injective) <| nodup_finRange n]
  

Proof state:
n : ℕ
σ : Perm (Fin n)
⊢ ∀ (a : Fin n), a ∈ map (⇑σ) (finRange n) ↔ a ∈ finRange n

Next tactic:
simpa [mem_map, mem_finRange, true_and_iff, iff_true_iff] using σ.surjective
/-- The list obtained from a permutation of a tuple `f` is permutation equivalent to
the list obtained from `f`. -/
theorem Equiv.Perm.ofFn_comp_perm {n : ℕ} {α : Type u} (σ : Equiv.Perm (Fin n)) (f : Fin n → α) :
    ofFn (f ∘ σ) ~ ofFn f := by
  

Proof state:
n : ℕ
α : Type u
σ : Perm (Fin n)
f : Fin n → α
⊢ ofFn (f ∘ ⇑σ) ~ ofFn f

Next tactic:
rw [ofFn_eq_map, ofFn_eq_map, ← map_map]
/-- The list obtained from a permutation of a tuple `f` is permutation equivalent to
the list obtained from `f`. -/
theorem Equiv.Perm.ofFn_comp_perm {n : ℕ} {α : Type u} (σ : Equiv.Perm (Fin n)) (f : Fin n → α) :
    ofFn (f ∘ σ) ~ ofFn f := by
  rw [ofFn_eq_map, ofFn_eq_map, ← map_map]
  

Proof state:
n : ℕ
α : Type u
σ : Perm (Fin n)
f : Fin n → α
⊢ map f (map (⇑σ) (finRange n)) ~ map f (finRange n)

Next tactic:
exact σ.map_finRange_perm.map f
/-- Only finitely many maximal ideals of `R` divide a given nonzero ideal. -/
theorem Ideal.finite_factors {I : Ideal R} (hI : I ≠ 0) :
    {v : HeightOneSpectrum R | v.asIdeal ∣ I}.Finite := by
  

Proof state:
R : Type u_1
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
K : Type u_2
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
I : Ideal R
hI : I ≠ 0
⊢ Set.Finite {v | v.asIdeal ∣ I}

Next tactic:
rw [← Set.finite_coe_iff, Set.coe_setOf]
/-- Only finitely many maximal ideals of `R` divide a given nonzero ideal. -/
theorem Ideal.finite_factors {I : Ideal R} (hI : I ≠ 0) :
    {v : HeightOneSpectrum R | v.asIdeal ∣ I}.Finite := by
  rw [← Set.finite_coe_iff, Set.coe_setOf]
  

Proof state:
R : Type u_1
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
K : Type u_2
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
I : Ideal R
hI : I ≠ 0
⊢ Finite { x // x.asIdeal ∣ I }

Next tactic:
haveI h_fin := fintypeSubtypeDvd I hI
/-- Only finitely many maximal ideals of `R` divide a given nonzero ideal. -/
theorem Ideal.finite_factors {I : Ideal R} (hI : I ≠ 0) :
    {v : HeightOneSpectrum R | v.asIdeal ∣ I}.Finite := by
  rw [← Set.finite_coe_iff, Set.coe_setOf]
  haveI h_fin := fintypeSubtypeDvd I hI
  

Proof state:
R : Type u_1
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
K : Type u_2
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
I : Ideal R
hI : I ≠ 0
h_fin : Fintype { x // x ∣ I }
⊢ Finite { x // x.asIdeal ∣ I }

Next tactic:
refine'
    Finite.of_injective (fun v => (⟨(v : HeightOneSpectrum R).asIdeal, v.2⟩ : { x // x ∣ I })) _
/-- Only finitely many maximal ideals of `R` divide a given nonzero ideal. -/
theorem Ideal.finite_factors {I : Ideal R} (hI : I ≠ 0) :
    {v : HeightOneSpectrum R | v.asIdeal ∣ I}.Finite := by
  rw [← Set.finite_coe_iff, Set.coe_setOf]
  haveI h_fin := fintypeSubtypeDvd I hI
  refine'
    Finite.of_injective (fun v => (⟨(v : HeightOneSpectrum R).asIdeal, v.2⟩ : { x // x ∣ I })) _
  

Proof state:
R : Type u_1
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
K : Type u_2
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
I : Ideal R
hI : I ≠ 0
h_fin : Fintype { x // x ∣ I }
⊢ Injective fun v => { val := (↑v).asIdeal, property := (_ : (↑v).asIdeal ∣ I) }

Next tactic:
intro v w hvw
/-- Only finitely many maximal ideals of `R` divide a given nonzero ideal. -/
theorem Ideal.finite_factors {I : Ideal R} (hI : I ≠ 0) :
    {v : HeightOneSpectrum R | v.asIdeal ∣ I}.Finite := by
  rw [← Set.finite_coe_iff, Set.coe_setOf]
  haveI h_fin := fintypeSubtypeDvd I hI
  refine'
    Finite.of_injective (fun v => (⟨(v : HeightOneSpectrum R).asIdeal, v.2⟩ : { x // x ∣ I })) _
  intro v w hvw
  

Proof state:
R : Type u_1
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
K : Type u_2
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
I : Ideal R
hI : I ≠ 0
h_fin : Fintype { x // x ∣ I }
v w : { x // x.asIdeal ∣ I }
hvw :
  (fun v => { val := (↑v).asIdeal, property := (_ : (↑v).asIdeal ∣ I) }) v =
    (fun v => { val := (↑v).asIdeal, property := (_ : (↑v).asIdeal ∣ I) }) w
⊢ v = w

Next tactic:
simp? at hvw says simp only [Subtype.mk.injEq] at hvw
/-- Only finitely many maximal ideals of `R` divide a given nonzero ideal. -/
theorem Ideal.finite_factors {I : Ideal R} (hI : I ≠ 0) :
    {v : HeightOneSpectrum R | v.asIdeal ∣ I}.Finite := by
  rw [← Set.finite_coe_iff, Set.coe_setOf]
  haveI h_fin := fintypeSubtypeDvd I hI
  refine'
    Finite.of_injective (fun v => (⟨(v : HeightOneSpectrum R).asIdeal, v.2⟩ : { x // x ∣ I })) _
  intro v w hvw
  simp? at hvw says 

Proof state:
R : Type u_1
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
K : Type u_2
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
I : Ideal R
hI : I ≠ 0
h_fin : Fintype { x // x ∣ I }
v w : { x // x.asIdeal ∣ I }
hvw :
  (fun v => { val := (↑v).asIdeal, property := (_ : (↑v).asIdeal ∣ I) }) v =
    (fun v => { val := (↑v).asIdeal, property := (_ : (↑v).asIdeal ∣ I) }) w
⊢ v = w

Next tactic:
simp only [Subtype.mk.injEq] at hvw
/-- Only finitely many maximal ideals of `R` divide a given nonzero ideal. -/
theorem Ideal.finite_factors {I : Ideal R} (hI : I ≠ 0) :
    {v : HeightOneSpectrum R | v.asIdeal ∣ I}.Finite := by
  rw [← Set.finite_coe_iff, Set.coe_setOf]
  haveI h_fin := fintypeSubtypeDvd I hI
  refine'
    Finite.of_injective (fun v => (⟨(v : HeightOneSpectrum R).asIdeal, v.2⟩ : { x // x ∣ I })) _
  intro v w hvw
  simp? at hvw says simp only [Subtype.mk.injEq] at hvw
  

Proof state:
R : Type u_1
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
K : Type u_2
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
I : Ideal R
hI : I ≠ 0
h_fin : Fintype { x // x ∣ I }
v w : { x // x.asIdeal ∣ I }
hvw : (↑v).asIdeal = (↑w).asIdeal
⊢ v = w

Next tactic:
exact Subtype.coe_injective ((HeightOneSpectrum.ext_iff (R := R) ↑v ↑w).mpr hvw)
/-- For every nonzero ideal `I` of `v`, there are finitely many maximal ideals `v` such that the
  multiplicity of `v` in the factorization of `I`, denoted `val_v(I)`, is nonzero. -/
theorem Associates.finite_factors {I : Ideal R} (hI : I ≠ 0) :
    ∀ᶠ v : HeightOneSpectrum R in Filter.cofinite,
      ((Associates.mk v.asIdeal).count (Associates.mk I).factors : ℤ) = 0 := by
  

Proof state:
R : Type u_1
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
K : Type u_2
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
I : Ideal R
hI : I ≠ 0
⊢ ∀ᶠ (v : HeightOneSpectrum R) in Filter.cofinite, ↑(count (Associates.mk v.asIdeal) (factors (Associates.mk I))) = 0

Next tactic:
have h_supp : {v : HeightOneSpectrum R | ¬((Associates.mk v.asIdeal).count
      (Associates.mk I).factors : ℤ) = 0} = {v : HeightOneSpectrum R | v.asIdeal ∣ I} := by
    ext v
    simp_rw [Int.coe_nat_eq_zero]
    exact Associates.count_ne_zero_iff_dvd hI v.irreducible
/-- For every nonzero ideal `I` of `v`, there are finitely many maximal ideals `v` such that the
  multiplicity of `v` in the factorization of `I`, denoted `val_v(I)`, is nonzero. -/
theorem Associates.finite_factors {I : Ideal R} (hI : I ≠ 0) :
    ∀ᶠ v : HeightOneSpectrum R in Filter.cofinite,
      ((Associates.mk v.asIdeal).count (Associates.mk I).factors : ℤ) = 0 := by
  have h_supp : {v : HeightOneSpectrum R | ¬((Associates.mk v.asIdeal).count
      (Associates.mk I).factors : ℤ) = 0} = {v : HeightOneSpectrum R | v.asIdeal ∣ I} := by
    

Proof state:
R : Type u_1
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
K : Type u_2
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
I : Ideal R
hI : I ≠ 0
⊢ {v | ¬↑(count (Associates.mk v.asIdeal) (factors (Associates.mk I))) = 0} = {v | v.asIdeal ∣ I}

Next tactic:
ext v
/-- For every nonzero ideal `I` of `v`, there are finitely many maximal ideals `v` such that the
  multiplicity of `v` in the factorization of `I`, denoted `val_v(I)`, is nonzero. -/
theorem Associates.finite_factors {I : Ideal R} (hI : I ≠ 0) :
    ∀ᶠ v : HeightOneSpectrum R in Filter.cofinite,
      ((Associates.mk v.asIdeal).count (Associates.mk I).factors : ℤ) = 0 := by
  have h_supp : {v : HeightOneSpectrum R | ¬((Associates.mk v.asIdeal).count
      (Associates.mk I).factors : ℤ) = 0} = {v : HeightOneSpectrum R | v.asIdeal ∣ I} := by
    ext v
    

Proof state:
case h
R : Type u_1
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
K : Type u_2
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
I : Ideal R
hI : I ≠ 0
v : HeightOneSpectrum R
⊢ v ∈ {v | ¬↑(count (Associates.mk v.asIdeal) (factors (Associates.mk I))) = 0} ↔ v ∈ {v | v.asIdeal ∣ I}

Next tactic:
simp_rw [Int.coe_nat_eq_zero]
/-- For every nonzero ideal `I` of `v`, there are finitely many maximal ideals `v` such that the
  multiplicity of `v` in the factorization of `I`, denoted `val_v(I)`, is nonzero. -/
theorem Associates.finite_factors {I : Ideal R} (hI : I ≠ 0) :
    ∀ᶠ v : HeightOneSpectrum R in Filter.cofinite,
      ((Associates.mk v.asIdeal).count (Associates.mk I).factors : ℤ) = 0 := by
  have h_supp : {v : HeightOneSpectrum R | ¬((Associates.mk v.asIdeal).count
      (Associates.mk I).factors : ℤ) = 0} = {v : HeightOneSpectrum R | v.asIdeal ∣ I} := by
    ext v
    simp_rw [Int.coe_nat_eq_zero]
    

Proof state:
case h
R : Type u_1
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
K : Type u_2
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v✝ : HeightOneSpectrum R
I : Ideal R
hI : I ≠ 0
v : HeightOneSpectrum R
⊢ v ∈ {v | ¬count (Associates.mk v.asIdeal) (factors (Associates.mk I)) = 0} ↔ v ∈ {v | v.asIdeal ∣ I}

Next tactic:
exact Associates.count_ne_zero_iff_dvd hI v.irreducible
/-- For every nonzero ideal `I` of `v`, there are finitely many maximal ideals `v` such that the
  multiplicity of `v` in the factorization of `I`, denoted `val_v(I)`, is nonzero. -/
theorem Associates.finite_factors {I : Ideal R} (hI : I ≠ 0) :
    ∀ᶠ v : HeightOneSpectrum R in Filter.cofinite,
      ((Associates.mk v.asIdeal).count (Associates.mk I).factors : ℤ) = 0 := by
  have h_supp : {v : HeightOneSpectrum R | ¬((Associates.mk v.asIdeal).count
      (Associates.mk I).factors : ℤ) = 0} = {v : HeightOneSpectrum R | v.asIdeal ∣ I} := by
    ext v
    simp_rw [Int.coe_nat_eq_zero]
    exact Associates.count_ne_zero_iff_dvd hI v.irreducible
  

Proof state:
R : Type u_1
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
K : Type u_2
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
I : Ideal R
hI : I ≠ 0
h_supp : {v | ¬↑(count (Associates.mk v.asIdeal) (factors (Associates.mk I))) = 0} = {v | v.asIdeal ∣ I}
⊢ ∀ᶠ (v : HeightOneSpectrum R) in Filter.cofinite, ↑(count (Associates.mk v.asIdeal) (factors (Associates.mk I))) = 0

Next tactic:
rw [Filter.eventually_cofinite, h_supp]
/-- For every nonzero ideal `I` of `v`, there are finitely many maximal ideals `v` such that the
  multiplicity of `v` in the factorization of `I`, denoted `val_v(I)`, is nonzero. -/
theorem Associates.finite_factors {I : Ideal R} (hI : I ≠ 0) :
    ∀ᶠ v : HeightOneSpectrum R in Filter.cofinite,
      ((Associates.mk v.asIdeal).count (Associates.mk I).factors : ℤ) = 0 := by
  have h_supp : {v : HeightOneSpectrum R | ¬((Associates.mk v.asIdeal).count
      (Associates.mk I).factors : ℤ) = 0} = {v : HeightOneSpectrum R | v.asIdeal ∣ I} := by
    ext v
    simp_rw [Int.coe_nat_eq_zero]
    exact Associates.count_ne_zero_iff_dvd hI v.irreducible
  rw [Filter.eventually_cofinite, h_supp]
  

Proof state:
R : Type u_1
inst✝⁵ : CommRing R
inst✝⁴ : IsDomain R
inst✝³ : IsDedekindDomain R
K : Type u_2
inst✝² : Field K
inst✝¹ : Algebra R K
inst✝ : IsFractionRing R K
v : HeightOneSpectrum R
I : Ideal R
hI : I ≠ 0
h_supp : {v | ¬↑(count (Associates.mk v.asIdeal) (factors (Associates.mk I))) = 0} = {v | v.asIdeal ∣ I}
⊢ Set.Finite {v | v.asIdeal ∣ I}

Next tactic:
exact Ideal.finite_factors hI