l3lab/ntp-mathlib huggingface dataset:
theorem _root_.IntermediateField.AdjoinSimple.norm_gen_eq_prod_roots (x : L)
    (hf : (minpoly K x).Splits (algebraMap K F)) :
    (algebraMap K F) (norm K (AdjoinSimple.gen K x)) =
      ((minpoly K x).aroots F).prod := by
  have injKxL := (algebraMap K⟮x⟯ L).injective
  by_cases hx : IsIntegral K x; swap
  · simp [minpoly.eq_zero hx, IntermediateField.AdjoinSimple.norm_gen_eq_one hx, aroots_def]
  rw [← adjoin.powerBasis_gen hx, PowerBasis.norm_gen_eq_prod_roots] <;>
    

Proof state:
case pos.hf
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Ring S
inst✝⁵ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field F
inst✝¹ : Algebra K L
inst✝ : Algebra K F
ι : Type w
x : L
hf : Splits (algebraMap K F) (minpoly K x)
injKxL : Function.Injective ⇑(algebraMap (↥K⟮x⟯) L)
hx : IsIntegral K x
⊢ Splits (algebraMap K F) (minpoly K (adjoin.powerBasis hx).gen)

Next tactic:
rw [adjoin.powerBasis_gen hx, ← minpoly.algebraMap_eq injKxL]
theorem _root_.IntermediateField.AdjoinSimple.norm_gen_eq_prod_roots (x : L)
    (hf : (minpoly K x).Splits (algebraMap K F)) :
    (algebraMap K F) (norm K (AdjoinSimple.gen K x)) =
      ((minpoly K x).aroots F).prod := by
  have injKxL := (algebraMap K⟮x⟯ L).injective
  by_cases hx : IsIntegral K x; swap
  · simp [minpoly.eq_zero hx, IntermediateField.AdjoinSimple.norm_gen_eq_one hx, aroots_def]
  rw [← adjoin.powerBasis_gen hx, PowerBasis.norm_gen_eq_prod_roots] <;>
    rw [adjoin.powerBasis_gen hx, ← minpoly.algebraMap_eq injKxL] <;>
    

Proof state:
case pos
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Ring S
inst✝⁵ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field F
inst✝¹ : Algebra K L
inst✝ : Algebra K F
ι : Type w
x : L
hf : Splits (algebraMap K F) (minpoly K x)
injKxL : Function.Injective ⇑(algebraMap (↥K⟮x⟯) L)
hx : IsIntegral K x
⊢ Multiset.prod (aroots (minpoly K ((algebraMap (↥K⟮x⟯) L) (AdjoinSimple.gen K x))) F) =
    Multiset.prod (aroots (minpoly K x) F)

Next tactic:
try simp only [AdjoinSimple.algebraMap_gen _ _]
theorem _root_.IntermediateField.AdjoinSimple.norm_gen_eq_prod_roots (x : L)
    (hf : (minpoly K x).Splits (algebraMap K F)) :
    (algebraMap K F) (norm K (AdjoinSimple.gen K x)) =
      ((minpoly K x).aroots F).prod := by
  have injKxL := (algebraMap K⟮x⟯ L).injective
  by_cases hx : IsIntegral K x; swap
  · simp [minpoly.eq_zero hx, IntermediateField.AdjoinSimple.norm_gen_eq_one hx, aroots_def]
  rw [← adjoin.powerBasis_gen hx, PowerBasis.norm_gen_eq_prod_roots] <;>
    rw [adjoin.powerBasis_gen hx, ← minpoly.algebraMap_eq injKxL] <;>
    try 

Proof state:
case pos
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Ring S
inst✝⁵ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field F
inst✝¹ : Algebra K L
inst✝ : Algebra K F
ι : Type w
x : L
hf : Splits (algebraMap K F) (minpoly K x)
injKxL : Function.Injective ⇑(algebraMap (↥K⟮x⟯) L)
hx : IsIntegral K x
⊢ Multiset.prod (aroots (minpoly K ((algebraMap (↥K⟮x⟯) L) (AdjoinSimple.gen K x))) F) =
    Multiset.prod (aroots (minpoly K x) F)

Next tactic:
simp only [AdjoinSimple.algebraMap_gen _ _]
theorem _root_.IntermediateField.AdjoinSimple.norm_gen_eq_prod_roots (x : L)
    (hf : (minpoly K x).Splits (algebraMap K F)) :
    (algebraMap K F) (norm K (AdjoinSimple.gen K x)) =
      ((minpoly K x).aroots F).prod := by
  have injKxL := (algebraMap K⟮x⟯ L).injective
  by_cases hx : IsIntegral K x; swap
  · simp [minpoly.eq_zero hx, IntermediateField.AdjoinSimple.norm_gen_eq_one hx, aroots_def]
  rw [← adjoin.powerBasis_gen hx, PowerBasis.norm_gen_eq_prod_roots] <;>
    rw [adjoin.powerBasis_gen hx, ← minpoly.algebraMap_eq injKxL] <;>
    

Proof state:
case pos.hf
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Ring S
inst✝⁵ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field F
inst✝¹ : Algebra K L
inst✝ : Algebra K F
ι : Type w
x : L
hf : Splits (algebraMap K F) (minpoly K x)
injKxL : Function.Injective ⇑(algebraMap (↥K⟮x⟯) L)
hx : IsIntegral K x
⊢ Splits (algebraMap K F) (minpoly K ((algebraMap (↥K⟮x⟯) L) (AdjoinSimple.gen K x)))

Next tactic:
try simp only [AdjoinSimple.algebraMap_gen _ _]
theorem _root_.IntermediateField.AdjoinSimple.norm_gen_eq_prod_roots (x : L)
    (hf : (minpoly K x).Splits (algebraMap K F)) :
    (algebraMap K F) (norm K (AdjoinSimple.gen K x)) =
      ((minpoly K x).aroots F).prod := by
  have injKxL := (algebraMap K⟮x⟯ L).injective
  by_cases hx : IsIntegral K x; swap
  · simp [minpoly.eq_zero hx, IntermediateField.AdjoinSimple.norm_gen_eq_one hx, aroots_def]
  rw [← adjoin.powerBasis_gen hx, PowerBasis.norm_gen_eq_prod_roots] <;>
    rw [adjoin.powerBasis_gen hx, ← minpoly.algebraMap_eq injKxL] <;>
    try 

Proof state:
case pos.hf
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Ring S
inst✝⁵ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field F
inst✝¹ : Algebra K L
inst✝ : Algebra K F
ι : Type w
x : L
hf : Splits (algebraMap K F) (minpoly K x)
injKxL : Function.Injective ⇑(algebraMap (↥K⟮x⟯) L)
hx : IsIntegral K x
⊢ Splits (algebraMap K F) (minpoly K ((algebraMap (↥K⟮x⟯) L) (AdjoinSimple.gen K x)))

Next tactic:
simp only [AdjoinSimple.algebraMap_gen _ _]
theorem _root_.IntermediateField.AdjoinSimple.norm_gen_eq_prod_roots (x : L)
    (hf : (minpoly K x).Splits (algebraMap K F)) :
    (algebraMap K F) (norm K (AdjoinSimple.gen K x)) =
      ((minpoly K x).aroots F).prod := by
  have injKxL := (algebraMap K⟮x⟯ L).injective
  by_cases hx : IsIntegral K x; swap
  · simp [minpoly.eq_zero hx, IntermediateField.AdjoinSimple.norm_gen_eq_one hx, aroots_def]
  rw [← adjoin.powerBasis_gen hx, PowerBasis.norm_gen_eq_prod_roots] <;>
    rw [adjoin.powerBasis_gen hx, ← minpoly.algebraMap_eq injKxL] <;>
    try simp only [AdjoinSimple.algebraMap_gen _ _]
  

Proof state:
case pos.hf
R : Type u_1
S : Type u_2
T : Type u_3
inst✝⁷ : CommRing R
inst✝⁶ : Ring S
inst✝⁵ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁴ : Field K
inst✝³ : Field L
inst✝² : Field F
inst✝¹ : Algebra K L
inst✝ : Algebra K F
ι : Type w
x : L
hf : Splits (algebraMap K F) (minpoly K x)
injKxL : Function.Injective ⇑(algebraMap (↥K⟮x⟯) L)
hx : IsIntegral K x
⊢ Splits (algebraMap K F) (minpoly K x)

Next tactic:
exact hf
theorem norm_eq_prod_embeddings_gen [Algebra R F] (pb : PowerBasis R S)
    (hE : (minpoly R pb.gen).Splits (algebraMap R F)) (hfx : (minpoly R pb.gen).Separable) :
    algebraMap R F (norm R pb.gen) =
      (@Finset.univ _ (PowerBasis.AlgHom.fintype pb)).prod fun σ => σ pb.gen := by
  

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : Ring S
inst✝⁸ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁷ : Field K
inst✝⁶ : Field L
inst✝⁵ : Field F
inst✝⁴ : Algebra K L
inst✝³ : Algebra K F
ι : Type w
E : Type u_7
inst✝² : Field E
inst✝¹ : Algebra K E
inst✝ : Algebra R F
pb : PowerBasis R S
hE : Splits (algebraMap R F) (minpoly R pb.gen)
hfx : Separable (minpoly R pb.gen)
⊢ (algebraMap R F) ((norm R) pb.gen) = ∏ σ : S →ₐ[R] F, σ pb.gen

Next tactic:
letI := Classical.decEq F
theorem norm_eq_prod_embeddings_gen [Algebra R F] (pb : PowerBasis R S)
    (hE : (minpoly R pb.gen).Splits (algebraMap R F)) (hfx : (minpoly R pb.gen).Separable) :
    algebraMap R F (norm R pb.gen) =
      (@Finset.univ _ (PowerBasis.AlgHom.fintype pb)).prod fun σ => σ pb.gen := by
  letI := Classical.decEq F
  

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : Ring S
inst✝⁸ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁷ : Field K
inst✝⁶ : Field L
inst✝⁵ : Field F
inst✝⁴ : Algebra K L
inst✝³ : Algebra K F
ι : Type w
E : Type u_7
inst✝² : Field E
inst✝¹ : Algebra K E
inst✝ : Algebra R F
pb : PowerBasis R S
hE : Splits (algebraMap R F) (minpoly R pb.gen)
hfx : Separable (minpoly R pb.gen)
this : DecidableEq F := Classical.decEq F
⊢ (algebraMap R F) ((norm R) pb.gen) = ∏ σ : S →ₐ[R] F, σ pb.gen

Next tactic:
rw [PowerBasis.norm_gen_eq_prod_roots pb hE]
theorem norm_eq_prod_embeddings_gen [Algebra R F] (pb : PowerBasis R S)
    (hE : (minpoly R pb.gen).Splits (algebraMap R F)) (hfx : (minpoly R pb.gen).Separable) :
    algebraMap R F (norm R pb.gen) =
      (@Finset.univ _ (PowerBasis.AlgHom.fintype pb)).prod fun σ => σ pb.gen := by
  letI := Classical.decEq F
  rw [PowerBasis.norm_gen_eq_prod_roots pb hE]
  

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : Ring S
inst✝⁸ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁷ : Field K
inst✝⁶ : Field L
inst✝⁵ : Field F
inst✝⁴ : Algebra K L
inst✝³ : Algebra K F
ι : Type w
E : Type u_7
inst✝² : Field E
inst✝¹ : Algebra K E
inst✝ : Algebra R F
pb : PowerBasis R S
hE : Splits (algebraMap R F) (minpoly R pb.gen)
hfx : Separable (minpoly R pb.gen)
this : DecidableEq F := Classical.decEq F
⊢ Multiset.prod (aroots (minpoly R pb.gen) F) = ∏ σ : S →ₐ[R] F, σ pb.gen

Next tactic:
rw [@Fintype.prod_equiv (S →ₐ[R] F) _ _ (PowerBasis.AlgHom.fintype pb) _ _ pb.liftEquiv'
    (fun σ => σ pb.gen) (fun x => x) ?_]
theorem norm_eq_prod_embeddings_gen [Algebra R F] (pb : PowerBasis R S)
    (hE : (minpoly R pb.gen).Splits (algebraMap R F)) (hfx : (minpoly R pb.gen).Separable) :
    algebraMap R F (norm R pb.gen) =
      (@Finset.univ _ (PowerBasis.AlgHom.fintype pb)).prod fun σ => σ pb.gen := by
  letI := Classical.decEq F
  rw [PowerBasis.norm_gen_eq_prod_roots pb hE]
  rw [@Fintype.prod_equiv (S →ₐ[R] F) _ _ (PowerBasis.AlgHom.fintype pb) _ _ pb.liftEquiv'
    (fun σ => σ pb.gen) (fun x => x) ?_]
  

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : Ring S
inst✝⁸ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁷ : Field K
inst✝⁶ : Field L
inst✝⁵ : Field F
inst✝⁴ : Algebra K L
inst✝³ : Algebra K F
ι : Type w
E : Type u_7
inst✝² : Field E
inst✝¹ : Algebra K E
inst✝ : Algebra R F
pb : PowerBasis R S
hE : Splits (algebraMap R F) (minpoly R pb.gen)
hfx : Separable (minpoly R pb.gen)
this : DecidableEq F := Classical.decEq F
⊢ Multiset.prod (aroots (minpoly R pb.gen) F) = ∏ x : { y // y ∈ aroots (minpoly R pb.gen) F }, ↑x
R : Type u_1
S : Type u_2
T : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : Ring S
inst✝⁸ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁷ : Field K
inst✝⁶ : Field L
inst✝⁵ : Field F
inst✝⁴ : Algebra K L
inst✝³ : Algebra K F
ι : Type w
E : Type u_7
inst✝² : Field E
inst✝¹ : Algebra K E
inst✝ : Algebra R F
pb : PowerBasis R S
hE : Splits (algebraMap R F) (minpoly R pb.gen)
hfx : Separable (minpoly R pb.gen)
this : DecidableEq F := Classical.decEq F
⊢ ∀ (x : S →ₐ[R] F), (fun σ => σ pb.gen) x = (fun x => ↑x) ((PowerBasis.liftEquiv' pb) x)

Next tactic:
rw [Finset.prod_mem_multiset, Finset.prod_eq_multiset_prod, Multiset.toFinset_val,
    Multiset.dedup_eq_self.mpr, Multiset.map_id]
theorem norm_eq_prod_embeddings_gen [Algebra R F] (pb : PowerBasis R S)
    (hE : (minpoly R pb.gen).Splits (algebraMap R F)) (hfx : (minpoly R pb.gen).Separable) :
    algebraMap R F (norm R pb.gen) =
      (@Finset.univ _ (PowerBasis.AlgHom.fintype pb)).prod fun σ => σ pb.gen := by
  letI := Classical.decEq F
  rw [PowerBasis.norm_gen_eq_prod_roots pb hE]
  rw [@Fintype.prod_equiv (S →ₐ[R] F) _ _ (PowerBasis.AlgHom.fintype pb) _ _ pb.liftEquiv'
    (fun σ => σ pb.gen) (fun x => x) ?_]
  rw [Finset.prod_mem_multiset, Finset.prod_eq_multiset_prod, Multiset.toFinset_val,
    Multiset.dedup_eq_self.mpr, Multiset.map_id]
  · 

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : Ring S
inst✝⁸ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁷ : Field K
inst✝⁶ : Field L
inst✝⁵ : Field F
inst✝⁴ : Algebra K L
inst✝³ : Algebra K F
ι : Type w
E : Type u_7
inst✝² : Field E
inst✝¹ : Algebra K E
inst✝ : Algebra R F
pb : PowerBasis R S
hE : Splits (algebraMap R F) (minpoly R pb.gen)
hfx : Separable (minpoly R pb.gen)
this : DecidableEq F := Classical.decEq F
⊢ Multiset.Nodup (aroots (minpoly R pb.gen) F)

Next tactic:
exact nodup_roots hfx.map
theorem norm_eq_prod_embeddings_gen [Algebra R F] (pb : PowerBasis R S)
    (hE : (minpoly R pb.gen).Splits (algebraMap R F)) (hfx : (minpoly R pb.gen).Separable) :
    algebraMap R F (norm R pb.gen) =
      (@Finset.univ _ (PowerBasis.AlgHom.fintype pb)).prod fun σ => σ pb.gen := by
  letI := Classical.decEq F
  rw [PowerBasis.norm_gen_eq_prod_roots pb hE]
  rw [@Fintype.prod_equiv (S →ₐ[R] F) _ _ (PowerBasis.AlgHom.fintype pb) _ _ pb.liftEquiv'
    (fun σ => σ pb.gen) (fun x => x) ?_]
  rw [Finset.prod_mem_multiset, Finset.prod_eq_multiset_prod, Multiset.toFinset_val,
    Multiset.dedup_eq_self.mpr, Multiset.map_id]
  · exact nodup_roots hfx.map
  · 

Proof state:
case hfg
R : Type u_1
S : Type u_2
T : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : Ring S
inst✝⁸ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁷ : Field K
inst✝⁶ : Field L
inst✝⁵ : Field F
inst✝⁴ : Algebra K L
inst✝³ : Algebra K F
ι : Type w
E : Type u_7
inst✝² : Field E
inst✝¹ : Algebra K E
inst✝ : Algebra R F
pb : PowerBasis R S
hE : Splits (algebraMap R F) (minpoly R pb.gen)
hfx : Separable (minpoly R pb.gen)
this : DecidableEq F := Classical.decEq F
⊢ ∀ (x : { x // x ∈ aroots (minpoly R pb.gen) F }), ↑x = _root_.id ↑x

Next tactic:
intro x
theorem norm_eq_prod_embeddings_gen [Algebra R F] (pb : PowerBasis R S)
    (hE : (minpoly R pb.gen).Splits (algebraMap R F)) (hfx : (minpoly R pb.gen).Separable) :
    algebraMap R F (norm R pb.gen) =
      (@Finset.univ _ (PowerBasis.AlgHom.fintype pb)).prod fun σ => σ pb.gen := by
  letI := Classical.decEq F
  rw [PowerBasis.norm_gen_eq_prod_roots pb hE]
  rw [@Fintype.prod_equiv (S →ₐ[R] F) _ _ (PowerBasis.AlgHom.fintype pb) _ _ pb.liftEquiv'
    (fun σ => σ pb.gen) (fun x => x) ?_]
  rw [Finset.prod_mem_multiset, Finset.prod_eq_multiset_prod, Multiset.toFinset_val,
    Multiset.dedup_eq_self.mpr, Multiset.map_id]
  · exact nodup_roots hfx.map
  · intro x; 

Proof state:
case hfg
R : Type u_1
S : Type u_2
T : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : Ring S
inst✝⁸ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁷ : Field K
inst✝⁶ : Field L
inst✝⁵ : Field F
inst✝⁴ : Algebra K L
inst✝³ : Algebra K F
ι : Type w
E : Type u_7
inst✝² : Field E
inst✝¹ : Algebra K E
inst✝ : Algebra R F
pb : PowerBasis R S
hE : Splits (algebraMap R F) (minpoly R pb.gen)
hfx : Separable (minpoly R pb.gen)
this : DecidableEq F := Classical.decEq F
x : { x // x ∈ aroots (minpoly R pb.gen) F }
⊢ ↑x = _root_.id ↑x

Next tactic:
rfl
theorem norm_eq_prod_embeddings_gen [Algebra R F] (pb : PowerBasis R S)
    (hE : (minpoly R pb.gen).Splits (algebraMap R F)) (hfx : (minpoly R pb.gen).Separable) :
    algebraMap R F (norm R pb.gen) =
      (@Finset.univ _ (PowerBasis.AlgHom.fintype pb)).prod fun σ => σ pb.gen := by
  letI := Classical.decEq F
  rw [PowerBasis.norm_gen_eq_prod_roots pb hE]
  rw [@Fintype.prod_equiv (S →ₐ[R] F) _ _ (PowerBasis.AlgHom.fintype pb) _ _ pb.liftEquiv'
    (fun σ => σ pb.gen) (fun x => x) ?_]
  rw [Finset.prod_mem_multiset, Finset.prod_eq_multiset_prod, Multiset.toFinset_val,
    Multiset.dedup_eq_self.mpr, Multiset.map_id]
  · exact nodup_roots hfx.map
  · intro x; rfl
  · 

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : Ring S
inst✝⁸ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁷ : Field K
inst✝⁶ : Field L
inst✝⁵ : Field F
inst✝⁴ : Algebra K L
inst✝³ : Algebra K F
ι : Type w
E : Type u_7
inst✝² : Field E
inst✝¹ : Algebra K E
inst✝ : Algebra R F
pb : PowerBasis R S
hE : Splits (algebraMap R F) (minpoly R pb.gen)
hfx : Separable (minpoly R pb.gen)
this : DecidableEq F := Classical.decEq F
⊢ ∀ (x : S →ₐ[R] F), (fun σ => σ pb.gen) x = (fun x => ↑x) ((PowerBasis.liftEquiv' pb) x)

Next tactic:
intro σ
theorem norm_eq_prod_embeddings_gen [Algebra R F] (pb : PowerBasis R S)
    (hE : (minpoly R pb.gen).Splits (algebraMap R F)) (hfx : (minpoly R pb.gen).Separable) :
    algebraMap R F (norm R pb.gen) =
      (@Finset.univ _ (PowerBasis.AlgHom.fintype pb)).prod fun σ => σ pb.gen := by
  letI := Classical.decEq F
  rw [PowerBasis.norm_gen_eq_prod_roots pb hE]
  rw [@Fintype.prod_equiv (S →ₐ[R] F) _ _ (PowerBasis.AlgHom.fintype pb) _ _ pb.liftEquiv'
    (fun σ => σ pb.gen) (fun x => x) ?_]
  rw [Finset.prod_mem_multiset, Finset.prod_eq_multiset_prod, Multiset.toFinset_val,
    Multiset.dedup_eq_self.mpr, Multiset.map_id]
  · exact nodup_roots hfx.map
  · intro x; rfl
  · intro σ; 

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝¹⁰ : CommRing R
inst✝⁹ : Ring S
inst✝⁸ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁷ : Field K
inst✝⁶ : Field L
inst✝⁵ : Field F
inst✝⁴ : Algebra K L
inst✝³ : Algebra K F
ι : Type w
E : Type u_7
inst✝² : Field E
inst✝¹ : Algebra K E
inst✝ : Algebra R F
pb : PowerBasis R S
hE : Splits (algebraMap R F) (minpoly R pb.gen)
hfx : Separable (minpoly R pb.gen)
this : DecidableEq F := Classical.decEq F
σ : S →ₐ[R] F
⊢ (fun σ => σ pb.gen) σ = (fun x => ↑x) ((PowerBasis.liftEquiv' pb) σ)

Next tactic:
simp only [PowerBasis.liftEquiv'_apply_coe]
theorem norm_eq_prod_roots [IsSeparable K L] [FiniteDimensional K L] {x : L}
    (hF : (minpoly K x).Splits (algebraMap K F)) :
    algebraMap K F (norm K x) =
      ((minpoly K x).aroots F).prod ^ finrank K⟮x⟯ L := by
  

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝¹¹ : CommRing R
inst✝¹⁰ : Ring S
inst✝⁹ : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝⁸ : Field K
inst✝⁷ : Field L
inst✝⁶ : Field F
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra K F
ι : Type w
E : Type u_7
inst✝³ : Field E
inst✝² : Algebra K E
inst✝¹ : IsSeparable K L
inst✝ : FiniteDimensional K L
x : L
hF : Splits (algebraMap K F) (minpoly K x)
⊢ (algebraMap K F) ((norm K) x) = Multiset.prod (aroots (minpoly K x) F) ^ finrank (↥K⟮x⟯) L

Next tactic:
rw [norm_eq_norm_adjoin K x, map_pow, IntermediateField.AdjoinSimple.norm_gen_eq_prod_roots _ hF]
theorem prod_embeddings_eq_finrank_pow [Algebra L F] [IsScalarTower K L F] [IsAlgClosed E]
    [IsSeparable K F] [FiniteDimensional K F] (pb : PowerBasis K L) :
    ∏ σ : F →ₐ[K] E, σ (algebraMap L F pb.gen) =
      ((@Finset.univ _ (PowerBasis.AlgHom.fintype pb)).prod
        fun σ : L →ₐ[K] E => σ pb.gen) ^ finrank L F := by
  

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝¹⁴ : CommRing R
inst✝¹³ : Ring S
inst✝¹² : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝¹¹ : Field K
inst✝¹⁰ : Field L
inst✝⁹ : Field F
inst✝⁸ : Algebra K L
inst✝⁷ : Algebra K F
ι : Type w
E : Type u_7
inst✝⁶ : Field E
inst✝⁵ : Algebra K E
inst✝⁴ : Algebra L F
inst✝³ : IsScalarTower K L F
inst✝² : IsAlgClosed E
inst✝¹ : IsSeparable K F
inst✝ : FiniteDimensional K F
pb : PowerBasis K L
⊢ ∏ σ : F →ₐ[K] E, σ ((algebraMap L F) pb.gen) = (∏ σ : L →ₐ[K] E, σ pb.gen) ^ finrank L F

Next tactic:
haveI : FiniteDimensional L F := FiniteDimensional.right K L F
theorem prod_embeddings_eq_finrank_pow [Algebra L F] [IsScalarTower K L F] [IsAlgClosed E]
    [IsSeparable K F] [FiniteDimensional K F] (pb : PowerBasis K L) :
    ∏ σ : F →ₐ[K] E, σ (algebraMap L F pb.gen) =
      ((@Finset.univ _ (PowerBasis.AlgHom.fintype pb)).prod
        fun σ : L →ₐ[K] E => σ pb.gen) ^ finrank L F := by
  haveI : FiniteDimensional L F := FiniteDimensional.right K L F
  

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝¹⁴ : CommRing R
inst✝¹³ : Ring S
inst✝¹² : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝¹¹ : Field K
inst✝¹⁰ : Field L
inst✝⁹ : Field F
inst✝⁸ : Algebra K L
inst✝⁷ : Algebra K F
ι : Type w
E : Type u_7
inst✝⁶ : Field E
inst✝⁵ : Algebra K E
inst✝⁴ : Algebra L F
inst✝³ : IsScalarTower K L F
inst✝² : IsAlgClosed E
inst✝¹ : IsSeparable K F
inst✝ : FiniteDimensional K F
pb : PowerBasis K L
this : FiniteDimensional L F
⊢ ∏ σ : F →ₐ[K] E, σ ((algebraMap L F) pb.gen) = (∏ σ : L →ₐ[K] E, σ pb.gen) ^ finrank L F

Next tactic:
haveI : IsSeparable L F := isSeparable_tower_top_of_isSeparable K L F
theorem prod_embeddings_eq_finrank_pow [Algebra L F] [IsScalarTower K L F] [IsAlgClosed E]
    [IsSeparable K F] [FiniteDimensional K F] (pb : PowerBasis K L) :
    ∏ σ : F →ₐ[K] E, σ (algebraMap L F pb.gen) =
      ((@Finset.univ _ (PowerBasis.AlgHom.fintype pb)).prod
        fun σ : L →ₐ[K] E => σ pb.gen) ^ finrank L F := by
  haveI : FiniteDimensional L F := FiniteDimensional.right K L F
  haveI : IsSeparable L F := isSeparable_tower_top_of_isSeparable K L F
  

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝¹⁴ : CommRing R
inst✝¹³ : Ring S
inst✝¹² : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝¹¹ : Field K
inst✝¹⁰ : Field L
inst✝⁹ : Field F
inst✝⁸ : Algebra K L
inst✝⁷ : Algebra K F
ι : Type w
E : Type u_7
inst✝⁶ : Field E
inst✝⁵ : Algebra K E
inst✝⁴ : Algebra L F
inst✝³ : IsScalarTower K L F
inst✝² : IsAlgClosed E
inst✝¹ : IsSeparable K F
inst✝ : FiniteDimensional K F
pb : PowerBasis K L
this✝ : FiniteDimensional L F
this : IsSeparable L F
⊢ ∏ σ : F →ₐ[K] E, σ ((algebraMap L F) pb.gen) = (∏ σ : L →ₐ[K] E, σ pb.gen) ^ finrank L F

Next tactic:
letI : Fintype (L →ₐ[K] E) := PowerBasis.AlgHom.fintype pb
theorem prod_embeddings_eq_finrank_pow [Algebra L F] [IsScalarTower K L F] [IsAlgClosed E]
    [IsSeparable K F] [FiniteDimensional K F] (pb : PowerBasis K L) :
    ∏ σ : F →ₐ[K] E, σ (algebraMap L F pb.gen) =
      ((@Finset.univ _ (PowerBasis.AlgHom.fintype pb)).prod
        fun σ : L →ₐ[K] E => σ pb.gen) ^ finrank L F := by
  haveI : FiniteDimensional L F := FiniteDimensional.right K L F
  haveI : IsSeparable L F := isSeparable_tower_top_of_isSeparable K L F
  letI : Fintype (L →ₐ[K] E) := PowerBasis.AlgHom.fintype pb
  

Proof state:
R : Type u_1
S : Type u_2
T : Type u_3
inst✝¹⁴ : CommRing R
inst✝¹³ : Ring S
inst✝¹² : Algebra R S
K : Type u_4
L : Type u_5
F : Type u_6
inst✝¹¹ : Field K
inst✝¹⁰ : Field L
inst✝⁹ : Field F
inst✝⁸ : Algebra K L
inst✝⁷ : Algebra K F
ι : Type w
E : Type u_7
inst✝⁶ : Field E
inst✝⁵ : Algebra K E
inst✝⁴ : Algebra L F
inst✝³ : IsScalarTower K L F
inst✝² : IsAlgClosed E
inst✝¹ : IsSeparable K F
inst✝ : FiniteDimensional K F
pb : PowerBasis K L
this✝¹ : FiniteDimensional L F
this✝ : IsSeparable L F
this : Fintype (L →ₐ[K] E) := PowerBasis.AlgHom.fintype pb
⊢ ∏ σ : F →ₐ[K] E, σ ((algebraMap L F) pb.gen) = (∏ σ : L →ₐ[K] E, σ pb.gen) ^ finrank L F

Next tactic:
letI : ∀ f : L →ₐ[K] E, Fintype (@AlgHom L F E _ _ _ _ f.toRingHom.toAlgebra) := ?_