End FinSplittingField.
Section FinFieldExists.
(* While he existence of finite splitting fields and of finite fields of      *)
(* arbitrary prime power order is mathematically straightforward, it is       *)
(* technically challenging to formalize in Coq. The Coq typechecker performs  *)
(* poorly for the spme of the deeply nested dependent types used in the       *)
(* construction, such as polynomials over extensions of extensions of finite  *)
(* fields. Any conversion in a nested structure parameter incurs a huge       *)
(* overhead as it is shared across term comparison by call-by-need evalution. *)
(* The proof of FinSplittingFieldFor is contrived to mitigate this effect:    *)
(* the abbreviation map_poly_extField alone divides by 3 the proof checking   *)
(* time, by reducing the number of occurrences of field(Ext)Type structures   *)
(* in the subgoals; the succesive, apparently redundant 'suffices' localize   *)
(* some of the conversions to smaller subgoals, yielding a further 8-fold     *)
(* time gain. In particular, we construct the splitting field as a subtype    *)
(* of a recursive construction rather than prove that the latter yields       *)
(* precisely a splitting field.                                               *)
(* The apparently redundant type annotation reduces checking time by 30%.     *)
Let map_poly_extField (F : fieldType) (L : fieldExtType F) :=
map_poly (in_alg L) : {poly F} -> {poly L}.
Local Notation "p ^%:A" := (map_poly_extField _ p)
(at level 2, format "p ^%:A") : ring_scope.

(* Specifications: *)
Lemma FinSplittingFieldFor (F : finFieldType) (p : {poly F}) :
p != 0 -> {L : splittingFieldType F | splittingFieldFor 1 p^%:A {:L}}.
Lemma PrimePowerField p k (m := (p ^ k)%N) :
prime p -> 0 < k -> {Fm : finFieldType | p \in [char Fm] & #|Fm| = m}.