Polycyclic groups

Introduction

A polycyclic group is a group $G$ which has a subnormal series $G = G_1 > G_2 > \cdots > G_n > G_{n+1} = \{ 1 \}$ such that the factor groups $G_i/G_{i+1}$ are cyclic.

Polycyclic groups are solvable, and every finite solvable group is polycyclic.

Each polycyclic group has a finite presentation with the following structure: Choose elements $g_i \in G_i \setminus G_{i+1}$, for $1 \leq i \leq n$, such that $G_i = \langle G_{i+1}, g_i \rangle$ holds, and let $r_i$ be the index of $G_{i+1}$ in $G_i$ (a positive integer or infinity), the relative order of $g_i$ w.r.t. the given subnormal series. Then each element of $G$ has a unique expression of the form $g_1^{e_1} g_2^{e_2} \cdots g_n^{e_n}$ where the exponent $e_i$ is in the set $\{ 0, 1, \ldots, r_i-1 \}$ if $r_i$ is finite, and $e_i$ is an integer otherwise; this expression is called the normal form of the group element.

The group $G$ has a presentation with generators $g_1, g_2, \ldots, g_n$ and defining relations of the following form, where we define $I$ as the set of indices $i$ for which $r_i$ is a positive integer.

\[ \begin{array}{lcll} g_i^{r_i} & = & g_{i+1}^{a(i,i,i+1)} \cdots g_n^{a(i,i,n)}, & 1 \leq i \leq n, i \in I \\ g_i^{-1} g_j g_i & = & g_{i+1}^{a(i,j,i+1)} \cdots g_n^{a(i,j,n)}, & 1 \leq i < j \leq n. \end{array}\]

For infinite groups, we need additionally

\[ \begin{array}{lcll} g_i^{-1} g_j^{-1} g_i & = & g_{i+1}^{b(i,j,i+1)} \cdots g_n^{b(i,j,n)}, & 1 \leq i < j \leq n, j \not\in I \\ g_i g_j g_i^{-1} & = & g_{i+1}^{c(i,j,i+1)} \cdots g_n^{c(i,j,n)}, & 1 \leq i < j \leq n, i \not\in I \\ g_i g_j^{-1} g_i^{-1} & = & g_{i+1}^{d(i,j,i+1)} \cdots g_n^{d(i,j,n)}, & 1 \leq i < j \leq n, i, j, \not\in I. \end{array}\]

Here we assume that the right hand sides are words in normal form.

This presentation describes a confluent rewriting system, thus it admits the computation of the normal form for each group element. Inverses and products of elements given by their normal forms can be efficiently written in normal form.

Groups which are given by a polycyclic presentation are called polycyclicly presented groups. The rest of this section is about these groups.

Polycyclicly presented groups in Oscar have the type PcGroup, their elements have the type PcGroupElem. Analogous to the situation with finitely presented groups and their subgroups, there are the types SubPcGroup for subgroups and SubPcGroupElem for their elements.

Basic Creation

One can write down a polycyclic presentation by hand, using a so-called collector, and then creating a group with this presentation.

julia> c = collector(2, Int);

julia> set_relative_orders!(c, [2, 3])

julia> set_conjugate!(c, 2, 1, [2 => 2])

julia> gg = pc_group(c)
Pc group of order 6

julia> describe(gg)
"S3"

Alternatively, one can take a polycyclic group, and let Oscar compute a pc presentation for it.

julia> g = symmetric_group(4)
Sym(4)

julia> iso = isomorphism(PcGroup, g);

julia> h = codomain(iso)
Pc group of order 24

For certain series of groups, one can create the members as pc groups.

julia> dihedral_group(8)
Pc group of order 8

And the groups from the small groups library are represented by pc groups whenever they are solvable.

julia> small_group(24, 12)
Pc group of order 24

Functions for (subgroups of) pc groups and their elements

relatorsMethod
relators(G::PcGroup)

Return a vector of elements in a free group of rank ngens(G) that describes the defining relators of the underlying polycyclic presentation of G.

Examples

julia> g = dihedral_group(8)
Pc group of order 8

julia> relators(g)
6-element Vector{FPGroupElem}:
 g1^2
 g2^-1*g1^-1*g2*g1*g3^-1
 g3^-1*g1^-1*g3*g1
 g2^2*g3^-1
 g3^-1*g2^-1*g3*g2
 g3^2
source
map_wordMethod
map_word(g::Union{PcGroupElem, SubPcGroupElem}, genimgs::Vector; genimgs_inv::Vector = Vector(undef, length(genimgs)), init = nothing)

If init is nothing, return the product $R_1 R_2 \cdots R_n$ that is described by g. This is a product of the form $g_{i_1}^{e_1} g_{i_2}^{e_2} \cdots g_{i_n}^{e_n}$ where $g_i$ is the $i$-th entry in the defining polycyclic generating sequence of full_group(parent(g)) and the $e_i$ are nonzero integers, and $R_j =$ genimgs[$i_j$]$^{e_j}$.

If init is different from nothing, return $x g_{i_1}^{e_1} g_{i_2}^{e_2} \cdots g_{i_n}^{e_n}$ where $x =$ init.

See also: map_word(::Union{FPGroupElem, SubFPGroupElem}, ::Vector), `map_word(::WeylGroupElem, ::Vector).

Examples

julia> G = dihedral_group(10)
Pc group of order 10

julia> x, y = gens(G);  g = x * y^4
f1*f2^4

julia> map_word(g, gens(free_group(:x, :y)))
x*y^4

julia> map_word(g, [3, 2], init=5)
240
source

The function full_group(G::T) where T <: Union{SubFPGroup, SubPcGroup} for finitely presented groups is applicable to polycyclicly presented groups as well.

Series of polycyclic groups

The following functions can be used to create polycyclicly presented groups from certain series of groups.

(In fact, one can request also other types for the results, but PcGroup is the default type in all cases except abelian_group.)

abelian_groupMethod
abelian_group(::Type{T} = PcGroup, v::Vector{S}) where T <: Group where S <: IntegerUnion

Return the direct product of cyclic groups of the orders v[1], v[2], $\ldots$, v[n], as an instance of T. Here, T must be one of PermGroup, FPGroup, SubFPGroup, PcGroup, or SubPcGroup.

The gens value of the returned group corresponds to v, that is, the number of generators is equal to length(v) and the order of the i-th generator is v[i].

Warning

The type need to be specified in the input of the function abelian_group, otherwise a group of type FinGenAbGroup is returned, which is not a GAP group type. In future versions of Oscar, this may change.

source
elementary_abelian_groupFunction
elementary_abelian_group(::Type{T} = PcGroup, n::S) where T <: Group where S <: IntegerUnion

Return the elementary abelian group group of order n, as an instance of T. Here, T must be one of PermGroup, FPGroup, SubFPGroup, PcGroup, SubPcGroup, or FinGenAbGroup, and n must be a prime power or 1.

The gens vector of the result has minimal length.

Examples

julia> g = elementary_abelian_group(27)
Pc group of order 27

julia> g = elementary_abelian_group(PermGroup, 27)
Permutation group of degree 9 and order 27
source
cyclic_groupFunction
cyclic_group(::Type{T} = PcGroup, n::IntegerUnion)
cyclic_group(::Type{T} = PcGroup, n::PosInf)

Return the cyclic group of order n, as an instance of type T.

Examples

julia> G = cyclic_group(5)
Pc group of order 5

julia> G = cyclic_group(PermGroup, 5)
Permutation group of degree 5 and order 5

julia> G = cyclic_group(PosInf())
Pc group of infinite order
source
dihedral_groupFunction
dihedral_group(::Type{T} = PcGroup, n::Union{IntegerUnion,PosInf})

Return the dihedral group of order n, as an instance of T, where T is in {PcGroup, SubPcGroup, PermGroup, FPGroup, SubFPGroup}.

Warning

There are two competing conventions for interpreting the argument n: In the one we use, the returned group has order n, and thus n must always be even. In the other, n indicates that the group describes the symmetry of an n-gon, and thus the group has order 2n.

Examples

julia> dihedral_group(6)
Pc group of order 6

julia> dihedral_group(PermGroup, 6)
Permutation group of degree 3

julia> dihedral_group(PosInf())
Pc group of infinite order

julia> dihedral_group(7)
ERROR: ArgumentError: n must be a positive even integer or infinity
source
quaternion_groupFunction
quaternion_group(::Type{T} = PcGroup, n::IntegerUnion)

Return the (generalized) quaternion group of order n, as an instance of T, where n is a power of 2 and T is in {PcGroup, SubPcGroup, PermGroup,FPGroup, SubFPGroup}.

Examples

julia> g = quaternion_group(8)
Pc group of order 8

julia> quaternion_group(PermGroup, 8)
Permutation group of degree 8

julia> g = quaternion_group(FPGroup, 8)
Finitely presented group of order 8

julia> relators(g)
3-element Vector{FPGroupElem}:
 r^2*s^-2
 s^4
 r^-1*s*r*s
source

Collectors for polycyclicly presented groups

The following functions can be used to enter polycyclic presentations by hand, or to create new such presentations from given ones.

collectorMethod
collector(n::Int, ::Type{T} = ZZRingElem) where T <: IntegerUnion

Return an empty collector object for a pc group with n generators and exponents of type T. It describes a free abelian group of rank n.

Examples

julia> G = pc_group(collector(2))
Pc group of infinite order

julia> is_abelian(G)
true
source
set_relative_order!Method
set_relative_order!(c::Collector{T}, i::Int, relord::T) where T <: IntegerUnion

Set the relative order of the i-th generator of c to relord, which must be either 0 (meaning infinite order) or a positive integer.

Examples

julia> c = collector(2, Int);

julia> set_relative_order!(c, 1, 2)
source
get_relative_orderMethod
get_relative_order(c::Collector{T}, i::Int) where T <: IntegerUnion

Get the relative order of the i-th generator of c.

Examples

julia> c = collector(2, Int);

julia> get_relative_order(c, 1)
0

julia> set_relative_order!(c, 1, 2)

julia> get_relative_order(c, 1)
2
source
set_relative_orders!Method
set_relative_orders!(c::Collector{T}, relords::Vector{T})

Set all relative orders of the generators of c, where the length of relords must be equal to the number of generators of c, and relords[i] denotes the relative order of the i-th generator. which must be either 0 (meaning infinite order) or a positive integer.

Examples

julia> c = collector(2);

julia> set_relative_orders!(c, ZZRingElem[2, 0])
source
get_relative_ordersMethod
get_relative_orders(c::Collector{T})

Get the Vector{T} of all relative orders of the generators of c.

Examples

julia> c = collector(2);

julia> get_relative_orders(c)
2-element Vector{ZZRingElem}:
 0
 0

julia> set_relative_orders!(c, ZZRingElem[2, 0])

julia> get_relative_orders(c)
2-element Vector{ZZRingElem}:
 2
 0
source
set_power!Method
set_power!(c::Collector{T}, i::Int, rhs::Vector{Pair{Int, T}}) where T <: IntegerUnion

Set the c.relorders[i]-th power of the i-th generator of c to the group element described by rhs.

Examples

julia> c = collector(2, Int);

julia> set_relative_order!(c, 1, 2)

julia> set_relative_order!(c, 2, 3)

julia> set_power!(c, 1, [2 => 1])
source
get_powerMethod
get_power(c::Collector{T}, i::Int) where T <: IntegerUnion

Get the Vector{Pair{Int, T}} that describes the c.relorders[i]-th power of the i-th generator of c.

Examples

julia> c = collector(2, Int);

julia> set_relative_order!(c, 1, 2)

julia> set_relative_order!(c, 2, 3)

julia> get_power(c, 1)
Pair{Int64, Int64}[]

julia> set_power!(c, 1, [2 => 1])

julia> get_power(c, 1)
1-element Vector{Pair{Int64, Int64}}:
 2 => 1
source
set_conjugate!Method
set_conjugate!(c::Collector{T}, j::Int, i::Int, rhs::Vector{Pair{Int, T}}) where T <: IntegerUnion

Set the value of the conjugate of the j-th generator of c by the i-th generator of c, for i < j, to the group element described by rhs.

Examples

julia> c = collector(2, Int);

julia> set_relative_orders!(c, [2, 3])

julia> set_conjugate!(c, 2, 1, [2 => 2])
source
get_conjugateMethod
get_conjugate(c::Collector{T}, j::Int, i::Int) where T <: IntegerUnion

Get the Vector{Pair{Int, T}} that describes the conjugate of the j-th generator of c by the i-th generator of c, for i < j.

Examples

julia> c = collector(2, Int);

julia> set_relative_orders!(c, [2, 3])

julia> get_conjugate(c, 2, 1)
1-element Vector{Pair{Int64, Int64}}:
 2 => 1

julia> set_conjugate!(c, 2, 1, [2 => 2])

julia> get_conjugate(c, 2, 1)
1-element Vector{Pair{Int64, Int64}}:
 2 => 2
source
set_commutator!Method
set_commutator!(c::Collector{T}, j::Int, i::Int, rhs::Vector{Pair{Int, T}}) where T <: IntegerUnion

Set the value of the commutator of the i-th and the j-th generator of c, for i < j, to the group element described by rhs.

Examples

julia> c = collector(2, Int);

julia> set_relative_orders!(c, [2, 3])

julia> set_commutator!(c, 2, 1, [2 => 1])
source
pc_groupMethod
pc_group(c::GAP_Collector)

Create a PcGroup object from c.

Examples

julia> c = collector(2, Int);

julia> Oscar.set_relative_orders!(c, [2, 3])

julia> Oscar.set_conjugate!(c, 2, 1, [2 => 2])

julia> gg = pc_group(c)
Pc group of order 6

julia> describe(gg)
"S3"
source
collectorMethod
collector([::Type{T} = ZZRingElem, ]G::PcGroup) where T <: IntegerUnion

Return a collector object for G.

Examples

julia> g = small_group(12, 3)
Pc group of order 12

julia> c = collector(g);

julia> gc = pc_group(c)
Pc group of order 12

julia> is_isomorphic(g, gc)
true
source

Technicalities

PcGroupType
PcGroup

Polycyclic group, a group that is defined by a finite presentation of a special kind, a so-called polycyclic presentation. Contrary to arbitrary finitely presented groups (see Finitely presented groups), this presentation allows for efficient computations with the group elements.

For a group G of type PcGroup, the elements in gens(G) satisfy the relators of the underlying presentation.

Functions that compute subgroups of G return groups of type SubPcGroup.

Examples

  • cyclic_group(n::Int): cyclic group of order n
  • abelian_group(PcGroup, v::Vector{Int}): direct product of cyclic groups of the orders v[1], v[2], ..., v[length(v)]
source
PcGroupElemType
PcGroupElem

Element of a polycyclic group.

The generators of a polycyclic group are displayed as f1, f2, f3, etc., and every element of a polycyclic group is displayed as product of the generators.

Examples

julia> G = abelian_group(PcGroup, [2, 3]);

julia> G[1], G[2]
(f1, f2)

julia> G[2]*G[1]
f1*f2

Note that this does not define Julia variables named f1, f2, etc.! To get the generators of the group G, use gens(G); for convenience they can also be accessed as G[1], G[2], as shown in Section Elements of groups.

source
SubPcGroupType
SubPcGroup

Subgroup of a polycyclic group, a group that is defined by generators that are elements of a group G of type PcGroup. The arithmetic operations with elements are thus performed using the polycyclic presentation of G.

Operations for computing subgroups of a group of type PcGroup or SubPcGroup, such as derived_subgroup and sylow_subgroup, return groups of type SubPcGroup.

source
SubPcGroupElemType
SubPcGroupElem

Element of a subgroup of a polycyclic group.

The elements are displayed in the same way as the elements of full polycyclic groups, see PcGroupElem.

Examples

julia> G = abelian_group(SubPcGroup, [4, 2]);

julia> G[1], G[2]
(f1, f3)

julia> G[2]*G[1]
f1*f3
source