1 #include "defs.h"
2
3 extern char inf0[],inf1[],inf4[],outf0[],outf1[],outf2[],outcopy[],
4 act,ch1,norm;
5 extern int intexp,facexp,stage,mcl,
6 prime,exp,nng,*rpf,*rpb,*eexpnt,*enexpnt,**pcb,dim,onng,**npcb,
7 rel[],expnt[],nexpnt[],pinv[],wt[],
8 d1[],d2[],*pcptr[],**powptr[],**comptr[],sd1[],sd2[],swt[],
9 dpth[],**mat[],cp[],**intg,**cintg,cbno,
10 ngens,maxm,matcl,**extno,**subno,chsdim,chpdim,exp1;
11 extern int rsp,ptrsp,rspk,marg;
12 extern long inf3offset,inf4offset;
13 int *wf,*wc,**inteno,intcpd,inng,*nsd1,*nsd2,intfe,**npcb2;
14 extern FILE *ip,*ipm,*op;
15 FILE *ipcopy,*opcopy;
16
17 int
spact(void)18 spact (void)
19 /* Computes cohomology group H^i(P,M) or H^i(Q,M) */
20 { int i,j,k,l,m,n,ie,ct,cl,fg,wi,wj,*p,*q,*r,*nrpf,*v1,*v2,
21 **swop,homcl,c;
22 char inp;
23 inp= (ch1 && act) ? 0 : 1;
24 /* inp as in calcfm in case ch1 */
25 if (ingp(inp) == -1) return(-1);
26 if (ch1 && act) { inf3offset=ftell(ip); fclose(ip);}
27 ct=ngens; j=exp;
28 for (i=1;i<=dim;i++)
29 { j++; wt[j]=swt[i]; d1[j]=(sd1[i]>0) ? sd1[i]+exp : 0; d2[j]=sd2[i]; }
30 printf("Computing matrices.\n");
31 /* Matrices for all pcp gens of P or Q are now computed */
32 if (maxm<2*facexp)
33 { fprintf(stderr,"Not enough mat space. Increase MSP (of MV or MM).\n");
34 return(-1);
35 }
36 for (i=facexp;i>=1;i--) if (wt[i]==1)
37 { if (i>ct)
38 { swop=mat[i]; mat[i]=mat[ct]; mat[ct]=swop;
39 for (j=1;j<=dim;j++) if (d2[exp+j]==ct) d2[exp+j]=i;
40 }
41 inv(mat[i],mat[facexp+i]); ct--;
42 }
43 if (ct!=0) {fprintf(stderr,"No of pgens wrong.\n"); return(-1); }
44 for (i=2;i<=facexp;i++) if (wt[i]>1)
45 { p= (d1[i]==d2[i]) ? *powptr[d1[i]] : *(comptr[d1[i]]+d2[i]);
46 q=p+ *p-2; *cp=0;
47 while (--q>p)
48 { k= *(q+1); for (j=1;j<=k;j++) cp[++(*cp)]= *q+facexp; q--; }
49 if (d1[i]==d2[i]) for (j=1;j<=prime;j++) cp[++(*cp)]=d1[i];
50 else
51 { cp[++(*cp)]=d1[i]+facexp; cp[++(*cp)]=d2[i]+facexp;
52 cp[++(*cp)]=d1[i]; cp[++(*cp)]=d2[i];
53 }
54 prod(cp,mat[i]); inv(mat[i],mat[i+facexp]);
55 }
56 if (act==0)
57 { op=fopen(outf2,"w");
58 fprintf(op,"%3d%3d%3d\n",prime,dim,facexp);
59 for (i=1;i<=facexp;i++) printmat(mat[i]);
60 fclose(op);
61 }
62
63
64 printf("Computing full pcp.\n");
65 /* pcp of P or Q in dual action on module is computed from the matrices. */
66 v1=mat[facexp+1][1]; v2=mat[facexp+1][2];
67 for (i=1;i<=dim;i++) v1[i]=0; ie=exp;
68 for (i=1;i<=dim;i++)
69 { if (i>1) v1[i-1]=0; v1[i]=1; ie++;
70 for (j=1;j<=facexp;j++) if (comm(v1,v2,mat[j]))
71 { *(comptr[ie]+j)=rpf+1; nrpf=rpf+2; l=0;
72 for (k=1;k<=dim;k++) if ((m=v2[k])!=0)
73 { *(nrpf++)=k+exp; *(nrpf++)=m; l+=2; }
74 *(rpf+1)=l; m= *(nrpf-2);
75 if (d1[m]==ie && d2[m]==j) *rpf=m; else *rpf=0; rpf=nrpf;
76 }
77 }
78 if (ch1==0)
79 { printf("Computing P-homs.\n"); fflush(stdout); homcl=0;
80 /* Hom-P(FM,M) will now be computed as dual of tensor product, using NQA */
81 if (matcl+1>=mcl)
82 { fprintf(stderr,"Class too big. Increase MCL.\n"); return(-1); }
83 for (cl=matcl+1;cl>1;cl--)
84 { printf("cl=%d.\n",cl);
85 for (fg=facexp+1;dpth[fg]==1 && fg<=exp;fg++) for (i=exp+1;i<=exp+dim;i++)
86 if (wt[i]+1==cl)
87 { if (intgen(i,fg)== -1) return(-1);
88 if ((k=wt[i]+wt[fg])>homcl)
89 { homcl=k;
90 if (homcl+1>=mcl)
91 { fprintf(stderr,"Class too big. Increase MCL.\n"); return(-1); }
92 }
93 }
94 while (fg<=exp)
95 { for (i=exp+1;i<=exp+dim;i++) if (wt[i]+dpth[fg]==cl)
96 { if (dpth[d1[fg]]==dpth[fg]-1)
97 { if (assoc(i,d1[fg],d2[fg]))
98 if (subrel(i,fg)== -1) return(-1);
99 }
100 else if (intgen(i,fg)== -1) return(-1);
101 if ((k=wt[i]+wt[fg])>homcl)
102 { homcl=k;
103 if (homcl+1>=mcl)
104 { fprintf(stderr,"Class too big. Increase MCL.\n"); return(-1); }
105 }
106 }
107 fg++;
108 }
109 for (i=1;i<=facexp;i++)
110 { wi=wt[i];
111 for (j=facexp+1;j<=exp;j++)
112 { wj=dpth[j]; if (wi+wj>=cl) break;
113 for (k=exp+1;k<=exp+dim;k++) if (wi+wj+wt[k]==cl) if (assoc(k,j,i))
114 { if ((l=prnrel())==0) goto nextcl; if (l== -1) return(-1); }
115 }
116 }
117 nextcl:;
118 }
119 bgc(); rsp=rpb-rel+1;
120 printf("Computing extensions. nng,homcl=%d,%d\n",nng,homcl); fflush(stdout);
121 stage=2; onng=nng; chpdim=0; chsdim=0; extno=pcptr+ptrsp-onng-1;
122 for (i=1;i<=nng;i++) extno[i]=0;
123 }
124 else
125 { stage=4; printf("Computing first cohomology group.\n"); homcl=matcl;
126 if (homcl+1>=mcl)
127 { fprintf(stderr,"Class too big. Increase MCL.\n"); return(-1); }
128 }
129
130 /* H^2 or H^1 will now be computed */
131 for (cl=homcl+1;cl>=2;cl--)
132 { printf("cl=%d\n",cl);
133 if (cl<=matcl+1)
134 { for (i=1;i<=facexp;i++) if (wt[i]==1) for (j=exp+1;j<=exp+dim;j++)
135 if (wt[j]+1==cl) if (intgen(j,i)== -1) return(-1);
136 for (i=1;i<=facexp;i++)
137 { wi=wt[i];
138 if (wi>1) for (j=exp+1;j<=exp+dim;j++)
139 if (wi+wt[j]==cl) if (assoc(j,d1[i],d2[i]))
140 if (subrel(j,i)== -1) return(-1);
141 }
142 }
143 for (i=1;i<=facexp;i++) for (j=i;j<=facexp;j++) for (k=exp+1;k<=exp+dim;k++)
144 if ((i==j && wt[i]+1+wt[k]==cl) || (i!=j && wt[i]+wt[j]+wt[k]==cl))
145 if (assoc(k,j,i))
146 if (ch1)
147 { if ((l=prnrel())==0) goto ncl; if (l== -1) return(-1); }
148 else
149 { l=prnrel(); if (l== -1) return(-1); if (l>1) nchg(); }
150 ncl:;
151 }
152 if (ch1) printf("Cohomology grp has dim %d\n",nng);
153 /* We now no longer need the data for Q in the back of rel. */
154 rpb=rel+rspk-1;
155 if (act) { if (ch1) onng=nng; else unlink(outf1); }
156 else
157 { if (stage>2) {onng=nng; strcpy(outf1,outf0);}
158 outgp();
159 if (ch1)
160 { ipcopy=fopen(outf1,"r"); opcopy=fopen(outcopy,"w");
161 while ((c=getc(ipcopy))!= -1) putc(c,opcopy);
162 fclose(ipcopy); fclose(opcopy);
163 }
164 }
165 return(0);
166 }
167
168 int
nchg(void)169 nchg (void)
170 /* We have a new generator for H^2. This is put into echelon form with the
171 existing generators, and stored.
172 */
173 { int l,m,n,len,*p,*q,*v1,*r,*r1;
174 for (m=1;m<=onng;m++) if ((n=nexpnt[m])!=0)
175 { if (n<0) {n+=prime; nexpnt[m]=n;}
176 if ((p=extno[m])!=0)
177 { expand(p,rpf,onng); p=rpf; n=prime-n; q=p+onng; v1=nexpnt+1;
178 while (++p<=q) {*v1+= (n* *p); *v1%=prime; v1++;}
179 }
180 }
181 for (m=1;m<=onng;m++) if ((n=nexpnt[m])!=0)
182 { n=pinv[n]; p=nexpnt+m-1; q=nexpnt+onng;
183 while (++p<=q) {*p *=n; *p%=prime; }
184 chpdim++; printf("chpdim=%2d, bno=%2d\n",chpdim,m);
185 for (l=1;l<=onng;l++) if ((p=extno[l])!=0)
186 { r=rpb-onng; expand(p,r,onng);
187 if ((n=r[m])!=0)
188 { n=prime-n; r1=r; q=r+onng; v1=nexpnt+1;
189 while (++r1<=q) {*r1+=(n* *v1); *r1%=prime; v1++;}
190 len=0;
191 for (n=1;n<=onng;n++) if (r[n]!=0) len+=2;
192 if (len> *p) {p=rpf; extno[l]=p; rpf+=(len+1); }
193 *p=len; compress(p,r,onng);
194 }
195 }
196 extno[m]=rpf;
197 len=0;
198 for (n=1;n<=onng;n++) if (nexpnt[n]!=0) len+=2;
199 *rpf=len; compress(rpf,nexpnt,onng); rpf+=(len+1);
200 break;
201 }
202 }
203
204 int
intact(void)205 intact (void)
206 /* In case act, appropriate quotient of H^i(P,M) is computed */
207 { int a,b,c,d,i,j,k,l,len,m,n,x,f1,f2,*p,*p1,*q,*q1,*r,*r1,*ia,*ib,*v1,
208 **bim,**cbim,**imcg,**cimcg,**dp,*null;
209 char pow,nz;
210 strcpy(inf1,inf0);
211 if (norm)
212 { if (ch1) strcpy(inf1,outcopy);
213 if (ingp(1)== -1) return(-1);
214 if (ch1) strcpy(inf1,inf0);
215 cbno=1; bim=mat[cbno]; onng=nng;
216 for (i=1;i<=dim;i++) {for (j=1;j<=dim;j++) bim[i][j]=0;bim[i][i]=1; }
217 }
218 /* It is now time to read in the full pcp for the Frattini extension of P
219 again, in order to compute the action on it. Before doing this, we must
220 save all necessary information about Q. intg and cintg are already safely
221 at the back of rel., and the cohomolgy gens of Q will also be copied there.
222 The definitions of the gens of Q will be copied to sd1 and sd2, but a
223 slightly messy method has been used to save long definitions.
224 */
225 p=d1; q=p+exp+dim+onng; v1=sd1+1;
226 while (++p<=q) *(v1++)= *p;
227 nsd1=sd1+exp+dim;
228 p=d2; q=p+exp+dim+onng; v1=sd2+1;
229 while (++p<=q) *(v1++)= *p;
230 nsd2=sd2+exp+dim;
231 if (ch1)
232 { for (i=exp+1;i<=exp+dim+nng;i++)
233 { p= (sd1[i]==0) ? 0 : *(comptr[sd1[i]]+sd2[i]);
234 if (p!=0)
235 { l= *p; if (i<=exp+dim) l-=2;
236 if (l>0)
237 { sd1[i]= -sd1[i]; q=p+l;
238 while (q>p) {*rpb= *q; q--; rpb--;}
239 *rpb=l; cintg[i]=rpb; rpb--;
240 }
241 }
242 }
243 }
244 else
245 for (i=1;i<=exp1;i++) if (sd1[i]!=0)
246 { p= sd1[i]==sd2[i] ? *powptr[sd1[i]] : *(comptr[sd1[i]]+sd2[i]);
247 l= *p;
248 if (l>2)
249 { sd1[i]= -sd1[i]; q=p+l-2;
250 while (q>p) {*rpb= *q; q--; rpb--; }
251 *rpb=l-2; cintg[i]=rpb; rpb--;
252 }
253 }
254 inng=onng; intexp=exp;
255 if (ch1==0)
256 { p=wt; q=p+facexp; v1=swt+1;
257 while (++p<=q) *(v1++)= *p;
258 inteno=extno; intcpd=chpdim; intfe=facexp;
259 if (norm==0)
260 { for (i=1;i<=onng;i++) if ((p=inteno[i])!=0)
261 { q=p+ *p; rpb-=(*p+1); v1=rpb;
262 while (p<=q) *(++v1)= *(p++);
263 inteno[i]=rpb+1;
264 }
265 ptrsp-=onng;
266 }
267 }
268 rsp=rpb-rel+1;
269 if (norm==0 || ch1) if (ingp(1)== -1) return(-1);
270 printf("Reading conj matrix.\n");
271 /* matrix of dcrep is read and multiplied by action base change matrix */
272 bim=mat[cbno]; cbim=mat[cbno+1];
273 ip=fopen(inf4,"r"); fseek(ip,inf4offset,0);
274 readmat(mat[cbno+2]);
275 inf4offset=ftell(ip); fclose(ip);
276 *cp=2; cp[1]=cbno; cp[2]=cbno+2; prod(cp,cbim);
277 if (ch1)
278 { printf("Computing action.\n"); wf=rpf; null=0;
279 for (i=1;i<=dim;i++) *(++npcb2)=0;
280 if (npcb2-pcptr>=ptrsp)
281 { fprintf(stderr,"Out of ptrsp. Increase PTRSP.\n"); return(-1); }
282 for (i=intexp+1;i<=intexp+dim+inng;i++)
283 { wc=wf-2; a=sd1[i]; if (a==0) continue;
284 b=sd2[i]; zero(nexpnt,enexpnt);
285 if (a<0)
286 { p=cintg[i]; q=p + *p -1;
287 while (q>p) { entvec(npcb[*q-intexp],bim[*q-intexp],-*(q+1)); q-=2;}
288 }
289 ia=bim[abs(a)-intexp]; ib=intg[b];
290 entvec(null,ia,-1); enter(ib,-1); entvec(null,ia,1); enter(ib,1);
291 zero(expnt,eexpnt); collect(wc,wf,1);
292 wc=wf-2;
293 if (a<0)
294 { p=cintg[i]; q=p + *p -1;
295 while (q>p) { entvec(null,cbim[*q-intexp],-*(q+1)); q-=2;}
296 }
297 ia=cbim[abs(a)-intexp]; ib=cintg[b];
298 entvec(null,ia,-1); enter(ib,-1); entvec(null,ia,1); enter(ib,1);
299 zero(expnt,eexpnt); collect(wc,wf,-1);
300 if (i<=intexp+dim)
301 { l=0;
302 for (j=nng;j>=1;j--) if ((k=nexpnt[j])!=0)
303 { if (k<0) k+=prime; *rpb=k; *(rpb-1)=j; rpb-=2; l+=2; }
304 if (l!=0) { npcb[i-intexp]= rpb; *rpb=l; *(rpb-1)=0; rpb-=2; }
305 }
306 else if ((l=prnrel())== -1 || l==0) return(l);
307 }
308 printf("End of this action. Present dimension=%d\n",nng);
309 fflush(stdout);
310 if (nng==0) return(2);
311 }
312 else
313 { printf("Computing Frattini embeddings.\n");
314 /* Now intg and cintg are computed as strings in gens of P for the gens of Q */
315 for (i=1;i<=exp1;i++) if (i>intfe || swt[i]>1)
316 { wf=rpf; a=sd1[i]; b=sd2[i]; wc=wf-2; pow = abs(a)==b;
317 /* a<0 means a long def */
318 if (a<0)
319 { p=cintg[i]; q=p+ *p-1;
320 while (q>p) { enter(intg[*q],-*(q+1)); q-=2; }
321 }
322 ia=intg[abs(a)]; ib=intg[b];
323 if (pow) enter(ia,prime);
324 else
325 { enter(ia,-1); enter(ib,-1); enter(ia,1); enter(ib,1); }
326 zero(expnt,eexpnt);
327 if (wc>=wf) collect(wc,wf,1);
328 l=0;
329 for (k=exp;k>=1;k--) if ((x=expnt[k])!=0)
330 { *rpb=x; *(rpb-1)=k; rpb-=2; l+=2; }
331 *rpb=l; intg[i]=rpb; rpb--; wc=wf-2;
332 if (a<0)
333 { a= -a; p=cintg[i]; q=p+ *p-1;
334 while (q>p) { enter(cintg[*q],-*(q+1)); q-=2; }
335 }
336 ia=cintg[a]; ib=cintg[b];
337 if (pow) enter(ia,prime);
338 else
339 { enter(ia,-1); enter(ib,-1); enter(ia,1); enter(ib,1); }
340 zero(expnt,eexpnt);
341 if (wc>=wf) collect(wc,wf,1);
342 l=0;
343 for (k=exp;k>=1;k--) if ((x=expnt[k])!=0)
344 { *rpb=x; *(rpb-1)=k; rpb-=2; l+=2; }
345 *rpb=l; cintg[i]=rpb; rpb--;
346 if (rpb-rpf<marg)
347 { fprintf(stderr,"Out of space. Increase RSP.\n"); return(-1); }
348 }
349 printf("Computing images of cohomology gens.\n");
350 /* Now images of cohomology gens of Q and its conjugte are computed as strings,
351 and stored in imcg and cimcg.
352 */
353
354 imcg=pcb; cimcg=imcg+inng;
355 if (pcb+2*(inng+nng)-pcptr>=ptrsp)
356 { fprintf(stderr,"Out of ptr space. Increase PTRSP.\n"); return(-1); }
357 for (i=1;i<=inng;i++)
358 { a=nsd1[i]-intexp; b=nsd2[i];
359 zero(rpf,rpf+nng);
360 p=bim[a]; p1=p+dim+1; q=intg[b]; q1=q+ *q;
361 while (--p1>p) if ((f1= *p1)!=0)
362 { c=p1-p+exp; q=intg[b];
363 while (++q<q1)
364 { d= *(q++); f2= *q;
365 if ((r= *(comptr[c]+d))!=0)
366 { r1=r+ *r; while (++r<r1) {rpf[*r]+= (*(r+1)*f1*f2); r++; }}
367 }
368 }
369 p=rpf; p1=p+nng;
370 while (++p<=p1) *p%=prime;
371 len=0;
372 for (j=1;j<=nng;j++) if (rpf[j]!=0) len+=2;
373 rpb-=len; imcg[i]=rpb; *rpb=len; compress(rpb,rpf,nng); rpb--;
374 zero(rpf,rpf+nng);
375 p=cbim[a]; p1=p+dim+1; q=cintg[b]; q1=q+ *q;
376 while (--p1>p) if ((f1= *p1)!=0)
377 { c=p1-p+exp; q=cintg[b];
378 while (++q<q1)
379 { d= *(q++); f2= *q;
380 if ((r= *(comptr[c]+d))!=0)
381 { r1=r+ *r; while (++r<r1) {rpf[*r]+= (*(r+1)*f1*f2); r++; }}
382 }
383 }
384 p=rpf; p1=p+nng;
385 while (++p<=p1) *p%=prime;
386 len=0;
387 for (j=1;j<=nng;j++) if (rpf[j]!=0) len+=2;
388 rpb-=len; cimcg[i]=rpb; *rpb=len; compress(rpb,rpf,nng); rpb--;
389 if (rpb-rpf-marg>rsp)
390 { fprintf(stderr,"Out of space. Increase RSP.\n"); return(-1); }
391 }
392 printf("Computing Sub-cohomology generators.\n");
393 /* Finally we are ready to compute gens of the subgroup of H^2(P,M) to be
394 factored out. These will be put into echelon form.
395 */
396 for (i=1;i<=inng;i++) if ((p=inteno[i])!=0)
397 { zero(nexpnt,enexpnt); p1=p+ *p;
398 while (--p1>p)
399 { a= *p1; f1= *(p1+1); p1--; q=rpf; q1=q+nng; r=q1; r1=nexpnt;
400 expand(imcg[a],q,nng); expand(cimcg[a],r,nng);
401 while (++q<=q1) { r++; r1++; *r1+=(f1* *q); *r1-=(f1* *r);}
402 }
403 r=nexpnt; nz=0; r1=r+nng;
404 while (++r<=r1) {*r%=prime; if (*r!=0) nz=1; }
405 if (nz)
406 { for (m=1;m<=nng;m++) if ((n=nexpnt[m])!=0)
407 { if (n<0) {n+=prime; nexpnt[m]=n;}
408 if ((q=subno[m])!=0)
409 { n=prime-n; r=q+ *q;
410 while (++q<r) {q1=nexpnt+ *q;q++; *q1+= (n* *q); *q1%=prime;}
411 }
412 }
413 for (m=1;m<=nng;m++) if ((n=nexpnt[m])!=0)
414 { n=pinv[n]; q=nexpnt+m-1; r=nexpnt+nng;
415 while (++q<=r) {*q *=n; *q%=prime; }
416 chsdim++; printf("chsdim=%2d, bno=%2d\n",chsdim,m);
417 for (l=1;l<=nng;l++) if ((p=subno[l])!=0)
418 { r=rpb-nng; expand(p,r,nng);
419 if ((n=r[m])!=0)
420 { n=prime-n; q=r+nng; q1=nexpnt+1; r1=r;
421 while (++r1<=q) {*r1+=(n* *q1); *r1%=prime; q1++;}
422 len=0;
423 for (n=1;n<=nng;n++) if (r[n]!=0) len+=2;
424 if (len> *p) {p=rpf; subno[l]=p; rpf+=(len+1); }
425 *p=len; compress(p,r,nng);
426 }
427 }
428 subno[m]=rpf;
429 len=0;
430 for (n=1;n<=nng;n++) if (nexpnt[n]!=0) len+=2;
431 *rpf=len; compress(rpf,nexpnt,nng); rpf+=(len+1);
432 if (rpb-rpf<marg)
433 { fprintf(stderr,"Out of space. Increase RSP.\n"); return(-1); }
434 break;
435 }
436 }
437 }
438 printf("End of this action. chpdim,chsdim=%d,%d\n\n",chpdim,chsdim);
439 fflush(stdout);
440 if (chpdim==chsdim) return(2);
441 }
442 strcpy(outf1,inf0); onng=nng; outgp();
443 return(0);
444 }
445
446 int
enter(int * g,int pow)447 enter (int *g, int pow)
448 /* Enters a power of the word pointed to by g into rel for collection. */
449 { int *ps,*pf,*pc,i,sgn;
450 if (pow<0) { sgn= -1; pow= -pow; pf=g+1; ps=g+ *g+1; }
451 else { sgn=1; ps=g-1; pf=g+ *g-1; }
452 for (i=1;i<=pow;i++)
453 { pc=ps;
454 while (pc!=pf) { pc +=(2*sgn); wc+=2; *wc= *pc; *(wc+1)= *(pc+1) *sgn; }
455 }
456 }
457
458 int
entvec(int * h,int * g,int pow)459 entvec (int *h, int *g, int pow)
460 /* Similar, but g is a vector. Used only for H^1. */
461 { int i,j,l,*p,*q;
462 for (i=1;i<=dim;i++) if ((j=g[i])!=0)
463 { j*=pow; j%=prime; if (j<0) j+=prime;
464 wc+=2; *wc=exp+i; *(wc+1)=j;
465 }
466 if (h!=0)
467 { l= *h; p=h+l;
468 while (++h<p)
469 { q=nexpnt+(*h); *q+=(pow* *(++h)); *q%=prime; if (*q<0) *q+=prime;}
470 }
471 }
472
473 int
expand(int * p1,int * p2,int len)474 expand (int *p1, int *p2, int len)
475 /* Expand word p1 to vector p2 of length len. */
476 { int l,*p,*q;
477 l= *p1; p=p1; q=p+l; zero(p2,p2+len);
478 while (++p<q) { p2[*p]= *(p+1); p++; }
479 }
480
481 int
compress(int * p1,int * p2,int len)482 compress (int *p1, int *p2, int len)
483 /* compress vector p2 of length len to word p1. */
484 { int i,n,*p;
485 p=p1;
486 for (i=1;i<=len;i++) if ((n=p2[i])!=0) { *(++p)=i; *(++p)=n; }
487 }
488