# Group libraries

## Transitive permutation groups of small degree

TODO: explain about the scope of this.

TODO: give proper attribution to the transgrp package (in particular, cite it)

The arrangement and the names of the groups of degree up to 15 is the same as given in [CHM98]. With the exception of the symmetric and alternating group (which are represented as `symmetric_group`

and `alternating_group`

) the generators for these groups also conform to this paper with the only difference that 0 (which is not permitted in GAP for permutations to act on) is always replaced by the degree.

The arrangement for all degrees is intended to be equal to the arrangement within the systems GAP and Magma, thus it should be safe to refer to particular (classes of) groups by their index numbers.

`all_transitive_groups`

— Function`all_transitive_groups(L...)`

Return the list of all transitive groups (up to permutation isomorphism) satisfying the conditions described by the arguments. These conditions may be of one of the following forms:

`func => intval`

selects groups for which the function`func`

returns`intval`

`func => list`

selects groups for which the function`func`

returns any element inside`list`

`func`

selects groups for which the function`func`

returns`true`

`!func`

selects groups for which the function`func`

returns`false`

As a special case, the first argument may also be one of the following:

`intval`

selects groups whose degree equals`intval`

; this is equivalent to`degree => intval`

`intlist`

selects groups whose degree is in`intlist`

; this is equivalent to`degree => intlist`

The following functions are currently supported as values for `func`

:

`degree`

`is_abelian`

`is_almost_simple`

`is_cyclic`

`is_nilpotent`

`is_perfect`

`is_primitive`

`is_quasisimple`

`is_simple`

`is_sporadic_simple`

`is_solvable`

`is_supersolvable`

`is_transitive`

`number_of_conjugacy_classes`

`number_of_moved_points`

`order`

`transitivity`

The type of the returned groups is `PermGroup`

.

**Examples**

```
julia> all_transitive_groups(4)
5-element Vector{PermGroup}:
Permutation group of degree 4
Permutation group of degree 4
Permutation group of degree 4
Alt(4)
Sym(4)
julia> all_transitive_groups(degree => 3:5, is_abelian)
4-element Vector{PermGroup}:
Alt(3)
Permutation group of degree 4
Permutation group of degree 4
Permutation group of degree 5
```

`has_number_of_transitive_groups`

— Function`has_number_of_transitive_groups(deg::Int)`

Return whether the number transitive groups groups of degree `deg`

are available for use via `number_of_transitive_groups`

.

**Examples**

```
julia> has_number_of_transitive_groups(30)
true
julia> has_number_of_transitive_groups(64)
false
```

`has_transitive_group_identification`

— Function`has_transitive_group_identification(deg::Int)`

Return whether identification of transitive groups groups of degree `deg`

is available via `transitive_group_identification`

.

**Examples**

```
julia> has_transitive_group_identification(30)
true
julia> has_transitive_group_identification(64)
false
```

`has_transitive_groups`

— Function`has_transitive_groups(deg::Int)`

Return whether the transitive groups groups of degree `deg`

are available for use. This function should be used to test for the scope of the library available.

**Examples**

```
julia> has_transitive_groups(30)
true
julia> has_transitive_groups(64)
false
```

`number_of_transitive_groups`

— Function`number_of_transitive_groups(deg::Int)`

Return the number of transitive groups of degree `deg`

, up to permutation isomorphism.

**Examples**

```
julia> number_of_transitive_groups(30)
5712
julia> number_of_transitive_groups(64)
ERROR: ArgumentError: the number of transitive groups of degree 64 is not available
```

`transitive_group`

— Function`transitive_group(deg::Int, i::Int)`

Return the `i`

-th group in the catalogue of transitive groups over the set `{1, ..., deg}`

in GAP's Transitive Groups Library. The output is a group of type `PermGroup`

.

**Examples**

```
julia> transitive_group(5,4)
Alt(5)
julia> transitive_group(5,6)
ERROR: ArgumentError: there are only 5 transitive groups of degree 5, not 6
```

`transitive_group_identification`

— Function`transitive_group_identification(G::PermGroup)`

Return a pair `(d,n)`

such that `G`

is permutation isomorphic with `transitive_group(d,n)`

, where `G`

acts transitively on `d`

points.

If `G`

is not transitive on its moved points, or if the transitive groups of degree `d`

are not available, an exception is thrown.

**Examples**

```
julia> G = symmetric_group(7); m = transitive_group_identification(G)
(7, 7)
julia> order(transitive_group(m...)) == order(G)
true
julia> S = sub(G, [perm([1, 3, 4, 5, 2])])[1]
Permutation group of degree 7
julia> is_transitive(S)
false
julia> is_transitive(S, moved_points(S))
true
julia> m = transitive_group_identification(S)
(4, 1)
julia> order(transitive_group(m...)) == order(S)
true
julia> transitive_group_identification(symmetric_group(64))
ERROR: ArgumentError: identification of transitive groups of degree 64 are not available
julia> S = sub(G, [perm([1,3,4,5,2,7,6])])[1];
julia> transitive_group_identification(S)
ERROR: ArgumentError: group is not transitive on its moved points
```

## Primitive permutation groups of small degree

TODO: explain about the scope of this.

TODO: give proper attribution to the primitive groups library (in particular, cite it)

`all_primitive_groups`

— Function`all_primitive_groups(L...)`

Return the list of all primitive permutation groups (up to permutation isomorphism) satisfying the conditions described by the arguments. These conditions may be of one of the following forms:

`func => intval`

selects groups for which the function`func`

returns`intval`

`func => list`

selects groups for which the function`func`

returns any element inside`list`

`func`

selects groups for which the function`func`

returns`true`

`!func`

selects groups for which the function`func`

returns`false`

As a special case, the first argument may also be one of the following:

`intval`

selects groups whose degree equals`intval`

; this is equivalent to`degree => intval`

`intlist`

selects groups whose degree is in`intlist`

; this is equivalent to`degree => intlist`

The following functions are currently supported as values for `func`

:

`degree`

`is_abelian`

`is_almost_simple`

`is_cyclic`

`is_nilpotent`

`is_perfect`

`is_primitive`

`is_quasisimple`

`is_simple`

`is_sporadic_simple`

`is_solvable`

`is_supersolvable`

`is_transitive`

`number_of_conjugacy_classes`

`number_of_moved_points`

`order`

`transitivity`

The type of the returned groups is `PermGroup`

.

**Examples**

```
julia> all_primitive_groups(4)
2-element Vector{PermGroup}:
Alt(4)
Sym(4)
julia> all_primitive_groups(degree => 3:5, is_abelian)
2-element Vector{PermGroup}:
Alt(3)
Permutation group of degree 5 and order 5
```

`has_number_of_primitive_groups`

— Function`has_number_of_primitive_groups(deg::Int)`

Return `true`

if the number of primitive permutation groups of degree `deg`

is available via `number_of_primitive_groups`

, otherwise `false`

.

Currently the number of primitive permutation groups is available up to degree 4095.

**Examples**

```
julia> has_number_of_primitive_groups(50)
true
julia> has_number_of_primitive_groups(5000)
false
```

`has_primitive_group_identification`

— Function`has_primitive_group_identification(deg::Int)`

Return `true`

if identification is supported for the primitive permutation groups of degree `deg`

via `primitive_group_identification`

, otherwise `false`

.

Currently identification is available for all primitive permutation groups up to degree 4095.

**Examples**

```
julia> has_primitive_group_identification(50)
true
julia> has_primitive_group_identification(5000)
false
```

`has_primitive_groups`

— Function`has_primitive_groups(deg::Int)`

Return `true`

if the primitive permutation groups of degree `deg`

are available via `primitive_group`

and `all_primitive_groups`

, otherwise `false`

.

Currently all primitive permutation groups up to degree 4095 are available.

**Examples**

```
julia> has_primitive_groups(50)
true
julia> has_primitive_groups(5000)
false
```

`number_of_primitive_groups`

— Function`number_of_primitive_groups(deg::Int)`

Return the number of primitive permutation groups of degree `deg`

, up to permutation isomorphism.

**Examples**

```
julia> number_of_primitive_groups(10)
9
julia> number_of_primitive_groups(4096)
ERROR: ArgumentError: the number of primitive permutation groups of degree 4096 is not available
```

`primitive_group`

— Function`primitive_group(deg::Int, i::Int)`

Return the `i`

-th group in the catalogue of primitive permutation groups over the set `{1, ..., deg}`

in GAP's library of primitive permutation groups. The output is a group of type `PermGroup`

.

**Examples**

```
julia> primitive_group(10,1)
Permutation group of degree 10 and order 60
julia> primitive_group(10,10)
ERROR: ArgumentError: there are only 9 primitive permutation groups of degree 10, not 10
```

`primitive_group_identification`

— Function`primitive_group_identification(G::PermGroup)`

Return a pair `(d,n)`

such that `G`

is permutation isomorphic with `primitive_group(d,n)`

, where `G`

acts primitively on `d`

points.

If `G`

is not primitive on its moved points, or if the primitive permutation groups of degree `d`

are not available, an exception is thrown.

**Examples**

```
julia> G = symmetric_group(7); m = primitive_group_identification(G)
(7, 7)
julia> order(primitive_group(m...)) == order(G)
true
julia> S = stabilizer(G, 1)[1]
Permutation group of degree 7 and order 720
julia> is_primitive(S)
false
julia> is_primitive(S, moved_points(S))
true
julia> m = primitive_group_identification(S)
(6, 4)
julia> order(primitive_group(m...)) == order(S)
true
julia> primitive_group_identification(symmetric_group(4096))
ERROR: ArgumentError: identification of primitive permutation groups of degree 4096 is not available
julia> S = sub(G, [perm([1,3,4,5,2,7,6])])[1];
julia> primitive_group_identification(S)
ERROR: ArgumentError: group is not primitive on its moved points
```

## Perfect groups of small order

The functions in this section are wrappers for the GAP library of finite perfect groups which provides, up to isomorphism, a list of all perfect groups whose sizes are less than $2\cdot 10^6$. The groups of most orders up to $10^6$ have been enumerated by Derek Holt and Wilhelm Plesken, see [HP89]. For orders $n = 86016$, 368640, or 737280 this work only counted the groups (but did not explicitly list them), the groups of orders $n = 61440$, 122880, 172032, 245760, 344064, 491520, 688128, or 983040 were omitted.

Several additional groups omitted from the book [HP89] have also been included. Two groups – one of order 450000 with a factor group of type $A_6$ and the one of order 962280 – were found by Jack Schmidt in

- Two groups of order 243000 and one each of orders 729000, 871200, 878460

were found in 2020 by Alexander Hulpke.

The perfect groups of size less than $2\cdot 10^6$ which had not been classified in the work of Holt and Plesken have been enumerated by Alexander Hulpke. They are stored directly and provide less construction information in their names.

As all groups are stored by presentations, a permutation representation is obtained by coset enumeration. Note that some of the library groups do not have a faithful permutation representation of small degree. Computations in these groups may be rather time consuming.

`all_perfect_groups`

— Function`all_perfect_groups(L...)`

Return the list of all perfect groups (up to permutation isomorphism) satisfying the conditions described by the arguments. These conditions may be of one of the following forms:

`func => intval`

selects groups for which the function`func`

returns`intval`

`func => list`

selects groups for which the function`func`

returns any element inside`list`

`func`

selects groups for which the function`func`

returns`true`

`!func`

selects groups for which the function`func`

returns`false`

As a special case, the first argument may also be one of the following:

`intval`

selects groups whose order equals`intval`

; this is equivalent to`order => intval`

`intlist`

selects groups whose order is in`intlist`

; this is equivalent to`order => intlist`

The following functions are currently supported as values for `func`

:

`is_quasisimple`

`is_simple`

`is_sporadic_simple`

`number_of_conjugacy_classes`

`order`

The type of the returned groups is `PermGroup`

.

**Examples**

```
julia> all_perfect_groups(7200)
2-element Vector{PermGroup}:
Permutation group of degree 29 and order 7200
Permutation group of degree 288 and order 7200
julia> all_perfect_groups(order => 1:200, !is_simple)
2-element Vector{PermGroup}:
Permutation group of degree 1 and order 1
Permutation group of degree 24 and order 120
```

`has_number_of_perfect_groups`

— Function`has_number_of_perfect_groups(n::Int)`

Return `true`

if the number of perfect groups of order `n`

are available via `number_of_perfect_groups`

, otherwise `false`

.

Currently the number of perfect groups is available up to order $2 \cdot 10^6$.

**Examples**

```
julia> has_number_of_perfect_groups(7200)
true
julia> has_number_of_perfect_groups(2*10^6+1)
false
```

`has_perfect_group_identification`

— Function`has_perfect_group_identification(n::Int)`

Return `true`

if identification is supported for the perfect groups of order `n`

via `perfect_group_identification`

, otherwise `false`

.

Currently identification is available for all perfect groups up to order $2 \cdot 10^6$.

**Examples**

```
julia> has_perfect_group_identification(7200)
true
julia> has_perfect_group_identification(2*10^6+1)
false
```

`has_perfect_groups`

— Function`has_perfect_groups(deg::Int)`

Return `true`

if the perfect groups of order `n`

are available via `perfect_group`

and `all_perfect_groups`

, otherwise `false`

.

Currently all perfect groups up to order $2 \cdot 10^6$ are available.

**Examples**

```
julia> has_perfect_groups(7200)
true
julia> has_perfect_groups(2*10^6+1)
false
```

`number_of_perfect_groups`

— Function`number_of_perfect_groups(n::IntegerUnion)`

Return the number of perfect groups of order `n`

, up to isomorphism.

**Examples**

```
julia> number_of_perfect_groups(60)
1
julia> number_of_perfect_groups(1966080)
7344
```

`orders_perfect_groups`

— Function`orders_perfect_groups()`

Return a sorted vector of all numbers to $2 \cdot 10^6$ that occur as orders of perfect groups.

**Examples**

```
julia> orders_perfect_groups()[1:10]
10-element Vector{Int64}:
1
60
120
168
336
360
504
660
720
960
```

`perfect_group`

— Function`perfect_group(::Type{T} = PermGroup, n::IntegerUnion, k::IntegerUnion)`

Return the `k`

-th group of order `n`

and type `T`

in the catalogue of perfect groups in GAP's Perfect Groups Library. The type `T`

can be either `PermGroup`

or `FPGroup`

.

**Examples**

```
julia> perfect_group(60, 1)
Permutation group of degree 5 and order 60
julia> gens(ans)
2-element Vector{PermGroupElem}:
(1,2)(4,5)
(2,3,4)
julia> perfect_group(FPGroup, 60, 1)
Finitely presented group of order 60
julia> gens(ans)
2-element Vector{FPGroupElem}:
a
b
julia> perfect_group(60, 2)
ERROR: ArgumentError: there are only 1 perfect groups of order 60
```

`perfect_group_identification`

— Function`perfect_group_identification(G::GAPGroup)`

Return `(n, m)`

such that `G`

is isomorphic with `perfect_group(n, m)`

. If `G`

is not perfect, an exception is thrown.

**Examples**

```
julia> perfect_group_identification(alternating_group(5))
(60, 1)
julia> perfect_group_identification(SL(2,7))
(336, 1)
```

## Groups of small order

TODO: explain about the scope of this.

TODO: give proper attribution to the smallgrp package and other things used (in particular, cite it)

`all_small_groups`

— Function`all_small_groups(L...)`

Return the list of all groups (up to isomorphism) satisfying the conditions described by the arguments. These conditions may be of one of the following forms:

`func => intval`

selects groups for which the function`func`

returns`intval`

`func => list`

selects groups for which the function`func`

returns any element inside`list`

`func`

selects groups for which the function`func`

returns`true`

`!func`

selects groups for which the function`func`

returns`false`

As a special case, the first argument may also be one of the following:

`intval`

selects groups whose order equals`intval`

; this is equivalent to`order => intval`

`intlist`

selects groups whose order is in`intlist`

; this is equivalent to`order => intlist`

Note that at least one of the conditions must impose a limit on the group order, otherwise an exception is thrown.

The following functions are currently supported as values for `func`

:

`exponent`

`is_abelian`

`is_almost_simple`

`is_cyclic`

`is_nilpotent`

`is_perfect`

`is_quasisimple`

`is_simple`

`is_sporadic_simple`

`is_solvable`

`is_supersolvable`

`number_of_conjugacy_classes`

`order`

The type of the returned groups is `PcGroup`

if the group is solvable, `PermGroup`

otherwise.

**Examples**

List all abelian non-cyclic groups of order 12:

```
julia> all_small_groups(12, !is_cyclic, is_abelian)
1-element Vector{PcGroup}:
Pc group of order 12
```

List groups of order 1 to 10 which are not abelian:

```
julia> all_small_groups(1:10, !is_abelian)
4-element Vector{PcGroup}:
Pc group of order 6
Pc group of order 8
Pc group of order 8
Pc group of order 10
```

`has_number_of_small_groups`

— Function`has_number_of_small_groups(n::IntegerUnion)`

Return `true`

if the number of groups of order `n`

is known, otherwise `false`

.

**Examples**

```
julia> has_number_of_small_groups(1024)
true
julia> has_number_of_small_groups(2048)
false
```

`has_small_group_identification`

— Function`has_small_group_identification(n::IntegerUnion)`

Return `true`

if identification for groups of order `n`

is available via `small_group_identification`

, otherwise `false`

.

**Examples**

```
julia> has_small_group_identification(256)
true
julia> has_small_group_identification(512)
false
```

`has_small_groups`

— Function`has_small_groups(n::IntegerUnion)`

Return `true`

if the groups of order `n`

are available via `small_group`

and `all_small_groups`

, otherwise `false`

.

**Examples**

```
julia> has_small_groups(512)
true
julia> has_small_groups(1024)
false
```

`number_of_small_groups`

— Function`number_of_small_groups(n::IntegerUnion)`

Return the number of groups of order `n`

, up to isomorphism.

**Examples**

```
julia> number_of_small_groups(8)
5
julia> number_of_small_groups(4096)
ERROR: ArgumentError: the number of groups of order 4096 is not available
julia> number_of_small_groups(next_prime(ZZRingElem(2)^64))
1
```

`small_group`

— Function```
small_group(::Type{T}, n::IntegerUnion, i::IntegerUnion) where T
small_group(n::IntegerUnion, i::IntegerUnion)
```

Return the `i`

-th group of order `n`

in the Small Groups Library. If a type `T`

is specified then an attempt is made to return the result with that type. If `T`

is omitted then the resulting group will have type `PcGroup`

if it is solvable, otherwise it will be of type `PermGroup`

.

**Examples**

```
julia> small_group(60, 4)
Pc group of order 60
julia> small_group(60, 5)
Permutation group of degree 5 and order 60
julia> small_group(PcGroup, 60, 4)
Pc group of order 60
```

`small_group_identification`

— Function`small_group_identification(G::Group)`

Return a pair of integer `(n, m)`

, where `G`

is isomorphic with `small_group(n, m)`

.

**Examples**

```
julia> small_group_identification(alternating_group(5))
(60, 5)
julia> small_group_identification(symmetric_group(20))
ERROR: ArgumentError: identification is not available for groups of order 2432902008176640000
```

## Atlas of Group Representations

The functions in this section give access to data in the Atlas of Group Representations [ATLAS]. The isomorphism types of the groups in question are specified via names for the groups, which coincide with the names of the corresponding character tables in the library of character tables, see `character_table(id::String, p::Int = 0)`

.

`number_of_atlas_groups`

— Function`number_of_atlas_groups([::Type{T}, ]name::String) where T <: Union{PermGroup, MatrixGroup}`

Return the number of groups from the Atlas of Group Representations whose isomorphism type is given by `name`

and have the type `T`

.

**Examples**

```
julia> number_of_atlas_groups("A5")
18
julia> number_of_atlas_groups(PermGroup, "A5")
3
julia> number_of_atlas_groups(MatrixGroup, "A5")
15
```

`all_atlas_group_infos`

— Function`all_atlas_group_infos(name::String, L...)`

Return the vector of dictionaries that describe Atlas groups whose isomorphism types are given by `name`

and which satisfy the conditions in `L`

. These conditions may be of one of the following forms:

`func => intval`

selects groups for which the function`func`

returns`intval`

`func => list`

selects groups for which the function`func`

returns any element inside`list`

`func`

selects groups for which the function`func`

returns`true`

`!func`

selects groups for which the function`func`

returns`false`

The following functions are currently supported as values for `func`

:

For permutation groups

`degree`

`is_primitive`

`is_transitive`

`rank_action`

`transitivity`

and for matrix groups

`base_ring`

`character`

`characteristic`

`dim`

**Examples**

```
julia> info = all_atlas_group_infos("A5", degree => [5, 6])
2-element Vector{Dict{Symbol, Any}}:
Dict(:constituents => [1, 4], :repname => "A5G1-p5B0", :degree => 5, :name => "A5")
Dict(:constituents => [1, 5], :repname => "A5G1-p6B0", :degree => 6, :name => "A5")
julia> atlas_group(info[1])
Permutation group of degree 5 and order 60
julia> info = all_atlas_group_infos("A5", dim => 4, characteristic => 3)
1-element Vector{Dict{Symbol, Any}}:
Dict(:dim => 4, :constituents => [4], :repname => "A5G1-f3r4B0", :name => "A5")
julia> atlas_group(info[1])
Matrix group of degree 4
over prime field of characteristic 3
```

`atlas_group`

— Function`atlas_group([::Type{T}, ]name::String) where T <: Union{PermGroup, MatrixGroup}`

Return a group from the Atlas of Group Representations whose isomorphism type is given by `name`

and have the type `T`

. If `T`

is not given then `PermGroup`

is chosen if a permutation group for `name`

is available, and `MatrixGroup`

otherwise.

**Examples**

```
julia> atlas_group("A5") # alternating group A5
Permutation group of degree 5 and order 60
julia> atlas_group(MatrixGroup, "A5")
Matrix group of degree 4
over prime field of characteristic 2
julia> atlas_group("M11") # Mathieu group M11
Permutation group of degree 11 and order 7920
julia> atlas_group("M") # Monster group M
ERROR: ArgumentError: the group atlas does not provide a representation for M
```

`atlas_group(info::Dict)`

Return the group from the Atlas of Group Representations that is defined by `info`

. Typically, `info`

is obtained from `all_atlas_group_infos`

.

**Examples**

```
julia> info = all_atlas_group_infos("A5", degree => 5)
1-element Vector{Dict{Symbol, Any}}:
Dict(:constituents => [1, 4], :repname => "A5G1-p5B0", :degree => 5, :name => "A5")
julia> atlas_group(info[1])
Permutation group of degree 5 and order 60
```

`atlas_subgroup`

— Function```
atlas_subgroup(G::GAPGroup, nr::Int)
atlas_subgroup([::Type{T}, ]name::String, nr::Int) where T <: Union{PermGroup, MatrixGroup}
atlas_subgroup(info::Dict, nr::Int)
```

Return a pair `(H, emb)`

where `H`

is a representative of the `nr`

-th class of maximal subgroups of the group `G`

, and `emb`

is an embedding of `H`

into `G`

.

The group `G`

can be given as the first argument, in this case it is assumed that `G`

has been created with `atlas_group`

. Otherwise `G`

is the group obtained by calling `atlas_group`

with (`T`

and) `name`

or with `info`

.

If the Atlas of Group Representations does not provide the information to compute `G`

or to compute generators of `H`

from `G`

then an exception is thrown.

**Examples**

```
julia> g = atlas_group("M11"); # Mathieu group M11
julia> h1, emb = atlas_subgroup(g, 1); h1
Permutation group of degree 11 and order 720
julia> order(h1) # largest maximal subgroup of M11
720
julia> h2, emb = atlas_subgroup("M11", 1); h2
Permutation group of degree 11 and order 720
julia> h3, emb = atlas_subgroup(MatrixGroup, "M11", 1 ); h3
Matrix group of degree 10
over prime field of characteristic 2
julia> info = all_atlas_group_infos("M11", degree => 11);
julia> h4, emb = atlas_subgroup(info[1], 1); h4
Permutation group of degree 11 and order 720
```