Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
gh-36252: no generator for S1
    
Trying to explain that the symmetric group S(1) has no generator

fixes #36204

### 📝 Checklist

- [x] The title is concise, informative, and self-explanatory.
- [x] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [x] I have created tests covering the changes.
    
URL: #36252
Reported by: Frédéric Chapoton
Reviewer(s): github-actions[bot], Travis Scrimshaw
  • Loading branch information
Release Manager committed Sep 22, 2023
2 parents 5b90f22 + 26ad664 commit 5bd0466
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 25 deletions.
31 changes: 21 additions & 10 deletions src/sage/groups/finitely_presented_named.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,10 @@ def CyclicPresentation(n):
n = Integer(n)
if n < 1:
raise ValueError('finitely presented group order must be positive')
F = FreeGroup( 'a' )
F = FreeGroup('a')
rls = F([1])**n,
return FinitelyPresentedGroup( F, rls )
return FinitelyPresentedGroup(F, rls)


def FinitelyGeneratedAbelianPresentation(int_list):
r"""
Expand Down Expand Up @@ -384,6 +385,7 @@ def DiCyclicPresentation(n):
rls = F([1])**(2*n), F([2,2])*F([-1])**n, F([-2,1,2,1])
return FinitelyPresentedGroup(F, rls)


def SymmetricPresentation(n):
r"""
Build the Symmetric group of order `n!` as a finitely presented group.
Expand Down Expand Up @@ -422,14 +424,18 @@ def SymmetricPresentation(n):
from sage.groups.free_group import _lexi_gen

n = Integer(n)
if n <= 1:
return FinitelyPresentedGroup(FreeGroup(()), ())

perm_rep = SymmetricGroup(n)
GAP_fp_rep = libgap.Image(libgap.IsomorphismFpGroupByGenerators(perm_rep, perm_rep.gens()))
image_gens = GAP_fp_rep.FreeGeneratorsOfFpGroup()
name_itr = _lexi_gen() # Python generator object for variable names
name_itr = _lexi_gen() # Python generator object for variable names
F = FreeGroup([next(name_itr) for x in perm_rep.gens()])
ret_rls = tuple([F(rel_word.TietzeWordAbstractWord(image_gens).sage())
for rel_word in GAP_fp_rep.RelatorsOfFpGroup()])
return FinitelyPresentedGroup(F,ret_rls)
for rel_word in GAP_fp_rep.RelatorsOfFpGroup()])
return FinitelyPresentedGroup(F, ret_rls)


def QuaternionPresentation():
r"""
Expand Down Expand Up @@ -481,9 +487,10 @@ def AlternatingPresentation(n):
sage: A6.as_permutation_group().is_isomorphic(AlternatingGroup(6)), A6.order()
(True, 360)
TESTS::
TESTS:
Even permutation tests::
sage: #even permutation test..
sage: A1 = groups.presentation.Alternating(1); A2 = groups.presentation.Alternating(2)
sage: A1.is_isomorphic(A2), A1.order()
(True, 1)
Expand All @@ -496,14 +503,18 @@ def AlternatingPresentation(n):
from sage.groups.free_group import _lexi_gen

n = Integer(n)
if n <= 2:
return FinitelyPresentedGroup(FreeGroup(()), ())

perm_rep = AlternatingGroup(n)
GAP_fp_rep = libgap.Image(libgap.IsomorphismFpGroupByGenerators(perm_rep, perm_rep.gens()))
image_gens = GAP_fp_rep.FreeGeneratorsOfFpGroup()
name_itr = _lexi_gen() # Python generator object for variable names
name_itr = _lexi_gen() # Python generator object for variable names
F = FreeGroup([next(name_itr) for x in perm_rep.gens()])
ret_rls = tuple([F(rel_word.TietzeWordAbstractWord(image_gens).sage())
for rel_word in GAP_fp_rep.RelatorsOfFpGroup()])
return FinitelyPresentedGroup(F,ret_rls)
for rel_word in GAP_fp_rep.RelatorsOfFpGroup()])
return FinitelyPresentedGroup(F, ret_rls)


def KleinFourPresentation():
r"""
Expand Down
9 changes: 6 additions & 3 deletions src/sage/groups/perm_gps/permgroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -1279,7 +1279,7 @@ def gens(self) -> tuple:
We make sure that the trivial group gets handled correctly::
sage: SymmetricGroup(1).gens()
((),)
()
"""
return self._gens

Expand Down Expand Up @@ -2034,8 +2034,11 @@ def strong_generating_system(self, base_of_group=None, implementation="sage"):
end;
return CosetsStabChain(S0);
end;""")
G = libgap.Group(self.gens()) # G = libgap(self)
S = G.StabChain()
if self._gens:
G = libgap.Group(self.gens()) # G = libgap(self)
else:
G = libgap.SymmetricGroup([])
S = G.StabChainImmutable()
cosets = gap_cosets(S)
one = self.one()
return [[one._generate_new_GAP(libgap.ListPerm(elt))
Expand Down
35 changes: 23 additions & 12 deletions src/sage/groups/perm_gps/permgroup_named.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,12 @@ class SymmetricGroup(PermutationGroup_symalt):
sage: groups.permutation.Symmetric(4)
Symmetric group of order 4! as a permutation group
sage: groups.permutation.Symmetric(1).gens()
()
Check for :issue:`36204`::
sage: h = SymmetricGroup(1).hom(SymmetricGroup(2))
"""
def __init__(self, domain=None):
"""
Expand All @@ -261,7 +267,8 @@ def __init__(self, domain=None):
# Note that we skip the call to the superclass initializer in order to
# avoid infinite recursion since SymmetricGroup is called by
# PermutationGroupElement
cat = Category.join([FinitePermutationGroups(), FiniteWeylGroups().Irreducible()])
cat = Category.join([FinitePermutationGroups(),
FiniteWeylGroups().Irreducible()])
super(PermutationGroup_generic, self).__init__(category=cat)

self._domain = domain
Expand All @@ -270,11 +277,14 @@ def __init__(self, domain=None):
self._domain_from_gap = {i+1: key for i, key in enumerate(self._domain)}

# Create the generators for the symmetric group
gens = [tuple(self._domain)]
if len(self._domain) > 2:
gens.append(tuple(self._domain[:2]))
self._gens = tuple([self.element_class(g, self, check=False)
for g in gens])
if self._deg <= 1:
self._gens = ()
else:
gens = [tuple(self._domain)]
if self._deg > 2:
gens.append(tuple(self._domain[:2]))
self._gens = tuple([self.element_class(g, self, check=False)
for g in gens])

def _gap_init_(self, gap=None):
"""
Expand Down Expand Up @@ -1946,11 +1956,11 @@ def TransitiveGroups(d=None):
"""
if d is None:
return TransitiveGroupsAll()
else:
d = Integer(d)
if d < 0:
raise ValueError("a transitive group acts on a non negative integer number of positions")
return TransitiveGroupsOfDegree(d)

d = Integer(d)
if d < 0:
raise ValueError("a transitive group acts on a non negative integer number of positions")
return TransitiveGroupsOfDegree(d)


class TransitiveGroupsAll(DisjointUnionEnumeratedSets):
Expand Down Expand Up @@ -3449,6 +3459,7 @@ def codegrees(self):
ret.append((self._n-1)*self._m - self._n)
return tuple(sorted(ret, reverse=True))


class SmallPermutationGroup(PermutationGroup_generic):
r"""
A GAP SmallGroup, returned as a permutation group.
Expand Down Expand Up @@ -3513,7 +3524,7 @@ def __init__(self, order, gap_id):
"""
self._n = order
self._gap_id = gap_id
self._gap_small_group = libgap.SmallGroup(order,gap_id)
self._gap_small_group = libgap.SmallGroup(order, gap_id)
gap_permutation_group = self._gap_small_group.IsomorphismPermGroup().Image(self._gap_small_group)
PermutationGroup_generic.__init__(self, gap_group=gap_permutation_group)

Expand Down

0 comments on commit 5bd0466

Please sign in to comment.