l3lab/ntp-mathlib huggingface dataset:
theorem quotientToQuotientRangePowQuotSucc_surjective [IsDomain S] [IsDedekindDomain S]
    (hP0 : P ≠ ⊥) [hP : P.IsPrime] {i : ℕ} (hi : i < e) {a : S} (a_mem : a ∈ P ^ i)
    (a_not_mem : a ∉ P ^ (i + 1)) :
    Function.Surjective (quotientToQuotientRangePowQuotSucc f p P a_mem) := by
  rintro ⟨⟨⟨x⟩, hx⟩⟩
  have Pe_le_Pi : P ^ e ≤ P ^ i := Ideal.pow_le_pow_right hi.le
  rw [Submodule.Quotient.quot_mk_eq_mk, Ideal.Quotient.mk_eq_mk, Ideal.mem_quotient_iff_mem_sup,
    sup_eq_left.mpr Pe_le_Pi] at hx
  suffices hx' : x ∈ Ideal.span {a} ⊔ P ^ (i + 1)
  · obtain ⟨y', hy', z, hz, rfl⟩ := Submodule.mem_sup.mp hx'
    obtain ⟨y, rfl⟩ := Ideal.mem_span_singleton.mp hy'
    refine ⟨Submodule.Quotient.mk y, ?_⟩
    simp only [Submodule.Quotient.quot_mk_eq_mk, quotientToQuotientRangePowQuotSucc_mk,
      Submodule.Quotient.eq, LinearMap.mem_range, Subtype.ext_iff, Subtype.coe_mk,
      Submodule.coe_sub]
    refine ⟨⟨_, Ideal.mem_map_of_mem _ (Submodule.neg_mem _ hz)⟩, ?_⟩
    rw [powQuotSuccInclusion_apply_coe, Subtype.coe_mk, Ideal.Quotient.mk_eq_mk, map_add,
      mul_comm y a, sub_add_cancel', map_neg]
  letI := Classical.decEq (Ideal S)
  rw [sup_eq_prod_inf_factors _ (pow_ne_zero _ hP0), normalizedFactors_pow,
    normalizedFactors_irreducible ((Ideal.prime_iff_isPrime hP0).mpr hP).irreducible, normalize_eq,
    Multiset.nsmul_singleton, Multiset.inter_replicate, Multiset.prod_replicate]
  rw [← Submodule.span_singleton_le_iff_mem, Ideal.submodule_span_eq] at a_mem a_not_mem
  

Proof state:
case hx'
R : Type u
inst✝³ : CommRing R
S : Type v
inst✝² : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
inst✝¹ : IsDomain S
inst✝ : IsDedekindDomain S
hP0 : P ≠ ⊥
hP : IsPrime P
i : ℕ
hi : i < e
a : S
a_mem : span {a} ≤ P ^ i
a_not_mem : ¬span {a} ≤ P ^ (i + 1)
b✝ : ↥(map (Quotient.mk (P ^ e)) (P ^ i)) ⧸ LinearMap.range (powQuotSuccInclusion f p P i)
val✝ : S ⧸ P ^ e
x : S
hx✝ : Quot.mk Setoid.r x ∈ map (Quotient.mk (P ^ e)) (P ^ i)
hx : x ∈ P ^ i
Pe_le_Pi : P ^ e ≤ P ^ i
this : DecidableEq (Ideal S) := Classical.decEq (Ideal S)
⊢ x ∈ P ^ min (Multiset.count P (normalizedFactors (span {a}))) (i + 1)
R : Type u
inst✝³ : CommRing R
S : Type v
inst✝² : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
inst✝¹ : IsDomain S
inst✝ : IsDedekindDomain S
hP0 : P ≠ ⊥
hP : IsPrime P
i : ℕ
hi : i < e
a : S
a_mem : a ∈ P ^ i
a_not_mem : a ∉ P ^ (i + 1)
b✝ : ↥(map (Quotient.mk (P ^ e)) (P ^ i)) ⧸ LinearMap.range (powQuotSuccInclusion f p P i)
val✝ : S ⧸ P ^ e
x : S
hx✝ : Quot.mk Setoid.r x ∈ map (Quotient.mk (P ^ e)) (P ^ i)
hx : x ∈ P ^ i
Pe_le_Pi : P ^ e ≤ P ^ i
this : DecidableEq (Ideal S) := Classical.decEq (Ideal S)
⊢ span {a} ≠ ⊥

Next tactic:
rwa [Ideal.count_normalizedFactors_eq a_mem a_not_mem, min_eq_left i.le_succ]
theorem quotientToQuotientRangePowQuotSucc_surjective [IsDomain S] [IsDedekindDomain S]
    (hP0 : P ≠ ⊥) [hP : P.IsPrime] {i : ℕ} (hi : i < e) {a : S} (a_mem : a ∈ P ^ i)
    (a_not_mem : a ∉ P ^ (i + 1)) :
    Function.Surjective (quotientToQuotientRangePowQuotSucc f p P a_mem) := by
  rintro ⟨⟨⟨x⟩, hx⟩⟩
  have Pe_le_Pi : P ^ e ≤ P ^ i := Ideal.pow_le_pow_right hi.le
  rw [Submodule.Quotient.quot_mk_eq_mk, Ideal.Quotient.mk_eq_mk, Ideal.mem_quotient_iff_mem_sup,
    sup_eq_left.mpr Pe_le_Pi] at hx
  suffices hx' : x ∈ Ideal.span {a} ⊔ P ^ (i + 1)
  · obtain ⟨y', hy', z, hz, rfl⟩ := Submodule.mem_sup.mp hx'
    obtain ⟨y, rfl⟩ := Ideal.mem_span_singleton.mp hy'
    refine ⟨Submodule.Quotient.mk y, ?_⟩
    simp only [Submodule.Quotient.quot_mk_eq_mk, quotientToQuotientRangePowQuotSucc_mk,
      Submodule.Quotient.eq, LinearMap.mem_range, Subtype.ext_iff, Subtype.coe_mk,
      Submodule.coe_sub]
    refine ⟨⟨_, Ideal.mem_map_of_mem _ (Submodule.neg_mem _ hz)⟩, ?_⟩
    rw [powQuotSuccInclusion_apply_coe, Subtype.coe_mk, Ideal.Quotient.mk_eq_mk, map_add,
      mul_comm y a, sub_add_cancel', map_neg]
  letI := Classical.decEq (Ideal S)
  rw [sup_eq_prod_inf_factors _ (pow_ne_zero _ hP0), normalizedFactors_pow,
    normalizedFactors_irreducible ((Ideal.prime_iff_isPrime hP0).mpr hP).irreducible, normalize_eq,
    Multiset.nsmul_singleton, Multiset.inter_replicate, Multiset.prod_replicate]
  rw [← Submodule.span_singleton_le_iff_mem, Ideal.submodule_span_eq] at a_mem a_not_mem
  rwa [Ideal.count_normalizedFactors_eq a_mem a_not_mem, min_eq_left i.le_succ]
  · 

Proof state:
R : Type u
inst✝³ : CommRing R
S : Type v
inst✝² : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
inst✝¹ : IsDomain S
inst✝ : IsDedekindDomain S
hP0 : P ≠ ⊥
hP : IsPrime P
i : ℕ
hi : i < e
a : S
a_mem : a ∈ P ^ i
a_not_mem : a ∉ P ^ (i + 1)
b✝ : ↥(map (Quotient.mk (P ^ e)) (P ^ i)) ⧸ LinearMap.range (powQuotSuccInclusion f p P i)
val✝ : S ⧸ P ^ e
x : S
hx✝ : Quot.mk Setoid.r x ∈ map (Quotient.mk (P ^ e)) (P ^ i)
hx : x ∈ P ^ i
Pe_le_Pi : P ^ e ≤ P ^ i
this : DecidableEq (Ideal S) := Classical.decEq (Ideal S)
⊢ span {a} ≠ ⊥

Next tactic:
intro ha
theorem quotientToQuotientRangePowQuotSucc_surjective [IsDomain S] [IsDedekindDomain S]
    (hP0 : P ≠ ⊥) [hP : P.IsPrime] {i : ℕ} (hi : i < e) {a : S} (a_mem : a ∈ P ^ i)
    (a_not_mem : a ∉ P ^ (i + 1)) :
    Function.Surjective (quotientToQuotientRangePowQuotSucc f p P a_mem) := by
  rintro ⟨⟨⟨x⟩, hx⟩⟩
  have Pe_le_Pi : P ^ e ≤ P ^ i := Ideal.pow_le_pow_right hi.le
  rw [Submodule.Quotient.quot_mk_eq_mk, Ideal.Quotient.mk_eq_mk, Ideal.mem_quotient_iff_mem_sup,
    sup_eq_left.mpr Pe_le_Pi] at hx
  suffices hx' : x ∈ Ideal.span {a} ⊔ P ^ (i + 1)
  · obtain ⟨y', hy', z, hz, rfl⟩ := Submodule.mem_sup.mp hx'
    obtain ⟨y, rfl⟩ := Ideal.mem_span_singleton.mp hy'
    refine ⟨Submodule.Quotient.mk y, ?_⟩
    simp only [Submodule.Quotient.quot_mk_eq_mk, quotientToQuotientRangePowQuotSucc_mk,
      Submodule.Quotient.eq, LinearMap.mem_range, Subtype.ext_iff, Subtype.coe_mk,
      Submodule.coe_sub]
    refine ⟨⟨_, Ideal.mem_map_of_mem _ (Submodule.neg_mem _ hz)⟩, ?_⟩
    rw [powQuotSuccInclusion_apply_coe, Subtype.coe_mk, Ideal.Quotient.mk_eq_mk, map_add,
      mul_comm y a, sub_add_cancel', map_neg]
  letI := Classical.decEq (Ideal S)
  rw [sup_eq_prod_inf_factors _ (pow_ne_zero _ hP0), normalizedFactors_pow,
    normalizedFactors_irreducible ((Ideal.prime_iff_isPrime hP0).mpr hP).irreducible, normalize_eq,
    Multiset.nsmul_singleton, Multiset.inter_replicate, Multiset.prod_replicate]
  rw [← Submodule.span_singleton_le_iff_mem, Ideal.submodule_span_eq] at a_mem a_not_mem
  rwa [Ideal.count_normalizedFactors_eq a_mem a_not_mem, min_eq_left i.le_succ]
  · intro ha
    

Proof state:
R : Type u
inst✝³ : CommRing R
S : Type v
inst✝² : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
inst✝¹ : IsDomain S
inst✝ : IsDedekindDomain S
hP0 : P ≠ ⊥
hP : IsPrime P
i : ℕ
hi : i < e
a : S
a_mem : a ∈ P ^ i
a_not_mem : a ∉ P ^ (i + 1)
b✝ : ↥(map (Quotient.mk (P ^ e)) (P ^ i)) ⧸ LinearMap.range (powQuotSuccInclusion f p P i)
val✝ : S ⧸ P ^ e
x : S
hx✝ : Quot.mk Setoid.r x ∈ map (Quotient.mk (P ^ e)) (P ^ i)
hx : x ∈ P ^ i
Pe_le_Pi : P ^ e ≤ P ^ i
this : DecidableEq (Ideal S) := Classical.decEq (Ideal S)
ha : span {a} = ⊥
⊢ False

Next tactic:
rw [Ideal.span_singleton_eq_bot.mp ha] at a_not_mem
theorem quotientToQuotientRangePowQuotSucc_surjective [IsDomain S] [IsDedekindDomain S]
    (hP0 : P ≠ ⊥) [hP : P.IsPrime] {i : ℕ} (hi : i < e) {a : S} (a_mem : a ∈ P ^ i)
    (a_not_mem : a ∉ P ^ (i + 1)) :
    Function.Surjective (quotientToQuotientRangePowQuotSucc f p P a_mem) := by
  rintro ⟨⟨⟨x⟩, hx⟩⟩
  have Pe_le_Pi : P ^ e ≤ P ^ i := Ideal.pow_le_pow_right hi.le
  rw [Submodule.Quotient.quot_mk_eq_mk, Ideal.Quotient.mk_eq_mk, Ideal.mem_quotient_iff_mem_sup,
    sup_eq_left.mpr Pe_le_Pi] at hx
  suffices hx' : x ∈ Ideal.span {a} ⊔ P ^ (i + 1)
  · obtain ⟨y', hy', z, hz, rfl⟩ := Submodule.mem_sup.mp hx'
    obtain ⟨y, rfl⟩ := Ideal.mem_span_singleton.mp hy'
    refine ⟨Submodule.Quotient.mk y, ?_⟩
    simp only [Submodule.Quotient.quot_mk_eq_mk, quotientToQuotientRangePowQuotSucc_mk,
      Submodule.Quotient.eq, LinearMap.mem_range, Subtype.ext_iff, Subtype.coe_mk,
      Submodule.coe_sub]
    refine ⟨⟨_, Ideal.mem_map_of_mem _ (Submodule.neg_mem _ hz)⟩, ?_⟩
    rw [powQuotSuccInclusion_apply_coe, Subtype.coe_mk, Ideal.Quotient.mk_eq_mk, map_add,
      mul_comm y a, sub_add_cancel', map_neg]
  letI := Classical.decEq (Ideal S)
  rw [sup_eq_prod_inf_factors _ (pow_ne_zero _ hP0), normalizedFactors_pow,
    normalizedFactors_irreducible ((Ideal.prime_iff_isPrime hP0).mpr hP).irreducible, normalize_eq,
    Multiset.nsmul_singleton, Multiset.inter_replicate, Multiset.prod_replicate]
  rw [← Submodule.span_singleton_le_iff_mem, Ideal.submodule_span_eq] at a_mem a_not_mem
  rwa [Ideal.count_normalizedFactors_eq a_mem a_not_mem, min_eq_left i.le_succ]
  · intro ha
    rw [Ideal.span_singleton_eq_bot.mp ha] at a_not_mem
    

Proof state:
R : Type u
inst✝³ : CommRing R
S : Type v
inst✝² : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
inst✝¹ : IsDomain S
inst✝ : IsDedekindDomain S
hP0 : P ≠ ⊥
hP : IsPrime P
i : ℕ
hi : i < e
a : S
a_mem : a ∈ P ^ i
a_not_mem : 0 ∉ P ^ (i + 1)
b✝ : ↥(map (Quotient.mk (P ^ e)) (P ^ i)) ⧸ LinearMap.range (powQuotSuccInclusion f p P i)
val✝ : S ⧸ P ^ e
x : S
hx✝ : Quot.mk Setoid.r x ∈ map (Quotient.mk (P ^ e)) (P ^ i)
hx : x ∈ P ^ i
Pe_le_Pi : P ^ e ≤ P ^ i
this : DecidableEq (Ideal S) := Classical.decEq (Ideal S)
ha : span {a} = ⊥
⊢ False

Next tactic:
have := (P ^ (i + 1)).zero_mem
theorem quotientToQuotientRangePowQuotSucc_surjective [IsDomain S] [IsDedekindDomain S]
    (hP0 : P ≠ ⊥) [hP : P.IsPrime] {i : ℕ} (hi : i < e) {a : S} (a_mem : a ∈ P ^ i)
    (a_not_mem : a ∉ P ^ (i + 1)) :
    Function.Surjective (quotientToQuotientRangePowQuotSucc f p P a_mem) := by
  rintro ⟨⟨⟨x⟩, hx⟩⟩
  have Pe_le_Pi : P ^ e ≤ P ^ i := Ideal.pow_le_pow_right hi.le
  rw [Submodule.Quotient.quot_mk_eq_mk, Ideal.Quotient.mk_eq_mk, Ideal.mem_quotient_iff_mem_sup,
    sup_eq_left.mpr Pe_le_Pi] at hx
  suffices hx' : x ∈ Ideal.span {a} ⊔ P ^ (i + 1)
  · obtain ⟨y', hy', z, hz, rfl⟩ := Submodule.mem_sup.mp hx'
    obtain ⟨y, rfl⟩ := Ideal.mem_span_singleton.mp hy'
    refine ⟨Submodule.Quotient.mk y, ?_⟩
    simp only [Submodule.Quotient.quot_mk_eq_mk, quotientToQuotientRangePowQuotSucc_mk,
      Submodule.Quotient.eq, LinearMap.mem_range, Subtype.ext_iff, Subtype.coe_mk,
      Submodule.coe_sub]
    refine ⟨⟨_, Ideal.mem_map_of_mem _ (Submodule.neg_mem _ hz)⟩, ?_⟩
    rw [powQuotSuccInclusion_apply_coe, Subtype.coe_mk, Ideal.Quotient.mk_eq_mk, map_add,
      mul_comm y a, sub_add_cancel', map_neg]
  letI := Classical.decEq (Ideal S)
  rw [sup_eq_prod_inf_factors _ (pow_ne_zero _ hP0), normalizedFactors_pow,
    normalizedFactors_irreducible ((Ideal.prime_iff_isPrime hP0).mpr hP).irreducible, normalize_eq,
    Multiset.nsmul_singleton, Multiset.inter_replicate, Multiset.prod_replicate]
  rw [← Submodule.span_singleton_le_iff_mem, Ideal.submodule_span_eq] at a_mem a_not_mem
  rwa [Ideal.count_normalizedFactors_eq a_mem a_not_mem, min_eq_left i.le_succ]
  · intro ha
    rw [Ideal.span_singleton_eq_bot.mp ha] at a_not_mem
    have := (P ^ (i + 1)).zero_mem
    

Proof state:
R : Type u
inst✝³ : CommRing R
S : Type v
inst✝² : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
inst✝¹ : IsDomain S
inst✝ : IsDedekindDomain S
hP0 : P ≠ ⊥
hP : IsPrime P
i : ℕ
hi : i < e
a : S
a_mem : a ∈ P ^ i
a_not_mem : 0 ∉ P ^ (i + 1)
b✝ : ↥(map (Quotient.mk (P ^ e)) (P ^ i)) ⧸ LinearMap.range (powQuotSuccInclusion f p P i)
val✝ : S ⧸ P ^ e
x : S
hx✝ : Quot.mk Setoid.r x ∈ map (Quotient.mk (P ^ e)) (P ^ i)
hx : x ∈ P ^ i
Pe_le_Pi : P ^ e ≤ P ^ i
this✝ : DecidableEq (Ideal S) := Classical.decEq (Ideal S)
ha : span {a} = ⊥
this : 0 ∈ P ^ (i + 1)
⊢ False

Next tactic:
contradiction
/-- Quotienting `P^i / P^e` by its subspace `P^(i+1) ⧸ P^e` is
`R ⧸ p`-linearly isomorphic to `S ⧸ P`. -/
noncomputable def quotientRangePowQuotSuccInclusionEquiv [IsDomain S] [IsDedekindDomain S]
    [P.IsPrime] (hP : P ≠ ⊥) {i : ℕ} (hi : i < e) :
    ((P ^ i).map (Ideal.Quotient.mk (P ^ e)) ⧸ LinearMap.range (powQuotSuccInclusion f p P i))
      ≃ₗ[R ⧸ p] S ⧸ P := by
  

Proof state:
R : Type u
inst✝⁴ : CommRing R
S : Type v
inst✝³ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
inst✝² : IsDomain S
inst✝¹ : IsDedekindDomain S
inst✝ : IsPrime P
hP : P ≠ ⊥
i : ℕ
hi : i < e
⊢ (↥(map (Quotient.mk (P ^ e)) (P ^ i)) ⧸ LinearMap.range (powQuotSuccInclusion f p P i)) ≃ₗ[R ⧸ p] S ⧸ P

Next tactic:
choose a a_mem a_not_mem using
    SetLike.exists_of_lt
      (Ideal.pow_right_strictAnti P hP (Ideal.IsPrime.ne_top inferInstance) (le_refl i.succ))
/-- Quotienting `P^i / P^e` by its subspace `P^(i+1) ⧸ P^e` is
`R ⧸ p`-linearly isomorphic to `S ⧸ P`. -/
noncomputable def quotientRangePowQuotSuccInclusionEquiv [IsDomain S] [IsDedekindDomain S]
    [P.IsPrime] (hP : P ≠ ⊥) {i : ℕ} (hi : i < e) :
    ((P ^ i).map (Ideal.Quotient.mk (P ^ e)) ⧸ LinearMap.range (powQuotSuccInclusion f p P i))
      ≃ₗ[R ⧸ p] S ⧸ P := by
  choose a a_mem a_not_mem using
    SetLike.exists_of_lt
      (Ideal.pow_right_strictAnti P hP (Ideal.IsPrime.ne_top inferInstance) (le_refl i.succ))
  

Proof state:
R : Type u
inst✝⁴ : CommRing R
S : Type v
inst✝³ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
inst✝² : IsDomain S
inst✝¹ : IsDedekindDomain S
inst✝ : IsPrime P
hP : P ≠ ⊥
i : ℕ
hi : i < e
a : S
a_mem : a ∈ (fun x => P ^ x) i
a_not_mem : a ∉ (fun x => P ^ x) (Nat.succ i)
⊢ (↥(map (Quotient.mk (P ^ e)) (P ^ i)) ⧸ LinearMap.range (powQuotSuccInclusion f p P i)) ≃ₗ[R ⧸ p] S ⧸ P

Next tactic:
refine' (LinearEquiv.ofBijective _ ⟨_, _⟩).symm
/-- Quotienting `P^i / P^e` by its subspace `P^(i+1) ⧸ P^e` is
`R ⧸ p`-linearly isomorphic to `S ⧸ P`. -/
noncomputable def quotientRangePowQuotSuccInclusionEquiv [IsDomain S] [IsDedekindDomain S]
    [P.IsPrime] (hP : P ≠ ⊥) {i : ℕ} (hi : i < e) :
    ((P ^ i).map (Ideal.Quotient.mk (P ^ e)) ⧸ LinearMap.range (powQuotSuccInclusion f p P i))
      ≃ₗ[R ⧸ p] S ⧸ P := by
  choose a a_mem a_not_mem using
    SetLike.exists_of_lt
      (Ideal.pow_right_strictAnti P hP (Ideal.IsPrime.ne_top inferInstance) (le_refl i.succ))
  refine' (LinearEquiv.ofBijective _ ⟨_, _⟩).symm
  · 

Proof state:
case refine'_1
R : Type u
inst✝⁴ : CommRing R
S : Type v
inst✝³ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
inst✝² : IsDomain S
inst✝¹ : IsDedekindDomain S
inst✝ : IsPrime P
hP : P ≠ ⊥
i : ℕ
hi : i < e
a : S
a_mem : a ∈ (fun x => P ^ x) i
a_not_mem : a ∉ (fun x => P ^ x) (Nat.succ i)
⊢ S ⧸ P →ₗ[R ⧸ p] ↥(map (Quotient.mk (P ^ e)) (P ^ i)) ⧸ LinearMap.range (powQuotSuccInclusion f p P i)

Next tactic:
exact quotientToQuotientRangePowQuotSucc f p P a_mem
/-- Quotienting `P^i / P^e` by its subspace `P^(i+1) ⧸ P^e` is
`R ⧸ p`-linearly isomorphic to `S ⧸ P`. -/
noncomputable def quotientRangePowQuotSuccInclusionEquiv [IsDomain S] [IsDedekindDomain S]
    [P.IsPrime] (hP : P ≠ ⊥) {i : ℕ} (hi : i < e) :
    ((P ^ i).map (Ideal.Quotient.mk (P ^ e)) ⧸ LinearMap.range (powQuotSuccInclusion f p P i))
      ≃ₗ[R ⧸ p] S ⧸ P := by
  choose a a_mem a_not_mem using
    SetLike.exists_of_lt
      (Ideal.pow_right_strictAnti P hP (Ideal.IsPrime.ne_top inferInstance) (le_refl i.succ))
  refine' (LinearEquiv.ofBijective _ ⟨_, _⟩).symm
  · exact quotientToQuotientRangePowQuotSucc f p P a_mem
  · 

Proof state:
case refine'_2
R : Type u
inst✝⁴ : CommRing R
S : Type v
inst✝³ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
inst✝² : IsDomain S
inst✝¹ : IsDedekindDomain S
inst✝ : IsPrime P
hP : P ≠ ⊥
i : ℕ
hi : i < e
a : S
a_mem : a ∈ (fun x => P ^ x) i
a_not_mem : a ∉ (fun x => P ^ x) (Nat.succ i)
⊢ Function.Injective ⇑(quotientToQuotientRangePowQuotSucc f p P a_mem)

Next tactic:
exact quotientToQuotientRangePowQuotSucc_injective f p P hi a_mem a_not_mem
/-- Quotienting `P^i / P^e` by its subspace `P^(i+1) ⧸ P^e` is
`R ⧸ p`-linearly isomorphic to `S ⧸ P`. -/
noncomputable def quotientRangePowQuotSuccInclusionEquiv [IsDomain S] [IsDedekindDomain S]
    [P.IsPrime] (hP : P ≠ ⊥) {i : ℕ} (hi : i < e) :
    ((P ^ i).map (Ideal.Quotient.mk (P ^ e)) ⧸ LinearMap.range (powQuotSuccInclusion f p P i))
      ≃ₗ[R ⧸ p] S ⧸ P := by
  choose a a_mem a_not_mem using
    SetLike.exists_of_lt
      (Ideal.pow_right_strictAnti P hP (Ideal.IsPrime.ne_top inferInstance) (le_refl i.succ))
  refine' (LinearEquiv.ofBijective _ ⟨_, _⟩).symm
  · exact quotientToQuotientRangePowQuotSucc f p P a_mem
  · exact quotientToQuotientRangePowQuotSucc_injective f p P hi a_mem a_not_mem
  · 

Proof state:
case refine'_3
R : Type u
inst✝⁴ : CommRing R
S : Type v
inst✝³ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
inst✝² : IsDomain S
inst✝¹ : IsDedekindDomain S
inst✝ : IsPrime P
hP : P ≠ ⊥
i : ℕ
hi : i < e
a : S
a_mem : a ∈ (fun x => P ^ x) i
a_not_mem : a ∉ (fun x => P ^ x) (Nat.succ i)
⊢ Function.Surjective ⇑(quotientToQuotientRangePowQuotSucc f p P a_mem)

Next tactic:
exact quotientToQuotientRangePowQuotSucc_surjective f p P hP hi a_mem a_not_mem
/-- Since the inclusion `(P^(i + 1) / P^e) ⊂ (P^i / P^e)` has a kernel isomorphic to `P / S`,
`[P^i / P^e : R / p] = [P^(i+1) / P^e : R / p] + [P / S : R / p]` -/
theorem rank_pow_quot_aux [IsDomain S] [IsDedekindDomain S] [p.IsMaximal] [P.IsPrime] (hP0 : P ≠ ⊥)
    {i : ℕ} (hi : i < e) :
    Module.rank (R ⧸ p) (Ideal.map (Ideal.Quotient.mk (P ^ e)) (P ^ i)) =
      Module.rank (R ⧸ p) (S ⧸ P) +
        Module.rank (R ⧸ p) (Ideal.map (Ideal.Quotient.mk (P ^ e)) (P ^ (i + 1))) := by
  

Proof state:
R : Type u
inst✝⁵ : CommRing R
S : Type v
inst✝⁴ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
inst✝³ : IsDomain S
inst✝² : IsDedekindDomain S
inst✝¹ : IsMaximal p
inst✝ : IsPrime P
hP0 : P ≠ ⊥
i : ℕ
hi : i < e
⊢ Module.rank (R ⧸ p) ↥(map (Quotient.mk (P ^ e)) (P ^ i)) =
    Module.rank (R ⧸ p) (S ⧸ P) + Module.rank (R ⧸ p) ↥(map (Quotient.mk (P ^ e)) (P ^ (i + 1)))

Next tactic:
letI : Field (R ⧸ p) := Ideal.Quotient.field _
/-- Since the inclusion `(P^(i + 1) / P^e) ⊂ (P^i / P^e)` has a kernel isomorphic to `P / S`,
`[P^i / P^e : R / p] = [P^(i+1) / P^e : R / p] + [P / S : R / p]` -/
theorem rank_pow_quot_aux [IsDomain S] [IsDedekindDomain S] [p.IsMaximal] [P.IsPrime] (hP0 : P ≠ ⊥)
    {i : ℕ} (hi : i < e) :
    Module.rank (R ⧸ p) (Ideal.map (Ideal.Quotient.mk (P ^ e)) (P ^ i)) =
      Module.rank (R ⧸ p) (S ⧸ P) +
        Module.rank (R ⧸ p) (Ideal.map (Ideal.Quotient.mk (P ^ e)) (P ^ (i + 1))) := by
  letI : Field (R ⧸ p) := Ideal.Quotient.field _
  

Proof state:
R : Type u
inst✝⁵ : CommRing R
S : Type v
inst✝⁴ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
inst✝³ : IsDomain S
inst✝² : IsDedekindDomain S
inst✝¹ : IsMaximal p
inst✝ : IsPrime P
hP0 : P ≠ ⊥
i : ℕ
hi : i < e
this : Field (R ⧸ p) := Quotient.field p
⊢ Module.rank (R ⧸ p) ↥(map (Quotient.mk (P ^ e)) (P ^ i)) =
    Module.rank (R ⧸ p) (S ⧸ P) + Module.rank (R ⧸ p) ↥(map (Quotient.mk (P ^ e)) (P ^ (i + 1)))

Next tactic:
rw [← rank_range_of_injective _ (powQuotSuccInclusion_injective f p P i),
    (quotientRangePowQuotSuccInclusionEquiv f p P hP0 hi).symm.rank_eq]
/-- Since the inclusion `(P^(i + 1) / P^e) ⊂ (P^i / P^e)` has a kernel isomorphic to `P / S`,
`[P^i / P^e : R / p] = [P^(i+1) / P^e : R / p] + [P / S : R / p]` -/
theorem rank_pow_quot_aux [IsDomain S] [IsDedekindDomain S] [p.IsMaximal] [P.IsPrime] (hP0 : P ≠ ⊥)
    {i : ℕ} (hi : i < e) :
    Module.rank (R ⧸ p) (Ideal.map (Ideal.Quotient.mk (P ^ e)) (P ^ i)) =
      Module.rank (R ⧸ p) (S ⧸ P) +
        Module.rank (R ⧸ p) (Ideal.map (Ideal.Quotient.mk (P ^ e)) (P ^ (i + 1))) := by
  letI : Field (R ⧸ p) := Ideal.Quotient.field _
  rw [← rank_range_of_injective _ (powQuotSuccInclusion_injective f p P i),
    (quotientRangePowQuotSuccInclusionEquiv f p P hP0 hi).symm.rank_eq]
  

Proof state:
R : Type u
inst✝⁵ : CommRing R
S : Type v
inst✝⁴ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
inst✝³ : IsDomain S
inst✝² : IsDedekindDomain S
inst✝¹ : IsMaximal p
inst✝ : IsPrime P
hP0 : P ≠ ⊥
i : ℕ
hi : i < e
this : Field (R ⧸ p) := Quotient.field p
⊢ Module.rank (R ⧸ p) ↥(map (Quotient.mk (P ^ e)) (P ^ i)) =
    Module.rank (R ⧸ p) (↥(map (Quotient.mk (P ^ e)) (P ^ i)) ⧸ LinearMap.range (powQuotSuccInclusion f p P i)) +
      Module.rank (R ⧸ p) ↥(LinearMap.range (powQuotSuccInclusion f p P i))

Next tactic:
exact (rank_quotient_add_rank (LinearMap.range (powQuotSuccInclusion f p P i))).symm
theorem rank_pow_quot [IsDomain S] [IsDedekindDomain S] [p.IsMaximal] [P.IsPrime] (hP0 : P ≠ ⊥)
    (i : ℕ) (hi : i ≤ e) :
    Module.rank (R ⧸ p) (Ideal.map (Ideal.Quotient.mk (P ^ e)) (P ^ i)) =
      (e - i) • Module.rank (R ⧸ p) (S ⧸ P) := by
-- Porting note: Lean cannot figure out what to prove by itself
  

Proof state:
R : Type u
inst✝⁵ : CommRing R
S : Type v
inst✝⁴ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
inst✝³ : IsDomain S
inst✝² : IsDedekindDomain S
inst✝¹ : IsMaximal p
inst✝ : IsPrime P
hP0 : P ≠ ⊥
i : ℕ
hi : i ≤ e
⊢ Module.rank (R ⧸ p) ↥(map (Quotient.mk (P ^ e)) (P ^ i)) = (e - i) • Module.rank (R ⧸ p) (S ⧸ P)

Next tactic:
let Q : ℕ → Prop :=
    fun i => Module.rank (R ⧸ p) { x // x ∈ map (Quotient.mk (P ^ e)) (P ^ i) }
      = (e - i) • Module.rank (R ⧸ p) (S ⧸ P)
theorem rank_pow_quot [IsDomain S] [IsDedekindDomain S] [p.IsMaximal] [P.IsPrime] (hP0 : P ≠ ⊥)
    (i : ℕ) (hi : i ≤ e) :
    Module.rank (R ⧸ p) (Ideal.map (Ideal.Quotient.mk (P ^ e)) (P ^ i)) =
      (e - i) • Module.rank (R ⧸ p) (S ⧸ P) := by
-- Porting note: Lean cannot figure out what to prove by itself
  let Q : ℕ → Prop :=
    fun i => Module.rank (R ⧸ p) { x // x ∈ map (Quotient.mk (P ^ e)) (P ^ i) }
      = (e - i) • Module.rank (R ⧸ p) (S ⧸ P)
  

Proof state:
R : Type u
inst✝⁵ : CommRing R
S : Type v
inst✝⁴ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
inst✝³ : IsDomain S
inst✝² : IsDedekindDomain S
inst✝¹ : IsMaximal p
inst✝ : IsPrime P
hP0 : P ≠ ⊥
i : ℕ
hi : i ≤ e
Q : ℕ → Prop :=
  fun i => Module.rank (R ⧸ p) ↥(map (Quotient.mk (P ^ e)) (P ^ i)) = (e - i) • Module.rank (R ⧸ p) (S ⧸ P)
⊢ Module.rank (R ⧸ p) ↥(map (Quotient.mk (P ^ e)) (P ^ i)) = (e - i) • Module.rank (R ⧸ p) (S ⧸ P)

Next tactic:
refine @Nat.decreasingInduction' Q i e (fun j lt_e _le_j ih => ?_) hi ?_
theorem rank_pow_quot [IsDomain S] [IsDedekindDomain S] [p.IsMaximal] [P.IsPrime] (hP0 : P ≠ ⊥)
    (i : ℕ) (hi : i ≤ e) :
    Module.rank (R ⧸ p) (Ideal.map (Ideal.Quotient.mk (P ^ e)) (P ^ i)) =
      (e - i) • Module.rank (R ⧸ p) (S ⧸ P) := by
-- Porting note: Lean cannot figure out what to prove by itself
  let Q : ℕ → Prop :=
    fun i => Module.rank (R ⧸ p) { x // x ∈ map (Quotient.mk (P ^ e)) (P ^ i) }
      = (e - i) • Module.rank (R ⧸ p) (S ⧸ P)
  refine @Nat.decreasingInduction' Q i e (fun j lt_e _le_j ih => ?_) hi ?_
  · 

Proof state:
case refine_1
R : Type u
inst✝⁵ : CommRing R
S : Type v
inst✝⁴ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
inst✝³ : IsDomain S
inst✝² : IsDedekindDomain S
inst✝¹ : IsMaximal p
inst✝ : IsPrime P
hP0 : P ≠ ⊥
i : ℕ
hi : i ≤ e
Q : ℕ → Prop :=
  fun i => Module.rank (R ⧸ p) ↥(map (Quotient.mk (P ^ e)) (P ^ i)) = (e - i) • Module.rank (R ⧸ p) (S ⧸ P)
j : ℕ
lt_e : j < e
_le_j : i ≤ j
ih : Q (j + 1)
⊢ Q j

Next tactic:
dsimp only
theorem rank_pow_quot [IsDomain S] [IsDedekindDomain S] [p.IsMaximal] [P.IsPrime] (hP0 : P ≠ ⊥)
    (i : ℕ) (hi : i ≤ e) :
    Module.rank (R ⧸ p) (Ideal.map (Ideal.Quotient.mk (P ^ e)) (P ^ i)) =
      (e - i) • Module.rank (R ⧸ p) (S ⧸ P) := by
-- Porting note: Lean cannot figure out what to prove by itself
  let Q : ℕ → Prop :=
    fun i => Module.rank (R ⧸ p) { x // x ∈ map (Quotient.mk (P ^ e)) (P ^ i) }
      = (e - i) • Module.rank (R ⧸ p) (S ⧸ P)
  refine @Nat.decreasingInduction' Q i e (fun j lt_e _le_j ih => ?_) hi ?_
  · dsimp only
    

Proof state:
case refine_1
R : Type u
inst✝⁵ : CommRing R
S : Type v
inst✝⁴ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
inst✝³ : IsDomain S
inst✝² : IsDedekindDomain S
inst✝¹ : IsMaximal p
inst✝ : IsPrime P
hP0 : P ≠ ⊥
i : ℕ
hi : i ≤ e
Q : ℕ → Prop :=
  fun i => Module.rank (R ⧸ p) ↥(map (Quotient.mk (P ^ e)) (P ^ i)) = (e - i) • Module.rank (R ⧸ p) (S ⧸ P)
j : ℕ
lt_e : j < e
_le_j : i ≤ j
ih : Q (j + 1)
⊢ Module.rank (R ⧸ p) ↥(map (Quotient.mk (P ^ e)) (P ^ j)) = (e - j) • Module.rank (R ⧸ p) (S ⧸ P)

Next tactic:
rw [rank_pow_quot_aux f p P _ lt_e, ih, ← succ_nsmul, Nat.sub_succ, ← Nat.succ_eq_add_one,
      Nat.succ_pred_eq_of_pos (Nat.sub_pos_of_lt lt_e)]