Permutation groups - Groups

Skip to content
Back to top
View this page
Edit this page

# Permutation groups

A permutation group is a finite group \(G\) whose elements are permutations of a given finite set \(X\) (i.e., bijections \(X \longrightarrow X\)) and whose group operation is the composition of permutations. The number of elements of \(X\) is called the degree of \(G\).

In Sage, a permutation is represented as either a string that defines a permutation using disjoint cycle notation, or a list of tuples, which represent disjoint cycles. That is:

    (a,...,b)(c,...,d)...(e,...,f)  <--> [(a,...,b), (c,...,d),..., (e,...,f)]
                      () = identity <--> []

You can make the “named” permutation groups (see `permgp_named.py`) and use the following constructions:

- permutation group generated by elements,

- `direct_product_permgroups`, which takes a list of permutation groups and returns their direct product.

JOKE: Q: What’s hot, chunky, and acts on a polygon? A: Dihedral soup. Renteln, P. and Dundes, A. “Foolproof: A Sampling of Mathematical Folk Humor.” Notices Amer. Math. Soc. 52, 24-34, 2005.

## Index of methods

Here are the methods of a `PermutationGroup()`

`are_conjugate()` | Return whether `H1` and `H2` are conjugate subgroups in `G`.
`as_finitely_presented_group()` | Return a finitely presented group isomorphic to `self`.
`blocks_all()` | Return the list of block systems of imprimitivity.
`cardinality()` | Return the number of elements of this group.
`center()` | Return the subgroup of elements that commute with every element of this group.
`centralizer()` | Return the centralizer of `g` in `self`.
`character()` | Return a group character from `values`, where `values` is a list of the values of the character evaluated on the conjugacy classes.
`character_table()` | Return the matrix of values of the irreducible characters of a permutation group \(G\) at the conjugacy classes of \(G\).
`cohomology()` | Compute the group cohomology \(H^n(G, F)\), where \(F = \ZZ\) if \(p=0\) and \(F = \ZZ / p \ZZ\) if \(p > 0\) is a prime.
`cohomology_part()` | Compute the p-part of the group cohomology \(H^n(G, F)\), where \(F = \ZZ\) if \(p=0\) and \(F = \ZZ / p \ZZ\) if \(p > 0\) is a prime.
`commutator()` | Return the commutator subgroup of a group, or of a pair of groups.
`composition_series()` | Return the composition series of this group as a list of permutation groups.
`conjugacy_class()` | Return the conjugacy class of `g` inside the group `self`.
`conjugacy_classes()` | Return a list with all the conjugacy classes of `self`.
`conjugacy_classes_representatives()` | Return a complete list of representatives of conjugacy classes in a permutation group \(G\).
`conjugacy_classes_subgroups()` | Return a complete list of representatives of conjugacy classes of subgroups in a permutation group \(G\).
`conjugate()` | Return the group formed by conjugating `self` with `g`.
`construction()` | Return the construction of `self`.
`cosets()` | Return a list of the cosets of `S` in `self`.
`degree()` | Return the degree of this permutation group.
`derived_series()` | Return the derived series of this group as a list of permutation groups.
`direct_product()` | Wraps GAP’s `DirectProduct`, `Embedding`, and `Projection`.
`domain()` | Return the underlying set that this permutation group acts on.
`exponent()` | Compute the exponent of the group.
`fitting_subgroup()` | Return the Fitting subgroup of `self`.
`fixed_points()` | Return the list of points fixed by `self`, i.e., the subset of `.domain()` not moved by any element of `self`.
`frattini_subgroup()` | Return the Frattini subgroup of `self`.
`gen()` | Return the \(i\)-th generator of `self`; that is, the \(i\)-th element of the list `self.gens()`.
`gens()` | Return tuple of generators of this group.
`gens_small()` | For this group, returns a generating set which has few elements.
`group_id()` | Return the ID code of this group, which is a list of two integers.
`group_primitive_id()` | Return the index of this group in the GAP database of primitive groups.
`holomorph()` | The holomorph of a group as a permutation group.
`homology()` | Compute the group homology \(H_n(G, F)\), where \(F = \ZZ\) if \(p=0\) and \(F = \ZZ / p \ZZ\) if \(p > 0\) is a prime. Wraps HAP’s `GroupHomology` function, written by Graham Ellis.
`homology_part()` | Compute the \(p\)-part of the group homology \(H_n(G, F)\), where \(F = \ZZ\) if \(p=0\) and \(F = \ZZ / p \ZZ\) if \(p > 0\) is a prime. Wraps HAP’s `Homology` function, written by Graham Ellis, applied to the \(p\)-Sylow subgroup of \(G\).
`id()` | Return the ID code of this group, which is a list of two integers.
`intersection()` | Return the permutation group that is the intersection of `self` and `other`.
`irreducible_characters()` | Return a list of the irreducible characters of `self`.
`is_cyclic()` | Return `True` if this group is cyclic.
`is_elementary_abelian()` | Return `True` if this group is elementary abelian.
`is_isomorphic()` | Return `True` if the groups are isomorphic.
`is_monomial()` | Return `True` if the group is monomial. A finite group is monomial if every irreducible complex character is induced from a linear character of a subgroup.
`is_nilpotent()` | Return `True` if this group is nilpotent.
`is_normal()` | Return `True` if this group is a normal subgroup of `other`.
`is_perfect()` | Return `True` if this group is perfect. A group is perfect if it equals its derived subgroup.
`is_pgroup()` | Return `True` if this group is a \(p\)-group.
`is_polycyclic()` | Return `True` if this group is polycyclic. A group is polycyclic if it has a subnormal series with cyclic factors. (For finite groups, this is the same as if the group is solvable - see `is_solvable()`.)
`is_primitive()` | Return `True` if `self` acts primitively on `domain`.
`is_regular()` | Return `True` if `self` acts regularly on `domain`.
`is_semi_regular()` | Return `True` if `self` acts semi-regularly on `domain`.
`is_simple()` | Return `True` if the group is simple.
`is_solvable()` | Return `True` if the group is solvable.
`is_subgroup()` | Return `True` if `self` is a subgroup of `other`.
`is_supersolvable()` | Return `True` if the group is supersolvable.
`is_transitive()` | Return `True` if `self` acts transitively on `domain`.
`isomorphism_to()` | Return an isomorphism from `self` to `right` if the groups are isomorphic, otherwise `None`.
`isomorphism_type_info_simple_group()` | If the group is simple, then this returns the name of the group.
`iteration()` | Return an iterator over the elements of this group.
`largest_moved_point()` | Return the largest point moved by a permutation in this group.
`list()` | Return list of all elements of this group.
`lower_central_series()` | Return the lower central series of this group as a list of permutation groups.
`maximal_normal_subgroups()` | Return the maximal proper normal subgroups of `self`.
`minimal_generating_set()` | Return a minimal generating set.
`minimal_normal_subgroups()` | Return the nontrivial minimal normal subgroups `self`.
`molien_series()` | Return the Molien series of a permutation group. The function
`ngens()` | Return the number of generators of `self`.
`non_fixed_points()` | Return the list of points not fixed by `self`, i.e., the subset of `self.domain()` moved by some element of `self`.
`normal_subgroups()` | Return the normal subgroups of this group as a (sorted in increasing order) list of permutation groups.
`normalizer()` | Return the normalizer of `g` in `self`.
`normalizes()` | Return `True` if the group `other` is normalized by `self`.
`poincare_series()` | Return the Poincaré series of \(G \mod p\) (\(p \geq 2\) must be a prime), for \(n\) large.
`random_element()` | Return a random element of this group.
`representative_action()` | Return an element of `self` that maps \(x\) to \(y\) if it exists.
`semidirect_product()` | The semidirect product of `self` with `N`.
`sign_representation()` | Return the sign representation of `self` over `base_ring`.
`socle()` | Return the socle of `self`.
`solvable_radical()` | Return the solvable radical of `self`.
`stabilizer()` | Return the subgroup of `self` which stabilize the given position. `self` and its stabilizers must have same degree.
`strong_generating_system()` | Return a Strong Generating System of `self` according the given base for the right action of `self` on itself.
`structure_description()` | Return a string that tries to describe the structure of `G`.
`subgroup()` | Wraps the `PermutationGroup_subgroup` constructor. The argument `gens` is a list of elements of `self`.
`subgroups()` | Return a list of all the subgroups of `self`.
`sylow_subgroup()` | Return a Sylow \(p\)-subgroup of the finite group \(G\), where \(p\) is a prime.
`transversals()` | If G is a permutation group acting on the set \(X = \{1, 2, ...., n\}\) and H is the stabilizer subgroup of <integer>, a right (respectively left) transversal is a set containing exactly one element from each right (respectively left) coset of H. This method returns a right transversal of `self` by the stabilizer of `self` on <integer> position.
`trivial_character()` | Return the trivial character of `self`.
`upper_central_series()` | Return the upper central series of this group as a list of permutation groups.

AUTHORS:

- David Joyner (2005-10-14): first version

- David Joyner (2005-11-17)

- William Stein (2005-11-26): rewrite to better wrap Gap

- David Joyner (2005-12-21)

- William Stein and David Joyner (2006-01-04): added conjugacy_class_representatives

- David Joyner (2006-03): reorganization into subdirectory perm_gps; added __contains__, has_element; fixed _cmp_; added subgroup class+methods, PGL,PSL,PSp, PSU classes,

- David Joyner (2006-06): added PGU, functionality to SymmetricGroup, AlternatingGroup, direct_product_permgroups

- David Joyner (2006-08): added degree, ramification_module_decomposition_modular_curve and ramification_module_decomposition_hurwitz_curve methods to PSL(2,q), MathieuGroup, is_isomorphic

- Bobby Moretti (2006)-10): Added KleinFourGroup, fixed bug in DihedralGroup

- David Joyner (2006-10): added is_subgroup (fixing a bug found by Kiran Kedlaya), is_solvable, normalizer, is_normal_subgroup, Suzuki

- David Kohel (2007-02): fixed __contains__ to not enumerate group elements, following the convention for __call__

- David Harvey, Mike Hansen, Nick Alexander, William Stein (2007-02,03,04,05): Various patches

- Nathan Dunfield (2007-05): added orbits

- David Joyner (2007-06): added subgroup method (suggested by David Kohel), composition_series, lower_central_series, upper_central_series, cayley_table, quotient_group, sylow_subgroup, is_cyclic, homology, homology_part, cohomology, cohomology_part, poincare_series, molien_series, is_simple, is_monomial, is_supersolvable, is_nilpotent, is_perfect, is_polycyclic, is_elementary_abelian, is_pgroup, gens_small, isomorphism_type_info_simple_group. moved all the”named” groups to a new file.

- Nick Alexander (2007-07): move is_isomorphic to isomorphism_to, add from_gap_list

- William Stein (2007-07): put is_isomorphic back (and make it better)

- David Joyner (2007-08): fixed bugs in composition_series, upper/lower_central_series, derived_series,

- David Joyner (2008-06): modified is_normal (reported by W. J. Palenstijn), and added normalizes

- David Joyner (2008-08): Added example to docstring of cohomology.

- Simon King (2009-04): __cmp__ methods for PermutationGroup_generic and PermutationGroup_subgroup

- Nicolas Borie (2009): Added orbit, transversals, stabiliser and strong_generating_system methods

- Christopher Swenson (2012): Added a special case to compute the order efficiently. (This patch Copyright 2012 Google Inc. All Rights Reserved. )

- Javier Lopez Pena (2013): Added conjugacy classes.

- Sebastian Oehms (2018): added _coerce_map_from_ in order to use isomorphism coming up with as_permutation_group method (Issue #25706)

- Christian Stump (2018): Added alternative implementation of strong_generating_system directly using GAP.

- Sebastian Oehms (2018): Added `PermutationGroup_generic._Hom_()` to use `sage.groups.libgap_morphism.GroupHomset_libgap` and `PermutationGroup_generic.gap()` and `PermutationGroup_generic._subgroup_constructor()` (for compatibility to libgap framework, see Issue #26750

REFERENCES:

- Cameron, P., Permutation Groups. New York: Cambridge University Press, 1999.

- Wielandt, H., Finite Permutation Groups. New York: Academic Press, 1964.

- Dixon, J. and Mortimer, B., Permutation Groups, Springer-Verlag, Berlin/New York, 1996.

Note

Though Suzuki groups are okay, Ree groups should not be wrapped as permutation groups - the construction is too slow - unless (for small values or the parameter) they are made using explicit generators.

sage.groups.perm_gps.permgroup.PermutationGroup(gens=None, *args, **kwds)

  Return the permutation group associated to \(x\) (typically a list of generators).

  INPUT:

  - `gens` – (default: `None`) list of generators

  - `gap_group` – (optional) a gap permutation group

  - `canonicalize` – boolean (default: `True`); if `True`, sort generators and remove duplicates

  OUTPUT: a permutation group

  EXAMPLES:

  Sage

      sage: G = PermutationGroup([[(1,2,3),(4,5)],[(3,4)]])
      sage: G
      Permutation Group with generators [(3,4), (1,2,3)(4,5)]

  Python

      >>> from sage.all import *
      >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3)),(Integer(4),Integer(5))],[(Integer(3),Integer(4))]])
      >>> G
      Permutation Group with generators [(3,4), (1,2,3)(4,5)]

  We can also make permutation groups from PARI groups:

  Sage

      sage: # needs sage.libs.pari
      sage: H = pari('x^4 - 2*x^3 - 2*x + 1').polgalois()
      sage: G = PariGroup(H, 4); G
      PARI group [8, -1, 3, "D(4)"] of degree 4
      sage: H = PermutationGroup(G); H
      Transitive group number 3 of degree 4
      sage: H.gens()
      ((1,2,3,4), (1,3))

  [Python]

      >>> from sage.all import *
      >>> # needs sage.libs.pari
      >>> H = pari('x^4 - 2*x^3 - 2*x + 1').polgalois()
      >>> G = PariGroup(H, Integer(4)); G
      PARI group [8, -1, 3, "D(4)"] of degree 4
      >>> H = PermutationGroup(G); H
      Transitive group number 3 of degree 4
      >>> H.gens()
      ((1,2,3,4), (1,3))

  We can also create permutation groups whose generators are GAP permutation objects:

  Sage

      sage: p = gap('(1,2)(3,7)(4,6)(5,8)'); p
      (1,2)(3,7)(4,6)(5,8)
      sage: PermutationGroup([p])
      Permutation Group with generators [(1,2)(3,7)(4,6)(5,8)]

  Python

      >>> from sage.all import *
      >>> p = gap('(1,2)(3,7)(4,6)(5,8)'); p
      (1,2)(3,7)(4,6)(5,8)
      >>> PermutationGroup([p])
      Permutation Group with generators [(1,2)(3,7)(4,6)(5,8)]

  Permutation groups can work on any domain. In the following examples, the permutations are specified in list notation, according to the order of the elements of the domain:

  Sage

      sage: list(PermutationGroup([['b','c','a']], domain=['a','b','c']))
      [(), ('a','b','c'), ('a','c','b')]
      sage: list(PermutationGroup([['b','c','a']], domain=['b','c','a']))
      [()]
      sage: list(PermutationGroup([['b','c','a']], domain=['a','c','b']))
      [(), ('a','b')]

  [Python]

      >>> from sage.all import *
      >>> list(PermutationGroup([['b','c','a']], domain=['a','b','c']))
      [(), ('a','b','c'), ('a','c','b')]
      >>> list(PermutationGroup([['b','c','a']], domain=['b','c','a']))
      [()]
      >>> list(PermutationGroup([['b','c','a']], domain=['a','c','b']))
      [(), ('a','b')]

  There is an underlying gap object that implements each permutation group:

  Sage

      sage: G = PermutationGroup([[(1,2,3,4)]])
      sage: G._gap_()
      Group( [ (1,2,3,4) ] )
      sage: gap(G)
      Group( [ (1,2,3,4) ] )
      sage: gap(G) is G._gap_()
      True
      sage: G = PermutationGroup([[(1,2,3),(4,5)],[(3,4)]])
      sage: current_randstate().set_seed_gap()
      sage: G1, G2 = G._gap_().DerivedSeries()
      sage: G1
      Group( [ (3,4), (1,2,3)(4,5) ] )
      sage: G2.GeneratorsSmallest()
      [ (3,4,5), (2,3)(4,5), (1,2)(4,5) ]

  Python

      >>> from sage.all import *
      >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))]])
      >>> G._gap_()
      Group( [ (1,2,3,4) ] )
      >>> gap(G)
      Group( [ (1,2,3,4) ] )
      >>> gap(G) is G._gap_()
      True
      >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3)),(Integer(4),Integer(5))],[(Integer(3),Integer(4))]])
      >>> current_randstate().set_seed_gap()
      >>> G1, G2 = G._gap_().DerivedSeries()
      >>> G1
      Group( [ (3,4), (1,2,3)(4,5) ] )
      >>> G2.GeneratorsSmallest()
      [ (3,4,5), (2,3)(4,5), (1,2)(4,5) ]

  We can create a permutation group from a group action:

  Sage

      sage: a = lambda x: (2*x) % 7
      sage: H = PermutationGroup(action=a, domain=range(7))                           # needs sage.combinat
      sage: H.orbits()                                                                # needs sage.libs.pari
      ((0,), (1, 2, 4), (3, 6, 5))
      sage: H.gens()                                                                  # needs sage.libs.pari
      ((1,2,4), (3,6,5))

  [Python]

      >>> from sage.all import *
      >>> a = lambda x: (Integer(2)*x) % Integer(7)
      >>> H = PermutationGroup(action=a, domain=range(Integer(7)))                           # needs sage.combinat
      >>> H.orbits()                                                                # needs sage.libs.pari
      ((0,), (1, 2, 4), (3, 6, 5))
      >>> H.gens()                                                                  # needs sage.libs.pari
      ((1,2,4), (3,6,5))

  Note that we provide generators for the acting group. The permutation group we construct is its homomorphic image:

  Sage

      sage: # needs sage.combinat
      sage: a = lambda g, x: vector(g*x, immutable=True)
      sage: X = [vector(x, immutable=True) for x in GF(3)^2]
      sage: G = SL(2,3); G.gens()
      (
      [1 1]  [0 1]
      [0 1], [2 0]
      )
      sage: H = PermutationGroup(G.gens(), action=a, domain=X)
      sage: H.orbits()
      (((0, 0),), ((1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, 2), (1, 2), (2, 2)))
      sage: H.gens()
      (((0,1),(1,1),(2,1))((0,2),(2,2),(1,2)),
       ((1,0),(0,2),(2,0),(0,1))((1,1),(1,2),(2,2),(2,1)))

  Python

      >>> from sage.all import *
      >>> # needs sage.combinat
      >>> a = lambda g, x: vector(g*x, immutable=True)
      >>> X = [vector(x, immutable=True) for x in GF(Integer(3))**Integer(2)]
      >>> G = SL(Integer(2),Integer(3)); G.gens()
      (
      [1 1]  [0 1]
      [0 1], [2 0]
      )
      >>> H = PermutationGroup(G.gens(), action=a, domain=X)
      >>> H.orbits()
      (((0, 0),), ((1, 0), (2, 0), (0, 1), (1, 1), (2, 1), (0, 2), (1, 2), (2, 2)))
      >>> H.gens()
      (((0,1),(1,1),(2,1))((0,2),(2,2),(1,2)),
       ((1,0),(0,2),(2,0),(0,1))((1,1),(1,2),(2,2),(2,1)))

  The orbits of the conjugation action are the conjugacy classes, i.e., in bijection with integer partitions:

  Sage

      sage: a = lambda g, x: g*x*g^-1
      sage: [len(PermutationGroup(SymmetricGroup(n).gens(), action=a,                 # needs sage.combinat
      ....:                       domain=SymmetricGroup(n)).orbits())
      ....:  for n in range(1, 8)]
      [1, 2, 3, 5, 7, 11, 15]

  [Python]

      >>> from sage.all import *
      >>> a = lambda g, x: g*x*g**-Integer(1)
      >>> [len(PermutationGroup(SymmetricGroup(n).gens(), action=a,                 # needs sage.combinat
      ...                       domain=SymmetricGroup(n)).orbits())
      ...  for n in range(Integer(1), Integer(8))]
      [1, 2, 3, 5, 7, 11, 15]

class sage.groups.perm_gps.permgroup.PermutationGroup_action(gens, action, domain, gap_group=None, category=None, canonicalize=None)

  Bases: `PermutationGroup_generic`

  A permutation group given by a finite group action.

  EXAMPLES:

  A cyclic action:

  Sage

      sage: n = 3
      sage: a = lambda x: SetPartition([[e % n + 1 for e in b] for b in x])
      sage: S = SetPartitions(n)                                                      # needs sage.combinat
      sage: G = PermutationGroup(action=a, domain=S)                                  # needs sage.combinat
      sage: G.orbits()                                                                # needs sage.combinat
      (({{1}, {2}, {3}},),
       ({{1, 2}, {3}}, {{1}, {2, 3}}, {{1, 3}, {2}}),
       ({{1, 2, 3}},))

  Python

      >>> from sage.all import *
      >>> n = Integer(3)
      >>> a = lambda x: SetPartition([[e % n + Integer(1) for e in b] for b in x])
      >>> S = SetPartitions(n)                                                      # needs sage.combinat
      >>> G = PermutationGroup(action=a, domain=S)                                  # needs sage.combinat
      >>> G.orbits()                                                                # needs sage.combinat
      (({{1}, {2}, {3}},),
       ({{1, 2}, {3}}, {{1}, {2, 3}}, {{1, 3}, {2}}),
       ({{1, 2, 3}},))

  The regular action of the symmetric group:

  Sage

      sage: a = lambda g, x: g*x*g^-1
      sage: S = SymmetricGroup(3)
      sage: G = PermutationGroup(S.gens(), action=a, domain=S)                        # needs sage.combinat
      sage: G.orbits()                                                                # needs sage.combinat
      (((),), ((1,3,2), (1,2,3)), ((2,3), (1,3), (1,2)))

  [Python]

      >>> from sage.all import *
      >>> a = lambda g, x: g*x*g**-Integer(1)
      >>> S = SymmetricGroup(Integer(3))
      >>> G = PermutationGroup(S.gens(), action=a, domain=S)                        # needs sage.combinat
      >>> G.orbits()                                                                # needs sage.combinat
      (((),), ((1,3,2), (1,2,3)), ((2,3), (1,3), (1,2)))

  The trivial action of the symmetric group:

  Sage

      sage: PermutationGroup(SymmetricGroup(3).gens(),                                # needs sage.combinat
      ....:                  action=lambda g, x: x, domain=[1])
      Permutation Group with generators [()]

  Python

      >>> from sage.all import *
      >>> PermutationGroup(SymmetricGroup(Integer(3)).gens(),                                # needs sage.combinat
      ...                  action=lambda g, x: x, domain=[Integer(1)])
      Permutation Group with generators [()]

  orbits()

    Return the orbits of the elements of the domain under the default group action.

    EXAMPLES:

    Sage

        sage: a = lambda x: (2*x) % 7
        sage: G = PermutationGroup(action=a, domain=range(7))                       # needs sage.combinat
        sage: G.orbits()                                                            # needs sage.combinat
        ((0,), (1, 2, 4), (3, 6, 5))

    Python

        >>> from sage.all import *
        >>> a = lambda x: (Integer(2)*x) % Integer(7)
        >>> G = PermutationGroup(action=a, domain=range(Integer(7)))                       # needs sage.combinat
        >>> G.orbits()                                                            # needs sage.combinat
        ((0,), (1, 2, 4), (3, 6, 5))

class sage.groups.perm_gps.permgroup.PermutationGroup_generic(gens=None, gap_group=None, canonicalize=True, domain=None, category=None)

  Bases: `FiniteGroup`

  A generic permutation group.

  EXAMPLES:

  Sage

      sage: G = PermutationGroup([[(1,2,3),(4,5)],[(3,4)]])
      sage: G
      Permutation Group with generators [(3,4), (1,2,3)(4,5)]
      sage: G.center()
      Subgroup generated by [()] of
       (Permutation Group with generators [(3,4), (1,2,3)(4,5)])
      sage: G.group_id()
      [120, 34]
      sage: n = G.order(); n
      120
      sage: G = PermutationGroup([[(1,2,3),(4,5)],[(3,4)]])
      sage: TestSuite(G).run()

  Python

      >>> from sage.all import *
      >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3)),(Integer(4),Integer(5))],[(Integer(3),Integer(4))]])
      >>> G
      Permutation Group with generators [(3,4), (1,2,3)(4,5)]
      >>> G.center()
      Subgroup generated by [()] of
       (Permutation Group with generators [(3,4), (1,2,3)(4,5)])
      >>> G.group_id()
      [120, 34]
      >>> n = G.order(); n
      120
      >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3)),(Integer(4),Integer(5))],[(Integer(3),Integer(4))]])
      >>> TestSuite(G).run()

  Element

    alias of `PermutationGroupElement`

  Subgroup

    alias of `PermutationGroup_subgroup`

  are_conjugate(H1, H2)

    Return whether `H1` and `H2` are conjugate subgroups in `G`.

    EXAMPLES:

    Sage

        sage: G = SymmetricGroup(3)
        sage: H1 = PermutationGroup([(1,2)])
        sage: H2 = PermutationGroup([(2,3)])
        sage: G.are_conjugate(H1, H2)
        True
        sage: G = SymmetricGroup(4)
        sage: H1 = PermutationGroup([[(1,3),(2,4)], [(1,2),(3,4)]])
        sage: H2 = PermutationGroup([[(1,2)], [(1,2),(3,4)]])
        sage: G.are_conjugate(H1, H2)
        False

    Python

        >>> from sage.all import *
        >>> G = SymmetricGroup(Integer(3))
        >>> H1 = PermutationGroup([(Integer(1),Integer(2))])
        >>> H2 = PermutationGroup([(Integer(2),Integer(3))])
        >>> G.are_conjugate(H1, H2)
        True
        >>> G = SymmetricGroup(Integer(4))
        >>> H1 = PermutationGroup([[(Integer(1),Integer(3)),(Integer(2),Integer(4))], [(Integer(1),Integer(2)),(Integer(3),Integer(4))]])
        >>> H2 = PermutationGroup([[(Integer(1),Integer(2))], [(Integer(1),Integer(2)),(Integer(3),Integer(4))]])
        >>> G.are_conjugate(H1, H2)
        False

  as_finitely_presented_group(reduced=False)

    Return a finitely presented group isomorphic to `self`.

    This method acts as wrapper for the GAP function `IsomorphismFpGroupByGenerators`, which yields an isomorphism from a given group to a finitely presented group.

    INPUT:

    - `reduced` – (default: `False`) if `True`, `FinitelyPresentedGroup.simplified` is called, attempting to simplify the presentation of the finitely presented group to be returned

    OUTPUT: finite presentation of `self`, obtained by taking the image of the isomorphism returned by the GAP function `IsomorphismFpGroupByGenerators`

    ALGORITHM: uses GAP

    EXAMPLES:

    Sage

        sage: CyclicPermutationGroup(50).as_finitely_presented_group()
        Finitely presented group < a | a^50 >
        sage: DihedralGroup(4).as_finitely_presented_group()
        Finitely presented group < a, b | b^2, a^4, (b*a)^2 >
        sage: GeneralDihedralGroup([2,2]).as_finitely_presented_group()
        Finitely presented group < a, b, c | a^2, b^2, c^2, (c*b)^2, (c*a)^2, (b*a)^2 >

    Python

        >>> from sage.all import *
        >>> CyclicPermutationGroup(Integer(50)).as_finitely_presented_group()
        Finitely presented group < a | a^50 >
        >>> DihedralGroup(Integer(4)).as_finitely_presented_group()
        Finitely presented group < a, b | b^2, a^4, (b*a)^2 >
        >>> GeneralDihedralGroup([Integer(2),Integer(2)]).as_finitely_presented_group()
        Finitely presented group < a, b, c | a^2, b^2, c^2, (c*b)^2, (c*a)^2, (b*a)^2 >

    GAP algorithm is not guaranteed to produce minimal or canonical presentation:

    Sage

        sage: G = PermutationGroup(['(1,2,3,4,5)', '(1,5)(2,4)'])
        sage: G.is_isomorphic(DihedralGroup(5))
        True
        sage: K = G.as_finitely_presented_group(); K
        Finitely presented group < a, b | b^2, (b*a)^2, b*a^-3*b*a^2 >
        sage: K.as_permutation_group().is_isomorphic(DihedralGroup(5))
        True

    [Python]

        >>> from sage.all import *
        >>> G = PermutationGroup(['(1,2,3,4,5)', '(1,5)(2,4)'])
        >>> G.is_isomorphic(DihedralGroup(Integer(5)))
        True
        >>> K = G.as_finitely_presented_group(); K
        Finitely presented group < a, b | b^2, (b*a)^2, b*a^-3*b*a^2 >
        >>> K.as_permutation_group().is_isomorphic(DihedralGroup(Integer(5)))
        True

    We can attempt to reduce the output presentation:

    Sage

        sage: H = PermutationGroup(['(1,2,3,4,5)', '(1,3,5,2,4)'])
        sage: H.as_finitely_presented_group()
        Finitely presented group < a, b | b^-2*a^-1, b*a^-2 >
        sage: H.as_finitely_presented_group(reduced=True)
        Finitely presented group < a | a^5 >

    Python

        >>> from sage.all import *
        >>> H = PermutationGroup(['(1,2,3,4,5)', '(1,3,5,2,4)'])
        >>> H.as_finitely_presented_group()
        Finitely presented group < a, b | b^-2*a^-1, b*a^-2 >
        >>> H.as_finitely_presented_group(reduced=True)
        Finitely presented group < a | a^5 >

    AUTHORS:

    - Davis Shurbert (2013-06-21): initial version

  base(seed=None)

    Return a (minimum) base of this permutation group.

    A base \(B\) of a permutation group is a subset of the domain of the group such that the only group element stabilizing all of \(B\) is the identity.

    INPUT:

    - `seed` – (default: `None`) if given must be a subset of the domain of a base. When used, an attempt to create a base containing all or part of `seed` will be made.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([(1,2,3),(6,7,8)])
        sage: G.base()
        [1, 6]
        sage: G.base([2])
        [2, 6]

        sage: H = PermutationGroup([('a','b','c'),('a','y')])
        sage: H.base()
        ['a', 'b', 'c']

        sage: S = SymmetricGroup(13)
        sage: S.base()
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

        sage: S = MathieuGroup(12)
        sage: S.base()
        [1, 2, 3, 4, 5]
        sage: S.base([1,3,5,7,9,11]) # create a base for M12 with only odd integers
        [1, 3, 5, 7, 9]

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([(Integer(1),Integer(2),Integer(3)),(Integer(6),Integer(7),Integer(8))])
        >>> G.base()
        [1, 6]
        >>> G.base([Integer(2)])
        [2, 6]

        >>> H = PermutationGroup([('a','b','c'),('a','y')])
        >>> H.base()
        ['a', 'b', 'c']

        >>> S = SymmetricGroup(Integer(13))
        >>> S.base()
        [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]

        >>> S = MathieuGroup(Integer(12))
        >>> S.base()
        [1, 2, 3, 4, 5]
        >>> S.base([Integer(1),Integer(3),Integer(5),Integer(7),Integer(9),Integer(11)]) # create a base for M12 with only odd integers
        [1, 3, 5, 7, 9]

  blocks_all(representatives=True)

    Return the list of block systems of imprimitivity.

    For more information on primitivity, see the Wikipedia article on primitive group actions.

    INPUT:

    - `representative` – boolean; whether to return all possible block systems of imprimitivity or only one of their representatives (the block can be obtained from its representative set \(S\) by computing the orbit of \(S\) under `self`).

      This parameter is set to `True` by default (as it is GAP’s default behaviour).

    OUTPUT:

    This method returns a description of all block systems. Hence, the output is a “list of lists of lists” or a “list of lists” depending on the value of `representatives`. A bit more clearly, output is:

    - A list of length (#number of different block systems) of

      - block systems, each of them being defined as

        - If `representatives=True`: a list of representatives of each set of the block system

        - If `representatives=False`: a partition of the elements defining an imprimitivity block.

    See also

    - `is_primitive()`

    EXAMPLES:

    Picking an interesting group:

    Sage

        sage: # needs sage.graphs
        sage: g = graphs.DodecahedralGraph()
        sage: g.is_vertex_transitive()
        True
        sage: ag = g.automorphism_group()
        sage: ag.is_primitive()
        False

    Python

        >>> from sage.all import *
        >>> # needs sage.graphs
        >>> g = graphs.DodecahedralGraph()
        >>> g.is_vertex_transitive()
        True
        >>> ag = g.automorphism_group()
        >>> ag.is_primitive()
        False

    Computing its blocks representatives:

    Sage

        sage: ag.blocks_all()                                                       # needs sage.graphs
        [[0, 15]]

    [Python]

        >>> from sage.all import *
        >>> ag.blocks_all()                                                       # needs sage.graphs
        [[0, 15]]

    Now the full block:

    Sage

        sage: sorted(ag.blocks_all(representatives=False)[0])                       # needs sage.graphs
        [[0, 15], [1, 16], [2, 12], [3, 13], [4, 9],
         [5, 10], [6, 11], [7, 18], [8, 17], [14, 19]]

    Python

        >>> from sage.all import *
        >>> sorted(ag.blocks_all(representatives=False)[Integer(0)])                       # needs sage.graphs
        [[0, 15], [1, 16], [2, 12], [3, 13], [4, 9],
         [5, 10], [6, 11], [7, 18], [8, 17], [14, 19]]

  cardinality()

    alias of `order()`.

  center()

    Return the subgroup of elements that commute with every element of this group.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2,3,4)]])
        sage: G.center()
        Subgroup generated by [(1,2,3,4)] of
         (Permutation Group with generators [(1,2,3,4)])
        sage: G = PermutationGroup([[(1,2,3,4)], [(1,2)]])
        sage: G.center()
        Subgroup generated by [()] of
         (Permutation Group with generators [(1,2), (1,2,3,4)])

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))]])
        >>> G.center()
        Subgroup generated by [(1,2,3,4)] of
         (Permutation Group with generators [(1,2,3,4)])
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))], [(Integer(1),Integer(2))]])
        >>> G.center()
        Subgroup generated by [()] of
         (Permutation Group with generators [(1,2), (1,2,3,4)])

  centralizer(g)

    Return the centralizer of `g` in `self`.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4)]])
        sage: g = G([(1,3)])
        sage: G.centralizer(g)
        Subgroup generated by [(1,3), (2,4)] of
         (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)])
        sage: g = G([(1,2,3,4)])
        sage: G.centralizer(g)
        Subgroup generated by [(1,2,3,4)] of
         (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)])
        sage: H = G.subgroup([G([(1,2,3,4)])])
        sage: G.centralizer(H)
        Subgroup generated by [(1,2,3,4)] of
         (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)])

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2)),(Integer(3),Integer(4))], [(Integer(1),Integer(2),Integer(3),Integer(4))]])
        >>> g = G([(Integer(1),Integer(3))])
        >>> G.centralizer(g)
        Subgroup generated by [(1,3), (2,4)] of
         (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)])
        >>> g = G([(Integer(1),Integer(2),Integer(3),Integer(4))])
        >>> G.centralizer(g)
        Subgroup generated by [(1,2,3,4)] of
         (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)])
        >>> H = G.subgroup([G([(Integer(1),Integer(2),Integer(3),Integer(4))])])
        >>> G.centralizer(H)
        Subgroup generated by [(1,2,3,4)] of
         (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)])

  character(values)

    Return a group character from `values`, where `values` is a list of the values of the character evaluated on the conjugacy classes.

    EXAMPLES:

    Sage

        sage: G = AlternatingGroup(4)
        sage: n = len(G.conjugacy_classes_representatives())
        sage: G.character([1]*n)                                                    # needs sage.rings.number_field
        Character of Alternating group of order 4!/2 as a permutation group

    Python

        >>> from sage.all import *
        >>> G = AlternatingGroup(Integer(4))
        >>> n = len(G.conjugacy_classes_representatives())
        >>> G.character([Integer(1)]*n)                                                    # needs sage.rings.number_field
        Character of Alternating group of order 4!/2 as a permutation group

  character_table()

    Return the matrix of values of the irreducible characters of a permutation group \(G\) at the conjugacy classes of \(G\).

    The columns represent the conjugacy classes of \(G\) and the rows represent the different irreducible characters in the ordering given by GAP.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3)]])
        sage: G.order()
        12
        sage: Gct = G.character_table(); Gct                                        # random, needs sage.rings.number_field
        [         1          1          1          1]
        [         1 -zeta3 - 1      zeta3          1]
        [         1      zeta3 -zeta3 - 1          1]
        [         3          0          0         -1]
        sage: sorted(Gct)                                                           # needs sage.rings.number_field
        [(1, -zeta3 - 1, zeta3, 1),
         (1, zeta3, -zeta3 - 1, 1),
         (1, 1, 1, 1),
         (3, 0, 0, -1)]
        sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3)]])
        sage: CT = gap(G).CharacterTable()

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2)),(Integer(3),Integer(4))], [(Integer(1),Integer(2),Integer(3))]])
        >>> G.order()
        12
        >>> Gct = G.character_table(); Gct                                        # random, needs sage.rings.number_field
        [         1          1          1          1]
        [         1 -zeta3 - 1      zeta3          1]
        [         1      zeta3 -zeta3 - 1          1]
        [         3          0          0         -1]
        >>> sorted(Gct)                                                           # needs sage.rings.number_field
        [(1, -zeta3 - 1, zeta3, 1),
         (1, zeta3, -zeta3 - 1, 1),
         (1, 1, 1, 1),
         (3, 0, 0, -1)]
        >>> G = PermutationGroup([[(Integer(1),Integer(2)),(Integer(3),Integer(4))], [(Integer(1),Integer(2),Integer(3))]])
        >>> CT = gap(G).CharacterTable()

    Type `CT.Display()` to display this nicely.

    Sage

        sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4)]])
        sage: G.order()
        8
        sage: Gct = G.character_table(); Gct                                        # random, needs sage.rings.number_field
        [ 1  1  1  1  1]
        [ 1 -1 -1  1  1]
        [ 1 -1  1 -1  1]
        [ 1  1 -1 -1  1]
        [ 2  0  0  0 -2]
        sage: sorted(Gct, key=str)                                                           # needs sage.rings.number_field
        [(1, -1, -1, 1, 1), (1, -1, 1, -1, 1), (1, 1, -1, -1, 1), (1, 1, 1, 1, 1), (2, 0, 0, 0, -2)]
        sage: CT = gap(G).CharacterTable()

    [Python]

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2)),(Integer(3),Integer(4))], [(Integer(1),Integer(2),Integer(3),Integer(4))]])
        >>> G.order()
        8
        >>> Gct = G.character_table(); Gct                                        # random, needs sage.rings.number_field
        [ 1  1  1  1  1]
        [ 1 -1 -1  1  1]
        [ 1 -1  1 -1  1]
        [ 1  1 -1 -1  1]
        [ 2  0  0  0 -2]
        >>> sorted(Gct, key=str)                                                           # needs sage.rings.number_field
        [(1, -1, -1, 1, 1), (1, -1, 1, -1, 1), (1, 1, -1, -1, 1), (1, 1, 1, 1, 1), (2, 0, 0, 0, -2)]
        >>> CT = gap(G).CharacterTable()

    Again, type `CT.Display()` to display this nicely.

    Sage

        sage: # needs sage.rings.number_field
        sage: SymmetricGroup(2).character_table()
        [ 1 -1]
        [ 1  1]
        sage: SymmetricGroup(3).character_table()
        [ 1 -1  1]
        [ 2  0 -1]
        [ 1  1  1]
        sage: SymmetricGroup(5).character_table()
        [ 1 -1  1  1 -1 -1  1]
        [ 4 -2  0  1  1  0 -1]
        [ 5 -1  1 -1 -1  1  0]
        [ 6  0 -2  0  0  0  1]
        [ 5  1  1 -1  1 -1  0]
        [ 4  2  0  1 -1  0 -1]
        [ 1  1  1  1  1  1  1]
        sage: sorted(AlternatingGroup(6).character_table(), key=str)
        [(1, 1, 1, 1, 1, 1, 1), (10, -2, 1, 1, 0, 0, 0),
         (5, 1, -1, 2, -1, 0, 0), (5, 1, 2, -1, -1, 0, 0),
         (8, 0, -1, -1, 0, -zeta5^3 - zeta5^2, zeta5^3 + zeta5^2 + 1),
         (8, 0, -1, -1, 0, zeta5^3 + zeta5^2 + 1, -zeta5^3 - zeta5^2),
         (9, 1, 0, 0, 1, -1, -1)]

    Python

        >>> from sage.all import *
        >>> # needs sage.rings.number_field
        >>> SymmetricGroup(Integer(2)).character_table()
        [ 1 -1]
        [ 1  1]
        >>> SymmetricGroup(Integer(3)).character_table()
        [ 1 -1  1]
        [ 2  0 -1]
        [ 1  1  1]
        >>> SymmetricGroup(Integer(5)).character_table()
        [ 1 -1  1  1 -1 -1  1]
        [ 4 -2  0  1  1  0 -1]
        [ 5 -1  1 -1 -1  1  0]
        [ 6  0 -2  0  0  0  1]
        [ 5  1  1 -1  1 -1  0]
        [ 4  2  0  1 -1  0 -1]
        [ 1  1  1  1  1  1  1]
        >>> sorted(AlternatingGroup(Integer(6)).character_table(), key=str)
        [(1, 1, 1, 1, 1, 1, 1), (10, -2, 1, 1, 0, 0, 0),
         (5, 1, -1, 2, -1, 0, 0), (5, 1, 2, -1, -1, 0, 0),
         (8, 0, -1, -1, 0, -zeta5^3 - zeta5^2, zeta5^3 + zeta5^2 + 1),
         (8, 0, -1, -1, 0, zeta5^3 + zeta5^2 + 1, -zeta5^3 - zeta5^2),
         (9, 1, 0, 0, 1, -1, -1)]

    Suppose that you have a class function \(f(g)\) on \(G\) and you know the values \(v_1, \ldots, v_n\) on the conjugacy class elements in `conjugacy_classes_representatives(G)` = \([g_1, \ldots, g_n]\). Since the irreducible characters \(\rho_1, \ldots, \rho_n\) of \(G\) form an \(E\)-basis of the space of all class functions (\(E\) a “sufficiently large” cyclotomic field), such a class function is a linear combination of these basis elements, \(f = c_1 \rho_1 + \cdots + c_n \rho_n\). To find the coefficients \(c_i\), you simply solve the linear system `character_table_values(G)` \([v_1, ..., v_n] = [c_1, ..., c_n]\), where \([v_1, \ldots, v_n]\) = `character_table_values(G)` \(^{(-1)}[c_1, ..., c_n]\).

    AUTHORS:

    - David Joyner and William Stein (2006-01-04)

  cohomology(n, p=0)

    Compute the group cohomology \(H^n(G, F)\), where \(F = \ZZ\) if \(p=0\) and \(F = \ZZ / p \ZZ\) if \(p > 0\) is a prime.

    Wraps HAP’s `GroupHomology` function, written by Graham Ellis.

    REQUIRES: GAP package HAP (in gap_packages-*.spkg).

    EXAMPLES:

    Sage

        sage: G = SymmetricGroup(4)
        sage: G.cohomology(1,2)                            # optional - gap_package_hap
        Multiplicative Abelian group isomorphic to C2
        sage: G = SymmetricGroup(3)
        sage: G.cohomology(5)                              # optional - gap_package_hap
        Trivial Abelian group
        sage: G.cohomology(5,2)                            # optional - gap_package_hap
        Multiplicative Abelian group isomorphic to C2
        sage: G.homology(5,3)                              # optional - gap_package_hap
        Trivial Abelian group
        sage: G.homology(5,4)                              # optional - gap_package_hap
        Traceback (most recent call last):
        ...
        ValueError: p must be 0 or prime

    Python

        >>> from sage.all import *
        >>> G = SymmetricGroup(Integer(4))
        >>> G.cohomology(Integer(1),Integer(2))                            # optional - gap_package_hap
        Multiplicative Abelian group isomorphic to C2
        >>> G = SymmetricGroup(Integer(3))
        >>> G.cohomology(Integer(5))                              # optional - gap_package_hap
        Trivial Abelian group
        >>> G.cohomology(Integer(5),Integer(2))                            # optional - gap_package_hap
        Multiplicative Abelian group isomorphic to C2
        >>> G.homology(Integer(5),Integer(3))                              # optional - gap_package_hap
        Trivial Abelian group
        >>> G.homology(Integer(5),Integer(4))                              # optional - gap_package_hap
        Traceback (most recent call last):
        ...
        ValueError: p must be 0 or prime

    This computes \(H^4(S_3, \ZZ)\) and \(H^4(S_3, \ZZ / 2 \ZZ)\), respectively.

    AUTHORS:

    - David Joyner and Graham Ellis

    REFERENCES:

    - G. Ellis, ‘Computing group resolutions’, J. Symbolic Computation. Vol.38, (2004)1077-1118 (Available at http://hamilton.nuigalway.ie/).

    - D. Joyner, ‘A primer on computational group homology and cohomology’, http://front.math.ucdavis.edu/0706.0549.

  cohomology_part(n, p=0)

    Compute the p-part of the group cohomology \(H^n(G, F)\), where \(F = \ZZ\) if \(p=0\) and \(F = \ZZ / p \ZZ\) if \(p > 0\) is a prime.

    Wraps HAP’s Homology function, written by Graham Ellis, applied to the \(p\)-Sylow subgroup of \(G\).

    REQUIRES: GAP package HAP (in gap_packages-*.spkg).

    EXAMPLES:

    Sage

        sage: G = SymmetricGroup(5)
        sage: G.cohomology_part(7,2)                   # optional - gap_package_hap
        Multiplicative Abelian group isomorphic to C2 x C2 x C2
        sage: G = SymmetricGroup(3)
        sage: G.cohomology_part(2,3)                   # optional - gap_package_hap
        Multiplicative Abelian group isomorphic to C3

    Python

        >>> from sage.all import *
        >>> G = SymmetricGroup(Integer(5))
        >>> G.cohomology_part(Integer(7),Integer(2))                   # optional - gap_package_hap
        Multiplicative Abelian group isomorphic to C2 x C2 x C2
        >>> G = SymmetricGroup(Integer(3))
        >>> G.cohomology_part(Integer(2),Integer(3))                   # optional - gap_package_hap
        Multiplicative Abelian group isomorphic to C3

    AUTHORS:

    - David Joyner and Graham Ellis

  commutator(other=None)

    Return the commutator subgroup of a group, or of a pair of groups.

    INPUT:

    - `other` – (default: `None`) a permutation group

    OUTPUT:

    Let \(G\) denote `self`. If `other` is `None`, then this method returns the subgroup of \(G\) generated by the set of commutators,

    \[\{[g_1,g_2]\vert g_1, g_2\in G\} = \{g_1^{-1}g_2^{-1}g_1g_2\vert g_1, g_2\in G\}\]

    Let \(H\) denote `other`, in the case that it is not `None`. Then this method returns the group generated by the set of commutators,

    \[\{[g,h]\vert g\in G\, h\in H\} = \{g^{-1}h^{-1}gh\vert g\in G\, h\in H\}\]

    The two groups need only be permutation groups, there is no notion of requiring them to explicitly be subgroups of some other group.

    Note

    For the identical statement, the generators of the returned group can vary from one execution to the next.

    EXAMPLES:

    Sage

        sage: G = DiCyclicGroup(4)
        sage: G.commutator()
        Permutation Group with generators [(1,3,5,7)(2,4,6,8)(9,11,13,15)(10,12,14,16)]

        sage: G = SymmetricGroup(5)
        sage: H = CyclicPermutationGroup(5)
        sage: C = G.commutator(H)
        sage: C.is_isomorphic(AlternatingGroup(5))
        True

    Python

        >>> from sage.all import *
        >>> G = DiCyclicGroup(Integer(4))
        >>> G.commutator()
        Permutation Group with generators [(1,3,5,7)(2,4,6,8)(9,11,13,15)(10,12,14,16)]

        >>> G = SymmetricGroup(Integer(5))
        >>> H = CyclicPermutationGroup(Integer(5))
        >>> C = G.commutator(H)
        >>> C.is_isomorphic(AlternatingGroup(Integer(5)))
        True

    An abelian group will have a trivial commutator.

    Sage

        sage: G = CyclicPermutationGroup(10)
        sage: G.commutator()
        Permutation Group with generators [()]

    [Python]

        >>> from sage.all import *
        >>> G = CyclicPermutationGroup(Integer(10))
        >>> G.commutator()
        Permutation Group with generators [()]

    The quotient of a group by its commutator is always abelian.

    Sage

        sage: G = DihedralGroup(20)
        sage: C = G.commutator()
        sage: Q = G.quotient(C)
        sage: Q.is_abelian()
        True

    Python

        >>> from sage.all import *
        >>> G = DihedralGroup(Integer(20))
        >>> C = G.commutator()
        >>> Q = G.quotient(C)
        >>> Q.is_abelian()
        True

    When forming commutators from two groups, the order of the groups does not matter.

    Sage

        sage: D = DihedralGroup(3)
        sage: S = SymmetricGroup(2)
        sage: C1 = D.commutator(S); C1
        Permutation Group with generators [(1,2,3)]
        sage: C2 = S.commutator(D); C2
        Permutation Group with generators [(1,3,2)]
        sage: C1 == C2
        True

    [Python]

        >>> from sage.all import *
        >>> D = DihedralGroup(Integer(3))
        >>> S = SymmetricGroup(Integer(2))
        >>> C1 = D.commutator(S); C1
        Permutation Group with generators [(1,2,3)]
        >>> C2 = S.commutator(D); C2
        Permutation Group with generators [(1,3,2)]
        >>> C1 == C2
        True

    This method calls two different functions in GAP, so this tests that their results are consistent. The commutator groups may have different generators, but the groups are equal.

    Sage

        sage: G = DiCyclicGroup(3)
        sage: C = G.commutator(); C
        Permutation Group with generators [(5,7,6)]
        sage: CC = G.commutator(G); CC
        Permutation Group with generators [(5,6,7)]
        sage: C == CC
        True

    Python

        >>> from sage.all import *
        >>> G = DiCyclicGroup(Integer(3))
        >>> C = G.commutator(); C
        Permutation Group with generators [(5,7,6)]
        >>> CC = G.commutator(G); CC
        Permutation Group with generators [(5,6,7)]
        >>> C == CC
        True

    The second group is checked.

    Sage

        sage: G = SymmetricGroup(2)
        sage: G.commutator('junk')
        Traceback (most recent call last):
        ...
        TypeError: junk is not a permutation group

    [Python]

        >>> from sage.all import *
        >>> G = SymmetricGroup(Integer(2))
        >>> G.commutator('junk')
        Traceback (most recent call last):
        ...
        TypeError: junk is not a permutation group

  composition_series()

    Return the composition series of this group as a list of permutation groups.

    EXAMPLES:

    These computations use pseudo-random numbers, so we set the seed for reproducible testing.

    Sage

        sage: set_random_seed(0)
        sage: G = PermutationGroup([[(1,2,3),(4,5)],[(3,4)]])
        sage: G.composition_series()
        [Subgroup generated by [(3,4), (1,2,3)(4,5)] of
          (Permutation Group with generators [(3,4), (1,2,3)(4,5)]),
         Subgroup generated by [(1,5)(3,4), (1,5)(2,4), (1,3,5)] of
          (Permutation Group with generators [(3,4), (1,2,3)(4,5)]),
         Subgroup generated by [()] of
          (Permutation Group with generators [(3,4), (1,2,3)(4,5)])]
        sage: G = PermutationGroup([[(1,2,3),(4,5)], [(1,2)]])
        sage: CS = G.composition_series()
        sage: CS[3]
        Subgroup generated by [()] of
         (Permutation Group with generators [(1,2), (1,2,3)(4,5)])

    Python

        >>> from sage.all import *
        >>> set_random_seed(Integer(0))
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3)),(Integer(4),Integer(5))],[(Integer(3),Integer(4))]])
        >>> G.composition_series()
        [Subgroup generated by [(3,4), (1,2,3)(4,5)] of
          (Permutation Group with generators [(3,4), (1,2,3)(4,5)]),
         Subgroup generated by [(1,5)(3,4), (1,5)(2,4), (1,3,5)] of
          (Permutation Group with generators [(3,4), (1,2,3)(4,5)]),
         Subgroup generated by [()] of
          (Permutation Group with generators [(3,4), (1,2,3)(4,5)])]
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3)),(Integer(4),Integer(5))], [(Integer(1),Integer(2))]])
        >>> CS = G.composition_series()
        >>> CS[Integer(3)]
        Subgroup generated by [()] of
         (Permutation Group with generators [(1,2), (1,2,3)(4,5)])

  conjugacy_class(g)

    Return the conjugacy class of `g` inside the group `self`.

    INPUT:

    - `g` – an element of the permutation group `self`

    OUTPUT:

    The conjugacy class of `g` in the group `self`. If `self` is the group denoted by \(G\), this method computes the set \(\{x^{-1}gx\ \vert\ x \in G \}\)

    EXAMPLES:

    Sage

        sage: G = DihedralGroup(3)
        sage: g = G.gen(0)
        sage: G.conjugacy_class(g)
        Conjugacy class of (1,2,3) in Dihedral group of order 6 as a permutation group

    Python

        >>> from sage.all import *
        >>> G = DihedralGroup(Integer(3))
        >>> g = G.gen(Integer(0))
        >>> G.conjugacy_class(g)
        Conjugacy class of (1,2,3) in Dihedral group of order 6 as a permutation group

  conjugacy_classes()

    Return a list with all the conjugacy classes of `self`.

    EXAMPLES:

    Sage

        sage: G = DihedralGroup(3)
        sage: G.conjugacy_classes()
        [Conjugacy class of () in Dihedral group of order 6 as a permutation group,
         Conjugacy class of (2,3) in Dihedral group of order 6 as a permutation group,
         Conjugacy class of (1,2,3) in Dihedral group of order 6 as a permutation group]

    Python

        >>> from sage.all import *
        >>> G = DihedralGroup(Integer(3))
        >>> G.conjugacy_classes()
        [Conjugacy class of () in Dihedral group of order 6 as a permutation group,
         Conjugacy class of (2,3) in Dihedral group of order 6 as a permutation group,
         Conjugacy class of (1,2,3) in Dihedral group of order 6 as a permutation group]

  conjugacy_classes_representatives()

    Return a complete list of representatives of conjugacy classes in a permutation group \(G\).

    The ordering is that given by GAP.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4)]])
        sage: cl = G.conjugacy_classes_representatives(); cl
        [(), (2,4), (1,2)(3,4), (1,2,3,4), (1,3)(2,4)]
        sage: cl[3] in G
        True

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2)),(Integer(3),Integer(4))], [(Integer(1),Integer(2),Integer(3),Integer(4))]])
        >>> cl = G.conjugacy_classes_representatives(); cl
        [(), (2,4), (1,2)(3,4), (1,2,3,4), (1,3)(2,4)]
        >>> cl[Integer(3)] in G
        True

    Sage

        sage: G = SymmetricGroup(5)
        sage: G.conjugacy_classes_representatives()                                 # needs sage.combinat
        [(), (1,2), (1,2)(3,4), (1,2,3), (1,2,3)(4,5), (1,2,3,4), (1,2,3,4,5)]

    [Python]

        >>> from sage.all import *
        >>> G = SymmetricGroup(Integer(5))
        >>> G.conjugacy_classes_representatives()                                 # needs sage.combinat
        [(), (1,2), (1,2)(3,4), (1,2,3), (1,2,3)(4,5), (1,2,3,4), (1,2,3,4,5)]

    Sage

        sage: S = SymmetricGroup(['a','b','c'])
        sage: S.conjugacy_classes_representatives()                                 # needs sage.combinat
        [(), ('a','b'), ('a','b','c')]

    Python

        >>> from sage.all import *
        >>> S = SymmetricGroup(['a','b','c'])
        >>> S.conjugacy_classes_representatives()                                 # needs sage.combinat
        [(), ('a','b'), ('a','b','c')]

    AUTHORS:

    - David Joyner and William Stein (2006-01-04)

  conjugacy_classes_subgroups()

    Return a complete list of representatives of conjugacy classes of subgroups in a permutation group \(G\).

    The ordering is that given by GAP.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4)]])
        sage: cl = G.conjugacy_classes_subgroups(); cl
        [Subgroup generated by [()] of
          (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)]),
         Subgroup generated by [(1,2)(3,4)] of
          (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)]),
         Subgroup generated by [(1,3)(2,4)] of
          (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)]),
         Subgroup generated by [(2,4)] of
          (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)]),
         Subgroup generated by [(1,4)(2,3), (1,2)(3,4)] of
          (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)]),
         Subgroup generated by [(2,4), (1,3)(2,4)] of
          (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)]),
         Subgroup generated by [(1,2,3,4), (1,3)(2,4)] of
          (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)]),
         Subgroup generated by [(1,4)(2,3), (1,2)(3,4), (2,4)] of
          (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)])]

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2)),(Integer(3),Integer(4))], [(Integer(1),Integer(2),Integer(3),Integer(4))]])
        >>> cl = G.conjugacy_classes_subgroups(); cl
        [Subgroup generated by [()] of
          (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)]),
         Subgroup generated by [(1,2)(3,4)] of
          (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)]),
         Subgroup generated by [(1,3)(2,4)] of
          (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)]),
         Subgroup generated by [(2,4)] of
          (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)]),
         Subgroup generated by [(1,4)(2,3), (1,2)(3,4)] of
          (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)]),
         Subgroup generated by [(2,4), (1,3)(2,4)] of
          (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)]),
         Subgroup generated by [(1,2,3,4), (1,3)(2,4)] of
          (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)]),
         Subgroup generated by [(1,4)(2,3), (1,2)(3,4), (2,4)] of
          (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)])]

    Sage

        sage: G = SymmetricGroup(3)
        sage: G.conjugacy_classes_subgroups()
        [Subgroup generated by [()] of
          (Symmetric group of order 3! as a permutation group),
         Subgroup generated by [(2,3)] of
          (Symmetric group of order 3! as a permutation group),
         Subgroup generated by [(1,2,3)] of
          (Symmetric group of order 3! as a permutation group),
         Subgroup generated by [(1,2,3), (2,3)] of
          (Symmetric group of order 3! as a permutation group)]

    [Python]

        >>> from sage.all import *
        >>> G = SymmetricGroup(Integer(3))
        >>> G.conjugacy_classes_subgroups()
        [Subgroup generated by [()] of
          (Symmetric group of order 3! as a permutation group),
         Subgroup generated by [(2,3)] of
          (Symmetric group of order 3! as a permutation group),
         Subgroup generated by [(1,2,3)] of
          (Symmetric group of order 3! as a permutation group),
         Subgroup generated by [(1,2,3), (2,3)] of
          (Symmetric group of order 3! as a permutation group)]

    AUTHORS:

    - David Joyner (2006-10)

  conjugate(g)

    Return the group formed by conjugating `self` with `g`.

    INPUT:

    - `g` – a permutation group element, or an object that converts to a permutation group element, such as a list of integers or a string of cycles.

    OUTPUT:

    If `self` is the group denoted by \(H\), then this method computes the group

    \[g^{-1}Hg = \{g^{-1}hg\vert h\in H\}\]

    which is the group \(H\) conjugated by \(g\).

    There are no restrictions on `self` and `g` belonging to a common permutation group, and correspondingly, there is no relationship (such as a common parent) between `self` and the output group.

    EXAMPLES:

    Sage

        sage: G = DihedralGroup(6)
        sage: a = PermutationGroupElement("(1,2,3,4)")
        sage: G.conjugate(a)
        Permutation Group with generators [(1,5,6,2,3,4), (1,4)(2,6)(3,5)]

    Python

        >>> from sage.all import *
        >>> G = DihedralGroup(Integer(6))
        >>> a = PermutationGroupElement("(1,2,3,4)")
        >>> G.conjugate(a)
        Permutation Group with generators [(1,5,6,2,3,4), (1,4)(2,6)(3,5)]

    The element performing the conjugation can be specified in several ways.

    Sage

        sage: G = DihedralGroup(6)
        sage: strng = "(1,2,3,4)"
        sage: G.conjugate(strng)
        Permutation Group with generators [(1,5,6,2,3,4), (1,4)(2,6)(3,5)]
        sage: G = DihedralGroup(6)
        sage: lst = [2,3,4,1]
        sage: G.conjugate(lst)
        Permutation Group with generators [(1,5,6,2,3,4), (1,4)(2,6)(3,5)]
        sage: G = DihedralGroup(6)
        sage: cycles = [(1,2,3,4)]
        sage: G.conjugate(cycles)
        Permutation Group with generators [(1,5,6,2,3,4), (1,4)(2,6)(3,5)]

    [Python]

        >>> from sage.all import *
        >>> G = DihedralGroup(Integer(6))
        >>> strng = "(1,2,3,4)"
        >>> G.conjugate(strng)
        Permutation Group with generators [(1,5,6,2,3,4), (1,4)(2,6)(3,5)]
        >>> G = DihedralGroup(Integer(6))
        >>> lst = [Integer(2),Integer(3),Integer(4),Integer(1)]
        >>> G.conjugate(lst)
        Permutation Group with generators [(1,5,6,2,3,4), (1,4)(2,6)(3,5)]
        >>> G = DihedralGroup(Integer(6))
        >>> cycles = [(Integer(1),Integer(2),Integer(3),Integer(4))]
        >>> G.conjugate(cycles)
        Permutation Group with generators [(1,5,6,2,3,4), (1,4)(2,6)(3,5)]

    Conjugation is a group automorphism, so conjugate groups will be isomorphic.

    Sage

        sage: G = DiCyclicGroup(6)
        sage: G.degree()
        11
        sage: cycle = [i+1 for i in range(1,11)] + [1]
        sage: C = G.conjugate(cycle)
        sage: G.is_isomorphic(C)
        True

    Python

        >>> from sage.all import *
        >>> G = DiCyclicGroup(Integer(6))
        >>> G.degree()
        11
        >>> cycle = [i+Integer(1) for i in range(Integer(1),Integer(11))] + [Integer(1)]
        >>> C = G.conjugate(cycle)
        >>> G.is_isomorphic(C)
        True

    The conjugating element may be from a symmetric group with larger degree than the group being conjugated.

    Sage

        sage: G = AlternatingGroup(5)
        sage: G.degree()
        5
        sage: g = "(1,3)(5,6,7)"
        sage: H = G.conjugate(g); H
        Permutation Group with generators [(1,4,6,3,2), (1,4,6)]
        sage: H.degree()
        6

    [Python]

        >>> from sage.all import *
        >>> G = AlternatingGroup(Integer(5))
        >>> G.degree()
        5
        >>> g = "(1,3)(5,6,7)"
        >>> H = G.conjugate(g); H
        Permutation Group with generators [(1,4,6,3,2), (1,4,6)]
        >>> H.degree()
        6

    The conjugating element is checked.

    Sage

        sage: G = SymmetricGroup(3)
        sage: G.conjugate("junk")
        Traceback (most recent call last):
        ...
        TypeError: junk does not convert to a permutation group element

    Python

        >>> from sage.all import *
        >>> G = SymmetricGroup(Integer(3))
        >>> G.conjugate("junk")
        Traceback (most recent call last):
        ...
        TypeError: junk does not convert to a permutation group element

  construction()

    Return the construction of `self`.

    EXAMPLES:

    Sage

        sage: P1 = PermutationGroup([[(1,2)]])
        sage: P1.construction()
        (PermutationGroupFunctor[(1,2)], Permutation Group with generators [()])

        sage: PermutationGroup([]).construction() is None
        True

    Python

        >>> from sage.all import *
        >>> P1 = PermutationGroup([[(Integer(1),Integer(2))]])
        >>> P1.construction()
        (PermutationGroupFunctor[(1,2)], Permutation Group with generators [()])

        >>> PermutationGroup([]).construction() is None
        True

    This allows us to perform computations like the following:

    Sage

        sage: P1 = PermutationGroup([[(1,2)]]); p1 = P1.gen()
        sage: P2 = PermutationGroup([[(1,3)]]); p2 = P2.gen()
        sage: p = p1*p2; p
        (1,2,3)
        sage: p.parent()
        Permutation Group with generators [(1,2), (1,3)]
        sage: p.parent().domain()
        {1, 2, 3}

    [Python]

        >>> from sage.all import *
        >>> P1 = PermutationGroup([[(Integer(1),Integer(2))]]); p1 = P1.gen()
        >>> P2 = PermutationGroup([[(Integer(1),Integer(3))]]); p2 = P2.gen()
        >>> p = p1*p2; p
        (1,2,3)
        >>> p.parent()
        Permutation Group with generators [(1,2), (1,3)]
        >>> p.parent().domain()
        {1, 2, 3}

    Note that this will merge permutation groups with different domains:

    Sage

        sage: g1 = PermutationGroupElement([(1,2),(3,4,5)])
        sage: g2 = PermutationGroup([('a','b')], domain=['a', 'b']).gens()[0]
        sage: g2
        ('a','b')
        sage: p = g1*g2; p
        (1,2)(3,4,5)('a','b')
        sage: P = parent(p)
        sage: P
        Permutation Group with generators [('a','b'), (1,2), (1,2,3,4,5)]

    Python

        >>> from sage.all import *
        >>> g1 = PermutationGroupElement([(Integer(1),Integer(2)),(Integer(3),Integer(4),Integer(5))])
        >>> g2 = PermutationGroup([('a','b')], domain=['a', 'b']).gens()[Integer(0)]
        >>> g2
        ('a','b')
        >>> p = g1*g2; p
        (1,2)(3,4,5)('a','b')
        >>> P = parent(p)
        >>> P
        Permutation Group with generators [('a','b'), (1,2), (1,2,3,4,5)]

  cosets(S, side='right')

    Return a list of the cosets of `S` in `self`.

    INPUT:

    - `S` – a subgroup of `self`; an error is raised if `S` is not a subgroup

    - `side` – (default: `'right'`) determines if right cosets or left cosets are returned. `side` refers to where the representative is placed in the products forming the cosets and thus allowable values are only `'right'` and `'left'`.

    OUTPUT:

    A list of lists. Each inner list is a coset of the subgroup in the group. The first element of each coset is the smallest element (based on the ordering of the elements of `self`) of all the group elements that have not yet appeared in a previous coset. The elements of each coset are in the same order as the subgroup elements used to build the coset’s elements.

    As a consequence, the subgroup itself is the first coset, and its first element is the identity element. For each coset, the first element listed is the element used as a representative to build the coset. These representatives form an increasing sequence across the list of cosets, and within a coset the representative is the smallest element of its coset (both orderings are based on of the ordering of elements of `self`).

    In the case of a normal subgroup, left and right cosets should appear in the same order as part of the outer list. However, the list of the elements of a particular coset may be in a different order for the right coset versus the order in the left coset. So, if you check to see if a subgroup is normal, it is necessary to sort each individual coset first (but not the list of cosets, due to the ordering of the representatives). See below for examples of this.

    Note

    This is a naive implementation intended for instructional purposes, and hence is slow for larger groups. Sage and GAP provide more sophisticated functions for working quickly with cosets of larger groups.

    EXAMPLES:

    The default is to build right cosets. This example works with the symmetry group of an 8-gon and a normal subgroup. Notice that a straight check on the equality of the output is not sufficient to check normality, while sorting the individual cosets is sufficient to then simply test equality of the list of lists. Study the second coset in each list to understand the need for sorting the elements of the cosets.

    Sage

        sage: G = DihedralGroup(8)
        sage: quarter_turn = G('(1,3,5,7)(2,4,6,8)'); quarter_turn
        (1,3,5,7)(2,4,6,8)
        sage: S = G.subgroup([quarter_turn])
        sage: rc = G.cosets(S); rc
        [[(), (1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8), (1,7,5,3)(2,8,6,4)],
         [(2,8)(3,7)(4,6), (1,7)(2,6)(3,5), (1,5)(2,4)(6,8), (1,3)(4,8)(5,7)],
         [(1,2)(3,8)(4,7)(5,6), (1,8)(2,7)(3,6)(4,5), (1,6)(2,5)(3,4)(7,8), (1,4)(2,3)(5,8)(6,7)],
         [(1,2,3,4,5,6,7,8), (1,4,7,2,5,8,3,6), (1,6,3,8,5,2,7,4), (1,8,7,6,5,4,3,2)]]
        sage: lc = G.cosets(S, side='left'); lc
        [[(), (1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8), (1,7,5,3)(2,8,6,4)],
         [(2,8)(3,7)(4,6), (1,3)(4,8)(5,7), (1,5)(2,4)(6,8), (1,7)(2,6)(3,5)],
         [(1,2)(3,8)(4,7)(5,6), (1,4)(2,3)(5,8)(6,7), (1,6)(2,5)(3,4)(7,8), (1,8)(2,7)(3,6)(4,5)],
         [(1,2,3,4,5,6,7,8), (1,4,7,2,5,8,3,6), (1,6,3,8,5,2,7,4), (1,8,7,6,5,4,3,2)]]

        sage: S.is_normal(G)
        True
        sage: rc == lc
        False
        sage: rc_sorted = [sorted(c) for c in rc]
        sage: lc_sorted = [sorted(c) for c in lc]
        sage: rc_sorted == lc_sorted
        True

    Python

        >>> from sage.all import *
        >>> G = DihedralGroup(Integer(8))
        >>> quarter_turn = G('(1,3,5,7)(2,4,6,8)'); quarter_turn
        (1,3,5,7)(2,4,6,8)
        >>> S = G.subgroup([quarter_turn])
        >>> rc = G.cosets(S); rc
        [[(), (1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8), (1,7,5,3)(2,8,6,4)],
         [(2,8)(3,7)(4,6), (1,7)(2,6)(3,5), (1,5)(2,4)(6,8), (1,3)(4,8)(5,7)],
         [(1,2)(3,8)(4,7)(5,6), (1,8)(2,7)(3,6)(4,5), (1,6)(2,5)(3,4)(7,8), (1,4)(2,3)(5,8)(6,7)],
         [(1,2,3,4,5,6,7,8), (1,4,7,2,5,8,3,6), (1,6,3,8,5,2,7,4), (1,8,7,6,5,4,3,2)]]
        >>> lc = G.cosets(S, side='left'); lc
        [[(), (1,3,5,7)(2,4,6,8), (1,5)(2,6)(3,7)(4,8), (1,7,5,3)(2,8,6,4)],
         [(2,8)(3,7)(4,6), (1,3)(4,8)(5,7), (1,5)(2,4)(6,8), (1,7)(2,6)(3,5)],
         [(1,2)(3,8)(4,7)(5,6), (1,4)(2,3)(5,8)(6,7), (1,6)(2,5)(3,4)(7,8), (1,8)(2,7)(3,6)(4,5)],
         [(1,2,3,4,5,6,7,8), (1,4,7,2,5,8,3,6), (1,6,3,8,5,2,7,4), (1,8,7,6,5,4,3,2)]]

        >>> S.is_normal(G)
        True
        >>> rc == lc
        False
        >>> rc_sorted = [sorted(c) for c in rc]
        >>> lc_sorted = [sorted(c) for c in lc]
        >>> rc_sorted == lc_sorted
        True

    An example with the symmetry group of a regular tetrahedron and a subgroup that is not normal. Thus, the right and left cosets are different (and so are the representatives). With each individual coset sorted, a naive test of normality is possible.

    Sage

        sage: A = AlternatingGroup(4)
        sage: face_turn = A('(1,2,3)'); face_turn
        (1,2,3)
        sage: stabilizer = A.subgroup([face_turn])
        sage: rc = A.cosets(stabilizer, side='right'); rc
        [[(), (1,2,3), (1,3,2)],
         [(2,3,4), (1,3)(2,4), (1,4,2)],
         [(2,4,3), (1,4,3), (1,2)(3,4)],
         [(1,2,4), (1,4)(2,3), (1,3,4)]]
        sage: lc = A.cosets(stabilizer, side='left'); lc
        [[(), (1,2,3), (1,3,2)],
         [(2,3,4), (1,2)(3,4), (1,3,4)],
         [(2,4,3), (1,2,4), (1,3)(2,4)],
         [(1,4,2), (1,4,3), (1,4)(2,3)]]

        sage: stabilizer.is_normal(A)
        False
        sage: rc_sorted = [sorted(c) for c in rc]
        sage: lc_sorted = [sorted(c) for c in lc]
        sage: rc_sorted == lc_sorted
        False

    [Python]

        >>> from sage.all import *
        >>> A = AlternatingGroup(Integer(4))
        >>> face_turn = A('(1,2,3)'); face_turn
        (1,2,3)
        >>> stabilizer = A.subgroup([face_turn])
        >>> rc = A.cosets(stabilizer, side='right'); rc
        [[(), (1,2,3), (1,3,2)],
         [(2,3,4), (1,3)(2,4), (1,4,2)],
         [(2,4,3), (1,4,3), (1,2)(3,4)],
         [(1,2,4), (1,4)(2,3), (1,3,4)]]
        >>> lc = A.cosets(stabilizer, side='left'); lc
        [[(), (1,2,3), (1,3,2)],
         [(2,3,4), (1,2)(3,4), (1,3,4)],
         [(2,4,3), (1,2,4), (1,3)(2,4)],
         [(1,4,2), (1,4,3), (1,4)(2,3)]]

        >>> stabilizer.is_normal(A)
        False
        >>> rc_sorted = [sorted(c) for c in rc]
        >>> lc_sorted = [sorted(c) for c in lc]
        >>> rc_sorted == lc_sorted
        False

    AUTHOR:

    - Rob Beezer (2011-01-31)

  degree()

    Return the degree of this permutation group.

    EXAMPLES:

    Sage

        sage: S = SymmetricGroup(['a','b','c'])
        sage: S.degree()
        3
        sage: G = PermutationGroup([(1,3),(4,5)])
        sage: G.degree()
        5

    Python

        >>> from sage.all import *
        >>> S = SymmetricGroup(['a','b','c'])
        >>> S.degree()
        3
        >>> G = PermutationGroup([(Integer(1),Integer(3)),(Integer(4),Integer(5))])
        >>> G.degree()
        5

    Note that you can explicitly specify the domain to get a permutation group of smaller degree:

    Sage

        sage: G = PermutationGroup([(1,3),(4,5)], domain=[1,3,4,5])
        sage: G.degree()
        4

    [Python]

        >>> from sage.all import *
        >>> G = PermutationGroup([(Integer(1),Integer(3)),(Integer(4),Integer(5))], domain=[Integer(1),Integer(3),Integer(4),Integer(5)])
        >>> G.degree()
        4

  derived_series()

    Return the derived series of this group as a list of permutation groups.

    EXAMPLES:

    These computations use pseudo-random numbers, so we set the seed for reproducible testing.

    Sage

        sage: set_random_seed(0)
        sage: G = PermutationGroup([[(1,2,3),(4,5)],[(3,4)]])
        sage: G.derived_series()
        [Subgroup generated by [(3,4), (1,2,3)(4,5)] of
          (Permutation Group with generators [(3,4), (1,2,3)(4,5)]),
         Subgroup generated by [(1,5)(3,4), (1,5)(2,4), (1,3,5)] of
          (Permutation Group with generators [(3,4), (1,2,3)(4,5)])]

    Python

        >>> from sage.all import *
        >>> set_random_seed(Integer(0))
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3)),(Integer(4),Integer(5))],[(Integer(3),Integer(4))]])
        >>> G.derived_series()
        [Subgroup generated by [(3,4), (1,2,3)(4,5)] of
          (Permutation Group with generators [(3,4), (1,2,3)(4,5)]),
         Subgroup generated by [(1,5)(3,4), (1,5)(2,4), (1,3,5)] of
          (Permutation Group with generators [(3,4), (1,2,3)(4,5)])]

  direct_product(other, maps=True)

    Wraps GAP’s `DirectProduct`, `Embedding`, and `Projection`.

    Sage calls GAP’s `DirectProduct`, which chooses an efficient representation for the direct product. The direct product of permutation groups will be a permutation group again. For a direct product `D`, the GAP operation `Embedding(D,i)` returns the homomorphism embedding the \(i\)-th factor into `D`. The GAP operation `Projection(D,i)` gives the projection of `D` onto the \(i\)-th factor. This method returns a 5-tuple: a permutation group and 4 morphisms.

    INPUT:

    - `self`, `other` – permutation groups

    OUTPUT:

    - `D` – a direct product of the inputs, returned as a permutation group as well

    - `iota1` – an embedding of `self` into `D`

    - `iota2` – an embedding of `other` into `D`

    - `pr1` – the projection of `D` onto `self` (giving a splitting `1 - other - D - self - 1`)

    - `pr2` – the projection of `D` onto `other` (giving a splitting `1 - self - D - other - 1`)

    EXAMPLES:

    Sage

        sage: G = CyclicPermutationGroup(4)
        sage: D = G.direct_product(G, False); D
        Permutation Group with generators [(1,2,3,4), (5,6,7,8)]
        sage: D,iota1,iota2,pr1,pr2 = G.direct_product(G)
        sage: D; iota1; iota2; pr1; pr2
        Permutation Group with generators [(1,2,3,4), (5,6,7,8)]
        Permutation group morphism:
          From: Cyclic group of order 4 as a permutation group
          To:   Permutation Group with generators [(1,2,3,4), (5,6,7,8)]
          Defn: Embedding( Group( [ (1,2,3,4), (5,6,7,8) ] ), 1 )
        Permutation group morphism:
          From: Cyclic group of order 4 as a permutation group
          To:   Permutation Group with generators [(1,2,3,4), (5,6,7,8)]
          Defn: Embedding( Group( [ (1,2,3,4), (5,6,7,8) ] ), 2 )
        Permutation group morphism:
          From: Permutation Group with generators [(1,2,3,4), (5,6,7,8)]
          To:   Cyclic group of order 4 as a permutation group
          Defn: Projection( Group( [ (1,2,3,4), (5,6,7,8) ] ), 1 )
        Permutation group morphism:
          From: Permutation Group with generators [(1,2,3,4), (5,6,7,8)]
          To:   Cyclic group of order 4 as a permutation group
          Defn: Projection( Group( [ (1,2,3,4), (5,6,7,8) ] ), 2 )
        sage: g = D([(1,3),(2,4)]); g
        (1,3)(2,4)
        sage: d = D([(1,4,3,2),(5,7),(6,8)]); d
        (1,4,3,2)(5,7)(6,8)
        sage: iota1(g); iota2(g); pr1(d); pr2(d)
        (1,3)(2,4)
        (5,7)(6,8)
        (1,4,3,2)
        (1,3)(2,4)

    Python

        >>> from sage.all import *
        >>> G = CyclicPermutationGroup(Integer(4))
        >>> D = G.direct_product(G, False); D
        Permutation Group with generators [(1,2,3,4), (5,6,7,8)]
        >>> D,iota1,iota2,pr1,pr2 = G.direct_product(G)
        >>> D; iota1; iota2; pr1; pr2
        Permutation Group with generators [(1,2,3,4), (5,6,7,8)]
        Permutation group morphism:
          From: Cyclic group of order 4 as a permutation group
          To:   Permutation Group with generators [(1,2,3,4), (5,6,7,8)]
          Defn: Embedding( Group( [ (1,2,3,4), (5,6,7,8) ] ), 1 )
        Permutation group morphism:
          From: Cyclic group of order 4 as a permutation group
          To:   Permutation Group with generators [(1,2,3,4), (5,6,7,8)]
          Defn: Embedding( Group( [ (1,2,3,4), (5,6,7,8) ] ), 2 )
        Permutation group morphism:
          From: Permutation Group with generators [(1,2,3,4), (5,6,7,8)]
          To:   Cyclic group of order 4 as a permutation group
          Defn: Projection( Group( [ (1,2,3,4), (5,6,7,8) ] ), 1 )
        Permutation group morphism:
          From: Permutation Group with generators [(1,2,3,4), (5,6,7,8)]
          To:   Cyclic group of order 4 as a permutation group
          Defn: Projection( Group( [ (1,2,3,4), (5,6,7,8) ] ), 2 )
        >>> g = D([(Integer(1),Integer(3)),(Integer(2),Integer(4))]); g
        (1,3)(2,4)
        >>> d = D([(Integer(1),Integer(4),Integer(3),Integer(2)),(Integer(5),Integer(7)),(Integer(6),Integer(8))]); d
        (1,4,3,2)(5,7)(6,8)
        >>> iota1(g); iota2(g); pr1(d); pr2(d)
        (1,3)(2,4)
        (5,7)(6,8)
        (1,4,3,2)
        (1,3)(2,4)

  disjoint_direct_product_decomposition()

    Return the finest partition of the underlying set such that `self` is isomorphic to the direct product of the projections of `self` onto each part of the partition. Each part is a union of orbits of `self`.

    The algorithm is from [CJ2022], which runs in time polynomial in \(n \cdot |X|\), where \(n\) is the degree of the group and \(|X|\) is the size of a generating set, see Theorem 4.5.

    EXAMPLES:

    The example from the original paper:

    Sage

        sage: H = PermutationGroup([[(1,2,3),(7,9,8),(10,12,11)],[(4,5,6),(7,8,9),(10,11,12)],[(5,6),(8,9),(11,12)],[(7,8,9),(10,11,12)]])
        sage: S = H.disjoint_direct_product_decomposition(); S
        {{1, 2, 3}, {4, 5, 6, 7, 8, 9, 10, 11, 12}}
        sage: A = libgap.Stabilizer(H, list(S[0]), libgap.OnTuples); A
        Group([ (7,8,9)(10,11,12), (5,6)(8,9)(11,12), (4,5,6)(7,8,9)(10,11,12) ])
        sage: B = libgap.Stabilizer(H, list(S[1]), libgap.OnTuples); B
        Group([ (1,2,3) ])
        sage: T = PermutationGroup(gap_group=libgap.DirectProduct(A,B))
        sage: T.is_isomorphic(H)
        True
        sage: PermutationGroup(PermutationGroup(gap_group=A).gens(),domain=list(S[1])).disjoint_direct_product_decomposition()
        {{4, 5, 6, 7, 8, 9, 10, 11, 12}}
        sage: PermutationGroup(PermutationGroup(gap_group=B).gens(),domain=list(S[0])).disjoint_direct_product_decomposition()
        {{1, 2, 3}}

    Python

        >>> from sage.all import *
        >>> H = PermutationGroup([[(Integer(1),Integer(2),Integer(3)),(Integer(7),Integer(9),Integer(8)),(Integer(10),Integer(12),Integer(11))],[(Integer(4),Integer(5),Integer(6)),(Integer(7),Integer(8),Integer(9)),(Integer(10),Integer(11),Integer(12))],[(Integer(5),Integer(6)),(Integer(8),Integer(9)),(Integer(11),Integer(12))],[(Integer(7),Integer(8),Integer(9)),(Integer(10),Integer(11),Integer(12))]])
        >>> S = H.disjoint_direct_product_decomposition(); S
        {{1, 2, 3}, {4, 5, 6, 7, 8, 9, 10, 11, 12}}
        >>> A = libgap.Stabilizer(H, list(S[Integer(0)]), libgap.OnTuples); A
        Group([ (7,8,9)(10,11,12), (5,6)(8,9)(11,12), (4,5,6)(7,8,9)(10,11,12) ])
        >>> B = libgap.Stabilizer(H, list(S[Integer(1)]), libgap.OnTuples); B
        Group([ (1,2,3) ])
        >>> T = PermutationGroup(gap_group=libgap.DirectProduct(A,B))
        >>> T.is_isomorphic(H)
        True
        >>> PermutationGroup(PermutationGroup(gap_group=A).gens(),domain=list(S[Integer(1)])).disjoint_direct_product_decomposition()
        {{4, 5, 6, 7, 8, 9, 10, 11, 12}}
        >>> PermutationGroup(PermutationGroup(gap_group=B).gens(),domain=list(S[Integer(0)])).disjoint_direct_product_decomposition()
        {{1, 2, 3}}

    An example with a different domain:

    Sage

        sage: PermutationGroup([[('a','c','d'),('b','e')]]).disjoint_direct_product_decomposition()
        {{'a', 'c', 'd'}, {'b', 'e'}}
        sage: PermutationGroup([[('a','c','d','b','e')]]).disjoint_direct_product_decomposition()
        {{'a', 'b', 'c', 'd', 'e'}}

    [Python]

        >>> from sage.all import *
        >>> PermutationGroup([[('a','c','d'),('b','e')]]).disjoint_direct_product_decomposition()
        {{'a', 'c', 'd'}, {'b', 'e'}}
        >>> PermutationGroup([[('a','c','d','b','e')]]).disjoint_direct_product_decomposition()
        {{'a', 'b', 'c', 'd', 'e'}}

    Counting the number of “connected” permutation groups of degree \(n\):

    Sage

        sage: seq = [sum(1 for G in SymmetricGroup(n).conjugacy_classes_subgroups() if len(G.disjoint_direct_product_decomposition()) == 1) for n in range(1,8)]; seq
        [1, 1, 2, 6, 6, 27, 20]
        sage: oeis(seq) # optional -- internet
        0: A005226: Number of atomic species of degree n; also number of connected permutation groups of degree n.

    Python

        >>> from sage.all import *
        >>> seq = [sum(Integer(1) for G in SymmetricGroup(n).conjugacy_classes_subgroups() if len(G.disjoint_direct_product_decomposition()) == Integer(1)) for n in range(Integer(1),Integer(8))]; seq
        [1, 1, 2, 6, 6, 27, 20]
        >>> oeis(seq) # optional -- internet
        0: A005226: Number of atomic species of degree n; also number of connected permutation groups of degree n.

  domain()

    Return the underlying set that this permutation group acts on.

    EXAMPLES:

    Sage

        sage: P = PermutationGroup([(1,2),(3,5)])
        sage: P.domain()
        {1, 2, 3, 4, 5}
        sage: S = SymmetricGroup(['a', 'b', 'c'])
        sage: S.domain()
        {'a', 'b', 'c'}

    Python

        >>> from sage.all import *
        >>> P = PermutationGroup([(Integer(1),Integer(2)),(Integer(3),Integer(5))])
        >>> P.domain()
        {1, 2, 3, 4, 5}
        >>> S = SymmetricGroup(['a', 'b', 'c'])
        >>> S.domain()
        {'a', 'b', 'c'}

  exponent()

    Compute the exponent of the group.

    The exponent \(e\) of a group \(G\) is the LCM of the orders of its elements, that is, \(e\) is the smallest integer such that \(g^e=1\) for all \(g \in G\).

    EXAMPLES:

    Sage

        sage: G = AlternatingGroup(4)
        sage: G.exponent()
        6

    Python

        >>> from sage.all import *
        >>> G = AlternatingGroup(Integer(4))
        >>> G.exponent()
        6

  fitting_subgroup()

    Return the Fitting subgroup of `self`.

    The Fitting subgroup of a group \(G\) is the largest nilpotent normal subgroup of \(G\).

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2,3,4)],[(2,4)]])
        sage: G.fitting_subgroup()
        Subgroup generated by [(2,4), (1,2,3,4), (1,3)] of
         (Permutation Group with generators [(2,4), (1,2,3,4)])
        sage: G = PermutationGroup([[(1,2,3,4)],[(1,2)]])
        sage: G.fitting_subgroup()
        Subgroup generated by [(1,2)(3,4), (1,3)(2,4)] of
         (Permutation Group with generators [(1,2), (1,2,3,4)])

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))],[(Integer(2),Integer(4))]])
        >>> G.fitting_subgroup()
        Subgroup generated by [(2,4), (1,2,3,4), (1,3)] of
         (Permutation Group with generators [(2,4), (1,2,3,4)])
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))],[(Integer(1),Integer(2))]])
        >>> G.fitting_subgroup()
        Subgroup generated by [(1,2)(3,4), (1,3)(2,4)] of
         (Permutation Group with generators [(1,2), (1,2,3,4)])

  fixed_points()

    Return the list of points fixed by `self`, i.e., the subset of `.domain()` not moved by any element of `self`.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([(1,2,3)])
        sage: G.fixed_points()
        []
        sage: G = PermutationGroup([(1,2,3),(5,6)])
        sage: G.fixed_points()
        [4]
        sage: G = PermutationGroup([[(1,4,7)],[(4,3),(6,7)]])
        sage: G.fixed_points()
        [2, 5]

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([(Integer(1),Integer(2),Integer(3))])
        >>> G.fixed_points()
        []
        >>> G = PermutationGroup([(Integer(1),Integer(2),Integer(3)),(Integer(5),Integer(6))])
        >>> G.fixed_points()
        [4]
        >>> G = PermutationGroup([[(Integer(1),Integer(4),Integer(7))],[(Integer(4),Integer(3)),(Integer(6),Integer(7))]])
        >>> G.fixed_points()
        [2, 5]

  frattini_subgroup()

    Return the Frattini subgroup of `self`.

    The Frattini subgroup of a group \(G\) is the intersection of all maximal subgroups of \(G\).

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2,3,4)],[(2,4)]])
        sage: G.frattini_subgroup()
        Subgroup generated by [(1,3)(2,4)] of
         (Permutation Group with generators [(2,4), (1,2,3,4)])
        sage: G = SymmetricGroup(4)
        sage: G.frattini_subgroup()
        Subgroup generated by [()] of
         (Symmetric group of order 4! as a permutation group)

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))],[(Integer(2),Integer(4))]])
        >>> G.frattini_subgroup()
        Subgroup generated by [(1,3)(2,4)] of
         (Permutation Group with generators [(2,4), (1,2,3,4)])
        >>> G = SymmetricGroup(Integer(4))
        >>> G.frattini_subgroup()
        Subgroup generated by [()] of
         (Symmetric group of order 4! as a permutation group)

  gap()

    This method from `sage.groups.libgap_wrapper.ParentLibGAP` is added in order to achieve compatibility and have `sage.groups.libgap_morphism.GroupHomset_libgap` work for permutation groups, as well

    OUTPUT: an instance of `sage.libs.gap.element.GapElement` representing this group

    EXAMPLES:

    Sage

        sage: P8 = PSp(8,3)
        sage: P8.gap()
        <permutation group of size 65784756654489600 with 2 generators>
        sage: gap(P8) == P8.gap()
        False
        sage: S3 = SymmetricGroup(3)
        sage: S3.gap()
        Sym( [ 1 .. 3 ] )
        sage: gap(S3) == S3.gap()
        False

    Python

        >>> from sage.all import *
        >>> P8 = PSp(Integer(8),Integer(3))
        >>> P8.gap()
        <permutation group of size 65784756654489600 with 2 generators>
        >>> gap(P8) == P8.gap()
        False
        >>> S3 = SymmetricGroup(Integer(3))
        >>> S3.gap()
        Sym( [ 1 .. 3 ] )
        >>> gap(S3) == S3.gap()
        False

  gen(i=None)

    Return the \(i\)-th generator of `self`; that is, the \(i\)-th element of the list `self.gens()`.

    The argument \(i\) may be omitted if there is only one generator (but this will raise an error otherwise).

    EXAMPLES:

    We explicitly construct the alternating group on four elements:

    Sage

        sage: A4 = PermutationGroup([[(1,2,3)],[(2,3,4)]]); A4
        Permutation Group with generators [(2,3,4), (1,2,3)]
        sage: A4.gens()
        ((2,3,4), (1,2,3))
        sage: A4.gen(0)
        (2,3,4)
        sage: A4.gen(1)
        (1,2,3)
        sage: A4.gens()[0]; A4.gens()[1]
        (2,3,4)
        (1,2,3)

        sage: P1 = PermutationGroup([[(1,2)]]); P1.gen()
        (1,2)

    Python

        >>> from sage.all import *
        >>> A4 = PermutationGroup([[(Integer(1),Integer(2),Integer(3))],[(Integer(2),Integer(3),Integer(4))]]); A4
        Permutation Group with generators [(2,3,4), (1,2,3)]
        >>> A4.gens()
        ((2,3,4), (1,2,3))
        >>> A4.gen(Integer(0))
        (2,3,4)
        >>> A4.gen(Integer(1))
        (1,2,3)
        >>> A4.gens()[Integer(0)]; A4.gens()[Integer(1)]
        (2,3,4)
        (1,2,3)

        >>> P1 = PermutationGroup([[(Integer(1),Integer(2))]]); P1.gen()
        (1,2)

  gens()

    Return tuple of generators of this group.

    These need not be minimal, as they are the generators used in defining this group.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2,3)], [(1,2)]])
        sage: G.gens()
        ((1,2), (1,2,3))

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3))], [(Integer(1),Integer(2))]])
        >>> G.gens()
        ((1,2), (1,2,3))

    Note that the generators need not be minimal, though duplicates are removed:

    Sage

        sage: G = PermutationGroup([[(1,2)], [(1,3)], [(2,3)], [(1,2)]])
        sage: G.gens()
        ((2,3), (1,2), (1,3))

    [Python]

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2))], [(Integer(1),Integer(3))], [(Integer(2),Integer(3))], [(Integer(1),Integer(2))]])
        >>> G.gens()
        ((2,3), (1,2), (1,3))

    We can use index notation to access the generators returned by `self.gens`:

    Sage

        sage: G = PermutationGroup([[(1,2,3,4), (5,6)], [(1,2)]])
        sage: g = G.gens()
        sage: g[0]
        (1,2)
        sage: g[1]
        (1,2,3,4)(5,6)

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4)), (Integer(5),Integer(6))], [(Integer(1),Integer(2))]])
        >>> g = G.gens()
        >>> g[Integer(0)]
        (1,2)
        >>> g[Integer(1)]
        (1,2,3,4)(5,6)

  gens_small()

    For this group, returns a generating set which has few elements.

    As neither irredundancy nor minimal length is proven, it is fast.

    EXAMPLES:

    Sage

        sage: R = "(25,27,32,30)(26,29,31,28)( 3,38,43,19)( 5,36,45,21)( 8,33,48,24)" ## R = right
        sage: U = "( 1, 3, 8, 6)( 2, 5, 7, 4)( 9,33,25,17)(10,34,26,18)(11,35,27,19)" ## U = top
        sage: L = "( 9,11,16,14)(10,13,15,12)( 1,17,41,40)( 4,20,44,37)( 6,22,46,35)" ## L = left
        sage: F = "(17,19,24,22)(18,21,23,20)( 6,25,43,16)( 7,28,42,13)( 8,30,41,11)" ## F = front
        sage: B = "(33,35,40,38)(34,37,39,36)( 3, 9,46,32)( 2,12,47,29)( 1,14,48,27)" ## B = back or rear
        sage: D = "(41,43,48,46)(42,45,47,44)(14,22,30,38)(15,23,31,39)(16,24,32,40)" ## D = down or bottom
        sage: G = PermutationGroup([R,L,U,F,B,D])
        sage: len(G.gens_small())
        2

    Python

        >>> from sage.all import *
        >>> R = "(25,27,32,30)(26,29,31,28)( 3,38,43,19)( 5,36,45,21)( 8,33,48,24)" ## R = right
        >>> U = "( 1, 3, 8, 6)( 2, 5, 7, 4)( 9,33,25,17)(10,34,26,18)(11,35,27,19)" ## U = top
        >>> L = "( 9,11,16,14)(10,13,15,12)( 1,17,41,40)( 4,20,44,37)( 6,22,46,35)" ## L = left
        >>> F = "(17,19,24,22)(18,21,23,20)( 6,25,43,16)( 7,28,42,13)( 8,30,41,11)" ## F = front
        >>> B = "(33,35,40,38)(34,37,39,36)( 3, 9,46,32)( 2,12,47,29)( 1,14,48,27)" ## B = back or rear
        >>> D = "(41,43,48,46)(42,45,47,44)(14,22,30,38)(15,23,31,39)(16,24,32,40)" ## D = down or bottom
        >>> G = PermutationGroup([R,L,U,F,B,D])
        >>> len(G.gens_small())
        2

    The output may be unpredictable, due to the use of randomized algorithms in GAP. Note that both the following answers are equally valid.

    Sage

        sage: G = PermutationGroup([[('a','b')], [('b', 'c')], [('a', 'c')]])
        sage: G.gens_small() # random
        [('b','c'), ('a','c','b')] ## (on 64-bit Linux)
        [('a','b'), ('a','c','b')] ## (on Solaris)
        sage: len(G.gens_small()) == 2 # random
        True

    [Python]

        >>> from sage.all import *
        >>> G = PermutationGroup([[('a','b')], [('b', 'c')], [('a', 'c')]])
        >>> G.gens_small() # random
        [('b','c'), ('a','c','b')] ## (on 64-bit Linux)
        [('a','b'), ('a','c','b')] ## (on Solaris)
        >>> len(G.gens_small()) == Integer(2) # random
        True

  group_id()

    Return the ID code of this group, which is a list of two integers.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2,3),(4,5)], [(1,2)]])
        sage: G.group_id()
        [12, 4]

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3)),(Integer(4),Integer(5))], [(Integer(1),Integer(2))]])
        >>> G.group_id()
        [12, 4]

  group_primitive_id()

    Return the index of this group in the GAP database of primitive groups.

    OUTPUT:

    A positive integer, following GAP’s conventions. A `ValueError` is raised if the group is not primitive.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2,3,4,5)], [(1,5),(2,4)]])
        sage: G.group_primitive_id()
        2
        sage: G.degree()
        5

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4),Integer(5))], [(Integer(1),Integer(5)),(Integer(2),Integer(4))]])
        >>> G.group_primitive_id()
        2
        >>> G.degree()
        5

    From the information of the degree and the identification number, you can recover the isomorphism class of your group in the GAP database:

    Sage

        sage: H = PrimitiveGroup(5,2)
        sage: G == H
        False
        sage: G.is_isomorphic(H)
        True

    [Python]

        >>> from sage.all import *
        >>> H = PrimitiveGroup(Integer(5),Integer(2))
        >>> G == H
        False
        >>> G.is_isomorphic(H)
        True

  has_regular_subgroup(return_group=False)

    Return whether the group contains a regular subgroup.

    INPUT:

    - `return_group` – boolean; if `True`, a regular subgroup is returned if there is one, and `None` if there isn’t. When `return_group=False` (default), only a boolean indicating whether such a group exists is returned instead.

    EXAMPLES:

    The symmetric group on 4 elements has a regular subgroup:

    Sage

        sage: S4 = groups.permutation.Symmetric(4)
        sage: S4.has_regular_subgroup()
        True
        sage: S4.has_regular_subgroup(return_group=True)  # random
        Subgroup of (Symmetric group of order 4! as a permutation group)
         generated by [(1,3)(2,4), (1,4)(2,3)]

    Python

        >>> from sage.all import *
        >>> S4 = groups.permutation.Symmetric(Integer(4))
        >>> S4.has_regular_subgroup()
        True
        >>> S4.has_regular_subgroup(return_group=True)  # random
        Subgroup of (Symmetric group of order 4! as a permutation group)
         generated by [(1,3)(2,4), (1,4)(2,3)]

    But the automorphism group of Petersen’s graph does not:

    Sage

        sage: # needs sage.graphs
        sage: G = graphs.PetersenGraph().automorphism_group()
        sage: G.has_regular_subgroup()
        False

    [Python]

        >>> from sage.all import *
        >>> # needs sage.graphs
        >>> G = graphs.PetersenGraph().automorphism_group()
        >>> G.has_regular_subgroup()
        False

  holomorph()

    The holomorph of a group as a permutation group.

    The holomorph of a group \(G\) is the semidirect product \(G \rtimes_{id} Aut(G)\), where \(id\) is the identity function on \(Aut(G)\), the automorphism group of \(G\).

    See Wikipedia article Holomorph (mathematics)

    OUTPUT: the holomorph of a given group as permutation group via a wrapping of GAP’s semidirect product function

    EXAMPLES:

    Thomas and Wood’s ‘Group Tables’ (Shiva Publishing, 1980) tells us that the holomorph of \(C_5\) is the unique group of order 20 with a trivial center.

    Sage

        sage: C5 = CyclicPermutationGroup(5)
        sage: A = C5.holomorph()
        sage: A.order()
        20
        sage: A.is_abelian()
        False
        sage: A.center()
        Subgroup generated by [()] of
         (Permutation Group with generators [(5,6,7,8,9), (1,2,4,3)(6,7,9,8)])
        sage: A
        Permutation Group with generators [(5,6,7,8,9), (1,2,4,3)(6,7,9,8)]

    Python

        >>> from sage.all import *
        >>> C5 = CyclicPermutationGroup(Integer(5))
        >>> A = C5.holomorph()
        >>> A.order()
        20
        >>> A.is_abelian()
        False
        >>> A.center()
        Subgroup generated by [()] of
         (Permutation Group with generators [(5,6,7,8,9), (1,2,4,3)(6,7,9,8)])
        >>> A
        Permutation Group with generators [(5,6,7,8,9), (1,2,4,3)(6,7,9,8)]

    Noting that the automorphism group of \(D_4\) is itself \(D_4\), it can easily be shown that the holomorph is indeed an internal semidirect product of these two groups.

    Sage

        sage: D4 = DihedralGroup(4)
        sage: H = D4.holomorph()
        sage: H.gens()
        ((2,3,5,8), (2,5)(3,8), (3,8)(4,7), (1,4,6,7)(2,3,5,8), (1,8)(2,7)(3,6)(4,5))
        sage: G = H.subgroup([H.gens()[0],H.gens()[1],H.gens()[2]])
        sage: N = H.subgroup([H.gens()[3],H.gens()[4]])
        sage: N.is_normal(H)
        True
        sage: G.is_isomorphic(D4)
        True
        sage: N.is_isomorphic(D4)
        True
        sage: G.intersection(N)
        Permutation Group with generators [()]
        sage: L = [H(x)*H(y) for x in G for y in N]; L.sort()
        sage: L1 = H.list(); L1.sort()
        sage: L == L1
        True

    [Python]

        >>> from sage.all import *
        >>> D4 = DihedralGroup(Integer(4))
        >>> H = D4.holomorph()
        >>> H.gens()
        ((2,3,5,8), (2,5)(3,8), (3,8)(4,7), (1,4,6,7)(2,3,5,8), (1,8)(2,7)(3,6)(4,5))
        >>> G = H.subgroup([H.gens()[Integer(0)],H.gens()[Integer(1)],H.gens()[Integer(2)]])
        >>> N = H.subgroup([H.gens()[Integer(3)],H.gens()[Integer(4)]])
        >>> N.is_normal(H)
        True
        >>> G.is_isomorphic(D4)
        True
        >>> N.is_isomorphic(D4)
        True
        >>> G.intersection(N)
        Permutation Group with generators [()]
        >>> L = [H(x)*H(y) for x in G for y in N]; L.sort()
        >>> L1 = H.list(); L1.sort()
        >>> L == L1
        True

    Author:

    - Kevin Halasz (2012-08-14)

  homology(n, p=0)

    Compute the group homology \(H_n(G, F)\), where \(F = \ZZ\) if \(p=0\) and \(F = \ZZ / p \ZZ\) if \(p > 0\) is a prime. Wraps HAP’s `GroupHomology` function, written by Graham Ellis.

    REQUIRES: GAP package HAP (in gap_packages-*.spkg).

    AUTHORS:

    - David Joyner and Graham Ellis

    The example below computes \(H_7(S_5, \ZZ)\), \(H_7(S_5, \ZZ / 2 \ZZ)\), \(H_7(S_5, \ZZ / 3 \ZZ)\), and \(H_7(S_5, \ZZ / 5 \ZZ)\), respectively. To compute the \(2\)-part of \(H_7(S_5, \ZZ)\), use the method `homology_part()`.

    EXAMPLES:

    Sage

        sage: G = SymmetricGroup(5)
        sage: G.homology(7)                              # optional - gap_package_hap
        Multiplicative Abelian group isomorphic to C2 x C2 x C4 x C3 x C5
        sage: G.homology(7,2)                              # optional - gap_package_hap
        Multiplicative Abelian group isomorphic to C2 x C2 x C2 x C2 x C2
        sage: G.homology(7,3)                              # optional - gap_package_hap
        Multiplicative Abelian group isomorphic to C3
        sage: G.homology(7,5)                              # optional - gap_package_hap
        Multiplicative Abelian group isomorphic to C5

    Python

        >>> from sage.all import *
        >>> G = SymmetricGroup(Integer(5))
        >>> G.homology(Integer(7))                              # optional - gap_package_hap
        Multiplicative Abelian group isomorphic to C2 x C2 x C4 x C3 x C5
        >>> G.homology(Integer(7),Integer(2))                              # optional - gap_package_hap
        Multiplicative Abelian group isomorphic to C2 x C2 x C2 x C2 x C2
        >>> G.homology(Integer(7),Integer(3))                              # optional - gap_package_hap
        Multiplicative Abelian group isomorphic to C3
        >>> G.homology(Integer(7),Integer(5))                              # optional - gap_package_hap
        Multiplicative Abelian group isomorphic to C5

    REFERENCES:

    - G. Ellis, “Computing group resolutions”, J. Symbolic Computation. Vol.38, (2004)1077-1118 (Available at http://hamilton.nuigalway.ie/.

    - D. Joyner, “A primer on computational group homology and cohomology”, http://front.math.ucdavis.edu/0706.0549

  homology_part(n, p=0)

    Compute the \(p\)-part of the group homology \(H_n(G, F)\), where \(F = \ZZ\) if \(p=0\) and \(F = \ZZ / p \ZZ\) if \(p > 0\) is a prime. Wraps HAP’s `Homology` function, written by Graham Ellis, applied to the \(p\)-Sylow subgroup of \(G\).

    REQUIRES: GAP package HAP (in gap_packages-*.spkg).

    EXAMPLES:

    Sage

        sage: G = SymmetricGroup(5)
        sage: G.homology_part(7,2)                              # optional - gap_package_hap
        Multiplicative Abelian group isomorphic to C2 x C2 x C2 x C2 x C4

    Python

        >>> from sage.all import *
        >>> G = SymmetricGroup(Integer(5))
        >>> G.homology_part(Integer(7),Integer(2))                              # optional - gap_package_hap
        Multiplicative Abelian group isomorphic to C2 x C2 x C2 x C2 x C4

    AUTHORS:

    - David Joyner and Graham Ellis

  id()

    Return the ID code of this group, which is a list of two integers.

    Same as `group_id()`.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2,3),(4,5)], [(1,2)]])
        sage: G.group_id()
        [12, 4]

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3)),(Integer(4),Integer(5))], [(Integer(1),Integer(2))]])
        >>> G.group_id()
        [12, 4]

  identity()

    alias of `one()`.

  intersection(other)

    Return the permutation group that is the intersection of `self` and `other`.

    INPUT:

    - `other` – a permutation group

    OUTPUT:

    A permutation group that is the set-theoretic intersection of `self` with `other`. The groups are viewed as subgroups of a symmetric group big enough to contain both group’s symbol sets. So there is no strict notion of the two groups being subgroups of a common parent.

    EXAMPLES:

    Sage

        sage: H = DihedralGroup(4)

        sage: K = CyclicPermutationGroup(4)
        sage: H.intersection(K)
        Permutation Group with generators [(1,2,3,4)]

        sage: L = DihedralGroup(5)
        sage: H.intersection(L)
        Permutation Group with generators [(1,4)(2,3)]

        sage: M = PermutationGroup(["()"])
        sage: H.intersection(M)
        Permutation Group with generators [()]

    Python

        >>> from sage.all import *
        >>> H = DihedralGroup(Integer(4))

        >>> K = CyclicPermutationGroup(Integer(4))
        >>> H.intersection(K)
        Permutation Group with generators [(1,2,3,4)]

        >>> L = DihedralGroup(Integer(5))
        >>> H.intersection(L)
        Permutation Group with generators [(1,4)(2,3)]

        >>> M = PermutationGroup(["()"])
        >>> H.intersection(M)
        Permutation Group with generators [()]

    Some basic properties.

    Sage

        sage: H = DihedralGroup(4)
        sage: L = DihedralGroup(5)
        sage: H.intersection(L) == L.intersection(H)
        True
        sage: H.intersection(H) == H
        True

    [Python]

        >>> from sage.all import *
        >>> H = DihedralGroup(Integer(4))
        >>> L = DihedralGroup(Integer(5))
        >>> H.intersection(L) == L.intersection(H)
        True
        >>> H.intersection(H) == H
        True

    The group `other` is verified as such.

    Sage

        sage: H = DihedralGroup(4)
        sage: H.intersection('junk')
        Traceback (most recent call last):
        ...
        TypeError: junk is not a permutation group

    Python

        >>> from sage.all import *
        >>> H = DihedralGroup(Integer(4))
        >>> H.intersection('junk')
        Traceback (most recent call last):
        ...
        TypeError: junk is not a permutation group

  irreducible_characters()

    Return a list of the irreducible characters of `self`.

    EXAMPLES:

    Sage

        sage: irr = SymmetricGroup(3).irreducible_characters()                      # needs sage.rings.number_field
        sage: [x.values() for x in irr]                                             # needs sage.rings.number_field
        [[1, -1, 1], [2, 0, -1], [1, 1, 1]]

    Python

        >>> from sage.all import *
        >>> irr = SymmetricGroup(Integer(3)).irreducible_characters()                      # needs sage.rings.number_field
        >>> [x.values() for x in irr]                                             # needs sage.rings.number_field
        [[1, -1, 1], [2, 0, -1], [1, 1, 1]]

  is_abelian()

    Return `True` if this group is abelian.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        sage: G.is_abelian()
        False
        sage: G = PermutationGroup(['(1,2,3)(4,5)'])
        sage: G.is_abelian()
        True

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        >>> G.is_abelian()
        False
        >>> G = PermutationGroup(['(1,2,3)(4,5)'])
        >>> G.is_abelian()
        True

  is_commutative()

    Return `True` if this group is commutative.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        sage: G.is_commutative()
        False
        sage: G = PermutationGroup(['(1,2,3)(4,5)'])
        sage: G.is_commutative()
        True

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        >>> G.is_commutative()
        False
        >>> G = PermutationGroup(['(1,2,3)(4,5)'])
        >>> G.is_commutative()
        True

  is_cyclic()

    Return `True` if this group is cyclic.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        sage: G.is_cyclic()
        False
        sage: G = PermutationGroup(['(1,2,3)(4,5)'])
        sage: G.is_cyclic()
        True

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        >>> G.is_cyclic()
        False
        >>> G = PermutationGroup(['(1,2,3)(4,5)'])
        >>> G.is_cyclic()
        True

  is_elementary_abelian()

    Return `True` if this group is elementary abelian.

    An elementary abelian group is a finite abelian group, where every nontrivial element has order \(p\), where \(p\) is a prime.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        sage: G.is_elementary_abelian()
        False
        sage: G = PermutationGroup(['(1,2,3)','(4,5,6)'])
        sage: G.is_elementary_abelian()
        True

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        >>> G.is_elementary_abelian()
        False
        >>> G = PermutationGroup(['(1,2,3)','(4,5,6)'])
        >>> G.is_elementary_abelian()
        True

  is_isomorphic(right)

    Return `True` if the groups are isomorphic.

    INPUT:

    - `self` – this group

    - `right` – a permutation group

    OUTPUT: boolean; `True` if `self` and `right` are isomorphic groups; `False` otherwise

    EXAMPLES:

    Sage

        sage: v = ['(1,2,3)(4,5)', '(1,2,3,4,5)']
        sage: G = PermutationGroup(v)
        sage: H = PermutationGroup(['(1,2,3)(4,5)'])
        sage: G.is_isomorphic(H)
        False
        sage: G.is_isomorphic(G)
        True
        sage: G.is_isomorphic(PermutationGroup(list(reversed(v))))
        True

    Python

        >>> from sage.all import *
        >>> v = ['(1,2,3)(4,5)', '(1,2,3,4,5)']
        >>> G = PermutationGroup(v)
        >>> H = PermutationGroup(['(1,2,3)(4,5)'])
        >>> G.is_isomorphic(H)
        False
        >>> G.is_isomorphic(G)
        True
        >>> G.is_isomorphic(PermutationGroup(list(reversed(v))))
        True

  is_monomial()

    Return `True` if the group is monomial. A finite group is monomial if every irreducible complex character is induced from a linear character of a subgroup.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup(['(1,2,3)(4,5)'])
        sage: G.is_monomial()
        True

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup(['(1,2,3)(4,5)'])
        >>> G.is_monomial()
        True

  is_nilpotent()

    Return `True` if this group is nilpotent.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        sage: G.is_nilpotent()
        False
        sage: G = PermutationGroup(['(1,2,3)(4,5)'])
        sage: G.is_nilpotent()
        True

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        >>> G.is_nilpotent()
        False
        >>> G = PermutationGroup(['(1,2,3)(4,5)'])
        >>> G.is_nilpotent()
        True

  is_normal(other)

    Return `True` if this group is a normal subgroup of `other`.

    EXAMPLES:

    Sage

        sage: AlternatingGroup(4).is_normal(SymmetricGroup(4))
        True
        sage: H = PermutationGroup(['(1,2,3)(4,5)'])
        sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        sage: H.is_normal(G)
        False

    Python

        >>> from sage.all import *
        >>> AlternatingGroup(Integer(4)).is_normal(SymmetricGroup(Integer(4)))
        True
        >>> H = PermutationGroup(['(1,2,3)(4,5)'])
        >>> G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        >>> H.is_normal(G)
        False

  is_perfect()

    Return `True` if this group is perfect. A group is perfect if it equals its derived subgroup.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        sage: G.is_perfect()
        False
        sage: G = PermutationGroup(['(1,2,3)(4,5)'])
        sage: G.is_perfect()
        False

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        >>> G.is_perfect()
        False
        >>> G = PermutationGroup(['(1,2,3)(4,5)'])
        >>> G.is_perfect()
        False

  is_pgroup()

    Return `True` if this group is a \(p\)-group.

    A finite group is a \(p\)-group if its order is of the form \(p^n\) for a prime integer \(p\) and a nonnegative integer \(n\).

    EXAMPLES:

    Sage

        sage: G = PermutationGroup(['(1,2,3,4,5)'])
        sage: G.is_pgroup()
        True

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup(['(1,2,3,4,5)'])
        >>> G.is_pgroup()
        True

  is_polycyclic()

    Return `True` if this group is polycyclic. A group is polycyclic if it has a subnormal series with cyclic factors. (For finite groups, this is the same as if the group is solvable - see `is_solvable()`.)

    EXAMPLES:

    Sage

        sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        sage: G.is_polycyclic()
        False
        sage: G = PermutationGroup(['(1,2,3)(4,5)'])
        sage: G.is_polycyclic()
        True

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        >>> G.is_polycyclic()
        False
        >>> G = PermutationGroup(['(1,2,3)(4,5)'])
        >>> G.is_polycyclic()
        True

  is_primitive(domain=None)

    Return `True` if `self` acts primitively on `domain`.

    A group \(G\) acts primitively on a set \(S\) if

    1. \(G\) acts transitively on \(S\) and

    2. the action induces no non-trivial block system on \(S\).

    INPUT:

    - `domain` – optional

    See also

    - `blocks_all()`

    EXAMPLES:

    By default, test for primitivity of `self` on its domain:

    Sage

        sage: G = PermutationGroup([[(1,2,3,4)],[(1,2)]])
        sage: G.is_primitive()
        True
        sage: G = PermutationGroup([[(1,2,3,4)],[(2,4)]])
        sage: G.is_primitive()
        False

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))],[(Integer(1),Integer(2))]])
        >>> G.is_primitive()
        True
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))],[(Integer(2),Integer(4))]])
        >>> G.is_primitive()
        False

    You can specify a domain on which to test primitivity:

    Sage

        sage: G = PermutationGroup([[(1,2,3,4)],[(2,4)]])
        sage: G.is_primitive([1..4])
        False
        sage: G = PermutationGroup([[(3,4,5,6)],[(3,4)]]) #S_4 on [3..6]
        sage: G.is_primitive(G.non_fixed_points())
        True

    [Python]

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))],[(Integer(2),Integer(4))]])
        >>> G.is_primitive((ellipsis_range(Integer(1),Ellipsis,Integer(4))))
        False
        >>> G = PermutationGroup([[(Integer(3),Integer(4),Integer(5),Integer(6))],[(Integer(3),Integer(4))]]) #S_4 on [3..6]
        >>> G.is_primitive(G.non_fixed_points())
        True

    If \(G\) does not act on the domain, it always returns `False`:

    Sage

        sage: G = PermutationGroup([[(1,2,3,4)],[(2,4)]])
        sage: G.is_primitive([1,2,3])
        False

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))],[(Integer(2),Integer(4))]])
        >>> G.is_primitive([Integer(1),Integer(2),Integer(3)])
        False

  is_regular(domain=None)

    Return `True` if `self` acts regularly on `domain`.

    A group \(G\) acts regularly on a set \(S\) if

    1. \(G\) acts transitively on \(S\) and

    2. \(G\) acts semi-regularly on \(S\).

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2,3,4)]])
        sage: G.is_regular()
        True
        sage: G = PermutationGroup([[(1,2,3,4)],[(5,6)]])
        sage: G.is_regular()
        False

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))]])
        >>> G.is_regular()
        True
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))],[(Integer(5),Integer(6))]])
        >>> G.is_regular()
        False

    You can pass in a domain on which to test regularity:

    Sage

        sage: G = PermutationGroup([[(1,2,3,4)],[(5,6)]])
        sage: G.is_regular([1..4])
        True
        sage: G.is_regular(G.non_fixed_points())
        False

    [Python]

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))],[(Integer(5),Integer(6))]])
        >>> G.is_regular((ellipsis_range(Integer(1),Ellipsis,Integer(4))))
        True
        >>> G.is_regular(G.non_fixed_points())
        False

  is_semi_regular(domain=None)

    Return `True` if `self` acts semi-regularly on `domain`.

    A group \(G\) acts semi-regularly on a set \(S\) if the point stabilizers of \(S\) in \(G\) are trivial.

    `domain` is optional and may take several forms. See examples.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2,3,4)]])
        sage: G.is_semi_regular()
        True
        sage: G = PermutationGroup([[(1,2,3,4)],[(5,6)]])
        sage: G.is_semi_regular()
        False

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))]])
        >>> G.is_semi_regular()
        True
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))],[(Integer(5),Integer(6))]])
        >>> G.is_semi_regular()
        False

    You can pass in a domain to test semi-regularity:

    Sage

        sage: G = PermutationGroup([[(1,2,3,4)],[(5,6)]])
        sage: G.is_semi_regular([1..4])
        True
        sage: G.is_semi_regular(G.non_fixed_points())
        False

    [Python]

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))],[(Integer(5),Integer(6))]])
        >>> G.is_semi_regular((ellipsis_range(Integer(1),Ellipsis,Integer(4))))
        True
        >>> G.is_semi_regular(G.non_fixed_points())
        False

  is_simple()

    Return `True` if the group is simple.

    A group is simple if it has no proper normal subgroups.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup(['(1,2,3)(4,5)'])
        sage: G.is_simple()
        False

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup(['(1,2,3)(4,5)'])
        >>> G.is_simple()
        False

  is_solvable()

    Return `True` if the group is solvable.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup(['(1,2,3)(4,5)'])
        sage: G.is_solvable()
        True

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup(['(1,2,3)(4,5)'])
        >>> G.is_solvable()
        True

  is_subgroup(other)

    Return `True` if `self` is a subgroup of `other`.

    EXAMPLES:

    Sage

        sage: G = AlternatingGroup(5)
        sage: H = SymmetricGroup(5)
        sage: G.is_subgroup(H)
        True

    Python

        >>> from sage.all import *
        >>> G = AlternatingGroup(Integer(5))
        >>> H = SymmetricGroup(Integer(5))
        >>> G.is_subgroup(H)
        True

  is_supersolvable()

    Return `True` if the group is supersolvable.

    A finite group is supersolvable if it has a normal series with cyclic factors.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup(['(1,2,3)(4,5)'])
        sage: G.is_supersolvable()
        True

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup(['(1,2,3)(4,5)'])
        >>> G.is_supersolvable()
        True

  is_transitive(domain=None)

    Return `True` if `self` acts transitively on `domain`.

    A group \(G\) acts transitively on set \(S\) if for all \(x,y\in S\) there is some \(g\in G\) such that \(x^g=y\).

    EXAMPLES:

    Sage

        sage: G = SymmetricGroup(5)
        sage: G.is_transitive()
        True
        sage: G = PermutationGroup(['(1,2)(3,4)(5,6)'])
        sage: G.is_transitive()
        False

    Python

        >>> from sage.all import *
        >>> G = SymmetricGroup(Integer(5))
        >>> G.is_transitive()
        True
        >>> G = PermutationGroup(['(1,2)(3,4)(5,6)'])
        >>> G.is_transitive()
        False

    Sage

        sage: G = PermutationGroup([[(1,2,3,4,5)],[(1,2)],[(6,7)]])
        sage: G.is_transitive([1,2,3,4,5])
        True
        sage: G.is_transitive([1..7])
        False
        sage: G.is_transitive(G.non_fixed_points())
        False
        sage: H = PermutationGroup([[(1,2,3)],[(4,5,6)]])
        sage: H.is_transitive(H.non_fixed_points())
        False

    [Python]

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4),Integer(5))],[(Integer(1),Integer(2))],[(Integer(6),Integer(7))]])
        >>> G.is_transitive([Integer(1),Integer(2),Integer(3),Integer(4),Integer(5)])
        True
        >>> G.is_transitive((ellipsis_range(Integer(1),Ellipsis,Integer(7))))
        False
        >>> G.is_transitive(G.non_fixed_points())
        False
        >>> H = PermutationGroup([[(Integer(1),Integer(2),Integer(3))],[(Integer(4),Integer(5),Integer(6))]])
        >>> H.is_transitive(H.non_fixed_points())
        False

    If \(G\) does not act on the domain, it always returns `False`:

    Sage

        sage: G = PermutationGroup([[(1,2,3,4,5)],[(1,2)]]) #S_5 on [1..5]
        sage: G.is_transitive([1,4,5])
        False

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4),Integer(5))],[(Integer(1),Integer(2))]]) #S_5 on [1..5]
        >>> G.is_transitive([Integer(1),Integer(4),Integer(5)])
        False

    Note that this differs from the definition in GAP, where `IsTransitive` returns whether the group is transitive on the set of points moved by the group.

    Sage

        sage: G = PermutationGroup([(2,3)])
        sage: G.is_transitive()
        False
        sage: gap(G).IsTransitive()
        true

    [Python]

        >>> from sage.all import *
        >>> G = PermutationGroup([(Integer(2),Integer(3))])
        >>> G.is_transitive()
        False
        >>> gap(G).IsTransitive()
        true

  is_trivial()

    Return `True` if this group is the trivial group.

    A permutation group is trivial, if it consists only of the identity element, that is, if it has no generators or only trivial generators.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([], domain=["a", "b", "c"])
        sage: G.is_trivial()
        True
        sage: SymmetricGroup(0).is_trivial()
        True
        sage: SymmetricGroup(1).is_trivial()
        True
        sage: SymmetricGroup(2).is_trivial()
        False
        sage: DihedralGroup(1).is_trivial()
        False

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([], domain=["a", "b", "c"])
        >>> G.is_trivial()
        True
        >>> SymmetricGroup(Integer(0)).is_trivial()
        True
        >>> SymmetricGroup(Integer(1)).is_trivial()
        True
        >>> SymmetricGroup(Integer(2)).is_trivial()
        False
        >>> DihedralGroup(Integer(1)).is_trivial()
        False

  isomorphism_to(right)

    Return an isomorphism from `self` to `right` if the groups are isomorphic, otherwise `None`.

    INPUT:

    - `self` – this group

    - `right` – a permutation group

    OUTPUT: `None`, or a morphism of permutation groups

    EXAMPLES:

    Sage

        sage: G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        sage: H = PermutationGroup(['(1,2,3)(4,5)'])
        sage: G.isomorphism_to(H) is None
        True
        sage: G = PermutationGroup([(1,2,3), (2,3)])
        sage: H = PermutationGroup([(1,2,4), (1,4)])
        sage: G.isomorphism_to(H)  # not tested, see below
        Permutation group morphism:
          From: Permutation Group with generators [(2,3), (1,2,3)]
          To:   Permutation Group with generators [(1,2,4), (1,4)]
          Defn: [(2,3), (1,2,3)] -> [(2,4), (1,2,4)]

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        >>> H = PermutationGroup(['(1,2,3)(4,5)'])
        >>> G.isomorphism_to(H) is None
        True
        >>> G = PermutationGroup([(Integer(1),Integer(2),Integer(3)), (Integer(2),Integer(3))])
        >>> H = PermutationGroup([(Integer(1),Integer(2),Integer(4)), (Integer(1),Integer(4))])
        >>> G.isomorphism_to(H)  # not tested, see below
        Permutation group morphism:
          From: Permutation Group with generators [(2,3), (1,2,3)]
          To:   Permutation Group with generators [(1,2,4), (1,4)]
          Defn: [(2,3), (1,2,3)] -> [(2,4), (1,2,4)]

  isomorphism_type_info_simple_group()

    If the group is simple, then this returns the name of the group.

    EXAMPLES:

    Sage

        sage: G = CyclicPermutationGroup(5)
        sage: G.isomorphism_type_info_simple_group()
        rec(
          name := "Z(5)",
          parameter := 5,
          series := "Z",
          shortname := "C5" )

    Python

        >>> from sage.all import *
        >>> G = CyclicPermutationGroup(Integer(5))
        >>> G.isomorphism_type_info_simple_group()
        rec(
          name := "Z(5)",
          parameter := 5,
          series := "Z",
          shortname := "C5" )

  iteration(algorithm='SGS')

    Return an iterator over the elements of this group.

    INPUT:

    - `algorithm` – (default: `'SGS'`) either

      - `'SGS'` – using strong generating system

      - `'BFS'` – a breadth first search on the Cayley graph with respect to `self.gens()`

      - `'DFS'` – a depth first search on the Cayley graph with respect to `self.gens()`

    Note

    In general, the algorithm `'SGS'` is faster. Yet, for small groups, `'BFS'` and `'DFS'` might be faster.

    Note

    The order in which the iterator visits the elements differs in the algorithms.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2)], [(2,3)]])

        sage: list(G.iteration())
        [(), (1,2,3), (1,3,2), (2,3), (1,2), (1,3)]

        sage: list(G.iteration(algorithm='BFS'))
        [(), (2,3), (1,2), (1,2,3), (1,3,2), (1,3)]

        sage: list(G.iteration(algorithm='DFS'))
        [(), (1,2), (1,3,2), (1,3), (1,2,3), (2,3)]

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2))], [(Integer(2),Integer(3))]])

        >>> list(G.iteration())
        [(), (1,2,3), (1,3,2), (2,3), (1,2), (1,3)]

        >>> list(G.iteration(algorithm='BFS'))
        [(), (2,3), (1,2), (1,2,3), (1,3,2), (1,3)]

        >>> list(G.iteration(algorithm='DFS'))
        [(), (1,2), (1,3,2), (1,3), (1,2,3), (2,3)]

  largest_moved_point()

    Return the largest point moved by a permutation in this group.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4)]])
        sage: G.largest_moved_point()
        4
        sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4,10)]])
        sage: G.largest_moved_point()
        10

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2)),(Integer(3),Integer(4))], [(Integer(1),Integer(2),Integer(3),Integer(4))]])
        >>> G.largest_moved_point()
        4
        >>> G = PermutationGroup([[(Integer(1),Integer(2)),(Integer(3),Integer(4))], [(Integer(1),Integer(2),Integer(3),Integer(4),Integer(10))]])
        >>> G.largest_moved_point()
        10

    Sage

        sage: G = PermutationGroup([[('a','b','c'),('d','e')]])
        sage: G.largest_moved_point()
        'e'

    [Python]

        >>> from sage.all import *
        >>> G = PermutationGroup([[('a','b','c'),('d','e')]])
        >>> G.largest_moved_point()
        'e'

    Warning

    The name of this function is not good; this function should be deprecated in term of degree:

    Sage

        sage: P = PermutationGroup([[1,2,3,4]])
        sage: P.largest_moved_point()
        4
        sage: P.cardinality()
        1

    Python

        >>> from sage.all import *
        >>> P = PermutationGroup([[Integer(1),Integer(2),Integer(3),Integer(4)]])
        >>> P.largest_moved_point()
        4
        >>> P.cardinality()
        1

  list()

    Return list of all elements of this group.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2,3,4)], [(1,2)]])
        sage: G.list()
        [(), (1,4)(2,3), (1,2)(3,4), (1,3)(2,4), (2,4,3), (1,4,2),
         (1,2,3), (1,3,4), (2,3,4), (1,4,3), (1,2,4), (1,3,2), (3,4),
         (1,4,2,3), (1,2), (1,3,2,4), (2,4), (1,4,3,2), (1,2,3,4),
         (1,3), (2,3), (1,4), (1,2,4,3), (1,3,4,2)]

        sage: G = PermutationGroup([[('a','b')]], domain=('a', 'b')); G
        Permutation Group with generators [('a','b')]
        sage: G.list()
        [(), ('a','b')]

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))], [(Integer(1),Integer(2))]])
        >>> G.list()
        [(), (1,4)(2,3), (1,2)(3,4), (1,3)(2,4), (2,4,3), (1,4,2),
         (1,2,3), (1,3,4), (2,3,4), (1,4,3), (1,2,4), (1,3,2), (3,4),
         (1,4,2,3), (1,2), (1,3,2,4), (2,4), (1,4,3,2), (1,2,3,4),
         (1,3), (2,3), (1,4), (1,2,4,3), (1,3,4,2)]

        >>> G = PermutationGroup([[('a','b')]], domain=('a', 'b')); G
        Permutation Group with generators [('a','b')]
        >>> G.list()
        [(), ('a','b')]

  lower_central_series()

    Return the lower central series of this group as a list of permutation groups.

    EXAMPLES:

    These computations use pseudo-random numbers, so we set the seed for reproducible testing.

    Sage

        sage: set_random_seed(0)
        sage: G = PermutationGroup([[(1,2,3),(4,5)],[(3,4)]])
        sage: G.lower_central_series()
        [Subgroup generated by [(3,4), (1,2,3)(4,5)] of
          (Permutation Group with generators [(3,4), (1,2,3)(4,5)]),
         Subgroup generated by [(1,5)(3,4), (1,5)(2,4), (1,3,5)] of
          (Permutation Group with generators [(3,4), (1,2,3)(4,5)])]

    Python

        >>> from sage.all import *
        >>> set_random_seed(Integer(0))
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3)),(Integer(4),Integer(5))],[(Integer(3),Integer(4))]])
        >>> G.lower_central_series()
        [Subgroup generated by [(3,4), (1,2,3)(4,5)] of
          (Permutation Group with generators [(3,4), (1,2,3)(4,5)]),
         Subgroup generated by [(1,5)(3,4), (1,5)(2,4), (1,3,5)] of
          (Permutation Group with generators [(3,4), (1,2,3)(4,5)])]

  maximal_normal_subgroups()

    Return the maximal proper normal subgroups of `self`.

    This raises an error if \(G/[G, G]\) is infinite, yielding infinitely many maximal normal subgroups.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([(1,2,3),(4,5)])
        sage: G.maximal_normal_subgroups()
        [Subgroup generated by [(1,2,3)] of (Permutation Group with generators [(4,5), (1,2,3)]),
         Subgroup generated by [(4,5)] of (Permutation Group with generators [(4,5), (1,2,3)])]

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([(Integer(1),Integer(2),Integer(3)),(Integer(4),Integer(5))])
        >>> G.maximal_normal_subgroups()
        [Subgroup generated by [(1,2,3)] of (Permutation Group with generators [(4,5), (1,2,3)]),
         Subgroup generated by [(4,5)] of (Permutation Group with generators [(4,5), (1,2,3)])]

  minimal_generating_set()

    Return a minimal generating set.

    EXAMPLES:

    Sage

        sage: # needs sage.graphs
        sage: g = graphs.CompleteGraph(4)
        sage: g.relabel(['a','b','c','d'])
        sage: mgs = g.automorphism_group().minimal_generating_set(); len(mgs)
        2
        sage: mgs # random
        [('b','d','c'), ('a','c','b','d')]

    Python

        >>> from sage.all import *
        >>> # needs sage.graphs
        >>> g = graphs.CompleteGraph(Integer(4))
        >>> g.relabel(['a','b','c','d'])
        >>> mgs = g.automorphism_group().minimal_generating_set(); len(mgs)
        2
        >>> mgs # random
        [('b','d','c'), ('a','c','b','d')]

  minimal_normal_subgroups()

    Return the nontrivial minimal normal subgroups `self`.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([(1,2,3),(4,5)])
        sage: G.minimal_normal_subgroups()
        [Subgroup generated by [(4,5)] of (Permutation Group with generators [(4,5), (1,2,3)]),
         Subgroup generated by [(1,2,3)] of (Permutation Group with generators [(4,5), (1,2,3)])]

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([(Integer(1),Integer(2),Integer(3)),(Integer(4),Integer(5))])
        >>> G.minimal_normal_subgroups()
        [Subgroup generated by [(4,5)] of (Permutation Group with generators [(4,5), (1,2,3)]),
         Subgroup generated by [(1,2,3)] of (Permutation Group with generators [(4,5), (1,2,3)])]

  molien_series()

    Return the Molien series of a permutation group. The function

    \[M(x) = (1/|G|)\sum_{g\in G} \det(1-x*g)^{-1}\]

    is sometimes called the “Molien series” of \(G\). GAP’s `MolienSeries` is associated to a character of a group \(G\). How are these related? A group \(G\), given as a permutation group on \(n\) points, has a “natural” representation of dimension \(n\), given by permutation matrices. The Molien series of \(G\) is the one associated to that permutation representation of \(G\) using the above formula. Character values then count fixed points of the corresponding permutations.

    EXAMPLES:

    Sage

        sage: G = SymmetricGroup(5)
        sage: G.molien_series()
        -1/(x^15 - x^14 - x^13 + x^10 + x^9 + x^8 - x^7 - x^6 - x^5 + x^2 + x - 1)
        sage: G = SymmetricGroup(3)
        sage: G.molien_series()
        -1/(x^6 - x^5 - x^4 + x^2 + x - 1)

    Python

        >>> from sage.all import *
        >>> G = SymmetricGroup(Integer(5))
        >>> G.molien_series()
        -1/(x^15 - x^14 - x^13 + x^10 + x^9 + x^8 - x^7 - x^6 - x^5 + x^2 + x - 1)
        >>> G = SymmetricGroup(Integer(3))
        >>> G.molien_series()
        -1/(x^6 - x^5 - x^4 + x^2 + x - 1)

    Some further tests (after Issue #15817):

    Sage

        sage: G = PermutationGroup([[(1,2,3,4)]])
        sage: S4ms = SymmetricGroup(4).molien_series()
        sage: G.molien_series() / S4ms
        x^5 + 2*x^4 + x^3 + x^2 + 1

    [Python]

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))]])
        >>> S4ms = SymmetricGroup(Integer(4)).molien_series()
        >>> G.molien_series() / S4ms
        x^5 + 2*x^4 + x^3 + x^2 + 1

    This works for not-transitive groups:

    Sage

        sage: G = PermutationGroup([[(1,2)],[(3,4)]])
        sage: G.molien_series() / S4ms
        x^4 + x^3 + 2*x^2 + x + 1

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2))],[(Integer(3),Integer(4))]])
        >>> G.molien_series() / S4ms
        x^4 + x^3 + 2*x^2 + x + 1

    This works for groups with fixed points:

    Sage

        sage: G = PermutationGroup([[(2,)]])
        sage: G.molien_series()
        1/(x^2 - 2*x + 1)

    [Python]

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(2),)]])
        >>> G.molien_series()
        1/(x^2 - 2*x + 1)

  ngens()

    Return the number of generators of `self`.

    EXAMPLES:

    Sage

        sage: A4 = PermutationGroup([[(1,2,3)], [(2,3,4)]]); A4
        Permutation Group with generators [(2,3,4), (1,2,3)]
        sage: A4.ngens()
        2

    Python

        >>> from sage.all import *
        >>> A4 = PermutationGroup([[(Integer(1),Integer(2),Integer(3))], [(Integer(2),Integer(3),Integer(4))]]); A4
        Permutation Group with generators [(2,3,4), (1,2,3)]
        >>> A4.ngens()
        2

  non_fixed_points()

    Return the list of points not fixed by `self`, i.e., the subset of `self.domain()` moved by some element of `self`.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(3,4,5)],[(7,10)]])
        sage: G.non_fixed_points()
        [3, 4, 5, 7, 10]
        sage: G = PermutationGroup([[(2,3,6)],[(9,)]]) # note: 9 is fixed
        sage: G.non_fixed_points()
        [2, 3, 6]

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(3),Integer(4),Integer(5))],[(Integer(7),Integer(10))]])
        >>> G.non_fixed_points()
        [3, 4, 5, 7, 10]
        >>> G = PermutationGroup([[(Integer(2),Integer(3),Integer(6))],[(Integer(9),)]]) # note: 9 is fixed
        >>> G.non_fixed_points()
        [2, 3, 6]

  normal_subgroups()

    Return the normal subgroups of this group as a (sorted in increasing order) list of permutation groups.

    The normal subgroups of \(H = PSL(2,7) \times PSL(2,7)\) are \(1\), two copies of \(PSL(2,7)\) and \(H\) itself, as the following example shows.

    EXAMPLES:

    Sage

        sage: G = PSL(2,7)
        sage: D = G.direct_product(G)
        sage: H = D[0]
        sage: NH = H.normal_subgroups()
        sage: len(NH)
        4
        sage: NH[1].is_isomorphic(G)
        True
        sage: NH[2].is_isomorphic(G)
        True

    Python

        >>> from sage.all import *
        >>> G = PSL(Integer(2),Integer(7))
        >>> D = G.direct_product(G)
        >>> H = D[Integer(0)]
        >>> NH = H.normal_subgroups()
        >>> len(NH)
        4
        >>> NH[Integer(1)].is_isomorphic(G)
        True
        >>> NH[Integer(2)].is_isomorphic(G)
        True

  normalizer(g)

    Return the normalizer of `g` in `self`.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4)]])
        sage: g = G([(1,3)])
        sage: G.normalizer(g)
        Subgroup generated by [(1,3), (2,4)] of
         (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)])
        sage: g = G([(1,2,3,4)])
        sage: G.normalizer(g)
        Subgroup generated by  [(1,2,3,4), (1,3)(2,4), (2,4)] of
         (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)])
        sage: H = G.subgroup([G([(1,2,3,4)])])
        sage: G.normalizer(H)
        Subgroup generated by [(1,2,3,4), (1,3)(2,4), (2,4)] of
         (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)])

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2)),(Integer(3),Integer(4))], [(Integer(1),Integer(2),Integer(3),Integer(4))]])
        >>> g = G([(Integer(1),Integer(3))])
        >>> G.normalizer(g)
        Subgroup generated by [(1,3), (2,4)] of
         (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)])
        >>> g = G([(Integer(1),Integer(2),Integer(3),Integer(4))])
        >>> G.normalizer(g)
        Subgroup generated by  [(1,2,3,4), (1,3)(2,4), (2,4)] of
         (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)])
        >>> H = G.subgroup([G([(Integer(1),Integer(2),Integer(3),Integer(4))])])
        >>> G.normalizer(H)
        Subgroup generated by [(1,2,3,4), (1,3)(2,4), (2,4)] of
         (Permutation Group with generators [(1,2)(3,4), (1,2,3,4)])

  normalizes(other)

    Return `True` if the group `other` is normalized by `self`.

    Wraps GAP’s `IsNormal` function.

    A group \(G\) normalizes a group \(U\) if and only if for every \(g \in G\) and \(u \in U\) the element \(u^g\) is a member of \(U\). Note that \(U\) need not be a subgroup of \(G\).

    EXAMPLES:

    Sage

        sage: G = PermutationGroup(['(1,2,3)(4,5)'])
        sage: H = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        sage: H.normalizes(G)
        False
        sage: G = SymmetricGroup(3)
        sage: H = PermutationGroup( [ (4,5,6) ] )
        sage: G.normalizes(H)
        True
        sage: H.normalizes(G)
        True

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup(['(1,2,3)(4,5)'])
        >>> H = PermutationGroup(['(1,2,3)(4,5)', '(1,2,3,4,5)'])
        >>> H.normalizes(G)
        False
        >>> G = SymmetricGroup(Integer(3))
        >>> H = PermutationGroup( [ (Integer(4),Integer(5),Integer(6)) ] )
        >>> G.normalizes(H)
        True
        >>> H.normalizes(G)
        True

    In the last example, \(G\) and \(H\) are disjoint, so each normalizes the other.

  one()

    Return the identity element of this group.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2,3),(4,5)]])
        sage: e = G.identity(); e                       # indirect doctest
        ()
        sage: g = G.gen(0)
        sage: g*e
        (1,2,3)(4,5)
        sage: e*g
        (1,2,3)(4,5)

        sage: S = SymmetricGroup(['a','b','c'])
        sage: S.identity()
        ()

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3)),(Integer(4),Integer(5))]])
        >>> e = G.identity(); e                       # indirect doctest
        ()
        >>> g = G.gen(Integer(0))
        >>> g*e
        (1,2,3)(4,5)
        >>> e*g
        (1,2,3)(4,5)

        >>> S = SymmetricGroup(['a','b','c'])
        >>> S.identity()
        ()

  orbit(point, action='OnPoints')

    Return the orbit of a point under a group action.

    INPUT:

    - `point` – can be a point or any of the list above, depending on the action to be considered

    - `action` – string; if `point` is an element from the domain, a tuple of elements of the domain, a tuple of tuples […], this variable describes how the group is acting

      The actions currently available through this method are `'OnPoints'`, `'OnTuples'`, `'OnSets'`, `'OnPairs'`, `'OnSetsSets'`, `'OnSetsDisjointSets'`, `'OnSetsTuples'`, `'OnTuplesSets'`, `'OnTuplesTuples'`. They are taken from GAP’s list of group actions, see `gap.help('Group Actions')`.

      It is set to `'OnPoints'` by default. See below for examples.

    OUTPUT:

    The orbit of `point` as a tuple. Each entry is an image under the action of the permutation group, if necessary converted to the corresponding container. That is, if `action='OnSets'` then each entry will be a set even if `point` was given by a list/tuple/iterable.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([ [(3,4)], [(1,3)] ])
        sage: G.orbit(3)
        (3, 4, 1)
        sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4,10)]])
        sage: G.orbit(3)
        (3, 4, 10, 1, 2)
        sage: G = PermutationGroup([ [('c','d')], [('a','c')] ])
        sage: G.orbit('a')
        ('a', 'c', 'd')

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([ [(Integer(3),Integer(4))], [(Integer(1),Integer(3))] ])
        >>> G.orbit(Integer(3))
        (3, 4, 1)
        >>> G = PermutationGroup([[(Integer(1),Integer(2)),(Integer(3),Integer(4))], [(Integer(1),Integer(2),Integer(3),Integer(4),Integer(10))]])
        >>> G.orbit(Integer(3))
        (3, 4, 10, 1, 2)
        >>> G = PermutationGroup([ [('c','d')], [('a','c')] ])
        >>> G.orbit('a')
        ('a', 'c', 'd')

    Action of \(S_3\) on sets:

    Sage

        sage: S3 = groups.permutation.Symmetric(3)
        sage: S3.orbit((1,2), action = "OnSets")
        ({1, 2}, {2, 3}, {1, 3})

    [Python]

        >>> from sage.all import *
        >>> S3 = groups.permutation.Symmetric(Integer(3))
        >>> S3.orbit((Integer(1),Integer(2)), action = "OnSets")
        ({1, 2}, {2, 3}, {1, 3})

    On tuples:

    Sage

        sage: S3.orbit((1,2), action = "OnTuples")
        ((1, 2), (2, 3), (2, 1), (3, 1), (1, 3), (3, 2))

    Python

        >>> from sage.all import *
        >>> S3.orbit((Integer(1),Integer(2)), action = "OnTuples")
        ((1, 2), (2, 3), (2, 1), (3, 1), (1, 3), (3, 2))

    Action of \(S_4\) on sets of disjoint sets:

    Sage

        sage: S4 = groups.permutation.Symmetric(4)
        sage: O = S4.orbit(((1,2),(3,4)), action='OnSetsDisjointSets')
        sage: {1, 2} in O[0] and {3, 4} in O[0]
        True
        sage: {1, 4} in O[1] and {2, 3} in O[1]
        True
        sage: all(x[0].union(x[1]) == {1,2,3,4} for x in O)
        True

    [Python]

        >>> from sage.all import *
        >>> S4 = groups.permutation.Symmetric(Integer(4))
        >>> O = S4.orbit(((Integer(1),Integer(2)),(Integer(3),Integer(4))), action='OnSetsDisjointSets')
        >>> {Integer(1), Integer(2)} in O[Integer(0)] and {Integer(3), Integer(4)} in O[Integer(0)]
        True
        >>> {Integer(1), Integer(4)} in O[Integer(1)] and {Integer(2), Integer(3)} in O[Integer(1)]
        True
        >>> all(x[Integer(0)].union(x[Integer(1)]) == {Integer(1),Integer(2),Integer(3),Integer(4)} for x in O)
        True

    Action of \(S_4\) (on a nonstandard domain) on tuples of sets:

    Sage

        sage: S4 = PermutationGroup([ [('c','d')], [('a','c')], [('a','b')] ])
        sage: orb = S4.orbit((('a','c'),('b','d')), "OnTuplesSets")
        sage: expect = (({'a', 'c'}, {'b', 'd'}), ({'a', 'd'}, {'c', 'b'}),
        ....:           ({'c', 'b'}, {'a', 'd'}), ({'b', 'd'}, {'a', 'c'}),
        ....:           ({'c', 'd'}, {'a', 'b'}), ({'a', 'b'}, {'c', 'd'}))
        sage: expect == orb
        True

    Python

        >>> from sage.all import *
        >>> S4 = PermutationGroup([ [('c','d')], [('a','c')], [('a','b')] ])
        >>> orb = S4.orbit((('a','c'),('b','d')), "OnTuplesSets")
        >>> expect = (({'a', 'c'}, {'b', 'd'}), ({'a', 'd'}, {'c', 'b'}),
        ...           ({'c', 'b'}, {'a', 'd'}), ({'b', 'd'}, {'a', 'c'}),
        ...           ({'c', 'd'}, {'a', 'b'}), ({'a', 'b'}, {'c', 'd'}))
        >>> expect == orb
        True

    Action of \(S_4\) (on a very nonstandard domain) on tuples of sets:

    Sage

        sage: S4 = PermutationGroup([ [((11,(12,13)),'d')],
        ....:         [((12,(12,11)),(11,(12,13)))], [((12,(12,11)),'b')] ])
        sage: orb = S4.orbit((( (11,(12,13)), (12,(12,11))),('b','d')),
        ....:                "OnTuplesSets")
        sage: expect = (({(11, (12, 13)), (12, (12, 11))}, {'b', 'd'}),
        ....:           ({'d', (12, (12, 11))}, {(11, (12, 13)), 'b'}),
        ....:           ({(11, (12, 13)), 'b'}, {'d', (12, (12, 11))}),
        ....:           ({(11, (12, 13)), 'd'}, {'b', (12, (12, 11))}),
        ....:           ({'b', 'd'}, {(11, (12, 13)), (12, (12, 11))}),
        ....:           ({'b', (12, (12, 11))}, {(11, (12, 13)), 'd'}))
        sage: all(x in orb for x in expect) and len(orb) == len(expect)
        True

    [Python]

        >>> from sage.all import *
        >>> S4 = PermutationGroup([ [((Integer(11),(Integer(12),Integer(13))),'d')],
        ...         [((Integer(12),(Integer(12),Integer(11))),(Integer(11),(Integer(12),Integer(13))))], [((Integer(12),(Integer(12),Integer(11))),'b')] ])
        >>> orb = S4.orbit((( (Integer(11),(Integer(12),Integer(13))), (Integer(12),(Integer(12),Integer(11)))),('b','d')),
        ...                "OnTuplesSets")
        >>> expect = (({(Integer(11), (Integer(12), Integer(13))), (Integer(12), (Integer(12), Integer(11)))}, {'b', 'd'}),
        ...           ({'d', (Integer(12), (Integer(12), Integer(11)))}, {(Integer(11), (Integer(12), Integer(13))), 'b'}),
        ...           ({(Integer(11), (Integer(12), Integer(13))), 'b'}, {'d', (Integer(12), (Integer(12), Integer(11)))}),
        ...           ({(Integer(11), (Integer(12), Integer(13))), 'd'}, {'b', (Integer(12), (Integer(12), Integer(11)))}),
        ...           ({'b', 'd'}, {(Integer(11), (Integer(12), Integer(13))), (Integer(12), (Integer(12), Integer(11)))}),
        ...           ({'b', (Integer(12), (Integer(12), Integer(11)))}, {(Integer(11), (Integer(12), Integer(13))), 'd'}))
        >>> all(x in orb for x in expect) and len(orb) == len(expect)
        True

  orbits()

    Return the orbits of the elements of the domain under the default group action.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([ [(3,4)], [(1,3)] ])
        sage: G.orbits()
        ((1, 3, 4), (2,))
        sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4,10)]])
        sage: G.orbits()
        ((1, 2, 3, 4, 10), (5,), (6,), (7,), (8,), (9,))

        sage: G = PermutationGroup([ [('c','d')], [('a','c')],[('b',)]])
        sage: G.orbits()
        (('a', 'c', 'd'), ('b',))

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([ [(Integer(3),Integer(4))], [(Integer(1),Integer(3))] ])
        >>> G.orbits()
        ((1, 3, 4), (2,))
        >>> G = PermutationGroup([[(Integer(1),Integer(2)),(Integer(3),Integer(4))], [(Integer(1),Integer(2),Integer(3),Integer(4),Integer(10))]])
        >>> G.orbits()
        ((1, 2, 3, 4, 10), (5,), (6,), (7,), (8,), (9,))

        >>> G = PermutationGroup([ [('c','d')], [('a','c')],[('b',)]])
        >>> G.orbits()
        (('a', 'c', 'd'), ('b',))

    The answer is cached:

    Sage

        sage: G.orbits() is G.orbits()
        True

    [Python]

        >>> from sage.all import *
        >>> G.orbits() is G.orbits()
        True

    AUTHORS:

    - Nathan Dunfield

  order()

    Return the number of elements of this group.

    See also: `degree()`.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2,3),(4,5)], [(1,2)]])
        sage: G.order()
        12
        sage: G = PermutationGroup([()])
        sage: G.order()
        1
        sage: G = PermutationGroup([])
        sage: G.order()
        1

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3)),(Integer(4),Integer(5))], [(Integer(1),Integer(2))]])
        >>> G.order()
        12
        >>> G = PermutationGroup([()])
        >>> G.order()
        1
        >>> G = PermutationGroup([])
        >>> G.order()
        1

    `cardinality()` is just an alias:

    Sage

        sage: PermutationGroup([(1,2,3)]).cardinality()
        3

    [Python]

        >>> from sage.all import *
        >>> PermutationGroup([(Integer(1),Integer(2),Integer(3))]).cardinality()
        3

  poincare_series(p=2, n=10)

    Return the Poincaré series of \(G \mod p\) (\(p \geq 2\) must be a prime), for \(n\) large.

    In other words, if you input a finite group \(G\), a prime \(p\), and a positive integer \(n\), it returns a quotient of polynomials \(f(x) = P(x) / Q(x)\) whose coefficient of \(x^k\) equals the rank of the vector space \(H_k(G, \ZZ / p \ZZ)\), for all \(k\) in the range \(1 \leq k \leq n\).

    REQUIRES: GAP package HAP (in gap_packages-*.spkg).

    EXAMPLES:

    Sage

        sage: G = SymmetricGroup(5)
        sage: G.poincare_series(2, 10)                             # optional - gap_package_hap
        (x^2 + 1)/(x^4 - x^3 - x + 1)
        sage: G = SymmetricGroup(3)
        sage: G.poincare_series(2, 10)                             # optional - gap_package_hap
        -1/(x - 1)

    Python

        >>> from sage.all import *
        >>> G = SymmetricGroup(Integer(5))
        >>> G.poincare_series(Integer(2), Integer(10))                             # optional - gap_package_hap
        (x^2 + 1)/(x^4 - x^3 - x + 1)
        >>> G = SymmetricGroup(Integer(3))
        >>> G.poincare_series(Integer(2), Integer(10))                             # optional - gap_package_hap
        -1/(x - 1)

    AUTHORS:

    - David Joyner and Graham Ellis

  quotient(N, **kwds)

    Return the quotient of this permutation group by the normal subgroup \(N\), as a permutation group.

    Further named arguments are passed to the permutation group constructor.

    Wraps the GAP operator “/”.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([(1,2,3), (2,3)])
        sage: N = PermutationGroup([(1,2,3)])
        sage: G.quotient(N)
        Permutation Group with generators [(1,2)]
        sage: G.quotient(G)
        Permutation Group with generators [(), ()]

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([(Integer(1),Integer(2),Integer(3)), (Integer(2),Integer(3))])
        >>> N = PermutationGroup([(Integer(1),Integer(2),Integer(3))])
        >>> G.quotient(N)
        Permutation Group with generators [(1,2)]
        >>> G.quotient(G)
        Permutation Group with generators [(), ()]

  random_element()

    Return a random element of this group.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(1,2,3),(4,5)], [(1,2)]])
        sage: a = G.random_element()
        sage: a in G
        True
        sage: a.parent() is G
        True
        sage: a^6
        ()

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3)),(Integer(4),Integer(5))], [(Integer(1),Integer(2))]])
        >>> a = G.random_element()
        >>> a in G
        True
        >>> a.parent() is G
        True
        >>> a**Integer(6)
        ()

  representative_action(x, y)

    Return an element of `self` that maps \(x\) to \(y\) if it exists.

    This method wraps the gap function `RepresentativeAction`, which can also return elements that map a given set of points on another set of points.

    INPUT:

    - `x`, `y` – two elements of the domain

    EXAMPLES:

    Sage

        sage: G = groups.permutation.Cyclic(14)
        sage: g = G.representative_action(1, 10)
        sage: all(g(x) == 1 + ((x+9-1)%14) for x in G.domain())
        True

    Python

        >>> from sage.all import *
        >>> G = groups.permutation.Cyclic(Integer(14))
        >>> g = G.representative_action(Integer(1), Integer(10))
        >>> all(g(x) == Integer(1) + ((x+Integer(9)-Integer(1))%Integer(14)) for x in G.domain())
        True

  semidirect_product(N, mapping, check=True)

    The semidirect product of `self` with `N`.

    INPUT:

    - `N` – a group which is acted on by `self` and naturally embeds as a normal subgroup of the returned semidirect product

    - `mapping` – a pair of lists that together define a homomorphism, \(\phi :\) `self` \(\rightarrow\) Aut(`N`), by giving, in the second list, the images of the generators of `self` in the order given in the first list

    - `check` – a boolean that, if set to `False`, will skip the initial tests which are made on `mapping`. This may be beneficial for large `N`, since in such cases the injectivity test can be expensive. Set to `True` by default.

    OUTPUT:

    The semidirect product of `self` and `N` defined by the action of `self` on `N` given in `mapping` (note that a homomorphism from \(A\) to the automorphism group of \(B\) is equivalent to an action of \(A\) on \(B\)’s underlying set). The semidirect product of two groups, \(H\) and \(N\), is a construct similar to the direct product in so far as the elements are the Cartesian product of the elements of \(H\) and the elements of \(N\). The operation, however, is built upon an action of \(H\) on \(N\), and is defined as such:

    \[(h_1,n_1)(h_2,n_2) = (h_{1}h_{2}, n_{1}^{h_2}n_2)\]

    This function is a wrapper for GAP’s `SemidirectProduct` command. The permutation group returned is built upon a permutation representation of the semidirect product of `self` and `N` on a set of size \(\mid N \mid\). The generators of `N` are given as their right regular representations, while the generators of `self` are defined by the underlying action of `self` on `N`. It should be noted that the defining action is not always faithful, and in this case the inputted representations of the generators of `self` are placed on additional letters and adjoined to the output’s generators of `self`.

    EXAMPLES:

    Perhaps the most common example of a semidirect product comes from the family of dihedral groups. Each dihedral group is the semidirect product of \(C_2\) with \(C_n\), where, by convention, \(3 \leq n\). In this case, the nontrivial element of \(C_2\) acts on \(C_n\) so as to send each element to its inverse.

    Sage

        sage: C2 = CyclicPermutationGroup(2)
        sage: C8 = CyclicPermutationGroup(8)
        sage: alpha = PermutationGroupMorphism_im_gens(C8,C8,[(1,8,7,6,5,4,3,2)])
        sage: S = C2.semidirect_product(C8,[[(1,2)],[alpha]])
        sage: S == DihedralGroup(8)
        False
        sage: S.is_isomorphic(DihedralGroup(8))
        True
        sage: S.gens()
        ((3,4,5,6,7,8,9,10), (1,2)(4,10)(5,9)(6,8))

    Python

        >>> from sage.all import *
        >>> C2 = CyclicPermutationGroup(Integer(2))
        >>> C8 = CyclicPermutationGroup(Integer(8))
        >>> alpha = PermutationGroupMorphism_im_gens(C8,C8,[(Integer(1),Integer(8),Integer(7),Integer(6),Integer(5),Integer(4),Integer(3),Integer(2))])
        >>> S = C2.semidirect_product(C8,[[(Integer(1),Integer(2))],[alpha]])
        >>> S == DihedralGroup(Integer(8))
        False
        >>> S.is_isomorphic(DihedralGroup(Integer(8)))
        True
        >>> S.gens()
        ((3,4,5,6,7,8,9,10), (1,2)(4,10)(5,9)(6,8))

    A more complicated example can be drawn from [TW1980]. It is there given that a semidirect product of \(D_4\) and \(C_3\) is isomorphic to one of \(C_2\) and the dicyclic group of order 12. This nonabelian group of order 24 has very similar structure to the dicyclic and dihedral groups of order 24, the three being the only groups of order 24 with a two-element center and 9 conjugacy classes.

    Sage

        sage: D4 = DihedralGroup(4)
        sage: C3 = CyclicPermutationGroup(3)
        sage: alpha1 = PermutationGroupMorphism_im_gens(C3,C3,[(1,3,2)])
        sage: alpha2 = PermutationGroupMorphism_im_gens(C3,C3,[(1,2,3)])
        sage: S1 = D4.semidirect_product(C3,[[(1,2,3,4),(1,3)],[alpha1,alpha2]])
        sage: C2 = CyclicPermutationGroup(2)
        sage: Q = DiCyclicGroup(3)
        sage: a = Q.gens()[0]; b=Q.gens()[1].inverse()
        sage: alpha = PermutationGroupMorphism_im_gens(Q,Q,[a,b])
        sage: S2 = C2.semidirect_product(Q,[[(1,2)],[alpha]])
        sage: S1.is_isomorphic(S2)
        True
        sage: S1.is_isomorphic(DihedralGroup(12))
        False
        sage: S1.is_isomorphic(DiCyclicGroup(6))
        False
        sage: S1.center()
        Subgroup generated by [(1,3)(2,4)] of
         (Permutation Group with generators [(5,6,7), (1,2,3,4)(6,7), (1,3)])
        sage: len(S1.conjugacy_classes_representatives())
        9

    [Python]

        >>> from sage.all import *
        >>> D4 = DihedralGroup(Integer(4))
        >>> C3 = CyclicPermutationGroup(Integer(3))
        >>> alpha1 = PermutationGroupMorphism_im_gens(C3,C3,[(Integer(1),Integer(3),Integer(2))])
        >>> alpha2 = PermutationGroupMorphism_im_gens(C3,C3,[(Integer(1),Integer(2),Integer(3))])
        >>> S1 = D4.semidirect_product(C3,[[(Integer(1),Integer(2),Integer(3),Integer(4)),(Integer(1),Integer(3))],[alpha1,alpha2]])
        >>> C2 = CyclicPermutationGroup(Integer(2))
        >>> Q = DiCyclicGroup(Integer(3))
        >>> a = Q.gens()[Integer(0)]; b=Q.gens()[Integer(1)].inverse()
        >>> alpha = PermutationGroupMorphism_im_gens(Q,Q,[a,b])
        >>> S2 = C2.semidirect_product(Q,[[(Integer(1),Integer(2))],[alpha]])
        >>> S1.is_isomorphic(S2)
        True
        >>> S1.is_isomorphic(DihedralGroup(Integer(12)))
        False
        >>> S1.is_isomorphic(DiCyclicGroup(Integer(6)))
        False
        >>> S1.center()
        Subgroup generated by [(1,3)(2,4)] of
         (Permutation Group with generators [(5,6,7), (1,2,3,4)(6,7), (1,3)])
        >>> len(S1.conjugacy_classes_representatives())
        9

    If your normal subgroup is large, and you are confident that your inputs will successfully create a semidirect product, then it is beneficial, for the sake of time efficiency, to set the `check` parameter to `False`.

    Sage

        sage: C2 = CyclicPermutationGroup(2)
        sage: C2000 = CyclicPermutationGroup(500)
        sage: alpha = PermutationGroupMorphism(C2000,C2000,[C2000.gen().inverse()])
        sage: S = C2.semidirect_product(C2000,[[(1,2)],[alpha]],check=False)

    Python

        >>> from sage.all import *
        >>> C2 = CyclicPermutationGroup(Integer(2))
        >>> C2000 = CyclicPermutationGroup(Integer(500))
        >>> alpha = PermutationGroupMorphism(C2000,C2000,[C2000.gen().inverse()])
        >>> S = C2.semidirect_product(C2000,[[(Integer(1),Integer(2))],[alpha]],check=False)

    AUTHOR:

    - Kevin Halasz (2012-8-12)

  sign_representation(base_ring=None)

    Return the sign representation of `self` over `base_ring`.

    INPUT:

    - `base_ring` – (optional) the base ring; the default is \(\ZZ\)

    EXAMPLES:

    Sage

        sage: G = groups.permutation.Dihedral(4)
        sage: G.sign_representation()
        Sign representation of Dihedral group of order 8
         as a permutation group over Integer Ring

    Python

        >>> from sage.all import *
        >>> G = groups.permutation.Dihedral(Integer(4))
        >>> G.sign_representation()
        Sign representation of Dihedral group of order 8
         as a permutation group over Integer Ring

  smallest_moved_point()

    Return the smallest point moved by a permutation in this group.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(3,4)], [(2,3,4)]])
        sage: G.smallest_moved_point()
        2
        sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4,10)]])
        sage: G.smallest_moved_point()
        1

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(3),Integer(4))], [(Integer(2),Integer(3),Integer(4))]])
        >>> G.smallest_moved_point()
        2
        >>> G = PermutationGroup([[(Integer(1),Integer(2)),(Integer(3),Integer(4))], [(Integer(1),Integer(2),Integer(3),Integer(4),Integer(10))]])
        >>> G.smallest_moved_point()
        1

    Note that this function uses the ordering from the domain:

    Sage

        sage: S = SymmetricGroup(['a','b','c'])
        sage: S.smallest_moved_point()
        'a'

    [Python]

        >>> from sage.all import *
        >>> S = SymmetricGroup(['a','b','c'])
        >>> S.smallest_moved_point()
        'a'

  socle()

    Return the socle of `self`.

    The socle of a group \(G\) is the subgroup generated by all minimal normal subgroups.

    EXAMPLES:

    Sage

        sage: G = SymmetricGroup(4)
        sage: s = G.socle(); s
        Subgroup generated by [(1,2)(3,4), (1,4)(2,3)] of
         (Symmetric group of order 4! as a permutation group)

    Python

        >>> from sage.all import *
        >>> G = SymmetricGroup(Integer(4))
        >>> s = G.socle(); s
        Subgroup generated by [(1,2)(3,4), (1,4)(2,3)] of
         (Symmetric group of order 4! as a permutation group)

    The socle of the socle is, essentially, the socle:

    Sage

        sage: s.socle() == s.subgroup(s.gens())
        True

    [Python]

        >>> from sage.all import *
        >>> s.socle() == s.subgroup(s.gens())
        True

  solvable_radical()

    Return the solvable radical of `self`.

    The solvable radical (or just radical) of a group \(G\) is the largest solvable normal subgroup of \(G\).

    EXAMPLES:

    Sage

        sage: G = SymmetricGroup(4)
        sage: G.solvable_radical()
        Subgroup generated by [(1,2,3,4), (1,2)] of
         (Symmetric group of order 4! as a permutation group)
        sage: G = SymmetricGroup(5)
        sage: G.solvable_radical()
        Subgroup generated by [()] of
         (Symmetric group of order 5! as a permutation group)

    Python

        >>> from sage.all import *
        >>> G = SymmetricGroup(Integer(4))
        >>> G.solvable_radical()
        Subgroup generated by [(1,2,3,4), (1,2)] of
         (Symmetric group of order 4! as a permutation group)
        >>> G = SymmetricGroup(Integer(5))
        >>> G.solvable_radical()
        Subgroup generated by [()] of
         (Symmetric group of order 5! as a permutation group)

  stabilizer(point, action='OnPoints')

    Return the subgroup of `self` which stabilize the given position. `self` and its stabilizers must have same degree.

    INPUT:

    - `point` – a point of the `domain()`, or a set of points depending on the value of `action`

    - `action` – string (default: `'OnPoints'`); should the group be considered to act on points (`action="OnPoints"`) or on sets of points (`action="OnSets"`)? In the latter case, the first argument must be a subset of `domain()`.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([ [(3,4)], [(1,3)] ])
        sage: G.stabilizer(1)
        Subgroup generated by [(3,4)] of (Permutation Group with generators [(3,4), (1,3)])
        sage: G.stabilizer(3)
        Subgroup generated by [(1,4)] of (Permutation Group with generators [(3,4), (1,3)])

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([ [(Integer(3),Integer(4))], [(Integer(1),Integer(3))] ])
        >>> G.stabilizer(Integer(1))
        Subgroup generated by [(3,4)] of (Permutation Group with generators [(3,4), (1,3)])
        >>> G.stabilizer(Integer(3))
        Subgroup generated by [(1,4)] of (Permutation Group with generators [(3,4), (1,3)])

    The stabilizer of a set of points:

    Sage

        sage: s10 = groups.permutation.Symmetric(10)
        sage: s10.stabilizer([1..3],"OnSets").cardinality()
        30240
        sage: factorial(3)*factorial(7)
        30240

    [Python]

        >>> from sage.all import *
        >>> s10 = groups.permutation.Symmetric(Integer(10))
        >>> s10.stabilizer((ellipsis_range(Integer(1),Ellipsis,Integer(3))),"OnSets").cardinality()
        30240
        >>> factorial(Integer(3))*factorial(Integer(7))
        30240

    Sage

        sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4,10)]])
        sage: G.stabilizer(10)
        Subgroup generated by [(1,2)(3,4), (2,3,4)] of (Permutation Group with generators [(1,2)(3,4), (1,2,3,4,10)])
        sage: G.stabilizer(1) == G.subgroup(['(2,3)(4,10)', '(2,10,3)'])
        True
        sage: G = PermutationGroup([[(2,3,4)],[(6,7)]])
        sage: G.stabilizer(1)
        Subgroup generated by [(6,7), (2,3,4)] of (Permutation Group with generators [(6,7), (2,3,4)])
        sage: G.stabilizer(2)
        Subgroup generated by [(6,7)] of (Permutation Group with generators [(6,7), (2,3,4)])
        sage: G.stabilizer(3)
        Subgroup generated by [(6,7)] of (Permutation Group with generators [(6,7), (2,3,4)])
        sage: G.stabilizer(4)
        Subgroup generated by [(6,7)] of (Permutation Group with generators [(6,7), (2,3,4)])
        sage: G.stabilizer(5)
        Subgroup generated by [(6,7), (2,3,4)] of (Permutation Group with generators [(6,7), (2,3,4)])
        sage: G.stabilizer(6)
        Subgroup generated by [(2,3,4)] of (Permutation Group with generators [(6,7), (2,3,4)])
        sage: G.stabilizer(7)
        Subgroup generated by [(2,3,4)] of (Permutation Group with generators [(6,7), (2,3,4)])
        sage: G.stabilizer(8)
        Traceback (most recent call last):
        ...
        ValueError: 8 does not belong to the domain

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2)),(Integer(3),Integer(4))], [(Integer(1),Integer(2),Integer(3),Integer(4),Integer(10))]])
        >>> G.stabilizer(Integer(10))
        Subgroup generated by [(1,2)(3,4), (2,3,4)] of (Permutation Group with generators [(1,2)(3,4), (1,2,3,4,10)])
        >>> G.stabilizer(Integer(1)) == G.subgroup(['(2,3)(4,10)', '(2,10,3)'])
        True
        >>> G = PermutationGroup([[(Integer(2),Integer(3),Integer(4))],[(Integer(6),Integer(7))]])
        >>> G.stabilizer(Integer(1))
        Subgroup generated by [(6,7), (2,3,4)] of (Permutation Group with generators [(6,7), (2,3,4)])
        >>> G.stabilizer(Integer(2))
        Subgroup generated by [(6,7)] of (Permutation Group with generators [(6,7), (2,3,4)])
        >>> G.stabilizer(Integer(3))
        Subgroup generated by [(6,7)] of (Permutation Group with generators [(6,7), (2,3,4)])
        >>> G.stabilizer(Integer(4))
        Subgroup generated by [(6,7)] of (Permutation Group with generators [(6,7), (2,3,4)])
        >>> G.stabilizer(Integer(5))
        Subgroup generated by [(6,7), (2,3,4)] of (Permutation Group with generators [(6,7), (2,3,4)])
        >>> G.stabilizer(Integer(6))
        Subgroup generated by [(2,3,4)] of (Permutation Group with generators [(6,7), (2,3,4)])
        >>> G.stabilizer(Integer(7))
        Subgroup generated by [(2,3,4)] of (Permutation Group with generators [(6,7), (2,3,4)])
        >>> G.stabilizer(Integer(8))
        Traceback (most recent call last):
        ...
        ValueError: 8 does not belong to the domain

    Sage

        sage: G = PermutationGroup([ [('c','d')], [('a','c')] ], domain='abcd')
        sage: G.stabilizer('a')
        Subgroup generated by [('c','d')] of (Permutation Group with generators [('c','d'), ('a','c')])
        sage: G.stabilizer('b')
        Subgroup generated by [('c','d'), ('a','c')] of (Permutation Group with generators [('c','d'), ('a','c')])
        sage: G.stabilizer('c')
        Subgroup generated by [('a','d')] of (Permutation Group with generators [('c','d'), ('a','c')])
        sage: G.stabilizer('d')
        Subgroup generated by [('a','c')] of (Permutation Group with generators [('c','d'), ('a','c')])

    [Python]

        >>> from sage.all import *
        >>> G = PermutationGroup([ [('c','d')], [('a','c')] ], domain='abcd')
        >>> G.stabilizer('a')
        Subgroup generated by [('c','d')] of (Permutation Group with generators [('c','d'), ('a','c')])
        >>> G.stabilizer('b')
        Subgroup generated by [('c','d'), ('a','c')] of (Permutation Group with generators [('c','d'), ('a','c')])
        >>> G.stabilizer('c')
        Subgroup generated by [('a','d')] of (Permutation Group with generators [('c','d'), ('a','c')])
        >>> G.stabilizer('d')
        Subgroup generated by [('a','c')] of (Permutation Group with generators [('c','d'), ('a','c')])

  strong_generating_system(base_of_group=None, implementation='sage')

    Return a Strong Generating System of `self` according the given base for the right action of `self` on itself.

    `base_of_group` is a list of the positions on which `self` acts, in any order. The algorithm returns a list of transversals and each transversal is a list of permutations. By default, `base_of_group` is `[1, 2, 3, ..., d]` where \(d\) is the degree of the group.

    For `base_of_group` = \([ \mathrm{pos}_1, \mathrm{pos}_2, \dots , \mathrm{pos}_d]\) let \(G_i\) be the subgroup of \(G\) = `self` which stabilizes \(\mathrm{pos}_1, \mathrm{pos}_2, \dots , \mathrm{pos}_i\), so

    \[G = G_0 \supset G_1 \supset G_2 \supset \dots \supset G_n = \{e\}\]

    Then the algorithm returns \([ G_i.\mathrm{transversals}(\mathrm{pos}_{i+1})]_{1 \leq i \leq n}\)

    INPUT:

    - `base_of_group` – (default: `[1, 2, 3, ..., d]`) a list containing the integers \(1, 2, \ldots , d\) in any order, where \(d\) is the degree of `self`

    - `implementation` – (default: `'sage'`) either

      - `'sage'` – use the direct implementation in Sage

      - `'gap'` – if used, the `base_of_group` must be `None` and the computation is directly performed in GAP

    OUTPUT: list of lists of permutations from the group, which forms a strong generating system

    Warning

    The outputs for implementations `'sage'` and `'gap'` differ: First, the output is reversed, and second, it might be that `'sage'` does not contain the trivial subgroup while `'gap'` does.

    Also, both algorithms might yield different results based on the order in which `base_of_group` is given in the first situation.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([[(7,8)],[(3,4)],[(4,5)]])
        sage: G.strong_generating_system()
        [[()], [()], [(), (3,4), (3,5,4)], [(), (4,5)], [()], [()], [(), (7,8)], [()]]
        sage: G = PermutationGroup([[(1,2,3,4)],[(1,2)]])
        sage: G.strong_generating_system()
        [[(), (1,2)(3,4), (1,3)(2,4), (1,4)(2,3)],
        [(), (2,4,3), (2,3,4)],
        [(), (3,4)],
        [()]]
        sage: G = PermutationGroup([[(1,2,3)],[(4,5,7)],[(1,4,6)]])
        sage: G.strong_generating_system()
        [[(), (1,2,3), (1,4,6), (1,3,2), (1,5,7,4,6), (1,6,4), (1,7,5,4,6)],
         [(), (2,3,6), (2,6,3), (2,7,5,6,3), (2,5,6,3)(4,7), (2,4,5,6,3)],
         [(), (3,5,6), (3,4,7,5,6), (3,6)(5,7), (3,7,4,5,6)],
         [(), (4,7,5), (4,5,7), (4,6,7)],
         [(), (5,6,7), (5,7,6)], [()], [()]]
        sage: G = PermutationGroup([[(1,2,3)],[(2,3,4)],[(3,4,5)]])
        sage: G.strong_generating_system([5,4,3,2,1])
        [[(), (1,5,3,4,2), (1,5,4,3,2), (1,5)(2,3), (1,5,2)],
         [(1,4)(2,3), (1,4,3), (1,4,2), ()],
         [(1,2,3), (1,3,2), ()], [()], [()]]
        sage: G = PermutationGroup([[(3,4)]])
        sage: G.strong_generating_system()
        [[()], [()], [(), (3,4)], [()]]
        sage: G.strong_generating_system(base_of_group=[3,1,2,4])
        [[(), (3,4)], [()], [()], [()]]
        sage: G = TransitiveGroup(12,17)
        sage: G.strong_generating_system()
        [[(), (1,4,11,2)(3,6,5,8)(7,10,9,12), (1,8,3,2)(4,11,10,9)(5,12,7,6),
          (1,7)(2,8)(3,9)(4,10)(5,11)(6,12), (1,12,7,2)(3,10,9,8)(4,11,6,5),
          (1,11)(2,8)(3,5)(4,10)(6,12)(7,9), (1,10,11,8)(2,3,12,5)(4,9,6,7),
          (1,3)(2,8)(4,10)(5,7)(6,12)(9,11), (1,2,3,8)(4,9,10,11)(5,6,7,12),
          (1,6,7,8)(2,3,4,9)(5,10,11,12), (1,5,9)(3,11,7), (1,9,5)(3,7,11)],
         [(), (2,6,10)(4,12,8), (2,10,6)(4,8,12)],
         [()], [()], [()], [()], [()], [()], [()], [()], [()], [()]]

        sage: A = PermutationGroup([(1,2),(1,2,3,4,5,6,7,8,9)])
        sage: X = A.strong_generating_system()
        sage: Y = A.strong_generating_system(implementation='gap')
        sage: [len(x) for x in X]
        [9, 8, 7, 6, 5, 4, 3, 2, 1]
        sage: [len(y) for y in Y]
        [1, 2, 3, 4, 5, 6, 7, 8, 9]

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(7),Integer(8))],[(Integer(3),Integer(4))],[(Integer(4),Integer(5))]])
        >>> G.strong_generating_system()
        [[()], [()], [(), (3,4), (3,5,4)], [(), (4,5)], [()], [()], [(), (7,8)], [()]]
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3),Integer(4))],[(Integer(1),Integer(2))]])
        >>> G.strong_generating_system()
        [[(), (1,2)(3,4), (1,3)(2,4), (1,4)(2,3)],
        [(), (2,4,3), (2,3,4)],
        [(), (3,4)],
        [()]]
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3))],[(Integer(4),Integer(5),Integer(7))],[(Integer(1),Integer(4),Integer(6))]])
        >>> G.strong_generating_system()
        [[(), (1,2,3), (1,4,6), (1,3,2), (1,5,7,4,6), (1,6,4), (1,7,5,4,6)],
         [(), (2,3,6), (2,6,3), (2,7,5,6,3), (2,5,6,3)(4,7), (2,4,5,6,3)],
         [(), (3,5,6), (3,4,7,5,6), (3,6)(5,7), (3,7,4,5,6)],
         [(), (4,7,5), (4,5,7), (4,6,7)],
         [(), (5,6,7), (5,7,6)], [()], [()]]
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3))],[(Integer(2),Integer(3),Integer(4))],[(Integer(3),Integer(4),Integer(5))]])
        >>> G.strong_generating_system([Integer(5),Integer(4),Integer(3),Integer(2),Integer(1)])
        [[(), (1,5,3,4,2), (1,5,4,3,2), (1,5)(2,3), (1,5,2)],
         [(1,4)(2,3), (1,4,3), (1,4,2), ()],
         [(1,2,3), (1,3,2), ()], [()], [()]]
        >>> G = PermutationGroup([[(Integer(3),Integer(4))]])
        >>> G.strong_generating_system()
        [[()], [()], [(), (3,4)], [()]]
        >>> G.strong_generating_system(base_of_group=[Integer(3),Integer(1),Integer(2),Integer(4)])
        [[(), (3,4)], [()], [()], [()]]
        >>> G = TransitiveGroup(Integer(12),Integer(17))
        >>> G.strong_generating_system()
        [[(), (1,4,11,2)(3,6,5,8)(7,10,9,12), (1,8,3,2)(4,11,10,9)(5,12,7,6),
          (1,7)(2,8)(3,9)(4,10)(5,11)(6,12), (1,12,7,2)(3,10,9,8)(4,11,6,5),
          (1,11)(2,8)(3,5)(4,10)(6,12)(7,9), (1,10,11,8)(2,3,12,5)(4,9,6,7),
          (1,3)(2,8)(4,10)(5,7)(6,12)(9,11), (1,2,3,8)(4,9,10,11)(5,6,7,12),
          (1,6,7,8)(2,3,4,9)(5,10,11,12), (1,5,9)(3,11,7), (1,9,5)(3,7,11)],
         [(), (2,6,10)(4,12,8), (2,10,6)(4,8,12)],
         [()], [()], [()], [()], [()], [()], [()], [()], [()], [()]]

        >>> A = PermutationGroup([(Integer(1),Integer(2)),(Integer(1),Integer(2),Integer(3),Integer(4),Integer(5),Integer(6),Integer(7),Integer(8),Integer(9))])
        >>> X = A.strong_generating_system()
        >>> Y = A.strong_generating_system(implementation='gap')
        >>> [len(x) for x in X]
        [9, 8, 7, 6, 5, 4, 3, 2, 1]
        >>> [len(y) for y in Y]
        [1, 2, 3, 4, 5, 6, 7, 8, 9]

  structure_description(G, latex=False)

    Return a string that tries to describe the structure of `G`.

    This methods wraps GAP’s `StructureDescription` method.

    For full details, including the form of the returned string and the algorithm to build it, see GAP’s documentation.

    INPUT:

    - `latex` – boolean (default: `False`); if `True`, return a LaTeX formatted string

    OUTPUT: string

    Warning

    From GAP’s documentation: The string returned by `StructureDescription` is not an isomorphism invariant: non-isomorphic groups can have the same string value, and two isomorphic groups in different representations can produce different strings.

    EXAMPLES:

    Sage

        sage: # needs sage.groups
        sage: G = CyclicPermutationGroup(6)
        sage: G.structure_description()
        'C6'
        sage: G.structure_description(latex=True)
        'C_{6}'
        sage: G2 = G.direct_product(G, maps=False)
        sage: LatexExpr(G2.structure_description(latex=True))
        C_{6} \times C_{6}

    Python

        >>> from sage.all import *
        >>> # needs sage.groups
        >>> G = CyclicPermutationGroup(Integer(6))
        >>> G.structure_description()
        'C6'
        >>> G.structure_description(latex=True)
        'C_{6}'
        >>> G2 = G.direct_product(G, maps=False)
        >>> LatexExpr(G2.structure_description(latex=True))
        C_{6} \times C_{6}

    This method is mainly intended for small groups or groups with few normal subgroups. Even then there are some surprises:

    Sage

        sage: D3 = DihedralGroup(3)                                                     # needs sage.groups
        sage: D3.structure_description()                                                # needs sage.groups
        'S3'

    [Python]

        >>> from sage.all import *
        >>> D3 = DihedralGroup(Integer(3))                                                     # needs sage.groups
        >>> D3.structure_description()                                                # needs sage.groups
        'S3'

    We use the Sage notation for the degree of dihedral groups:

    Sage

        sage: D4 = DihedralGroup(4)                                                     # needs sage.groups
        sage: D4.structure_description()                                                # needs sage.groups
        'D4'

    Python

        >>> from sage.all import *
        >>> D4 = DihedralGroup(Integer(4))                                                     # needs sage.groups
        >>> D4.structure_description()                                                # needs sage.groups
        'D4'

    Works for finitely presented groups (Issue #17573):

    Sage

        sage: F.<x, y> = FreeGroup()                                                    # needs sage.groups
        sage: G = F / [x^2*y^-1, x^3*y^2, x*y*x^-1*y^-1]                                # needs sage.groups
        sage: G.structure_description()                                                 # needs sage.groups
        'C7'

    [Python]

        >>> from sage.all import *
        >>> F = FreeGroup(names=('x', 'y',)); (x, y,) = F._first_ngens(2)# needs sage.groups
        >>> G = F / [x**Integer(2)*y**-Integer(1), x**Integer(3)*y**Integer(2), x*y*x**-Integer(1)*y**-Integer(1)]                                # needs sage.groups
        >>> G.structure_description()                                                 # needs sage.groups
        'C7'

    And matrix groups (Issue #17573):

    Sage

        sage: groups.matrix.GL(4,2).structure_description()                             # needs sage.libs.gap sage.modules
        'A8'

    Python

        >>> from sage.all import *
        >>> groups.matrix.GL(Integer(4),Integer(2)).structure_description()                             # needs sage.libs.gap sage.modules
        'A8'

  subgroup(gens=None, gap_group=None, domain=None, category=None, canonicalize=True, check=True)

    Wraps the `PermutationGroup_subgroup` constructor. The argument `gens` is a list of elements of `self`.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([(1,2,3),(3,4,5)])
        sage: g = G((1,2,3))
        sage: G.subgroup([g])
        Subgroup generated by [(1,2,3)] of
         (Permutation Group with generators [(3,4,5), (1,2,3)])

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([(Integer(1),Integer(2),Integer(3)),(Integer(3),Integer(4),Integer(5))])
        >>> g = G((Integer(1),Integer(2),Integer(3)))
        >>> G.subgroup([g])
        Subgroup generated by [(1,2,3)] of
         (Permutation Group with generators [(3,4,5), (1,2,3)])

  subgroups()

    Return a list of all the subgroups of `self`.

    OUTPUT:

    Each possible subgroup of `self` is contained once in the returned list. The list is in order, according to the size of the subgroups, from the trivial subgroup with one element on through up to the whole group. Conjugacy classes of subgroups are contiguous in the list.

    Warning

    For even relatively small groups this method can take a very long time to execute, or create vast amounts of output. Likely both. Its purpose is instructional, as it can be useful for studying small groups. The 156 subgroups of the full symmetric group on 5 symbols of order 120, \(S_5\), can be computed in about a minute on commodity hardware in 2011. The 64 subgroups of the cyclic group of order \(30030 = 2\cdot 3\cdot 5\cdot 7\cdot 11\cdot 13\) takes about twice as long.

    For faster results, which still exhibit the structure of the possible subgroups, use `conjugacy_classes_subgroups()`.

    EXAMPLES:

    Sage

        sage: G = SymmetricGroup(3)
        sage: G.subgroups()
        [Subgroup generated by [()] of
          (Symmetric group of order 3! as a permutation group),
         Subgroup generated by [(2,3)] of
          (Symmetric group of order 3! as a permutation group),
         Subgroup generated by [(1,2)] of
          (Symmetric group of order 3! as a permutation group),
         Subgroup generated by [(1,3)] of
          (Symmetric group of order 3! as a permutation group),
         Subgroup generated by [(1,2,3)] of
          (Symmetric group of order 3! as a permutation group),
         Subgroup generated by [(1,2,3), (2,3)] of
          (Symmetric group of order 3! as a permutation group)]

        sage: G = CyclicPermutationGroup(14)
        sage: G.subgroups()
        [Subgroup generated by [()] of
          (Cyclic group of order 14 as a permutation group),
         Subgroup generated by [(1,8)(2,9)(3,10)(4,11)(5,12)(6,13)(7,14)] of
          (Cyclic group of order 14 as a permutation group),
         Subgroup generated by [(1,3,5,7,9,11,13)(2,4,6,8,10,12,14)] of
          (Cyclic group of order 14 as a permutation group),
         Subgroup generated by [(1,3,5,7,9,11,13)(2,4,6,8,10,12,14),
                                (1,2,3,4,5,6,7,8,9,10,11,12,13,14)] of
          (Cyclic group of order 14 as a permutation group)]

    Python

        >>> from sage.all import *
        >>> G = SymmetricGroup(Integer(3))
        >>> G.subgroups()
        [Subgroup generated by [()] of
          (Symmetric group of order 3! as a permutation group),
         Subgroup generated by [(2,3)] of
          (Symmetric group of order 3! as a permutation group),
         Subgroup generated by [(1,2)] of
          (Symmetric group of order 3! as a permutation group),
         Subgroup generated by [(1,3)] of
          (Symmetric group of order 3! as a permutation group),
         Subgroup generated by [(1,2,3)] of
          (Symmetric group of order 3! as a permutation group),
         Subgroup generated by [(1,2,3), (2,3)] of
          (Symmetric group of order 3! as a permutation group)]

        >>> G = CyclicPermutationGroup(Integer(14))
        >>> G.subgroups()
        [Subgroup generated by [()] of
          (Cyclic group of order 14 as a permutation group),
         Subgroup generated by [(1,8)(2,9)(3,10)(4,11)(5,12)(6,13)(7,14)] of
          (Cyclic group of order 14 as a permutation group),
         Subgroup generated by [(1,3,5,7,9,11,13)(2,4,6,8,10,12,14)] of
          (Cyclic group of order 14 as a permutation group),
         Subgroup generated by [(1,3,5,7,9,11,13)(2,4,6,8,10,12,14),
                                (1,2,3,4,5,6,7,8,9,10,11,12,13,14)] of
          (Cyclic group of order 14 as a permutation group)]

    AUTHOR:

    - Rob Beezer (2011-01-24)

  sylow_subgroup(p)

    Return a Sylow \(p\)-subgroup of the finite group \(G\), where \(p\) is a prime.

    This is a \(p\)-subgroup of \(G\) whose index in \(G\) is coprime to \(p\).

    Wraps the GAP function `SylowSubgroup`.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup(['(1,2,3)', '(2,3)'])
        sage: G.sylow_subgroup(2)
        Subgroup generated by [(2,3)] of
         (Permutation Group with generators [(2,3), (1,2,3)])
        sage: G.sylow_subgroup(5)
        Subgroup generated by [()] of
         (Permutation Group with generators [(2,3), (1,2,3)])

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup(['(1,2,3)', '(2,3)'])
        >>> G.sylow_subgroup(Integer(2))
        Subgroup generated by [(2,3)] of
         (Permutation Group with generators [(2,3), (1,2,3)])
        >>> G.sylow_subgroup(Integer(5))
        Subgroup generated by [()] of
         (Permutation Group with generators [(2,3), (1,2,3)])

  transversals(point)

    If G is a permutation group acting on the set \(X = \{1, 2, ...., n\}\) and H is the stabilizer subgroup of <integer>, a right (respectively left) transversal is a set containing exactly one element from each right (respectively left) coset of H. This method returns a right transversal of `self` by the stabilizer of `self` on <integer> position.

    EXAMPLES:

    Sage

        sage: G = PermutationGroup([ [(3,4)], [(1,3)] ])
        sage: G.transversals(1)
        [(), (1,3,4), (1,4,3)]
        sage: G = PermutationGroup([[(1,2),(3,4)], [(1,2,3,4,10)]])
        sage: G.transversals(1)
        [(), (1,2)(3,4), (1,3,2,10,4), (1,4,2,10,3), (1,10,4,3,2)]

        sage: G = PermutationGroup([ [('c','d')], [('a','c')] ])
        sage: G.transversals('a')
        [(), ('a','c','d'), ('a','d','c')]

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([ [(Integer(3),Integer(4))], [(Integer(1),Integer(3))] ])
        >>> G.transversals(Integer(1))
        [(), (1,3,4), (1,4,3)]
        >>> G = PermutationGroup([[(Integer(1),Integer(2)),(Integer(3),Integer(4))], [(Integer(1),Integer(2),Integer(3),Integer(4),Integer(10))]])
        >>> G.transversals(Integer(1))
        [(), (1,2)(3,4), (1,3,2,10,4), (1,4,2,10,3), (1,10,4,3,2)]

        >>> G = PermutationGroup([ [('c','d')], [('a','c')] ])
        >>> G.transversals('a')
        [(), ('a','c','d'), ('a','d','c')]

  trivial_character()

    Return the trivial character of `self`.

    EXAMPLES:

    Sage

        sage: SymmetricGroup(3).trivial_character()                                 # needs sage.rings.number_field
        Character of Symmetric group of order 3! as a permutation group

    Python

        >>> from sage.all import *
        >>> SymmetricGroup(Integer(3)).trivial_character()                                 # needs sage.rings.number_field
        Character of Symmetric group of order 3! as a permutation group

  upper_central_series()

    Return the upper central series of this group as a list of permutation groups.

    EXAMPLES:

    These computations use pseudo-random numbers, so we set the seed for reproducible testing:

    Sage

        sage: G = PermutationGroup([[(1,2,3),(4,5)],[(3,4)]])
        sage: G.upper_central_series()
        [Subgroup generated by [()] of
         (Permutation Group with generators [(3,4), (1,2,3)(4,5)])]

    Python

        >>> from sage.all import *
        >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3)),(Integer(4),Integer(5))],[(Integer(3),Integer(4))]])
        >>> G.upper_central_series()
        [Subgroup generated by [()] of
         (Permutation Group with generators [(3,4), (1,2,3)(4,5)])]

class sage.groups.perm_gps.permgroup.PermutationGroup_subgroup(ambient, gens=None, gap_group=None, domain=None, category=None, canonicalize=True, check=True)

  Bases: `PermutationGroup_generic`

  Subgroup subclass of `PermutationGroup_generic`, so instance methods are inherited.

  EXAMPLES:

  Sage

      sage: G = CyclicPermutationGroup(4)
      sage: gens = G.gens()
      sage: H = DihedralGroup(4)
      sage: H.subgroup(gens)
      Subgroup generated by [(1,2,3,4)] of
       (Dihedral group of order 8 as a permutation group)
      sage: K = H.subgroup(gens)
      sage: K.list()
      [(), (1,2,3,4), (1,3)(2,4), (1,4,3,2)]
      sage: K.ambient_group()
      Dihedral group of order 8 as a permutation group
      sage: K.gens()
      ((1,2,3,4),)

  Python

      >>> from sage.all import *
      >>> G = CyclicPermutationGroup(Integer(4))
      >>> gens = G.gens()
      >>> H = DihedralGroup(Integer(4))
      >>> H.subgroup(gens)
      Subgroup generated by [(1,2,3,4)] of
       (Dihedral group of order 8 as a permutation group)
      >>> K = H.subgroup(gens)
      >>> K.list()
      [(), (1,2,3,4), (1,3)(2,4), (1,4,3,2)]
      >>> K.ambient_group()
      Dihedral group of order 8 as a permutation group
      >>> K.gens()
      ((1,2,3,4),)

  ambient_group()

    Return the ambient group related to `self`.

    EXAMPLES:

    An example involving the dihedral group on four elements, \(D_8\):

    Sage

        sage: G = DihedralGroup(4)
        sage: H = CyclicPermutationGroup(4)
        sage: gens = H.gens()
        sage: S = PermutationGroup_subgroup(G, list(gens))
        sage: S.ambient_group()
        Dihedral group of order 8 as a permutation group
        sage: S.ambient_group() == G
        True

    Python

        >>> from sage.all import *
        >>> G = DihedralGroup(Integer(4))
        >>> H = CyclicPermutationGroup(Integer(4))
        >>> gens = H.gens()
        >>> S = PermutationGroup_subgroup(G, list(gens))
        >>> S.ambient_group()
        Dihedral group of order 8 as a permutation group
        >>> S.ambient_group() == G
        True

  is_normal(other=None)

    Return `True` if this group is a normal subgroup of `other`.

    If `other` is not specified, then it is assumed to be the ambient group.

    EXAMPLES:

    Sage

        sage: S = SymmetricGroup(['a','b','c'])
        sage: H = S.subgroup([('a', 'b', 'c')]); H
        Subgroup generated by [('a','b','c')] of
         (Symmetric group of order 3! as a permutation group)
        sage: H.is_normal()
        True

    Python

        >>> from sage.all import *
        >>> S = SymmetricGroup(['a','b','c'])
        >>> H = S.subgroup([('a', 'b', 'c')]); H
        Subgroup generated by [('a','b','c')] of
         (Symmetric group of order 3! as a permutation group)
        >>> H.is_normal()
        True

sage.groups.perm_gps.permgroup.direct_product_permgroups(P)

  Take the direct product of the permutation groups listed in `P`.

  EXAMPLES:

  Sage

      sage: G1 = AlternatingGroup([1,2,4,5])
      sage: G2 = AlternatingGroup([3,4,6,7])
      sage: D = direct_product_permgroups([G1,G2,G1])
      sage: D.order()
      1728
      sage: D = direct_product_permgroups([G1])
      sage: D == G1
      True
      sage: direct_product_permgroups([])
      Symmetric group of order 0! as a permutation group

  Python

      >>> from sage.all import *
      >>> G1 = AlternatingGroup([Integer(1),Integer(2),Integer(4),Integer(5)])
      >>> G2 = AlternatingGroup([Integer(3),Integer(4),Integer(6),Integer(7)])
      >>> D = direct_product_permgroups([G1,G2,G1])
      >>> D.order()
      1728
      >>> D = direct_product_permgroups([G1])
      >>> D == G1
      True
      >>> direct_product_permgroups([])
      Symmetric group of order 0! as a permutation group

sage.groups.perm_gps.permgroup.from_gap_list(G, src)

  Convert a string giving a list of GAP permutations into a list of elements of `G`.

  EXAMPLES:

  Sage

      sage: from sage.groups.perm_gps.permgroup import from_gap_list
      sage: G = PermutationGroup([[(1,2,3),(4,5)],[(3,4)]])
      sage: L = from_gap_list(G, "[(1,2,3)(4,5), (3,4)]"); L
      [(1,2,3)(4,5), (3,4)]
      sage: L[0].parent() is G
      True
      sage: L[1].parent() is G
      True

  Python

      >>> from sage.all import *
      >>> from sage.groups.perm_gps.permgroup import from_gap_list
      >>> G = PermutationGroup([[(Integer(1),Integer(2),Integer(3)),(Integer(4),Integer(5))],[(Integer(3),Integer(4))]])
      >>> L = from_gap_list(G, "[(1,2,3)(4,5), (3,4)]"); L
      [(1,2,3)(4,5), (3,4)]
      >>> L[Integer(0)].parent() is G
      True
      >>> L[Integer(1)].parent() is G
      True

sage.groups.perm_gps.permgroup.hap_decorator(f)

  A decorator for permutation group methods that require HAP. It checks to see that HAP is installed as well as checks that the argument `p` is either 0 or prime.

  EXAMPLES:

  Sage

      sage: # optional - gap_package_hap
      sage: from sage.groups.perm_gps.permgroup import hap_decorator
      sage: def foo(self, n, p=0): print("Done")
      sage: foo = hap_decorator(foo)
      sage: foo(None, 3)
      Done
      sage: foo(None, 3, 0)
      Done
      sage: foo(None, 3, 5)
      Done
      sage: foo(None, 3, 4)
      Traceback (most recent call last):
      ...
      ValueError: p must be 0 or prime

  Python

      >>> from sage.all import *
      >>> # optional - gap_package_hap
      >>> from sage.groups.perm_gps.permgroup import hap_decorator
      >>> def foo(self, n, p=Integer(0)): print("Done")
      >>> foo = hap_decorator(foo)
      >>> foo(None, Integer(3))
      Done
      >>> foo(None, Integer(3), Integer(0))
      Done
      >>> foo(None, Integer(3), Integer(5))
      Done
      >>> foo(None, Integer(3), Integer(4))
      Traceback (most recent call last):
      ...
      ValueError: p must be 0 or prime

sage.groups.perm_gps.permgroup.load_hap()

  Load the GAP hap package into the default GAP interpreter interface.

  EXAMPLES:

  Sage

      sage: sage.groups.perm_gps.permgroup.load_hap()         # optional - gap_package_hap

  Python

      >>> from sage.all import *
      >>> sage.groups.perm_gps.permgroup.load_hap()         # optional - gap_package_hap