l3lab/ntp-mathlib huggingface dataset:
/-- If `p` is a maximal ideal of `R`, and `S` is the integral closure of `R` in `L`,
then the dimension `[S/pS : R/p]` is equal to `[Frac(S) : Frac(R)]`. -/
theorem finrank_quotient_map [IsDomain R] [IsDomain S] [IsDedekindDomain R] [Algebra K L]
    [Algebra R L] [IsScalarTower R K L] [IsScalarTower R S L] [IsIntegralClosure S R L]
    [hp : p.IsMaximal] [IsNoetherian R S] :
    finrank (R ⧸ p) (S ⧸ map (algebraMap R S) p) = finrank K L := by
  -- Choose an arbitrary basis `b` for `[S/pS : R/p]`.
  -- We'll use the previous results to turn it into a basis on `[Frac(S) : Frac(R)]`.
  letI : Field (R ⧸ p) := Ideal.Quotient.field _
  let ι := Module.Free.ChooseBasisIndex (R ⧸ p) (S ⧸ map (algebraMap R 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
inst✝²⁴ : Algebra R S
K : Type u_1
inst✝²³ : Field K
inst✝²² : Algebra R K
hRK : IsFractionRing R K
L : Type u_2
inst✝²¹ : Field L
inst✝²⁰ : Algebra S L
inst✝¹⁹ : IsFractionRing S L
V : Type u_3
V' : Type u_4
V'' : Type u_5
inst✝¹⁸ : AddCommGroup V
inst✝¹⁷ : Module R V
inst✝¹⁶ : Module K V
inst✝¹⁵ : IsScalarTower R K V
inst✝¹⁴ : AddCommGroup V'
inst✝¹³ : Module R V'
inst✝¹² : Module S V'
inst✝¹¹ : IsScalarTower R S V'
inst✝¹⁰ : AddCommGroup V''
inst✝⁹ : Module R V''
inst✝⁸ : IsDomain R
inst✝⁷ : IsDomain S
inst✝⁶ : IsDedekindDomain R
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra R L
inst✝³ : IsScalarTower R K L
inst✝² : IsScalarTower R S L
inst✝¹ : IsIntegralClosure S R L
hp : IsMaximal p
inst✝ : IsNoetherian R S
this : Field (R ⧸ p) := Quotient.field p
ι : Type v := Module.Free.ChooseBasisIndex (R ⧸ p) (S ⧸ map (algebraMap R S) p)
⊢ finrank (R ⧸ p) (S ⧸ map (algebraMap R S) p) = finrank K L

Next tactic:
let b : Basis ι (R ⧸ p) (S ⧸ map (algebraMap R S) p) := Module.Free.chooseBasis _ _
/-- If `p` is a maximal ideal of `R`, and `S` is the integral closure of `R` in `L`,
then the dimension `[S/pS : R/p]` is equal to `[Frac(S) : Frac(R)]`. -/
theorem finrank_quotient_map [IsDomain R] [IsDomain S] [IsDedekindDomain R] [Algebra K L]
    [Algebra R L] [IsScalarTower R K L] [IsScalarTower R S L] [IsIntegralClosure S R L]
    [hp : p.IsMaximal] [IsNoetherian R S] :
    finrank (R ⧸ p) (S ⧸ map (algebraMap R S) p) = finrank K L := by
  -- Choose an arbitrary basis `b` for `[S/pS : R/p]`.
  -- We'll use the previous results to turn it into a basis on `[Frac(S) : Frac(R)]`.
  letI : Field (R ⧸ p) := Ideal.Quotient.field _
  let ι := Module.Free.ChooseBasisIndex (R ⧸ p) (S ⧸ map (algebraMap R S) p)
  let b : Basis ι (R ⧸ p) (S ⧸ map (algebraMap R S) p) := Module.Free.chooseBasis _ _
  -- Namely, choose a representative `b' i : S` for each `b i : S / pS`.
  

Proof state:
R : Type u
inst✝²⁶ : CommRing R
S : Type v
inst✝²⁵ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
inst✝²⁴ : Algebra R S
K : Type u_1
inst✝²³ : Field K
inst✝²² : Algebra R K
hRK : IsFractionRing R K
L : Type u_2
inst✝²¹ : Field L
inst✝²⁰ : Algebra S L
inst✝¹⁹ : IsFractionRing S L
V : Type u_3
V' : Type u_4
V'' : Type u_5
inst✝¹⁸ : AddCommGroup V
inst✝¹⁷ : Module R V
inst✝¹⁶ : Module K V
inst✝¹⁵ : IsScalarTower R K V
inst✝¹⁴ : AddCommGroup V'
inst✝¹³ : Module R V'
inst✝¹² : Module S V'
inst✝¹¹ : IsScalarTower R S V'
inst✝¹⁰ : AddCommGroup V''
inst✝⁹ : Module R V''
inst✝⁸ : IsDomain R
inst✝⁷ : IsDomain S
inst✝⁶ : IsDedekindDomain R
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra R L
inst✝³ : IsScalarTower R K L
inst✝² : IsScalarTower R S L
inst✝¹ : IsIntegralClosure S R L
hp : IsMaximal p
inst✝ : IsNoetherian R S
this : Field (R ⧸ p) := Quotient.field p
ι : Type v := Module.Free.ChooseBasisIndex (R ⧸ p) (S ⧸ map (algebraMap R S) p)
b : Basis ι (R ⧸ p) (S ⧸ map (algebraMap R S) p) := Module.Free.chooseBasis (R ⧸ p) (S ⧸ map (algebraMap R S) p)
⊢ finrank (R ⧸ p) (S ⧸ map (algebraMap R S) p) = finrank K L

Next tactic:
let b' : ι → S := fun i => (Ideal.Quotient.mk_surjective (b i)).choose
/-- If `p` is a maximal ideal of `R`, and `S` is the integral closure of `R` in `L`,
then the dimension `[S/pS : R/p]` is equal to `[Frac(S) : Frac(R)]`. -/
theorem finrank_quotient_map [IsDomain R] [IsDomain S] [IsDedekindDomain R] [Algebra K L]
    [Algebra R L] [IsScalarTower R K L] [IsScalarTower R S L] [IsIntegralClosure S R L]
    [hp : p.IsMaximal] [IsNoetherian R S] :
    finrank (R ⧸ p) (S ⧸ map (algebraMap R S) p) = finrank K L := by
  -- Choose an arbitrary basis `b` for `[S/pS : R/p]`.
  -- We'll use the previous results to turn it into a basis on `[Frac(S) : Frac(R)]`.
  letI : Field (R ⧸ p) := Ideal.Quotient.field _
  let ι := Module.Free.ChooseBasisIndex (R ⧸ p) (S ⧸ map (algebraMap R S) p)
  let b : Basis ι (R ⧸ p) (S ⧸ map (algebraMap R S) p) := Module.Free.chooseBasis _ _
  -- Namely, choose a representative `b' i : S` for each `b i : S / pS`.
  let b' : ι → S := fun i => (Ideal.Quotient.mk_surjective (b i)).choose
  

Proof state:
R : Type u
inst✝²⁶ : CommRing R
S : Type v
inst✝²⁵ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
inst✝²⁴ : Algebra R S
K : Type u_1
inst✝²³ : Field K
inst✝²² : Algebra R K
hRK : IsFractionRing R K
L : Type u_2
inst✝²¹ : Field L
inst✝²⁰ : Algebra S L
inst✝¹⁹ : IsFractionRing S L
V : Type u_3
V' : Type u_4
V'' : Type u_5
inst✝¹⁸ : AddCommGroup V
inst✝¹⁷ : Module R V
inst✝¹⁶ : Module K V
inst✝¹⁵ : IsScalarTower R K V
inst✝¹⁴ : AddCommGroup V'
inst✝¹³ : Module R V'
inst✝¹² : Module S V'
inst✝¹¹ : IsScalarTower R S V'
inst✝¹⁰ : AddCommGroup V''
inst✝⁹ : Module R V''
inst✝⁸ : IsDomain R
inst✝⁷ : IsDomain S
inst✝⁶ : IsDedekindDomain R
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra R L
inst✝³ : IsScalarTower R K L
inst✝² : IsScalarTower R S L
inst✝¹ : IsIntegralClosure S R L
hp : IsMaximal p
inst✝ : IsNoetherian R S
this : Field (R ⧸ p) := Quotient.field p
ι : Type v := Module.Free.ChooseBasisIndex (R ⧸ p) (S ⧸ map (algebraMap R S) p)
b : Basis ι (R ⧸ p) (S ⧸ map (algebraMap R S) p) := Module.Free.chooseBasis (R ⧸ p) (S ⧸ map (algebraMap R S) p)
b' : ι → S := fun i => Exists.choose (_ : ∃ a, (Quotient.mk (map (algebraMap R S) p)) a = b i)
⊢ finrank (R ⧸ p) (S ⧸ map (algebraMap R S) p) = finrank K L

Next tactic:
have b_eq_b' : ⇑b = (Submodule.mkQ (map (algebraMap R S) p)).restrictScalars R ∘ b' :=
    funext fun i => (Ideal.Quotient.mk_surjective (b i)).choose_spec.symm
/-- If `p` is a maximal ideal of `R`, and `S` is the integral closure of `R` in `L`,
then the dimension `[S/pS : R/p]` is equal to `[Frac(S) : Frac(R)]`. -/
theorem finrank_quotient_map [IsDomain R] [IsDomain S] [IsDedekindDomain R] [Algebra K L]
    [Algebra R L] [IsScalarTower R K L] [IsScalarTower R S L] [IsIntegralClosure S R L]
    [hp : p.IsMaximal] [IsNoetherian R S] :
    finrank (R ⧸ p) (S ⧸ map (algebraMap R S) p) = finrank K L := by
  -- Choose an arbitrary basis `b` for `[S/pS : R/p]`.
  -- We'll use the previous results to turn it into a basis on `[Frac(S) : Frac(R)]`.
  letI : Field (R ⧸ p) := Ideal.Quotient.field _
  let ι := Module.Free.ChooseBasisIndex (R ⧸ p) (S ⧸ map (algebraMap R S) p)
  let b : Basis ι (R ⧸ p) (S ⧸ map (algebraMap R S) p) := Module.Free.chooseBasis _ _
  -- Namely, choose a representative `b' i : S` for each `b i : S / pS`.
  let b' : ι → S := fun i => (Ideal.Quotient.mk_surjective (b i)).choose
  have b_eq_b' : ⇑b = (Submodule.mkQ (map (algebraMap R S) p)).restrictScalars R ∘ b' :=
    funext fun i => (Ideal.Quotient.mk_surjective (b i)).choose_spec.symm
  -- We claim `b'` is a basis for `Frac(S)` over `Frac(R)` because it is linear independent
  -- and spans the whole of `Frac(S)`.
  

Proof state:
R : Type u
inst✝²⁶ : CommRing R
S : Type v
inst✝²⁵ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
inst✝²⁴ : Algebra R S
K : Type u_1
inst✝²³ : Field K
inst✝²² : Algebra R K
hRK : IsFractionRing R K
L : Type u_2
inst✝²¹ : Field L
inst✝²⁰ : Algebra S L
inst✝¹⁹ : IsFractionRing S L
V : Type u_3
V' : Type u_4
V'' : Type u_5
inst✝¹⁸ : AddCommGroup V
inst✝¹⁷ : Module R V
inst✝¹⁶ : Module K V
inst✝¹⁵ : IsScalarTower R K V
inst✝¹⁴ : AddCommGroup V'
inst✝¹³ : Module R V'
inst✝¹² : Module S V'
inst✝¹¹ : IsScalarTower R S V'
inst✝¹⁰ : AddCommGroup V''
inst✝⁹ : Module R V''
inst✝⁸ : IsDomain R
inst✝⁷ : IsDomain S
inst✝⁶ : IsDedekindDomain R
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra R L
inst✝³ : IsScalarTower R K L
inst✝² : IsScalarTower R S L
inst✝¹ : IsIntegralClosure S R L
hp : IsMaximal p
inst✝ : IsNoetherian R S
this : Field (R ⧸ p) := Quotient.field p
ι : Type v := Module.Free.ChooseBasisIndex (R ⧸ p) (S ⧸ map (algebraMap R S) p)
b : Basis ι (R ⧸ p) (S ⧸ map (algebraMap R S) p) := Module.Free.chooseBasis (R ⧸ p) (S ⧸ map (algebraMap R S) p)
b' : ι → S := fun i => Exists.choose (_ : ∃ a, (Quotient.mk (map (algebraMap R S) p)) a = b i)
b_eq_b' : ⇑b = ⇑(↑R (Submodule.mkQ (map (algebraMap R S) p))) ∘ b'
⊢ finrank (R ⧸ p) (S ⧸ map (algebraMap R S) p) = finrank K L

Next tactic:
let b'' : ι → L := algebraMap S L ∘ b'
/-- If `p` is a maximal ideal of `R`, and `S` is the integral closure of `R` in `L`,
then the dimension `[S/pS : R/p]` is equal to `[Frac(S) : Frac(R)]`. -/
theorem finrank_quotient_map [IsDomain R] [IsDomain S] [IsDedekindDomain R] [Algebra K L]
    [Algebra R L] [IsScalarTower R K L] [IsScalarTower R S L] [IsIntegralClosure S R L]
    [hp : p.IsMaximal] [IsNoetherian R S] :
    finrank (R ⧸ p) (S ⧸ map (algebraMap R S) p) = finrank K L := by
  -- Choose an arbitrary basis `b` for `[S/pS : R/p]`.
  -- We'll use the previous results to turn it into a basis on `[Frac(S) : Frac(R)]`.
  letI : Field (R ⧸ p) := Ideal.Quotient.field _
  let ι := Module.Free.ChooseBasisIndex (R ⧸ p) (S ⧸ map (algebraMap R S) p)
  let b : Basis ι (R ⧸ p) (S ⧸ map (algebraMap R S) p) := Module.Free.chooseBasis _ _
  -- Namely, choose a representative `b' i : S` for each `b i : S / pS`.
  let b' : ι → S := fun i => (Ideal.Quotient.mk_surjective (b i)).choose
  have b_eq_b' : ⇑b = (Submodule.mkQ (map (algebraMap R S) p)).restrictScalars R ∘ b' :=
    funext fun i => (Ideal.Quotient.mk_surjective (b i)).choose_spec.symm
  -- We claim `b'` is a basis for `Frac(S)` over `Frac(R)` because it is linear independent
  -- and spans the whole of `Frac(S)`.
  let b'' : ι → L := algebraMap S L ∘ b'
  

Proof state:
R : Type u
inst✝²⁶ : CommRing R
S : Type v
inst✝²⁵ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
inst✝²⁴ : Algebra R S
K : Type u_1
inst✝²³ : Field K
inst✝²² : Algebra R K
hRK : IsFractionRing R K
L : Type u_2
inst✝²¹ : Field L
inst✝²⁰ : Algebra S L
inst✝¹⁹ : IsFractionRing S L
V : Type u_3
V' : Type u_4
V'' : Type u_5
inst✝¹⁸ : AddCommGroup V
inst✝¹⁷ : Module R V
inst✝¹⁶ : Module K V
inst✝¹⁵ : IsScalarTower R K V
inst✝¹⁴ : AddCommGroup V'
inst✝¹³ : Module R V'
inst✝¹² : Module S V'
inst✝¹¹ : IsScalarTower R S V'
inst✝¹⁰ : AddCommGroup V''
inst✝⁹ : Module R V''
inst✝⁸ : IsDomain R
inst✝⁷ : IsDomain S
inst✝⁶ : IsDedekindDomain R
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra R L
inst✝³ : IsScalarTower R K L
inst✝² : IsScalarTower R S L
inst✝¹ : IsIntegralClosure S R L
hp : IsMaximal p
inst✝ : IsNoetherian R S
this : Field (R ⧸ p) := Quotient.field p
ι : Type v := Module.Free.ChooseBasisIndex (R ⧸ p) (S ⧸ map (algebraMap R S) p)
b : Basis ι (R ⧸ p) (S ⧸ map (algebraMap R S) p) := Module.Free.chooseBasis (R ⧸ p) (S ⧸ map (algebraMap R S) p)
b' : ι → S := fun i => Exists.choose (_ : ∃ a, (Quotient.mk (map (algebraMap R S) p)) a = b i)
b_eq_b' : ⇑b = ⇑(↑R (Submodule.mkQ (map (algebraMap R S) p))) ∘ b'
b'' : ι → L := ⇑(algebraMap S L) ∘ b'
⊢ finrank (R ⧸ p) (S ⧸ map (algebraMap R S) p) = finrank K L

Next tactic:
have b''_li : LinearIndependent K b'' := ?_
/-- If `p` is a maximal ideal of `R`, and `S` is the integral closure of `R` in `L`,
then the dimension `[S/pS : R/p]` is equal to `[Frac(S) : Frac(R)]`. -/
theorem finrank_quotient_map [IsDomain R] [IsDomain S] [IsDedekindDomain R] [Algebra K L]
    [Algebra R L] [IsScalarTower R K L] [IsScalarTower R S L] [IsIntegralClosure S R L]
    [hp : p.IsMaximal] [IsNoetherian R S] :
    finrank (R ⧸ p) (S ⧸ map (algebraMap R S) p) = finrank K L := by
  -- Choose an arbitrary basis `b` for `[S/pS : R/p]`.
  -- We'll use the previous results to turn it into a basis on `[Frac(S) : Frac(R)]`.
  letI : Field (R ⧸ p) := Ideal.Quotient.field _
  let ι := Module.Free.ChooseBasisIndex (R ⧸ p) (S ⧸ map (algebraMap R S) p)
  let b : Basis ι (R ⧸ p) (S ⧸ map (algebraMap R S) p) := Module.Free.chooseBasis _ _
  -- Namely, choose a representative `b' i : S` for each `b i : S / pS`.
  let b' : ι → S := fun i => (Ideal.Quotient.mk_surjective (b i)).choose
  have b_eq_b' : ⇑b = (Submodule.mkQ (map (algebraMap R S) p)).restrictScalars R ∘ b' :=
    funext fun i => (Ideal.Quotient.mk_surjective (b i)).choose_spec.symm
  -- We claim `b'` is a basis for `Frac(S)` over `Frac(R)` because it is linear independent
  -- and spans the whole of `Frac(S)`.
  let b'' : ι → L := algebraMap S L ∘ b'
  have b''_li : LinearIndependent K b'' := ?_
  have b''_sp : Submodule.span K (Set.range b'') = ⊤ := ?_
  -- Since the two bases have the same index set, the spaces have the same dimension.
  let c : Basis ι K L := Basis.mk b''_li b''_sp.ge
  rw [finrank_eq_card_basis b, finrank_eq_card_basis c]
  -- It remains to show that the basis is indeed linear independent and spans the whole space.
  · 

Proof state:
case refine_2.refine_1
R : Type u
inst✝²⁶ : CommRing R
S : Type v
inst✝²⁵ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
inst✝²⁴ : Algebra R S
K : Type u_1
inst✝²³ : Field K
inst✝²² : Algebra R K
hRK : IsFractionRing R K
L : Type u_2
inst✝²¹ : Field L
inst✝²⁰ : Algebra S L
inst✝¹⁹ : IsFractionRing S L
V : Type u_3
V' : Type u_4
V'' : Type u_5
inst✝¹⁸ : AddCommGroup V
inst✝¹⁷ : Module R V
inst✝¹⁶ : Module K V
inst✝¹⁵ : IsScalarTower R K V
inst✝¹⁴ : AddCommGroup V'
inst✝¹³ : Module R V'
inst✝¹² : Module S V'
inst✝¹¹ : IsScalarTower R S V'
inst✝¹⁰ : AddCommGroup V''
inst✝⁹ : Module R V''
inst✝⁸ : IsDomain R
inst✝⁷ : IsDomain S
inst✝⁶ : IsDedekindDomain R
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra R L
inst✝³ : IsScalarTower R K L
inst✝² : IsScalarTower R S L
inst✝¹ : IsIntegralClosure S R L
hp : IsMaximal p
inst✝ : IsNoetherian R S
this : Field (R ⧸ p) := Quotient.field p
ι : Type v := Module.Free.ChooseBasisIndex (R ⧸ p) (S ⧸ map (algebraMap R S) p)
b : Basis ι (R ⧸ p) (S ⧸ map (algebraMap R S) p) := Module.Free.chooseBasis (R ⧸ p) (S ⧸ map (algebraMap R S) p)
b' : ι → S := fun i => Exists.choose (_ : ∃ a, (Quotient.mk (map (algebraMap R S) p)) a = b i)
b_eq_b' : ⇑b = ⇑(↑R (Submodule.mkQ (map (algebraMap R S) p))) ∘ b'
b'' : ι → L := ⇑(algebraMap S L) ∘ b'
b''_li : LinearIndependent K b''
⊢ Submodule.span K (Set.range b'') = ⊤

Next tactic:
rw [Set.range_comp]
/-- If `p` is a maximal ideal of `R`, and `S` is the integral closure of `R` in `L`,
then the dimension `[S/pS : R/p]` is equal to `[Frac(S) : Frac(R)]`. -/
theorem finrank_quotient_map [IsDomain R] [IsDomain S] [IsDedekindDomain R] [Algebra K L]
    [Algebra R L] [IsScalarTower R K L] [IsScalarTower R S L] [IsIntegralClosure S R L]
    [hp : p.IsMaximal] [IsNoetherian R S] :
    finrank (R ⧸ p) (S ⧸ map (algebraMap R S) p) = finrank K L := by
  -- Choose an arbitrary basis `b` for `[S/pS : R/p]`.
  -- We'll use the previous results to turn it into a basis on `[Frac(S) : Frac(R)]`.
  letI : Field (R ⧸ p) := Ideal.Quotient.field _
  let ι := Module.Free.ChooseBasisIndex (R ⧸ p) (S ⧸ map (algebraMap R S) p)
  let b : Basis ι (R ⧸ p) (S ⧸ map (algebraMap R S) p) := Module.Free.chooseBasis _ _
  -- Namely, choose a representative `b' i : S` for each `b i : S / pS`.
  let b' : ι → S := fun i => (Ideal.Quotient.mk_surjective (b i)).choose
  have b_eq_b' : ⇑b = (Submodule.mkQ (map (algebraMap R S) p)).restrictScalars R ∘ b' :=
    funext fun i => (Ideal.Quotient.mk_surjective (b i)).choose_spec.symm
  -- We claim `b'` is a basis for `Frac(S)` over `Frac(R)` because it is linear independent
  -- and spans the whole of `Frac(S)`.
  let b'' : ι → L := algebraMap S L ∘ b'
  have b''_li : LinearIndependent K b'' := ?_
  have b''_sp : Submodule.span K (Set.range b'') = ⊤ := ?_
  -- Since the two bases have the same index set, the spaces have the same dimension.
  let c : Basis ι K L := Basis.mk b''_li b''_sp.ge
  rw [finrank_eq_card_basis b, finrank_eq_card_basis c]
  -- It remains to show that the basis is indeed linear independent and spans the whole space.
  · rw [Set.range_comp]
    

Proof state:
case refine_2.refine_1
R : Type u
inst✝²⁶ : CommRing R
S : Type v
inst✝²⁵ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
inst✝²⁴ : Algebra R S
K : Type u_1
inst✝²³ : Field K
inst✝²² : Algebra R K
hRK : IsFractionRing R K
L : Type u_2
inst✝²¹ : Field L
inst✝²⁰ : Algebra S L
inst✝¹⁹ : IsFractionRing S L
V : Type u_3
V' : Type u_4
V'' : Type u_5
inst✝¹⁸ : AddCommGroup V
inst✝¹⁷ : Module R V
inst✝¹⁶ : Module K V
inst✝¹⁵ : IsScalarTower R K V
inst✝¹⁴ : AddCommGroup V'
inst✝¹³ : Module R V'
inst✝¹² : Module S V'
inst✝¹¹ : IsScalarTower R S V'
inst✝¹⁰ : AddCommGroup V''
inst✝⁹ : Module R V''
inst✝⁸ : IsDomain R
inst✝⁷ : IsDomain S
inst✝⁶ : IsDedekindDomain R
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra R L
inst✝³ : IsScalarTower R K L
inst✝² : IsScalarTower R S L
inst✝¹ : IsIntegralClosure S R L
hp : IsMaximal p
inst✝ : IsNoetherian R S
this : Field (R ⧸ p) := Quotient.field p
ι : Type v := Module.Free.ChooseBasisIndex (R ⧸ p) (S ⧸ map (algebraMap R S) p)
b : Basis ι (R ⧸ p) (S ⧸ map (algebraMap R S) p) := Module.Free.chooseBasis (R ⧸ p) (S ⧸ map (algebraMap R S) p)
b' : ι → S := fun i => Exists.choose (_ : ∃ a, (Quotient.mk (map (algebraMap R S) p)) a = b i)
b_eq_b' : ⇑b = ⇑(↑R (Submodule.mkQ (map (algebraMap R S) p))) ∘ b'
b'' : ι → L := ⇑(algebraMap S L) ∘ b'
b''_li : LinearIndependent K b''
⊢ Submodule.span K (⇑(algebraMap S L) '' Set.range b') = ⊤

Next tactic:
refine FinrankQuotientMap.span_eq_top p hp.ne_top _ (top_le_iff.mp ?_)
theorem powQuotSuccInclusion_injective (i : ℕ) :
    Function.Injective (powQuotSuccInclusion f p P i) := 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
i : ℕ
⊢ Function.Injective ⇑(powQuotSuccInclusion f p P i)

Next tactic:
rw [← LinearMap.ker_eq_bot, LinearMap.ker_eq_bot']
theorem powQuotSuccInclusion_injective (i : ℕ) :
    Function.Injective (powQuotSuccInclusion f p P i) := by
  rw [← LinearMap.ker_eq_bot, LinearMap.ker_eq_bot']
  

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
i : ℕ
⊢ ∀ (m : ↥(map (Quotient.mk (P ^ e)) (P ^ (i + 1)))), (powQuotSuccInclusion f p P i) m = 0 → m = 0

Next tactic:
rintro ⟨x, hx⟩ hx0
theorem powQuotSuccInclusion_injective (i : ℕ) :
    Function.Injective (powQuotSuccInclusion f p P i) := by
  rw [← LinearMap.ker_eq_bot, LinearMap.ker_eq_bot']
  rintro ⟨x, hx⟩ hx0
  

Proof state:
case mk
R : Type u
inst✝¹ : CommRing R
S : Type v
inst✝ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
i : ℕ
x : S ⧸ P ^ e
hx : x ∈ map (Quotient.mk (P ^ e)) (P ^ (i + 1))
hx0 : (powQuotSuccInclusion f p P i) { val := x, property := hx } = 0
⊢ { val := x, property := hx } = 0

Next tactic:
rw [Subtype.ext_iff] at hx0 ⊢
theorem powQuotSuccInclusion_injective (i : ℕ) :
    Function.Injective (powQuotSuccInclusion f p P i) := by
  rw [← LinearMap.ker_eq_bot, LinearMap.ker_eq_bot']
  rintro ⟨x, hx⟩ hx0
  rw [Subtype.ext_iff] at hx0 ⊢
  

Proof state:
case mk
R : Type u
inst✝¹ : CommRing R
S : Type v
inst✝ : CommRing S
f : R →+* S
p : Ideal R
P : Ideal S
hfp : NeZero e
i : ℕ
x : S ⧸ P ^ e
hx : x ∈ map (Quotient.mk (P ^ e)) (P ^ (i + 1))
hx0 : ↑((powQuotSuccInclusion f p P i) { val := x, property := hx }) = ↑0
⊢ ↑{ val := x, property := hx } = ↑0

Next tactic:
rwa [powQuotSuccInclusion_apply_coe] at hx0
/-- `S ⧸ P` embeds into the quotient by `P^(i+1) ⧸ P^e` as a subspace of `P^i ⧸ P^e`.
See `quotientToQuotientRangePowQuotSucc` for this as a linear map,
and `quotientRangePowQuotSuccInclusionEquiv` for this as a linear equivalence.
-/
noncomputable def quotientToQuotientRangePowQuotSuccAux {i : ℕ} {a : S} (a_mem : a ∈ P ^ i) :
    S ⧸ P →
      (P ^ i).map (Ideal.Quotient.mk (P ^ e)) ⧸ LinearMap.range (powQuotSuccInclusion f p P i) :=
  Quotient.map' (fun x : S => ⟨_, Ideal.mem_map_of_mem _ (Ideal.mul_mem_left _ x a_mem)⟩)
    fun x y h => 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
i : ℕ
a : S
a_mem : a ∈ P ^ i
x y : S
h : Setoid.r x y
⊢ Setoid.r
    ((fun x =>
        { val := (Quotient.mk (P ^ e)) (x * a),
          property := (_ : (Quotient.mk (P ^ e)) (x * a) ∈ map (Quotient.mk (P ^ e)) (P ^ i)) })
      x)
    ((fun x =>
        { val := (Quotient.mk (P ^ e)) (x * a),
          property := (_ : (Quotient.mk (P ^ e)) (x * a) ∈ map (Quotient.mk (P ^ e)) (P ^ i)) })
      y)

Next tactic:
rw [Submodule.quotientRel_r_def] at h ⊢
/-- `S ⧸ P` embeds into the quotient by `P^(i+1) ⧸ P^e` as a subspace of `P^i ⧸ P^e`.
See `quotientToQuotientRangePowQuotSucc` for this as a linear map,
and `quotientRangePowQuotSuccInclusionEquiv` for this as a linear equivalence.
-/
noncomputable def quotientToQuotientRangePowQuotSuccAux {i : ℕ} {a : S} (a_mem : a ∈ P ^ i) :
    S ⧸ P →
      (P ^ i).map (Ideal.Quotient.mk (P ^ e)) ⧸ LinearMap.range (powQuotSuccInclusion f p P i) :=
  Quotient.map' (fun x : S => ⟨_, Ideal.mem_map_of_mem _ (Ideal.mul_mem_left _ x a_mem)⟩)
    fun x y h => by
    rw [Submodule.quotientRel_r_def] at h ⊢
    

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
i : ℕ
a : S
a_mem : a ∈ P ^ i
x y : S
h : x - y ∈ P
⊢ (fun x =>
          { val := (Quotient.mk (P ^ e)) (x * a),
            property := (_ : (Quotient.mk (P ^ e)) (x * a) ∈ map (Quotient.mk (P ^ e)) (P ^ i)) })
        x -
      (fun x =>
          { val := (Quotient.mk (P ^ e)) (x * a),
            property := (_ : (Quotient.mk (P ^ e)) (x * a) ∈ map (Quotient.mk (P ^ e)) (P ^ i)) })
        y ∈
    LinearMap.range (powQuotSuccInclusion f p P i)

Next tactic:
simp only [_root_.map_mul, LinearMap.mem_range]
/-- `S ⧸ P` embeds into the quotient by `P^(i+1) ⧸ P^e` as a subspace of `P^i ⧸ P^e`.
See `quotientToQuotientRangePowQuotSucc` for this as a linear map,
and `quotientRangePowQuotSuccInclusionEquiv` for this as a linear equivalence.
-/
noncomputable def quotientToQuotientRangePowQuotSuccAux {i : ℕ} {a : S} (a_mem : a ∈ P ^ i) :
    S ⧸ P →
      (P ^ i).map (Ideal.Quotient.mk (P ^ e)) ⧸ LinearMap.range (powQuotSuccInclusion f p P i) :=
  Quotient.map' (fun x : S => ⟨_, Ideal.mem_map_of_mem _ (Ideal.mul_mem_left _ x a_mem)⟩)
    fun x y h => by
    rw [Submodule.quotientRel_r_def] at h ⊢
    simp only [_root_.map_mul, LinearMap.mem_range]
    

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
i : ℕ
a : S
a_mem : a ∈ P ^ i
x y : S
h : x - y ∈ P
⊢ ∃ y_1,
    (powQuotSuccInclusion f p P i) y_1 =
      { val := (Quotient.mk (P ^ e)) x * (Quotient.mk (P ^ e)) a,
          property :=
            (_ :
              (fun x => x ∈ map (Quotient.mk (P ^ e)) (P ^ i)) ((Quotient.mk (P ^ e)) x * (Quotient.mk (P ^ e)) a)) } -
        { val := (Quotient.mk (P ^ e)) y * (Quotient.mk (P ^ e)) a,
          property :=
            (_ : (fun x => x ∈ map (Quotient.mk (P ^ e)) (P ^ i)) ((Quotient.mk (P ^ e)) y * (Quotient.mk (P ^ e)) a)) }

Next tactic:
refine' ⟨⟨_, Ideal.mem_map_of_mem _ (Ideal.mul_mem_mul h a_mem)⟩, _⟩