From e0ad11c900b0f33b4078892ed3416d82c0535caf Mon Sep 17 00:00:00 2001
From: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
Date: Fri, 12 Jun 2026 03:12:02 -0700
Subject: [PATCH 1/4] docs: document the integer encoding used by CodePcGroup
and PcGroupCode
Fixes #6419
---
lib/randiso.gd | 74 +++++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 67 insertions(+), 7 deletions(-)
diff --git a/lib/randiso.gd b/lib/randiso.gd
index 2a33d8b415..e899adc26f 100644
--- a/lib/randiso.gd
+++ b/lib/randiso.gd
@@ -21,13 +21,60 @@ DeclareAttribute( "OmegaAndLowerPCentralSeries", IsGroup );
##
##
##
-## returns the code corresponding to pcgs.
+## returns the non-negative integer code corresponding to the finite pcgs
+## pcgs. The code stores the relative orders of pcgs and
+## the right hand sides of the nontrivial power and commutator relations
+## of the pc presentation defined by pcgs.
+##
+## More precisely, let
+## g_1,\ldots,g_l be the entries of pcgs, and let
+## r_1,\ldots,r_l be their relative orders. If l=0,
+## the code is 0. Otherwise put
+## m = \max_i r_i - 1. If the relative orders are not all equal,
+## the first l base m digits are
+## r_1-2,\ldots,r_l-2, so the relative order part is
+## \sum_{i=1}^l (r_i-2)m^{l-i}. If the relative orders are all
+## equal, this part is omitted; on decoding the relative orders are then
+## read from the factorisation of the supplied group order.
+##
+## After the relative order part comes a bit mask of length
+## l(l+1)/2-1. The bits, from least significant to most
+## significant, correspond first to the power relations
+## g_1^{r_1},\ldots,g_{l-1}^{r_{l-1}}, and then to the
+## commutators [g_j,g_i] for
+## 1 \leq i < j \leq l, ordered by increasing i and, for
+## fixed i, increasing j. A bit is 1 exactly when
+## the corresponding right hand side is nontrivial. The final power
+## relation g_l^{r_l}=1 is not stored separately.
+##
+## The nontrivial right hand sides, in the same order as their set bits,
+## are stored as base |G| digits, where G is the group
+## generated by pcgs. If
+## x = g_1^{e_1} \cdots g_l^{e_l}, with
+## 0 \leq e_i < r_i, then the digit for x is
+## \sum_{i=1}^l e_i\prod_{k=i+1}^l r_k. Equivalently, this is
+## the zero-based position of x in the canonical list
+## g_1^{e_1}\cdots g_l^{e_l}, ordered with e_l varying
+## fastest, then e_{l-1}, and so on.
+##
+## Thus if b is m^l when the relative order part is present
+## and 1 otherwise, if u is the bit mask, and if
+## a_1,\ldots,a_t are the digits for the nontrivial right hand
+## sides, then the complete code is
+## A + b(u + 2^{l(l+1)/2-1}(a_1 + |G|a_2 + \cdots +
+## |G|^{t-1}a_t)), where A is the relative order part, or
+## 0 if that part is omitted.
## G := CyclicGroup(512);;
+## gap> G := CyclicGroup(8);;
## gap> p := Pcgs( G );;
## gap> CodePcgs( p );
-## 162895587718739690298008513020159
+## 323
## ]]>
+## In this example the relative orders are [2,2,2], so there is
+## no relative order part. The nontrivial power tails are g_2
+## and g_3, with digits 2 and 1 in the canonical
+## list. Hence the code is
+## 1 + 2 + 2^5(2 + 8\cdot 1) = 323.
##
##
## <#/GAPDoc>
@@ -43,11 +90,15 @@ DeclareGlobalFunction( "CodePcgs" );
##
##
##
-## returns the code for a pcgs of G.
+## returns the code for the pcgs returned by Pcgs for G.
+## The encoding is the one described for .
## G := DihedralGroup(512);;
-## gap> CodePcGroup( G );
-## 2940208627577393070560341803949986912431725641726
+## gap> G := CyclicGroup(8);;
+## gap> code := CodePcGroup( G );
+## 323
+## gap> H := PcGroupCode( code, Size( G ) );;
+## gap> IsCyclic( H ) and Size( H ) = Size( G );
+## true
## ]]>
##
##
@@ -69,6 +120,15 @@ DeclareGlobalFunction( "CodePcGroup" );
## otherwise anything may happen.
## Valid codes are usually obtained by one of the functions
## or .
+## The inverse construction uses the integer format described for
+## . The length of the pcgs, and in the case where
+## all relative orders are equal also the relative orders themselves, are
+## recovered from the prime factorisation of size.
+##
+## The same integer format is also used by Magma's
+## SmallGroupEncoding and SmallGroupDecoding, and by
+## OSCAR's encode for pc groups and
+## pc_group( order, code ).
## G := SmallGroup( 24, 12 );;
## gap> p := Pcgs( G );;
From 184326c9238152e878fd489348918d5cbc1349ed Mon Sep 17 00:00:00 2001
From: Matt Van Horn
Date: Mon, 15 Jun 2026 08:37:03 -0700
Subject: [PATCH 2/4] doc: cite Besche-Eick paper in CodePcgs encoding
description
---
lib/randiso.gd | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/lib/randiso.gd b/lib/randiso.gd
index e899adc26f..c96d0bb6cb 100644
--- a/lib/randiso.gd
+++ b/lib/randiso.gd
@@ -24,7 +24,9 @@ DeclareAttribute( "OmegaAndLowerPCentralSeries", IsGroup );
## returns the non-negative integer code corresponding to the finite pcgs
## pcgs. The code stores the relative orders of pcgs and
## the right hand sides of the nontrivial power and commutator relations
-## of the pc presentation defined by pcgs.
+## of the pc presentation defined by pcgs. This integer encoding of
+## pc groups underlies the group construction method described in
+## .
##
## More precisely, let
## g_1,\ldots,g_l be the entries of pcgs, and let
From 4c943a4dd8d57536603943c466c645befb7deb74 Mon Sep 17 00:00:00 2001
From: Max Horn
Date: Wed, 1 Jul 2026 13:18:45 +0200
Subject: [PATCH 3/4] Apply suggestions from code review
Co-authored-by: Max Horn
Co-authored-by: Thomas Breuer
---
lib/randiso.gd | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/lib/randiso.gd b/lib/randiso.gd
index c96d0bb6cb..084764a496 100644
--- a/lib/randiso.gd
+++ b/lib/randiso.gd
@@ -22,7 +22,8 @@ DeclareAttribute( "OmegaAndLowerPCentralSeries", IsGroup );
##
##
## returns the non-negative integer code corresponding to the finite pcgs
-## pcgs. The code stores the relative orders of pcgs and
+## pcgs, which must be in .
+The code stores the relative orders of pcgs and
## the right hand sides of the nontrivial power and commutator relations
## of the pc presentation defined by pcgs. This integer encoding of
## pc groups underlies the group construction method described in
@@ -56,8 +57,8 @@ DeclareAttribute( "OmegaAndLowerPCentralSeries", IsGroup );
## 0 \leq e_i < r_i, then the digit for x is
## \sum_{i=1}^l e_i\prod_{k=i+1}^l r_k. Equivalently, this is
## the zero-based position of x in the canonical list
-## g_1^{e_1}\cdots g_l^{e_l}, ordered with e_l varying
-## fastest, then e_{l-1}, and so on.
+## g_1^{e_1}\cdots g_l^{e_l}, ordered according to the
+## lexicographic order of the tuples e_1,\dots,e_l.
##
## Thus if b is m^l when the relative order part is present
## and 1 otherwise, if u is the bit mask, and if
From 12e78e0190d64933f04809124f6b7fc2bf1c1c63 Mon Sep 17 00:00:00 2001
From: Thomas Breuer
Date: Wed, 1 Jul 2026 16:58:36 +0200
Subject: [PATCH 4/4] Apply suggestion from @ThomasBreuer
---
lib/randiso.gd | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/randiso.gd b/lib/randiso.gd
index 084764a496..5f66f30e93 100644
--- a/lib/randiso.gd
+++ b/lib/randiso.gd
@@ -23,7 +23,7 @@ DeclareAttribute( "OmegaAndLowerPCentralSeries", IsGroup );
##
## returns the non-negative integer code corresponding to the finite pcgs
## pcgs, which must be in .
-The code stores the relative orders of pcgs and
+## The code stores the relative orders of pcgs and
## the right hand sides of the nontrivial power and commutator relations
## of the pc presentation defined by pcgs. This integer encoding of
## pc groups underlies the group construction method described in