Alexander Hulpke, May 15, 1998 Alexander Hulpke, May 15, 1998 7 Alexander Hulpke, May 15, 1998 Transformation := NewOperationArgs("Transformation"); 3 The next will be a function to create a transformation from an image list. We fi rst declare it The actual implementation then can happen much later (we can separate declaration and implementation like in .h and .c fi les): TransformationsType:=NewType(TransformationsFamily, IsTransformationDefaultRep); As there is only one family and one representation we get just one type which we also create immediately: TransformationsFamily:=NewFamily("TransformationsFamily",IsTransformation We need a family for transformations. There is just one family (no parametrization) and so we create it here (and not in a function). The family requires all elements to be transformations. (We could implement further representations if we wanted.) ImageTransformation:=NewAttribute("ImageTransformation",IsTransformation) ... InstallMethod(ImageTransformation,"default rep",true, [IsTransformationDefaultRep],0, function(t) return SSortedList(t!.images); # strictly sorted list end); As an example of an attribute we take the image of a transformation. (The operation Image applies only to mappings which our transformations are not.) (another method is needed for perm*transformation.) InstallMethod(\*,"transf. with perm",true, [IsTransformationDefaultRep,IsPermutation],0, ... It is possible to install methods to multiply transformations with permutations: We should also install methods for One (returns Transformation([])), Inverse and \^ (left as exercise). 2 Alexander Hulpke, May 15, 1998 Alexander Hulpke, May 15, 1998 6 IsTransformationDefaultRep:=NewRepresentation("IsTransformationDefaultRep IsTransformation and IsComponentObjectRep and IsAttributeStoringRep, ["images"] ); IsTransformationsCollection:=CategoryCollection(IsTransformation); IsTransformationSemigroup:=IsSemigroup and IsTransformationsCollection; Transformations will be represented by a list of images. As we might want to store further information (for example kernel) we use component objects which have a component images for this list: IsTransformation:=NewCategory("IsTransformation", IsMultiplicativeElement); We will disregard for the time being the built-in permutations and create completely new objects. For these we need a category, which will identify objects as being transformations. This example implements rudimentary code for transformations. 1 A longer example Some special operations Now we can for example make a semigroup from transformations (even though few algorithms would apply for such semigroups). By defi ning the collection for transformations we easily get the category of transformation semigroups. Alexander Hulpke, May 15, 1998 Arithmetic \+(a,b) is called by a+b; (Similarly: \-,\*,\/ and \^). Neutral One(a) and Zero(a) return the neutral elements. (Both commands also apply to collections and families.) Inverse Inverse(a) tries to compute an inverse and returns fail if not invertible. Element test \in(e,c) is called by e in c. Display Print and View call PrintObj(a) and ViewObj(a). List simulation \[\](l,pos) simulates list access. List assignement is simulated by \[\]\:\=(l,pos,val) and there are IsBound\[\](l,pos) and Unbind(l,pos). Record simulation \.(r,rnum) simulates record access. (Components identifi ed via the RNum, an integer identifi er). if aims[i]>l then c[i]:=aims[i]; # b does not map i^a else c[i]:=bims[aims[i]]; # map with a and then b fi; od; # here i equals length(aims)+1 if i<=l then # b maps points a does not Append(c,bims{[i..l]}); fi; return Transformation(c); end); Abstract This lecture gives examples of how to create objects and install methods for them. 5 http://www-gap.dcs.st-and.ac.uk/~ahulpke/course.html Alexander Hulpke, May 15, 1998 June 1, 1998 InstallMethod(\*,"transformations",IsIdenticalObj, [IsTransformationDefaultRep,IsTransformationDefaultRep],0, function(a,b) local i,c,l,aims,bims; c:=[]; aims:=a!.images; bims:=b!.images; l:=Length(bims); for i in [1..Length(a!.images)] do 4 Alexander Hulpke InstallMethod(\^,"transformation on point",true, [IsPosInt,IsTransformationDefaultRep],0, function(p,t) if p>Length(t!.images) then return p; else return t!.images[p]; fi; end); Alexander Hulpke, May 15, 1998 Next come commands to apply transformations to a positive integer and to multiply them: Note that this method is installed for the representation, because we actually look in it. (O course this implies the category.) InstallMethod(PrintObj,"transformations",true,[IsTransformationDefaultRep function(t) Print("Transformation(",t!.images,")"); end); We should at least be able to see the transformations. As View calls Print by default, we just implement a Print method here: (For the time being we dispense with a test for correct input.) InstallGlobalFunction(Transformation, function(list) return Objectify(TransformationsType,rec(images:=list)); end); GAP4 III. New Objects - !.wholeGroup Free group Collection - GeneratorsOfGroup IsomorphismPermGroup faithful Repres. ? .. .. . . Fp group Fp gen 14 FamilyObj !.wholeGroup Alexander Hulpke, May 15, 1998 family Relators ,, * , ,, RelatorsOfFpGroup ,, ,, ,, free ge FreeGeneratorsOfFpGroup - GeneratorsOfGroup 13 ElementsFamily - CollectionFamily FamilyObj 1 6 !.freeGroup FreeGroup family Collection Alexander Hulpke, May 15, 1998 family ElementsFamily - CollectionFamily Fp elements family Free elements The following picture sums up the situation: 9 10 Alexander Hulpke, May 15, 1998 11 When asking for equality of elements of g, GAP calls the attribute IsomorphismPermGroup(g which will try to compute a faithful representation. The elements then are compared in this image. Proper subgroups of g can always refer to the full group (for example to deduce information from a coset table.) become trivial in the fp group.) RelatorsOfFpGroup The relators as words in these generators. (The relators by defi nition FreeGeneratorsOfFpGroup The free generators (whose images are the fp generators). FreeGroupOfFpGroup The free group. The full fi nitely presented group has the attributes: Again for the full group the property IsWholeFamily is set and the collections family knows the full group. The fi nitely presented group and its subgroups have the category IsSubgroupFpGroup. Alexander Hulpke, May 15, 1998 Arithmetic in g will work with these representatives, but comparisons have to be done in the fi nitely presented image. To be able to do this, the family knows components !.freeGroup and relators. GAP creates a new family for the elements of g. These elements are positional objects whose entry in position 1 is a representative in f, that can be obtained via the operation UnderlyingElement. gap> g:=f/[f.1^2,f.2^3,(f.1*f.2)^5]; <fp group on the generators [x,y]> gap> g.1^2 x^2 Now lets create an fi nitely presented group by factoring out some relators: The free group has the category IsFreeGroup, for the full group the property IsWholeFamily is also set. The collections family of words knows the full free group (in the component !.wholeGroup) Alexander Hulpke, May 15, 1998 The elements belong to the category IsAssociativeWordWithInverse. There are 4 representations of such words, that reserve for a generator/exponent pair 8, 16 or 32 bits or use two full integers. The family of f is the CollectionsFamily of the family of its elements. (The free generators here are printed as “x” and “y”, but this has no relation to variable names!) gap> f:=FreeGroup(["x","y"]); <free group on the generators [x,y]> gap> f.1*f.2^5; x*y^5 Every free group has its own family of elements. Finitely presented groups serve as a more elaborate example with different families. Free groups and fi nitely presented groups 8 Alexander Hulpke, May 15, 1998 Alexander Hulpke, May 15, 1998 12 If this was a library we would have used the “Declare...” commands instead that would also protect the variable names against overwriting. (As this homomorphism is not well-defi ned, the “<” comparison of elements of an fp group is session-dependent.)