l3lab/ntp-mathlib huggingface dataset:
/-- If `a ∈ P^i \ P^(i+1)` and `c ∈ P^i`, then `a * d + e = c` for `e ∈ P^(i+1)`.
`Ideal.mul_add_mem_pow_succ_unique` shows the choice of `d` is unique, up to `P`.
Inspired by [Neukirch], proposition 6.1 -/
theorem Ideal.exists_mul_add_mem_pow_succ [IsDedekindDomain S] {i : ℕ} (a c : S) (a_mem : a ∈ P ^ i)
    (a_not_mem : a ∉ P ^ (i + 1)) (c_mem : c ∈ P ^ i) :
    ∃ d : S, ∃ e ∈ P ^ (i + 1), a * d + e = c := by
  suffices eq_b : P ^ i = Ideal.span {a} ⊔ P ^ (i + 1)
  · rw [eq_b] at c_mem
    simp only [mul_comm a]
    

Proof state:
S : Type u_1
inst✝² : CommRing S
inst✝¹ : IsDomain S
P : Ideal S
P_prime : IsPrime P
hP : P ≠ ⊥
inst✝ : IsDedekindDomain S
i : ℕ
a c : S
a_mem : a ∈ P ^ i
a_not_mem : a ∉ P ^ (i + 1)
c_mem : c ∈ span {a} ⊔ P ^ (i + 1)
eq_b : P ^ i = span {a} ⊔ P ^ (i + 1)
⊢ ∃ d, ∃ e ∈ P ^ (i + 1), d * a + e = c

Next tactic:
exact Ideal.mem_span_singleton_sup.mp c_mem
/-- If `a ∈ P^i \ P^(i+1)` and `c ∈ P^i`, then `a * d + e = c` for `e ∈ P^(i+1)`.
`Ideal.mul_add_mem_pow_succ_unique` shows the choice of `d` is unique, up to `P`.
Inspired by [Neukirch], proposition 6.1 -/
theorem Ideal.exists_mul_add_mem_pow_succ [IsDedekindDomain S] {i : ℕ} (a c : S) (a_mem : a ∈ P ^ i)
    (a_not_mem : a ∉ P ^ (i + 1)) (c_mem : c ∈ P ^ i) :
    ∃ d : S, ∃ e ∈ P ^ (i + 1), a * d + e = c := by
  suffices eq_b : P ^ i = Ideal.span {a} ⊔ P ^ (i + 1)
  · rw [eq_b] at c_mem
    simp only [mul_comm a]
    exact Ideal.mem_span_singleton_sup.mp c_mem
  

Proof state:
case eq_b
S : Type u_1
inst✝² : CommRing S
inst✝¹ : IsDomain S
P : Ideal S
P_prime : IsPrime P
hP : P ≠ ⊥
inst✝ : IsDedekindDomain S
i : ℕ
a c : S
a_mem : a ∈ P ^ i
a_not_mem : a ∉ P ^ (i + 1)
c_mem : c ∈ P ^ i
⊢ P ^ i = span {a} ⊔ P ^ (i + 1)

Next tactic:
refine (Ideal.eq_prime_pow_of_succ_lt_of_le hP (lt_of_le_of_ne le_sup_right ?_)
    (sup_le (Ideal.span_le.mpr (Set.singleton_subset_iff.mpr a_mem))
      (Ideal.pow_succ_lt_pow hP i).le)).symm
/-- If `a ∈ P^i \ P^(i+1)` and `c ∈ P^i`, then `a * d + e = c` for `e ∈ P^(i+1)`.
`Ideal.mul_add_mem_pow_succ_unique` shows the choice of `d` is unique, up to `P`.
Inspired by [Neukirch], proposition 6.1 -/
theorem Ideal.exists_mul_add_mem_pow_succ [IsDedekindDomain S] {i : ℕ} (a c : S) (a_mem : a ∈ P ^ i)
    (a_not_mem : a ∉ P ^ (i + 1)) (c_mem : c ∈ P ^ i) :
    ∃ d : S, ∃ e ∈ P ^ (i + 1), a * d + e = c := by
  suffices eq_b : P ^ i = Ideal.span {a} ⊔ P ^ (i + 1)
  · rw [eq_b] at c_mem
    simp only [mul_comm a]
    exact Ideal.mem_span_singleton_sup.mp c_mem
  refine (Ideal.eq_prime_pow_of_succ_lt_of_le hP (lt_of_le_of_ne le_sup_right ?_)
    (sup_le (Ideal.span_le.mpr (Set.singleton_subset_iff.mpr a_mem))
      (Ideal.pow_succ_lt_pow hP i).le)).symm
  

Proof state:
case eq_b
S : Type u_1
inst✝² : CommRing S
inst✝¹ : IsDomain S
P : Ideal S
P_prime : IsPrime P
hP : P ≠ ⊥
inst✝ : IsDedekindDomain S
i : ℕ
a c : S
a_mem : a ∈ P ^ i
a_not_mem : a ∉ P ^ (i + 1)
c_mem : c ∈ P ^ i
⊢ P ^ (i + 1) ≠ span {a} ⊔ P ^ (i + 1)

Next tactic:
contrapose! a_not_mem with this
/-- If `a ∈ P^i \ P^(i+1)` and `c ∈ P^i`, then `a * d + e = c` for `e ∈ P^(i+1)`.
`Ideal.mul_add_mem_pow_succ_unique` shows the choice of `d` is unique, up to `P`.
Inspired by [Neukirch], proposition 6.1 -/
theorem Ideal.exists_mul_add_mem_pow_succ [IsDedekindDomain S] {i : ℕ} (a c : S) (a_mem : a ∈ P ^ i)
    (a_not_mem : a ∉ P ^ (i + 1)) (c_mem : c ∈ P ^ i) :
    ∃ d : S, ∃ e ∈ P ^ (i + 1), a * d + e = c := by
  suffices eq_b : P ^ i = Ideal.span {a} ⊔ P ^ (i + 1)
  · rw [eq_b] at c_mem
    simp only [mul_comm a]
    exact Ideal.mem_span_singleton_sup.mp c_mem
  refine (Ideal.eq_prime_pow_of_succ_lt_of_le hP (lt_of_le_of_ne le_sup_right ?_)
    (sup_le (Ideal.span_le.mpr (Set.singleton_subset_iff.mpr a_mem))
      (Ideal.pow_succ_lt_pow hP i).le)).symm
  contrapose! a_not_mem with this
  

Proof state:
case eq_b
S : Type u_1
inst✝² : CommRing S
inst✝¹ : IsDomain S
P : Ideal S
P_prime : IsPrime P
hP : P ≠ ⊥
inst✝ : IsDedekindDomain S
i : ℕ
a c : S
a_mem : a ∈ P ^ i
c_mem : c ∈ P ^ i
this : P ^ (i + 1) = span {a} ⊔ P ^ (i + 1)
⊢ a ∈ P ^ (i + 1)

Next tactic:
rw [this]
/-- If `a ∈ P^i \ P^(i+1)` and `c ∈ P^i`, then `a * d + e = c` for `e ∈ P^(i+1)`.
`Ideal.mul_add_mem_pow_succ_unique` shows the choice of `d` is unique, up to `P`.
Inspired by [Neukirch], proposition 6.1 -/
theorem Ideal.exists_mul_add_mem_pow_succ [IsDedekindDomain S] {i : ℕ} (a c : S) (a_mem : a ∈ P ^ i)
    (a_not_mem : a ∉ P ^ (i + 1)) (c_mem : c ∈ P ^ i) :
    ∃ d : S, ∃ e ∈ P ^ (i + 1), a * d + e = c := by
  suffices eq_b : P ^ i = Ideal.span {a} ⊔ P ^ (i + 1)
  · rw [eq_b] at c_mem
    simp only [mul_comm a]
    exact Ideal.mem_span_singleton_sup.mp c_mem
  refine (Ideal.eq_prime_pow_of_succ_lt_of_le hP (lt_of_le_of_ne le_sup_right ?_)
    (sup_le (Ideal.span_le.mpr (Set.singleton_subset_iff.mpr a_mem))
      (Ideal.pow_succ_lt_pow hP i).le)).symm
  contrapose! a_not_mem with this
  rw [this]
  

Proof state:
case eq_b
S : Type u_1
inst✝² : CommRing S
inst✝¹ : IsDomain S
P : Ideal S
P_prime : IsPrime P
hP : P ≠ ⊥
inst✝ : IsDedekindDomain S
i : ℕ
a c : S
a_mem : a ∈ P ^ i
c_mem : c ∈ P ^ i
this : P ^ (i + 1) = span {a} ⊔ P ^ (i + 1)
⊢ a ∈ span {a} ⊔ P ^ (i + 1)

Next tactic:
exact mem_sup.mpr ⟨a, mem_span_singleton_self a, 0, by simp, by simp⟩
/-- If `a ∈ P^i \ P^(i+1)` and `c ∈ P^i`, then `a * d + e = c` for `e ∈ P^(i+1)`.
`Ideal.mul_add_mem_pow_succ_unique` shows the choice of `d` is unique, up to `P`.
Inspired by [Neukirch], proposition 6.1 -/
theorem Ideal.exists_mul_add_mem_pow_succ [IsDedekindDomain S] {i : ℕ} (a c : S) (a_mem : a ∈ P ^ i)
    (a_not_mem : a ∉ P ^ (i + 1)) (c_mem : c ∈ P ^ i) :
    ∃ d : S, ∃ e ∈ P ^ (i + 1), a * d + e = c := by
  suffices eq_b : P ^ i = Ideal.span {a} ⊔ P ^ (i + 1)
  · rw [eq_b] at c_mem
    simp only [mul_comm a]
    exact Ideal.mem_span_singleton_sup.mp c_mem
  refine (Ideal.eq_prime_pow_of_succ_lt_of_le hP (lt_of_le_of_ne le_sup_right ?_)
    (sup_le (Ideal.span_le.mpr (Set.singleton_subset_iff.mpr a_mem))
      (Ideal.pow_succ_lt_pow hP i).le)).symm
  contrapose! a_not_mem with this
  rw [this]
  exact mem_sup.mpr ⟨a, mem_span_singleton_self a, 0, by 

Proof state:
S : Type u_1
inst✝² : CommRing S
inst✝¹ : IsDomain S
P : Ideal S
P_prime : IsPrime P
hP : P ≠ ⊥
inst✝ : IsDedekindDomain S
i : ℕ
a c : S
a_mem : a ∈ P ^ i
c_mem : c ∈ P ^ i
this : P ^ (i + 1) = span {a} ⊔ P ^ (i + 1)
⊢ 0 ∈ P ^ (i + 1)

Next tactic:
simp
/-- If `a ∈ P^i \ P^(i+1)` and `c ∈ P^i`, then `a * d + e = c` for `e ∈ P^(i+1)`.
`Ideal.mul_add_mem_pow_succ_unique` shows the choice of `d` is unique, up to `P`.
Inspired by [Neukirch], proposition 6.1 -/
theorem Ideal.exists_mul_add_mem_pow_succ [IsDedekindDomain S] {i : ℕ} (a c : S) (a_mem : a ∈ P ^ i)
    (a_not_mem : a ∉ P ^ (i + 1)) (c_mem : c ∈ P ^ i) :
    ∃ d : S, ∃ e ∈ P ^ (i + 1), a * d + e = c := by
  suffices eq_b : P ^ i = Ideal.span {a} ⊔ P ^ (i + 1)
  · rw [eq_b] at c_mem
    simp only [mul_comm a]
    exact Ideal.mem_span_singleton_sup.mp c_mem
  refine (Ideal.eq_prime_pow_of_succ_lt_of_le hP (lt_of_le_of_ne le_sup_right ?_)
    (sup_le (Ideal.span_le.mpr (Set.singleton_subset_iff.mpr a_mem))
      (Ideal.pow_succ_lt_pow hP i).le)).symm
  contrapose! a_not_mem with this
  rw [this]
  exact mem_sup.mpr ⟨a, mem_span_singleton_self a, 0, by simp, by 

Proof state:
S : Type u_1
inst✝² : CommRing S
inst✝¹ : IsDomain S
P : Ideal S
P_prime : IsPrime P
hP : P ≠ ⊥
inst✝ : IsDedekindDomain S
i : ℕ
a c : S
a_mem : a ∈ P ^ i
c_mem : c ∈ P ^ i
this : P ^ (i + 1) = span {a} ⊔ P ^ (i + 1)
⊢ a + 0 = a

Next tactic:
simp
theorem Ideal.mem_prime_of_mul_mem_pow [IsDedekindDomain S] {P : Ideal S} [P_prime : P.IsPrime]
    (hP : P ≠ ⊥) {i : ℕ} {a b : S} (a_not_mem : a ∉ P ^ (i + 1)) (ab_mem : a * b ∈ P ^ (i + 1)) :
    b ∈ P := by
  

Proof state:
S : Type u_1
inst✝² : CommRing S
inst✝¹ : IsDomain S
P✝ : Ideal S
P_prime✝ : IsPrime P✝
hP✝ : P✝ ≠ ⊥
inst✝ : IsDedekindDomain S
P : Ideal S
P_prime : IsPrime P
hP : P ≠ ⊥
i : ℕ
a b : S
a_not_mem : a ∉ P ^ (i + 1)
ab_mem : a * b ∈ P ^ (i + 1)
⊢ b ∈ P

Next tactic:
simp only [← Ideal.span_singleton_le_iff_mem, ← Ideal.dvd_iff_le, pow_succ, ←
    Ideal.span_singleton_mul_span_singleton] at a_not_mem ab_mem ⊢
theorem Ideal.mem_prime_of_mul_mem_pow [IsDedekindDomain S] {P : Ideal S} [P_prime : P.IsPrime]
    (hP : P ≠ ⊥) {i : ℕ} {a b : S} (a_not_mem : a ∉ P ^ (i + 1)) (ab_mem : a * b ∈ P ^ (i + 1)) :
    b ∈ P := by
  simp only [← Ideal.span_singleton_le_iff_mem, ← Ideal.dvd_iff_le, pow_succ, ←
    Ideal.span_singleton_mul_span_singleton] at a_not_mem ab_mem ⊢
  

Proof state:
S : Type u_1
inst✝² : CommRing S
inst✝¹ : IsDomain S
P✝ : Ideal S
P_prime✝ : IsPrime P✝
hP✝ : P✝ ≠ ⊥
inst✝ : IsDedekindDomain S
P : Ideal S
P_prime : IsPrime P
hP : P ≠ ⊥
i : ℕ
a b : S
a_not_mem : ¬P * P ^ i ∣ span {a}
ab_mem : P * P ^ i ∣ span {a} * span {b}
⊢ P ∣ span {b}

Next tactic:
exact (prime_pow_succ_dvd_mul (Ideal.prime_of_isPrime hP P_prime) ab_mem).resolve_left a_not_mem
/-- The choice of `d` in `Ideal.exists_mul_add_mem_pow_succ` is unique, up to `P`.
Inspired by [Neukirch], proposition 6.1 -/
theorem Ideal.mul_add_mem_pow_succ_unique [IsDedekindDomain S] {i : ℕ} (a d d' e e' : S)
    (a_not_mem : a ∉ P ^ (i + 1)) (e_mem : e ∈ P ^ (i + 1)) (e'_mem : e' ∈ P ^ (i + 1))
    (h : a * d + e - (a * d' + e') ∈ P ^ (i + 1)) : d - d' ∈ P := by
  

Proof state:
S : Type u_1
inst✝² : CommRing S
inst✝¹ : IsDomain S
P : Ideal S
P_prime : IsPrime P
hP : P ≠ ⊥
inst✝ : IsDedekindDomain S
i : ℕ
a d d' e e' : S
a_not_mem : a ∉ P ^ (i + 1)
e_mem : e ∈ P ^ (i + 1)
e'_mem : e' ∈ P ^ (i + 1)
h : a * d + e - (a * d' + e') ∈ P ^ (i + 1)
⊢ d - d' ∈ P

Next tactic:
have h' : a * (d - d') ∈ P ^ (i + 1) := by
    convert Ideal.add_mem _ h (Ideal.sub_mem _ e'_mem e_mem) using 1
    ring
/-- The choice of `d` in `Ideal.exists_mul_add_mem_pow_succ` is unique, up to `P`.
Inspired by [Neukirch], proposition 6.1 -/
theorem Ideal.mul_add_mem_pow_succ_unique [IsDedekindDomain S] {i : ℕ} (a d d' e e' : S)
    (a_not_mem : a ∉ P ^ (i + 1)) (e_mem : e ∈ P ^ (i + 1)) (e'_mem : e' ∈ P ^ (i + 1))
    (h : a * d + e - (a * d' + e') ∈ P ^ (i + 1)) : d - d' ∈ P := by
  have h' : a * (d - d') ∈ P ^ (i + 1) := by
    

Proof state:
S : Type u_1
inst✝² : CommRing S
inst✝¹ : IsDomain S
P : Ideal S
P_prime : IsPrime P
hP : P ≠ ⊥
inst✝ : IsDedekindDomain S
i : ℕ
a d d' e e' : S
a_not_mem : a ∉ P ^ (i + 1)
e_mem : e ∈ P ^ (i + 1)
e'_mem : e' ∈ P ^ (i + 1)
h : a * d + e - (a * d' + e') ∈ P ^ (i + 1)
⊢ a * (d - d') ∈ P ^ (i + 1)

Next tactic:
convert Ideal.add_mem _ h (Ideal.sub_mem _ e'_mem e_mem) using 1
/-- The choice of `d` in `Ideal.exists_mul_add_mem_pow_succ` is unique, up to `P`.
Inspired by [Neukirch], proposition 6.1 -/
theorem Ideal.mul_add_mem_pow_succ_unique [IsDedekindDomain S] {i : ℕ} (a d d' e e' : S)
    (a_not_mem : a ∉ P ^ (i + 1)) (e_mem : e ∈ P ^ (i + 1)) (e'_mem : e' ∈ P ^ (i + 1))
    (h : a * d + e - (a * d' + e') ∈ P ^ (i + 1)) : d - d' ∈ P := by
  have h' : a * (d - d') ∈ P ^ (i + 1) := by
    convert Ideal.add_mem _ h (Ideal.sub_mem _ e'_mem e_mem) using 1
    

Proof state:
case h.e'_4
S : Type u_1
inst✝² : CommRing S
inst✝¹ : IsDomain S
P : Ideal S
P_prime : IsPrime P
hP : P ≠ ⊥
inst✝ : IsDedekindDomain S
i : ℕ
a d d' e e' : S
a_not_mem : a ∉ P ^ (i + 1)
e_mem : e ∈ P ^ (i + 1)
e'_mem : e' ∈ P ^ (i + 1)
h : a * d + e - (a * d' + e') ∈ P ^ (i + 1)
⊢ a * (d - d') = a * d + e - (a * d' + e') + (e' - e)

Next tactic:
ring
/-- The choice of `d` in `Ideal.exists_mul_add_mem_pow_succ` is unique, up to `P`.
Inspired by [Neukirch], proposition 6.1 -/
theorem Ideal.mul_add_mem_pow_succ_unique [IsDedekindDomain S] {i : ℕ} (a d d' e e' : S)
    (a_not_mem : a ∉ P ^ (i + 1)) (e_mem : e ∈ P ^ (i + 1)) (e'_mem : e' ∈ P ^ (i + 1))
    (h : a * d + e - (a * d' + e') ∈ P ^ (i + 1)) : d - d' ∈ P := by
  have h' : a * (d - d') ∈ P ^ (i + 1) := by
    convert Ideal.add_mem _ h (Ideal.sub_mem _ e'_mem e_mem) using 1
    ring
  

Proof state:
S : Type u_1
inst✝² : CommRing S
inst✝¹ : IsDomain S
P : Ideal S
P_prime : IsPrime P
hP : P ≠ ⊥
inst✝ : IsDedekindDomain S
i : ℕ
a d d' e e' : S
a_not_mem : a ∉ P ^ (i + 1)
e_mem : e ∈ P ^ (i + 1)
e'_mem : e' ∈ P ^ (i + 1)
h : a * d + e - (a * d' + e') ∈ P ^ (i + 1)
h' : a * (d - d') ∈ P ^ (i + 1)
⊢ d - d' ∈ P

Next tactic:
exact Ideal.mem_prime_of_mul_mem_pow hP a_not_mem h'
/-- Multiplicity of the ideal norm, for powers of prime ideals. -/
theorem cardQuot_pow_of_prime [IsDedekindDomain S] [Module.Finite ℤ S] [Module.Free ℤ S] {i : ℕ} :
    cardQuot (P ^ i) = cardQuot P ^ i := by
  

Proof state:
S : Type u_1
inst✝⁴ : CommRing S
inst✝³ : IsDomain S
P : Ideal S
P_prime : Ideal.IsPrime P
hP : P ≠ ⊥
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Finite ℤ S
inst✝ : Module.Free ℤ S
i : ℕ
⊢ cardQuot (P ^ i) = cardQuot P ^ i

Next tactic:
let _ := Module.Free.chooseBasis ℤ S
/-- Multiplicity of the ideal norm, for powers of prime ideals. -/
theorem cardQuot_pow_of_prime [IsDedekindDomain S] [Module.Finite ℤ S] [Module.Free ℤ S] {i : ℕ} :
    cardQuot (P ^ i) = cardQuot P ^ i := by
  let _ := Module.Free.chooseBasis ℤ S
  

Proof state:
S : Type u_1
inst✝⁴ : CommRing S
inst✝³ : IsDomain S
P : Ideal S
P_prime : Ideal.IsPrime P
hP : P ≠ ⊥
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Finite ℤ S
inst✝ : Module.Free ℤ S
i : ℕ
x✝ : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
⊢ cardQuot (P ^ i) = cardQuot P ^ i

Next tactic:
classical
  induction' i with i ih
  · simp
  letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i.succ) (pow_ne_zero _ hP)
  letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i) (pow_ne_zero _ hP)
  letI := Ideal.fintypeQuotientOfFreeOfNeBot P hP
  have : P ^ (i + 1) < P ^ i := Ideal.pow_succ_lt_pow hP i
  suffices hquot : map (P ^ i.succ).mkQ (P ^ i) ≃ S ⧸ P
  · rw [pow_succ (cardQuot P), ← ih, cardQuot_apply (P ^ i.succ), ←
      card_quotient_mul_card_quotient (P ^ i) (P ^ i.succ) this.le, cardQuot_apply (P ^ i),
      cardQuot_apply P]
    congr 1
    rw [Fintype.card_eq]
    exact ⟨hquot⟩
  choose a a_mem a_not_mem using SetLike.exists_of_lt this
  choose f g hg hf using fun c (hc : c ∈ P ^ i) =>
    Ideal.exists_mul_add_mem_pow_succ hP a c a_mem a_not_mem hc
  choose k hk_mem hk_eq using fun c' (hc' : c' ∈ map (mkQ (P ^ i.succ)) (P ^ i)) =>
    Submodule.mem_map.mp hc'
  refine Equiv.ofBijective (fun c' => Quotient.mk'' (f (k c' c'.prop) (hk_mem c' c'.prop))) ⟨?_, ?_⟩
  · rintro ⟨c₁', hc₁'⟩ ⟨c₂', hc₂'⟩ h
    rw [Subtype.mk_eq_mk, ← hk_eq _ hc₁', ← hk_eq _ hc₂', mkQ_apply, mkQ_apply,
      Submodule.Quotient.eq, ← hf _ (hk_mem _ hc₁'), ← hf _ (hk_mem _ hc₂')]
    refine Ideal.mul_add_mem_pow_succ_inj _ _ _ _ _ _ a_mem (hg _ _) (hg _ _) ?_
    simpa only [Submodule.Quotient.mk''_eq_mk, Submodule.Quotient.mk''_eq_mk,
      Submodule.Quotient.eq] using h
  · intro d'
    refine Quotient.inductionOn' d' fun d => ?_
    have hd' := (mem_map (f := mkQ (P ^ i.succ))).mpr ⟨a * d, Ideal.mul_mem_right d _ a_mem, rfl⟩
    refine ⟨⟨_, hd'⟩, ?_⟩
    simp only [Submodule.Quotient.mk''_eq_mk, Ideal.Quotient.mk_eq_mk, Ideal.Quotient.eq,
      Subtype.coe_mk]
    refine
      Ideal.mul_add_mem_pow_succ_unique hP a _ _ _ _ a_not_mem (hg _ (hk_mem _ hd')) (zero_mem _) ?_
    rw [hf, add_zero]
    exact (Submodule.Quotient.eq _).mp (hk_eq _ hd')
/-- Multiplicity of the ideal norm, for powers of prime ideals. -/
theorem cardQuot_pow_of_prime [IsDedekindDomain S] [Module.Finite ℤ S] [Module.Free ℤ S] {i : ℕ} :
    cardQuot (P ^ i) = cardQuot P ^ i := by
  let _ := Module.Free.chooseBasis ℤ S
  classical
  

Proof state:
S : Type u_1
inst✝⁴ : CommRing S
inst✝³ : IsDomain S
P : Ideal S
P_prime : Ideal.IsPrime P
hP : P ≠ ⊥
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Finite ℤ S
inst✝ : Module.Free ℤ S
i : ℕ
x✝ : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
⊢ cardQuot (P ^ i) = cardQuot P ^ i

Next tactic:
induction' i with i ih
/-- Multiplicity of the ideal norm, for powers of prime ideals. -/
theorem cardQuot_pow_of_prime [IsDedekindDomain S] [Module.Finite ℤ S] [Module.Free ℤ S] {i : ℕ} :
    cardQuot (P ^ i) = cardQuot P ^ i := by
  let _ := Module.Free.chooseBasis ℤ S
  classical
  induction' i with i ih
  · 

Proof state:
case zero
S : Type u_1
inst✝⁴ : CommRing S
inst✝³ : IsDomain S
P : Ideal S
P_prime : Ideal.IsPrime P
hP : P ≠ ⊥
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Finite ℤ S
inst✝ : Module.Free ℤ S
x✝ : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
⊢ cardQuot (P ^ Nat.zero) = cardQuot P ^ Nat.zero

Next tactic:
simp
/-- Multiplicity of the ideal norm, for powers of prime ideals. -/
theorem cardQuot_pow_of_prime [IsDedekindDomain S] [Module.Finite ℤ S] [Module.Free ℤ S] {i : ℕ} :
    cardQuot (P ^ i) = cardQuot P ^ i := by
  let _ := Module.Free.chooseBasis ℤ S
  classical
  induction' i with i ih
  · simp
  

Proof state:
case succ
S : Type u_1
inst✝⁴ : CommRing S
inst✝³ : IsDomain S
P : Ideal S
P_prime : Ideal.IsPrime P
hP : P ≠ ⊥
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Finite ℤ S
inst✝ : Module.Free ℤ S
x✝ : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
i : ℕ
ih : cardQuot (P ^ i) = cardQuot P ^ i
⊢ cardQuot (P ^ Nat.succ i) = cardQuot P ^ Nat.succ i

Next tactic:
letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i.succ) (pow_ne_zero _ hP)
/-- Multiplicity of the ideal norm, for powers of prime ideals. -/
theorem cardQuot_pow_of_prime [IsDedekindDomain S] [Module.Finite ℤ S] [Module.Free ℤ S] {i : ℕ} :
    cardQuot (P ^ i) = cardQuot P ^ i := by
  let _ := Module.Free.chooseBasis ℤ S
  classical
  induction' i with i ih
  · simp
  letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i.succ) (pow_ne_zero _ hP)
  

Proof state:
case succ
S : Type u_1
inst✝⁴ : CommRing S
inst✝³ : IsDomain S
P : Ideal S
P_prime : Ideal.IsPrime P
hP : P ≠ ⊥
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Finite ℤ S
inst✝ : Module.Free ℤ S
x✝ : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
i : ℕ
ih : cardQuot (P ^ i) = cardQuot P ^ i
this : Fintype (S ⧸ P ^ Nat.succ i) := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ Nat.succ i) (_ : P ^ Nat.succ i ≠ 0)
⊢ cardQuot (P ^ Nat.succ i) = cardQuot P ^ Nat.succ i

Next tactic:
letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i) (pow_ne_zero _ hP)
/-- Multiplicity of the ideal norm, for powers of prime ideals. -/
theorem cardQuot_pow_of_prime [IsDedekindDomain S] [Module.Finite ℤ S] [Module.Free ℤ S] {i : ℕ} :
    cardQuot (P ^ i) = cardQuot P ^ i := by
  let _ := Module.Free.chooseBasis ℤ S
  classical
  induction' i with i ih
  · simp
  letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i.succ) (pow_ne_zero _ hP)
  letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i) (pow_ne_zero _ hP)
  

Proof state:
case succ
S : Type u_1
inst✝⁴ : CommRing S
inst✝³ : IsDomain S
P : Ideal S
P_prime : Ideal.IsPrime P
hP : P ≠ ⊥
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Finite ℤ S
inst✝ : Module.Free ℤ S
x✝ : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
i : ℕ
ih : cardQuot (P ^ i) = cardQuot P ^ i
this✝ : Fintype (S ⧸ P ^ Nat.succ i) := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ Nat.succ i) (_ : P ^ Nat.succ i ≠ 0)
this : Fintype (S ⧸ P ^ i) := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i) (_ : P ^ i ≠ 0)
⊢ cardQuot (P ^ Nat.succ i) = cardQuot P ^ Nat.succ i

Next tactic:
letI := Ideal.fintypeQuotientOfFreeOfNeBot P hP
/-- Multiplicity of the ideal norm, for powers of prime ideals. -/
theorem cardQuot_pow_of_prime [IsDedekindDomain S] [Module.Finite ℤ S] [Module.Free ℤ S] {i : ℕ} :
    cardQuot (P ^ i) = cardQuot P ^ i := by
  let _ := Module.Free.chooseBasis ℤ S
  classical
  induction' i with i ih
  · simp
  letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i.succ) (pow_ne_zero _ hP)
  letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i) (pow_ne_zero _ hP)
  letI := Ideal.fintypeQuotientOfFreeOfNeBot P hP
  

Proof state:
case succ
S : Type u_1
inst✝⁴ : CommRing S
inst✝³ : IsDomain S
P : Ideal S
P_prime : Ideal.IsPrime P
hP : P ≠ ⊥
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Finite ℤ S
inst✝ : Module.Free ℤ S
x✝ : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
i : ℕ
ih : cardQuot (P ^ i) = cardQuot P ^ i
this✝¹ : Fintype (S ⧸ P ^ Nat.succ i) := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ Nat.succ i) (_ : P ^ Nat.succ i ≠ 0)
this✝ : Fintype (S ⧸ P ^ i) := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i) (_ : P ^ i ≠ 0)
this : Fintype (S ⧸ P) := Ideal.fintypeQuotientOfFreeOfNeBot P hP
⊢ cardQuot (P ^ Nat.succ i) = cardQuot P ^ Nat.succ i

Next tactic:
have : P ^ (i + 1) < P ^ i := Ideal.pow_succ_lt_pow hP i
/-- Multiplicity of the ideal norm, for powers of prime ideals. -/
theorem cardQuot_pow_of_prime [IsDedekindDomain S] [Module.Finite ℤ S] [Module.Free ℤ S] {i : ℕ} :
    cardQuot (P ^ i) = cardQuot P ^ i := by
  let _ := Module.Free.chooseBasis ℤ S
  classical
  induction' i with i ih
  · simp
  letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i.succ) (pow_ne_zero _ hP)
  letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i) (pow_ne_zero _ hP)
  letI := Ideal.fintypeQuotientOfFreeOfNeBot P hP
  have : P ^ (i + 1) < P ^ i := Ideal.pow_succ_lt_pow hP i
  

Proof state:
case succ
S : Type u_1
inst✝⁴ : CommRing S
inst✝³ : IsDomain S
P : Ideal S
P_prime : Ideal.IsPrime P
hP : P ≠ ⊥
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Finite ℤ S
inst✝ : Module.Free ℤ S
x✝ : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
i : ℕ
ih : cardQuot (P ^ i) = cardQuot P ^ i
this✝² : Fintype (S ⧸ P ^ Nat.succ i) := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ Nat.succ i) (_ : P ^ Nat.succ i ≠ 0)
this✝¹ : Fintype (S ⧸ P ^ i) := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i) (_ : P ^ i ≠ 0)
this✝ : Fintype (S ⧸ P) := Ideal.fintypeQuotientOfFreeOfNeBot P hP
this : P ^ (i + 1) < P ^ i
⊢ cardQuot (P ^ Nat.succ i) = cardQuot P ^ Nat.succ i

Next tactic:
suffices hquot : map (P ^ i.succ).mkQ (P ^ i) ≃ S ⧸ P
/-- Multiplicity of the ideal norm, for powers of prime ideals. -/
theorem cardQuot_pow_of_prime [IsDedekindDomain S] [Module.Finite ℤ S] [Module.Free ℤ S] {i : ℕ} :
    cardQuot (P ^ i) = cardQuot P ^ i := by
  let _ := Module.Free.chooseBasis ℤ S
  classical
  induction' i with i ih
  · simp
  letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i.succ) (pow_ne_zero _ hP)
  letI := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i) (pow_ne_zero _ hP)
  letI := Ideal.fintypeQuotientOfFreeOfNeBot P hP
  have : P ^ (i + 1) < P ^ i := Ideal.pow_succ_lt_pow hP i
  suffices hquot : map (P ^ i.succ).mkQ (P ^ i) ≃ S ⧸ P
  · 

Proof state:
case succ
S : Type u_1
inst✝⁴ : CommRing S
inst✝³ : IsDomain S
P : Ideal S
P_prime : Ideal.IsPrime P
hP : P ≠ ⊥
inst✝² : IsDedekindDomain S
inst✝¹ : Module.Finite ℤ S
inst✝ : Module.Free ℤ S
x✝ : Basis (Module.Free.ChooseBasisIndex ℤ S) ℤ S := Module.Free.chooseBasis ℤ S
i : ℕ
ih : cardQuot (P ^ i) = cardQuot P ^ i
this✝² : Fintype (S ⧸ P ^ Nat.succ i) := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ Nat.succ i) (_ : P ^ Nat.succ i ≠ 0)
this✝¹ : Fintype (S ⧸ P ^ i) := Ideal.fintypeQuotientOfFreeOfNeBot (P ^ i) (_ : P ^ i ≠ 0)
this✝ : Fintype (S ⧸ P) := Ideal.fintypeQuotientOfFreeOfNeBot P hP
this : P ^ (i + 1) < P ^ i
hquot : ↥(map (mkQ (P ^ Nat.succ i)) (P ^ i)) ≃ S ⧸ P
⊢ cardQuot (P ^ Nat.succ i) = cardQuot P ^ Nat.succ i

Next tactic:
rw [pow_succ (cardQuot P), ← ih, cardQuot_apply (P ^ i.succ), ←
      card_quotient_mul_card_quotient (P ^ i) (P ^ i.succ) this.le, cardQuot_apply (P ^ i),
      cardQuot_apply P]