FORM  4.1
index.c
Go to the documentation of this file.
1 
8 /* #[ License : */
9 /*
10  * Copyright (C) 1984-2013 J.A.M. Vermaseren
11  * When using this file you are requested to refer to the publication
12  * J.A.M.Vermaseren "New features of FORM" math-ph/0010025
13  * This is considered a matter of courtesy as the development was paid
14  * for by FOM the Dutch physics granting agency and we would like to
15  * be able to track its scientific use to convince FOM of its value
16  * for the community.
17  *
18  * This file is part of FORM.
19  *
20  * FORM is free software: you can redistribute it and/or modify it under the
21  * terms of the GNU General Public License as published by the Free Software
22  * Foundation, either version 3 of the License, or (at your option) any later
23  * version.
24  *
25  * FORM is distributed in the hope that it will be useful, but WITHOUT ANY
26  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
27  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
28  * details.
29  *
30  * You should have received a copy of the GNU General Public License along
31  * with FORM. If not, see <http://www.gnu.org/licenses/>.
32  */
33 /* #] License : */
34 
35 /*
36  #[ Includes : index.c
37 */
38 
39 #include "form3.h"
40 
41 /*
42  #] Includes :
43  #[ syntax and use :
44 
45  The indexing of brackets is not automatic! It should only be used
46  when one intends to use the contents of individual brackets.
47  This is done with the addition of a + sign to the bracket statement:
48  B+ a,b,c; or AB+ a,b,c;
49  It does require resources! The index is kept in memory and is removed
50  once the expression is treated and passed on to the output with different
51  or no brackets.
52  The index is limited to a given amount of space. Hence if there are too
53  many brackets we will skip some in the index. Skipping goes by space
54  occupied by the contents. We take the two adjacent bracket(s) with the
55  least space together and represent them by the first one only. This gives
56  a new spot.
57  The expression struct has two pointers:
58  bracketinfo for using.
59  newbracketinfo for making new index.
60 
61  #] syntax and use :
62  #[ FindBracket :
63 */
64 
65 POSITION *FindBracket(WORD nexp, WORD *bracket)
66 {
67  GETIDENTITY
68  BRACKETINDEX *bi;
69  BRACKETINFO *bracketinfo;
70  EXPRESSIONS e = &(Expressions[nexp]);
71  LONG hi, low, med;
72  int i;
73  WORD oldsorttype = AR.SortType, *t1, *t2, j, bsize, *term, *p, *pstop, *pp;
74  WORD *tstop, *cp, a[4];
75  FILEHANDLE *fi;
76  POSITION auxpos, toppos;
77 
78  switch ( e->status ) {
79  case UNHIDELEXPRESSION:
80  case UNHIDEGEXPRESSION:
81  case DROPHLEXPRESSION:
82  case DROPHGEXPRESSION:
83  case HIDDENLEXPRESSION:
84  case HIDDENGEXPRESSION:
85  fi = AR.hidefile;
86  break;
87  default:
88  fi = AR.infile;
89  break;
90  }
91  if ( AT.bracketinfo ) bracketinfo = AT.bracketinfo;
92  else bracketinfo = e->bracketinfo;
93  hi = bracketinfo->indexfill; low = 0;
94  if ( hi <= 0 ) return(0);
95  AT.fromindex = 1;
96  AR.SortType = bracketinfo->SortType;
97  bi = bracketinfo->indexbuffer + hi - 1;
98  if ( *bracket == 4 ) {
99  if ( bracketinfo->bracketbuffer[bi->bracket] == 4 ) i = 0;
100  else i = -1;
101  }
102  else if ( bracketinfo->bracketbuffer[bi->bracket] == 4 ) i = 1;
103  else i = CompareTerms(BHEAD bracket,bracketinfo->bracketbuffer+bi->bracket,0);
104  if ( i < 0 ) {
105  AR.SortType = oldsorttype;
106  AT.fromindex = 0;
107  return(0);
108  }
109  else if ( i == 0 ) med = hi-1;
110  else for (;;) {
111  med = (hi+low)/2;
112  bi = bracketinfo->indexbuffer + med;
113  if ( *bracket == 4 ) {
114  if ( bracketinfo->bracketbuffer[bi->bracket] == 4 ) i = 0;
115  else i = -1;
116  }
117  else if ( bracketinfo->bracketbuffer[bi->bracket] == 4 ) i = 1;
118  else i = CompareTerms(BHEAD bracket,bracketinfo->bracketbuffer+bi->bracket,0);
119  if ( i == 0 ) { break; }
120  if ( i > 0 ) {
121  if ( low == med ) { /* no occurrence */
122  AR.SortType = oldsorttype;
123  AT.fromindex = 0;
124  return(0);
125  }
126  hi = med;
127  }
128  else if ( i < 0 ) {
129  if ( low == med ) break;
130  low = med;
131  }
132  }
133 /*
134  The bracket is now either bi itself or between bi and the next one
135  or it is not present at all.
136 */
137  AN.theposition = AS.OldOnFile[nexp];
138  ADD2POS(AN.theposition,bi->start);
139 /*
140  The seek will have to move closer to the actual read so that we
141  can place a lock around the two.
142  if ( fi->handle >= 0 ) SeekFile(fi->handle,&AN.theposition,SEEK_SET);
143  else SetScratch(fi,&AN.theposition);
144 */
145 /*
146  Put the bracket in the compress buffer as if it were the last term read.
147  Have a look at AR.CompressPointer. (set it right)
148 */
149  term = AT.WorkPointer;
150  t1 = bracketinfo->bracketbuffer+bi->bracket;
151  j = *t1;
152 /*
153  The next is (hopefully) a bug fix. Originally the code read bsize = j
154  but that overcounts one. We have the part outside the bracket and the
155  coefficient which is 1,1,3. But we also have the length indicator.
156  Where we use the variable bsize we do not include the length indicator,
157  and we have the part outside plus 7,3,0 which is also three words.
158 */
159  bsize = j-1;
160  t2 = AR.CompressPointer;
161  NCOPY(t2,t1,j)
162  if ( i == 0 ) { /* We found the proper bracket already */
163  AR.SortType = oldsorttype;
164  AT.fromindex = 0;
165  return(&AN.theposition);
166  }
167 /*
168  Here we have to skip to the bracket if it exists (!)
169  Let us first look whether the expression is in memory.
170  If not we have to make a buffer to increase speed..
171 */
172  if ( fi->handle < 0 ) {
173  p = (WORD *)((UBYTE *)(fi->PObuffer)
174  + BASEPOSITION(AS.OldOnFile[nexp])
175  + BASEPOSITION(bi->start));
176  pstop = (WORD *)((UBYTE *)(fi->PObuffer)
177  + BASEPOSITION(AS.OldOnFile[nexp])
178  + BASEPOSITION(bi->next));
179  while ( p < pstop ) {
180 /*
181  Check now: if size or part from previous term < size of bracket
182  we have to setup the bracket again and test.
183  Otherwise, skip immediately to the next term.
184 */
185  if ( *p <= -bsize ) { /* no change of bracket */
186  p++; p += *p + 1;
187  }
188  else if ( *p < 0 ) { /* changes bracket */
189  pp = p;
190  t2 = AR.CompressPointer;
191  t1 = t2 - *p++ + 1;
192  j = *p++;
193  NCOPY(t1,p,j)
194  t2++; while ( *t2 != HAAKJE ) t2 += t2[1];
195  a[1] = t2[0]; a[2] = t2[1]; a[3] = t2[2];
196  *t2++ = 1; *t2++ = 1; *t2++ = 3;
197  *AR.CompressPointer = t2 - AR.CompressPointer;
198  if ( *bracket == 4 ) {
199  if ( AR.CompressPointer[0] == 4 ) i = 0;
200  else i = -1;
201  }
202  else if ( AR.CompressPointer[0] == 4 ) i = 1;
203  else i = CompareTerms(BHEAD bracket,AR.CompressPointer,0);
204  t2[-3] = a[1]; t2[-2] = a[2]; t2[-1] = a[3];
205  if ( i == 0 ) {
206  SETBASEPOSITION(AN.theposition,(pp-fi->PObuffer)*sizeof(WORD));
207  fi->POfill = pp;
208  goto found;
209  }
210  if ( i > 0 ) break; /* passed what was possible */
211  }
212  else { /* no compression. We have to check! */
213  WORD *oldworkpointer = AT.WorkPointer, *t3, *t4;
214  t2 = p + 1; while ( *t2 != HAAKJE ) t2 += t2[1];
215 /*
216  Here we need to copy the term. Modifying has proven to
217  be NOT threadsafe.
218 */
219  t3 = oldworkpointer; t4 = p;
220  while ( t4 < t2 ) *t3++ = *t4++;
221  *t3++ = 1; *t3++ = 1; *t3++ = 3;
222  *oldworkpointer = t3 - oldworkpointer;
223  AT.WorkPointer = t3;
224  t3 = oldworkpointer;
225  if ( *bracket == 4 ) {
226  if ( t3[0] == 4 ) i = 0;
227  else i = -1;
228  }
229  else if ( t3[0] == 4 ) i = 1;
230  else {
231  i = CompareTerms(BHEAD bracket,t3,0);
232  }
233  AT.WorkPointer = oldworkpointer;
234  if ( i == 0 ) {
235  SETBASEPOSITION(AN.theposition,(p-fi->PObuffer)*sizeof(WORD));
236  fi->POfill = p;
237  goto found;
238  }
239  if ( i > 0 ) break; /* passed what was possible */
240  p += *p;
241  }
242  }
243  AR.SortType = oldsorttype;
244  AT.fromindex = 0;
245  return(0); /* Bracket does not exist */
246  }
247  else {
248  toppos = AS.OldOnFile[nexp];
249  ADD2POS(toppos,bi->next);
250  cp = AR.CompressPointer;
251  for(;;) {
252  auxpos = AN.theposition;
253  GetOneTerm(BHEAD term,fi,&auxpos,0);
254  if ( *term == 0 ) {
255  AR.SortType = oldsorttype;
256  AT.fromindex = 0;
257  return(0); /* Bracket does not exist */
258  }
259  tstop = term + *term;
260  tstop -= ABS(tstop[-1]);
261  t1 = term + 1;
262  while ( *t1 != HAAKJE && t1 < tstop ) t1 += t1[1];
263  i = *bracket-4;
264  if ( t1-term == *bracket-3 ) {
265  t1 = term + 1; t2 = bracket+1;
266  while ( i > 0 && *t1 == *t2 ) { t1++; t2++; i--; }
267  if ( i <= 0 ) {
268  AR.CompressPointer = cp;
269  goto found;
270  }
271  }
272  AR.CompressPointer = cp;
273  AN.theposition = auxpos;
274 /*
275  Now check whether we passed the 'point'
276 */
277  if ( ISGEPOS(AN.theposition,toppos) ) {
278  AR.SortType = oldsorttype;
279  AR.CompressPointer = cp;
280  AT.fromindex = 0;
281  return(0); /* Bracket does not exist */
282  }
283  }
284  }
285 found:
286  AR.SortType = oldsorttype;
287  AT.fromindex = 0;
288  return(&AN.theposition);
289 }
290 
291 /*
292  #] FindBracket :
293  #[ PutBracketInIndex :
294 
295  Call via
296  if ( AR.BracketOn ) PutBracketInIndex(BHEAD term);
297 
298  This means that there should be a bracket somewhere
299  Note that the brackets come in in proper order.
300 
301  DON'T forget AR.SortType to be put into e->bracketinfo->SortType
302 */
303 
304 VOID PutBracketInIndex(PHEAD WORD *term, POSITION *newpos)
305 {
306  GETBIDENTITY
307  BRACKETINDEX *bi, *b1, *b2, *b3;
308  BRACKETINFO *b;
309  POSITION thepos;
310  EXPRESSIONS e = Expressions + AR.CurExpr;
311  LONG hi, i, average;
312  WORD *t, *tstop, *t1, *t2, *oldt, oldsize, oldh, oldhs;
313  if ( ( b = e->newbracketinfo ) == 0 ) return;
314  DIFPOS(thepos,*newpos,e->onfile);
315  tstop = term + *term;
316  tstop -= ABS(tstop[-1]);
317  t = term+1;
318  while ( *t != HAAKJE && t < tstop ) t += t[1];
319  if ( *t != HAAKJE ) return; /* no ticket, no laundry */
320  oldt = t; oldsize = *term; *t++ = 1; oldhs = *t; *t++ = 1;
321  oldh = *t; *t++ = 3; *term = t - term;
322  AT.fromindex = 1;
323 /*
324  Check now with the last bracket in the buffer.
325  If it is the same we can abort.
326 */
327  hi = b->indexfill;
328  if ( hi > 0 ) {
329  bi = b->indexbuffer + hi - 1;
330  bi->next = thepos;
331  if ( *term == 4 ) {
332  if ( b->bracketbuffer[bi->bracket] == 4 ) i = 0;
333  else i = -1;
334  }
335  else if ( b->bracketbuffer[bi->bracket] == 4 ) i = 1;
336  else i = CompareTerms(BHEAD term,b->bracketbuffer+bi->bracket,0);
337  if ( i == 0 ) { /* still the same bracket */
338  bi->termsinbracket++;
339  goto bracketdone;
340  }
341  if ( i > 0 ) { /* We have a problem */
342 /*
343  There is a special case in which // we have only functions and
344  term is contained completely in the bracket
345 */
346 /*
347  t = term + 1;
348  tstop = term + *term - 3;
349  while ( t < tstop && *t > HAAKJE ) t += t[1];
350  if ( t < tstop ) goto problems;
351 */
352  for ( i = 1; i < *term - 3; i++ ) {
353  if ( term[i] != b->bracketbuffer[bi->bracket+i] ) break;
354  }
355  if ( i < *term - 3 ) {
356 /*
357 problems:;
358 */
359  *term = oldsize; oldt[0] = HAAKJE; oldt[1] = oldhs; oldt[2] = oldh;
360  MLOCK(ErrorMessageLock);
361  MesPrint("Error!!!! Illegal bracket sequence detected in PutBracketInIndex");
362 #ifdef WITHPTHREADS
363  MesPrint("Worker = %w");
364 #endif
365  PrintTerm(term,"term into index");
366  PrintTerm(b->bracketbuffer+bi->bracket,"Last in index");
367  MUNLOCK(ErrorMessageLock);
368  AT.fromindex = 0;
369  Terminate(-1);
370  }
371  i = -1;
372  }
373  }
374 /*
375  If there is room for more brackets, we add this one.
376 */
377  if ( b->bracketfill+*term >= b->bracketbuffersize
378  && ( b->bracketbuffersize < AM.MaxBracketBufferSize
379  || ( e->vflags & ISFACTORIZED ) != 0 ) ) {
380 /*
381  Enlarge bracket buffer
382 */
383  WORD *oldbracketbuffer = b->bracketbuffer;
384  i = b->bracketbuffersize * 2;
385  if ( i > AM.MaxBracketBufferSize && ( e->vflags & ISFACTORIZED ) == 0 )
386  i = AM.MaxBracketBufferSize;
387  if ( i > b->bracketfill+*term ) {
388  b->bracketbuffersize = i;
389  b->bracketbuffer = (WORD *)Malloc1(b->bracketbuffersize*sizeof(WORD),
390  "new bracket buffer");
391  t1 = b->bracketbuffer; t2 = oldbracketbuffer;
392  i = b->bracketfill;
393  NCOPY(t1,t2,i)
394  if ( oldbracketbuffer ) M_free(oldbracketbuffer,"old bracket buffer");
395  }
396  }
397  if ( b->bracketfill+*term < b->bracketbuffersize ) {
398  if ( b->indexfill >= b->indexbuffersize ) {
399 /*
400  Enlarge index
401 */
402  BRACKETINDEX *oldindexbuffer = b->indexbuffer;
403  b->indexbuffersize *= 2;
404  b->indexbuffer = (BRACKETINDEX *)
405  Malloc1(b->indexbuffersize*sizeof(BRACKETINDEX),"new bracket index");
406  b1 = b->indexbuffer; b2 = oldindexbuffer;
407  i = b->indexfill;
408  NCOPY(b1,b2,i)
409  if ( oldindexbuffer ) M_free(oldindexbuffer,"old bracket index");
410  }
411  }
412  else {
413 /*
414  We have too many brackets in the buffer. Try to improve.
415  This is the interesting algorithm. We try to eliminate about 1/4 to
416  1/2 of the brackets from the index. This should be done by size of
417  the bracket contents to make the searching as fast as possible.
418  But! Do not touch the last bracket.
419  Note that we are always filling from the back.
420  Algorithm: Throw away every second bracket, unless b1+b2 is much longer
421  than average. How much is something we can tune.
422 */
423  average = DIVPOS(thepos,b->indexfill+1);
424  if ( ( average <= 0 ) || ( (average*4) <= 0 ) ) {
425  MLOCK(ErrorMessageLock);
426  MesPrint("Problems with bracket buffer. Increase MaxBracketBufferSize in form.set");
427  MesPrint("Current size is %l",AM.MaxBracketBufferSize*sizeof(WORD));
428  MUNLOCK(ErrorMessageLock);
429  Terminate(-1);
430  }
431  average *= 4; /* 2*2: one 2 for much longer, one 2 because we have pairs */
432  t2 = b->bracketbuffer;
433  b3 = b1 = b->indexbuffer;
434  bi = b->indexbuffer + b->indexfill;
435  b2 = b1+1;
436  while ( b2+2 < bi ) {
437  if ( DIFBASE(b2->next,b1->start) > average ) {
438  t1 = b->bracketbuffer + b1->bracket;
439  b1->bracket = t2 - b->bracketbuffer;
440  i = *t1; NCOPY(t2,t1,i)
441  *b3++ = *b1;
442  t1 = b->bracketbuffer + b2->bracket;
443  b2->bracket = t2 - b->bracketbuffer;
444  i = *t1; NCOPY(t2,t1,i)
445  *b3++ = *b2;
446  if ( b3 <= b1 ) {
447  PUTZERO(b1->start);
448  PUTZERO(b1->next);
449  b1->bracket = 0;
450  b1->termsinbracket = 0;
451  }
452  if ( b3 <= b2 ) {
453  PUTZERO(b2->start);
454  PUTZERO(b2->next);
455  b2->bracket = 0;
456  b2->termsinbracket = 0;
457  }
458  }
459  else {
460  t1 = b->bracketbuffer + b1->bracket;
461  b1->bracket = t2 - b->bracketbuffer;
462  i = *t1; NCOPY(t2,t1,i)
463  b1->next = b2->next;
464  b1->termsinbracket += b2->termsinbracket;
465  *b3++ = *b1;
466  if ( b3 <= b1 ) {
467  PUTZERO(b1->start);
468  PUTZERO(b1->next);
469  b1->bracket = 0;
470  b1->termsinbracket = 0;
471  }
472  PUTZERO(b2->start);
473  PUTZERO(b2->next);
474  b2->bracket = 0;
475  b2->termsinbracket = 0;
476  }
477  b1 += 2; b2 += 2;
478  }
479  while ( b1 < bi ) {
480  t1 = b->bracketbuffer + b1->bracket;
481  b1->bracket = t2 - b->bracketbuffer;
482  i = *t1; NCOPY(t2,t1,i)
483  *b3++ = *b1;
484  if ( b3 <= b1 ) {
485  PUTZERO(b1->start);
486  PUTZERO(b1->next);
487  b1->bracket = 0;
488  b1->termsinbracket = 0;
489  }
490  b1++;
491  }
492  b->indexfill = b3 - b->indexbuffer;
493  b->bracketfill = t2 - b->bracketbuffer;
494  }
495  bi = b->indexbuffer + b->indexfill;
496  b->indexfill++;
497  bi->bracket = b->bracketfill;
498  bi->start = thepos;
499  bi->next = thepos;
500  bi->termsinbracket = 1;
501 /*
502  Copy the bracket into the buffer
503 */
504  t1 = term; t2 = b->bracketbuffer + bi->bracket; i = *t1;
505  b->bracketfill += i;
506  NCOPY(t2,t1,i)
507 bracketdone:
508  *term = oldsize; oldt[0] = HAAKJE; oldt[1] = oldhs; oldt[2] = oldh;
509  AT.fromindex = 0;
510 }
511 
512 /*
513  #] PutBracketInIndex :
514  #[ ClearBracketIndex :
515 */
516 
517 void ClearBracketIndex(WORD numexp)
518 {
519  BRACKETINFO *b;
520  if ( numexp >= 0 ) {
521  b = Expressions[numexp].bracketinfo;
522  Expressions[numexp].bracketinfo = 0;
523  }
524  else if ( numexp == -1 ) {
525  GETIDENTITY
526  b = AT.bracketinfo;
527  AT.bracketinfo = 0;
528  }
529  else {
530  numexp = -numexp-2;
531  b = Expressions[numexp].newbracketinfo;
532  Expressions[numexp].newbracketinfo = 0;
533  }
534  if ( b == 0 ) return;
535  b->indexfill = b->indexbuffersize = 0;
536  b->bracketfill = b->bracketbuffersize = 0;
537  M_free(b->bracketbuffer,"ClearBracketBuffer");
538  M_free(b->indexbuffer,"ClearIndexBuffer");
539  M_free(b,"BracketInfo");
540 }
541 
542 /*
543  #] ClearBracketIndex :
544  #[ OpenBracketIndex :
545 
546  Note: This routine is thread-safe
547 */
548 
549 VOID OpenBracketIndex(WORD nexpr)
550 {
551  EXPRESSIONS e = Expressions + nexpr;
552  BRACKETINFO *bi;
553  LONG i;
554  bi = (BRACKETINFO *)Malloc1(sizeof(BRACKETINFO),"BracketInfo");
555  e->newbracketinfo = bi;
556 /*
557  i = 20*AM.MaxTer/sizeof(WORD);
558  if ( i < 1000 ) i = 1000;
559 */
560  i = 2000;
561  bi->bracketbuffer = (WORD *)Malloc1(i*sizeof(WORD),"Bracket Buffer");
562  bi->bracketbuffersize = i;
563  bi->bracketfill = 0;
564  i = 50;
565  bi->indexbuffer = (BRACKETINDEX *)Malloc1(i*sizeof(BRACKETINDEX),"Bracket Index");
566  bi->indexbuffersize = i;
567  bi->indexfill = 0;
568  bi->SortType = AC.SortType;
569 }
570 
571 /*
572  #] OpenBracketIndex :
573  #[ PutInside :
574 
575  Puts a term, or a bracket determined part of a term inside a function.
576 
577  AT.WorkPointer points at term+*term
578 */
579 
580 int PutInside(PHEAD WORD *term, WORD *code)
581 {
582  WORD *from, *to, *oldbuf, *tStop, *t, *tt, oldon, oldact, inc, argsize, *termout;
583  int i, ii, error;
584 
585  if ( code[1] == 4 && ( code[2] == 0 || code[2] == 1 ) ) {
586 /*
587  Put all inside. Move the term by 1+FUNHEAD+ARGHEAD
588 */
589  from = term+*term; to = from+1+ARGHEAD+FUNHEAD; i = ii = *term;
590  to[0] = 1; to[1] = 1; to[2] = 3;
591  while ( --i >= 0 ) *--to = *--from;
592  to = term;
593  *to++ = term[0]+4+ARGHEAD+FUNHEAD;
594  *to++ = code[3];
595  *to++ = ii+FUNHEAD+ARGHEAD;
596  *to++ = 1; /* set dirty flags, because there could be a fast notation */
597  FILLFUN3(to)
598  *to++ = ii+ARGHEAD;
599  *to++ = 1;
600  FILLARG(to)
601  return(0);
602  }
603 /*
604  First we save the old bracket variables. Then we set variables to
605  influence the PutBracket routine and call it.
606  After that we set the values back and sort out the results by placing the
607  inside of the bracket inside the function.
608 */
609  termout = AT.WorkPointer;
610  oldbuf = AT.BrackBuf;
611  oldon = AR.BracketOn;
612  oldact = AT.PolyAct;
613  AR.BracketOn = -code[2];
614  AT.BrackBuf = code+4;
615  AT.PolyAct = 0;
616  error = PutBracket(BHEAD term);
617  AT.PolyAct = oldact;
618  AT.BrackBuf = oldbuf;
619  AR.BracketOn = oldon;
620  if ( error ) return(error);
621  i = *termout; from = termout; to = term;
622  NCOPY(to,from,i);
623  tStop = term +*term; tStop -= tStop[-1];
624  t = term+1;
625  while ( t < tStop && *t != HAAKJE ) t += t[1];
626  from = term + *term;
627  inc = FUNHEAD+ARGHEAD-t[1]+1;
628  tt = t + t[1];
629  argsize = from-tt+1;
630  to = from + inc;
631  to[0] = 1;
632  to[1] = 1;
633  to[2] = 3;
634  while ( from > tt ) *--to = *--from;
635  *--to = argsize;
636  *t++ = code[3];
637  *t++ = argsize+FUNHEAD+ARGHEAD;
638  *t++ = 1;
639  FILLFUN3(t);
640  *t++ = argsize+ARGHEAD;
641  *t++ = 1;
642  FILLARG(t);
643  *term += inc+3;
644  AT.WorkPointer = term+*term;
645  if ( Normalize(BHEAD term) ) error = 1;
646  return(error);
647 }
648 
649 /*
650  #] PutInside :
651 */
652 
653 /*
654  The next routines are for indexing the local output files in a parallel
655  sort. This indexing is needed to get a fast determination of the
656  splitting terms needed to divide the terms evenly over the processors.
657  Actually this method works well for ParFORM, but may not work well
658  for TFORM.
659 
660  #[ PutTermInIndex :
661 
662  Puts a term in the term index.
663  Action:
664  if the index hasn't reached its full size
665  if there is room, put the term
666  if there is no room: extend the buffer, put the term
667  else
668  check if the last term has a number of the type skip*m+1
669  if no, overwrite the last term
670  if yes, check whether there is room for one more term
671  yes: add the term
672  no: drop all even terms, compress the list,
673  multiply skip by 2, and add this term.
674 
675 int PutTermInIndex(WORD *term,POSITION *position)
676 {
677  return(0);
678 }
679 
680  #] PutTermInIndex :
681 */
WORD * bracketbuffer
Definition: structs.h:318
Definition: structs.h:618
#define PHEAD
Definition: ftypes.h:56
WORD SortType
Definition: structs.h:323
BRACKETINDEX * indexbuffer
Definition: structs.h:317
int handle
Definition: structs.h:646