GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
#include "defs.h"1#include "permfns.h"23#define RD(A,B) (done[(B)/32][(A)]&(one<<((B)%32)))4#define WD(A,B) done[(B)/32][(A)]|=(one<<((B)%32))5extern char inf[],outf[],outfg[],gap,firstnew;6extern int imsp[],*done[],*imcos[];7extern short perm[],sv[],cp[],orb[],8base[],lorb[],pno[], *pptr[],*svptr[],9inv[],rno[],mp,mrel,dnwds,mpt,mb;10extern int psp,svsp,space;11int nr,endr,maxcos,*fpt,*bpt,*def,scanno,nscan,nelim,bno,lo,12ccos,lastd,cind,nfree,stcr,endcr,fcos,bcos,lcl,np2,*rel,one=1;13short npt;14int rsp;15char fullsc,clsd,lkah;16FILE *ip,*op;17/* Many of the variables are as in program tcrun */1819int20grprog (void)21{ int i,j,k,l,m,n,b,l1,l2,nb,rn1,nperms,npt1,mxp,min,mini;22int spn,quot; float a;23ip=fopen(inf,"r");24if (ip==0) { fprintf(stderr,"Cannot open %s\n",inf); return(-1); }25fscanf(ip,"%hd%d%d%d",&npt,&nperms,&nb,&k);26if (npt>mpt) { fprintf(stderr,"npt too big. Increase NPT.\n"); return(-1);}27if (nb>=mb) { fprintf(stderr,"nb too big. Increase MB.\n"); return(-1); }28if (nb*npt>svsp)29{ fprintf(stderr,"Out of sv space.Increase SVSP.\n"); return(-1);}30if (k<=0) {fprintf(stderr,"Wrong input format.\n"); return(-1); }31npt1=npt+1; np2=2*nperms-1;32quot=psp/npt1; if (quot>mp) quot=mp; mxp=quot;33for (i=0;i<mxp;i++) pptr[i]=perm+i*npt1-1;34for (i=1;i<=nb;i++) svptr[i]=sv+(i-1)*npt-1;35if (np2>=mxp)36{ fprintf(stderr,"nperms too big. Increase PSP (or MP).\n"); return(-1); }37readbaselo(nb,base,lorb); readpsv(0,nb,nperms,svptr);38fclose(ip);39for (i=0;i<np2;i+=2) { inv[i]=i+1; inv[i+1]=i; }4041/* Group is read in. Now initialize coset table for enumaration. */42printf("Input a,b,l1,l2.\nmaxcos = a*lorb+b\n");43printf("Exit lookahead after scanning l1 or eliminating l2 cosets.\n");44scanf("%f%d%d%d",&a,&b,&l1,&l2);45mrel=dnwds*32; maxcos=a*npt+b; spn=maxcos*(np2+4+dnwds)+1;46if (spn>space)47{ fprintf(stderr,"Not enough space in coset table. Increase SPACE.\n");48return(-1);49}50rel=imsp+spn; rsp=space-spn;51for (i=0;i<=np2;i++) imcos[i]=imsp+i*maxcos-1;52fpt=imcos[np2]+maxcos+1; bpt=fpt+maxcos; def=bpt+maxcos;53for (i=0;i<dnwds;i++) done[i]=def+maxcos*(i+1);5455if (gap) {op=fopen(outfg,"w"); fprintf(op,"COHOMOLO.PermRels := [\n");}56nr=0; endr= -1;57for (bno=nb;bno>=1;bno--)58{ printf("bno=%d.\n",bno);59/* We are going to do a coset enumeration of the group G[bno] (in the stabilizer60chain), using genrators of G[bno+1] as subgroup.61First we write in as many entries in the coset table as possible, making62definitions of the cosets corresponding to the points in the orbit of bno63under G[bno], using the Schreier vector sv[bno]. At the end of the64enumeration, only these cosets should remain, and none of them should get65eliminated.66*/67lo=lorb[bno]; rno[bno]=nr; maxcos=lo*a+b; rn1=nr-1; *pno=0;68for (i=0;i<=np2;i++) for (j=1;j<=maxcos;j++) imcos[i][j]=0;69for (i=0;i<np2;i+=2) if (pptr[i][npt1]>=bno)70{ (*pno)++; pno[*pno]=i;71if (pptr[i][npt1]>bno) {imcos[i][1]=1; imcos[i+1][1]=1;}72}73if (orbitsv(base[bno],svptr[bno],0)!=lo)74{ fprintf(stderr,"Orbit length wrong!\n"); return(-1); }75if (lo==1) continue;76def[1]= -1;77for (l=1;l<=lo;l++)78{ n=orb[l]; cp[n]=l;79if ((k=svptr[bno][n])!= -1)80{ j=pptr[k][n]; m=cp[j]; imcos[k-1][m]=l; imcos[k][l]=m; def[l]=k; }81}82/* Now we initialize the relator set, by putting in one relator for each83generator in G[bno].84*/85for (i=0;i<np2;i+=2) if (pptr[i][npt1]==bno)86{ *cp=1; cp[1]=i+1;87for (j=bno;j<=nb;j++) addsv(image(base[j]),svptr[j]);88if (addrel()== -1) return(-1);89}9091/* Since new relators will be added in the course of the enumeration, we want92to avoid scanning the same coset under the same relator more than once.93The array done records which pairs have been scanned in compressed form,94using one bit for each coset-relator pair.95WD(a,b) writes a one into the bit corresponding to coset a and relator b.96RD(a,b) returns the value of this bit.97*/98for (j=0;j<dnwds;j++) for (i=1;i<=lo;i++) done[j][i]=0;99for (i=0;i<=rn1;i++) WD(1,i);100/* Now we start the enumeration, as in tcrun */101lastd=lo; cind=lo; nfree=lo+1;102for (i=1;i<=lo;i++) bpt[i]=i-1;103for (i=0;i<maxcos;i++) fpt[i]=i+1;104fpt[lo]=0; fpt[maxcos]=0;105while(1)106{ ccos=1; lkah=0;107while (ccos!=0)108{ clsd=1; endcr= -1; scanno= -1;109while (endcr!=endr)110{ scanno++; fullsc=1;111stcr=endcr+2; endcr+=(1+rel[stcr-1]);112if (RD(ccos,scanno)==0) scanrel();113if (fullsc==0)114{ clsd=0;115if (lkah==0)116{ lcl=bpt[ccos]; lkah=1; nscan=0; nelim=0;117/* printf("Entering lookahead.\n"); */118}119}120}121ccos=fpt[ccos];122if (lkah)123{ nscan++;124if (nscan>l1 || nelim>=l2 || ccos==0)125{ if (cind!=maxcos)126{ /* printf("Exiting lookahead. cind=%d.\n",cind); */127ccos=fpt[lcl]; lkah=0;128}129else ccos=0;130}131}132}133if (cind==lo) break;134/* The enumeration did not complete, so we add a new relator */135if (firstnew) i=fpt[lo]; else136{ min=0;137for (n=fpt[lo];n!=0;n=fpt[n])138{ *cp=0; i=n;139for (j=def[i];j!= -1;j=def[i]) { (*cp)++; cp[*cp]=j; i=imcos[j][i]; }140for (i=1,j= *cp;i<=j;i++,j--)141{ if (i==j) cp[i]=inv[cp[i]];142else { k=cp[i]; cp[i]=inv[cp[j]]; cp[j]=inv[k]; }143}144for (i=bno;i<=nb;i++) addsv(image(base[i]),svptr[i]);145if (min==0 || *cp<min) { min= *cp; mini=n;}146}147i=mini;148}149*cp=0;150for (j=def[i];j!= -1;j=def[i]) { (*cp)++; cp[*cp]=j; i=imcos[j][i]; }151for (i=1,j= *cp;i<=j;i++,j--)152{ if (i==j) cp[i]=inv[cp[i]];153else { k=cp[i]; cp[i]=inv[cp[j]]; cp[j]=inv[k]; }154}155for (i=bno;i<=nb;i++) addsv(image(base[i]),svptr[i]);156if (addrel()== -1) return(-1);157}158}159if (gap) {fprintf(op,"];\n"); fclose(op);}160op=fopen(outf,"w");161fprintf(op,"%3d ",nb); for (i=1;i<=nb;i++) fprintf(op,"%4d",rno[i]);162fprintf(op,"\n");163m= -1;164while (m!=endr)165{ m++; l=rel[m];166for (i=0;i<=l;i++) fprintf(op,"%4d",rel[m+i]);167fprintf(op,"\n"); m+=l;168}169return(0);170}171172int173addrel (void)174/* Adds a relator */175{ int i,j,k;176nr++;177if (nr>mrel)178{ fprintf(stderr,"Too many relations. Increase MREL.\n"); return(-1); }179if (endr+ *cp+1 >=rsp)180{ fprintf(stderr,"Out of relation space. Increase SPACE.\n"); return(-1); }181endr++; rel[endr]= *cp;182for (i=1;i<= *cp;i++) rel[endr+i]=inv[cp[*cp+1-i]];183rno[bno]++; endr+= *cp;184if (gap)185{ if (nr>1) fprintf(op,",\n");186putc('[',op);187for (i=1;i<= *cp;i++)188{ j=cp[*cp+1-i]; k= (j%2==0) ? -(j/2 +1) : (j/2 +1);189fprintf(op,"%d",k);190if (i< *cp) putc(',',op); else putc(']',op);191}192}193for (i=1;i<= *cp;i++)194{ j=cp[*cp+1-i]; k= (j%2==0) ? -(j/2 +1) : (j/2 +1);195printf("%2d",k);196if (i< *cp) printf(" * "); else printf("\n");197}198return(0);199}200201int202scanrel (void)203{ int i,j,k,l,m; char comp;204fcos=ccos; bcos=ccos;205comp=1;206for (i=stcr;i<=endcr;i++)207{ k=imcos[rel[i]][fcos];208if (k==0) { comp=0; break;}209fcos=k;210}211if (comp) { if (fcos!=bcos) coinc(fcos,bcos); WD(ccos,scanno); return(0); }212stcr=i;213for (i=endcr;i>=stcr;i--)214{ l=rel[i]; m=inv[l]; k=imcos[m][bcos];215if (k==0)216{ if (i==stcr)217{ k=imcos[l][fcos];218if (k==0) { imcos[l][fcos]=bcos; imcos[m][bcos]=fcos; }219else if (k!=bcos) coinc(k,bcos);220WD(ccos,scanno); return(0);221}222if (lkah || nfree==0) { fullsc=0; return(0); }223for (j=0;j<=np2;j++) imcos[j][nfree]=0;224for (j=0;j<dnwds;j++) done[j][nfree]=0;225cind++; def[nfree]=l;226imcos[m][bcos]=nfree; imcos[l][nfree]=bcos; bcos=nfree;227bpt[nfree]=lastd; fpt[lastd]=nfree; lastd=nfree;228nfree=fpt[nfree]; fpt[lastd]=0;229}230else bcos=k;231}232if (fcos!=bcos) coinc(fcos,bcos);233WD(ccos,scanno);234return(0);235}236237int238coinc (int c1, int c2)239{ int lc,hc,qh,qt,i,j,y,fhc,bhc,lim,him,x; char sw;240lc=1;241while (lc!=c1 && lc!=c2) lc=fpt[lc];242hc= lc==c1 ? c2 : c1;243if (hc<=lo) {fprintf(stderr,"Impossible coincidence.\n"); return(-1); }244/* Cosets with numbers <=lo should certainly not be eliminated! */245qh=0; qt=0;246fhc=fpt[hc]; bhc=bpt[hc]; fpt[bhc]=fhc;247if (fhc==0) lastd=bhc; else bpt[fhc]=bhc;248if (ccos==hc) { ccos=bhc; endcr=endr; clsd=0; }249if (lkah && lcl==hc) lcl=bhc;250while (1)251{ fpt[hc]=nfree; nfree=hc; cind--; nelim++;252x=1; sw=0;253while (x<= *pno)254{ if (sw) i++; else i=pno[x];255him=imcos[i][hc];256if (him!=0)257{ j=inv[i]; lim=imcos[i][lc];258if (him==hc) him=lc; else imcos[j][him]=0;259if (lim==0) imcos[i][lc]=him;260else261{ if (lim==hc) { imcos[i][lc]=lc; lim=lc; }262while (fpt[him]<0) him= -fpt[him];263while (fpt[lim]<0) lim= -fpt[lim];264if (him!=lim)265{ y=1;266while (y!=him && y!=lim) y=fpt[y];267if (y==him) { him=lim; lim=y; }268if (him<=lo)269{ fprintf(stderr,"Impossible coincidence(q).\n"); return(-1); }270fhc=fpt[him]; bhc=bpt[him]; fpt[bhc]=fhc;271if (fhc==0) lastd=bhc; else bpt[fhc]=bhc;272if (ccos==him) { ccos=bhc; endcr=endr; clsd=0; }273if (lkah && lcl==him) lcl=bhc;274fpt[him]= -lim;275if (qh==0) qh=him; else bpt[qt]=him;276qt=him; bpt[qt]=0;277}278}279y=imcos[i][lc];280if (imcos[j][y]==0) imcos[j][y]=lc;281}282if (sw) x++; sw= sw ? 0 : 1;283}284if (qh==0) break;285hc=qh; qh=bpt[qh]; lc= -fpt[hc]; bpt[hc]=0;286}287return(0);288}289290291