l3lab/ntp-mathlib huggingface dataset:
/-- The lift `End(B/A) → End(L/K)` in an ALKB setup.
This is inverse to the restriction. See `galRestrictHom`. -/
noncomputable
def galLift (σ : B →ₐ[A] B) : L →ₐ[K] L :=
  haveI := (IsFractionRing.injective A K).isDomain
  haveI := NoZeroSMulDivisors.trans A K L
  haveI := IsIntegralClosure.isLocalization A K L B (Algebra.IsIntegral.of_finite _ _).isAlgebraic
  haveI H : ∀ (y :  Algebra.algebraMapSubmonoid B A⁰),
      IsUnit (((algebraMap B L).comp σ) (y : B)) := by
    rintro ⟨_, x, hx, rfl⟩
    simpa only [RingHom.coe_comp, RingHom.coe_coe, Function.comp_apply, AlgHom.commutes,
      isUnit_iff_ne_zero, ne_eq, map_eq_zero_iff _ (NoZeroSMulDivisors.algebraMap_injective _ _),
      ← IsScalarTower.algebraMap_apply] using nonZeroDivisors.ne_zero hx
  haveI H_eq : (IsLocalization.lift (S := L) H).comp (algebraMap K L) = (algebraMap K L) := by
    apply IsLocalization.ringHom_ext A⁰
    ext
    

Proof state:
case h.a
A : Type u_1
K : Type u_2
L : Type u_3
B : Type u_4
inst✝¹³ : CommRing A
inst✝¹² : CommRing B
inst✝¹¹ : Algebra A B
inst✝¹⁰ : Field K
inst✝⁹ : Field L
inst✝⁸ : Algebra A K
inst✝⁷ : IsFractionRing A K
inst✝⁶ : Algebra B L
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra A L
inst✝³ : IsScalarTower A B L
inst✝² : IsScalarTower A K L
inst✝¹ : IsIntegralClosure B A L
inst✝ : FiniteDimensional K L
σ : B →ₐ[A] B
this✝¹ : IsDomain A
this✝ : NoZeroSMulDivisors A L
this : IsLocalization (Algebra.algebraMapSubmonoid B A⁰) L
H : ∀ (y : ↥(Algebra.algebraMapSubmonoid B A⁰)), IsUnit ((RingHom.comp (algebraMap B L) ↑σ) ↑y)
x✝ : A
⊢ (RingHom.comp (RingHom.comp (IsLocalization.lift H) (algebraMap K L)) (algebraMap A K)) x✝ =
    (RingHom.comp (algebraMap K L) (algebraMap A K)) x✝

Next tactic:
simp only [RingHom.coe_comp, Function.comp_apply, ← IsScalarTower.algebraMap_apply A K L,
      IsScalarTower.algebraMap_apply A B L, IsLocalization.lift_eq,
      RingHom.coe_coe, AlgHom.commutes]
/-- The restriction `End(L/K) → End(B/A)` in an AKLB setup.
Also see `galRestrict` for the `AlgEquiv` version. -/
noncomputable
def galRestrictHom : (L →ₐ[K] L) ≃* (B →ₐ[A] B) where
  toFun := fun f ↦ (IsIntegralClosure.equiv A (integralClosure A L) L B).toAlgHom.comp
      (((f.restrictScalars A).comp (IsScalarTower.toAlgHom A B L)).codRestrict
        (integralClosure A L) (fun x ↦ IsIntegral.map _ (IsIntegralClosure.isIntegral A L x)))
  map_mul' := by
    intros σ₁ σ₂
    ext x
    apply (IsIntegralClosure.equiv A (integralClosure A L) L B).symm.injective
    ext
    dsimp
    simp only [AlgEquiv.symm_apply_apply, AlgHom.coe_codRestrict, AlgHom.coe_comp,
      AlgHom.coe_restrictScalars', IsScalarTower.coe_toAlgHom', Function.comp_apply,
      AlgHom.mul_apply, IsIntegralClosure.algebraMap_equiv, Subalgebra.algebraMap_eq]
    rfl
  invFun := galLift A K L B
  left_inv σ :=
    have := (IsFractionRing.injective A K).isDomain
    have := IsIntegralClosure.isLocalization A K L B (Algebra.IsIntegral.of_finite _ _).isAlgebraic
    AlgHom.coe_ringHom_injective <| IsLocalization.ringHom_ext (Algebra.algebraMapSubmonoid B A⁰)
      <| RingHom.ext fun x ↦ by 

Proof state:
A : Type u_1
K : Type u_2
L : Type u_3
B : Type u_4
inst✝¹³ : CommRing A
inst✝¹² : CommRing B
inst✝¹¹ : Algebra A B
inst✝¹⁰ : Field K
inst✝⁹ : Field L
inst✝⁸ : Algebra A K
inst✝⁷ : IsFractionRing A K
inst✝⁶ : Algebra B L
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra A L
inst✝³ : IsScalarTower A B L
inst✝² : IsScalarTower A K L
inst✝¹ : IsIntegralClosure B A L
inst✝ : FiniteDimensional K L
σ : L →ₐ[K] L
this✝ : IsDomain A
this : IsLocalization (Algebra.algebraMapSubmonoid B A⁰) L
x : B
⊢ (RingHom.comp
        (↑(galLift A K L B
            ((fun f =>
                AlgHom.comp (↑(IsIntegralClosure.equiv A (↥(integralClosure A L)) L B))
                  (AlgHom.codRestrict (AlgHom.comp (AlgHom.restrictScalars A f) (IsScalarTower.toAlgHom A B L))
                    (integralClosure A L)
                    (_ :
                      ∀ (x : B),
                        IsIntegral A ((AlgHom.comp (AlgHom.restrictScalars A f) (IsScalarTower.toAlgHom A B L)) x))))
              σ)))
        (algebraMap B L))
      x =
    (RingHom.comp (↑σ) (algebraMap B L)) x

Next tactic:
simp [Subalgebra.algebraMap_eq, galLift]
/-- The restriction `End(L/K) → End(B/A)` in an AKLB setup.
Also see `galRestrict` for the `AlgEquiv` version. -/
noncomputable
def galRestrictHom : (L →ₐ[K] L) ≃* (B →ₐ[A] B) where
  toFun := fun f ↦ (IsIntegralClosure.equiv A (integralClosure A L) L B).toAlgHom.comp
      (((f.restrictScalars A).comp (IsScalarTower.toAlgHom A B L)).codRestrict
        (integralClosure A L) (fun x ↦ IsIntegral.map _ (IsIntegralClosure.isIntegral A L x)))
  map_mul' := by
    intros σ₁ σ₂
    ext x
    apply (IsIntegralClosure.equiv A (integralClosure A L) L B).symm.injective
    ext
    dsimp
    simp only [AlgEquiv.symm_apply_apply, AlgHom.coe_codRestrict, AlgHom.coe_comp,
      AlgHom.coe_restrictScalars', IsScalarTower.coe_toAlgHom', Function.comp_apply,
      AlgHom.mul_apply, IsIntegralClosure.algebraMap_equiv, Subalgebra.algebraMap_eq]
    rfl
  invFun := galLift A K L B
  left_inv σ :=
    have := (IsFractionRing.injective A K).isDomain
    have := IsIntegralClosure.isLocalization A K L B (Algebra.IsIntegral.of_finite _ _).isAlgebraic
    AlgHom.coe_ringHom_injective <| IsLocalization.ringHom_ext (Algebra.algebraMapSubmonoid B A⁰)
      <| RingHom.ext fun x ↦ by simp [Subalgebra.algebraMap_eq, galLift]
  right_inv σ :=
    have := (IsFractionRing.injective A K).isDomain
    have := IsIntegralClosure.isLocalization A K L B (Algebra.IsIntegral.of_finite _ _).isAlgebraic
    AlgHom.ext fun x ↦
      IsIntegralClosure.algebraMap_injective B A L (by 

Proof state:
A : Type u_1
K : Type u_2
L : Type u_3
B : Type u_4
inst✝¹³ : CommRing A
inst✝¹² : CommRing B
inst✝¹¹ : Algebra A B
inst✝¹⁰ : Field K
inst✝⁹ : Field L
inst✝⁸ : Algebra A K
inst✝⁷ : IsFractionRing A K
inst✝⁶ : Algebra B L
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra A L
inst✝³ : IsScalarTower A B L
inst✝² : IsScalarTower A K L
inst✝¹ : IsIntegralClosure B A L
inst✝ : FiniteDimensional K L
σ : B →ₐ[A] B
this✝ : IsDomain A
this : IsLocalization (Algebra.algebraMapSubmonoid B A⁰) L
x : B
⊢ (algebraMap B L)
      (((fun f =>
            AlgHom.comp (↑(IsIntegralClosure.equiv A (↥(integralClosure A L)) L B))
              (AlgHom.codRestrict (AlgHom.comp (AlgHom.restrictScalars A f) (IsScalarTower.toAlgHom A B L))
                (integralClosure A L)
                (_ :
                  ∀ (x : B),
                    IsIntegral A ((AlgHom.comp (AlgHom.restrictScalars A f) (IsScalarTower.toAlgHom A B L)) x))))
          (galLift A K L B σ))
        x) =
    (algebraMap B L) (σ x)

Next tactic:
simp [Subalgebra.algebraMap_eq, galLift]
/-- The restriction `End(L/K) → End(B/A)` in an AKLB setup.
Also see `galRestrict` for the `AlgEquiv` version. -/
noncomputable
def galRestrictHom : (L →ₐ[K] L) ≃* (B →ₐ[A] B) where
  toFun := fun f ↦ (IsIntegralClosure.equiv A (integralClosure A L) L B).toAlgHom.comp
      (((f.restrictScalars A).comp (IsScalarTower.toAlgHom A B L)).codRestrict
        (integralClosure A L) (fun x ↦ IsIntegral.map _ (IsIntegralClosure.isIntegral A L x)))
  map_mul' := by
    intros σ₁ σ₂
    ext x
    apply (IsIntegralClosure.equiv A (integralClosure A L) L B).symm.injective
    ext
    dsimp
    

Proof state:
case H.a.a
A : Type u_1
K : Type u_2
L : Type u_3
B : Type u_4
inst✝¹³ : CommRing A
inst✝¹² : CommRing B
inst✝¹¹ : Algebra A B
inst✝¹⁰ : Field K
inst✝⁹ : Field L
inst✝⁸ : Algebra A K
inst✝⁷ : IsFractionRing A K
inst✝⁶ : Algebra B L
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra A L
inst✝³ : IsScalarTower A B L
inst✝² : IsScalarTower A K L
inst✝¹ : IsIntegralClosure B A L
inst✝ : FiniteDimensional K L
σ₁ σ₂ : L →ₐ[K] L
x : B
⊢ ↑((AlgEquiv.symm (IsIntegralClosure.equiv A (↥(integralClosure A L)) L B))
        ((IsIntegralClosure.equiv A (↥(integralClosure A L)) L B)
          ((AlgHom.codRestrict (AlgHom.comp (AlgHom.restrictScalars A (σ₁ * σ₂)) (IsScalarTower.toAlgHom A B L))
              (integralClosure A L)
              (_ :
                ∀ (x : B),
                  IsIntegral A ((AlgHom.comp (AlgHom.restrictScalars A (σ₁ * σ₂)) (IsScalarTower.toAlgHom A B L)) x)))
            x))) =
    ↑((AlgEquiv.symm (IsIntegralClosure.equiv A (↥(integralClosure A L)) L B))
        ((IsIntegralClosure.equiv A (↥(integralClosure A L)) L B)
          ((AlgHom.codRestrict (AlgHom.comp (AlgHom.restrictScalars A σ₁) (IsScalarTower.toAlgHom A B L))
              (integralClosure A L)
              (_ :
                ∀ (x : B), IsIntegral A ((AlgHom.comp (AlgHom.restrictScalars A σ₁) (IsScalarTower.toAlgHom A B L)) x)))
            ((IsIntegralClosure.equiv A (↥(integralClosure A L)) L B)
              ((AlgHom.codRestrict (AlgHom.comp (AlgHom.restrictScalars A σ₂) (IsScalarTower.toAlgHom A B L))
                  (integralClosure A L)
                  (_ :
                    ∀ (x : B),
                      IsIntegral A ((AlgHom.comp (AlgHom.restrictScalars A σ₂) (IsScalarTower.toAlgHom A B L)) x)))
                x)))))

Next tactic:
simp only [AlgEquiv.symm_apply_apply, AlgHom.coe_codRestrict, AlgHom.coe_comp,
      AlgHom.coe_restrictScalars', IsScalarTower.coe_toAlgHom', Function.comp_apply,
      AlgHom.mul_apply, IsIntegralClosure.algebraMap_equiv, Subalgebra.algebraMap_eq]
/-- The restriction `End(L/K) → End(B/A)` in an AKLB setup.
Also see `galRestrict` for the `AlgEquiv` version. -/
noncomputable
def galRestrictHom : (L →ₐ[K] L) ≃* (B →ₐ[A] B) where
  toFun := fun f ↦ (IsIntegralClosure.equiv A (integralClosure A L) L B).toAlgHom.comp
      (((f.restrictScalars A).comp (IsScalarTower.toAlgHom A B L)).codRestrict
        (integralClosure A L) (fun x ↦ IsIntegral.map _ (IsIntegralClosure.isIntegral A L x)))
  map_mul' := by
    intros σ₁ σ₂
    ext x
    apply (IsIntegralClosure.equiv A (integralClosure A L) L B).symm.injective
    ext
    dsimp
    simp only [AlgEquiv.symm_apply_apply, AlgHom.coe_codRestrict, AlgHom.coe_comp,
      AlgHom.coe_restrictScalars', IsScalarTower.coe_toAlgHom', Function.comp_apply,
      AlgHom.mul_apply, IsIntegralClosure.algebraMap_equiv, Subalgebra.algebraMap_eq]
    

Proof state:
case H.a.a
A : Type u_1
K : Type u_2
L : Type u_3
B : Type u_4
inst✝¹³ : CommRing A
inst✝¹² : CommRing B
inst✝¹¹ : Algebra A B
inst✝¹⁰ : Field K
inst✝⁹ : Field L
inst✝⁸ : Algebra A K
inst✝⁷ : IsFractionRing A K
inst✝⁶ : Algebra B L
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra A L
inst✝³ : IsScalarTower A B L
inst✝² : IsScalarTower A K L
inst✝¹ : IsIntegralClosure B A L
inst✝ : FiniteDimensional K L
σ₁ σ₂ : L →ₐ[K] L
x : B
⊢ σ₁ (σ₂ ((algebraMap B L) x)) =
    σ₁
      ((RingHom.comp (algebraMap L L) ↑(Subalgebra.val (integralClosure A L)))
        ((AlgHom.codRestrict (AlgHom.comp (AlgHom.restrictScalars A σ₂) (IsScalarTower.toAlgHom A B L))
            (integralClosure A L)
            (_ :
              ∀ (x : B), IsIntegral A ((AlgHom.comp (AlgHom.restrictScalars A σ₂) (IsScalarTower.toAlgHom A B L)) x)))
          x))

Next tactic:
rfl
@[simp]
lemma algebraMap_galRestrictHom_apply (σ : L →ₐ[K] L) (x : B) :
    algebraMap B L (galRestrictHom A K L B σ x) = σ (algebraMap B L x) := by
  

Proof state:
A : Type u_1
K : Type u_2
L : Type u_3
B : Type u_4
inst✝¹³ : CommRing A
inst✝¹² : CommRing B
inst✝¹¹ : Algebra A B
inst✝¹⁰ : Field K
inst✝⁹ : Field L
inst✝⁸ : Algebra A K
inst✝⁷ : IsFractionRing A K
inst✝⁶ : Algebra B L
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra A L
inst✝³ : IsScalarTower A B L
inst✝² : IsScalarTower A K L
inst✝¹ : IsIntegralClosure B A L
inst✝ : FiniteDimensional K L
σ : L →ₐ[K] L
x : B
⊢ (algebraMap B L) (((galRestrictHom A K L B) σ) x) = σ ((algebraMap B L) x)

Next tactic:
simp [galRestrictHom, Subalgebra.algebraMap_eq]
@[simp, nolint unusedHavesSuffices] -- false positive from unfolding galRestrictHom
lemma galRestrictHom_symm_algebraMap_apply (σ : B →ₐ[A] B) (x : B) :
    (galRestrictHom A K L B).symm σ (algebraMap B L x) = algebraMap B L (σ x) := by
  

Proof state:
A : Type u_1
K : Type u_2
L : Type u_3
B : Type u_4
inst✝¹³ : CommRing A
inst✝¹² : CommRing B
inst✝¹¹ : Algebra A B
inst✝¹⁰ : Field K
inst✝⁹ : Field L
inst✝⁸ : Algebra A K
inst✝⁷ : IsFractionRing A K
inst✝⁶ : Algebra B L
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra A L
inst✝³ : IsScalarTower A B L
inst✝² : IsScalarTower A K L
inst✝¹ : IsIntegralClosure B A L
inst✝ : FiniteDimensional K L
σ : B →ₐ[A] B
x : B
⊢ ((MulEquiv.symm (galRestrictHom A K L B)) σ) ((algebraMap B L) x) = (algebraMap B L) (σ x)

Next tactic:
have := (IsFractionRing.injective A K).isDomain
@[simp, nolint unusedHavesSuffices] -- false positive from unfolding galRestrictHom
lemma galRestrictHom_symm_algebraMap_apply (σ : B →ₐ[A] B) (x : B) :
    (galRestrictHom A K L B).symm σ (algebraMap B L x) = algebraMap B L (σ x) := by
  have := (IsFractionRing.injective A K).isDomain
  

Proof state:
A : Type u_1
K : Type u_2
L : Type u_3
B : Type u_4
inst✝¹³ : CommRing A
inst✝¹² : CommRing B
inst✝¹¹ : Algebra A B
inst✝¹⁰ : Field K
inst✝⁹ : Field L
inst✝⁸ : Algebra A K
inst✝⁷ : IsFractionRing A K
inst✝⁶ : Algebra B L
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra A L
inst✝³ : IsScalarTower A B L
inst✝² : IsScalarTower A K L
inst✝¹ : IsIntegralClosure B A L
inst✝ : FiniteDimensional K L
σ : B →ₐ[A] B
x : B
this : IsDomain A
⊢ ((MulEquiv.symm (galRestrictHom A K L B)) σ) ((algebraMap B L) x) = (algebraMap B L) (σ x)

Next tactic:
have := IsIntegralClosure.isLocalization A K L B (Algebra.IsIntegral.of_finite _ _).isAlgebraic
@[simp, nolint unusedHavesSuffices] -- false positive from unfolding galRestrictHom
lemma galRestrictHom_symm_algebraMap_apply (σ : B →ₐ[A] B) (x : B) :
    (galRestrictHom A K L B).symm σ (algebraMap B L x) = algebraMap B L (σ x) := by
  have := (IsFractionRing.injective A K).isDomain
  have := IsIntegralClosure.isLocalization A K L B (Algebra.IsIntegral.of_finite _ _).isAlgebraic
  

Proof state:
A : Type u_1
K : Type u_2
L : Type u_3
B : Type u_4
inst✝¹³ : CommRing A
inst✝¹² : CommRing B
inst✝¹¹ : Algebra A B
inst✝¹⁰ : Field K
inst✝⁹ : Field L
inst✝⁸ : Algebra A K
inst✝⁷ : IsFractionRing A K
inst✝⁶ : Algebra B L
inst✝⁵ : Algebra K L
inst✝⁴ : Algebra A L
inst✝³ : IsScalarTower A B L
inst✝² : IsScalarTower A K L
inst✝¹ : IsIntegralClosure B A L
inst✝ : FiniteDimensional K L
σ : B →ₐ[A] B
x : B
this✝ : IsDomain A
this : IsLocalization (Algebra.algebraMapSubmonoid B A⁰) L
⊢ ((MulEquiv.symm (galRestrictHom A K L B)) σ) ((algebraMap B L) x) = (algebraMap B L) (σ x)

Next tactic:
simp [galRestrictHom, galLift, Subalgebra.algebraMap_eq]
lemma prod_galRestrict_eq_norm [IsGalois K L] [IsIntegrallyClosed A] (x : B) :
    (∏ σ : L ≃ₐ[K] L, galRestrict A K L B σ x) =
    algebraMap A B (IsIntegralClosure.mk' (R := A) A (Algebra.norm K <| algebraMap B L x)
      (Algebra.isIntegral_norm K (IsIntegralClosure.isIntegral A L x).algebraMap)) := by
  

Proof state:
A : Type u_1
K : Type u_2
L : Type u_3
B : Type u_4
inst✝¹⁵ : CommRing A
inst✝¹⁴ : CommRing B
inst✝¹³ : Algebra A B
inst✝¹² : Field K
inst✝¹¹ : Field L
inst✝¹⁰ : Algebra A K
inst✝⁹ : IsFractionRing A K
inst✝⁸ : Algebra B L
inst✝⁷ : Algebra K L
inst✝⁶ : Algebra A L
inst✝⁵ : IsScalarTower A B L
inst✝⁴ : IsScalarTower A K L
inst✝³ : IsIntegralClosure B A L
inst✝² : FiniteDimensional K L
inst✝¹ : IsGalois K L
inst✝ : IsIntegrallyClosed A
x : B
⊢ ∏ σ : L ≃ₐ[K] L, ((galRestrict A K L B) σ) x =
    (algebraMap A B)
      (IsIntegralClosure.mk' A ((Algebra.norm K) ((algebraMap B L) x))
        (_ : IsIntegral A ((Algebra.norm K) ((algebraMap B L) x))))

Next tactic:
apply IsIntegralClosure.algebraMap_injective B A L
lemma prod_galRestrict_eq_norm [IsGalois K L] [IsIntegrallyClosed A] (x : B) :
    (∏ σ : L ≃ₐ[K] L, galRestrict A K L B σ x) =
    algebraMap A B (IsIntegralClosure.mk' (R := A) A (Algebra.norm K <| algebraMap B L x)
      (Algebra.isIntegral_norm K (IsIntegralClosure.isIntegral A L x).algebraMap)) := by
  apply IsIntegralClosure.algebraMap_injective B A L
  

Proof state:
case a
A : Type u_1
K : Type u_2
L : Type u_3
B : Type u_4
inst✝¹⁵ : CommRing A
inst✝¹⁴ : CommRing B
inst✝¹³ : Algebra A B
inst✝¹² : Field K
inst✝¹¹ : Field L
inst✝¹⁰ : Algebra A K
inst✝⁹ : IsFractionRing A K
inst✝⁸ : Algebra B L
inst✝⁷ : Algebra K L
inst✝⁶ : Algebra A L
inst✝⁵ : IsScalarTower A B L
inst✝⁴ : IsScalarTower A K L
inst✝³ : IsIntegralClosure B A L
inst✝² : FiniteDimensional K L
inst✝¹ : IsGalois K L
inst✝ : IsIntegrallyClosed A
x : B
⊢ (algebraMap B L) (∏ σ : L ≃ₐ[K] L, ((galRestrict A K L B) σ) x) =
    (algebraMap B L)
      ((algebraMap A B)
        (IsIntegralClosure.mk' A ((Algebra.norm K) ((algebraMap B L) x))
          (_ : IsIntegral A ((Algebra.norm K) ((algebraMap B L) x)))))

Next tactic:
rw [← IsScalarTower.algebraMap_apply, IsScalarTower.algebraMap_eq A K L]
lemma prod_galRestrict_eq_norm [IsGalois K L] [IsIntegrallyClosed A] (x : B) :
    (∏ σ : L ≃ₐ[K] L, galRestrict A K L B σ x) =
    algebraMap A B (IsIntegralClosure.mk' (R := A) A (Algebra.norm K <| algebraMap B L x)
      (Algebra.isIntegral_norm K (IsIntegralClosure.isIntegral A L x).algebraMap)) := by
  apply IsIntegralClosure.algebraMap_injective B A L
  rw [← IsScalarTower.algebraMap_apply, IsScalarTower.algebraMap_eq A K L]
  

Proof state:
case a
A : Type u_1
K : Type u_2
L : Type u_3
B : Type u_4
inst✝¹⁵ : CommRing A
inst✝¹⁴ : CommRing B
inst✝¹³ : Algebra A B
inst✝¹² : Field K
inst✝¹¹ : Field L
inst✝¹⁰ : Algebra A K
inst✝⁹ : IsFractionRing A K
inst✝⁸ : Algebra B L
inst✝⁷ : Algebra K L
inst✝⁶ : Algebra A L
inst✝⁵ : IsScalarTower A B L
inst✝⁴ : IsScalarTower A K L
inst✝³ : IsIntegralClosure B A L
inst✝² : FiniteDimensional K L
inst✝¹ : IsGalois K L
inst✝ : IsIntegrallyClosed A
x : B
⊢ (algebraMap B L) (∏ σ : L ≃ₐ[K] L, ((galRestrict A K L B) σ) x) =
    (RingHom.comp (algebraMap K L) (algebraMap A K))
      (IsIntegralClosure.mk' A ((Algebra.norm K) ((algebraMap B L) x))
        (_ : IsIntegral A ((Algebra.norm K) ((algebraMap B L) x))))

Next tactic:
simp only [map_prod, algebraMap_galRestrict_apply, IsIntegralClosure.algebraMap_mk',
    Algebra.norm_eq_prod_automorphisms, AlgHom.coe_coe, RingHom.coe_comp, Function.comp_apply]
@[simp] lemma powerset_univ : (univ : Finset α).powerset = univ :=
  coe_injective <| by 

Proof state:
α : Type u_1
inst✝ : Fintype α
s : Finset α
k : ℕ
⊢ ↑(powerset univ) = ↑univ

Next tactic:
simp [-coe_eq_univ]
lemma filter_subset_univ [DecidableEq α] (s : Finset α) :
    filter (fun t ↦ t ⊆ s) univ = powerset s := by 

Proof state:
α : Type u_1
inst✝¹ : Fintype α
s✝ : Finset α
k : ℕ
inst✝ : DecidableEq α
s : Finset α
⊢ filter (fun t => t ⊆ s) univ = powerset s

Next tactic:
ext
lemma filter_subset_univ [DecidableEq α] (s : Finset α) :
    filter (fun t ↦ t ⊆ s) univ = powerset s := by ext; 

Proof state:
case a
α : Type u_1
inst✝¹ : Fintype α
s✝ : Finset α
k : ℕ
inst✝ : DecidableEq α
s a✝ : Finset α
⊢ a✝ ∈ filter (fun t => t ⊆ s) univ ↔ a✝ ∈ powerset s

Next tactic:
simp
@[simp] lemma powerset_eq_univ : s.powerset = univ ↔ s = univ := by
  

Proof state:
α : Type u_1
inst✝ : Fintype α
s : Finset α
k : ℕ
⊢ powerset s = univ ↔ s = univ

Next tactic:
rw [← Finset.powerset_univ, powerset_inj]
@[simp] lemma univ_filter_card_eq (k : ℕ) :
    (univ : Finset (Finset α)).filter (fun s ↦ s.card = k) = univ.powersetCard k := by 

Proof state:
α : Type u_1
inst✝ : Fintype α
s : Finset α
k✝ k : ℕ
⊢ filter (fun s => card s = k) univ = powersetCard k univ

Next tactic:
ext
@[simp] lemma univ_filter_card_eq (k : ℕ) :
    (univ : Finset (Finset α)).filter (fun s ↦ s.card = k) = univ.powersetCard k := by ext; 

Proof state:
case a
α : Type u_1
inst✝ : Fintype α
s : Finset α
k✝ k : ℕ
a✝ : Finset α
⊢ a✝ ∈ filter (fun s => card s = k) univ ↔ a✝ ∈ powersetCard k univ

Next tactic:
simp
@[simp]
theorem Fintype.card_finset_len [Fintype α] (k : ℕ) :
    Fintype.card { s : Finset α // s.card = k } = Nat.choose (Fintype.card α) k := by
  

Proof state:
α : Type u_1
inst✝ : Fintype α
k : ℕ
⊢ card { s // Finset.card s = k } = Nat.choose (card α) k

Next tactic:
simp [Fintype.subtype_card, Finset.card_univ]
instance Set.fintype [Fintype α] : Fintype (Set α) :=
  ⟨(@Finset.univ α _).powerset.map ⟨(↑), coe_injective⟩, fun s => by
    

Proof state:
α : Type u_1
inst✝ : Fintype α
s : Set α
⊢ s ∈ map { toFun := toSet, inj' := (_ : Function.Injective toSet) } (Finset.powerset Finset.univ)

Next tactic:
classical
      refine' mem_map.2 ⟨Finset.univ.filter s, Finset.mem_powerset.2 (Finset.subset_univ _), _⟩
      apply (coe_filter _ _).trans
      simp
      rfl
instance Set.fintype [Fintype α] : Fintype (Set α) :=
  ⟨(@Finset.univ α _).powerset.map ⟨(↑), coe_injective⟩, fun s => by
    classical
      

Proof state:
α : Type u_1
inst✝ : Fintype α
s : Set α
⊢ s ∈ map { toFun := toSet, inj' := (_ : Function.Injective toSet) } (Finset.powerset Finset.univ)

Next tactic:
refine' mem_map.2 ⟨Finset.univ.filter s, Finset.mem_powerset.2 (Finset.subset_univ _), _⟩
instance Set.fintype [Fintype α] : Fintype (Set α) :=
  ⟨(@Finset.univ α _).powerset.map ⟨(↑), coe_injective⟩, fun s => by
    classical
      refine' mem_map.2 ⟨Finset.univ.filter s, Finset.mem_powerset.2 (Finset.subset_univ _), _⟩
      

Proof state:
α : Type u_1
inst✝ : Fintype α
s : Set α
⊢ { toFun := toSet, inj' := (_ : Function.Injective toSet) } (filter s Finset.univ) = s

Next tactic:
apply (coe_filter _ _).trans
instance Set.fintype [Fintype α] : Fintype (Set α) :=
  ⟨(@Finset.univ α _).powerset.map ⟨(↑), coe_injective⟩, fun s => by
    classical
      refine' mem_map.2 ⟨Finset.univ.filter s, Finset.mem_powerset.2 (Finset.subset_univ _), _⟩
      apply (coe_filter _ _).trans
      

Proof state:
α : Type u_1
inst✝ : Fintype α
s : Set α
⊢ {x | x ∈ Finset.univ ∧ s x} = s

Next tactic:
simp
instance Set.fintype [Fintype α] : Fintype (Set α) :=
  ⟨(@Finset.univ α _).powerset.map ⟨(↑), coe_injective⟩, fun s => by
    classical
      refine' mem_map.2 ⟨Finset.univ.filter s, Finset.mem_powerset.2 (Finset.subset_univ _), _⟩
      apply (coe_filter _ _).trans
      simp
      

Proof state:
α : Type u_1
inst✝ : Fintype α
s : Set α
⊢ {x | s x} = s

Next tactic:
rfl
instance Set.finite' [Finite α] : Finite (Set α) := by
  

Proof state:
α : Type u_1
inst✝ : Finite α
⊢ Finite (Set α)

Next tactic:
cases nonempty_fintype α
instance Set.finite' [Finite α] : Finite (Set α) := by
  cases nonempty_fintype α
  

Proof state:
case intro
α : Type u_1
inst✝ : Finite α
val✝ : Fintype α
⊢ Finite (Set α)

Next tactic:
infer_instance
theorem AffineSubspace.nonempty_map {E : AffineSubspace k P₁} [Ene : Nonempty E] {φ : P₁ →ᵃ[k] P₂} :
    Nonempty (E.map φ) := by
  

Proof state:
k : Type u_1
V₁ : Type u_2
P₁ : Type u_3
V₂ : Type u_4
P₂ : Type u_5
inst✝⁶ : Ring k
inst✝⁵ : AddCommGroup V₁
inst✝⁴ : AddCommGroup V₂
inst✝³ : Module k V₁
inst✝² : Module k V₂
inst✝¹ : AddTorsor V₁ P₁
inst✝ : AddTorsor V₂ P₂
E : AffineSubspace k P₁
Ene : Nonempty ↥E
φ : P₁ →ᵃ[k] P₂
⊢ Nonempty ↥(map φ E)

Next tactic:
obtain ⟨x, hx⟩ := id Ene
theorem AffineSubspace.nonempty_map {E : AffineSubspace k P₁} [Ene : Nonempty E] {φ : P₁ →ᵃ[k] P₂} :
    Nonempty (E.map φ) := by
  obtain ⟨x, hx⟩ := id Ene
  

Proof state:
case intro.mk
k : Type u_1
V₁ : Type u_2
P₁ : Type u_3
V₂ : Type u_4
P₂ : Type u_5
inst✝⁶ : Ring k
inst✝⁵ : AddCommGroup V₁
inst✝⁴ : AddCommGroup V₂
inst✝³ : Module k V₁
inst✝² : Module k V₂
inst✝¹ : AddTorsor V₁ P₁
inst✝ : AddTorsor V₂ P₂
E : AffineSubspace k P₁
Ene : Nonempty ↥E
φ : P₁ →ᵃ[k] P₂
x : P₁
hx : x ∈ E
⊢ Nonempty ↥(map φ E)

Next tactic:
refine' ⟨⟨φ x, AffineSubspace.mem_map.mpr ⟨x, hx, rfl⟩⟩⟩
/-- Restrict domain and codomain of an affine map to the given subspaces. -/
def AffineMap.restrict (φ : P₁ →ᵃ[k] P₂) {E : AffineSubspace k P₁} {F : AffineSubspace k P₂}
    [Nonempty E] [Nonempty F] (hEF : E.map φ ≤ F) : E →ᵃ[k] F := by
  

Proof state:
k : Type u_1
V₁ : Type u_2
P₁ : Type u_3
V₂ : Type u_4
P₂ : Type u_5
inst✝⁸ : Ring k
inst✝⁷ : AddCommGroup V₁
inst✝⁶ : AddCommGroup V₂
inst✝⁵ : Module k V₁
inst✝⁴ : Module k V₂
inst✝³ : AddTorsor V₁ P₁
inst✝² : AddTorsor V₂ P₂
φ : P₁ →ᵃ[k] P₂
E : AffineSubspace k P₁
F : AffineSubspace k P₂
inst✝¹ : Nonempty ↥E
inst✝ : Nonempty ↥F
hEF : AffineSubspace.map φ E ≤ F
⊢ ↥E →ᵃ[k] ↥F

Next tactic:
refine' ⟨_, _, _⟩