Section ModularGroup.
Variables p n : nat.
Let m := (p ^ n)%N.
Let q := (p ^ n.-1)%N.
Let r := (p ^ n.-2)%N.
Hypotheses (p_pr : prime p) (n_gt2 : n > 2).
Let p_gt1 := prime_gt1 p_pr.
Let p_gt0 := ltnW p_gt1.
Let def_n := esym (subnKC n_gt2).
Let def_p : pdiv m = p. Proof. by rewrite /m def_n pdiv_pfactor. Qed.
Let def_q : m %/ p = q. Proof. by rewrite /m /q def_n expnS mulKn. Qed.
Let def_r : q %/ p = r. Proof. by rewrite /r /q def_n expnS mulKn. Qed.
Let ltqm : q < m. Proof. by rewrite ltn_exp2l // def_n. Qed.
Let ltrq : r < q. Proof. by rewrite ltn_exp2l // def_n. Qed.
Let r_gt0 : 0 < r. Proof. by rewrite expn_gt0 ?p_gt0. Qed.
Let q_gt1 : q > 1. Proof. exact: leq_ltn_trans r_gt0 ltrq. Qed.

(* Specifications: *)
Lemma card_modular_group : #|'Mod_(p ^ n)| = (p ^ n)%N.
Definition modular_group_generators gT (xy : gT * gT) :=
let: (x, y) := xy in #[y] = p /\ x ^ y = x ^+ r.+1.
Lemma generators_modular_group gT (G : {group gT}) :
G \isog 'Mod_m ->
exists2 xy, extremal_generators G p n xy & modular_group_generators xy.
(* This is an adaptation of Aschbacher, exercise 8.2: *)
(*  - We allow an alternative to the #[x] = p ^ n.-1 condition that meshes    *)
(*    better with the modular_Grp lemma above.                                *)
(*  - We state explicitly some "obvious" properties of G, namely that G is    *)
(*    the non-abelian semi-direct product <[x]> ><| <[y]> and that y ^+ j     *)
(*    acts on <[x]> via z |-> z ^+ (j * p ^ n.-2).+1                          *)
(*  - We also give the values of the 'Mho^k(G).                               *)
(*  - We corrected a pair of typos.                                           *)
Lemma modular_group_structure gT (G : {group gT}) x y :
extremal_generators G p n (x, y) ->
G \isog 'Mod_m -> modular_group_generators (x, y) ->
let X := <[x]> in
[/\ [/\ X ><| <[y]> = G, ~~ abelian G
& {in X, forall z j, z ^ (y ^+ j) = z ^+ (j * r).+1}],
[/\ 'Z(G) = <[x ^+ p]>, 'Phi(G) = 'Z(G) & #|'Z(G)| = r],
[/\ G^`(1) = <[x ^+ r]>, #|G^`(1)| = p & nil_class G = 2],
forall k, k > 0 -> 'Mho^k(G) = <[x ^+ (p ^ k)]>
& if (p, n) == (2, 3) then 'Ohm_1(G) = G else
forall k, 0 < k < n.-1 ->
<[x ^+ (p ^ (n - k.+1))]> \x <[y]> = 'Ohm_k(G)
/\ #|'Ohm_k(G)| = (p ^ k.+1)%N].