Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 418346############################################################################# #### ## #W pgrelfind.g ACE Research Example Alexander Hulpke #W Greg Gamble #W George Havas ## ## Defines programs and variables for finding 3-relator presentations of a ## specific form, for perfect simple groups. ## ## Featured in this file is a genuine research example. The original code ## was written by Alexander Hulpke. Greg Gamble later modified it ## significantly, adding comments and options, and alterations needed to ## enable it to work with the latest ACE Package. Names of some functions ## and variables were also changed. ## #Y Copyright (C) 2000 Centre for Discrete Mathematics and Computing #Y Department of Computer Science & Electrical Eng. #Y University of Queensland, Australia. ## ## Begin if not(IsBound(ACEResExample) and IsBound(ACEResExample.reread)) then ACEResExample := rec(filename := "pgrelfind.g"); LoadPackage("ace", "3.0"); fi; # Use ACE for CosetTableFromGensAndRels coset enumerations TCENUM := ACETCENUM;; # The following global variables are set in PGRelFind ALLRELS := []; # in case we want to collect all relators tried. newrels := []; # in case we want to collect all relators that work. PGRelFind := function(Fgens, rels, sgens) ## For the perfect *simple* group S = <Fgens | rels> with subgroup <sgens> ## where each element of the list sgens is a word in the generators Fgens, ## try to find one `extra' relator. Fgens should contain two generators of a ## free group, say [a, b]; rels should contain words in the generators ## Fgens, the first of which, should determine that a is an involution, the ## second should determine the order of b. The subgroup <sgens> should ## ideally be a maximal subgroup of <Fgens | rels>. The purpose of PGRelFind ## is to find a presentation containing just 3 relators, one determining the ## order of a, one determining the order of b, and just one other. After a ## search is successful, searching continues in case there is a shorter ## relator, and terminates with a relator of shortest length. ## ## Options : ## head : Each relator tested is of form `head' * `middle' * `tail' ## where `head' is constant. This option sets the value of `head'. ## Value: a word in Fgens ## Default: a*b*a*b*a/b (if |b| = 3), a*b (otherwise) ## Nrandom : Each `middle' may be generated sequentially or randomly. ## If Nrandom = 0 then `middle's are generated sequentially. ## If Nrandom is a positive integer then for each length of a ## middle Nrandom `middle's are generated. ## If Nrandom is a positive integer valued single-argument ## function then for each length len of a middle Nrandom(len) ## `middle's are generated. ## Value: a non-negative integer OR a single-argument function ## that returns a positive integer. ## Default: 0 ## ACEworkspace : The workspace ACE is set to use when running the ## index check of the large subgroup. If the index is right, ## double this workspace is used to check the index of <b>. ## Value: a positive integer ## Default: 10^6 ## Ntails : Approximate no. of tails generated. It is used to set ## maxTailLength. ## Value: a positive integer ## Default: 2048 ## maxTailLength : (Intended) maximum tail length. Actual maximum ## tail length may be 1 less, so that it has the same parity as ## the minimum tail length. Overrides the effect of Ntails. ## Value: a positive integer ## Default: LogInt(Ntails, |b| - 1) ## minMiddleLength : Minimum length of a `middle'. ## Value: non-negative integer ## Default: 0 ## maxMiddleLength : (Intended) maximum length of a `middle'. Actual ## maximum may be less, in order to ensure granularity + 2 divides ## maxMiddleLength - minMiddleLength, where ## ## granularity = maxTailLength - minTailLength ## ## Value: positive integer ## Default: 30 ## local SetConstFromOption, NewRelator, F, a, b, t, permSgens, idx, orderS, orderb, whead; SetConstFromOption := function(opt, default) # Sets a PGRelFind constant according to the option opt passed to # PGRelFind, or if no such option is passed sets the constant to # default. local optval; optval := ValueOption(opt); if optval = fail then optval := default; fi; return optval; end; NewRelator := function(gens) # Produces a,b-words starting with whead until a new relator that # satisfies IsPresentation is found and returns that relator. local ACEworkspace, Nrandom, headLength, minMiddleLength, maxMiddleLength, Ntails, minTailLength, maxTailLength, granularity, GAPstarttime, IsPresentation, ap, bp, head, headbExptSum, Nbexpts, bexpts, absylls, Initc, cLength, c, cCtr, NcVectors, bExptSum, GetNextc, Permc, Wordc, TailLenIndex, tails, NonZeroModOrderb, tail, UnbindList, nrandom, bPowers, Randomc, relatorExclusions, maxTailLenIndex, p, tailrec, w, Nwbisyllables; # Constants ... read `Length' as #a,b-bisyllables ACEworkspace := SetConstFromOption("ACEworkspace", 10^6); Nrandom := SetConstFromOption("Nrandom", 0); headLength := ExponentSumWord(whead, a); minTailLength := (headLength - 1) mod 2; Ntails := SetConstFromOption("Ntails", 2048); maxTailLength := SetConstFromOption( "maxTailLength", LogInt(Ntails, orderb - 1) ); # ensure maxTailLength has same parity as minTailLength maxTailLength := maxTailLength - (maxTailLength - minTailLength) mod 2; granularity := maxTailLength - minTailLength; minMiddleLength := SetConstFromOption("minMiddleLength", 0); # ensure minMiddleLength is even minMiddleLength := minMiddleLength - (minMiddleLength mod 2); maxMiddleLength := SetConstFromOption("maxMiddleLength", 30); # ensure granularity + 2 divides maxMiddleLength - minTailLength maxMiddleLength := maxMiddleLength - (maxMiddleLength - minMiddleLength) mod (granularity + 2); GAPstarttime := Runtime(); # Each potential new relator w will be constructed as: # # w = whead * wmiddle * wtail # # with corresponding permutation representation: # # wp = head * middle * tail. # # To be a relator, such a word w must be the identity. # In particular, 1^wp = 1 i.e. 1^(head * middle) = 1^(tail^-1). # As we go, we ensure that the total number of bisyllables # (= ExponentSum(w, a)) is odd ... avoiding an explicit # perfectness test for the as. IsPresentation := function(word) # As a side-effect IsPresentation prints coset enumeration stats. local t, PrintACEStats; PrintACEStats := function(msg) Print("ACEStats", msg, ":\n index=", t.index, " cputime=", t.cputime * 10, " ms", " maxcosets=", t.maxcosets, " totcosets=", t.totcosets,"\n"); end; # First test whether the subgroup has the right index t := ACEStats([a,b], [a^2,b^orderb,word], sgens :workspace:=ACEworkspace, hard, mend, acenow, aceignoreu); PrintACEStats(""); if t.index=idx then Print("Large subgroup index OK\n"); t := ACEStats([a,b], [a^2,b^orderb,word], [b] :workspace:=2*ACEworkspace, hard, mend, acenow, aceignoreu); PrintACEStats(" for cyclic subgroup"); if t.index * orderb=orderS then Print("Cyclic subgroup index OK\n"); return true; else return false; fi; fi; return false; end; ap := gens[1]; bp := gens[2]; Print("#bisyllables in head = ", headLength, " head: ", whead, "\n"); head := MappedWord(whead, [a,b], [ap,bp]); headbExptSum := ExponentSumWord(whead, b); # Each a,b-(sub)word (be it head, middle or tail) is of form: # # e[1] e[2] e[eLength] # a b a b ... a b # # where e[i] = bexpts[ c[i] ] Nbexpts := orderb - 1; # Number of b exponents bexpts # Possible b exponents (we assume |b| is odd) # [ 1, 2, ..., |b| div 2, -(|b| div 2), ..., -2, -1 ] := Concatenation([1 .. Int(orderb/2)], [-Int(orderb/2) .. -1]); absylls := List(bexpts, i -> ap*bp^i); # feasible a,b-bisyllables Initc := function() # Initialise c c := ListWithIdenticalEntries(cLength, bexpts[1]); bExptSum := cLength; NcVectors := Nbexpts^cLength; # Number of different cs end; GetNextc := function() # Essentially, if n is a counter in base (|b| - 1), # with #c digits, then c[i] = n[i] + 1 # i.e. each digit n[i] is in the range [0 .. |b| - 2] # so that c[i] = n[i] + 1 is in the range [1 .. |b| - 1]. local i; if cCtr < NcVectors then # We only need bExptSum to be correct modulo |b| if c[1] < Nbexpts then c[1] := c[1] + 1; bExptSum := bExptSum + 1; else i := 1; while c[i] = Nbexpts do c[i] := 1; bExptSum := bExptSum + 2; # Correct modulo |b| i := i + 1; od; c[i] := c[i] + 1; bExptSum := bExptSum + 1; fi; fi; end; # Permc gives the corresponding permutation to c Permc := c -> Product(c, ci -> absylls[ci], One(ap)); # Wordc gives the corresponding a,b-word to c Wordc := c -> Product(c, ci -> a*b^bexpts[ci], One(a)); Print("Max #bisyllables in tail = ", maxTailLength, " (granularity = ", maxTailLength - minTailLength, ")\n"); # Produce all tails up to maxTailLength bisyllables and index them # according to: # # * their preimages of 1 # * their b exponent sums after multiplication by head # * their number of bisyllables # # in the following way. If tailrec = tails[i][j][k] and # # wtail = tailrec.word ... tail as an a,b-word # tail = tailrec.perm ... tail as a permutation # # then: # # i = 1^(tail^-1) # j = ExponentSumWord(whead * wtail, b) mod |b| # (except that j = |b| where the above returns 0) # ... this enables a fast perfectness check for # the b exponent sum # k = ((#bisyllables in wtail) div 2) + 1 # # We also include #bisyllables in wtail in the tailrec as # # aExpt = tailrec.aExptSum # TailLenIndex := length -> Int(length/2) + 1; tails := List([1..idx], i -> List([1..orderb], j -> List([1..TailLenIndex(maxTailLength)], k -> []))); NonZeroModOrderb := function(x) local xmodb; xmodb := x mod orderb; if xmodb = 0 then return orderb; else return xmodb; fi; end; for cLength in [minTailLength, minTailLength + 2 .. maxTailLength] do Initc(); for cCtr in [1 .. NcVectors] do tail := Permc(c); # tail as permutation Add(tails[1^(tail^-1)] [NonZeroModOrderb(headbExptSum + bExptSum)] [TailLenIndex(cLength)], rec(word := Wordc(c), perm := tail, aExptSum := cLength)); GetNextc(); od; od; UnbindList := function(list, indexlist) # Unbinds list[i] for each i in indexlist local i; for i in indexlist do Unbind(list[i]); od; end; if IsInt(Nrandom) and Nrandom > 0 then # First make Nrandom a function, if Nrandom is a nonzero constant nrandom := Nrandom; Nrandom := len -> nrandom; fi; if IsFunction(Nrandom) then # If random non-zero middles are to be chosen randomly # ... so we redefine Initc() and GetNextc() bPowers := [1 .. orderb - 1]; Randomc := function() c := List([1..cLength], i -> Random(bPowers)); bExptSum := Sum(c); end; Initc := function() NcVectors := Nrandom(cLength); Randomc(); end; GetNextc := function() if cCtr < NcVectors then Randomc(); fi; end; fi; newrels := []; # newrels is a global variable relatorExclusions # relators already checked of each length := List([1 .. headLength + maxMiddleLength + maxTailLength], i -> []); maxTailLenIndex := TailLenIndex(maxTailLength); # Now compute all middles ... and use them for cLength in [minMiddleLength, minMiddleLength + granularity + 2 .. maxMiddleLength] do Print("#bisyllables in middle = ", cLength, "\n"); Initc(); for cCtr in [1 .. NcVectors] do if cCtr mod 10000 = 0 then Print("#words tested: ", cCtr, " GAP time: ", Runtime() - GAPstarttime, " ms\n"); fi; p := head * Permc(c); # head * middle for tailrec in Flat(tails[1^p] # tails with the right preimage of 1 {Filtered([1..orderb],# s.t. #bs in w is coprime to |b| j -> Gcd(j + bExptSum, orderb) = 1 )} {[1..maxTailLenIndex]}) do if # w = p * tail is a relator (i.e. p * tail = identity) # ... first check 2 fixed - (quicker test than order) (2^p)^tailrec.perm = 2 and Order(p * tailrec.perm) = 1 then w := whead * Wordc(c) * tailrec.word; Nwbisyllables := headLength + cLength + tailrec.aExptSum; if ForAll(RelatorRepresentatives([w]), wc -> not(wc in relatorExclusions[Nwbisyllables])) then Add(relatorExclusions[Nwbisyllables], w); # Avoid testing # essentially the # same relator twice Print("Candidate relator: ",w,"\n", " #bisyllables = ", Nwbisyllables, " (#bisyllables in tail = ", tailrec.aExptSum, ")", " #words tested: ", cCtr, "\n"); Add(ALLRELS, w); if IsPresentation(w) then Print("Success! ... new relator: \n ", w, "\n"); maxTailLenIndex := TailLenIndex(tailrec.aExptSum) - 1; if maxTailLenIndex < 1 then Print("Relator found is shortest possible.\n"); return w; else Print("... continuing (there may be a shorter relator).\n"); Add(newrels, w); fi; fi; fi; fi; od; GetNextc(); od; if maxTailLenIndex < TailLenIndex(maxTailLength) then # We have found at least one new relator ... and since we have # now exhausted the middles for this iteration, we now know # the last relator found is shortest possible. w := newrels[Length(newrels)]; Print("Middles of length ", cLength, " exhausted.\n"); Print("Relator found of length ", ExponentSumWord(w, a), ", is shortest.\n"); return newrels[Length(newrels)]; fi; UnbindList(relatorExclusions, [1 .. headLength + cLength]); od; # If the alternative `Error("Success! ...' lines are used above # then newrels at this point can be non-empty ... otherwise the # only way we can get here is if we didn't succeed. if IsEmpty(newrels) then Print("Search completed! ... but no new relator found :-("); return []; else Error("Search completed! \n", "... newrels contains all new relators that work"); # A continuation from the break-loop here will effect a graceful # exit from RelatorWords. return newrels[Length(newrels)]; fi; end; F := GroupWithGenerators(Fgens); a := F.1; b := F.2; # We create an initial permutation representation . . . . . . . . . . # Since S = <Fgens | rels> is simple, the permutation representation # permS of S's action on the right cosets of a large subgroup of G is # isomorphic to S itself i.e. # # phi : S -> permS # [a, b] |-> [permSgens[1], permSgens[2]] # # is an isomorphism. Word calculations using this permutation repres- # entation are far more efficient than using a free presentation. t := CosetTableFromGensAndRels(Fgens, rels, sgens : acenow, aceignoreu); permSgens := List(t{[1,3..Length(t)-1]}, PermList); idx := Length(t[1]); if Order(permSgens[1]) <> 2 then Error(a, " (1st gen'r) should be an involution, not of order ", Order(permSgens[1]), "\n"); fi; orderb := Order(permSgens[2]); if orderb = 2 or not IsPrime(orderb) then Error("order of ", b, " (2nd gen'r) is ", orderb, " ... it should be an odd prime\n"); fi; if orderb = 3 then # we can guarantee a slightly longer head whead := SetConstFromOption("head", a*b*a*b*a/b); else whead := SetConstFromOption("head", a*b); # a*b*a/b often works fi; orderS := Order(Group(permSgens)); Print("GroupOrder=", orderS, " SubgroupIndex=", idx, "\n"); return rec(gens := Fgens, rels := [a^2, b^orderb, NewRelator(permSgens)], sgens := sgens); end; ClassesGenPairs := function(G, orderx, ordery) ## Finds generator pairs for G of orders orderx and ordery. local a, b, p, h, cla, clb, ai, bi, ra, rb, cena, cenb, gens, u, dc, j; a := AutomorphismGroup(G); p := IsomorphismPermGroup(a); b := Image(p, a); h := Image(p, InnerAutomorphismsAutomorphismGroup(a)); cla := Filtered(ConjugacyClasses(b), i -> Order(Representative(i)) = orderx and Representative(i) in h); clb := Filtered(ConjugacyClasses(b), i -> Order(Representative(i)) = ordery and Representative(i) in h); gens := []; for ai in cla do cena := Centralizer(ai); ra := Representative(ai); for bi in clb do cenb := Centralizer(bi); rb := Representative(bi); dc := List(DoubleCosetRepsAndSizes(b, cenb, cena), Representative); for j in dc do u := Subgroup(b, [ra, rb^j]); if Index(h, u)=1 then Add(gens, [ConjugatorInnerAutomorphism( PreImagesRepresentative(p, ra) ), ConjugatorInnerAutomorphism( PreImagesRepresentative(p, rb^j) ) ]); fi; od; od; od; return gens; end; # Global variables used in TranslatePresentation newF := FreeGroup("x", "y"); x := newF.1; y := newF.2; TranslatePresentation := function(Fgens, rels, sgens, newgens) ## For the *simple* quotient q = F/rels where F is a free group with two ## generators Fgens, and the subgroup of q generated by the words in Fgens ## in the list sgens and a pair of new generators newgens for q, in terms of ## Fgens, returns a record with fields gens, rels, sgens where gens = [x, y] ## represent the new generators newgens, <gens | rels> is the new ## presentation (rels is a list of words in x and y) and sgens is the list ## of subgroup words of the input sgens, but in terms of x and y. The first ## new generator newgens[1] should be an involution. ## local F, t, Permqgens, Permqnewgens, ValueInPermq, orderx, ordery, q, p, newFgens, n, nrels, Prune, CheckOrders, xwords, ywords, xywords, xyValueInPermq, Permqvalues, MakeNewWords, xyFgens, unboundi, xyList, i; if Length(Fgens) <> 2 then Error("Free group of first argument should have 2 generators"); fi; # We create an initial permutation representation . . . . . . . . . . # Since q = F/rels is a simple group, the permutation representation # Permq of q's action on the right cosets of a large subgroup of q is # isomorphic to q itself i.e. # # phi : q -> Permq # [q.1, q.2] |-> [Permqgens[1], Permqgens[2]] # # is an isomorphism. Word calculations using this permutation repres- # entation are far more efficient than using a free presentation. t := CosetTableFromGensAndRels(Fgens, rels, sgens : acenow, aceignoreu); Permqgens := List(t{[1,3..Length(t)-1]}, PermList); Permqnewgens := List(newgens, i -> MappedWord(i, Fgens, Permqgens)); # Value of a word in the generators of F in Permq ValueInPermq := w -> MappedWord(w, Fgens, Permqgens); # The group output will be on generators x and y # i.e. think of newgens[1] as x, and newgens[2] as y # (or in the Permq representation Permqnewgens[1] represents x etc.) orderx := Order(Permqnewgens[1]); if orderx <> 2 then Error("First new generator should be an involution"); fi; ordery := Order(Permqnewgens[2]); F := GroupWithGenerators(Fgens); q := F/rels; # New presentation in terms of newgens p := PresentationSubgroupMtc( q, Subgroup( q, List(newgens, w -> MappedWord(w, Fgens, GeneratorsOfGroup(q)) ) ) ); TzGoGo(p); newFgens := GeneratorsOfGroup(newF); n := FpGroupPresentation(p); nrels := Union(List(RelatorsOfFpGroup(n), w -> MappedWord(w, FreeGeneratorsOfFpGroup(n), newFgens) ), # Ensure presentation contains relators giving generator # orders List([1..2], i->newFgens[i]^Order(Permqnewgens[i])) ); # Calculate x,y-expressions xyFgens for the old generators Fgens. # We need these to rewrite sgens in terms of x and y. # This is of course hidden in the rewriting code, # but there is no proper interfacing function yet. # So we recursively generate x,y-words until we find what we want. # This could be expensive! Prune := u -> u{[1..Length(u)-1]}; CheckOrders := o -> Prune(Concatenation([1,-1], [2..o-1])); xwords := List(CheckOrders(orderx), i -> x^i); ywords := List(CheckOrders(ordery), i -> y^i); # Initialise xywords to the words in x,y of one syllable # ... the first component has words ending in an x-syllable, # the second component has words ending in a y-syllable. xywords := [xwords, ywords]; # The value of an x,y-word in Permq xyValueInPermq := w -> MappedWord(w, newFgens, Permqnewgens); # Permqvalues contains the values in Permq of all x,y-words that # have been generated. Permqvalues := List(Concatenation(xywords), w -> xyValueInPermq(w)); # Adds one extra x- or y- syllable to each x,y-word in xywords, # omitting any words that have Permqvalues we've met already. # Permqvalues is also updated. MakeNewWords := function() local NewWords, i; NewWords := function(wlist, words) return Concatenation( List(wlist, wl -> List(words, word -> wl * word)) ); end; xywords := [ NewWords(xywords[2], xwords), NewWords(xywords[1], ywords) ]; for i in [1,2] do xywords[i] := Filtered(xywords[i], w -> not(xyValueInPermq(w) in Permqvalues)); Permqvalues := Concatenation(Permqvalues, List(xywords[i], w -> xyValueInPermq(w))); od; end; xyFgens := []; unboundi := [1,2]; # The list of indices i of xyFgens for which # xyFgens[i] is unbound i.e. not known yet. repeat for i in unboundi do # See if one of our latest x,y-words represents Permqgens[i] xyList := Filtered(Concatenation(xywords), w -> xyValueInPermq(w) = Permqgens[i]); if not(IsEmpty(xyList)) then xyFgens[i] := xyList[1]; fi; od; unboundi := Filtered(unboundi, i -> not(IsBound(xyFgens[i]))); if not(IsEmpty(unboundi)) then MakeNewWords(); fi; until IsEmpty(unboundi); return rec(fgens := [x, y], rels := nrels, sgens := List(sgens, w -> MappedWord(w, Fgens, xyFgens)) ); end; F := FreeGroup("a","b"); a := F.1; b := F.2; # The presentations below have been obtained from: # [CCN85] J.H. Conway et al, `Atlas of Finite Groups' # [CMY79] John J. Cannon, John McKay, Kiang-chuen Young, # `The non-abelian Simple groups G, |G| < 10^5', # Comm. Alg. 7(13), 1397-1406 (1979). # [CR84] Colin M. Campbell and Edmund F. Robertson, # `Presentations for the Simple groups G, 10^5 < |G| < 10^6', # Comm. Alg. 12(21), 2643-2663 (1984). # [Bray] John Bray's web site: http://www.cix.co.uk/~vicarage/ L2_8 := rec( source := "[CCN85, p6]", rels := [a^7, (a^2*b)^3, (a^3*b)^2, (a*b^5)^2], sgens := [a] ); L2_16 := rec( source := "[CCN85, p12]", rels := [a^15, (a^2*b)^3, (a^3*b)^2, (a*b^9)^2, (a^8*b^2)^2, b^17 ], sgens := [a] ); L3_3s := [# L_3(3), 1 rec( source := "[CMY79, 5.1]", rels := [a^2, b^3, (a*b)^13, ((a*b)^4*a*b^-1)^2*(a*b)^2*(a*b^-1)^2* (a*b)*(a*b^-1)^2*(a*b)^2*a*b^-1], sgens := [a^(b*a), b] ), # L_3(3), 2 rec( source := "[CMY79, 5.2]", rels := [a^2, b^3, (a*b)^13, (Comm(a,b))^6, ((a*b)^2*(a*b^-1)^2)^3], sgens := [a^(b*a), b^(a*b)] ), # L_3(3), 3 rec( source := "[CCN85, p13]", rels := [a^6, b^3, (a*b)^4, (a^2*b)^4, (a^3*b)^3, Comm(a^2,(b*a^2*b)^2)], sgens := [a] ) ]; U3_3s := [# U_3(3), 1 rec( source := "[CMY79, 6.1]", rels := [a^2, b^6, (a*b)^7, (a*b^2)^3*(a*b^-2)^3, (a*b*a*b^-2)^3*a*b*(a*b^-1)^2], sgens := [a^b, a*b*a*b*a*b^-2] ), # U_3(3), 2 rec( source := "[CMY79, 6.2]", rels := [a^2, b^6, (a*b)^8, (Comm(a,b))^4, (a*b^3)^3, (a*b^2)^3*(a*b^-2)^3, ((a*b)^2*a*b^2)^3], sgens := [a, a^b*b] ) ]; M11 := rec( source := "[CMY79, 7.1]", rels := [a^2, b^4, (a*b)^11, (a*b^2)^6, (a*b)^2*(a*b^-1)^2*a*b*a*b^-1*a*b^2*a*b*a*b^-1], sgens := [a, b^((a*b)^2)] ); M12 := rec( source := "[Bray, M=C2]", rels := [a^2, b^3, (a*b)^11, (Comm(a,b))^6, (a*b)^8*(a*b^-1)^2*(a*b*a*b^-1)^4*a*b^-1, (a*b*a*b*a*b^-1)^6], sgens := [a, b*a*b*a*b*a*b^-1] ); L2_32 := rec( source := "[CCN85, p29]", rels := [a^31, (a^2*b)^3, (a^3*b)^2, (a*b^6)^2, (a^2*b^4*a^4*b^5)^2, (a^2*b^5*a^4*b^4)^2 ], sgens := [a] ); U3_4s := [# U_3(4), 1 rec( source := "[CMY79, 12.1]", rels := [a^2, b^3, (a*b)^13, a*b*(a*b^-1)^2*(a*b)^2*a*b^-1*a*b*(a*b^-1)^4* a*b*a*b^-1*(a*b)^4*a*b^-1], sgens := [(a*b)^5*a, (a*b)^2*a*b^-1*a*b*(a*b^-1)^2*a, (a*b*(a*b^-1)^2)^2, a*b*a*b^2*(a*b)^2*(a*b^-1)^2*a*b] ), # U_3(4), 2 rec( source := "[CMY79, 12.2]", rels := [a^2, b^3, (a*b)^15, (Comm(a,b))^5, ((a*b)^3*(a*b^-1)^3)^3, (a*b^-1*(a*b)^5)^4], sgens := [a*b*a*b^2*a*b^-1*a*b*a, b*a*b*(a*b^-1)^3*a*b]) ]; J1s := [#J1, 1 rec( source := "[CR84, 15.1]", rels := [a^2, b^3, (a*b)^7, (Comm(a,b))^10, (Comm(a, b^-1*(a*b)^2))^6], sgens := [a, b^(a*b*(a*b^-1)^2)] ), #J1, 2 rec( source := "[CR84, 15.3]", rels := [a^2, b^3, (a*b)^7, ((a*b)^2*a*b^-1)^11, (Comm(a,b*(a*b^-1)^2))^5], sgens := [a, b^(a*b^-1)] ), #J1, 3 rec( source := "[CR84, 15.5]", rels := [a^2, b^3, (a*b)^7, (Comm(a,b))^15, (Comm(a,b^-1*(a*b)^2))^5, ((a*b*a*b^-1)^2*a*b)^6], sgens := [a, b^((a*b^-1*a*b)^2*a*b^-1)] ), #J1, 4 rec( source := "[CR84, 15.7]", rels := [a^2, b^3, (a*b)^7, ((a*b*a*b^-1)^3*a*b)^5, ((a*b*a*b^-1)^3*(a*b^-1*a*b)^3)^3], sgens := [a, b^((a*b^-1*a*b)^2*a*b^-1*(a*b)^2)] ), #J1, 5 rec( source := "[CR84, 15.8]", rels := [a^2, b^3, (a*b)^10, (Comm(a, b^-1*a*b^-1*(a*b)^3))^2, ((a*b)^3*(a*b*a*b^-1)^2*(a*b)^2*(a*b^-1)^2)^3], sgens := [a, b^((a*b^-1)^3)] ), #J1, 6 rec( source := "[CR84, 15.10]", rels := [a^2, b^3, (a*b)^10, ((a*b)^2*a*b^-1)^7, (Comm(a, b*a*b^-1*(a*b)^3))^2], sgens := [a, b^(a*b^-1*a*b*(a*b^-1)^2)] ), #J1, 7 rec( source := "[CR84, 15.12]", rels := [a^2, b^3, (a*b)^10, (Comm(a, b*a*b*(a*b^-1)^3))^2, ((a*b)^4*a*b^-1*a*b*(a*b*a*b^-1)^2)^3], sgens := [a, b^(a*b^-1*a*b*a*b^-1)] ), #J1, 8 rec( source := "[CR84, 15.14]", rels := [a^2, b^3, (a*b)^10, ((a*b)^2*a*b^-1)^5, ((a*b)^2*(a*b*a*b^-1)^2*(a*b)^2*(a*b^-1)^3)^3], sgens := [a, b^(a*b*(a*b^-1)^2*(a*b)^2)] ), #J1, 9 rec( source := "[CR84, 15.15]", rels := [a^2, b^3, (a*b)^10, ((a*b)^3*(a*b^-1)^2)^5, ((a*b)^2*(a*b*a*b^-1)^2*(a*b)^2*(a*b^-1)^3)^3], sgens := [a, b^(a*b*(a*b^-1)^2*(a*b)^2)] ), #J1, 10 rec( source := "[CR84, 15.16]", rels := [a^2, b^3, (a*b)^11, ((a*b)^2*(a*b^-1)^2)^5, ((a*b)^4*(a*b^-1)^3*(a*b)^2*(a*b^-1)^4)^2], sgens := [a, b^(a*b^-1*a*b*(a*b^-1)^2*a*b)] ), #J1, 11 rec( source := "[CR84, 15.18]", rels := [a^2, b^3, (a*b)^11, ((a*b)^2*a*b^-1)^6, ((a*b)^4*(a*b^-1)^3)^3], sgens := [a, b^((a*b^-1)^2*(a*b)^2)] ), #J1, 12 rec( source := "[CR84, 15.19]", rels := [a^2, b^3, (a*b)^15, (Comm(a,b))^5, ((a*b)^4*(a*b^-1)^2)^5, ((a*b)^2*((a*b^2)*(a*b^-1)^2)^2)^3], sgens := [a, b^((a*b^-1)^3*(a*b)^2)] ), #J1, 13 rec( source := "[CR84, 15.20]", rels := [a^2, b^3, (Comm(a,b))^6, ((a*b)^2*a*b^-1)^7, (Comm(a, b^-1*(a*b)^3))^2], sgens := [a, b^(a*b*(a*b^-1)^4)] ), #J1, 14 rec( source := "[CR84, 15.22]", rels := [a^2, b^3, (a*b)^15, (Comm(a, b*a*b))^5, ((a*b)^5*(a*b^-1*a*b*a*b^-1)^2*a*b^-1)^2, ((a*b)^3*((a*b)^2*a*b^-1)^2*(a*b^-1*a*b)^2)^2], sgens := [a, b^(a*b^-1)] ), #J1, 15 rec( source := "[CR84, 15.24]", rels := [a^2, b^3, (a*b)^15, (Comm(a, b*a*b))^5, ((a*b)^2*a*b^-1)^6, ((a*b)^5*a*b^-1)^7, (Comm(a, (b*a)^2*(b^-1*a)^3*b))^2], sgens := [a, b^((a*b)^3*a*b^-1)] ), #J1, 16 rec( source := "[CR84, 15.26]", rels := [a^2, b^3, (a*b)^15, (Comm(a, b*a*b))^3, ((a*b)^4*(a*b^-1)^2)^5, ((a*b)^4*(a*b^-1*a*b)^2*(a*b^-1)^2*a*b*(a*b^-1)^3)^2], sgens := [a, b^(a*b)] ), #J1, 17 rec( source := "[CR84, 15.27]", rels := [a^2, b^3, (a*b)^19, ((a*b)^3*(a*b^-1*a*b)^4)^2, (((a*b)^4*a*b^-1)^2*a*b^-1)^2], sgens := [a, b^(a*b^-1*(a*b)^4)] ), #J1, 18 rec( source := "[CR84, 15.28]", rels := [a^2, b^3, (a*b)^19, ((a*b)^2*(a*b*a*b^-1)^2)^2, (((a*b)^4*a*b^-1)^2*a*b^-1)^3], sgens := [a, b^((a*b)^2)] ), #J1, 19 rec( source := "[CR84, 15.29]", rels := [a^2, b^3, (a*b)^19, ((a*b)^2*a*b^-1)^6, ((a*b)^3*a*b^-1)^6, (Comm(a, (b*a)^4*b^-1*a*b))^2, ((a*b)^4*a*b^-1*a*b*(a*b^-1)^3*(a*b)^2*a*b^-1)^2], sgens := [a, b^((a*b^-1*a*b)^2*a*b^-1*(a*b)^2)] ), #J1, 20 rec( source := "[CR84, 15.31]", rels := [a^2, b^3, (a*b)^19, (Comm(a, b*(a*b)^2))^3, ((a*b)^5*((a*b)^2*a*b^-1)^2)^2], sgens := [a, b^(a*b*a*b^-1*(a*b)^2)] ), #J1, 21 rec( source := "[CR84, 15.32]", rels := [a^2, b^3, (a*b)^19, (Comm(a, b*a*b))^3, ((a*b)^3*(a*b*a*b^-1)^2)^3], sgens := [a, b^((a*b)^5)] ) ]; L3_5s := [# L_3(5), 1 rec( source := "[CR84, 17.1]", rels := [a^2, b^3, (a*b)^24, Comm(a,b)^6, ((a*b)^6*(a/b)^2)^3, ((a*b)^3*(a*b*a/b)^2)^5, ((a*b)^5*(a/b*a*b)^2*(a*b)^2*(a*b*a/b)^2)^2], sgens := [a, (b*a*b)^(a*b)] ), # L_3(5), 2 rec( source := "[CR84, 17.2]", rels := [a^2, b^3, (a*b)^24, Comm(a,b)^10, Comm(a,b*a*b)^3, Comm(a,b*(a*b)^2)^4, ((a*b*a/b)^3*a*b)^5,((a*b)^2*((a*b)^2*a/b)^2)^3], sgens := [a, (b*a*b)^(a*b*a/b)] ), # L_3(5), 3 rec( source := "[CR84, 17.3]", rels := [a^2, b^3, (a*b)^31, Comm(a,b)^4, ((a*b)^4*a/b)^4, Comm(a,b*(a*b)^4)^3], sgens := [a, (b^-1*a)^3*b*(a*b*a/b)^2] ), # L_3(5), 4 rec( source := "[CR84, 17.4]", rels := [a^2, b^3, (a*b)^31, Comm(a,b)^5, ((a*b)^5*(a/b)^4)^2, ((a*b)^6*(a/b)^2)^3], sgens := [a^b, (b*a)^3/b*a] ), # L_3(5), 5 rec( source := "[CR84, 17.5]", rels := [a^2, b^3, (a*b)^31, Comm(a,b)^6, Comm(a,b*(a*b)^2)^3, Comm(a,b*(a*b)^3)^3, ((a*b)^3*(a*b*a/b)^2)^3], sgens := [a, b*a/b*a*b*a*b] ), # L_3(5), 6 rec( source := "[CR84, 17.6]", rels := [a^2, b^3, (a*b)^31, (a*b)^9*a/b*a*b*((a/b)^3*a*b)^3*a/b, (a*b)^4*(a*b*a/b)^2*(a*b)^5*(a/b)^4* (a*b*a/b)^2*(a/b)^3], sgens := [a^(b*a), b*a*(a^(b*a*b))] ), # L_3(5), 7 rec( source := "[CR84, 17.7]", rels := [a^2, b^3, (a*b)^31, Comm(a,b*a*b)^4, Comm(a,b^-1*(a*b)^2)^6, ((a*b)^5*(a/b)^2)^3, ((a*b)^3*(a/b)^2)^5], sgens := [a*b*a/b, b^-1*(a*b)^5*a/b*(a*b)^3] ) ]; PSp4_4s := [#PSp(4,4), 1 rec( source := "[CR84, 20.1]", rels := [a^2, b^5, Comm(a,b)^5, (a*b^2)^17, Comm(a,b^2)^2, ((a*b)^2*a/b^2)^4], sgens := [b*(b*a)^3/b*a, (a/b*a*b)^2*b] ), #PSp(4,4), 2 rec( source := "[CR84, 20.2]", rels := [a^2, b^5, (a*b)^17, Comm(a,b)^2, Comm(a,b^2)^5, (a*b*(a*b^2)^2)^4, Comm(a,b^2*a*b*a*b^2)^2], sgens := [a*b^2*(a*b)^3, (b^2*a)^5*b] ), #PSp(4,4), 3 rec( source := "[CR84, 20.3]", rels := [a^2, b^5, (a*b)^17, Comm(a,b)^5, Comm(a,b*a*b)^3, Comm(a,(b*a)^2/b)^2, Comm(b^-1*a*b,(b*a)^2)^2], sgens := [b^2*(a*b)^4*b, a/b*(a*b^2*a*b^-2)^2] ), #PSp(4,4), 4 rec( source := "[CR84, 20.4]", rels := [a^2, b^4, Comm(a,b)^4, (a*b)^15, (a*b*(a*b^2)^4*a*b^-1*(a*b^2)^2)^2, (a*b)^2*(a*b^2)^4*(a*b^-1)^2*(a*b^2)^2* a*b*a*b^2*a*b^-1*(a*b^2)^2], sgens := [a*b^2, a^(b^-1*a*b^-1*a*b)*a*b] ), #PSp(4,4), 5 rec( source := "[CR84, 20.6]", rels := [a^2, b^4, (a*b)^15, ((a*b*(a*b^2)^2)^2*b)^2, ((a*b*a*b^-1*a*b)^2*b)^2, ((a*b*a*b^2*a*b)^2*b*a*b^-1)^3, ((a*b*a*b^-1)^2*(a*b^2)^2*a*b^-1*(a*b^2)^2)^2, ((a*b*a*b^2)^2*(a*b^2*a*b^-1)^2*a*b^-1)^2, ((a*b)^4*b*a*b*a*b^-1*a*b^2*(a*b)^2*a*b^-1)^2], sgens := [a*b, b^(a*b*a*b^-1)*a*b^-1] ), #PSp(4,4), 6 rec( source := "[CR84, 20.8]", rels := [a^2, b^4, (a*b)^15, ((a*b)^2*(a*b*(a*b^2)^2)^2)^2, ((a*b)^2*(a*b^-1*a*b^2)^2*a*b^2)^3, ((a*b)^3*b)^4, (((a*b)^4*b)^2*a*b^2)^2, ((a*b*a*b^-1)^2*a*b^-1*a*b^2*(a*b^-1)^2)^2], sgens := [a*b, (b*a*b^2*a)^2*b^(a*b^-1)] ), #PSp(4,4), 7 rec( source := "[CR84, 20.9]", rels := [a^2, b^4, (a*b)^15, (((a*b)^3*b)^2*a*b^-1)^2, ((a*b)^2*(a*b^-1)^2*b^-1)^5, ((a*b*a*b^2*(a*b^-1)^2)^2*b^-1)^2, ((a*b)^2*a*b^-1*a*b*a*b^2*a*b^-1*a*b^2)^2], sgens := [a*b, a^(b^2)*(a*b^-1)^3] ), #PSp(4,4), 8 rec( source := "[CR84, 20.11]", rels := [a^2, b^4, Comm(a,b)^4, (a*b)^17, ((a*b)^2*(a*b^2)^2*a*b^-1)^3, (a*b*(a*b^2*(a*b)^2*a*b^-1)^2)^2, ((a*b)^6*b*(a*b^-1)^2*a*b*a*b^2)^2, ((a*b)^2*a*b^-1*a*b*a*b^2*a*b*(a*b^2)^3)^2], sgens := [a*b^2*a*b^-1, (b^2*a)^3*b^(a*b^-1)] ), #PSp(4,4), 9 rec( source := "[CR84, 20.13]", rels := [a^2, b^4, (a*b)^17, (a*b*(a*b^2)^3*a*b^-1)^3, ((a*b^-1*a*b)^2*(a*b*a*b^-1)^2*b^-1*a*b^2)^2, Comm(a,b)^6, ((a*b^2)^3*(a*b)^3*a*b^-1*a*b)^2, (a*b)^3*((a*b)^3*(b*a)^2*b^-1)^2*(a*b^-1)^2], sgens := [a*b^2*a*b*a*b, (b^2*a)^3*a^(b*a*b)] ), #PSp(4,4), 10 rec( source := "[CR84, 20.15]", rels := [a^2, b^4, (a*b)^17, ((a*b)^2*a*b^-1)^4, (a*b*a*b^2*a*b^-1)^5, (a*b*(a*b^-1)^2*(a*b^2)^2*a*b^-1)^2, (a*b*a*b^-1*(a*b^2)^3*a*b^-1*(a*b^2)^2)^2], sgens := [a*b^2*a*b^-1, (a*b^2)^4*a*b] ), #PSp(4,4), 11 rec( source := "[CR84, 20.17]", rels := [a^2, b^4, (a*b)^17, Comm(a,(b*a*b)^2)^2, ((a*b*a*b^-1)^2*a*b^2)^5, (a*b*(a*b^2)^2*a*b^-1*(a*b^2)^2*a*b*a*b^-1)^2, ((a*b)^3*b*a*b*a*b^-1*a*b*(a*b^2)^2*a*b^-1)^2], sgens := [a*b*a*b^-1, (b^2*a)^2*b*a] ), #PSp(4,4), 12 rec( source := "[CR84, 20.18]", rels := [a^2, b^4, (a*b)^17, ((a*b)^2*(a*b^-1*a*b^2)^2*a*b*a*b^2)^2, (a*b*(a*b^2)^2)^4, ((a*b)^2*b)^6, ((a*b)^4*(b*a)^2*b^-1*(a*b)^2*b)^2, (a*b*((a*b)^2*b)^2*a*b*a*b^-1*a*b^2)^3], sgens := [(a*b)^2*a*b^-1, a*b^2] ), #PSp(4,4), 13 rec( source := "[CR84, 20.19]", rels := [a^2, b^4, (a*b)^5, Comm(b,(a*b^2)^4*a)^2, (a*b*a*b^2*a*b^-1*(a*b^2)^4)^3, (a*b^-1*a*b^2*a*b*(a*b^2)^4)^3, (a*b^-1*(a*b^2)^2*a*b*a*b^-1*a*b*(a*b^2)^2)^3], sgens := [(a*b^2*a*b)^2*b^2, a*b^-1*a*(b^2*a)^3*b*a*b^-1] ), #PSp(4,4), 14 rec( source := "[CR84, 20.20]", rels := [a^2, b^4, (a*b)^15, Comm(a,b)^5, (a*b^2)^15, ((a*b)^2*(a*b^-1)^2*a*b^2)^2, ((a*b)^2*a*b^-1*a*b*a*b^2)^4, ((a*b)^4*a*b^2*a*b^-1*(a*b^2)^3)^2, (a*b)^4*(b*a*b*a*b^-1*a*b^2)^2*(a*b)^3* b*a*b^2*(a*b^-1*a*b)^2], sgens := [a*b^2, (b*a*b^2*a*b*a)^2*b^-1] ), #PSp(4,4), 15 rec( source := "[CR84, 20.22]", rels := [a^2, b^4, (a*b)^15, (a*b^2)^6, ((a*b)^3*b)^4, Comm(a,b*(a*b)^2)^2, ((a*b)^3*(b*a)^2*b^-1*(a*b^2)^2)^3], sgens := [a*b*a*b^-1, a*b^2*(a*b)^5] ), #PSp(4,4), 16 rec( source := "[CR84, 20.23]", rels := [a^2, b^4, (a*b)^15, (a*b^2)^6, ((a*b)^2*a*b^-1)^4, (a*b*(a*b^2)^2)^4, Comm(a,(b*a*b)^2)^2, ((a*b*a*b^-1)^2*a*b^2*a*b^-1*a*b)^3], sgens := [a*b, (b^2*a*b^-1*a)^2*b^2] ), #PSp(4,4), 17 rec( source := "[CR84, 20.24]", rels := [a^2, b^4, (a*b)^15, (a*b^2)^5, Comm(a,b*a*b)^4, ((a*b)^4*(b*a)^2*b^-1*a*b^2)^2], sgens := [(a*b)^3*a*b^-1, (b^2*a)^2*b*a*b^-1] ), #PSp(4,4), 18 rec( source := "[CR84, 20.26]", rels := [a^2, b^4, (a*b)^15, Comm(a,b)^17, (a*b^2)^10, (a*b*(a*b^2)^2*(a*b^-1*a*b)^2*b)^3, ((a*b)^2*a*b^2)^2*(a*b)^3*(a*b^-1*a*b)^3, (a*b*(a*b^2)^3*a*b*a*b^-1*a*b^2*a*b^-1)^2], sgens := [a*b, a^(b^2)] ), #PSp(4,4), 19 rec( source := "[CR84, 20.27]", rels := [a^2, b^4, (a*b)^17, (a*b^2)^10, ((a*b)^4*b)^4, ((a*b)^2*(b*a)^2*b^-1)^2, ((a*b)^2*(a*b^2)^3*(a*b^-1)^3)^3], sgens := [(a*b)^2*a*b^-1, b*(a*b^2)^4] ), #PSp(4,4), 20 rec( source := "[CR84, 20.28]", rels := [a^2, b^4, (a*b)^17, (((a*b)^2*a*b^2)^2*(a*b^2)^2)^2, ((a*b)^2*a*b^2*(a*b^-1)^2)^3, (a*b^2)^10, ((a*b^-1*a*b)^3*(b^2*a)^2*b^-1)^2, ((a*b^-1*a*b^2)^3*b^-1*a*b^2*a*b)^2], sgens := [a*b*a*b^-1*a*b*a*b*a*b^-1, a*b^2*a*b] ), #PSp(4,4), 21 rec( source := "[CR84, 20.29]", rels := [a^2, b^4, (a*b)^17, (a*b*(a*b^2)^3*a*b^-1)^3, (a*b*(a*b^2)^4*a*b*a*b^-1*(a*b^2)^2)^2, a*b*(a*b^2)^3*(a*b*a*b^-1)^2*(a*b^2)^3* a*b^-1*(a*b^2)^3], sgens := [a*b*a*b^-1, b^-1*(a*b)^3*b*a*b^-1] ), #PSp(4,4), 22 rec( source := "[CR84, 20.31]", rels := [a^2, b^4, (a*b)^17, (a*b*a*b^-1*a*b^2)^3, ((a*b)^3*b*a*b*(a*b^-1)^2*(a*b^2)^3)^2, ((a*b)^3*b*a*b*a*b^-1*(a*b*a*b^2)^2)^2, (a*b)^2*a*b^-1*(a*b^2)^5*a*b*(a*b^-1)^2* a*b^2*a*b^-1*a*b*a*b^2], sgens := [a*b^2, a*b*a*b^-1*a*b*a*b] ) ]; presentations := rec( L2_8 := L2_8, L2_16 := L2_16, L3_3s := L3_3s, U3_3s := U3_3s, M11 := M11, M12 := M12, L2_32 := L2_32, U3_4s := U3_4s, J1s := J1s, L3_5s := L3_5s, PSp4_4s := PSp4_4s ); IsACEResExampleOK := function() ## does a number of integrity checks and tries to give an accurate diagnosis ## if something is wrong. local head, grp, n, newgens, ok, saved, IsFunctionsOK, IsGensOK, IsGroupOK, IsNewgensOK, IsnOK; head := ValueOption("head"); grp := ValueOption("grp"); n := ValueOption("n"); newgens := ValueOption("newgens"); saved := ACEResExample; IsFunctionsOK := function() return IsBound(PGRelFind) and IsFunction(PGRelFind) and IsBound(TranslatePresentation) and IsFunction(TranslatePresentation); end; IsGensOK := function(u, v) return (FamilyObj(u) = FamilyObj(v)) and IsAssocWordWithInverse(u) and ForAll([u, v], g -> (NumberSyllables(g) = 1) and (ExponentSyllable(g, 1) = 1)); end; IsGroupOK := function() return (grp <> fail) and IsBound(presentations) and IsRecord(presentations) and (grp in RecNames(presentations)); end; IsnOK := function() return (grp[Length(grp)] <> 's') or (IsPosInt(n) and (n <= Length( presentations.(grp) ))); end; IsNewgensOK := function() return IsBound(a) and IsBound(b) and IsGensOK(a, b) and (newgens = fail or (IsList(newgens) and (Length(newgens) = 2) and (ForAll(newgens, w -> FamilyObj(w) = FamilyObj(a))))); end; ok := false; if ACEResExample.filename = "doGrp.g" and not IsFunctionsOK() then Print("Error, ACEReadResearchExample: functions not initialised.\n", "Please type: 'ACEReadResearchExample();'\n", "and try again.\n"); elif ACEResExample.filename = "doGrp.g" and not(IsGroupOK() and IsnOK() and IsNewgensOK()) then ACEResExample.reread := true; LoadPackage("ace", "3.0"); ACEReadResearchExample("pgrelfind.g"); ACEResExample := saved; Unbind(ACEResExample.reread); Print("Error, ", "`grp' (and maybe `n' and/or `newgens') options must have values.\n", "Usage: ACEReadResearchExample(\"doGrp.g\"\n", " : grp := <grp>,\n", " [n := <int>,]\n", " [newgens := [<w1>, <w2>]]\n", " [, opt := <val> ...]);\n", "where <grp> must be a string in the following list:\n", RecNames(presentations),"\n", "and <w1>, <w2> must be words in `a' and `b'.\n"); elif head <> fail and not(IsBound(x) and IsBound(y) and IsGensOK(x, y)) then Print("Error, `x' and `y' do not have correct values.\n", "Please type: 'ACEReadResearchExample();'\n", "to (re-)initialise `x' and `y' and try your call of\n", "'ACEReadResearchExample(", ACEResExample.filename, ");' again.\n"); else ok := true; fi; if ok then if ACEResExample.filename = "doGrp.g" then if grp[ Length(grp) ] = 's' then ACEResExample.grp := presentations.(grp)[n]; else ACEResExample.grp := presentations.(grp); fi; ACEResExample.newgens := newgens; elif not(IsFunctionsOK() and IsBound(a) and IsBound(b) and IsGensOK(a, b)) then ACEResExample.reread := true; LoadPackage("ace", "3.0"); ACEReadResearchExample("pgrelfind.g"); ACEResExample := saved; Unbind(ACEResExample.reread); fi; fi; return ok; end; ## End if not(IsBound(ACEResExample.reread) and ACEResExample.reread) then for s in ["The following are now defined:", "", "Functions:", " PGRelFind, ClassesGenPairs, TranslatePresentation,", " IsACEResExampleOK", "Variables:", " ACEResExample, ALLRELS, newrels, F, a, b, newF, x, y,", " L2_8, L2_16, L3_3s, U3_3s, M11, M12, L2_32,", " U3_4s, J1s, L3_5s, PSp4_4s, presentations", "", "Also:", "", "TCENUM = ACETCENUM (Todd-Coxeter Enumerator is now ACE)", "", "For an example of their application, you might like to try:", "gap> ACEReadResearchExample(\"doL28.g\" : optex := [1,2,4,5,8]);", "(the output is 65 lines followed by a 'gap> ' prompt)", "", "For information type: ?Using ACEReadResearchExample" ] do Info(InfoACE, 1, s); od; fi; #E pgrelfind.g . . . . . . . . . . . . . . . . . . . . . . . . . . ends here