End Construction.
End Extremal.
Section SpecializeExtremals.
Variable m : nat.
Let p := pdiv m.
Let q := m %/ p.
Definition modular_gtype := gtype q p (q %/ p).+1.
Definition dihedral_gtype := gtype q 2 q.-1.
Definition semidihedral_gtype := gtype q 2 (q %/ p).-1.
Definition quaternion_kernel :=
<<[set u | u ^+ 2 == 1] :\: [set u ^+ 2 | u in [set: gtype q 4 q.-1]]>>.
Definition quaternion_gtype :=
locked_with gtype_key (coset_groupType quaternion_kernel).
End SpecializeExtremals.
Notation "''Mod_' m" := (modular_gtype m) : type_scope.
Notation "''Mod_' m" := [set: gsort 'Mod_m] : group_scope.
Notation "''Mod_' m" := [set: gsort 'Mod_m]%G : Group_scope.
Notation "''D_' m" := (dihedral_gtype m) : type_scope.
Notation "''D_' m" := [set: gsort 'D_m] : group_scope.
Notation "''D_' m" := [set: gsort 'D_m]%G : Group_scope.
Notation "''SD_' m" := (semidihedral_gtype m) : type_scope.
Notation "''SD_' m" := [set: gsort 'SD_m] : group_scope.
Notation "''SD_' m" := [set: gsort 'SD_m]%G : Group_scope.
Notation "''Q_' m" := (quaternion_gtype m) : type_scope.
Notation "''Q_' m" := [set: gsort 'Q_m] : group_scope.
Notation "''Q_' m" := [set: gsort 'Q_m]%G : Group_scope.
Section ExtremalTheory.
Implicit Types (gT : finGroupType) (p q m n : nat).

(* This is Aschbacher (23.3), with the isomorphism made explicit, and a       *)
(* slightly reworked case analysis on the prime and exponent; in particular   *)
(* the inverting involution is available for all non-trivial p-cycles.        *)
Lemma cyclic_pgroup_Aut_structure gT p (G : {group gT}) :
p.-group G -> cyclic G -> G :!=: 1 ->
let q := #|G| in let n := (logn p q).-1 in
let A := Aut G in let P := 'O_p(A) in let F := 'O_p^'(A) in
exists m : {perm gT} -> 'Z_q,
[/\ [/\ {in A & G, forall a x, x ^+ m a = a x},
m 1 = 1%R /\ {in A &, {morph m : a b / a * b >-> (a * b)%R}},
{in A &, injective m} /\ image m A =i GRing.unit,
forall k, {in A, {morph m : a / a ^+ k >-> (a ^+ k)%R}}
& {in A, {morph m : a / a^-1 >-> (a^-1)%R}}],
[/\ abelian A, cyclic F, #|F| = p.-1
& [faithful F, on 'Ohm_1(G) | [Aut G]]]
& if n == 0%N then A = F else
exists t, [/\ t \in A, #[t] = 2, m t = - 1%R
& if odd p then
[/\ cyclic A /\ cyclic P,
exists s, [/\ s \in A, #[s] = (p ^ n)%N, m s = p.+1%:R & P = <[s]>]
& exists s0, [/\ s0 \in A, #[s0] = p, m s0 = (p ^ n).+1%:R
& 'Ohm_1(P) = <[s0]>]]
else if n == 1%N then A = <[t]>
else exists s,
[/\ s \in A, #[s] = (2 ^ n.-1)%N, m s = 5%:R, <[s]> \x <[t]> = A
& exists s0, [/\ s0 \in A, #[s0] = 2, m s0 = (2 ^ n).+1%:R,
m (s0 * t) = (2 ^ n).-1%:R & 'Ohm_1(<[s]>) = <[s0]>]]]].