1#############################################################################
2##
3##  This file is part of GAP, a system for computational discrete algebra.
4##  This file's authors include Frank Celler.
5##
6##  Copyright of GAP belongs to its developers, whose names are too numerous
7##  to list here. Please refer to the COPYRIGHT file for details.
8##
9##  SPDX-License-Identifier: GPL-2.0-or-later
10##
11##  This file contains the operations for the construction of the basic group
12##  types.
13##
14
15
16#############################################################################
17##
18##  <#GAPDoc Label="[1]{basic}">
19##  There are several infinite families of groups which are parametrized by
20##  numbers.
21##  &GAP; provides various functions to construct these groups.
22##  The functions always permit (but do not require) one to indicate
23##  a filter (see&nbsp;<Ref Sect="Filters"/>),
24##  for example <Ref Filt="IsPermGroup"/>, <Ref Filt="IsMatrixGroup"/> or
25##  <Ref Filt="IsPcGroup"/>, in which the group shall be constructed.
26##  There always is a default filter corresponding to a <Q>natural</Q> way
27##  to describe the group in question.
28##  Note that not every group can be constructed in every filter,
29##  there may be theoretical restrictions (<Ref Filt="IsPcGroup"/> only works
30##  for solvable groups) or methods may be available only for a few filters.
31##  <P/>
32##  Certain filters may admit additional hints.
33##  For example, groups constructed in <Ref Filt="IsMatrixGroup"/> may be
34##  constructed over a specified field, which can be given as second argument
35##  of the function that constructs the group;
36##  The default field is <Ref Var="Rationals"/>.
37##  <#/GAPDoc>
38
39
40#############################################################################
41##
42#O  TrivialGroupCons( <filter> )
43##
44##  <ManSection>
45##  <Oper Name="TrivialGroupCons" Arg='filter'/>
46##
47##  <Description>
48##  </Description>
49##  </ManSection>
50##
51DeclareConstructor( "TrivialGroupCons", [ IsGroup ] );
52
53
54#############################################################################
55##
56#F  TrivialGroup( [<filter>] )  . . . . . . . . . . . . . . . . trivial group
57##
58##  <#GAPDoc Label="TrivialGroup">
59##  <ManSection>
60##  <Func Name="TrivialGroup" Arg='[filter]'/>
61##
62##  <Description>
63##  constructs a trivial group in the category given by the filter
64##  <A>filter</A>.
65##  If <A>filter</A> is not given it defaults to <Ref Filt="IsPcGroup"/>.
66##  For more information on possible values of <A>filt</A> see section
67##  (<Ref Sect="Basic Groups"/>).
68##  <P/>
69##  <Example><![CDATA[
70##  gap> TrivialGroup();
71##  <pc group of size 1 with 0 generators>
72##  gap> TrivialGroup( IsPermGroup );
73##  Group(())
74##  ]]></Example>
75##  </Description>
76##  </ManSection>
77##  <#/GAPDoc>
78##
79BindGlobal( "TrivialGroup", function( arg )
80
81  if Length( arg ) = 0 then
82    return TrivialGroupCons( IsPcGroup );
83  elif IsFilter( arg[1] ) and Length( arg ) = 1 then
84    return TrivialGroupCons( arg[1] );
85  fi;
86  Error( "usage: TrivialGroup( [<filter>] )" );
87
88end );
89
90
91#############################################################################
92##
93#O  AbelianGroupCons( <filter>, <ints> )
94##
95##  <ManSection>
96##  <Oper Name="AbelianGroupCons" Arg='filter, ints'/>
97##
98##  <Description>
99##  </Description>
100##  </ManSection>
101##
102DeclareConstructor( "AbelianGroupCons", [ IsGroup, IsList ] );
103
104
105#############################################################################
106##
107#F  AbelianGroup( [<filt>, ]<ints> )  . . . . . . . . . . . . . abelian group
108##
109##  <#GAPDoc Label="AbelianGroup">
110##  <ManSection>
111##  <Func Name="AbelianGroup" Arg='[filt, ]ints'/>
112##
113##  <Description>
114##  constructs an abelian group in the category given by the filter
115##  <A>filt</A> which is of isomorphism type
116##  <M>C_{{<A>ints</A>[1]}} \times C_{{<A>ints</A>[2]}} \times \ldots
117##  \times C_{{<A>ints</A>[n]}}</M>,
118##  where <A>ints</A> must be a list of non-negative integers or
119##  <Ref Var="infinity"/>; for the latter value or 0, <M>C_{{<A>ints</A>[i]}}</M>
120##  is taken as an infinite cyclic group, otherwise as a cyclic group of
121##  order <A>ints</A>[i].
122##
123##  If <A>filt</A> is not given it defaults to <Ref Filt="IsPcGroup"/>,
124##  unless any 0 or <C>infinity</C> is contained in  <A>ints</A>, in which
125##  the default filter is switched to  <Ref Filt="IsFpGroup"/>.
126##  The generators of the group returned are the elements corresponding to
127##  the factors <M>C_{{<A>ints</A>[i]}}</M> and hence the integers in <A>ints</A>.
128##  For more information on possible values of <A>filt</A> see section
129##  (<Ref Sect="Basic Groups"/>).
130##  <P/>
131##  <Example><![CDATA[
132##  gap> AbelianGroup([1,2,3]);
133##  <pc group of size 6 with 3 generators>
134##  gap> G:=AbelianGroup([0,3]);
135##  <fp group of size infinity on the generators [ f1, f2 ]>
136##  gap> AbelianInvariants(G);
137##  [ 0, 3 ]
138##  ]]></Example>
139##  </Description>
140##  </ManSection>
141##  <#/GAPDoc>
142##
143BindGlobal( "AbelianGroup", function ( arg )
144
145  if Length(arg) = 1  then
146    if ForAny(arg[1],x->x=0 or x=infinity) then
147      return AbelianGroupCons( IsFpGroup, arg[1] );
148    fi;
149    return AbelianGroupCons( IsPcGroup, arg[1] );
150  elif IsOperation(arg[1]) then
151    if Length(arg) = 2  then
152      return AbelianGroupCons( arg[1], arg[2] );
153    fi;
154  fi;
155  Error( "usage: AbelianGroup( [<filter>, ]<ints> )" );
156
157end );
158
159
160#############################################################################
161##
162#O  AlternatingGroupCons( <filter>, <deg> )
163##
164##  <ManSection>
165##  <Oper Name="AlternatingGroupCons" Arg='filter, deg'/>
166##
167##  <Description>
168##  </Description>
169##  </ManSection>
170##
171DeclareConstructor( "AlternatingGroupCons", [ IsGroup, IsInt ] );
172
173
174#############################################################################
175##
176#F  AlternatingGroup( [<filt>, ]<deg> ) . . . . . . . . . . alternating group
177#F  AlternatingGroup( [<filt>, ]<dom> ) . . . . . . . . . . alternating group
178##
179##  <#GAPDoc Label="AlternatingGroup">
180##  <ManSection>
181##  <Heading>AlternatingGroup</Heading>
182##  <Func Name="AlternatingGroup" Arg='[filt, ]deg' Label="for a degree"/>
183##  <Func Name="AlternatingGroup" Arg='[filt, ]dom' Label="for a domain"/>
184##
185##  <Description>
186##  constructs the alternating group of degree <A>deg</A> in the category given
187##  by the filter <A>filt</A>.
188##  If <A>filt</A> is not given it defaults to <Ref Filt="IsPermGroup"/>.
189##  For more information on possible values of <A>filt</A> see section
190##  (<Ref Sect="Basic Groups"/>).
191##  In the second version, the function constructs the alternating group on
192##  the points given in the set <A>dom</A> which must be a set of positive
193##  integers.
194##  <Example><![CDATA[
195##  gap> AlternatingGroup(5);
196##  Alt( [ 1 .. 5 ] )
197##  ]]></Example>
198##  </Description>
199##  </ManSection>
200##  <#/GAPDoc>
201##
202BindGlobal( "AlternatingGroup", function ( arg )
203
204  if Length(arg) = 1  then
205    return  AlternatingGroupCons( IsPermGroup, arg[1] );
206  elif IsOperation(arg[1]) then
207
208    if Length(arg) = 2  then
209      return  AlternatingGroupCons( arg[1], arg[2] );
210    fi;
211  fi;
212  Error( "usage: AlternatingGroup( [<filter>, ]<deg> )" );
213
214end );
215
216
217#############################################################################
218##
219#O  CyclicGroupCons( <filter>, <n> )
220##
221##  <ManSection>
222##  <Oper Name="CyclicGroupCons" Arg='filter, n'/>
223##
224##  <Description>
225##  </Description>
226##  </ManSection>
227##
228DeclareConstructor( "CyclicGroupCons", [ IsGroup, IsInt ] );
229
230
231#############################################################################
232##
233#F  CyclicGroup( [<filt>, ]<n> )  . . . . . . . . . . . . . . .  cyclic group
234##
235##  <#GAPDoc Label="CyclicGroup">
236##  <ManSection>
237##  <Func Name="CyclicGroup" Arg='[filt, ]n'/>
238##
239##  <Description>
240##  constructs the cyclic group of size <A>n</A> in the category given by the
241##  filter <A>filt</A>.
242##  If <A>filt</A> is not given it defaults to <Ref Filt="IsPcGroup"/>,
243##  unless <A>n</A> equals <Ref Var="infinity"/>, in which case the
244##  default filter is switched to  <Ref Filt="IsFpGroup"/>.
245##  For more information on possible values of <A>filt</A> see section
246##  (<Ref Sect="Basic Groups"/>).
247##  <P/>
248##  <Example><![CDATA[
249##  gap> CyclicGroup(12);
250##  <pc group of size 12 with 3 generators>
251##  gap> CyclicGroup(infinity);
252##  <free group on the generators [ a ]>
253##  gap> CyclicGroup(IsPermGroup,12);
254##  Group([ (1,2,3,4,5,6,7,8,9,10,11,12) ])
255##  gap> matgrp1:= CyclicGroup( IsMatrixGroup, 12 );
256##  <matrix group of size 12 with 1 generators>
257##  gap> FieldOfMatrixGroup( matgrp1 );
258##  Rationals
259##  gap> matgrp2:= CyclicGroup( IsMatrixGroup, GF(2), 12 );
260##  <matrix group of size 12 with 1 generators>
261##  gap> FieldOfMatrixGroup( matgrp2 );
262##  GF(2)
263##  ]]></Example>
264##  </Description>
265##  </ManSection>
266##  <#/GAPDoc>
267##
268BindGlobal( "CyclicGroup", function ( arg )
269
270  if Length(arg) = 1  then
271    if arg[1]=infinity then
272      return CyclicGroupCons(IsFpGroup, arg[1]);
273    fi;
274    return CyclicGroupCons( IsPcGroup, arg[1] );
275  elif IsOperation(arg[1]) then
276    if Length(arg) = 2  then
277      return CyclicGroupCons( arg[1], arg[2] );
278    elif Length(arg) = 3  then
279      # some filters require extra arguments, e.g. IsMatrixGroup + field
280      return CyclicGroupCons( arg[1], arg[2], arg[3] );
281    fi;
282  fi;
283  Error( "usage: CyclicGroup( [<filter>, ]<size> )" );
284
285end );
286
287
288#############################################################################
289##
290#O  DihedralGroupCons( <filter>, <n> )
291##
292##  <ManSection>
293##  <Oper Name="DihedralGroupCons" Arg='filter, n'/>
294##
295##  <Description>
296##  </Description>
297##  </ManSection>
298##
299DeclareConstructor( "DihedralGroupCons", [ IsGroup, IsInt ] );
300
301
302#############################################################################
303##
304#F  DihedralGroup( [<filt>, ]<n> )  . . . . . . . dihedral group of order <n>
305##
306##  <#GAPDoc Label="DihedralGroup">
307##  <ManSection>
308##  <Func Name="DihedralGroup" Arg='[filt, ]n'/>
309##
310##  <Description>
311##  constructs the dihedral group of size <A>n</A> in the category given by the
312##  filter <A>filt</A>.
313##  If <A>filt</A> is not given it defaults to <Ref Filt="IsPcGroup"/>,
314##  unless <A>n</A> equals <Ref Var="infinity"/>, in which case the
315##  default filter is switched to  <Ref Filt="IsFpGroup"/>.
316##  For more information on possible values of <A>filt</A> see section
317##  (<Ref Sect="Basic Groups"/>).
318##  <P/>
319##  <Example><![CDATA[
320##  gap> DihedralGroup(8);
321##  <pc group of size 8 with 3 generators>
322##  gap> DihedralGroup( IsPermGroup, 8 );
323##  Group([ (1,2,3,4), (2,4) ])
324##  gap> DihedralGroup(infinity);
325##  <fp group of size infinity on the generators [ r, s ]>
326##  ]]></Example>
327##  </Description>
328##  </ManSection>
329##  <#/GAPDoc>
330##
331BindGlobal( "DihedralGroup", function ( arg )
332
333  if Length(arg) = 1  then
334    if arg[1]=infinity then
335      return DihedralGroupCons( IsFpGroup, arg[1] );
336    fi;
337    return DihedralGroupCons( IsPcGroup, arg[1] );
338  elif IsOperation(arg[1]) then
339    if Length(arg) = 2  then
340      return DihedralGroupCons( arg[1], arg[2] );
341    fi;
342  fi;
343  Error( "usage: DihedralGroup( [<filter>, ]<size> )" );
344
345end );
346
347#############################################################################
348##
349#O  DicyclicGroupCons( <filter>, <n> )
350##
351##  <ManSection>
352##  <Oper Name="DicyclicGroupCons" Arg='filter, n'/>
353##
354##  <Description>
355##  </Description>
356##  </ManSection>
357##
358DeclareConstructor( "DicyclicGroupCons", [ IsGroup, IsInt ] );
359DeclareSynonym("QuaternionGroupCons", DicyclicGroupCons);
360
361
362#############################################################################
363##
364#F  DicyclicGroup( [<filt>, [<field>, ] ]<n> )  Dicyclic group of order <n>
365##
366##  <#GAPDoc Label="DicyclicGroup">
367##  <ManSection>
368##  <Func Name="DicyclicGroup" Arg='[filt, [field, ]]n'/>
369##  <Func Name="QuaternionGroup" Arg='[filt, [field, ]]n'/>
370##
371##  <Description>
372##  <Ref Func="DicyclicGroup"/> constructs the dicyclic group of size <A>n</A>
373##  in the category given by the filter <A>filt</A>. Here, <A>n</A> must be a
374##  multiple of 4. The synonym <Ref Func="QuaternionGroup"/> for
375##  <Ref Func="DicyclicGroup" /> is provided for backward compatibility, but will
376##  print a warning if <A>n</A> is not a power of <M>2</M>.
377##  If <A>filt</A> is not given it defaults to <Ref Filt="IsPcGroup"/>.
378##  For more information on possible values of <A>filt</A> see section
379##  (<Ref Sect="Basic Groups"/>).
380##  Methods are also available for permutation and matrix groups (of minimal
381##  degree and minimal dimension in coprime characteristic).
382##  <P/>
383##  <Example><![CDATA[
384##  gap> DicyclicGroup(24);
385##  <pc group of size 24 with 4 generators>
386##  gap> g:=QuaternionGroup(IsMatrixGroup,CF(16),32);
387##  Group([ [ [ 0, 1 ], [ -1, 0 ] ], [ [ E(16), 0 ], [ 0, -E(16)^7 ] ] ])
388##  ]]></Example>
389##  </Description>
390##  </ManSection>
391##  <#/GAPDoc>
392##
393BindGlobal( "GRPLIB_DicyclicParameterCheck",
394function(args, quaternion)
395    local size;
396
397    if Length(args) = 1 then
398        args := [ IsPcGroup, args[1] ];
399    elif Length(args) = 2 then
400        # 2 inputs are valid, but we just reuse args
401        # args := args;
402    elif Length(args) = 3 then
403        if not IsField(args[2]) then
404            ErrorNoReturn("usage: <field> must be a field");
405        fi;
406    else
407        ErrorNoReturn("usage: DicyclicGroup( [<filter>, [<field>, ] ] <size> )");
408    fi;
409
410    size := args[Length(args)];
411    if not IsFilter(args[1]) then
412        ErrorNoReturn("usage: <filter> must be a filter");
413    fi;
414
415    if not (IsPosInt(size) and (size mod 4 = 0)) then
416        ErrorNoReturn("usage: <size> must be a positive integer divisible by 4");
417    fi;
418
419    if not IsPrimePowerInt(size) or size < 8 then
420        if quaternion = "error" then
421            ErrorNoReturn("usage: <size> must be a power of 2 and at least 8");
422        elif quaternion = "warn" then
423            if not IsPrimePowerInt(size) then
424                Info(InfoWarning, 1, "Warning: QuaternionGroup called with <size> ", size,
425                                     " which is not a power of 2");
426            else
427                Info(InfoWarning, 1, "Warning: QuaternionGroup called with <size> ", size,
428                                     " which is less than 8");
429            fi;
430        fi;
431    fi;
432
433    return args;
434end);
435
436BindGlobal( "DicyclicGroup",
437function(args...)
438    local res;
439
440    res := GRPLIB_DicyclicParameterCheck(args, "");
441
442    return CallFuncList(DicyclicGroupCons, res);
443end);
444
445BindGlobal( "QuaternionGroup",
446function(args...)
447    local res;
448
449    res := GRPLIB_DicyclicParameterCheck(args, "warn");
450
451    return CallFuncList(DicyclicGroupCons, res);
452end);
453
454BindGlobal( "GeneralisedQuaternionGroup",
455function(args...)
456    local res, grp;
457
458    res := GRPLIB_DicyclicParameterCheck(args, "error");
459    grp := CallFuncList(DicyclicGroupCons, res);
460    SetIsGeneralisedQuaternionGroup(grp, true);
461
462    return grp;
463end);
464
465
466#############################################################################
467##
468#O  ElementaryAbelianGroupCons( <filter>, <n> )
469##
470##  <ManSection>
471##  <Oper Name="ElementaryAbelianGroupCons" Arg='filter, n'/>
472##
473##  <Description>
474##  </Description>
475##  </ManSection>
476##
477DeclareConstructor( "ElementaryAbelianGroupCons", [ IsGroup, IsInt ] );
478
479
480#############################################################################
481##
482#F  ElementaryAbelianGroup( [<filt>, ]<n> ) . . . .  elementary abelian group
483##
484##  <#GAPDoc Label="ElementaryAbelianGroup">
485##  <ManSection>
486##  <Func Name="ElementaryAbelianGroup" Arg='[filt, ]n'/>
487##
488##  <Description>
489##  constructs the elementary abelian group of size <A>n</A> in the category
490##  given by the filter <A>filt</A>.
491##  If <A>filt</A> is not given it defaults to <Ref Filt="IsPcGroup"/>.
492##  For more information on possible values of <A>filt</A> see section
493##  (<Ref Sect="Basic Groups"/>).
494##  <P/>
495##  <Example><![CDATA[
496##  gap> ElementaryAbelianGroup(8192);
497##  <pc group of size 8192 with 13 generators>
498##  ]]></Example>
499##  </Description>
500##  </ManSection>
501##  <#/GAPDoc>
502##
503BindGlobal( "ElementaryAbelianGroup", function ( arg )
504
505  if Length(arg) = 1  then
506    return ElementaryAbelianGroupCons( IsPcGroup, arg[1] );
507  elif IsOperation(arg[1]) then
508    if Length(arg) = 2  then
509      return ElementaryAbelianGroupCons( arg[1], arg[2] );
510    fi;
511  fi;
512  Error( "usage: ElementaryAbelianGroup( [<filter>, ]<size> )" );
513
514end );
515
516
517#############################################################################
518##
519#O  FreeAbelianGroupCons( <filter>, <rank> )
520##
521##  <ManSection>
522##  <Oper Name="FreeAbelianGroupCons" Arg='filter, rank'/>
523##
524##  <Description>
525##  </Description>
526##  </ManSection>
527##
528DeclareConstructor( "FreeAbelianGroupCons", [ IsGroup, IsInt ] );
529
530
531#############################################################################
532##
533#F  FreeAbelianGroup( [<filt>, ]<rank> ) . . . . . . . . . .  free abelian group
534##
535##  <#GAPDoc Label="FreeAbelianGroup">
536##  <ManSection>
537##  <Func Name="FreeAbelianGroup" Arg='[filt, ]rank'/>
538##
539##  <Description>
540##  constructs the free abelian group of rank <A>n</A> in the category
541##  given by the filter <A>filt</A>.
542##  If <A>filt</A> is not given it defaults to <Ref Filt="IsFpGroup"/>.
543##  For more information on possible values of <A>filt</A> see section
544##  (<Ref Sect="Basic Groups"/>).
545##  <P/>
546##  <Example><![CDATA[
547##  gap> FreeAbelianGroup(4);
548##  <fp group of size infinity on the generators [ f1, f2, f3, f4 ]>
549##  ]]></Example>
550##  </Description>
551##  </ManSection>
552##  <#/GAPDoc>
553##
554BindGlobal( "FreeAbelianGroup", function ( arg )
555
556  if Length(arg) = 1  then
557    return FreeAbelianGroupCons( IsFpGroup, arg[1] );
558  elif IsOperation(arg[1]) then
559    if Length(arg) = 2  then
560      return FreeAbelianGroupCons( arg[1], arg[2] );
561    fi;
562  fi;
563  Error( "usage: FreeAbelianGroup( [<filter>, ]<rank> )" );
564
565end );
566
567
568#############################################################################
569##
570#O  ExtraspecialGroupCons( <filter>, <order>, <exponent> )
571##
572##  <ManSection>
573##  <Oper Name="ExtraspecialGroupCons" Arg='filter, order, exponent'/>
574##
575##  <Description>
576##  </Description>
577##  </ManSection>
578##
579DeclareConstructor( "ExtraspecialGroupCons", [ IsGroup, IsInt, IsObject ] );
580
581
582#############################################################################
583##
584#F  ExtraspecialGroup( [<filt>, ]<order>, <exp> ) . . . .  extraspecial group
585##
586##  <#GAPDoc Label="ExtraspecialGroup">
587##  <ManSection>
588##  <Func Name="ExtraspecialGroup" Arg='[filt, ]order, exp'/>
589##
590##  <Description>
591##  Let <A>order</A> be of the form <M>p^{{2n+1}}</M>, for a prime integer
592##  <M>p</M> and a positive integer <M>n</M>.
593##  <Ref Func="ExtraspecialGroup"/> returns the extraspecial group of order
594##  <A>order</A> that is determined by <A>exp</A>,
595##  in the category given by the filter <A>filt</A>.
596##  <P/>
597##  If <M>p</M> is odd then admissible values of <A>exp</A> are the exponent
598##  of the group (either <M>p</M> or <M>p^2</M>) or one of <C>'+'</C>,
599##  <C>"+"</C>, <C>'-'</C>, <C>"-"</C>.
600##  For <M>p = 2</M>, only the above plus or minus signs are admissible.
601##  <P/>
602##  If <A>filt</A> is not given it defaults to <Ref Filt="IsPcGroup"/>.
603##  For more information on possible values of <A>filt</A> see section
604##  (<Ref Sect="Basic Groups"/>).
605##  <P/>
606##  <Example><![CDATA[
607##  gap> ExtraspecialGroup( 27, 3 );
608##  <pc group of size 27 with 3 generators>
609##  gap> ExtraspecialGroup( 27, '+' );
610##  <pc group of size 27 with 3 generators>
611##  gap> ExtraspecialGroup( 8, "-" );
612##  <pc group of size 8 with 3 generators>
613##  ]]></Example>
614##  </Description>
615##  </ManSection>
616##  <#/GAPDoc>
617##
618BindGlobal( "ExtraspecialGroup", function ( arg )
619
620  if Length(arg) = 2  then
621    return ExtraspecialGroupCons( IsPcGroup, arg[1], arg[2] );
622  elif IsOperation(arg[1]) then
623    if Length(arg) = 3  then
624      return ExtraspecialGroupCons( arg[1], arg[2], arg[3] );
625    fi;
626  fi;
627  Error( "usage: ExtraspecialGroup( [<filter>, ]<order>, <exponent> )" );
628
629end );
630
631
632#############################################################################
633##
634#O  MathieuGroupCons( <filter>, <degree> )
635##
636##  <ManSection>
637##  <Oper Name="MathieuGroupCons" Arg='filter, degree'/>
638##
639##  <Description>
640##  </Description>
641##  </ManSection>
642##
643DeclareConstructor( "MathieuGroupCons", [ IsGroup, IsInt ] );
644
645
646#############################################################################
647##
648#F  MathieuGroup( [<filt>, ]<degree> )  . . . . . . . . . . . . Mathieu group
649##
650##  <#GAPDoc Label="MathieuGroup">
651##  <ManSection>
652##  <Func Name="MathieuGroup" Arg='[filt, ]degree'/>
653##
654##  <Description>
655##  constructs the Mathieu group of degree <A>degree</A> in the category
656##  given by the filter <A>filt</A>, where <A>degree</A> must be in the set
657##  <M>\{ 9, 10, 11, 12, 21, 22, 23, 24 \}</M>.
658##  If <A>filt</A> is not given it defaults to <Ref Filt="IsPermGroup"/>.
659##  For more information on possible values of <A>filt</A> see section
660##  (<Ref Sect="Basic Groups"/>).
661##  <P/>
662##  <Example><![CDATA[
663##  gap> MathieuGroup( 11 );
664##  Group([ (1,2,3,4,5,6,7,8,9,10,11), (3,7,11,8)(4,10,5,6) ])
665##  ]]></Example>
666##  </Description>
667##  </ManSection>
668##  <#/GAPDoc>
669##
670BindGlobal( "MathieuGroup", function( arg )
671
672  if Length( arg ) = 1 then
673    return MathieuGroupCons( IsPermGroup, arg[1] );
674  elif IsOperation( arg[1] ) then
675    if Length( arg ) = 2 then
676      return MathieuGroupCons( arg[1], arg[2] );
677    fi;
678  fi;
679  Error( "usage: MathieuGroup( [<filter>, ]<degree> )" );
680
681end );
682
683
684#############################################################################
685##
686#O  SymmetricGroupCons( <filter>, <deg> )
687##
688##  <ManSection>
689##  <Oper Name="SymmetricGroupCons" Arg='filter, deg'/>
690##
691##  <Description>
692##  </Description>
693##  </ManSection>
694##
695DeclareConstructor( "SymmetricGroupCons", [ IsGroup, IsInt ] );
696
697
698#############################################################################
699##
700#F  SymmetricGroup( [<filt>, ]<deg> )
701#F  SymmetricGroup( [<filt>, ]<dom> )
702##
703##  <#GAPDoc Label="SymmetricGroup">
704##  <ManSection>
705##  <Heading>SymmetricGroup</Heading>
706##  <Func Name="SymmetricGroup" Arg='[filt, ]deg' Label="for a degree"/>
707##  <Func Name="SymmetricGroup" Arg='[filt, ]dom' Label="for a domain"/>
708##
709##  <Description>
710##  constructs the symmetric group of degree <A>deg</A> in the category
711##  given by the filter <A>filt</A>.
712##  If <A>filt</A> is not given it defaults to <Ref Filt="IsPermGroup"/>.
713##  For more information on possible values of <A>filt</A> see section
714##  (<Ref Sect="Basic Groups"/>).
715##  In the second version, the function constructs the symmetric group on
716##  the points given in the set <A>dom</A> which must be a set of positive
717##  integers.
718##  <P/>
719##  <Example><![CDATA[
720##  gap> SymmetricGroup(10);
721##  Sym( [ 1 .. 10 ] )
722##  ]]></Example>
723##  <P/>
724##  Note that permutation groups provide special treatment of symmetric and
725##  alternating groups,
726##  see&nbsp;<Ref Sect="Symmetric and Alternating Groups"/>.
727##  </Description>
728##  </ManSection>
729##  <#/GAPDoc>
730##
731BindGlobal( "SymmetricGroup", function ( arg )
732
733  if Length(arg) = 1  then
734    return  SymmetricGroupCons( IsPermGroup, arg[1] );
735  elif IsOperation(arg[1]) then
736
737    if Length(arg) = 2  then
738      return  SymmetricGroupCons( arg[1], arg[2] );
739    fi;
740  fi;
741  Error( "usage: SymmetricGroup( [<filter>, ]<deg> )" );
742
743end );
744
745BIND_GLOBAL("PermConstructor",function(oper,filter,use)
746local val, i;
747  val:=0;
748  # force value 0 (unless offset).
749  for i in filter do
750    val:=val-RankFilter(i);
751  od;
752
753  InstallOtherMethod( oper,
754    "convert to permgroup",
755    filter,
756    val,
757  function(arg)
758  local argc,g,h;
759    argc:=ShallowCopy(arg);
760    argc[1]:=use;
761    g:=CallFuncList(oper,argc);
762    h:=Image(IsomorphismPermGroup(g),g);
763    if HasName(g) then
764      SetName(h,Concatenation("Perm_",Name(g)));
765    fi;
766    if HasSize(g) then
767      SetSize(h,Size(g));
768    fi;
769    return h;
770  end);
771
772end);
773