This file contains the mails sent to the GAP forum in October-December 1994.

Name                Email address                           Mails   Lines
Martin Schoenert    Martin.Schoenert@Math.RWTH-Aachen.DE        7     647
James McCarron      jmccarro@barrow.uwaterloo.ca                5     290
Derek Holt          dfh@maths.warwick.ac.uk                     2     190
Alexander Hulpke    Alexander.Hulpke@Math.RWTH-Aachen.DE        2     161
Joachim Neubueser   Joachim.Neubueser@Math.RWTH-Aachen.DE       2      98
Harald Boegeholz    hwblist@machnix.mathematik.uni-stuttgart.de 2      97
Thomas Breuer       Thomas.Breuer@Math.RWTH-Aachen.DE           2      80
Steve Linton        sal@cs.st-andrews.ac.uk                     2      73
Jim Howie           jim@cara.maths.heriot-watt.ac.uk            2      47
Frank Celler        Frank.Celler@Math.RWTH-Aachen.DE            1     119
BURKHARD HOEFLING   hoefling@mat.mathematik.uni-mainz.de        1     101
Dima Pasechnik      pasec@can.nl                                1      26
Paulo Ney de Souza  desouza@math.berkeley.edu                   1      26
John Neil           neil@alamo.mth.pdx.edu                      1      16
M.F.(Mike) Newman   mike.newman@maths.anu.edu.au                1      16
Peter Mueller       mueller@mi.uni-erlangen.de                  1      15
Johannes Mueller    mueller@leon.informatik.uni-bonn.de         1      13
Chris Charnes       charnes@osiris.cs.uow.edu.au                1      11
Jacob Hirbawi       jcbhrb@cerf.net                             1       8
Daniel Ruberman     ruberman@maths.ox.ac.uk                     1       6
Geoff Smith         gcs@maths.bath.ac.uk                        1       6

This  file is in Berkeley mail drop format, which means you can read this
file with 'mail -f <name-of-the-file>'  or 'mailx -f <name-of-the-file>'.
It is also possible however to read this file with any text editor.



From neil@alamo.mth.pdx.edu Fri Sep 30 16:19:00 1994
Date:         Fri, 30 Sep 94 16:19:00 -0700
From:         "John R. Neil" <neil@alamo.mth.pdx.edu>
Subject:      US FTP site change

	Due to a hardware failure, we have been forced to move our
anonymous FTP site to a different machine.  This includes our mirror of
the GAP archives.  This change is permanent.  The old address of
<dehn.mth.pdx.edu> has been replaced with <alamo.mth.pdx.edu>.  Any
attempt to FTP to dehn will result in failure as this machine is currently
turned off.  Hopefully this change can also be made in the GAP
documentation.  The directory structure remains identical.  Any questions
regarding this matter should be sent directly to me. 

--John

John Neil                                        e-mail:  neil@math.mth.pdx.edu
Mathematics Department UNIX SysAdmin and Maple Tech. Rep.
Portland State University, Portland, Oregon
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=



From dfh@maths.warwick.ac.uk Fri Sep 30 19:21:00 1994
Date:         Fri, 30 Sep 94 19:21:00 -0700
From:         "Derek Holt" <dfh@maths.warwick.ac.uk>
Subject:      GAP computation

Dear GAP-FORUM,

This is a description of a calculation of a subgroup presentation using GAP,
which I carried out initially, and then communicated to Volkmar Felsch,
who was able to find a much quicker method of completing the final step.
The index of the subgroup in question in the original problem was
244823040 (= order of the Mathieu group M24), which is really quite large
for this sort of calculation, but in fact part of the argument is
theoretical (since the subgroup turns out to be a free group).

Derek Holt.



The problem initially came from Peter Rowley. He had an epimorphism of a
certain finitely presented group onto M24, and wanted to know whether the
kernel was free, and what its rank was. 

The presentation is:

F := FreeGroup(4);
F.relators := [ F.1^2,  F.2^2,  F.3^2,  F.4^2,
      (F.2*F.3)^4,  (F.1*F.3)^3,  (F.2*F.4)^3,
      (F.3*F.1)*F.2*F.3*F.2*F.3*(F.1*F.3)*F.2,
      (F.2*F.4)*F.2*F.3*F.2*F.3*(F.4*F.2)*F.3
];

and the images of the generators in the map onto M24, are a,b,c,d,
defined as follows.

a:=(1,2)(3,5)(4,9)(6,10)(7,13)(8,15)(11,14)(12,21)(16,24)(17,19)(18,20)(22,23);
b:=(1,3)(2,5)(4,10)(6,9)(7,14)(8,16)(11,13)(12,18)(15,24)(17,23)(19,22)(20,21);
c:=(1,2)(3,7)(4,6)(5,11)(8,15)(9,17)(10,19)(12,20)(13,14)(16,21)(18,24)(22,23);
d:=(1,4)(2,6)(3,8)(5,12)(7,15)(9,18)(10,16)(11,20)(13,22)(14,23)(17,24)(19,21);

The first step was to find the inverse image  G  of the point-stabiliser M23
under this mapping, and to get a presentation of G. Since the index is only
24, that was straightforward, and I will omit details.
G turned out to be a free product of 3 cyclic groups of order 3.
(I think that Peter Rowley knew that already.)
Here is the presentation of G, and the images px,py,pz of the epimorphism of
G onto P = M23.

G:=FreeGroup("x","y","z");
x:=G.1;; y:=G.2;; z:=G.3;
G.relators:=[x^3,y^3,z^3];

px:=( 1,20,21)( 3,13,11)( 4,10,17)( 5,14, 7)( 6, 9,19)(12,18,16);
py:=( 1,16,14)( 3,10, 9)( 4, 8,20)( 6,12,15)( 7,17,19)(13,21,18);
pz:=( 1,17,18)( 2, 4, 6)( 3,15, 8)( 5,20,12)(13,23,22)(16,21,19);
P:=Group(px,py,pz);

Now the Kurosh Subgroup Theorem for free products states that any subgroup
of a free product is isomorphic to a free product of conjugates of the
free factors of the original group and a free group. Since the free factors
of  G  do not lie in the kernel of the map onto M23, none of their conjugates
can lie in the kernel, and so it follows immediately from the Kurosh Theorem
that this kernel must be free.
However, I know of no theoretical results which will tell us what the rank of
this kernel is. Does anyone know any more about results in this area?
It turned out eventually that the rank of the kernel was |M23| + 1,
so there must surely be some theoretical reason for this.

Now, assuming that the kernel really is free, it follows easily that the
inverse image in G of any subgroup of P with order not divisible by 3 must
also be free. The largest such subgroup is a normaliser of a Sylow
23-subgroup, and has order 253. The GAP calculation continues as follows.

S23:=SylowSubgroup(P,23);
N23:=Normalizer(P,S23); # N23 has order 253 and index 40320 in P.
         #It was chosen because it appears to be the largest 3'-subgroup of  P.

RC:=RightCosets(P,N23);
Q:=Operation(P,RC,OnRight);
QG:=Q.generators;    # QG is the permutation representation of P on the
		     # right cosets of N23. We want a presentation of
	  	     # the inverse image of N23 in G. To do this, we
		     # need to calculate the coset table of this inverse
	             # image. This consists of the permutations and their
		     # inverses converted into lists.
CT:=[];
CT[1]:=ListPerm(QG[1]);
CT[2]:=ListPerm(QG[1]^-1);
CT[3]:=ListPerm(QG[2]);   
CT[4]:=ListPerm(QG[2]^-1);
CT[5]:=ListPerm(QG[3]);   
CT[6]:=ListPerm(QG[3]^-1);

HP:=PresentationSubgroup(G,CT,"h");

#Answer was (after a few hours runtime):
  # presentation with 53696 gens and 13375 rels of total length 40125

In fact, it turned out that each relator had length 3 and expressed one
generator as a product of two others, so the group itself is free of rank
53696 - 13375 = 40321.
In GAP, I first tried

SimplifyPresentation(HP);;
# Interrupted (after 58 hours total running time) - output so far:
  #I  there are 53596 generators and 13275 relators of total length 39825
  #I  there are 53496 generators and 13175 relators of total length 39525
  #I  there are 53396 generators and 13075 relators of total length 39225
  #I  there are 53296 generators and 12975 relators of total length 38925
  #I  there are 53196 generators and 12875 relators of total length 38625

#After interruption, there were 53128 generators remaining.
#At this rate, we will have a very long wait!

I then decided it would be wiser to try and verify directly that no generator
occurred more than once in the complete set of relators. I did this as
follows - this took about one hour of cpu-time.

for i in [1..53128] do
  occ:=TzOccurrences(HP.tietze,i);
  if occ[1][1]>1 then
    Print(i,occ,"\n");
  fi;
od;

Since nothing was printed, we conclude that no generator occurs more than once
in the total relator list, and so the group must be free of rank
53196 - 12875 = 40321 (which is the 1 + index of subgroup).
(In fact each relator has length 3.)
Since the kernel of the map from G to P has index 253 in the group HP, we
conclude that it is free of rank 253(40321 - 1) + 1 = |M23| + 1.


I wrote to Volkmar Felsch giving the details of this calculation, and he
found a much quicker method of checking that there were no repeated
generators in the final presentation. Here is his reply:


Dear Dr. Holt,

Thank you for sending me your interesting example. I think your
piece of code for proving that each generator occurs at most once
in the relators was a very clever approach. Of course, there are
a lot of different possibilities to do this, and some of these are
essentially faster. After reproducing your presentation HP, I have
tested a few of these approaches. The most efficient I found took
not even three seconds (on an HP 9000/725). Here it is:

gap> # Get a copy of the presentation record
gap> P := Copy( HP );
<< presentation with 53696 gens and 13375 rels of total length 40125 >>
gap> oldtime := Runtime( );;
gap> 
gap> # Check whether each generator occurs at most once in the relators
gap> rels := P.tietze[TZ_RELATORS];;
gap> flat := Flat( rels );;
gap> for i in [ 1 .. Length( flat ) ] do                 
> if flat[i] < 0 then flat[i] := -flat[i]; fi;
> od;
gap> if Length( Set( flat ) ) = Length( flat ) then
> gens := P.tietze[TZ_GENERATORS];
> rank := Length( gens ) - Length( rels );
> Print( "    The group is free of rank ", rank, "\n" );
> fi;
    The group is free of rank 40321
gap> 
gap> # Print the time used
gap> Print( "time = ", Runtime( ) - oldtime, "\n" );   
time = 2660
gap>

I wonder if we should insert such a kind of test into the default
strategy of the SimplifyPresentation function. On the one hand,
there is only a very small probability that a presentation under
investigation will have this property, on the other hand this test
is very cheap compared, for instance, with the expense of the
substring search procedure involved in that command. (When I designed
the Tietze functions, I did not at all think of presentations of this
magnitude.)



From jim@cara.maths.heriot-watt.ac.uk Tue Oct  4 12:34:00 1994
Date:         Tue, 04 Oct 94 12:34:00 BST
From:         "Jim Howie" <jim@cara.maths.heriot-watt.ac.uk>
Subject:      Re: GAP computation

In connection with a GAP computation involving the Mathieu
groups M24 and M23, Derek Holt asked for theoretical results
giving the rank of a free subgroup of a free product.
Such a result exists for the finite index case, when the
free factors are finite (which is the case in his example).

Use rational euler characteristics.   For a finite group
G, this is defined as \chi(G)=1/|G|.   For a free product
you have \chi(A*B)=\chi(A)+\chi(B)-1.   Hence if G is the
free product of three cyclic groups of order 3 we have
\chi(G)=1/3 + 1/3 + 1/3 - 2 = -1.   For subgroups of finite
index H\subseteq G we have the rule \chi(H)=|G:H|.\chi(G),
so for the kernel K of Derek's map G --> M23 we have
\chi(K)=|M23|.\chi(G) = -|M23|.
Finally, the euler characteristic of a free group of rank r 
is \chi(F_r)=1-r, so we recover Derek's result:
rank(K)=1-\chi(K)=|M23|+1.

QED.

Jim Howie.



From gcs@maths.bath.ac.uk Wed Oct  5 10:36:00 1994
Date:         Wed, 05 Oct 94 10:36:00 +1000
From:         "Geoff Smith" <gcs@maths.bath.ac.uk>
Subject:      Re: GAP computation

Nice one Jim,

Is there a good place to read about rational Euler characteristics?

Geoff



From jim@cara.maths.heriot-watt.ac.uk Wed Oct  5 10:08:00 1994
Date:         Wed, 05 Oct 94 10:08:00 BST
From:         "Jim Howie" <jim@cara.maths.heriot-watt.ac.uk>
Subject:      Re: GAP computation

> From GAP-Forum-Sender@Math.RWTH-Aachen.DE Wed Oct  5 09:52:39 1994
> Sender: GAP-Forum-Sender@Math.RWTH-Aachen.DE
> Reply-To: GAP Forum <GAP-Forum@Math.RWTH-Aachen.DE>
> X-Miles:        GAP Forum article 392 accepted at 05 Oct 94 09:28 +0100
> Date:           05 Oct 94 10:36 +1000
> From: gcs@mundoe.maths.mu.oz.au <gcs@maths.bath.ac.uk>
> To: Multiple recipients of list <GAP-Forum@Math.RWTH-Aachen.DE>
> Subject:        Re: GAP computation 
> Content-Length: 91
> 
> 
> Nice one Jim,
> 
> Is there a good place to read about rational Euler characteristics?
> 
> Geoff
> 

Try Ken Brown's article "Groups of virtually finite dimension"
in "Homological Group Theory" (LMS Lect Notes 36, ed. CTC Wall).
In particular all the properties that I mentioned follow from
formulae (6.1) and (6.3) there (together with \chi({1}) = 1).

Jim



From mueller@leon.informatik.uni-bonn.de Fri Oct  7 09:22:00 1994
Date:         Fri, 07 Oct 94 09:22:00 +0000
From:         "Johannes Mueller" <mueller@leon.informatik.uni-bonn.de>
Subject:      Best Memory Size under OS/2

-P17805@K

Dear Forum,

can you tell me, what number X (given to GAPEMX.EXE with parameter -m Xm)
works best (fastest) with respect to invoking Editor or computation of
large objects (garbage collection etc.).

My own tests (I have a 386-PC with 8Mb) brought this: Calling GAP with -m
4m results in (a little) faster Execution as -m 6m being faster as -m 7m.

Bye, Johannes



From ruberman@maths.ox.ac.uk Tue Oct 11 09:24:00 1994
Date:         Tue, 11 Oct 94 09:24:00 +0100
From:         "Daniel Ruberman" <ruberman@maths.ox.ac.uk>
Subject:      presentation for permutation groups

Dear Gap Forum: Is there an algorithm implemented in GAP for finding a
presentation for a finite permutation group, given its generators?  I've
looked in the manual as best I can but didn't locate any relevant command.

Daniel Ruberman



From Alexander.Hulpke@Math.RWTH-Aachen.DE Tue Oct 11 15:42:00 1994
Date:         Tue, 11 Oct 94 15:42:00 +0100
From:         "Alexander Hulpke" <Alexander.Hulpke@Math.RWTH-Aachen.DE>
Subject:      Re: presentation for permutation groups

Dear Gap-Forum,

Daniel Ruberman asked:

> Dear Gap Forum: Is there an algorithm implemented in GAP for finding a
> presentation for a finite permutation group, given its generators?  I've
> looked in the manual as best I can but didn't locate any relevant command.

At the moment, there is no 'official' command for computing a presentation
for a permutation group. However the routine which checks, whether a
'GroupHomomorphismByImages' is indeed an homomorphism basically computes a
presentation and can be almost abused for our purpose. Anyhow we need to
almost duplicate the routine, as we are forced otherwise to check inclusion in
subgroups of the free group (Instead of building a relator subgroup, we will
just create a relator list).
The following code will do this task (it is mainly 'borrowed' from the
homomorphism routines), it will also be included in the next version:

#############################################################################

CoKernelGens := function ( hom )
    local   C,          # cokernel of <hom>, result
            stb,        # stabilizer in the chain of <hom>
            bpt,        # basepoint of stabilizer
            elm,        # one schreier generator
            img,        # image of <elm> under <hom>
            i, k,       # loop variables
            oldhom;

  # make sure we have a stabilizer chain for <hom>
  if not IsBound( hom.stabilizer )  then
      hom.operations.MakeMapping( hom );
  fi;

  # loop over the stabilizer chain
  C := [];
  oldhom:= hom;
  while hom.generators <> []  do

      # for all orbit points
      for i  in hom.orbit  do

	  # and all generators
	  for k  in [ 1 .. Length(hom.generators) ]  do

	      # make the schreier generator and its image
	      img := hom.transimages[i];
	      elm := hom.transversal[i];
	      while i^elm <> hom.orbit[1]  do
		  img := img * hom.transimages[i^elm];
		  elm := elm * hom.transversal[i^elm];
	      od;
	      img := img^-1 * hom.genimages[k];
	      elm := elm^-1 * hom.generators[k];

	      # divide the schreier generator through the stabilizer chain
	      stb := hom;
	      while stb.generators <> []
		and IsBound(stb.transversal[stb.orbit[1]^elm])  do
		  bpt := stb.orbit[1];
		  while bpt ^ elm <> bpt  do
		      img := img * stb.transimages[bpt^elm];
		      elm := elm * stb.transversal[bpt^elm];
		  od;
		  stb := stb.stabilizer;
	      od;

	      # if the image is not trivial add it to the cokernel
	      if not img in C  then
		  Add(C,img);
	      fi;

	  od;

      od;

      # go down to the next stabilizer
      hom := hom.stabilizer;

  od;

  # return the cokernel
  return Difference(C,[IdWord]);

end;


#############################################################################
##
#F  PermGroupOps.FpGroup( <U> ) . . . . . . . . . . presentation of a PermGrp
##
PermGroupOps.FpGroup := function( arg )
local U,gens,h,F;

  # check trivial case
  U:=arg[1];
  if 0 = Length(U.generators)  then
    F:=FreeGroup(0);
    F.relators:=[];
    F.bijection:=GroupHomomorphismByImages(F,U,[],[]);
    return F;
  fi;

  # Try to find suitable names for this generators.
  if Length(arg) = 2 then
    gens:=WordList(Length(U.generators), arg[2] );
  else
    gens:=WordList(Length(U.generators), "F" );
  fi;

  # compute the presentation
  F:=Group( gens, IdWord );
  h:=GroupHomomorphismByImages(U,F,U.generators,gens);
  F.relators:=CoKernelGens(h);
  h:=GroupHomomorphismByImages(F,U,gens,U.generators);
  h.isMapping:=true;
  h.isHomomorphism:=true;
  F.bijection:=h;

  # Return the presenation.
  return F;

end;

#############################################################################

If you call F:=FpGroup(G);
then generators correspond (you might use F.bijection for automatic mapping)
and F.relators is a set of defining relators for the permutation group <G>.

Hope this helps,

Alexander Hulpke



From hoefling@mat.mathematik.uni-mainz.de Wed Oct 12 12:57:00 1994
Date:         Wed, 12 Oct 94 12:57:00 +0100
From:         "BURKHARD HOEFLING" <hoefling@mat.mathematik.uni-mainz.de>
Subject:      bug in semidirect product routine

Dear authors of GAP,

I would like to notify to You the following error, presumably in
PermGroupOps.SemidirectProduct. The error occurs whenever I try
to construct a semidirect product in which the "top" group (i.e.
the nonnormal one) is a permutation group. In the included examples,
I construct a symmetric group of degree 3 by letting a cyclic
(permutation) group of order 2 operate on a cyclic group of order 3
(which is a permutation group in the first example and an AgGroup in
the second one). On the other hand, if I define the cyclic group of
order 2 as an AgGroup (i.e. by

C2 := CyclicGroup(AgWords,2);

then everything seems to work as it should. While I am working with
GAP 3.2.2 (I am using the GAP port of Henry Lakser for the Mac),
I have tested the below examples on the DOS i386 port available on the
Aachen file server, running GAP versions 3.3.0 and the recently released
version 3.4.1. All these show exactly the same behaviour.

In the following examples, my comments are marked ### while the GAP output
is marked #.

################## example 1 #############################
###
### define Sym(3) as a semidirect product ...
###
C3 := CyclicGroup (3);
alpha := GroupHomomorphismByImages (C3,C3,[(1,2,3)],[(1,3,2)]);
A := Group (alpha);
C2 := Group ((10,11));
a := GroupHomomorphismByImages (C2,A,[(10,11)],[alpha]);
G := SemidirectProduct (C2,a,C3);

### then try the following ...

Z := Centre (G);

# Error, Record: element 'MakeMapping' must have an assigned value at
# hom1.operations.MakeMapping( hom2 ) ... in
# map1.operations.CompositionMapping( map2, map1 ) called from
# <rec1> * <rec2> called from
# <rec1> ^ <rec2> called from
# <rec1> ^ <rec2> called from
# arg[1].operations.Stabilizer( arg[1], arg[2], OnPoints ) called from
# ...

FittingSubgroup (G);

# Error, Record: element 'isNilpotent' must have an assigned value at
# if not IsBound( G.isNilpotent ) and G.isNilpotent ... in
# FittingSubgroup( G ) called from
# main loop

Order (G,G.generators[1]);

# Error, Record: element 'Order' must have an assigned value at
# return G.operations.Order( G, g ) ... in
# Order( G, G.generators[1] ) called from
# main loop

##################### example 2 ###########################
LogTo("AgSdir.log");
C3 := CyclicGroup (AgWords,3);
alpha := GroupHomomorphismByImages (C3,C3,[C3.1],[C3.1^2]);
A := Group (alpha);
C2 := CyclicGroup (2);
a := GroupHomomorphismByImages (C2,A,C2.generators,[alpha]);
G := SemidirectProduct (C2,a,C3);
F := FittingSubgroup (G);

# Error, sorry, the elements of <arg> lie in no common ring domain in
# Domain( [ g, h ] ) called from
# SemidirectProductElement( g, g ^ D.mapping, h ) called from
# D.operations.Random( D ) called from
# Random( G ) called from
# G.operations.SylowSubgroup( G, p ) called from
# ...
# brk>


##################### end of example 2 ####################

I hope that the above examples will serve You to locate this error.

Besides, let me include the following question (I know I am not the
first one who asks it, as I found out from the GAP forum messages
distributed with GAP 3.4.1). What about the binary files corresponding
to the MAC ports of GAP that are so frequently announced but never
seem to appear on the file server in Aachen? Is there any other file
server where I might get it? I also noticed that the GAP 3.2.2 port by
Henry Lakser disappeared from ftp.cc.umanitoba.ca. Is he perhaps
releasing a new version? --- If these questions have been answered
recently, as I suppose, could you just send it to me as I have subscribed
gap-forum only a few minutes ago?


Best regards,

Burkhard H”fling, Uni Mainz.



From hwblist@machnix.mathematik.uni-stuttgart.de Fri Oct 14 23:10:00 1994
Date:         Fri, 14 Oct 94 23:10:00 +0100
From:         "Harald Boegeholz" <hwblist@machnix.mathematik.uni-stuttgart.de>
Subject:      Re: Best Memory Size under OS/2

>   X-Miles:        GAP Forum article 395 accepted at 10 Oct 94 10:03 +0100
>   Date:           07 Oct 94 09:22 +0000 (GMT)
>   From: Johannes Mueller <mueller@leon.informatik.uni-bonn.de>
>
>   can you tell me, what number X (given to GAPEMX.EXE with parameter -m Xm)
>   works best (fastest) with respect to invoking Editor or computation of
>   large objects (garbage collection etc.).
>
>   My own tests (I have a 386-PC with 8Mb) brought this: Calling GAP with -m
>   4m results in (a little) faster Execution as -m 6m being faster as -m 7m.


Dear Johannes,


I don't have an OS/2 specific answer to that, but rather some general
remarks.

GAPs memory management works in such a way that it periodically has to
collect garbage. During this process, practically all memory in GAPs
workspace gets touched. Which means that if you use GAP under _any_
operating system with virtual memory (even extended DOS is such an
operating system), you will get extremely poor results if you specify
more than your physical memory size. This is because for every garbage
collection, the swapper will have to pull the whole workspace
"through" the real memory and swap it out again causing heavy disk
I/O.

If you have lots of memory, my experiences show that a larger
workspace makes GAP faster. If you know in advance that during the
computation of a given problem GAP has to enlarge the workspace, you
can save lots of time by specifying a sufficient initial memory
size. To find out, run GAP with the -g option.

On the other hand, GAP slows down as soon as it has to swap. On your
machine with 8MB, GAP's working set alone is 4MB data plus some
code. I don't know what the working set of OS/2 is when runs just GAP,
but remember you have a powerful object oriented graphical user
interface running all the time (and maybe some toys like screen savers
etc.)

Based on my subjective experience (not exact measurements) I recommend
a workspace at least as large as the problem requires, of course. More
workspace doesn't hurt, unless you have to swap. So if you run just
GAP and nothing else, use a workspace of MMS - 4MB (MMS = Main Memory
Size).  If you run GAP under Emacs, use MMS - 8MB (which means don't
do it at all on your machine, sorry). Generally (for all operating
systems I can think of), make sure the working set of all active
processes fits into physical memory for optimum performance.

If you want to do some work to really analyze this, I can recommend
the tool Theseus2. It is part of a (commercial) IBM product called
SPM/2. Theseus2 gives you extensive information about memory usage of
all processes including the OS/2 kernel. It also allows you to measure
the working set of active processes.

Maybe one of the GAP developers (Martin?) can confirm that in theory
(if you have enough physical memory), a larger workspace should by no
means slow GAP down. (I hope it is designed this way.)


mfg
hwb

-- 
Harald Boegeholz |   hwb@mathematik.uni-stuttgart.de
                 |   os2a@info2.rus.uni-stuttgart.de



From Martin.Schoenert@Math.RWTH-Aachen.DE Sat Oct 15 00:17:00 1994
Date:         Sat, 15 Oct 94 00:17:00 -0700
From:         "Martin Schoenert" <Martin.Schoenert@Math.RWTH-Aachen.DE>
Subject:      Re: Re: Best Memory Size under OS/2

Harald Boegeholz writes in his message of 1994/10/14 23:10

    GAPs memory management works in such a way that it periodically has to
    collect garbage. During this process, practically all memory in GAPs
    workspace gets touched. Which means that if you use GAP under _any_
    operating system with virtual memory (even extended DOS is such an
    operating system), you will get extremely poor results if you specify
    more than your physical memory size. This is because for every garbage
    collection, the swapper will have to pull the whole workspace
    "through" the real memory and swap it out again causing heavy disk
    I/O.

Actually it is even worse than that, because the first (mark) phase
of the garbage collection touches the storage in an almost random order.
That means that Gasman (GAP's storage manager) causes tons of page
faults if the workspace size exceeds the available real storage size.

Do as Harald suggests, use GAP's '-g' option.
This displays a single information line for every garbage collection.
This line usually helps in deciding whether you want to give GAP
more or less storage.

If GAP does thousands of garbage collections, each freeing only very
little storage, then you know that you gave GAP too little storage.
Namely GAP will extend the worspace only when it absolutely has to.
So in some computations the given workspace is barely enough,
but GAP has to do many garbage collections, each freeing only
several KByte of storage.  In extreme cases GAP spends most of
its time in garbage collections, meaning that it will run *much*
faster if you give it a little bit more storage.

If GAP does few garbage collections, but each takes very long (especially
in the first phase, which takes place between the printing of '#G' and
the first numbers), then you gave GAP too much storage.  Namely each
garbage collection causes many page faults, and giving GAP a little bit
less storage will make it quite a bit faster.

For single user systems (personal computers and single user workstations)
something like main memory size - 4 MByte (2 for the operating system
and 2 for the GAP executable and GAP's static data) is usually a good
rule of thumb.  (This together with the fact that GAP 3.4 needs
at least 4 MByte of workspace for any serious computation means that
GAP 3.4 will not run well on 4 MByte systems; hopefully future versions
of GAP will be less demanding).

Harald continues

    Maybe one of the GAP developers (Martin?) can confirm that in theory
    (if you have enough physical memory), a larger workspace should by no
    means slow GAP down. (I hope it is designed this way.)

The time for the basic computation is indepedent of the size of the
workspace.  But a larger workspace means fewer garbage collections
and thus faster runtime.

But there are secondary effects, which counter this effect.  Once you hit
virtual memory each garbage collection will take much longer (so the
total runtime increases, even if there are fewer garbage collections).
Sometimes there are also strange interactions with the cache (especially
direct mapped caches, such as the ones used on HP workstations), but they
are generally so unpredictable, that you shouldn't bother.

Martin.

-- .- .-. - .. -.  .-.. --- ...- . ...  .- -. -. .. -.- .-
Martin Sch"onert,   Martin.Schoenert@Math.RWTH-Aachen.DE,   +49 241 804551
Lehrstuhl D f"ur Mathematik, Templergraben 64, RWTH, 52056 Aachen, Germany



From jcbhrb@cerf.net Thu Oct 20 13:01:00 1994
Date:         Thu, 20 Oct 94 13:01:00 -0700
From:         "Jacob Hirbawi" <jcbhrb@cerf.net>
Subject:      Size of subgroup generated by classes

Given a charatcer table record, I'd like to calculate the size of the
subgroup generated by a list of classes. Is this possible in GAP?
Actually I am not sure if this is theoretically possible, so perhaps 
I should ask if the character table record (and in particular the power
maps) contain enough information to do this. Thanks.

Jacob Hirbawi <JcbHrb@CERF.net>



From pasec@can.nl Thu Oct 20 23:03:00 1994
Date:         Thu, 20 Oct 94 23:03:00 +0100
From:         "Dima Pasechnik" <pasec@can.nl>
Subject:      Re: Size of subgroup generated by classes

    Given a charatcer table record, I'd like to calculate the size of the
    subgroup generated by a list of classes. Is this possible in GAP?
    Actually I am not sure if this is theoretically possible, so perhaps 
    I should ask if the character table record (and in particular the power
    maps) contain enough information to do this. Thanks.

    Jacob Hirbawi <JcbHrb@CERF.net>

I'd guess that all the information needed is already in. 
There is a function ClassMultCoeffCharTable(tbl,c1,c2,c3),
it returns the number of pairs (x,y) of elements of G
such that x\in c1, y\in c2, and xy is a fixed element
of c3.

So one can start with a given subset of classes and repeatedly
apply this function to find all the classes which get involved.
Then it remains to add up their sizes.

( Since it appears to be practically possible, it should also 
be possible theoretically. :-) )

Regards,
Dima Pasechnik,
pasec@can.nl
dima@maths.uwa.edu.au



From Martin.Schoenert@Math.RWTH-Aachen.DE Fri Oct 21 10:48:00 1994
Date:         Fri, 21 Oct 94 10:48:00 -0700
From:         "Martin Schoenert" <Martin.Schoenert@Math.RWTH-Aachen.DE>
Subject:      Re: bug in semidirect product routine

Burkhard Hoefling writes in his e-mail message of 1994/10/12

    I would like to notify to You the following error, presumably in
    PermGroupOps.SemidirectProduct.
    ...

    C3 := CyclicGroup (3);
    alpha := GroupHomomorphismByImages (C3,C3,[(1,2,3)],[(1,3,2)]);
    A := Group (alpha);
    C2 := Group ((10,11));
    a := GroupHomomorphismByImages (C2,A,[(10,11)],[alpha]);
    G := SemidirectProduct (C2,a,C3);

    Z := Centre (G);
    # Error, Record: element 'MakeMapping' must have an assigned value at
    ...

Here GAP tries to multiply two semidirect product elements, resp. their
induced automorphisms <h1> and <h2>.  To do this it needs to compute some
information about <2> with 'MakeMapping'.  But it tries to look up this
method in <h1>'s operations record.  Usually this is not a problem, since
<h1> and <h2> have the same operations records anyhow.  But in this case
<h1> is 'IdentityMapping(...)', which doesn't have a 'MakeMapping'
method.  Small problem, small fix.

--- /usd/gap/3.4/lib/permhomo.g	Mon Jul 11 01:28:57 1994
+++ permhomo.g	Sun Oct 16 23:03:43 1994
@@ -939,7 +939,7 @@
 
             # make sure we have a stabilizer chain for the left homomorphism
             if not IsBound( hom2.stabilizer )  then
-                hom1.operations.MakeMapping( hom2 );
+                hom2.operations.MakeMapping( hom2 );
             fi;
 
             # make the homomorphism

Burkhard Hoefling continues

    FittingSubgroup (G);
    # Error, Record: element 'isNilpotent' must have an assigned value at
    ...

This particular problem has been fixed in GAP 3.4.1.  But GAP 3.4.1 fails
almost immediately too when it tries to compute the order of an element.

Burkhard Hoefling probably noticed this, because he continues

    Order (G,G.generators[1]);
    # Error, Record: element 'Order' must have an assigned value at
    ...

The problem here is slightly more technical.  For those interested.
The  operations record for semidirect products ('SemidirectProductOps')
inherits from the operations record for generic groups ('GroupOps').
But when it inherits (by beeing created as a copy of 'GroupOps'),
'GroupOps' has not yet aquired all generic methods, e.g., the
generic 'Order' method is not yet entered into 'GroupOps'.

Again there is a simply fix.  Simply enter

    MergeOperationsEntries( GroupOps, SemidirectProductOps );

before you call 'SemidirectProduct'.

Burkhard Hoefling continues

    C3 := CyclicGroup (AgWords,3);
    alpha := GroupHomomorphismByImages (C3,C3,[C3.1],[C3.1^2]);
    A := Group (alpha);
    C2 := CyclicGroup (2);
    a := GroupHomomorphismByImages (C2,A,C2.generators,[alpha]);
    G := SemidirectProduct (C2,a,C3);
    F := FittingSubgroup (G);
    # Error, sorry, the elements of <arg> lie in no common ring domain in
    ...

This is a much more serious problem.  It happens when the two groups have
different representations (in this case one is a permutation group and
the other is an AG group).

I must confess that I am not certain what the correct way to solve it is.
It depends on what the (undocumented) function 'SemidirectProductElement'
does.

Anyhow the following solves your problem for now

--- /usd/gap/3.4/lib/grpprods.g	Mon Jul 11 01:28:37 1994
+++ grpprods.g	Sun Oct 16 23:17:39 1994
@@ -806,7 +806,7 @@
 ##
 SemidirectProductElement := function ( g, a, h )
     local   D;
-    D := Domain( [ g, h ] );
+    D := GroupElements;
     return D.operations.SemidirectProductElement( D, g, a, h );
 end;
 

Burkhard Hoefling continues

                                 What about the binary files corresponding
    to the MAC ports of GAP that are so frequently announced but never
    seem to appear on the file server in Aachen? 

Look again (yes I know, it is difficult to believe, but it is finally
available).

Martin.

-- .- .-. - .. -.  .-.. --- ...- . ...  .- -. -. .. -.- .-
Martin Sch"onert,   Martin.Schoenert@Math.RWTH-Aachen.DE,   +49 241 804551
Lehrstuhl D f"ur Mathematik, Templergraben 64, RWTH, 52056 Aachen, Germany



From Martin.Schoenert@Math.RWTH-Aachen.DE Fri Oct 21 11:01:00 1994
Date:         Fri, 21 Oct 94 11:01:00 -0700
From:         "Martin Schoenert" <Martin.Schoenert@Math.RWTH-Aachen.DE>
Subject:      GAP for Macintosh

Finally we now have a port of GAP for the Macintosh.  GAP for MAC is a
standalone application not an MPW Tool.  I include the full 'README.MAC'
below.

The binaries are available on 'ftp.math.rwth-aachen.de' in the directory
'/pub/gap/bin'.  They should also make it to the other servers soon.

GAP for MAC was compiled using MPW with the SIOW library.  Because of
limitations of this library it is still a bit awkward to use.  Currently
we do not have the resources to improve the port so that it does not need
the SIOW library and becomes a wellbehaved Macintosh program.

If you would like to help us to improve this port, please contact us, so
that we can coordinate such efforts.

Martin.

-- .- .-. - .. -.  .-.. --- ...- . ...  .- -. -. .. -.- .-
Martin Sch"onert,   Martin.Schoenert@Math.RWTH-Aachen.DE,   +49 241 804551
Lehrstuhl D f"ur Mathematik, Templergraben 64, RWTH, 52056 Aachen, Germany

==========================================================================

GAP for MAC
===========

    This section  contains information about  GAP that is  specific to the
    port of GAP for the Apple Macintosh (simply called GAP for MAC below).

    To  run GAP for  MAC you need an Apple  Macintosh.  GAP for MAC should
    run in emulation mode on PowerMacs, but this has  not been tested yet.
    The computer must have at least 6 MByte of memory and a harddisk.  The
    operating system must be System 7 (earlier versions may work, but this
    has not been tested yet).

    The section "Copyright of  GAP for MAC"  describes the copyright as it
    applies to the  executable  version that we  distribute.   The section
    "Installation of  GAP for MAC" describes how  you install GAP for MAC,
    and the   section "Features of   GAP  for MAC"  describes  the special
    features of GAP for MAC.


Copyright of GAP for MAC
========================

    In addition to the general copyright for GAP set forth in 'README' the
    following terms apply to GAP for MAC.

    The system dependent  part for GAP for MAC  was written  by Dave Bayer
    ('dab@maths.columbia.edu').  He assignes the  copyright to Lehrstuhl D
    fuer Mathematik.  Many thanks to Dave Bayer for his work.

    The application of GAP  for MAC that  we distribute was compiled  with
    Apple's Mac Programmers Workshop (MPW) C  compiler version 3.3.1 using
    the  Simple  Input/Output Window  (SIOW)  library.  The  MPW copyright
    allows us free redistribution of the application.


Installation of GAP for MAC
===========================

    Installation   of GAP for  MAC is  fairly easy.   As already mentioned
    above, GAP must be installed on a harddisk, because it is too large to
    be run from floppy disks.

    First create a folder where you  want to install GAP, e.g., 'HD:GAP:'.
    GAP will be installed in  a subfolder ':gap3r4p1:' of this  directory.
    You can later move GAP to another location,  for example you can first
    install it in 'HD:temp:' and once it works move it to 'HD:GAP:'.

    Get the GAP  distribution onto your Macintosh  into  that folder.  One
    usual way would be  to get the distribution with  'ftp' onto some UNIX
    workstation and  to download it   from there onto your  Macintosh, for
    example with 'kermit'.   Remember  that the distribution consists   of
    binary files and that you must transmit them in binary mode.

    If you get  the distribution via 'ftp',  you must get the distribution
    'gap3r4p1.zoo',     the        zoo         archive           extractor
    'unzoo-mac-m68k-system7-siow.hqx',  which is in the subdirectory 'bin'
    and which   you should  rename  to  'unzoo.hqx',  and  the application
    'bin3r4p1-mac-m68k-system7-siow.zoo', which   is  in the  subdirectory
    'bin' and which you should rename to 'bin3r4p1.zoo'.   You may have to
    get  the latter 2  files  from 'ftp.math.rwth-aachen.de', because some
    'ftp' servers may not  keep them.  We  recommend that you  use 'unzoo'
    even  if  you   already have  'zoo'  on  you  system, because  'unzoo'
    automatically translates text files to the appropriate local format.

    Unpack the 'unzoo' application, which  comes in *BinHex 4* format, for
    example using the 'Convert FROM BinHex4...' command in 'Compact Pro'.

    Start   the  'unzoo' application and unpack    the application and the
    distribution with    the following commands, using    <control>-'Q' to
    terminate 'unzoo' afterwards.

        -x -o bin3r4p1
        -x -o gap3r4p1

    You must  use  the distributed   binary, because  the source that   we
    currently  distribute is not ready  to be compiled  with MPW, since we
    haven't yet merged the latest modifications into the source.

    Set the amount  of memory that the GAP  applications is given with the
    'Info' command  in the 'File' menu  of the Finder.  The minimal amount
    should be 5632 KByte.  The preffered amount should  not be larger than
    the amount of real memory in your machine approximately 1024 KByte for
    the system (even  if  you  have  virtual  memory).  The Finder    will
    allocate the preffered amount, or  less if  less memory is  available.
    The size of GAP's workspace is the allocated amount minus 1536 KByte.

    If you have a big version of LaTeX available, you may now want to make
    a printed copy of  the  manual.  The  LaTeX source  is in the  ':doc:'
    subdirectory.  You  must run LaTeX *twice*  to resolve all references.
    Then print the *dvi* file.

    Try something in GAP, e.g., the following exercises GAP quite a bit

        gap> m11 := Group((1,2,3,4,5,6,7,8,9,10,11),(3,7,11,8)(4,10,5,6));;
        gap> Number( ConjugacyClasses( m11 ) );

    The result should be 10.

    Thats  all, finally you are  done.  We hope  that you will enjoy using
    GAP.  If you have problems, do not hesitate to contact us.


Features of GAP for MAC
=======================

    GAP for the MAC  has been ported using  the Simple Input/Output Window
    (SIOW)  library of MPW.     This library  makes  it possible   to port
    programs that read from 'stdin' and write to 'stdout', such as GAP, to
    the  Macintosh, where  the interaction is  displayed  in a single text
    window.   Unfortunately this library  has  a few peculiarities,  which
    make GAP for MAC awkward to use.

    To terminate GAP it is not enough to enter  'quit;' at the GAP prompt.
    You must also choose the 'Quit' command from the  'File' menu or enter
    <command>-'Q'.  This gives  you the option  of saving  the contents of
    the window to a file.

    To interrupt a   computation enter  <command>-'.'   or  <control>-'C'.
    While <command>-'.'  is more correct, because it follows the Macintosh
    convention,  it has the disadvantage   that  it terminates GAP if  you
    enter it at the prompt.  We thus suggest that you use <control>-'C'.

    The usual command  line editing is  *not* available.  Especially <tab>
    cannot  be used to  complete   identifier, and <control>-'P' will  not
    recall previous input lines.

    As if  that is  not  bad enough,  cutting and   pasting does  not work
    correct either.   If  you paste something to  the  current input line,
    SIOW will duplicate it.  E.g. if you paste '2 * 2;' to the input line,
    SIOW sends 'gap> gap> 2  * 2;2 * 2;' to  GAP, which complains that the
    variable 'gap' has no assigned value.

    GAP for MAC  keeps up to 32  KByte of Input/Output  in the window.  If
    your session contains more than that, it will discard  text at the top
    of the window.  This restriction is not due to  SIOW, it is build into
    the TextEdit  class  in the  *Toolbox*, and  circumventing it requires
    quite a bit of work.

    Help texts are  displayed in one piece  without stoppign to ask you to
    enter '--  <space>   for more --'.   Instead   you can scroll  around.
    Luckily there is no individual section larger than 32 KByte.

    You can only scroll, cut&paste, and switch  to other applications when
    GAP is waiting for your input.  This is because this  is the only time
    that  SIOW,    which knows  about   windows,  events,  and cooperative
    multitasking, is in control.


I still hope you will find GAP usefull, Martin.

-- .- .-. - .. -.  .-.. --- ...- . ...  .- -. -. .. -.- .-
Martin Sch"onert,   Martin.Schoenert@Math.RWTH-Aachen.DE,   +49 241 804551
Lehrstuhl D f"ur Mathematik, Templergraben 64, RWTH, 52056 Aachen, Germany



From Joachim.Neubueser@Math.RWTH-Aachen.DE Mon Oct 31 10:14:00 1994
Date:         Mon, 31 Oct 94 10:14:00 +0100
From:         "Joachim Neubueser" <Joachim.Neubueser@Math.RWTH-Aachen.DE>
Subject:      Forwarded mail...

Dear Colleagues,

The following message, which I received throuh the group-pub-forum, is
probably of interest to several members of the gap-forum.

Joachim Neubueser

======================================================================
> FIRST ANNOUNCEMENT
> 
> SPECIAL YEAR IN GEOMETRIC GROUP THEORY, 1996
> 
> A special year in Geometric Group Theory will be held in Australia during
> 1996, sponsored by the School of Mathematical Sciences, Australian National
> University. The title is intended to be interpreted broadly, and will
> include the various aspects of the interplay between geometry and group
> theory. There will be two major meetings during the year and a number of
> smaller associated meetings. 
> 
> Overseas visitors interested in these meetings are encouraged to arrange
> for a more extended visit to Australia in conjunction with the meeting.
> Several universities are cooperating in making arrangements for visitors
> and some financial assistance may be possible. Visitors are encouraged to
> get in touch with one of the committee members listed below and register
> their interest.
> 
> The two major meetings during the year will be a Workshop and a Conference. 
> 
> Workshop on Geometric Group Theory
> 22 January to 9 February 1996
> Australian National University,
> Canberra, ACT, Australia
> 
> This will be an instructional workshop, aimed at being accessible to
> graduate students. There will be several series of expository lectures and
> a number of talks on recent research. Lecture series during the first week
> will be quite basic, with those in the second and third weeks progressively
> more specialised. As far as is possible in three weeks, the intention is to
> present a broad overview of and a perspective on current research in
> geometric group theory. Speakers will include both Australian and overseas
> experts. It is expected that the workshop will also be useful to
> mathematicians with an interest in the area who do not work directly in the
> area.
> 
> The expository series of lectures will include the following topics: groups
> in algebraic geometry, computational group theory, geometric group theory,
> combinatorial group theory, R-trees, geometrically hyperbolic groups,
> buildings and Coxeter groups, homology of groups.
> 
> The Workshop will provide significant assistance towards student board and
> accommodation, and hope that the student's home institution will contribute
> to their travel costs.
> 
> Conference on Geometric Group Theory
> 14-19 July 1996
> Australian National University
> Canberra, ACT, Australia
> 
> This will be an international research conference, with invited lectures on
> the various aspects of the interplay between geometry and group theory by
> more than thirty researchers. 
> 
> The organising committee for this special year is:
> CF Miller (Melbourne, cfm@maths.mu.oz.au) - chairperson
> MDE Conder (Auckland, conder@mat.aukuni.ac.nz)
> J Cossey (ANU, cossey@pell.anu.edu.au)
> G Havas (Queensland, havas@cs.uq.oz.au)
> GI Lehrer (Sydney, lehrer_g@maths.su.oz.au) 
> GJ Martin (ANU and Auckland, gaven.martin@maths.anu.edu.au)
> BH Neumann (ANU, bhn@pell.anu.edu.au)
> WD Neumann (Melbourne, neumann@mundoe.maths.mu.oz.au)
> MF Newman (ANU, newman@pell.anu.edu.au)
> CE Praeger (Western Australia, praeger@maths.uwa.oz.au)
> DE Taylor (Sydney, taylor_d@maths.su.oz.au)
> 
> If you wish to be kept informed about the special year, please let us know
> (by contacting one of the committee members). You can help us by passing
> this message on to anyone else you think will be interested 
> 
> ------------------------------------------------------------------------------
> 



From Thomas.Breuer@Math.RWTH-Aachen.DE Thu Nov 10 17:17:00 1994
Date:         Thu, 10 Nov 94 17:17:00 WET
From:         "Thomas Breuer" <Thomas.Breuer@Math.RWTH-Aachen.DE>
Subject:      update of the MeatAxe package

Dear Mrs. and Mr. Forum,

recently Gene Cooperman offered us some improvements to the MeatAxe
package in GAP which allows compilation with old (non-ANSI) compilers.
The author of the MeatAxe package, Michael Ringe, has now incorporated
these changes in his programs.
An archive with the updated MeatAxe version (2.0.12) is available on
our ftp server 'ftp.math.rwth-aachen.de', as 'meataxe.zoo' in
the directory 'pub/incoming'.

Kind regards
Thomas Breuer



From Martin.Schoenert@Math.RWTH-Aachen.DE Thu Nov 10 22:19:00 1994
Date:         Thu, 10 Nov 94 22:19:00 -0700
From:         "Martin Schoenert" <Martin.Schoenert@Math.RWTH-Aachen.DE>
Subject:      GAP on Solaris 2.3

One of our users (in Zimbabwe, with no Internet connection) is having
trouble to compile GAP no a Sun running SunOS 5.3 (Solaris 2.3).

Has somebody compiled GAP on such a machine successfully?  Or has
somebody access to a machine and could try it?  Finally (yes I know this
is asking much), in case there are really problems, could somebody help
us to solve them (e.g. arranging a temporary account for us, so we can
debug GAP on such a system)?

Any help is appreciated.

Thanks in advance, Martin.

-- .- .-. - .. -.  .-.. --- ...- . ...  .- -. -. .. -.- .-
Martin Sch"onert,   Martin.Schoenert@Math.RWTH-Aachen.DE,   +49 241 804551
Lehrstuhl D f"ur Mathematik, Templergraben 64, RWTH, 52056 Aachen, Germany



From mike.newman@maths.anu.edu.au Fri Nov 11 09:06:00 1994
Date:         Fri, 11 Nov 94 09:06:00 +1100
From:         "M.F.(Mike) Newman" <mike.newman@maths.anu.edu.au>
Subject:      Re:  GAP on Solaris 2.3

Martin,

Our local expert, Eamonn, is away and out of contact at present.
We seem to have gap running on Wilton which is running Solaris 2.3
At present aachen (?Frank) is running a job which is going nowhere.
Is that an attempt to compile?
It looks to me as if it should be killed.
You are of course welcome to continue using that account to
experiment.
If you need another account let me know.
Also if there is anything else I can help with.

All the best

Mike



From jmccarro@barrow.uwaterloo.ca Thu Nov 10 17:26:00 1994
Date:         Thu, 10 Nov 94 17:26:00 -0500
From:         "James McCarron" <jmccarro@barrow.uwaterloo.ca>
Subject:      Re: GAP on Solaris 2.3

> 
> One of our users (in Zimbabwe, with no Internet connection) is having
> trouble to compile GAP no a Sun running SunOS 5.3 (Solaris 2.3).
> 
> Has somebody compiled GAP on such a machine successfully?  Or has
> somebody access to a machine and could try it?  Finally (yes I know this
> is asking much), in case there are really problems, could somebody help
> us to solve them (e.g. arranging a temporary account for us, so we can
> debug GAP on such a system)?
> 
> Any help is appreciated.
> 
> Thanks in advance, Martin.
>
Hello:

	Yes, I have installed GAP on my Sparc5, running Solaris 2.3 and SunOS5.3.
I used gcc (the only C compiler I have) and needed to make only minor
modifications, I believe just in system.c (after fixing the things I broke the
first time :-).  
	Unfortunately, my Sparc5 is not on the Internet, although I could try to
I used gcc (the only C compiler I have) .  As I recall, there were only a few
small problems (after I fixed the things I broke the first time :-).
Unfortunately, my Sparc5 is not on the Internet (it is at home), but I could
try to provide rcsdiffs (if I kept them; I'll check on it).  I should be able
to transfer the file(s) to this computer via modem.  If this will be of any
help at all, please let me know where to send it.  If there is anything else
I can tell you, I will be very happy to try to help in whatever way I can.


Sincerely,

James McCarron
Pure Mathematics
University of Waterloo
CANADA

> -- .- .-. - .. -.  .-.. --- ...- . ...  .- -. -. .. -.- .-
> Martin Sch"onert,   Martin.Schoenert@Math.RWTH-Aachen.DE,   +49 241 804551
> Lehrstuhl D f"ur Mathematik, Templergraben 64, RWTH, 52056 Aachen, Germany
> 



From Martin.Schoenert@Math.RWTH-Aachen.DE Thu Nov 10 23:39:00 1994
Date:         Thu, 10 Nov 94 23:39:00 -0700
From:         "Martin Schoenert" <Martin.Schoenert@Math.RWTH-Aachen.DE>
Subject:      Re: Re: GAP on Solaris 2.3

Thanks a lot for your fast reply.

'gcc' does not seem to cause any problems.  Unfortunately for our user in
Zimbabwe, getting GNU C would be a major undertaking.

The problems you had in 'system.c' were probably caused by a conflict
between the declaration of 'signal' in 'system.c' and the Solaris include
files.  In this case just building with
'make COPTS=-DSYS_HAS_SIGNAL_PROTO' should also solve it.
Could you check, whether this is true?

Martin.

-- .- .-. - .. -.  .-.. --- ...- . ...  .- -. -. .. -.- .-
Martin Sch"onert,   Martin.Schoenert@Math.RWTH-Aachen.DE,   +49 241 804551
Lehrstuhl D f"ur Mathematik, Templergraben 64, RWTH, 52056 Aachen, Germany



From jmccarro@barrow.uwaterloo.ca Thu Nov 10 18:51:00 1994
Date:         Thu, 10 Nov 94 18:51:00 -0500
From:         "James McCarron" <jmccarro@barrow.uwaterloo.ca>
Subject:      Re: Re: GAP on Solaris 2.3

> 
> Thanks a lot for your fast reply.
> 
> 'gcc' does not seem to cause any problems.  Unfortunately for our user in
> Zimbabwe, getting GNU C would be a major undertaking.
> 
> The problems you had in 'system.c' were probably caused by a conflict
> between the declaration of 'signal' in 'system.c' and the Solaris include
> files.  In this case just building with
> 'make COPTS=-DSYS_HAS_SIGNAL_PROTO' should also solve it.
> Could you check, whether this is true?
> 
> Martin.
> 
> -- .- .-. - .. -.  .-.. --- ...- . ...  .- -. -. .. -.- .-
> Martin Sch"onert,   Martin.Schoenert@Math.RWTH-Aachen.DE,   +49 241 804551
> Lehrstuhl D f"ur Mathematik, Templergraben 64, RWTH, 52056 Aachen, Germany
> 

Hello again:

	Sure, I will take a look at it.  I also tweaked the Makefile
slightly, and that may have been what I did (I don't recall at the
moment, but I will check).

Cheers!

James McCarron
Pure Mathematics
University of Waterloo
CANADA



From dfh@maths.warwick.ac.uk Fri Nov 11 10:22:00 1994
Date:         Fri, 11 Nov 94 10:22:00 +0000
From:         "Derek Holt" <dfh@maths.warwick.ac.uk>
Subject:      Re:  GAP on Solaris 2.3

We have two very new machines running Solaris 2.4. 
I had not got round to compiling GAP on them until today.
(One reason for this is that GAP compiled on SUN 4 using
sun-sparc-sunos-cc does run on the Solaris machines (although this
compatability does not seem to work in the other direction).

Unfortunately, we also do not have cc (since SUN no longer supply it
free) so we have to use gcc. I eventually got it to compile and run
successfully with

make usg CC=gcc COPTS="-DSYS_HAS_SIGNAL_PROTO -DSYS_HAS_TIME_PROTO"

Best wishes,
Derek.



From desouza@math.berkeley.edu Fri Nov 11 13:20:00 1994
Date:         Fri, 11 Nov 94 13:20:00 -0800
From:         "Paulo Ney de Souza" <desouza@math.berkeley.edu>
Subject:      Re:  GAP on Solaris 2.3

    >From GAP-Forum-Sender@Math.RWTH-Aachen.DE Fri Nov 11 03:40:01 1994
    >From: Derek Holt  <dfh@maths.warwick.ac.uk>
    >To: Multiple recipients of list <GAP-Forum@Math.RWTH-Aachen.DE>
    >Subject:        Re:  GAP on Solaris 2.3
    >
    >We have two very new machines running Solaris 2.4. 
    >I had not got round to compiling GAP on them until today.
    >(One reason for this is that GAP compiled on SUN 4 using
    >sun-sparc-sunos-cc does run on the Solaris machines (although this
    >compatability does not seem to work in the other direction).
    >
    >Unfortunately, we also do not have cc (since SUN no longer supply it
    >free) so we have to use gcc. I eventually got it to compile and run
    >successfully with
    >
    >make usg CC=gcc COPTS="-DSYS_HAS_SIGNAL_PROTO -DSYS_HAS_TIME_PROTO"
    >
    >Best wishes,
    >Derek.
    >


How do you get Solaris 2.4 ? I called SUN and they say it is not out yet!!!

Paulo de Souza



From jmccarro@barrow.uwaterloo.ca Sat Nov 12 03:47:00 1994
Date:         Sat, 12 Nov 94 03:47:00 -0500
From:         "James McCarron" <jmccarro@barrow.uwaterloo.ca>
Subject:      Re: Re: GAP on Solaris 2.3

Martin Schoenert writes:

   ...

>'gcc' does not seem to cause any problems.  Unfortunately for our user in
>Zimbabwe, getting GNU C would be a major undertaking.

	Walnut Creek CDROM (info@cdrom.com) delivers very quickly.  I got
alot of GNU source and Solaris binaries on CDROM from them (including gcc),
and it only took 3 days from California to Canada.  Prices seem reasonable
too, and they serve world wide, as I recall.

>The problems you had in 'system.c' were probably caused by a conflict
>between the declaration of 'signal' in 'system.c' and the Solaris include
>files.  In this case just building with
>'make COPTS=-DSYS_HAS_SIGNAL_PROTO' should also solve it.
>Could you check, whether this is true?

	Well I gave it a try, but this did not work for me.  The 
trouble I had was with conflicting prototypes for time. Here is the
make target I used:


> 	@echo "'sun-sparc-solaris2.3-gcc' for SUN under Solaris2.3(SunOS5.3) with gcc 2.6"
274a276,280
> sun-sparc-solaris2.3-gcc:
> 	@$(MAKE) system.o   CC=gcc  CFLAGS="$(COPTS)  -O6 -DSYS_IS_USG -DSYS_HAS_TIME_PROTO -DSOLARIS2" 
> 	@$(MAKE) gap        CC=gcc  CFLAGS="$(COPTS)  -O6"  SYS_FILE=system.o  LOPTS="$(LOPTS)"   

(The rest of the diff is just the RCS $Id$ field and a modified clean
target.)

The reason for the '-DSOLARIS2' is that I had to omit a couple of
prototypes in 'system.c'.  Here is part of a context diff of
system.c to illustrate the change I made:

***************
*** 1478,1486 ****
--- 1478,1489 ----
  #ifndef SYS_HAS_SIGNAL_PROTO            /* ANSI/TRAD decl. from H&S 19.6   */
  extern  sig_handler_t * signal P(( int, sig_handler_t * ));
  extern  int             getpid P(( void ));
+ #ifndef SOLARIS2
  extern  int             kill P(( int, int ));
  #endif
+ #endif
  
+ 
  #ifndef SYS_HAS_READ_PROTO              /* UNIX decl. from 'man'           */
  extern  int             read P(( int, char *, int ));
  extern  int             write P(( int, char *, int ));
***************
*** 2431,2437 ****
--- 2434,2442 ----
  #ifndef SYS_HAS_SIGNAL_PROTO            /* ANSI/TRAD decl. from H&S 19.6   */
  extern  sig_handler_t * signal P(( int, sig_handler_t * ));
  extern  int             getpid P(( void ));
+ #ifndef SOLARIS2
  extern  int             kill P(( int, int ));
+ #endif
  #endif
  
  #ifndef SYS_TIME_H                      /* time functions                  */

I confess I do not know why this was necessary, but it did work.
I should point out that this is from patch level 0, not patch
level 1, which I have yet to load onto my Sparc.
	I hope this information will be of some help to you or to 
our friend in Zimbabwe.  If there is anything else I can tell you
please let me know.

Cheers!

James



From mueller@mi.uni-erlangen.de Mon Nov 14 21:19:00 1994
Date:         Mon, 14 Nov 94 21:19:00 +0100
From:         "Peter Mueller" <mueller@mi.uni-erlangen.de>
Subject:      bug in PermutationCharacter

gap> g:=Group((1,7)(2,5)(3,6)(4,8), (1,5,3,7,2,8,4,6));;
gap> u:=Stabilizer(g,1);;
gap> pc:=PermutationCharacter(g,u);
Error, Variable: 'cl' must have a value at
Add( c, 
 Number( DoubleCosets( G, U, Subgroup( Parent( G ), [ cl[i].representative ] 
       ) ), function ( x ) ... end ) ) ... in
GroupOps.PermutationCharacter( arg[1], arg[2] ) called from
arg[1].operations.PermutationCharacter( arg[1], arg[2] ) called from
PermutationCharacter( g, u ) called from
main loop
brk> quit;

(Running on Gap3.4, patchlevel 1)



From Alexander.Hulpke@Math.RWTH-Aachen.DE Tue Nov 15 13:12:00 1994
Date:         Tue, 15 Nov 94 13:12:00 +1553
From:         "Alexander Hulpke" <Alexander.Hulpke@Math.RWTH-Aachen.DE>
Subject:      Re: bug in PermutationCharacter

Dear GAP-Forum,

Peter Mueller reported a bug in PermutationCharacter:

> gap> g:=Group((1,7)(2,5)(3,6)(4,8), (1,5,3,7,2,8,4,6));;
> gap> u:=Stabilizer(g,1);;
> gap> pc:=PermutationCharacter(g,u);
> Error, Variable: 'cl' must have a value at
[...]

I am completly mystified how this typo could creep into the library. I'm
quite sure, that it worked at the point of writing it. The fix (which will
be added in the next patch) is quite easy if you are in urgent need of it:
In the library file grpcoset.g replace in the function
GroupOps.PermutationCharacter

	        Subgroup( Parent(G), [cl[i].representative]) ),

by
	        Subgroup( Parent(G), [C[i].representative]) ),

(BTW: in this special case PermutationCharacter(g) would also do the work)

Sorry for the inconvenience,

Alexander Hulpke



From Martin.Schoenert@Math.RWTH-Aachen.DE Thu Nov 24 13:15:00 1994
Date:         Thu, 24 Nov 94 13:15:00 -0700
From:         "Martin Schoenert" <Martin.Schoenert@Math.RWTH-Aachen.DE>
Subject:      Re: GAP Forum article 422 rejected at 19 Nov 94 04:27 +0100

Your article to the GAP Forum was rejected, because you are not
subscribed to the GAP Forum.  However, I can answer your question
right away.  Some examples are contained in the first chapter
"About GAP" of the GAP Manual.  Apart from that now booklet is
available.  Some examples can be found in various files in
'ftp://ftp.math.rwth-aachen.de/pub/incoming/'.

Martin.

-- .- .-. - .. -.  .-.. --- ...- . ...  .- -. -. .. -.- .-
Martin Sch"onert,   Martin.Schoenert@Math.RWTH-Aachen.DE,   +49 241 804551
Lehrstuhl D f"ur Mathematik, Templergraben 64, RWTH, 52056 Aachen, Germany



From jmccarro@barrow.uwaterloo.ca Tue Dec  6 19:43:00 1994
Date:         Tue, 06 Dec 94 19:43:00 -0500
From:         "James McCarron" <jmccarro@barrow.uwaterloo.ca>
Subject:      how are library files used?

Hello:

	I wonder if someone can explain something  about how GAP uses its
library files (I mean the ones in lib/*.g ).  Does GAP need to read the 
appropriate file each time it uses a routine defined in the file, or are the
functions read when GAP starts up, and stored in memory for the duration of
the session. In other words, once GAP is started, does it still need these
library files?  I have looked through the source code but it is just too
vast for me to comprehend.
	Secondly, could someone tell me where to look in the source code to
find the code which handles the online help system.  I found a number of things
in 'system.c', but is it all localised to a single module, or does the help
system require parts from many different files.
	The reason I am wondering about these two things is that I am thinking
about whether it might be possible to make some not-too-difficult modification
which would enable GAP to be run with the files in 'lib' 'doc', and so on, as
compressed files (to save precious disk space).
	Any help or thoughts will be much appreciated.  Thanks!


James

-
James McCarron

Department of Pure Mathematics			Internet: jmccarron@barrow.uwaterloo.ca
University of Waterloo
Waterloo, Ontario
CANADA
N2L 3G1



From sal@cs.st-andrews.ac.uk Wed Dec  7 10:00:00 1994
Date:         Wed, 07 Dec 94 10:00:00 +0100
From:         "Steve Linton" <sal@cs.st-andrews.ac.uk>
Subject:      Re: how are library files used?

        06 Dec 94 19:43 -0500
> From: James McCarron <jmccarro@barrow.uwaterloo.ca>
> Subject:        how are library files used?
> 
> 
> 	I wonder if someone can explain something  about how GAP uses its
> library files (I mean the ones in lib/*.g ).  Does GAP need to read the 
> appropriate file each time it uses a routine defined in the file, or are the
> functions read when GAP starts up, and stored in memory for the duration of
> the session. In other words, once GAP is started, does it still need these
> library files?  I have looked through the source code but it is just too
> vast for me to comprehend.

The place to start looking is lib/init.g which contains many
sections of the form 

    AUTO( ReadLib( "abattoir" ),
      LengthString, SubString, ConcatenationString, Edit, ProductPol, ValuePol,
      MergedRecord, UnionBlist, IntersectionBlist, DifferenceBlist, SetPrintLevel,
      Save, SetPkgname, PKGNAME, LOADED_PACKAGES, ReadPkg, ExecPkg, LoadPackage,
      RequirePackage, OpsOps, OperationsRecord, EXEC, IsOddInt, IsEvenInt );
 
This defines the global variables LengthString etc. and sets them to
a special value such that when one of them is evaluated the command 
"ReadLib( "abattoir" )" is executed, and then the variable is
re-evaluated.  Reading this library file overwrites the values of
all these globals so that it will not be automatically read again.

In other words each library file is read once the first time it is
needed and then (unless the user forces it) never again. In practice
a large part of the library is read the first time you (for example)
construct a group, and then the remaining files trickle in by dribs
and drabs.

> 	Secondly, could someone tell me where to look in the source code to
> find the code which handles the online help system.  I found a number of things
> in 'system.c', but is it all localised to a single module, or does the help
> system require parts from many different files.

I think it is in system.c. Certainly it was last time I looked for
it.

> 	The reason I am wondering about these two things is that I am thinking
> about whether it might be possible to make some not-too-difficult modification
> which would enable GAP to be run with the files in 'lib' 'doc', and so on, as
> compressed files (to save precious disk space).

This should be possible, though I suspect that it would slow down the
GAP start-up (when most of the library is read) quite a lot. All
reading of files  is done in system.c, so it should be enough to
change a few routines there to look for <name>.gz as well as <name>
and set up a  gunzip process if needed. I think you just need to
look at SyFopen, SyFgets and SyFclose, but don't quote me on that.

One thing you can do is to strip comments and superfluous white
space from the library files. I once wrote a little PERL script to
do it, though I don't think I have it any more. You have to be
careful of quoted # signs, quoted \" characters and so on, but it
can be done.

I take it you have already deleted source and object files and given
thought to which of the group and character table libraries you
need.


	Steve



From jmccarro@barrow.uwaterloo.ca Wed Dec 14 19:27:00 1994
Date:         Wed, 14 Dec 94 19:27:00 -0500
From:         "James McCarron" <jmccarro@barrow.uwaterloo.ca>
Subject:      Re: how are library files used?

Hello again!

	Many thanks to Steve Linton for the helpful information.

With that help, I have studied the code, and tried a few things.
I am beginning to believe this is not as easy as I had hoped.
Rather than rewriting SyFopen, SyFclose, etc., I thought that it
might be safer to write wrapper functions for these two, and then
replace them by the wrapper functions at those places where I want
to open and close compressed files.
	For example, this is the wrapper function I have tried for
SyFopen:




long
GzFopen(char *name, char *mode)
{
	long fid;		/* file identifier */

	/* uncompress the file */
	Gunzip(name);

	/* open the file */
	fid = SyFopen(name, mode);

	/* record the name of the file in syBuf[fid] */
	syBuf[fid].fname = (char *)malloc(1 + sizeof(name)/sizeof(char));
	syBuf[fid].fname = name;

	return fid;

}	/* GzFopen */



The function 'Gunzip' simply uncompresses the file "name" using
SyExec.

This required changing the structure 'syBuf' in system.c, adding the
component

char fname[MAXPATHLEN];

This seems to be necessary so that, when the fid is passed to the
corresponding function 'GzFclose', which closes and then compresses
a file, we can recover the filename to pass to SyExec.
	The function GzFclose takes the fid as argument, and simply
closes the file and then compresses it with a function 'Gzip', which
requires the filename;hence, the requirement for the change to syBuf.
	For the moment, I am just playing with the online help.  It seems
a safer place to experiment than with the library files *.g.
	Okay, sounds good so far.  However, when I replace all the calls
to SyFopen and SyFclose in the function SyHelp (in system.c), everything
seems to work just fine, until I try to use the online help.  I think
there must be other calls to these functions, outside of SyHelp, which I
have not found.  When I try to call the online help with, say

gap>?Chapters

Gap replies that it cannot find the file 'manual.toc'.  (I have compressed
all the manual files).  If I uncompress manual.toc before trying this,
Gap will give me the list of Chapters as per normal.  As expected, when
the command is complete, the file manual.toc ends up compressed.  So maybe
GzFclose is working.  However, any subsequent request to list chapters
fails as before.
	The question is: Why might Gap not be able to find the manual.toc
file when it is compressed?
	From the comments in 'system.c', I realise that malloc should not
be used.  I tried this with 'SyGetmem' in place of 'malloc', but when I
use that, it gives me a Bus error and core dump.  (and really messes my
terminal :-)  I wonder if I may not be using 'SyGetmem' correctly?  I have
used it exactly where i have 'malloc' above (same args, etc.).
	I have only tried this sort of thing before in shell scripts, where
I can set up a pipeline.  I wonder whether there might be a better solution
along those lines.  In a shell script, one can do something like:

zcat $file | nroff -man | more

to read compressed manual pages.  Could something like this be done in C,
replacing 'nroff -man | more' part by the SyHelp function? Perhaps the
way to handle this idea is to extract the help system as a standalone
program which could be run in a different window.  Hmmm... I am perplexed.
Any suggestions?

	By the way, is there any documentation on the implementation of GAP?
It occurs to me that some of GAP's authors might have written papers on
the *implementation* (as opposed to user documentation, which is, of course,
excellent).  I found none in the bibliography of the manual.  
But a project of this size must surely
have been documented in the literature?  Perhaps if I studied some of this
more technical material, it would help me navigate the code.

	Thanks again!

James

P.S.  Apologies for the delay  -- it's that time of year again, when final
exams must be graded. :-)


James McCarron

Department of Pure Mathematics			Internet: jmccarron@barrow.uwaterloo.ca
University of Waterloo
Waterloo, Ontario
CANADA
N2L 3G1



From sal@cs.st-andrews.ac.uk Thu Dec 15 10:31:00 1994
Date:         Thu, 15 Dec 94 10:31:00 +0100
From:         "Steve Linton" <sal@cs.st-andrews.ac.uk>
Subject:      Re: how are library files used?

This was getting rather technical, so I have sent a long reply
directly to James (copied to the gap-trouble list) if anyone else
wants a copy, or wants to be included in the thread, let me know.

	Steve



From Martin.Schoenert@Math.RWTH-Aachen.DE Thu Dec 15 23:45:00 1994
Date:         Thu, 15 Dec 94 23:45:00 -0700
From:         "Martin Schoenert" <Martin.Schoenert@Math.RWTH-Aachen.DE>
Subject:      Re: Re: how are library files used?

James McCarron wrote in his e-mail message of 1994/12/14

    With that help, I have studied the code, and tried a few things.
    I am beginning to believe this is not as easy as I had hoped.

I think it is easier than you believe.

James continued

    Rather than rewriting SyFopen, SyFclose, etc., I thought that it
    might be safer to write wrapper functions for these two, and then
    replace them by the wrapper functions at those places where I want
    to open and close compressed files.
	For example, this is the wrapper function I have tried for
    SyFopen:

    long
    GzFopen(char *name, char *mode)
    {
	long fid;		/* file identifier */

	/* uncompress the file */
	Gunzip(name);

	/* open the file */
	fid = SyFopen(name, mode);

	/* record the name of the file in syBuf[fid] */
	syBuf[fid].fname = (char *)malloc(1 + sizeof(name)/sizeof(char));
	syBuf[fid].fname = name;

	return fid;

    }	/* GzFopen */

    The function 'Gunzip' simply uncompresses the file "name" using
    SyExec.

    This required changing the structure 'syBuf' in system.c, adding the
    component

    char fname[MAXPATHLEN];

    This seems to be necessary so that, when the fid is passed to the
    corresponding function 'GzFclose', which closes and then compresses
    a file, we can recover the filename to pass to SyExec.

If you really declared the component as 'char fname[MAXPATHLEN]'
(and not 'char *fname') then storage for 'fname' is statically allocated,
and there is no need to allocate storage for 'fname' dynamically.
In fact in this case 'syBuf[fid].fname' is *not* a valid left-hand-side
and your compiler should complain about 'syBuf[fid].fname = malloc(...)'.
In any case you need to copy the *contents* of 'name' to 'fname',
not the *pointer*, i.e., you need to write
'SyStrncat( syBuf[fid].fname, name, MAXPATHLEN-1 );'

James continued

	For the moment, I am just playing with the online help.  It seems
    a safer place to experiment than with the library files *.g.

Working with the online help may actually be more difficult than working
with the library.

James continued

	Okay, sounds good so far.  However, when I replace all the calls
    to SyFopen and SyFclose in the function SyHelp (in system.c), everything
    seems to work just fine, until I try to use the online help.  I think
    there must be other calls to these functions, outside of SyHelp, which I
    have not found.  When I try to call the online help with, say

    gap>?Chapters

    Gap replies that it cannot find the file 'manual.toc'.  (I have compressed
    all the manual files).  If I uncompress manual.toc before trying this,
    Gap will give me the list of Chapters as per normal.  As expected, when
    the command is complete, the file manual.toc ends up compressed.  So maybe
    GzFclose is working.  However, any subsequent request to list chapters
    fails as before.
	The question is: Why might Gap not be able to find the manual.toc
    file when it is compressed?

If 'Gunzip' really does what you say, then I see no reason why this
should not work.  Note that there are many calls to 'SyFopen' in
'SyHelp', maybe you missed one?  'SyHelp' is selfcontained, there
is nothing outside of 'SyHelp' that influences 'SyHelp', except
for the setting of the pathname 'Helpname' in 'SyInit'.

James continued

	From the comments in 'system.c', I realise that malloc should not
    be used.  I tried this with 'SyGetmem' in place of 'malloc', but when I
    use that, it gives me a Bus error and core dump.  (and really messes my
    terminal :-)  I wonder if I may not be using 'SyGetmem' correctly?  I have
    used it exactly where i have 'malloc' above (same args, etc.).

If you declare 'fname' as 'char fname[MAXPATHLEN]', the storage is
allocated statically (when GAP starts), and there is no need to
allocate something dynamically.  So you don't need 'malloc' or
'SyGetmem' then.  Using either is not a very good idea, because it
usually has the effect that GAP cannot extend its workspace anymore.

James continued

	I have only tried this sort of thing before in shell scripts, where
    I can set up a pipeline.  I wonder whether there might be a better
    solution along those lines.

Here is such a solution.

--- system.c.orig	Thu Dec 15 10:49:13 1994
+++ system.c	Thu Dec 15 10:49:19 1994
@@ -510,6 +510,10 @@
 # include       <stdio.h>
 # define SYS_STDIO_H
 #endif
+#ifndef SYS_UNISTD_H                    /* definition of 'R_OK'            */
+# include       <unistd.h>
+# define SYS_UNISTD_H
+#endif
 #ifndef SYS_HAS_STDIO_PROTO             /* ANSI/TRAD decl. from H&S 15     */
 extern  FILE *          fopen P(( SYS_CONST char *, SYS_CONST char * ));
 extern  int             fclose P(( FILE * ));
@@ -521,6 +525,7 @@
 struct {
     FILE *      fp;                     /* file pointer for this file      */
     FILE *      echo;                   /* file pointer for the echo       */
+    long        pipe;                   /* file is really a pipe           */
     char        buf [BUFSIZ];           /* the buffer for this file        */
 }       syBuf [16];
 
@@ -552,6 +557,8 @@
     char *              mode;
 {
     long                fid;
+    char                namegz [1024];
+    char                cmd [1024];
 
     /* handle standard files                                               */
     if ( SyStrcmp( name, "*stdin*" ) == 0 ) {
@@ -578,10 +585,26 @@
     if ( fid == sizeof(syBuf)/sizeof(syBuf[0]) )
         return (long)-1;
 
+    /* set up <namegz> and <cmd> for pipe command                          */
+    namegz[0] = '\0';
+    SyStrncat( namegz, name, sizeof(namegz)-5 );
+    SyStrncat( namegz, ".gz", 4 );
+    cmd[0] = '\0';
+    SyStrncat( cmd, "gunzip <", 9 );
+    SyStrncat( cmd, namegz, sizeof(cmd)-10 );
+
     /* try to open the file                                                */
-    syBuf[fid].fp = fopen( name, mode );
-    if ( syBuf[fid].fp == (FILE*)0 )
+    if      ( (syBuf[fid].fp = fopen(name,mode)) ) {
+        syBuf[fid].pipe = 0;
+    }
+    else if ( SyStrcmp(mode,"r") == 0
+           && access(namegz,R_OK) == 0
+           && (syBuf[fid].fp = popen(cmd,mode)) ) {
+        syBuf[fid].pipe = 1;
+    }
+    else {
         return (long)-1;
+    }
 
     /* allocate the buffer                                                 */
     setbuf( syBuf[fid].fp, syBuf[fid].buf );
@@ -613,7 +636,8 @@
     }
 
     /* try to close the file                                               */
-    if ( fclose( syBuf[fid].fp ) == EOF ) {
+    if ( (syBuf[fid].pipe == 0 && fclose( syBuf[fid].fp ) == EOF)
+      || (syBuf[fid].pipe == 1 && pclose( syBuf[fid].fp ) == -1) ) {
         fputs("gap: 'SyFclose' cannot close file, ",stderr);
         fputs("maybe your file system is full?\n",stderr);
     }
@@ -4194,12 +4218,12 @@
             SyHelpname[0] = '\0';
 #if SYS_BSD || SYS_MACH || SYS_USG || SYS_OS2_EMX
             SyStrncat( SyHelpname, argv[2], sizeof(SyLibname)-2 );
-            if ( SyLibname[SyStrlen(SyHelpname)-1] != '/' )
+            if ( SyHelpname[SyStrlen(SyHelpname)-1] != '/' )
                 SyStrncat( SyHelpname, "/", 1 );
 #endif
 #if SYS_MSDOS_DJGPP || SYS_TOS_GCC2
             SyStrncat( SyHelpname, argv[2], sizeof(SyLibname)-2 );
-            if ( SyLibname[SyStrlen(SyHelpname)-1] != '\\' )
+            if ( SyHelpname[SyStrlen(SyHelpname)-1] != '\\' )
                 SyStrncat( SyHelpname, "\\", 1 );
 #endif
             ++argv; --argc;

On each open, it first tests whether there is an uncompressed file
that can be used.  If not and the open is for reading, then it
tests whether there is a compressed file.  If so, it opens a
*pipe* from 'gunzip' and reads from that pipe.  We only need to
remember (in 'syBuf[fid]') whether the file is a proper file
or a pipe, so that we can use 'fclose' or 'pclose' as appropriate.
You may have to tweak the code a little bit, depending on where
stuff like 'R_OK' is declared (you may also need to add
'COPTS=-DSYS_HAS_READ_PROTO' to the 'make' command).

This works very nicely for me.  'lib' and 'doc' now take less
than 1 MByte each, and the performance penalty is not dramatic.

But this only works under UNIX (or other systems that support 'popen').
On the other hand compressing library files and documentation might
be more important on DOS or Macintosh systems.  And then again on
those systems already support compression at the file system level,
so compressing the files again may not gain that much.  Perhaps the
nicest solution would be to incorporate part of the 'unzoo' source in
'system.c', so that GAP can read files directly from the 'zoo' archives,
without the need to start a separate process.  This should be possible,
but quite a bit more complicated than the above solution.

James continued

	By the way, is there any documentation on the implementation of GAP?
    It occurs to me that some of GAP's authors might have written papers on
    the *implementation* (as opposed to user documentation, which is, of
    course, excellent).  I found none in the bibliography of the manual.  
    But a project of this size must surely
    have been documented in the literature?  Perhaps if I studied some of this
    more technical material, it would help me navigate the code.

No, there is no documentation on the implementation of GAP, except for
the comments in the source files.  We agree that there should be such
documentation.  And we plan to write some such reports for the next
version of GAP.  There already is a longish report on the new storage
manager available at 'ftp://ftp.math.rwth-aachen.de/pub/gasman/'.

Martin.

-- .- .-. - .. -.  .-.. --- ...- . ...  .- -. -. .. -.- .-
Martin Sch"onert,   Martin.Schoenert@Math.RWTH-Aachen.DE,   +49 241 804551
Lehrstuhl D f"ur Mathematik, Templergraben 64, RWTH, 52056 Aachen, Germany



From charnes@osiris.cs.uow.edu.au Fri Dec 16 14:59:00 1994
Date:         Fri, 16 Dec 94 14:59:00 +1100
From:         "Chris Charnes" <charnes@osiris.cs.uow.edu.au>
Subject:      matrix groups

Dear Martin, I have a question regarding matrix groups (I don't know if I have choosen
the right forum).

I am calculating some group data with GAP 3.3 
for groups  defined by (4x4) generators over GF(7). 
I am interested in particular in the factors of the
derived series of the groups. Would  the running time be shorter if the groups
were defined by a smaller set of generators? (Say 5 instead of 13.)

Yours, C. Charnes



From Frank.Celler@Math.RWTH-Aachen.DE Tue Dec 20 14:39:00 1994
Date:         Tue, 20 Dec 94 14:39:00 -0700
From:         "Frank Celler" <Frank.Celler@Math.RWTH-Aachen.DE>
Subject:      matrix groups

Dear Chris,

you asked:

    I am calculating some group data with GAP 3.3 for groups defined
    by (4x4) generators over GF(7).  I am interested in particular in
    the factors of the derived series of the groups. Would the running
    time be shorter if the groups were defined by a smaller set of
    generators? (Say 5 instead of 13.)

there are various  ways to speed  up the calculations depending on the
exact nature  of your  problem.  If you  are  just  interested in  the
abelian invariants it  would be  sensible  to compute  for each matrix
group an isomorphic permutation group  using  'PermGroup' and to  work
with this  permutation  group.  Again, depending  on  our  problem, it
might  be faster  to first convert  the factor  group to a permutation
group using 'PermGroup' before computing the abelian invariants.

There  are other possible  speedups.   The  'PermGroup' conversion  is
quite slow, so you could either

- try the function below which  will use boolean  list to speed up the
conversion from a matrix  group over a finite  field to  a permutation
group or

-  try to construct  your matrix  groups as  subgroups of  (one fixed)
$GL(4,7)$, this  will avoid the orbit calculation   for each group but
your permutation groups will have much larger degrees.

best wishes
  Frank

=============================================================================
#############################################################################
##
#F  MatGroupOps.MakePermGroupP(<G>) . . . make a isomorphic permutation group
##
##  The difference between this function and the usual  'PermGroup'  is  that
##  the permutation group constructed for <G>  will  be  a  subgroup  of  the
##  corresponding permutation group of <G>'s parent.
##
orbitFiniteFieldMatGroup := function ( G, d )
    local   pow,  size,  i,  int,  blt,  orb,  pnt,  gen,  img,  num;

    # set up an enumerator for finite field vectors
    pow  := [1];
    size := Size(G.field);
    for i  in [ 1 .. Length(d)-1 ]  do
        pow[i+1] := pow[i]*size;
    od;
    int := [ 1 .. size-1 ];
    IsVector(int);

    # construct a bit list
    size := size^G.dimension;
    blt  := BlistList( [1..size], [] );

    # start the orbit algorithm with vector <d>
    orb := [d];
    blt[NumberVecFFE(d,pow,int)] := true;

    for pnt  in orb  do
        for gen  in G.generators  do
            img := pnt ^ gen;
            num := NumberVecFFE( img, pow, int );
            if not blt[num]  then
                Add( orb, img );
                blt[num] := true;
            fi;
        od;
    od;

    # and return
    return orb;

end;

MatGroupOps.MakePermGroupP := function ( G )
    local   P,  domain,  p;

    # get the parent of <G>
    P := Parent(G);

    # if <P> is not finite compute the perm representation in <G>
    if IsBound(P.isFinite) and not P.isFinite  then
        if not IsBound( G.permGroupP )  then
            G.permDomain := Union( Orbits( G, G.identity ) );
            G.permGroupP := Operation( G, G.permDomain );
        fi;

    # otherwise compute the perm representation for the parent
    else
        if not IsBound(P.permDomain)  then

            # if <P> is written over a finite field use blists
            if IsBound(P.field) and IsFinite(P.field)  then
                domain := [];
                for p  in P.identity  do
                    UniteSet( domain, orbitFiniteFieldMatGroup( P, p ) );
                od;
                P.permDomain := domain;

            # otherwise use normal orbit operation
            else
                G.permDomain := Union( Orbits( G, G.identity ) );
            fi;
            P.permGroupP := Operation( P, P.permDomain );
        fi;

        # compute the isomorphic permutation group for <G>
        if not IsBound(G.permGroupP)  then
            G.permDomain := P.permDomain;
            G.permGroupP := Subgroup( P.permGroupP,
                                  Operation( G, P.permDomain ).generators );
        fi;
    fi;

end;



From hwblist@machnix.mathematik.uni-stuttgart.de Tue Dec 20 15:42:00 1994
Date:         Tue, 20 Dec 94 15:42:00 +0100
From:         "Harald Boegeholz" <hwblist@machnix.mathematik.uni-stuttgart.de>
Subject:      an application of GAP for computations in Hecke algebras

Dear forum,


I'd recently finished my thesis to get my Diplom in mathematics. In my
work, I used GAP to compute a basis for the centre of the Hecke
algebra of type A_n which consists of symmetric polynomials in Murphy
operators. 

Just in case it might be of interest to anyone, I'd like to announce
here that my work is availble via WWW (see my signature below). It is
in German, of course (except for the GAP programs, which are written
in GAP and English).

The programs contain two functions that might be of general
interest. Since GAP has no mechanism for saving the whole workspace in
a file, I wrote two functions (MurphyLoad and MurphySave, see
pg. 73ff) that save and load certain results to/from a file. I found
that saving/loading polynomials the straightforward way (PrintTo a
file and Read it back) ist far slower than what I do now, so maybe
someone can use this technique elsewhere.


Harald Boegeholz

-- 
Harald Boegeholz |   hwb@mathematik.uni-stuttgart.de
                 |   os2a@ftp.uni-stuttgart.de
      http://www.mathematik.uni-stuttgart.de/mathB/lst3/hwb.html



From Joachim.Neubueser@Math.RWTH-Aachen.DE Wed Dec 21 17:23:00 1994
Date:         Wed, 21 Dec 94 17:23:00 +0100
From:         "Joachim Neubueser" <Joachim.Neubueser@Math.RWTH-Aachen.DE>
Subject:      Reports

Dear Colleagues,

I would  like to thank Harald Boegeholz  for  his short report  on the
work on Hecke    Algebras he has  done  using  GAP,  for  making  this
available (via WWW), and  for  offering  some  functions that he   has
written for general use.

As  I have done before, I  would like to  encourage to send such short
reports on  work done  with GAP to   the forum,  to provide access  to
written documentation of such work, and to offer GAP functions written
for specific problems for general  use.  Since we are meanwhile  about
350  forum  members,  I  think there   is a  good    chance  that such
information will be helpful for others.

With kind regards    Joachim Neubueser



From Thomas.Breuer@Math.RWTH-Aachen.DE Thu Dec 22 16:22:00 1994
Date:         Thu, 22 Dec 94 16:22:00 WET
From:         "Thomas Breuer" <Thomas.Breuer@Math.RWTH-Aachen.DE>
Subject:      Vector Spaces in GAP-3.4

Dear Mrs. and Mr. Forum,

today 'gap-trouble' got a message about a problem with vector spaces in GAP.
Perhaps it is useful to tell this story to you, too.

Suppose you have a (row) vector space <V> and a list of vectors that form
a basis of <V>, and you want to compute the coefficients of arbitrary
vectors in <V> with respect to this basis.
In GAP-3.4 there is a solution for this, contrary to previous versions.

In GAP-3.3 only very special vector space bases were supported.
If the user wanted to define a basis for <V> this was done
by 'AddBase( <V>, <vectors> )', and if <vectors> was not a matrix in upper
triangular form then the basis could not be used for the computation of
coefficients.

In GAP-3.4 another mechanism is used to deal with bases of row spaces.
Such a basis is now a record constructed by 'Basis( <V>, <vectors> )'.
The basis knows about the space, the basis vectors, and how to compute
coefficients.
This means the basis is asked for the coefficients of a vector, not the
space.
The main differences between the mechanisms in GAP-3.3 and GAP-3.4 are
that in GAP-3.4 arbitrary row space bases can be defined, and that one
can deal with several bases for the same space.

Here is an example.

    gap> # Construct the space.
    gap> vectors:= [ [ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ], 
    >                [ 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0 ], 
    >                [ 1, 1, 1, 0, 0, 0, 1, 1, 1, 0, 0, 0 ], 
    >                [ 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 0, 0 ], 
    >                [ 0, 1, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1 ], 
    >                [ 0, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1 ] ] * Z(3)^0;;
    gap> golay:= VectorSpace( vectors, GF(3) );
    RowSpace( GF(3), 
    [ [ Z(3)^0, Z(3)^0, Z(3)^0, Z(3)^0, Z(3)^0, Z(3)^0, Z(3)^0, Z(3)^0,
          Z(3)^0, Z(3)^0, Z(3)^0, Z(3)^0 ], 
      [ Z(3)^0, Z(3)^0, Z(3)^0, Z(3)^0, Z(3)^0, Z(3)^0, 0*Z(3), 0*Z(3),
          0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ], 
      [ Z(3)^0, Z(3)^0, Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, Z(3)^0,
          Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3) ], 
      [ Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, Z(3)^0, 0*Z(3), Z(3)^0,
          Z(3)^0, Z(3)^0, 0*Z(3), 0*Z(3) ], 
      [ 0*Z(3), Z(3)^0, 0*Z(3), 0*Z(3), Z(3)^0, Z(3)^0, Z(3)^0, 0*Z(3),
          Z(3)^0, 0*Z(3), 0*Z(3), Z(3)^0 ], 
      [ 0*Z(3), 0*Z(3), Z(3)^0, Z(3)^0, 0*Z(3), Z(3)^0, 0*Z(3), Z(3)^0,
          Z(3)^0, 0*Z(3), 0*Z(3), Z(3)^0 ] ] )
    gap> Dimension( golay );
    6
    gap> 
    gap> # Define the basis.
    gap> b:= Basis( golay, golay.generators );;
    gap> 
    gap> # Compute coefficients.
    gap> List( golay.generators, x -> Coefficients( b, x ) );
    [ [ Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ], 
      [ 0*Z(3), Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3) ], 
      [ 0*Z(3), 0*Z(3), Z(3)^0, 0*Z(3), 0*Z(3), 0*Z(3) ], 
      [ 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, 0*Z(3), 0*Z(3) ], 
      [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0, 0*Z(3) ], 
      [ 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), 0*Z(3), Z(3)^0 ] ]
    gap> 

Kind regards
Thomas Breuer


