Notation "f ^-1" := (inv_ahom f) : lrfun_scope.
Arguments kHomP {F L K V f}.
Arguments kAHomP {F L U V f}.
Arguments kHom_lrmorphism {F L f}.
Module SplittingField.
Section ClassDef.
Variable F : fieldType.
Definition axiom (L : fieldExtType F) :=
exists2 p : {poly L}, p \is a polyOver 1%VS & splittingFieldFor 1 p {:L}.
Record class_of (L : Type) : Type :=
Class {base : FieldExt.class_of F L; _ : axiom (FieldExt.Pack _ base)}.
Local Coercion base : class_of >-> FieldExt.class_of.
Structure type (phF : phant F) := Pack {sort; _ : class_of sort}.
Local Coercion sort : type >-> Sortclass.
Variable (phF : phant F) (T : Type) (cT : type phF).
Definition class := let: Pack _ c as cT' := cT return class_of cT' in c.
Let xT := let: Pack T _ := cT in T.
Notation xclass := (class : class_of xT).
Definition clone c of phant_id class c := @Pack phF T c.
Definition pack b0 (ax0 : axiom (@FieldExt.Pack F (Phant F) T b0)) :=
fun bT b & phant_id (@FieldExt.class F phF bT) b =>
fun   ax & phant_id ax0 ax => Pack (Phant F) (@Class T b ax).
Definition eqType := @Equality.Pack cT xclass.
Definition choiceType := @Choice.Pack cT xclass.
Definition zmodType := @Zmodule.Pack cT xclass.
Definition ringType := @Ring.Pack cT xclass.
Definition unitRingType := @UnitRing.Pack cT xclass.
Definition comRingType := @ComRing.Pack cT xclass.
Definition comUnitRingType := @ComUnitRing.Pack cT xclass.
Definition idomainType := @IntegralDomain.Pack cT xclass.
Definition fieldType := @Field.Pack cT xclass.
Definition lmodType := @Lmodule.Pack F phF cT xclass.
Definition lalgType := @Lalgebra.Pack F phF cT xclass.
Definition algType := @Algebra.Pack F phF cT xclass.
Definition unitAlgType := @UnitAlgebra.Pack F phF cT xclass.
Definition vectType := @Vector.Pack F phF cT xclass.
Definition FalgType := @Falgebra.Pack F phF cT xclass.
Definition fieldExtType := @FieldExt.Pack F phF cT xclass.
End ClassDef.
Module Exports.
Coercion sort : type >-> Sortclass.
Bind Scope ring_scope with sort.
Coercion base : class_of >-> FieldExt.class_of.
Coercion eqType : type >-> Equality.type.
Canonical eqType.
Coercion choiceType : type >-> Choice.type.
Canonical choiceType.
Coercion zmodType : type >-> Zmodule.type.
Canonical zmodType.
Coercion ringType : type >-> Ring.type.
Canonical ringType.
Coercion unitRingType : type >-> UnitRing.type.
Canonical unitRingType.
Coercion comRingType : type >-> ComRing.type.
Canonical comRingType.
Coercion comUnitRingType : type >-> ComUnitRing.type.
Canonical comUnitRingType.
Coercion idomainType : type >-> IntegralDomain.type.
Canonical idomainType.
Coercion fieldType : type >-> Field.type.
Canonical fieldType.
Coercion lmodType : type >-> Lmodule.type.
Canonical lmodType.
Coercion lalgType : type >-> Lalgebra.type.
Canonical lalgType.
Coercion algType : type >-> Algebra.type.
Canonical algType.
Coercion unitAlgType : type >-> UnitAlgebra.type.
Canonical unitAlgType.
Coercion vectType : type >-> Vector.type.
Canonical vectType.
Coercion FalgType : type >-> Falgebra.type.
Canonical FalgType.
Coercion fieldExtType : type >-> FieldExt.type.
Canonical fieldExtType.
Notation splittingFieldType F := (type (Phant F)).
Notation SplittingFieldType F L ax := (@pack _ (Phant F) L _ ax _ _ id _ id).
Notation "[ 'splittingFieldType' F 'of' L 'for' K ]" :=
(@clone _ (Phant F) L K _ idfun)
(at level 0, format "[ 'splittingFieldType'  F  'of'  L  'for'  K ]")
: form_scope.
Notation "[ 'splittingFieldType' F 'of' L ]" :=
(@clone _ (Phant F) L _ _ id)
(at level 0, format "[ 'splittingFieldType'  F  'of'  L ]") : form_scope.
End Exports.
End SplittingField.
Export SplittingField.Exports.

(* Specifications: *)
Lemma normal_field_splitting (F : fieldType) (L : fieldExtType F) :
(forall (K : {subfield L}) x,
exists r, minPoly K x == \prod_(y <- r) ('X - y%:P)) ->
SplittingField.axiom L.