source: git/Singular/tgb.cc @ dd83f3

spielwiese
Last change on this file since dd83f3 was dd83f3, checked in by Michael Brickenstein <bricken@…>, 20 years ago
*bricken: compile fixes, further work towards F4 git-svn-id: file:///usr/local/Singular/svn/trunk@7449 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 80.4 KB
Line 
1
2// #define OM_CHECK 3
3// #define OM_TRACK 5
4// #define OM_KEEP  1
5// TODO:
6//       deg -> poly_crit
7//       multiple rings
8//       shorten_tails und dessen Aufrufe pruefen wlength!!!
9//       calculating with formal sums
10//       try to create spolys as formal sums
11
12#include "tgb.h"
13
14#define LEN_VAR1
15#define degbound(p) assume(pTotaldegree(p)<10)
16//#define inDebug(p) assume((debug_Ideal==NULL)||(kNF(debug_Ideal,NULL,p,0,0)==0))
17#ifdef LEN_VAR1
18// erste Variante: Laenge: Anzahl der Monome
19int pSLength(poly p, int l) {
20  return l; }
21int kSBucketLength(kBucket* bucket) {return bucket_guess(bucket);}
22#endif
23
24#ifdef LEN_VAR2
25// 2. Variante: Laenge: Platz fuer die Koeff.
26int pSLength(poly p,int l)
27{
28  int s=0;
29  while (p!=NULL) { s+=nSize(pGetCoeff(p));pIter(p); }
30  return s;
31}
32int kSBucketLength(kBucket* b)
33{
34  int s=0;
35  int i;
36  for (i=MAX_BUCKET;i>=0;i--)
37  {
38    s+=pSLength(b->buckets[i],0);
39  }
40  return s;
41}
42#endif
43
44#ifdef LEN_VAR3
45// 3.Variante: Laenge: Platz fuer Leitk * Monomanzahl
46int pSLength(poly p,int l)
47{
48  int c=nSize(pGetCoeff(p));
49  return c*l /*pLength(p)*/;
50}
51int kSBucketLength(kBucket* b)
52{
53  int s=0;
54  int c=nSize(pGetCoeff(kBucketGetLm(b)))+1;
55  int i;
56  for (i=MAX_BUCKET;i>0;i--)
57  {
58    s+=b->buckets_length[i] /*pLength(b->buckets[i])*/;
59  }
60  return s*c;
61}
62#endif
63
64#ifdef LEN_VAR4
65// 4.Variante: Laenge: Platz fuer Leitk * (1+Platz fuer andere Koeff.)
66int pSLength(poly p, int l)
67{
68  int s=1;
69  int c=nSize(pGetCoeff(p));
70  pIter(p);
71  while (p!=NULL) { s+=nSize(pGetCoeff(p));pIter(p); }
72  return s*c;
73}
74int kSBucketLength(kBucket* b)
75{
76  int s=1;
77  int c=nSize(pGetCoeff(kBucketGetLm(b)));
78  int i;
79  for (i=MAX_BUCKET;i>0;i--)
80  {
81    if(b->buckets[i]==NULL) continue;
82    s+=pSLength(b->buckets[i],0);
83  }
84  return s*c;
85}
86#endif
87static void finalize_reduction_step(reduction_step* r){
88  delete r;
89}
90static int LObject_better_gen(const void* ap, const void* bp)
91{
92  LObject* a=*(LObject**)ap;
93  LObject* b=*(LObject**)bp;
94  return(pLmCmp(a->p,b->p));
95}
96static int red_object_better_gen(const void* ap, const void* bp)
97{
98
99
100  return(pLmCmp(((red_object*) ap)->p,((red_object*) bp)->p));
101}
102static int monom_poly_crit(const void* ap1, const void* ap2){
103  monom_poly* p1;
104  monom_poly* p2;
105  p1=((monom_poly*) ap1);
106  p2=((monom_poly*)ap2);
107
108  int c=pLmCmp(p1->f,p2->f);
109  if (c !=0) return c;
110  c=pLmCmp(p1->m,p2->m);
111  return c;
112}
113static int pLmCmp_func(const void* ap1, const void* ap2){
114    poly p1,p2;
115  p1=*((poly*) ap1);
116  p2=*((poly*)ap2);
117
118  return pLmCmp(p1,p2);
119}
120static int pLmCmp_func_inverted(const void* ap1, const void* ap2){
121    poly p1,p2;
122  p1=*((poly*) ap1);
123  p2=*((poly*)ap2);
124
125  return -pLmCmp(p1,p2);
126}
127
128static int pair_better_gen2(const void* ap,const void* bp){
129  return(-pair_better_gen(ap,bp));
130}
131static int kFindDivisibleByInS_easy(kStrategy strat,const red_object & obj){
132  int i;
133  long not_sev=~obj.sev;
134  poly p=obj.p;
135  for(i=0;i<=strat->sl;i++){
136    if (pLmShortDivisibleBy(strat->S[i],strat->sevS[i],p,not_sev))
137      return i;
138  }
139  return -1;
140}
141static int kFindDivisibleByInS_easy(kStrategy strat,poly p, long sev){
142  int i;
143  long not_sev=~sev;
144  for(i=0;i<=strat->sl;i++){
145    if (pLmShortDivisibleBy(strat->S[i],strat->sevS[i],p,not_sev))
146      return i;
147  }
148  return -1;
149}
150static int posInPairs (sorted_pair_node**  p, int pn, sorted_pair_node* qe,calc_dat* c,int an=0)
151{
152  if(pn==0) return 0;
153
154  int length=pn-1;
155  int i;
156  //int an = 0;
157  int en= length;
158
159  if (pair_better(qe,p[en],c))
160    return length+1;
161
162  while(1)
163    {
164      //if (an >= en-1)
165      if(en-1<=an)
166      {
167        if (pair_better(p[an],qe,c)) return an;
168        return en;
169      }
170      i=(an+en) / 2;
171        if (pair_better(p[i],qe,c))
172          en=i;
173      else an=i;
174    }
175}
176static int posInPolys (poly*  p, int pn, poly qe,calc_dat* c)
177{
178  if(pn==0) return 0;
179
180  int length=pn-1;
181  int i;
182  int an = 0;
183  int en= length;
184
185  if (pLmCmp(qe,p[en])==1)
186    return length+1;
187
188  while(1)
189    {
190      //if (an >= en-1)
191      if(en-1<=an)
192      {
193        if (pLmCmp(p[an],qe)==1) return an;
194        return en;
195      }
196      i=(an+en) / 2;
197        if (pLmCmp(p[i],qe)==1)
198          en=i;
199      else an=i;
200    }
201}
202static BOOLEAN  ascending(int* i,int top){
203  if(top<1) return TRUE;
204  if(i[top]<i[top-1]) return FALSE;
205  return ascending(i,top-1);
206}
207
208sorted_pair_node**  merge(sorted_pair_node** p, int pn,sorted_pair_node **q, int qn,calc_dat* c){
209  int i;
210  int* a= (int*) omalloc(qn*sizeof(int));
211//   int mc;
212//   PrintS("Debug\n");
213//   for(mc=0;mc<qn;mc++)
214// {
215
216//     wrp(q[mc]->lcm_of_lm);
217//     PrintS("\n");
218// }
219//    PrintS("Debug they are in\n");
220//   for(mc=0;mc<pn;mc++)
221// {
222
223//     wrp(p[mc]->lcm_of_lm);
224//     PrintS("\n");
225// }
226  int lastpos=0;
227  for(i=0;i<qn;i++){
228    lastpos=posInPairs(p,pn,q[i],c, max(lastpos-1,0));
229    //   cout<<lastpos<<"\n";
230    a[i]=lastpos;
231
232  }
233  if((pn+qn)>c->max_pairs){
234    p=(sorted_pair_node**) omrealloc(p,2*(pn+qn)*sizeof(sorted_pair_node*));
235    c->max_pairs=2*(pn+qn);
236  }
237  for(i=qn-1;i>=0;i--){
238    size_t size;
239    if(qn-1>i)
240      size=(a[i+1]-a[i])*sizeof(sorted_pair_node*);
241    else
242      size=(pn-a[i])*sizeof(sorted_pair_node*); //as indices begin with 0
243    memmove (p+a[i]+(1+i), p+a[i], size);
244    p[a[i]+i]=q[i];
245  }
246  omfree(a);
247  return p;
248}
249
250
251static BOOLEAN trivial_syzygie(int pos1,int pos2,poly bound,calc_dat* c){
252
253
254  poly p1=c->S->m[pos1];
255  poly p2=c->S->m[pos2];
256  ring r=c->r;
257 
258
259  if (pGetComp(p1) > 0 || pGetComp(p2) > 0)
260    return FALSE;
261  int i = 1;
262  poly m=NULL;
263  poly gcd1=c->gcd_of_terms[pos1];
264  poly gcd2=c->gcd_of_terms[pos2];
265 
266  if((gcd1!=NULL) && (gcd2!=NULL)) 
267    {
268      gcd1->next=gcd2; //may ordered incorrect
269      poly m=gcd_of_terms(gcd1,c->r);
270      gcd1->next=NULL;
271     
272    } 
273
274  if (m==NULL) 
275  {
276     loop
277      {
278        if (pGetExp(p1, i)+ pGetExp(p2, i) > pGetExp(bound,i))   return FALSE;
279        if (i == pVariables){
280          PrintS("trivial");
281          return TRUE;
282        }
283        i++;
284      }
285  }
286  else 
287  {
288    loop
289      {
290        if (pGetExp(p1, i)-pGetExp(m,i) + pGetExp(p2, i) > pGetExp(bound,i))   return FALSE;
291        if (i == pVariables){
292          pDelete(&m);
293          PrintS("trivial");
294          return TRUE;
295        }
296        i++;
297      }
298  }
299
300 
301
302 
303}
304
305///returns position sets w as weight
306int find_best(red_object* r,int l, int u, int &w, calc_dat* c){
307  int best=l;
308  int i;
309  w=r[l].guess_quality(c);
310  for(i=l+1;i<=u;i++){
311    int w2=r[i].guess_quality(c);
312    if(w2<w){
313      w=w2;
314      best=i;
315    }
316   
317  }
318 return best;
319}
320
321#if 0 
322int find_best(red_object* r,int l, int u, int &w, calc_dat* c){
323
324  int sz=u-l+1;
325  int n=sz/10+1;
326  int filled=0;
327  int* indizes=(int*) omalloc(n*sizeof(int));
328  int* weight=(int*) omalloc(n*sizeof(int));
329  int worst=-1;
330  int i; 
331  for(i=l;i<=u;i++){
332    int q=r[i].guess_quality(c);
333    if ((filled<n)||(q<worst)){
334      if(filled<n){
335        worst=max(q,worst);
336        indizes[filled]=i;
337        weight[filled]=q;
338        filled++;
339      }
340    }
341    else{
342      int j;
343      for(j=0;j<filled;j++){
344        if (worst==weight[j]){
345          weight[j]=q;
346          indizes[j]=i;
347        }
348      }
349      worst=-1;
350      for(j=0;j<filled;j++){
351        if (worst<weight[j]){
352          worst=weight[j];
353        }
354      }
355    }
356  }
357  assume(filled==n);
358  int pos=0;
359
360  for(i=0;i<filled;i++){ 
361    r[indizes[i]].canonicalize();
362    weight[i]=r[indizes[i]].guess_quality(c);
363    if(weight[i]<weight[pos]) pos=i;
364  }
365  w=weight[pos];
366  pos=indizes[pos];
367
368  omfree(indizes);
369  omfree(weight);
370
371  assume(w==r[pos].guess_quality(c));
372  assume(l<=pos);
373  assume(u>=pos);
374  return pos;
375 
376}
377
378#endif
379void red_object::canonicalize(){
380  kBucketCanonicalize(bucket);
381  if(sum)
382    kBucketCanonicalize(sum->ac->bucket);
383 
384}
385BOOLEAN good_has_t_rep(int i, int j,calc_dat* c){
386  assume(i>=0);
387    assume(j>=0);
388  if (has_t_rep(i,j,c)) return TRUE;
389  poly lm=pOne();
390
391  pLcm(c->S->m[i], c->S->m[j], lm);
392  pSetm(lm);
393  assume(lm!=NULL);
394  int deciding_deg= pTotaldegree(lm);
395  int* i_con =make_connections(i,j,lm,c);
396  p_Delete(&lm,c->r);
397
398
399  for (int n=0;((n<c->n) && (i_con[n]>=0));n++){
400    if (i_con[n]==j){
401      now_t_rep(i,j,c);
402      omfree(i_con);
403
404      return TRUE;
405    }
406  }
407  omfree(i_con);
408
409  return FALSE;
410}
411BOOLEAN lenS_correct(kStrategy strat){
412  int i;
413  for(i=0;i<=strat->sl;i++){
414    if (strat->lenS[i]!=pLength(strat->S[i]))
415      return FALSE;
416  }
417  return TRUE;
418}
419
420static void notice_miss(int i, int j, calc_dat* c){
421  PrintS("-");
422 
423}
424
425static void cleanS(kStrategy strat){
426  int i=0;
427  LObject P;
428  while(i<=strat->sl){
429    P.p=strat->S[i];
430    P.sev=strat->sevS[i];
431    if(kFindDivisibleByInS(strat->S,strat->sevS,strat->sl,&P)!=i){
432      deleteInS(i,strat);
433      //remember destroying poly
434    }
435    else i++;
436  }
437}
438static int bucket_guess(kBucket* bucket){
439  int sum=0;
440  int i;
441  for (i=MAX_BUCKET;i>=0;i--){
442    sum+=bucket->buckets_length[i];
443  }
444  return sum;
445}
446
447
448
449
450
451
452static int add_to_reductors(calc_dat* c, poly h, int len){
453  //inDebug(h);
454  assume(lenS_correct(c->strat));
455 
456  int i;
457  if (c->is_char0)
458       i=simple_posInS(c->strat,h,pSLength(h,len),c->is_char0);
459  else
460    i=simple_posInS(c->strat,h,len,c->is_char0);
461 
462  LObject P; memset(&P,0,sizeof(P));
463  P.tailRing=c->r;
464  P.p=h; /*p_Copy(h,c->r);*/
465  P.FDeg=pFDeg(P.p,c->r);
466  if (!rField_is_Zp(c->r)){ 
467    pCleardenom(P.p);
468    pContent(P.p); //is a duplicate call, but belongs here
469  }
470 
471  else                     
472    pNorm(P.p);
473 
474
475  c->strat->enterS(P,i,c->strat);
476 
477 
478
479  c->strat->lenS[i]=len;
480 
481  if(c->strat->lenSw)
482    c->strat->lenSw[i]=pSLength(P.p,len);
483  return i;
484 
485}
486static void length_one_crit(calc_dat* c, int pos, int len)
487{
488  if (len==1)
489  {
490    int i;
491    for ( i=0;i<pos;i++)
492    {
493      if (c->lengths[i]==1)
494        c->states[pos][i]=HASTREP;
495    }
496    for ( i=pos+1;i<c->n;i++){
497      if (c->lengths[i]==1)
498        c->states[i][pos]=HASTREP;
499    }
500    shorten_tails(c,c->S->m[pos]);
501  }
502}
503static sorted_pair_node* find_next_pair2(calc_dat* c, BOOLEAN go_higher){
504  clean_top_of_pair_list(c);
505  sorted_pair_node* s=pop_pair(c);
506
507
508  return s;
509}
510
511static void move_forward_in_S(int old_pos, int new_pos,kStrategy strat, BOOLEAN is_char0)
512{
513  assume(old_pos>=new_pos);
514  poly p=strat->S[old_pos];
515  int ecart=strat->ecartS[old_pos];
516  long sev=strat->sevS[old_pos];
517  int s_2_r=strat->S_2_R[old_pos];
518  int length=strat->lenS[old_pos];
519  int length_w;
520  if(is_char0)
521    length_w=strat->lenSw[old_pos];
522  int i;
523  for (i=old_pos; i>new_pos; i--)
524  {
525    strat->S[i] = strat->S[i-1];
526    strat->ecartS[i] = strat->ecartS[i-1];
527    strat->sevS[i] = strat->sevS[i-1];
528    strat->S_2_R[i] = strat->S_2_R[i-1];
529  }
530  if (strat->lenS!=NULL)
531    for (i=old_pos; i>new_pos; i--)
532      strat->lenS[i] = strat->lenS[i-1];
533  if (strat->lenSw!=NULL)
534    for (i=old_pos; i>new_pos; i--)
535      strat->lenSw[i] = strat->lenSw[i-1];
536
537  strat->S[new_pos]=p;
538  strat->ecartS[new_pos]=ecart;
539  strat->sevS[new_pos]=sev;
540  strat->S_2_R[new_pos]=s_2_r;
541  strat->lenS[new_pos]=length;
542  if(is_char0)
543    strat->lenSw[new_pos]=length_w;
544  //assume(lenS_correct(strat));
545}
546static void replace_pair(int & i, int & j, calc_dat* c)
547{
548  c->soon_free=NULL;
549  int curr_deg;
550  poly lm=pOne();
551
552  pLcm(c->S->m[i], c->S->m[j], lm);
553  pSetm(lm);
554  int deciding_deg= pTotaldegree(lm);
555  int* i_con =make_connections(i,j,lm,c);
556  int z=0;
557
558  for (int n=0;((n<c->n) && (i_con[n]>=0));n++){
559    if (i_con[n]==j){
560      now_t_rep(i,j,c);
561      omfree(i_con);
562      p_Delete(&lm,c->r);
563      return;
564    }
565  }
566
567  int* j_con =make_connections(j,lm,c);
568  i= i_con[0];
569  j=j_con[0];
570  if(c->n>1){
571    if (i_con[1]>=0)
572      i=i_con[1];
573    else {
574      if (j_con[1]>=0)
575        j=j_con[1];
576    }
577  }
578  pLcm(c->S->m[i], c->S->m[j], lm);
579  pSetm(lm);
580  poly short_s;
581  curr_deg=pTotaldegree(lm);
582  int_pair_node* last=NULL;
583
584  for (int n=0;((n<c->n) && (j_con[n]>=0));n++){
585    for (int m=0;((m<c->n) && (i_con[m]>=0));m++){
586      pLcm(c->S->m[i_con[m]], c->S->m[j_con[n]], lm);
587      pSetm(lm);
588      if (pTotaldegree(lm)>=deciding_deg)
589      {
590        soon_t_rep(i_con[m],j_con[n],c);
591        int_pair_node* h= (int_pair_node*)omalloc(sizeof(int_pair_node));
592        if (last!=NULL)
593          last->next=h;
594        else
595          c->soon_free=h;
596        h->next=NULL;
597        h->a=i_con[m];
598        h->b=j_con[n];
599        last=h;
600      }
601      //      if ((comp_deg<curr_deg)
602      //  ||
603      //  ((comp_deg==curr_deg) &&
604      short_s=ksCreateShortSpoly(c->S->m[i_con[m]],c->S->m[j_con[n]],c->r);
605      if (short_s==NULL) {
606        i=i_con[m];
607        j=j_con[n];
608        now_t_rep(i_con[m],j_con[n],c);
609        p_Delete(&lm,c->r);
610        omfree(i_con);
611        omfree(j_con);
612
613        return;
614      }
615#ifdef QUICK_SPOLY_TEST
616      for (int dz=0;dz<=c->n;dz++){
617        if (dz==c->n) {
618          //have found not head reducing pair
619          i=i_con[m];
620          j=j_con[n];
621          p_Delete(&short_s,c->r);
622          p_Delete(&lm,c->r);
623          omfree(i_con);
624          omfree(j_con);
625
626          return;
627        }
628        if (p_LmDivisibleBy(c->S->m[dz],short_s,c->r)) break;
629      }
630#endif
631      int comp_deg(pTotaldegree(short_s));
632      p_Delete(&short_s,c->r);
633      if ((comp_deg<curr_deg))
634         
635      {
636        curr_deg=comp_deg;
637        i=i_con[m];
638        j=j_con[n];
639      }
640    }
641  }
642  p_Delete(&lm,c->r);
643  omfree(i_con);
644  omfree(j_con);
645  return;
646}
647
648
649static int* make_connections(int from, poly bound, calc_dat* c)
650{
651  ideal I=c->S;
652  int s=pTotaldegree(bound);
653  int* cans=(int*) omalloc(c->n*sizeof(int));
654  int* connected=(int*) omalloc(c->n*sizeof(int));
655  int cans_length=0;
656  connected[0]=from;
657  int connected_length=1;
658  long neg_bounds_short= ~p_GetShortExpVector(bound,c->r);
659  for (int i=0;i<c->n;i++){
660    if (c->T_deg[i]>s) continue;
661    if (i!=from){
662      if(p_LmShortDivisibleBy(I->m[i],c->short_Exps[i],bound,neg_bounds_short,c->r)){
663        cans[cans_length]=i;
664        cans_length++;
665      }
666    }
667  }
668  int not_yet_found=cans_length;
669  int con_checked=0;
670  int pos;
671  while((not_yet_found>0) && (con_checked<connected_length)){
672    pos=connected[con_checked];
673    for(int i=0;i<cans_length;i++){
674      if (cans[i]<0) continue;
675      if (has_t_rep(pos,cans[i],c))
676      {
677        connected[connected_length]=cans[i];
678        connected_length++;
679        cans[i]=-1;
680        --not_yet_found;
681      }
682    }
683    con_checked++;
684  }
685  if (connected_length<c->n){
686    connected[connected_length]=-1;
687  }
688  omfree(cans);
689  return connected;
690}
691static int* make_connections(int from, int to, poly bound, calc_dat* c)
692{
693  ideal I=c->S;
694  int s=pTotaldegree(bound);
695  int* cans=(int*) omalloc(c->n*sizeof(int));
696  int* connected=(int*) omalloc(c->n*sizeof(int));
697  cans[0]=to;
698  int cans_length=1;
699  connected[0]=from;
700  int last_cans_pos=-1;
701  int connected_length=1;
702  long neg_bounds_short= ~p_GetShortExpVector(bound,c->r);
703
704  int not_yet_found=cans_length;
705  int con_checked=0;
706  int pos;
707  BOOLEAN can_find_more=TRUE;
708  while(TRUE){
709    if ((con_checked<connected_length)&& (not_yet_found>0)){
710      pos=connected[con_checked];
711      for(int i=0;i<cans_length;i++){
712        if (cans[i]<0) continue;
713        if (has_t_rep(pos,cans[i],c))//||(trivial_syzygie(pos,cans[i],bound,c))
714{
715
716          connected[connected_length]=cans[i];
717          connected_length++;
718          cans[i]=-1;
719          --not_yet_found;
720
721          if (connected[connected_length-1]==to){
722            if (connected_length<c->n){
723              connected[connected_length]=-1;
724            }
725            omfree(cans);
726            return connected;
727          }
728        }
729      }
730      con_checked++;
731    }
732    else
733    {
734      for(last_cans_pos++;last_cans_pos<=c->n;last_cans_pos++){
735        if (last_cans_pos==c->n){
736          if (connected_length<c->n){
737            connected[connected_length]=-1;
738          }
739          omfree(cans);
740          return connected;
741        }
742        if ((last_cans_pos==from)||(last_cans_pos==to))
743          continue;
744        if(p_LmShortDivisibleBy(I->m[last_cans_pos],c->short_Exps[last_cans_pos],bound,neg_bounds_short,c->r)){
745          cans[cans_length]=last_cans_pos;
746          cans_length++;
747          break;
748        }
749      }
750      not_yet_found++;
751      for (int i=0;i<con_checked;i++){
752        if (has_t_rep(connected[i],last_cans_pos,c)){
753
754          connected[connected_length]=last_cans_pos;
755          connected_length++;
756          cans[cans_length-1]=-1;
757
758          --not_yet_found;
759          if (connected[connected_length-1]==to){
760            if (connected_length<c->n){
761              connected[connected_length]=-1;
762            }
763
764            omfree(cans);
765            return connected;
766          }
767          break;
768        }
769      }
770    }
771  }
772  if (connected_length<c->n){
773    connected[connected_length]=-1;
774  }
775
776  omfree(cans);
777  return connected;
778}
779#ifdef HEAD_BIN
780static inline poly p_MoveHead(poly p, omBin b)
781{
782  poly np;
783  omTypeAllocBin(poly, np, b);
784  memmove(np, p, b->sizeW*sizeof(long));
785  omFreeBinAddr(p);
786  return np;
787}
788#endif
789
790
791
792//len should be weighted length in char 0
793static int simple_posInS (kStrategy strat, poly p,int len, BOOLEAN is_char0)
794{
795
796
797  if(strat->sl==-1) return 0;
798  polyset set=strat->S;
799  intset setL=strat->lenS;
800  if (is_char0) setL=strat->lenSw;
801  int length=strat->sl;
802  int i;
803  int an = 0;
804  int en= length;
805
806  if ((len>setL[length])
807      || ((len==setL[length]) && (pLmCmp(set[length],p)== -1)))
808    return length+1;
809
810  loop
811  {
812    if (an >= en-1)
813    {
814      if ((len<setL[an])
815          || ((len==setL[an]) && (pLmCmp(set[an],p) == 1))) return an;
816      return en;
817    }
818    i=(an+en) / 2;
819    if ((len<setL[i])
820        || ((len==setL[i]) && (pLmCmp(set[i],p) == 1))) en=i;
821    //else if ((len>setL[i])
822    //|| ((len==setL[i]) && (pLmCmp(set[i],p) == -1))) an=i;
823    else an=i;
824  }
825}
826/*2
827 *if the leading term of p
828 *divides the leading term of some S[i] it will be canceled
829 */
830static inline void clearS (poly p, unsigned long p_sev,int l, int* at, int* k,
831                           kStrategy strat)
832{
833  assume(p_sev == pGetShortExpVector(p));
834  if (!pLmShortDivisibleBy(p,p_sev, strat->S[*at], ~ strat->sevS[*at])) return;
835  if (l>=strat->lenS[*at]) return;
836  PrintS("!");mflush();
837  //pDelete(&strat->S[*at]);
838  deleteInS((*at),strat);
839  (*at)--;
840  (*k)--;
841//  assume(lenS_correct(strat));
842}
843static sorted_pair_node** add_to_basis(poly h, int i_pos, int j_pos,calc_dat* c, int* ip)
844{
845
846  assume(h!=NULL);
847//  BOOLEAN corr=lenS_correct(c->strat);
848  BOOLEAN R_found=FALSE;
849  void* hp;
850
851  ++(c->n);
852  ++(c->S->ncols);
853  int i,j;
854  i=c->n-1;
855  sorted_pair_node** nodes=(sorted_pair_node**) omalloc(sizeof(sorted_pair_node*)*i);
856  int spc=0;
857  c->T_deg=(int*) omrealloc(c->T_deg,c->n*sizeof(int));
858  c->T_deg[i]=pTotaldegree(h);
859  hp=omrealloc(c->rep, c->n *sizeof(int));
860  if (hp!=NULL){
861    c->rep=(int*) hp;
862  } else {
863    exit(1);
864  }
865  c->short_Exps=(long *) omrealloc(c->short_Exps ,c->n*sizeof(long));
866
867  hp=omrealloc(c->lengths, c->n *sizeof(int));
868  if (hp!=NULL){
869    c->lengths=(int*) hp;
870  } else {
871    exit(1);
872  }
873  c->lengths[i]=pLength(h);
874  hp=omrealloc(c->states, c->n * sizeof(char*));
875 
876    c->states=(char**) hp;
877  c->gcd_of_terms=(poly*) omrealloc(c->gcd_of_terms, c->n *sizeof(poly));
878  c->gcd_of_terms[i]=gcd_of_terms(h,c->r);
879  c->rep[i]=i;
880  hp=omalloc(i*sizeof(char));
881  if (hp!=NULL){
882    c->states[i]=(char*) hp;
883  } else {
884    exit(1);
885  }
886  hp=omrealloc(c->S->m,c->n*sizeof(poly));
887  if (hp!=NULL){
888    c->S->m=(poly*) hp;
889  } else {
890    exit(1);
891  }
892  c->S->m[i]=h;
893  c->short_Exps[i]=p_GetShortExpVector(h,c->r);
894  for (j=0;j<i;j++){
895    if (c->rep[j]==j){
896      //check product criterion
897
898      c->states[i][j]=UNCALCULATED;
899
900      //lies I[i] under I[j] ?
901      if(p_LmShortDivisibleBy(c->S->m[i],c->short_Exps[i],c->S->m[j],~(c->short_Exps[j]),c->r)){
902        c->rep[j]=i;
903       
904        PrintS("R"); R_found=TRUE;
905
906        c->Rcounter++;
907        if((i_pos>=0) && (j_pos>=0)){
908       
909        }
910        for(int z=0;z<j;z++){
911          if(c->rep[z]!=z) continue;
912          if (c->states[j][z]==UNCALCULATED){
913            c->states[j][z]=UNIMPORTANT;
914          }
915        }
916        for(int z=j+1;z<i;z++){
917          if(c->rep[z]!=z) continue;
918          if (c->states[z][j]==UNCALCULATED){
919            c->states[z][j]=UNIMPORTANT;
920          }
921        }
922      }
923    }
924    else {
925      c->states[i][j]=UNIMPORTANT;
926    }
927    if ((c->lengths[i]==1) && (c->lengths[j]==1))
928      c->states[i][j]=HASTREP;
929    else if (pHasNotCF(c->S->m[i],c->S->m[j])){
930      c->easy_product_crit++;
931      c->states[i][j]=HASTREP;
932    }
933                        else if(extended_product_criterion(c->S->m[i],c->gcd_of_terms[i],c->S->m[j],c->gcd_of_terms[j],c)){
934                                        c->states[i][j]=HASTREP;
935                                        c->extended_product_crit++;
936                                        //PrintS("E");
937                        }
938    if (c->states[i][j]==UNCALCULATED){
939
940     
941//      poly short_s=ksCreateShortSpoly(c->S->m[i],c->S->m[j],c->r);
942      //    if (short_s)
943      //    {
944        sorted_pair_node* s=(sorted_pair_node*) omalloc(sizeof(sorted_pair_node));
945        s->i=max(i,j);
946        s->j=min(i,j);
947        s->expected_length=c->lengths[i]+c->lengths[j]-2;
948     
949        poly lm=pOne();
950
951        pLcm(c->S->m[i], c->S->m[j], lm);
952        pSetm(lm);
953        s->deg=pTotaldegree(lm);
954        s->lcm_of_lm=lm;
955//          pDelete(&short_s);
956        //assume(lm!=NULL);
957        nodes[spc]=s;
958        spc++;
959        // }
960        //else
961        //{
962        //c->states[i][j]=HASTREP;
963        //}
964    }
965  }
966
967  add_to_reductors(c, h, c->lengths[c->n-1]);
968  //i=posInS(c->strat,c->strat->sl,h,0 ecart);
969
970  if (c->lengths[c->n-1]==1)
971    shorten_tails(c,c->S->m[c->n-1]);
972  //you should really update c->lengths, c->strat->lenS, and the oder of polys in strat if you sort after lengths
973
974  //for(i=c->strat->sl; i>0;i--)
975  //  if(c->strat->lenS[i]<c->strat->lenS[i-1]) printf("fehler bei %d\n",i);
976  if (c->Rcounter>50) {
977    c->Rcounter=0;
978    cleanS(c->strat);
979  }
980  if(!ip){
981    qsort(nodes,spc,sizeof(sorted_pair_node*),pair_better_gen2);
982 
983   
984    c->apairs=merge(c->apairs,c->pair_top+1,nodes,spc,c);
985    c->pair_top+=spc;
986    clean_top_of_pair_list(c);
987    omfree(nodes);
988    return NULL;
989  }
990  {
991    *ip=spc;
992    return nodes;
993  }
994
995 
996
997}
998#if 0
999static poly redNF (poly h,kStrategy strat)
1000{
1001  int j = 0;
1002  int z = 3;
1003  unsigned long not_sev;
1004
1005  if (0 > strat->sl)
1006  {
1007    return h;
1008  }
1009  not_sev = ~ pGetShortExpVector(h);
1010  loop
1011    {
1012      if (pLmShortDivisibleBy(strat->S[j], strat->sevS[j], h, not_sev))
1013      {
1014        //if (strat->interpt) test_int_std(strat->kIdeal);
1015        /*- compute the s-polynomial -*/
1016#ifdef KDEBUG
1017        if (TEST_OPT_DEBUG)
1018        {
1019          PrintS("red:");
1020          wrp(h);
1021          PrintS(" with ");
1022          wrp(strat->S[j]);
1023        }
1024#endif
1025        h = ksOldSpolyRed(strat->S[j],h,strat->kNoether);
1026#ifdef KDEBUG
1027        if (TEST_OPT_DEBUG)
1028        {
1029          PrintS("\nto:");
1030          wrp(h);
1031          PrintLn();
1032        }
1033#endif
1034        if (h == NULL) return NULL;
1035        z++;
1036        if (z>=10)
1037        {
1038          z=0;
1039          pNormalize(h);
1040        }
1041        /*- try to reduce the s-polynomial -*/
1042        j = 0;
1043        not_sev = ~ pGetShortExpVector(h);
1044      }
1045      else
1046      {
1047        if (j >= strat->sl) return h;
1048        j++;
1049      }
1050    }
1051}
1052#else
1053
1054static poly redNF2 (poly h,calc_dat* c , int &len, number&  m,int n)
1055{
1056  m=nInit(1);
1057  if (h==NULL) return NULL;
1058
1059  assume(len==pLength(h));
1060  kStrategy strat=c->strat;
1061  if (0 > strat->sl)
1062  {
1063    return h;
1064  }
1065  int j;
1066 
1067  LObject P(h);
1068  P.SetShortExpVector();
1069  P.bucket = kBucketCreate(currRing);
1070  // BOOLEAN corr=lenS_correct(strat);
1071  kBucketInit(P.bucket,P.p,len /*pLength(P.p)*/);
1072  //int max_pos=simple_posInS(strat,P.p);
1073  loop
1074    {
1075
1076      j=kFindDivisibleByInS(strat->S,strat->sevS,strat->sl,&P);
1077      if ((j>=0) && ((!n)||(strat->lenS[j]<=n)))
1078      {
1079
1080       
1081        nNormalize(pGetCoeff(P.p));
1082#ifdef KDEBUG
1083        if (TEST_OPT_DEBUG)
1084        {
1085          PrintS("red:");
1086          wrp(h);
1087          PrintS(" with ");
1088          wrp(strat->S[j]);
1089        }
1090#endif
1091       
1092        number coef=kBucketPolyRed(P.bucket,strat->S[j],
1093                                   strat->lenS[j]/*pLength(strat->S[j])*/,
1094                                   strat->kNoether);
1095        number m2=nMult(m,coef);
1096        nDelete(&m);
1097        m=m2;
1098        nDelete(&coef);
1099        h = kBucketGetLm(P.bucket);
1100       
1101        if (h==NULL) {
1102          len=0;
1103          return 
1104          NULL;}
1105        P.p=h;
1106        P.t_p=NULL;
1107        P.SetShortExpVector();
1108#ifdef KDEBUG
1109        if (TEST_OPT_DEBUG)
1110        {
1111          PrintS("\nto:");
1112          wrp(h);
1113          PrintLn();
1114        }
1115#endif
1116      }
1117      else
1118      {
1119        kBucketClear(P.bucket,&(P.p),&len);
1120        kBucketDestroy(&P.bucket);
1121        pNormalize(P.p);
1122        assume(len==(pLength(P.p)));
1123        return P.p;
1124      }
1125    }
1126}
1127
1128
1129static poly redTailShort(poly h, kStrategy strat){
1130
1131  int sl=strat->sl;
1132  int i;
1133  int len=pLength(h);
1134  for(i=0;i<=strat->sl;i++){
1135    if(strat->lenS[i]>2)
1136      break;
1137  }
1138  return(redNFTail(h,i-1,strat, len));
1139}
1140
1141static void line_of_extended_prod(int fixpos,calc_dat* c){
1142    if (c->gcd_of_terms[fixpos]==NULL)
1143  {
1144    c->gcd_of_terms[fixpos]=gcd_of_terms(c->S->m[fixpos],c->r);
1145    if (c->gcd_of_terms[fixpos])
1146    {
1147      int i;
1148      for(i=0;i<fixpos;i++)
1149        if((c->states[fixpos][i]!=HASTREP)&& (extended_product_criterion(c->S->m[fixpos],c->gcd_of_terms[fixpos], c->S->m[i],c->gcd_of_terms[i],c)))
1150{
1151          c->states[fixpos][i]=HASTREP;
1152          c->extended_product_crit++;
1153}     
1154      for(i=fixpos+1;i<c->n;i++)
1155        if((c->states[i][fixpos]!=HASTREP)&& (extended_product_criterion(c->S->m[fixpos],c->gcd_of_terms[fixpos], c->S->m[i],c->gcd_of_terms[i],c)))
1156        {        c->states[i][fixpos]=HASTREP;
1157        c->extended_product_crit++;
1158        }
1159    }
1160  }
1161}
1162static void c_S_element_changed_hook(int pos, calc_dat* c){
1163  length_one_crit(c,pos, c->lengths[pos]);
1164  line_of_extended_prod(pos,c);
1165}
1166class poly_tree_node {
1167public:
1168  poly p;
1169  poly_tree_node* l;
1170  poly_tree_node* r;
1171  int n;
1172  poly_tree_node(int sn):l(NULL),r(NULL),n(sn){}
1173};
1174class exp_number_builder{
1175public:
1176  poly_tree_node* top_level;
1177  int n;
1178  int get_n(poly p);
1179  exp_number_builder():top_level(0),n(0){}
1180};
1181int exp_number_builder::get_n(poly p){
1182  poly_tree_node** node=&top_level;
1183  while(*node!=NULL){
1184    int c=pLmCmp(p,(*node)->p);
1185    if (c==0) return (*node)->n;
1186    if (c==-1) node=&((*node)->r);
1187    else
1188      node=&((*node)->l);
1189  }
1190  (*node)= new poly_tree_node(n);
1191  n++;
1192  (*node)->p=pLmInit(p);
1193  return (*node)->n;
1194}
1195class mac_poly_r{
1196public:
1197  number coef;
1198  mac_poly_r* next;
1199  int exp;
1200  mac_poly_r():next(NULL){}
1201};
1202//mac_polys exp are smaller iff they are greater by monomial ordering
1203//corresponding to solving linear equations notation
1204struct int_poly_pair{
1205  poly p;
1206  int n;
1207};
1208typedef mac_poly_r* mac_poly;
1209  void t2ippa_rec(poly* ip,int* ia, poly_tree_node* k, int &offset){
1210    if(!k) return;
1211    t2ippa_rec(ip,ia,k->l,offset);
1212    ip[offset]=k->p;
1213    ia[k->n]=offset;
1214    ++offset;
1215
1216    t2ippa_rec(ip,ia,k->r,offset);
1217    delete k;
1218  }
1219void t2ippa(poly* ip,int* ia,exp_number_builder & e){
1220
1221  int o=0;
1222  t2ippa_rec(ip,ia,e.top_level,o);
1223}
1224int anti_poly_order(const void* a, const void* b){
1225  return -pLmCmp(((int_poly_pair*) a)->p,((int_poly_pair*) b)->p );
1226}
1227mac_poly mac_p_add_ff_qq(mac_poly a, number f,mac_poly b){
1228  mac_poly erg;
1229  mac_poly* set_this;
1230  set_this=&erg;
1231  while((a!=NULL) &&(b!=NULL)){
1232    if (a->exp<b->exp){
1233      (*set_this)=a;
1234      a=a->next;
1235      set_this= &((*set_this)->next);
1236    } 
1237    else{
1238      if (a->exp>b->exp){
1239        mac_poly in =new mac_poly_r();
1240        in->exp=b->exp;
1241        in->coef=nMult(b->coef,f);
1242        (*set_this)=in;
1243        b=b->next;
1244        set_this= &((*set_this)->next);
1245      }
1246      else {
1247        //a->exp==b->ecp
1248        number n=nMult(b->coef,f);
1249        number n2=nAdd(a->coef,n);
1250        nDelete(&n);
1251        nDelete(&(a->coef));
1252        if (nIsZero(n2)){
1253          nDelete(&n2);
1254          mac_poly ao=a;
1255          a=a->next;
1256          delete ao;
1257          b=b->next;
1258         
1259        } else {
1260          a->coef=n2;
1261          b=b->next;
1262          (*set_this)=a;
1263          a=a->next;
1264          set_this= &((*set_this)->next);
1265        }
1266 
1267      }
1268   
1269    }
1270  }
1271  if((a==NULL)&&(b==NULL)){
1272    (*set_this)=NULL;
1273    return erg;
1274  }
1275  if (b==NULL) {
1276    (*set_this=a);
1277    return erg;
1278  }
1279 
1280  //a==NULL
1281  while(b!=NULL){
1282    mac_poly mp= new mac_poly_r();
1283    mp->exp=b->exp;
1284    mp->coef=nMult(f,b->coef);
1285    (*set_this)=mp;
1286    set_this=&(mp->next);
1287    b=b->next;
1288  }
1289  (*set_this)=NULL;
1290  return erg;
1291 
1292}
1293void mac_mult_cons(mac_poly p,number c){
1294  while(p){
1295    number m=nMult(p->coef,c);
1296    nDelete(&(p->coef));
1297    p->coef=m;
1298    p=p->next;
1299  }
1300 
1301}
1302int mac_length(mac_poly p){
1303  int l=0;
1304  while(p){
1305    l++;
1306    p=p->next;
1307  }
1308  return l;
1309}
1310BOOLEAN is_valid_ro(red_object & ro){
1311  red_object r2=ro;
1312  ro.validate();
1313  if ((r2.p!=ro.p)||(r2.sev!=ro.sev)||(r2.sum!=ro.sum)) return FALSE;
1314  return TRUE;
1315}
1316void pre_comp(poly* p,int & pn,calc_dat* c){
1317  if(!(pn))
1318    return;
1319  mac_poly* q=(mac_poly*) omalloc(pn*sizeof(mac_poly)); 
1320  int i;
1321  exp_number_builder e;
1322  for(i=0;i<pn;i++){
1323    assume(p[i]!=NULL);
1324    q[i]=new mac_poly_r();
1325    q[i]->exp=e.get_n(p[i]);
1326    q[i]->coef=nCopy(p[i]->coef);
1327   
1328    mac_poly qa=q[i];
1329    poly pa=p[i];
1330    while(pa->next!=NULL){
1331      qa->next = new mac_poly_r();
1332      qa=qa->next;
1333      pa=pa->next,
1334      qa->exp=e.get_n(pa);
1335      qa->coef=nCopy(pa->coef);
1336     
1337     
1338    }
1339    qa->next=NULL;
1340    pDelete(&p[i]);
1341  }
1342  poly* ip= (poly*)omalloc (e.n*sizeof(poly));
1343  int* ia=(int*) omalloc (e.n*sizeof(int));
1344  t2ippa(ip,ia,e);
1345  for(i=0;i<pn;i++){
1346    mac_poly mp=q[i];
1347    while(mp!=NULL){
1348      mp->exp=ia[mp->exp];
1349      mp=mp->next;
1350    }
1351   
1352  }
1353//gaus reduction start
1354  int col, row;
1355  col=0;
1356  row=0;
1357  assume(pn>0);
1358  while(row<pn-1){
1359    //row is the row where pivot should be
1360    // row== pn-1 means we have only to act on one row so no red nec.
1361    //we assume further all rows till the pn-1 row are non-zero
1362   
1363    //select column
1364    int i;
1365    col=q[row]->exp;
1366    int found_in_row=row;
1367    for(i=row;i<pn;i++){
1368      if(q[i]->exp<col){
1369        col=q[i]->exp;
1370        found_in_row=i;
1371      }
1372     
1373    }
1374    //select pivot
1375    int act_l=mac_length(q[found_in_row]);
1376    for(i=row+1;i<pn;i++){
1377      if((q[i]->exp==col)&&(mac_length(q[i])<act_l)){
1378        found_in_row=i;
1379        act_l=mac_length(q[i]);//should be optimized here
1380      }
1381    }
1382    mac_poly h=q[row];
1383    q[row]=q[found_in_row];
1384    q[found_in_row]=h;
1385
1386    //reduction
1387    for(i=row+1;i<pn;i++){
1388      if(q[i]->exp==q[row]->exp){
1389       
1390        number c1=nNeg(q[i]->coef);
1391        number c2=q[row]->coef;
1392        //use checkcoeff later
1393        mac_mult_cons(q[i],c2);
1394        q[i]=mac_p_add_ff_qq(q[i],c1,q[row]);
1395      }
1396         
1397       
1398       
1399    }
1400    for(i=row+1;i<pn;i++){
1401      if(q[i]==NULL){
1402        q[i]=q[pn-1];
1403        pn--;
1404        if(i!=pn){i--;}
1405      }
1406    }
1407 
1408
1409
1410
1411
1412
1413
1414
1415    row++;
1416  }
1417
1418
1419//gaus reduction end 
1420
1421
1422
1423
1424
1425  for(i=0;i<pn;i++){
1426    poly pa;
1427    mac_poly qa;
1428    p[i]=pLmInit(ip[q[i]->exp]);
1429    pSetCoeff(p[i],q[i]->coef);
1430    pa=p[i];
1431    qa=q[i];
1432    while(qa->next!=NULL){
1433      qa=qa->next;
1434      pa->next=pLmInit(ip[qa->exp]);
1435      pa=pa->next;
1436      pa->coef=qa->coef;
1437    }
1438    pa->next=NULL;
1439  }
1440  for(i=0;i<e.n;i++){
1441    pDelete(&ip[i]); 
1442  }
1443  omfree(ip);
1444  omfree(ia);
1445}
1446
1447static void go_on (calc_dat* c){
1448  //set limit of 1000 for multireductions, at the moment for
1449  //programming reasons
1450  int i=0;
1451  c->average_length=0;
1452  for(i=0;i<c->n;i++){
1453    c->average_length+=c->lengths[i];
1454  }
1455  c->average_length=c->average_length/c->n;
1456  i=0;
1457  poly* p=(poly*) omalloc((PAR_N+1)*sizeof(poly));//nullterminated
1458
1459  int curr_deg=-1;
1460  while(i<PAR_N){
1461    sorted_pair_node* s=top_pair(c);//here is actually chain criterium done
1462    if (!s) break;
1463    if(curr_deg>=0){
1464      if (s->deg >curr_deg) break;
1465    }
1466
1467    else curr_deg=s->deg;
1468    quick_pop_pair(c);
1469    if(s->i>=0){
1470      //replace_pair(s->i,s->j,c);
1471    if(s->i==s->j) {
1472      free_sorted_pair_node(s,c->r);
1473      continue;
1474        }
1475    }
1476    poly h;
1477    if(s->i>=0)
1478      h=ksOldCreateSpoly(c->S->m[s->i], c->S->m[s->j], NULL, c->r);
1479    else
1480      h=s->lcm_of_lm;
1481    if(s->i>=0)
1482      now_t_rep(s->j,s->i,c);
1483    number coef;
1484    int mlen=pLength(h);
1485    h=redNF2(h,c,mlen,coef,2);
1486    redTailShort(h,c->strat);
1487    nDelete(&coef);
1488
1489    free_sorted_pair_node(s,c->r);
1490    if(!h) continue;
1491    int len=pLength(h);
1492    p[i]=h;
1493   
1494    i++;
1495  }
1496  p[i]=NULL;
1497//  pre_comp(p,i,c);
1498  if(i==0){
1499    omfree(p);
1500    return;
1501  }
1502  red_object* buf=(red_object*) omalloc(i*sizeof(red_object));
1503  c->normal_forms+=i;
1504  int j;
1505  for(j=0;j<i;j++){
1506    buf[j].p=p[j];
1507    buf[j].sev=pGetShortExpVector(p[j]);
1508    buf[j].sum=NULL;
1509    buf[j].bucket = kBucketCreate(currRing);
1510    int len=pLength(p[j]);
1511    kBucketInit(buf[j].bucket,buf[j].p,len);
1512  }
1513  omfree(p);
1514  qsort(buf,i,sizeof(red_object),red_object_better_gen);
1515//    Print("\ncurr_deg:%i\n",curr_deg);
1516  Print("M[%i, ",i);
1517#ifdef FIND_DETERMINISTIC
1518  c->modifiedS=(BOOLEAN*) omalloc((c->strat->sl+1)*sizeof(BOOLEAN));
1519  c->expandS=(poly*) omalloc((1)*sizeof(poly));
1520  c->expandS[0]=NULL;
1521  int z2;
1522  for(z2=0;z2<=c->strat->sl;z2++)
1523    c->modifiedS[z2]=FALSE;
1524#endif
1525  multi_reduction(buf, i, c);
1526
1527  //resort S
1528#ifdef FIND_DETERMINISTIC
1529  for(z2=0;z2<=c->strat->sl;z2++)
1530  {
1531    if (c->modifiedS[z2])
1532    {
1533      int qal;
1534      if (c->strat->lenSw)
1535        qal=c->strat->lenSw[z2];
1536      else
1537        qal=c->strat->lenS[z2];
1538      int new_pos=simple_posInS(c->strat,c->strat->S[z2],qal,c->is_char0);
1539      if (new_pos<z2)
1540      { 
1541        move_forward_in_S(z2,new_pos,c->strat,c->is_char0);
1542      }
1543    }
1544  }
1545  for(z2=0;c->expandS[z2]!=NULL;z2++)
1546  {
1547    add_to_reductors(c,c->expandS[z2],pLength(c->expandS[z2]));
1548    // PrintS("E");
1549  }
1550  omfree(c->modifiedS);
1551  c->modifiedS=NULL;
1552  omfree(c->expandS);
1553  c->expandS=NULL;
1554#endif
1555  Print("%i]",i); 
1556 //  for(j=0;j<i;j++){
1557//     if(buf[j].p==NULL) PrintS("\n ZERO ALERT \n");
1558//     int z;
1559//      for(z=0;z<j;z++){
1560//       if (pLmEqual(buf[z].p, buf[j].p))
1561//      PrintS("\n Critical Warning!!!! \n");
1562     
1563//     }
1564//   }
1565  int* ibuf=(int*) omalloc(i*sizeof(int));
1566  sorted_pair_node*** sbuf=(sorted_pair_node***) omalloc(i*sizeof(sorted_pair_node**));
1567  for(j=0;j<i;j++)
1568  {
1569    int len;
1570    poly p;
1571    buf[j].flatten();
1572    kBucketClear(buf[j].bucket,&p, &len);
1573    kBucketDestroy(&buf[j].bucket);
1574    // delete buf[j];
1575    //remember to free res here
1576    p=redTailShort(p, c->strat);
1577    sbuf[j]=add_to_basis(p,-1,-1,c,ibuf+j);
1578   
1579  }
1580  int sum=0;
1581  for(j=0;j<i;j++){
1582    sum+=ibuf[j];
1583  }
1584  sorted_pair_node** big_sbuf=(sorted_pair_node**) omalloc(sum*sizeof(sorted_pair_node*));
1585  int partsum=0;
1586  for(j=0;j<i;j++)
1587  {
1588    memmove(big_sbuf+partsum, sbuf[j],ibuf[j]*sizeof(sorted_pair_node*));
1589    omfree(sbuf[j]);
1590    partsum+=ibuf[j];
1591  }
1592
1593  qsort(big_sbuf,sum,sizeof(sorted_pair_node*),pair_better_gen2);
1594  c->apairs=merge(c->apairs,c->pair_top+1,big_sbuf,sum,c);
1595  c->pair_top+=sum;
1596  clean_top_of_pair_list(c);
1597  omfree(big_sbuf);
1598  omfree(sbuf);
1599  omfree(ibuf);
1600  omfree(buf);
1601#ifdef TGB_DEBUG
1602  int z;
1603  for(z=1;z<=c->pair_top;z++)
1604  {
1605    assume(pair_better(c->apairs[z],c->apairs[z-1],c));
1606  }
1607#endif
1608  return;
1609}
1610
1611static poly redNF (poly h,kStrategy strat, int &len)
1612{
1613  len=0;
1614  if (h==NULL) return NULL;
1615  int j;
1616
1617  len=pLength(h);
1618  if (0 > strat->sl)
1619  {
1620    return h;
1621  }
1622  LObject P(h);
1623  P.SetShortExpVector();
1624  P.bucket = kBucketCreate(currRing);
1625  kBucketInit(P.bucket,P.p,len /*pLength(P.p)*/);
1626  //int max_pos=simple_posInS(strat,P.p);
1627  loop
1628    {
1629      j=kFindDivisibleByInS(strat->S,strat->sevS,strat->sl,&P);
1630      if (j>=0)
1631      {
1632        nNormalize(pGetCoeff(P.p));
1633#ifdef KDEBUG
1634        if (TEST_OPT_DEBUG)
1635        {
1636          PrintS("red:");
1637          wrp(h);
1638          PrintS(" with ");
1639          wrp(strat->S[j]);
1640        }
1641#endif
1642        number coef=kBucketPolyRed(P.bucket,strat->S[j],
1643                                   strat->lenS[j]/*pLength(strat->S[j])*/,
1644                                   strat->kNoether);
1645        nDelete(&coef);
1646        h = kBucketGetLm(P.bucket);
1647        if (h==NULL) return NULL;
1648        P.p=h;
1649        P.t_p=NULL;
1650        P.SetShortExpVector();
1651#ifdef KDEBUG
1652        if (TEST_OPT_DEBUG)
1653        {
1654          PrintS("\nto:");
1655          wrp(h);
1656          PrintLn();
1657        }
1658#endif
1659      }
1660      else
1661      {
1662        kBucketClear(P.bucket,&(P.p),&len);
1663        kBucketDestroy(&P.bucket);
1664        pNormalize(P.p);
1665        return P.p;
1666      }
1667    }
1668}
1669#endif
1670#ifdef REDTAIL_S
1671
1672static poly redNFTail (poly h,const int sl,kStrategy strat, int len)
1673{
1674  if (h==NULL) return NULL;
1675  pTest(h);
1676  if (0 > sl)
1677    return h;
1678  if (pNext(h)==NULL) return h;
1679
1680  int j;
1681  poly res=h;
1682  poly act=res;
1683  LObject P(pNext(h));
1684  pNext(res)=NULL;
1685  P.bucket = kBucketCreate(currRing);
1686  len--;
1687  h=P.p;
1688  if (len <=0) len=pLength(h);
1689  kBucketInit(P.bucket,h /*P.p*/,len /*pLength(P.p)*/);
1690  pTest(h);
1691  loop
1692    {
1693      P.p=h;
1694      P.t_p=NULL;
1695      P.SetShortExpVector();
1696      loop
1697        {
1698          j=kFindDivisibleByInS(strat->S,strat->sevS,sl,&P);
1699          if (j>=0)
1700          {
1701#ifdef REDTAIL_PROT
1702            PrintS("r");
1703#endif
1704            nNormalize(pGetCoeff(P.p));
1705#ifdef KDEBUG
1706            if (TEST_OPT_DEBUG)
1707            {
1708              PrintS("red tail:");
1709              wrp(h);
1710              PrintS(" with ");
1711              wrp(strat->S[j]);
1712            }
1713#endif
1714            number coef;
1715            pTest(strat->S[j]);
1716            coef=kBucketPolyRed(P.bucket,strat->S[j],
1717                                strat->lenS[j]/*pLength(strat->S[j])*/,strat->kNoether);
1718            pMult_nn(res,coef);
1719            nDelete(&coef);
1720            h = kBucketGetLm(P.bucket);
1721            pTest(h);
1722            if (h==NULL)
1723            {
1724#ifdef REDTAIL_PROT
1725              PrintS(" ");
1726#endif
1727              return res;
1728            }
1729            pTest(h);
1730            P.p=h;
1731            P.t_p=NULL;
1732            P.SetShortExpVector();
1733#ifdef KDEBUG
1734            if (TEST_OPT_DEBUG)
1735            {
1736              PrintS("\nto tail:");
1737              wrp(h);
1738              PrintLn();
1739            }
1740#endif
1741          }
1742          else
1743          {
1744#ifdef REDTAIL_PROT
1745            PrintS("n");
1746#endif
1747            break;
1748          }
1749        } /* end loop current mon */
1750      poly tmp=pHead(h /*kBucketGetLm(P.bucket)*/);
1751      act->next=tmp;pIter(act);
1752      poly tmp2=pHead(h);
1753      pNeg(tmp2);
1754      int ltmp2=1;
1755      pTest(tmp2);
1756      kBucket_Add_q(P.bucket, tmp2, &ltmp2);
1757
1758      h = kBucketGetLm(P.bucket);
1759      if (h==NULL)
1760      {
1761#ifdef REDTAIL_PROT
1762        PrintS(" ");
1763#endif
1764        return res;
1765      }
1766      pTest(h);
1767    }
1768}
1769#endif
1770
1771static void do_this_spoly_stuff(int i,int j,calc_dat* c){
1772  poly f=c->S->m[i];
1773  poly g=c->S->m[j];
1774  poly h=ksOldCreateSpoly(f, g, NULL, c->r);
1775  poly hr=NULL;
1776#ifdef FULLREDUCTIONS
1777  if (h!=NULL)
1778  {
1779    int len;
1780
1781//    hr=redNF2(h,c,len);
1782//      hr=redNF(h,c->strat,len);
1783
1784    if (hr!=NULL)
1785#ifdef REDTAIL_S
1786      hr = redNFTail(hr,c->strat->sl,c->strat,len);
1787#else
1788    hr = redtailBba(hr,c->strat->sl,c->strat);
1789#endif
1790
1791  }
1792#else
1793  if (h!=NULL)
1794  {
1795    int len;
1796//    hr=redNF2(h,c,len);
1797  }
1798#endif
1799  c->normal_forms++;
1800  if (hr==NULL)
1801  {
1802    notice_miss(i, j, c);
1803
1804  }
1805  else
1806  {
1807
1808#ifdef HEAD_BIN
1809    hr=p_MoveHead(hr,c->HeadBin);
1810#endif
1811    add_to_basis(hr, i,j,c);
1812  }
1813}
1814//try to fill, return FALSE iff queue is empty
1815static void simplify(monom_poly h, calc_dat* c){
1816  mp_array_list* F=c->F;
1817  poly_array_list* F_minus=c->F_minus;
1818  while(F)
1819  {
1820    assume(F_minus!=NULL);
1821    int i;
1822    for(i=0;i<F->size;i++)
1823    {
1824      if ((h.f==F->mp[i].f) &&(p_LmDivisibleBy(F->mp[i].m,h.m,c->r)))
1825      {
1826       
1827          //according to the algorithm you should test (!(pIsConstant(F[i].m)))
1828          //but I think this is only because of bad formulation
1829        int j;
1830       
1831        poly lm=pLmInit(h.f);
1832        pSetCoeff(lm,nInit(1));
1833
1834        lm=pMult_mm(lm,F->mp[i].m);
1835        for(j=0;j<F_minus->size;j++)
1836        {
1837          if (pLmEqual(F_minus->p[j],lm))
1838            break;
1839        }
1840        assume(j<F_minus->size);
1841        pDelete(&lm);
1842        if(j<F_minus->size)
1843        {
1844          pExpVectorSub(h.m,F->mp[i].m);
1845          h.f=F->mp[j].f;
1846        }
1847        break;
1848      }
1849    }
1850    F=F->next;
1851    F_minus=F_minus->next;
1852  }
1853  assume(F_minus==NULL);
1854}
1855tgb_matrix::tgb_matrix(int i, int j){
1856  n=(number**) omalloc(i*sizeof (number*));;
1857  int z;
1858  int z2;
1859  for(z=0;z<i;z++)
1860  {
1861    n[z]=(number*)omalloc(j*sizeof(number));
1862    for(z2=0;z2<j;z2++)
1863    {
1864      n[z][z2]=nInit(0);
1865    }
1866  }
1867  this->columns=j;
1868  this->rows=i;
1869  free_numbers=FALSE;
1870}
1871tgb_matrix::~tgb_matrix(){
1872  int z;
1873  for(z=0;z<rows;z++)
1874  {
1875    if(free_numbers)
1876    {
1877      int z2;
1878      for(z2=0;z2<columns;z2++)
1879      {
1880        nDelete(&(n[z][z2]));
1881      }
1882    }
1883    omfree(n[z]);
1884  }
1885  omfree(n);
1886}
1887
1888//transfers ownership of n to the matrix
1889void tgb_matrix::set(int i, int j, number n){
1890  assume(i<rows);
1891  assume(j<columns);
1892  this->n[i][j]=n;
1893}
1894int tgb_matrix::get_rows(){
1895  return rows;
1896}
1897int tgb_matrix::get_columns(){
1898  return columns;
1899}
1900number tgb_matrix::get(int i, int j){
1901  assume(i<rows);
1902  assume(j<columns);
1903  return n[i][j];
1904}
1905BOOLEAN tgb_matrix::is_zero_entry(int i, int j){
1906  return (nIsZero(n[i][j]));
1907}
1908void tgb_matrix::perm_rows(int i, int j){
1909  number* h;
1910  h=n[i];
1911  n[i]=n[j];
1912  n[j]=h;
1913}
1914BOOLEAN tgb_matrix::min_col_not_zero_in_row(int row){
1915  int i;
1916  for(i=0;i<columns;i++)
1917  {
1918    if(!(nIsZero(n[row][i])))
1919      return i;
1920  }
1921  return columns;//error code
1922}
1923BOOLEAN tgb_matrix::zero_row(int row){
1924  int i;
1925  for(i=0;i<columns;i++)
1926  {
1927    if(!(nIsZero(n[row][i])))
1928      return FALSE;
1929  }
1930  return TRUE;
1931}
1932int tgb_matrix::non_zero_entries(int row){
1933  int i;
1934  int z=0;
1935  for(i=0;i<columns;i++)
1936  {
1937    if(!(nIsZero(n[row][i])))
1938      z++;
1939  }
1940  return z;
1941}
1942//row add_to=row add_to +row summand*factor
1943void tgb_matrix::add_lambda_times_row(int add_to,int summand,number factor){
1944  int i;
1945  for(i=0;i<columns;i++){
1946    if(!(nIsZero(n[summand][i])))
1947    {
1948      number n1=n[add_to][i];
1949      number n2=nMult(factor,n[summand][i]);
1950      n[add_to][i]=nAdd(n1,n2);
1951      nDelete(&n1);
1952      nDelete(&n2);
1953    }
1954  }
1955}
1956void tgb_matrix::mult_row(int row,number factor){
1957  int i;
1958  for(i=0;i<columns;i++){
1959    if(!(nIsZero(n[row][i])))
1960    {
1961      number n1=n[row][i];
1962      n[row][i]=nMult(n1,factor);
1963      nDelete(&n1);
1964    }
1965  }
1966}
1967void simple_gauss(tgb_matrix* mat){
1968  int col, row;
1969  col=0;
1970  row=0;
1971  int i;
1972  int pn=mat->get_rows();
1973  assume(pn>0);
1974  //first clear zeroes
1975  for(i=0;i<pn;i++)
1976  {
1977    if(mat->zero_row(i))
1978    {
1979      mat->perm_rows(i,pn-1);
1980      pn--;
1981      //if(i!=pn){i--;}
1982    }
1983  }
1984  while(row<pn-1){
1985    //row is the row where pivot should be
1986    // row== pn-1 means we have only to act on one row so no red nec.
1987    //we assume further all rows till the pn-1 row are non-zero
1988   
1989    //select column
1990   
1991    col=mat->min_col_not_zero_in_row(row);
1992    assume(col!=mat->get_columns());
1993    int found_in_row;
1994   
1995    found_in_row=row;
1996    assume(pn<mat->get_rows());
1997    for(i=row+1;i<pn;i++){
1998      int first=mat->min_col_not_zero_in_row(i);
1999      if(first<col)
2000      {
2001        col=first;
2002        found_in_row=i;
2003      }
2004    }
2005    //select pivot
2006    int act_l=mat->non_zero_entries(found_in_row);
2007    for(i=row+1;i<pn;i++){
2008      assume(mat->min_col_not_zero_in_row(i)>=col);
2009      if((!(mat->is_zero_entry(i,col)))&&(mat->non_zero_entries(i)<act_l))
2010      {
2011        found_in_row=i;
2012        act_l=mat->non_zero_entries(i);//should be optimized here
2013      }
2014
2015    }
2016    mat->perm_rows(row,found_in_row);
2017
2018   
2019    //reduction
2020    for(i=row+1;i<pn;i++){
2021      assume(mat->min_col_not_zero_in_row(i)>=col);
2022      if(!(mat->is_zero_entry(i,col)))
2023      {
2024       
2025        number c1=nNeg(mat->get(i,col));
2026        number c2=mat->get(row,col);
2027        number n1=c1;
2028        number n2=c2;
2029
2030        ksCheckCoeff(&n1,&n2);
2031        nDelete(&c1);
2032        mat->mult_row(i,n2);
2033        mat->add_lambda_times_row(i,row,n1);
2034        assume(mat->is_zero_entry(i,col));
2035
2036      } 
2037      assume(mat->min_col_not_zero_in_row(i)>col);
2038    }
2039    for(i=row+1;i<pn;i++)
2040    {
2041      if(mat->zero_row(i))
2042      {
2043        mat->perm_rows(i,pn-1);
2044        pn--;
2045      }
2046    }
2047    row++;
2048  }
2049}
2050
2051static tgb_matrix* build_matrix(poly* p,int p_index,poly* done, int done_index, calc_dat* c){
2052  tgb_matrix* t=new tgb_matrix(p_index,done_index);
2053  int i, pos;
2054  for(i=0;i<p_index;i++)
2055  { 
2056    poly p_i=p[i];
2057    while(p_i)
2058    {
2059      int v=-1;
2060      pos=posInPolys (done, done_index, p_i,c);
2061      if((done_index>pos)&&(pLmEqual(p_i,done[pos])))
2062        v=pos;
2063      if((pos>0) &&(pLmEqual(p_i,done[pos-1])))
2064        v=pos-1;
2065      assume(v!=-1);
2066      //v is ascending ordered, we need descending order
2067      v=done_index-1-v;
2068      t->set(i,v,nCopy(p_i->coef));
2069    }
2070  }
2071  return t;
2072}
2073static void go_on_F4 (calc_dat* c){
2074  //set limit of 1000 for multireductions, at the moment for
2075  //programming reasons
2076  int done_size=PAR_N_F4*2;
2077  poly* done=(poly*) omalloc(done_size*sizeof(poly));
2078  int done_index=0; //done_index must always be smaller than done_size
2079  int chosen_size=PAR_N_F4*2;
2080  monom_poly* chosen=(monom_poly*) omalloc(done_size*sizeof(monom_poly));
2081  int chosen_index=0;
2082  int i=0;
2083  c->average_length=0;
2084  for(i=0;i<c->n;i++){
2085    c->average_length+=c->lengths[i];
2086  }
2087  c->average_length=c->average_length/c->n;
2088  i=0;
2089  poly* p;
2090
2091  int curr_deg=-1;
2092 
2093  //choose pairs and preprocess symbolically
2094  while(chosen_index<PAR_N_F4)
2095  {
2096    sorted_pair_node* s=top_pair(c);//here is actually chain criterium done
2097    if (!s) break;
2098    if(curr_deg>=0)
2099    {
2100      if (s->deg >curr_deg) break;
2101    }
2102
2103    else curr_deg=s->deg;
2104    quick_pop_pair(c);
2105    if(s->i>=0)
2106    {
2107      //replace_pair(s->i,s->j,c);
2108      if(s->i==s->j) 
2109      {
2110        free_sorted_pair_node(s,c->r);
2111        continue;
2112      }
2113    }
2114    monom_poly h;
2115    BOOLEAN only_free=FALSE;
2116    if(s->i>=0)
2117    {
2118     
2119      poly lcm=pOne();
2120     
2121      pLcm(c->S->m[s->i], c->S->m[s->j], lcm);
2122      pSetm(lcm);
2123      assume(lcm!=NULL);
2124      poly factor1=pCopy(lcm);
2125      pExpVectorSub(factor1,c->S->m[s->i]);
2126      poly factor2=pCopy(lcm);
2127      pExpVectorSub(factor2,c->S->m[s->j]);
2128
2129      if(done_index>=done_size)
2130      {
2131        done_size+=PAR_N_F4;
2132        done=(poly*) omrealloc(done,done_size*sizeof(poly));
2133      }
2134      done[done_index++]=lcm;
2135      if(chosen_index+1>=chosen_size)
2136      {
2137        //PAR_N_F4 must be greater equal 2
2138        chosen_size+=max(PAR_N_F4,2);
2139        chosen=(monom_poly*) omrealloc(chosen,chosen_size*sizeof(monom_poly));
2140      }
2141      h.f=c->S->m[s->i];
2142      h.m=factor1;
2143      chosen[chosen_index++]=h;
2144      h.f=c->S->m[s->j];
2145      h.m=factor2;
2146      chosen[chosen_index++]=h;
2147    }
2148    else
2149    {
2150      if(chosen_index>=chosen_size)
2151      {
2152        chosen_size+=PAR_N_F4;
2153        chosen=(monom_poly*) omrealloc(chosen,chosen_size*sizeof(monom_poly));
2154      }
2155      h.f=s->lcm_of_lm;
2156      h.m=pOne();
2157      pSetm(h.m);
2158      chosen[chosen_index++]=h;
2159      //must carefull remember to destroy such a h;
2160      poly_list_node* next=c->to_destroy;
2161     
2162      c->to_destroy=(poly_list_node*) omalloc(sizeof(poly_list_node));
2163      c->to_destroy->next=next;
2164      only_free=TRUE;
2165    }
2166
2167    if(s->i>=0)
2168      now_t_rep(s->j,s->i,c);
2169
2170    if(!(only_free))
2171      free_sorted_pair_node(s,c->r);
2172    else
2173      omfree(s);
2174   
2175 
2176
2177  }
2178
2179  //next Step, simplify all pairs
2180  for(i=0;i<chosen_index;i++)
2181  {
2182    simplify(chosen[i],c);
2183  }
2184 
2185  //next Step remove duplicate entries
2186  qsort(chosen,chosen_index,sizeof(monom_poly),monom_poly_crit);
2187  int pos=0;
2188  for(i=1;i<chosen_index;i++)
2189  {
2190    if((!(pLmEqual(chosen[i].f,chosen[pos].f)))||(!(pLmEqual(chosen[i].m,chosen[pos].m))))
2191      chosen[++pos]=chosen[i];
2192    else pDelete(&(chosen[i].m));
2193  }
2194  chosen_index=pos;
2195  //next step process polys
2196  int p_size=2*chosen_index;
2197  int p_index=0;
2198  p=(poly*) omalloc(p_size*sizeof(poly));
2199  for(p_index=0;p_index<chosen_index;p_index++)
2200  {
2201    p[p_index]=ppMult_mm(chosen[p_index].f,chosen[p_index].m);
2202  }
2203
2204  qsort(done, done_index,sizeof(poly),pLmCmp_func);
2205  pos=0;
2206  for(i=1;i<done_index;i++)
2207  {
2208    if((!(pLmEqual(done[i],done[pos]))))
2209      done[++pos]=done[i];
2210    else pDelete(&(done[i]));
2211  }
2212  done_index=pos;
2213
2214  poly* m;
2215  int m_index=0;
2216  int m_size=0;
2217  for(i=0;i<p_index;i++)
2218  {
2219    m_size+=pLength(p[i]);
2220  }
2221  //q=(poly*) omalloc(m_size*sizeof(poly));
2222 
2223  for(i=0;i<p_index;i++)
2224  {
2225    poly p_i=p[i];
2226    while(p_i)
2227    {
2228      m[m_index]=pLmInit(p_i);
2229      pSetCoeff(m[m_index],nInit(1));
2230      p_i=p_i->next;
2231      m_index++;
2232    }
2233  }
2234  int q_size=m_index;
2235  poly* q=(poly*) omalloc(q_size*sizeof(poly));
2236  int q_index=0;
2237  //next Step additional reductors
2238  while(m_index>0)
2239  {
2240    qsort(m, m_index,sizeof(poly),pLmCmp_func);
2241
2242   
2243    pos;
2244    for(i=1;i<m_index;i++)
2245    {
2246      if((!(pLmEqual(m[i],m[pos]))))
2247        m[++pos]=m[i];
2248      else pDelete(&(done[i]));
2249    }
2250    m_index=pos;
2251    if(done_size<done_index+m_index)
2252    {
2253      done_size=done_index+2*m_index;
2254      done=(poly*) omrealloc(done,done_size*sizeof(poly));
2255    }
2256    if(chosen_size<chosen_index+m_index)
2257    {
2258      chosen_size=chosen_index+2*m_index;
2259      chosen=(monom_poly*) omrealloc(chosen,chosen_size*sizeof(monom_poly));
2260    }
2261    q_index=0;
2262    if(q_size<m_index)
2263    {
2264      q_size=2*m_index;
2265      omfree(q);
2266      q=(poly*) omalloc(q_size*sizeof(poly));
2267    }
2268    for(i=0;i<m_index;i++)
2269    {
2270      BOOLEAN in_done=FALSE;
2271      pos=posInPolys (done, done_index, m[i],c);
2272      if(((done_index>pos)&&(pLmEqual(m[i],done[pos]))) ||(pos>0) &&(pLmEqual(m[i],done[pos-1])))
2273        in_done=TRUE;
2274      if (!(in_done))
2275      {
2276        pos=kFindDivisibleByInS_easy(c->strat,m[i], pGetShortExpVector(m[i]));
2277        if(pos>=0)
2278        {
2279          monom_poly h;
2280          h.f=c->strat->S[pos];
2281          h.m=pOne();
2282          int* ev=(int*) omalloc((c->r->N+1)*sizeof(int));
2283          pGetExpV(m[i],ev);
2284          pSetExpV(h.m,ev);
2285          omfree(ev);
2286          pExpVectorSub(h.m,c->strat->S[pos]);
2287          simplify(h,c);
2288          q[q_index]=ppMult_mm(h.f,h.m);
2289          chosen[chosen_index++]=h;
2290          q_index++;
2291        }
2292        done[done_index++]=m[i];
2293      }
2294      else
2295        pDelete(&m[i]);
2296    }
2297    if(p_size<p_index+q_index)
2298    {
2299      p_size=p_index+2*q_index;
2300      p=(poly*) omrealloc(p,p_size*sizeof(poly));
2301    }
2302    for (i=0;i<q_index;i++)
2303      p[p_index++]=q[i];
2304    m_index=0;
2305    int sum=0;
2306    for(i=0;i<p_index;i++)
2307    {
2308      sum+=pLength(p[i]);
2309    }
2310    if (m_size<sum)
2311    {
2312      omfree(m);
2313      m=(poly*) omalloc(sum*sizeof(poly));
2314    }
2315    m_size=sum;
2316    for(i=0;i<q_index;i++)
2317    {
2318      poly p_i=q[i];
2319      while(p_i)
2320      {
2321        m[m_index]=pLmInit(p_i);
2322        pSetCoeff(m[m_index],nInit(1));
2323        p_i=p_i->next;
2324        m_index++;
2325      }
2326    }
2327    qsort(done, done_index,sizeof(poly),pLmCmp_func);
2328  }
2329  omfree(m);
2330  omfree(q);
2331  //next Step build matrix
2332  assume(p_index==chosen_index);
2333 
2334  tgb_matrix* mat=build_matrix(p,p_index,done, done_index,c);
2335
2336  //next Step Gauss
2337
2338  //next Step addElements to basis
2339 
2340//  pre_comp(p,i,c);
2341  if(i==0){
2342    omfree(p);
2343    return;
2344  }
2345  red_object* buf=(red_object*) omalloc(i*sizeof(red_object));
2346  c->normal_forms+=i;
2347  int j;
2348  for(j=0;j<i;j++){
2349    buf[j].p=p[j];
2350    buf[j].sev=pGetShortExpVector(p[j]);
2351    buf[j].sum=NULL;
2352    buf[j].bucket = kBucketCreate(currRing);
2353    int len=pLength(p[j]);
2354    kBucketInit(buf[j].bucket,buf[j].p,len);
2355  }
2356  omfree(p);
2357  qsort(buf,i,sizeof(red_object),red_object_better_gen);
2358//    Print("\ncurr_deg:%i\n",curr_deg);
2359  Print("M[%i, ",i);
2360
2361  multi_reduction(buf, i, c);
2362
2363  //resort S
2364
2365  Print("%i]",i); 
2366
2367  int* ibuf=(int*) omalloc(i*sizeof(int));
2368  sorted_pair_node*** sbuf=(sorted_pair_node***) omalloc(i*sizeof(sorted_pair_node**));
2369  for(j=0;j<i;j++)
2370  {
2371    int len;
2372    poly p;
2373    buf[j].flatten();
2374    kBucketClear(buf[j].bucket,&p, &len);
2375    kBucketDestroy(&buf[j].bucket);
2376    // delete buf[j];
2377    //remember to free res here
2378    //    p=redTailShort(p, c->strat);
2379    sbuf[j]=add_to_basis(p,-1,-1,c,ibuf+j);
2380   
2381  }
2382  int sum=0;
2383  for(j=0;j<i;j++){
2384    sum+=ibuf[j];
2385  }
2386  sorted_pair_node** big_sbuf=(sorted_pair_node**) omalloc(sum*sizeof(sorted_pair_node*));
2387  int partsum=0;
2388  for(j=0;j<i;j++)
2389  {
2390    memmove(big_sbuf+partsum, sbuf[j],ibuf[j]*sizeof(sorted_pair_node*));
2391    omfree(sbuf[j]);
2392    partsum+=ibuf[j];
2393  }
2394
2395  qsort(big_sbuf,sum,sizeof(sorted_pair_node*),pair_better_gen2);
2396  c->apairs=merge(c->apairs,c->pair_top+1,big_sbuf,sum,c);
2397  c->pair_top+=sum;
2398  clean_top_of_pair_list(c);
2399  omfree(big_sbuf);
2400  omfree(sbuf);
2401  omfree(ibuf);
2402  omfree(buf);
2403#ifdef TGB_DEBUG
2404  int z;
2405  for(z=1;z<=c->pair_top;z++)
2406  {
2407    assume(pair_better(c->apairs[z],c->apairs[z-1],c));
2408  }
2409#endif
2410
2411  return;
2412}
2413
2414
2415static int poly_crit(const void* ap1, const void* ap2){
2416  poly p1,p2;
2417  p1=*((poly*) ap1);
2418  p2=*((poly*)ap2);
2419
2420  int c=pLmCmp(p1,p2);
2421  if (c !=0) return c;
2422  int l1=pLength(p1);
2423  int l2=pLength(p2);
2424  if (l1<l2) return -1;
2425  if (l1>l2) return 1;
2426  return 0;
2427}
2428
2429ideal t_rep_gb(ring r,ideal arg_I, BOOLEAN F4_mode){
2430  if (F4_mode)
2431    PrintS("F4 Modus \n");
2432   
2433     
2434  //debug_Ideal=arg_debug_Ideal;
2435  //if (debug_Ideal) PrintS("DebugIdeal received\n");
2436  // Print("Idelems %i \n----------\n",IDELEMS(arg_I));
2437  ideal I=idCompactify(arg_I);
2438  qsort(I->m,IDELEMS(I),sizeof(poly),poly_crit);
2439  //Print("Idelems %i \n----------\n",IDELEMS(I));
2440  calc_dat* c=(calc_dat*) omalloc(sizeof(calc_dat));
2441  c->r=currRing;
2442  void* h;
2443  poly hp;
2444  int i,j;
2445  c->to_destroy=NULL;
2446  c->easy_product_crit=0;
2447  c->extended_product_crit=0;
2448  c->is_char0=(rChar()==0);
2449  c->F4_mode=F4_mode;
2450  c->reduction_steps=0;
2451  c->last_index=-1;
2452
2453  c->F=NULL;
2454  c->F_minus=NULL;
2455
2456  c->Rcounter=0;
2457
2458  c->soon_free=NULL;
2459
2460
2461  c->normal_forms=0;
2462  c->current_degree=1;
2463 
2464  c->max_pairs=5*I->idelems();
2465 
2466  c->apairs=(sorted_pair_node**) omalloc(sizeof(sorted_pair_node*)*c->max_pairs);
2467  c->pair_top=-1;
2468  int n=I->idelems();
2469  for (i=0;i<n;i++){
2470    wrp(I->m[i]);
2471    PrintS("\n");
2472  }
2473    i=0;
2474  c->n=0;
2475  c->T_deg=(int*) omalloc(n*sizeof(int));
2476 
2477#ifdef HEAD_BIN
2478  c->HeadBin=omGetSpecBin(POLYSIZE + (currRing->ExpL_Size)*sizeof(long));
2479#endif
2480  /* omUnGetSpecBin(&(c->HeadBin)); */
2481  h=omalloc(n*sizeof(char*));
2482  c->states=(char**) h;
2483  h=omalloc(n*sizeof(int));
2484  c->lengths=(int*) h;
2485  h=omalloc(n*sizeof(int));
2486        c->gcd_of_terms=(poly*) omalloc(n*sizeof(poly));
2487  c->rep=(int*) h;
2488  c->short_Exps=(long*) omalloc(n*sizeof(long));
2489  c->S=idInit(n,1);
2490  c->strat=new skStrategy;
2491  c->strat->syzComp = 0;
2492  initBuchMoraCrit(c->strat);
2493  initBuchMoraPos(c->strat);
2494  c->strat->initEcart = initEcartBBA;
2495  c->strat->enterS = enterSBba;
2496  c->strat->sl = -1;
2497  i=n;
2498  /* initS(c->S,NULL,c->strat); */
2499/* intS start: */
2500  i=((i+IDELEMS(c->S)+15)/16)*16;
2501  c->strat->ecartS=(intset)omAlloc(i*sizeof(int)); /*initec(i);*/
2502  c->strat->sevS=(unsigned long*)omAlloc0(i*sizeof(unsigned long));
2503  /*initsevS(i);*/
2504  c->strat->S_2_R=(int*)omAlloc0(i*sizeof(int));/*initS_2_R(i);*/
2505  c->strat->fromQ=NULL;
2506  c->strat->Shdl=idInit(1,1);
2507  c->strat->S=c->strat->Shdl->m;
2508  c->strat->lenS=(int*)omAlloc0(i*sizeof(int));
2509  if(c->is_char0)
2510    c->strat->lenSw=(int*)omAlloc0(i*sizeof(int));
2511  else
2512    c->strat->lenSw=NULL;
2513  sorted_pair_node* si;
2514  assume(n>0);
2515  add_to_basis(I->m[0],-1,-1,c);
2516
2517  assume(c->strat->sl==c->strat->Shdl->idelems()-1);
2518
2519  for (i=1;i<n;i++)//the 1 is wanted, because first element is added to basis
2520  {
2521    //     add_to_basis(I->m[i],-1,-1,c);
2522    si=(sorted_pair_node*) omalloc(sizeof(sorted_pair_node));
2523    si->i=-1;
2524    si->j=-1;
2525    si->expected_length=pLength(I->m[i]);
2526    si->deg=pTotaldegree(I->m[i]);
2527    si->lcm_of_lm=I->m[i];
2528   
2529//      c->apairs[n-1-i]=si;
2530    c->apairs[n-i-1]=si;
2531    ++(c->pair_top);
2532   }
2533 
2534
2535  while(c->pair_top>=0)
2536  {
2537    go_on(c);
2538  }
2539  while(c->to_destroy)
2540  {
2541    pDelete(&c->to_destroy->p);
2542    poly_list_node* old=c->to_destroy;
2543    c->to_destroy=c->to_destroy->next;
2544    omfree(old);
2545  }
2546  for(int z=0;z<c->n;z++){
2547    omfree(c->states[z]);
2548  }
2549  omfree(c->states);
2550  omfree(c->lengths);
2551
2552
2553  omfree(c->short_Exps);
2554  omfree(c->T_deg);
2555
2556     omFree(c->strat->ecartS);
2557     omFree(c->strat->sevS);
2558//   /*initsevS(i);*/
2559   omFree(c->strat->S_2_R);
2560   
2561
2562  omFree(c->strat->lenS);
2563
2564   if(c->strat->lenSw)  omFree(c->strat->lenSw);
2565
2566
2567
2568
2569  for(i=0;i<c->n;i++){
2570    if(c->gcd_of_terms[i])
2571      pDelete(&(c->gcd_of_terms[i]));
2572  }
2573  omfree(c->gcd_of_terms);
2574
2575  omfree(c->apairs);
2576  printf("calculated %d NFs\n",c->normal_forms);
2577  printf("applied %i product crit, %i extended_product crit \n", c->easy_product_crit, c->extended_product_crit);
2578  int deleted_form_c_s=0;
2579
2580  for(i=0;i<c->n;i++){
2581    if (c->rep[i]!=i){
2582      for(j=0;j<=c->strat->sl;j++){
2583        if(c->strat->S[j]==c->S->m[i]){
2584          c->strat->S[j]=NULL;
2585          break;
2586        }
2587      }
2588//      PrintS("R_delete");
2589      pDelete(&c->S->m[i]);
2590    }
2591  }
2592  for(i=0;i<=c->strat->sl;i++){
2593    if (!c->strat->S[i]) continue;
2594    BOOLEAN found=FALSE;
2595    for(j=0;j<c->n;j++){
2596      if (c->S->m[j]==c->strat->S[i]){
2597        found=TRUE;
2598        break;
2599      }
2600    }
2601    if(!found) pDelete(&c->strat->S[i]);
2602  }
2603  omfree(c->rep);
2604  for(i=0;i<I->idelems();i++)
2605  {
2606    I->m[i]=NULL;
2607  }
2608  idDelete(&I);
2609  I=c->S;
2610 
2611  IDELEMS(I)=c->n;
2612
2613  idSkipZeroes(c->S);
2614  for(i=0;i<=c->strat->sl;i++)
2615    c->strat->S[i]=NULL;
2616  id_Delete(&c->strat->Shdl,c->r);
2617  delete c->strat;
2618  omfree(c);
2619
2620  return(I);
2621}
2622static void now_t_rep(const int & arg_i, const int & arg_j, calc_dat* c){
2623  int i,j;
2624  if (arg_i==arg_j){
2625    return;
2626  }
2627  if (arg_i>arg_j){
2628    i=arg_j;
2629    j=arg_i;
2630  } else {
2631    i=arg_i;
2632    j=arg_j;
2633  }
2634  c->states[j][i]=HASTREP;
2635}
2636static void soon_t_rep(const int& arg_i, const int& arg_j, calc_dat* c)
2637{
2638  assume(0<=arg_i);
2639  assume(0<=arg_j);
2640  assume(arg_i<c->n);
2641  assume(arg_j<c->n);
2642  int i,j;
2643  if (arg_i==arg_j){
2644    return;
2645  }
2646  if (arg_i>arg_j){
2647    i=arg_j;
2648    j=arg_i;
2649  } else {
2650    i=arg_i;
2651    j=arg_j;
2652  }
2653  if (!
2654      (c->states[j][i]==HASTREP))
2655    c->states[j][i]=SOONTREP;
2656}
2657static BOOLEAN has_t_rep(const int & arg_i, const  int & arg_j, calc_dat* state){
2658  assume(0<=arg_i);
2659  assume(0<=arg_j);
2660  assume(arg_i<state->n);
2661  assume(arg_j<state->n);
2662  if (arg_i==arg_j)
2663  {
2664    return (TRUE);
2665  }
2666  if (arg_i>arg_j)
2667  {
2668    return (state->states[arg_i][arg_j]==HASTREP);
2669  } else
2670  {
2671    return (state->states[arg_j][arg_i]==HASTREP);
2672  }
2673}
2674static int pLcmDeg(poly a, poly b)
2675{
2676  int i;
2677  int n=0;
2678  for (i=pVariables; i; i--)
2679  {
2680    n+=max( pGetExp(a,i), pGetExp(b,i));
2681  }
2682  return n;
2683
2684}
2685
2686
2687
2688static void shorten_tails(calc_dat* c, poly monom)
2689{
2690  return;
2691// BOOLEAN corr=lenS_correct(c->strat);
2692  for(int i=0;i<c->n;i++)
2693  {
2694    //enter tail
2695    if (c->rep[i]!=i) continue;
2696    if (c->S->m[i]==NULL) continue;
2697    poly tail=c->S->m[i]->next;
2698    poly prev=c->S->m[i];
2699    BOOLEAN did_something=FALSE;
2700    while((tail!=NULL)&& (pLmCmp(tail, monom)>=0))
2701    {
2702      if (p_LmDivisibleBy(monom,tail,c->r))
2703      {
2704        did_something=TRUE;
2705        prev->next=tail->next;
2706        tail->next=NULL;
2707        p_Delete(& tail,c->r);
2708        tail=prev;
2709        //PrintS("Shortened");
2710        c->lengths[i]--;
2711      }
2712      prev=tail;
2713      tail=tail->next;
2714    }
2715    if (did_something)
2716    {
2717      int new_pos;
2718      int q;
2719      q=quality(c->S->m[i],c->lengths[i],c);
2720      new_pos=simple_posInS(c->strat,c->S->m[i],q,c->is_char0);
2721
2722      int old_pos=-1;
2723      //assume new_pos<old_pos
2724      for (int z=0;z<=c->strat->sl;z++)
2725      {
2726        if (c->strat->S[z]==c->S->m[i])
2727        {
2728          old_pos=z;
2729          break;
2730        }
2731      }
2732      if (old_pos== -1)
2733        for (int z=new_pos-1;z>=0;z--)
2734        {
2735          if (c->strat->S[z]==c->S->m[i])
2736          {
2737            old_pos=z;
2738            break;
2739          }
2740        }
2741      assume(old_pos>=0);
2742      assume(new_pos<=old_pos);
2743      assume(pLength(c->strat->S[old_pos])==c->lengths[i]);
2744      c->strat->lenS[old_pos]=c->lengths[i];
2745      if (c->strat->lenSw)
2746        c->strat->lenSw[old_pos]=q;
2747
2748      if (new_pos<old_pos)
2749        move_forward_in_S(old_pos,new_pos,c->strat, c->is_char0);
2750
2751      length_one_crit(c,i,c->lengths[i]);
2752    }
2753  }
2754}
2755static sorted_pair_node* pop_pair(calc_dat* c){
2756  clean_top_of_pair_list(c);
2757
2758  if(c->pair_top<0) return NULL;
2759  else return (c->apairs[c->pair_top--]);
2760}
2761static sorted_pair_node* top_pair(calc_dat* c){
2762  super_clean_top_of_pair_list(c);//yeah, I know, it's odd that I use a different proc here
2763
2764  if(c->pair_top<0) return NULL;
2765  else return (c->apairs[c->pair_top]);
2766}
2767static sorted_pair_node* quick_pop_pair(calc_dat* c){
2768  if(c->pair_top<0) return NULL;
2769  else return (c->apairs[c->pair_top--]);
2770}
2771static BOOLEAN no_pairs(calc_dat* c){
2772  clean_top_of_pair_list(c);
2773  return (c->pair_top==-1);
2774}
2775
2776
2777static void super_clean_top_of_pair_list(calc_dat* c){
2778  while((c->pair_top>=0) && (c->apairs[c->pair_top]->i>=0) && (good_has_t_rep(c->apairs[c->pair_top]->j, c->apairs[c->pair_top]->i,c))){
2779
2780    free_sorted_pair_node(c->apairs[c->pair_top],c->r);
2781    c->pair_top--;
2782
2783  }
2784}
2785static void clean_top_of_pair_list(calc_dat* c){
2786  while((c->pair_top>0) && (c->apairs[c->pair_top]->i>=0) && (!state_is(UNCALCULATED,c->apairs[c->pair_top]->j, c->apairs[c->pair_top]->i,c))){
2787
2788    free_sorted_pair_node(c->apairs[c->pair_top],c->r);
2789    c->pair_top--;
2790
2791  }
2792}
2793static BOOLEAN state_is(calc_state state, const int & arg_i, const  int & arg_j, calc_dat* c){
2794  assume(0<=arg_i);
2795  assume(0<=arg_j);
2796  assume(arg_i<c->n);
2797  assume(arg_j<c->n);
2798  if (arg_i==arg_j)
2799  {
2800    return (TRUE);
2801  }
2802  if (arg_i>arg_j)
2803  {
2804    return (c->states[arg_i][arg_j]==state);
2805  }
2806  else return(c->states[arg_j][arg_i]==state);
2807}
2808static void free_sorted_pair_node(sorted_pair_node* s, ring r){
2809  if (s->i>=0)
2810    p_Delete(&s->lcm_of_lm,r);
2811  omfree(s);
2812}
2813static BOOLEAN pair_better(sorted_pair_node* a,sorted_pair_node* b, calc_dat* c){
2814  if (a->deg<b->deg) return TRUE;
2815  if (a->deg>b->deg) return FALSE;
2816
2817//  if (a->expected_length<b->expected_length) return TRUE;
2818  //  if (a->expected_length>b->expected_length) return FALSE;
2819  int comp=pLmCmp(a->lcm_of_lm, b->lcm_of_lm);
2820  if (comp==1) return FALSE;
2821  if (-1==comp) return TRUE;
2822  if (a->i+a->j<b->i+b->j) return TRUE;
2823   if (a->i+a->j>b->i+b->j) return FALSE;
2824  if (a->i<b->i) return TRUE;
2825  if (a->i>b->i) return FALSE;
2826  return TRUE;
2827}
2828
2829static int pair_better_gen(const void* ap,const void* bp){
2830
2831  sorted_pair_node* a=*((sorted_pair_node**)ap);
2832  sorted_pair_node* b=*((sorted_pair_node**)bp);
2833  assume(a->i>a->j);
2834  assume(b->i>b->j);
2835  if (a->deg<b->deg) return -1;
2836  if (a->deg>b->deg) return 1;
2837
2838
2839//  if (a->expected_length<b->expected_length) return -1;
2840  // if (a->expected_length>b->expected_length) return 1;
2841 int comp=pLmCmp(a->lcm_of_lm, b->lcm_of_lm);
2842 
2843  if (comp==1) return 1;
2844  if (-1==comp) return -1;
2845  if (a->i+a->j<b->i+b->j) return -1;
2846   if (a->i+a->j>b->i+b->j) return 1;
2847  if (a->i<b->i) return -1;
2848   if (a->i>b->i) return 1;
2849  return 0;
2850}
2851
2852
2853static poly gcd_of_terms(poly p, ring r){
2854  int max_g_0=0;
2855  assume(p!=NULL);
2856  int i;
2857  poly m=pOne();
2858  poly t;
2859  for (i=pVariables; i; i--)
2860  {
2861      pSetExp(m,i, pGetExp(p,i));
2862      if (max_g_0==0)
2863        if (pGetExp(m,i)>0)
2864          max_g_0=i;
2865  }
2866 
2867  t=p->next;
2868  while (t!=NULL){
2869   
2870    if (max_g_0==0) break;
2871    for (i=pVariables; i; i--)
2872    {
2873      pSetExp(m,i, min(pGetExp(t,i),pGetExp(m,i)));
2874      if (max_g_0==i)
2875        if (pGetExp(m,i)==0)
2876          max_g_0=0;
2877      if ((max_g_0==0) && (pGetExp(m,i)>0)){
2878        max_g_0=i;
2879      }
2880    }
2881                t=t->next;
2882  }
2883        for (i=pVariables;i;i--)
2884        {
2885                if(pGetExp(m,i)>0)
2886                        return m;
2887  }
2888        pDelete(&m);
2889  return NULL;
2890}
2891static BOOLEAN pHasNotCFExtended(poly p1, poly p2, poly m)
2892{
2893
2894  if (pGetComp(p1) > 0 || pGetComp(p2) > 0)
2895    return FALSE;
2896  int i = 1;
2897  loop
2898  {
2899    if ((pGetExp(p1, i)-pGetExp(m,i) >0) && (pGetExp(p2, i) -pGetExp(m,i)> 0))   return FALSE;
2900    if (i == pVariables)                                return TRUE;
2901    i++;
2902  }
2903}
2904
2905
2906//for impl reasons may return false if the the normal product criterion matches
2907static BOOLEAN extended_product_criterion(poly p1, poly gcd1, poly p2, poly gcd2, calc_dat* c){
2908  if(gcd1==NULL) return FALSE;
2909        if(gcd2==NULL) return FALSE;
2910        gcd1->next=gcd2; //may ordered incorrect
2911        poly m=gcd_of_terms(gcd1,c->r);
2912        gcd1->next=NULL;
2913        if (m==NULL) return FALSE;
2914
2915        BOOLEAN erg=pHasNotCFExtended(p1,p2,m);
2916        pDelete(&m);
2917        return erg;
2918}
2919static poly kBucketGcd(kBucket* b, ring r)
2920{
2921  int s=0;
2922  int i;
2923  poly m, n;
2924  BOOLEAN initialized=FALSE;
2925  for (i=MAX_BUCKET-1;i>=0;i--)
2926  { 
2927    if (b->buckets[i]!=NULL){
2928      if (!initialized){
2929        m=gcd_of_terms(b->buckets[i],r);
2930        initialized=TRUE;
2931        if (m==NULL) return NULL;
2932      }
2933      else
2934        {
2935          n=gcd_of_terms(b->buckets[i],r);
2936          if (n==NULL) {
2937            pDelete(&m);
2938            return NULL;   
2939          }
2940          n->next=m;
2941          poly t=gcd_of_terms(n,r);
2942          n->next=NULL;
2943          pDelete(&m);
2944          pDelete(&n);
2945          m=t;
2946          if (m==NULL) return NULL;
2947         
2948        }
2949    }
2950  }
2951  return m;
2952}
2953
2954
2955
2956static int guess_quality(const red_object & p, calc_dat* c){
2957  //looks only on bucket
2958  if (c->is_char0) return kSBucketLength(p.bucket);
2959  return (bucket_guess(p.bucket));
2960}
2961static int quality_of_pos_in_strat_S(int pos, calc_dat* c){
2962  if (c->is_char0) return c->strat->lenSw[pos];
2963  return c->strat->lenS[pos];
2964}
2965static int quality(poly p, int len, calc_dat* c){
2966  if (c->is_char0) return pSLength(p,len);
2967  return pLength(p);
2968}
2969static void multi_reduction_lls_trick(red_object* los, int losl,calc_dat* c,find_erg & erg){
2970  erg.expand=NULL;
2971  BOOLEAN swap_roles; //from reduce_by, to_reduce_u if fromS
2972  if(erg.fromS){
2973    if(pLmEqual(c->strat->S[erg.reduce_by],los[erg.to_reduce_u].p))
2974    {
2975      int i;
2976      int quality_a=quality_of_pos_in_strat_S(erg.reduce_by,c);
2977      int best=erg.to_reduce_u+1;
2978/*
2979      for (i=erg.to_reduce_u;i>=erg.to_reduce_l;i--){
2980        int qc=los[i].guess_quality(c);
2981        if (qc<quality_a){
2982          best=i;
2983          quality_a=qc;
2984        }
2985      }
2986      if(best!=erg.to_reduce_u+1){*/
2987      int qc;
2988      best=find_best(los,erg.to_reduce_l,erg.to_reduce_u,qc,c);
2989      assume(qc==los[best].guess_quality(c));
2990      if(qc<quality_a){
2991        red_object h=los[erg.to_reduce_u];
2992        los[erg.to_reduce_u]=los[best];
2993        los[best]=h;
2994        swap_roles=TRUE;
2995      }
2996      else{
2997       
2998        swap_roles=FALSE;
2999      }
3000 
3001    }
3002      else
3003    {
3004      if (erg.to_reduce_u>erg.to_reduce_l){
3005
3006        int i;
3007        int quality_a=quality_of_pos_in_strat_S(erg.reduce_by,c);
3008        int best=erg.to_reduce_u+1;
3009        int qc;
3010        best=find_best(los,erg.to_reduce_l,erg.to_reduce_u,qc,c);
3011        assume(qc==los[best].guess_quality(c));
3012        if(qc<quality_a){
3013          //(best!=erg.to_reduce_u+1){
3014          red_object h=los[erg.to_reduce_l];
3015          los[erg.to_reduce_l]=los[best];
3016          los[best]=h;
3017          erg.reduce_by=erg.to_reduce_l;
3018          erg.fromS=FALSE;
3019          erg.to_reduce_l++;
3020         
3021        }
3022      }
3023      else 
3024      {
3025        assume(erg.to_reduce_u==erg.to_reduce_l);
3026        int quality_a=quality_of_pos_in_strat_S(erg.reduce_by,c);
3027        int qc=los[erg.to_reduce_u].guess_quality(c);
3028        if(qc<quality_a){
3029          BOOLEAN exp=FALSE;
3030          if(qc<=2)
3031            exp=TRUE;
3032          else {
3033            if (qc<quality_a/2)
3034              exp=TRUE;
3035            else
3036              if(erg.reduce_by<c->n/4)
3037                exp=TRUE;
3038          }
3039          if (exp){
3040            poly clear_into;
3041            los[erg.to_reduce_u].flatten();
3042            kBucketClear(los[erg.to_reduce_u].bucket,&clear_into,&erg.expand_length);
3043            erg.expand=pCopy(clear_into);
3044            kBucketInit(los[erg.to_reduce_u].bucket,clear_into,erg.expand_length);
3045            PrintS("e");
3046           
3047          }
3048        }
3049
3050       
3051      }
3052     
3053      swap_roles=FALSE;
3054      return;
3055      }
3056   
3057  }
3058  else{
3059    if(erg.reduce_by>erg.to_reduce_u){
3060      //then lm(rb)>= lm(tru) so =
3061      assume(erg.reduce_by==erg.to_reduce_u+1);
3062      int best=erg.reduce_by;
3063      int quality_a=los[erg.reduce_by].guess_quality(c);
3064      int qc;
3065      best=find_best(los,erg.to_reduce_l,erg.to_reduce_u,qc,c);
3066     
3067      int i;
3068      if(qc<quality_a){
3069          red_object h=los[erg.reduce_by];
3070          los[erg.reduce_by]=los[best];
3071          los[best]=h;
3072        }
3073        swap_roles=FALSE;
3074        return;
3075       
3076         
3077    }
3078    else
3079    {
3080      assume(!pLmEqual(los[erg.reduce_by].p,los[erg.to_reduce_l].p));
3081      //further assume, that reduce_by is the above all other polys
3082      //with same leading term
3083      int il=erg.reduce_by;
3084      int quality_a =los[erg.reduce_by].guess_quality(c);
3085      int qc;
3086      while((il>0) && pLmEqual(los[il-1].p,los[il].p)){
3087        il--;
3088        qc=los[il].guess_quality(c);
3089        if (qc<quality_a){
3090          quality_a=qc;
3091          erg.reduce_by=il;
3092        }
3093      }
3094      swap_roles=FALSE;
3095    }
3096 
3097  }
3098  if(swap_roles)
3099  {
3100    PrintS("b");
3101    poly clear_into;
3102    int dummy_len;
3103    int new_length;
3104    int bp=erg.to_reduce_u;//bucket_positon
3105    //kBucketClear(los[bp].bucket,&clear_into,&new_length);
3106    new_length=los[bp].clear_to_poly();
3107    clear_into=los[bp].p;
3108    poly p=c->strat->S[erg.reduce_by];
3109    int j=erg.reduce_by;
3110    int old_length=c->strat->lenS[j];// in view of S
3111    los[bp].p=p;
3112    kBucketInit(los[bp].bucket,p,old_length);
3113    int qal=quality(clear_into,new_length,c);
3114    int pos_in_c=-1;   
3115    int z;
3116    int new_pos;
3117    new_pos=simple_posInS(c->strat,clear_into,qal,c->is_char0);
3118    assume(new_pos<=j);
3119    for (z=c->n;z;z--)
3120    {
3121      if(p==c->S->m[z-1])
3122      {
3123        pos_in_c=z-1;
3124        break;
3125      }
3126    }
3127    if(pos_in_c>=0)
3128    {
3129      c->S->m[pos_in_c]=clear_into;
3130      c->lengths[pos_in_c]=new_length;
3131      c_S_element_changed_hook(pos_in_c,c);
3132    }
3133    c->strat->S[j]=clear_into;
3134    c->strat->lenS[j]=new_length;
3135    if(c->strat->lenSw)
3136      c->strat->lenS[j]=qal;
3137    if(c->is_char0)
3138    {
3139      pContent(clear_into);
3140      pCleardenom(clear_into);
3141    }
3142    else                     
3143      pNorm(clear_into);
3144#ifdef FIND_DETERMINISTIC
3145    erg.reduce_by=j;
3146    //resort later see diploma thesis, find_in_S must be deterministic
3147    //during multireduction if spolys are only in the span of the
3148    //input polys
3149#else
3150   
3151    if (new_pos<j)
3152    { 
3153      move_forward_in_S(j,new_pos,c->strat,c->is_char0);
3154      erg.reduce_by=new_pos;
3155    }
3156#endif
3157  }
3158}
3159static void multi_reduction_find(red_object* los, int losl,calc_dat* c,int startf,find_erg & erg){
3160  kStrategy strat=c->strat;
3161
3162  assume(startf<=losl);
3163  assume((startf==losl-1)||(pLmCmp(los[startf].p,los[startf+1].p)==-1));
3164  int i=startf;
3165 
3166  int j;
3167  while(i>=0){
3168    assume((i==losl-1)||(pLmCmp(los[i].p,los[i+1].p)<=0));
3169    assume(is_valid_ro(los[i]));
3170    j=kFindDivisibleByInS_easy(strat,los[i]);
3171    if(j>=0){
3172     
3173      erg.to_reduce_u=i;
3174      erg.reduce_by=j;
3175      erg.fromS=TRUE;
3176      int i2;
3177      for(i2=i-1;i2>=0;i2--){
3178        if(!pLmEqual(los[i].p,los[i2].p))
3179          break;
3180      }
3181     
3182      erg.to_reduce_l=i2+1;
3183      assume((i==losl-1)||(pLmCmp(los[i].p,los[i+1].p)==-1));
3184      return;
3185    }
3186    if (j<0){
3187     
3188      //not reduceable, try to use this for reducing higher terms
3189      int i2;
3190      i2=i;
3191      while((i2>0)&&(pLmEqual(los[i].p,los[i2-1].p)))
3192        i2--;
3193      if(i2!=i){
3194       
3195        erg.to_reduce_u=i-1;
3196        erg.to_reduce_l=i2;
3197        erg.reduce_by=i;
3198        erg.fromS=FALSE;
3199        assume((i==losl-1)||(pLmCmp(los[i].p,los[i+1].p)==-1));
3200        return;
3201      }
3202 
3203      for (i2=i+1;i2<losl;i2++){
3204        if (p_LmShortDivisibleBy(los[i].p,los[i].sev,los[i2].p,~los[i2].sev,
3205                                c->r)){
3206          int i3=i2;
3207          while((i3+1<losl) && (pLmEqual(los[i2].p, los[i3+1].p)))
3208            i3++;
3209          erg.to_reduce_u=i3;
3210          erg.to_reduce_l=i2;
3211          erg.reduce_by=i;
3212          erg.fromS=FALSE;
3213          assume((i==losl-1)||(pLmCmp(los[i].p,los[i+1].p)==-1));
3214          return;
3215        }
3216//      else {assume(!p_LmDivisibleBy(los[i].p, los[i2].p,c->r));}
3217      }
3218
3219      i--;
3220    }
3221  }
3222  erg.reduce_by=-1;//error code
3223  return;
3224}
3225
3226 //  nicht reduzierbare eintraege in ergebnisliste schreiben
3227//   nullen loeschen
3228//   while(finde_groessten leitterm reduzierbar(c,erg)){
3229 
3230static int multi_reduction_clear_zeroes(red_object* los, int  losl, int l, int u)
3231{
3232
3233
3234  int deleted=0;
3235  int  i=l;
3236  int last=-1;
3237  while(i<=u)
3238  {
3239   
3240    if(los[i].p==NULL){
3241      kBucketDestroy(&los[i].bucket);
3242//      delete los[i];//here we assume los are constructed with new
3243      //destroy resources, must be added here   
3244     if (last>=0)
3245     {
3246       memmove(los+(int)(last+1-deleted),los+(last+1),sizeof(red_object)*(i-1-last));
3247     }
3248     last=i;
3249     deleted++;
3250    }
3251    i++;
3252  }
3253  if((last>=0)&&(last!=losl-1))
3254      memmove(los+(int)(last+1-deleted),los+last+1,sizeof(red_object)*(losl-1-last));
3255  return deleted;
3256 
3257}
3258
3259static void sort_region_down(red_object* los, int l, int u, calc_dat* c)
3260{
3261  qsort(los+l,u-l+1,sizeof(red_object),red_object_better_gen);
3262  int i;
3263
3264  for(i=l;i<=u;i++)
3265  {
3266    BOOLEAN moved=FALSE;
3267    int j;
3268    for(j=i;j;j--)
3269    {
3270      if(pLmCmp(los[j].p,los[j-1].p)==-1){
3271        red_object h=los[j];
3272        los[j]=los[j-1];
3273        los[j-1]=h;
3274        moved=TRUE;
3275      }
3276      else break;
3277    }
3278    if(!moved) return;
3279  }
3280}
3281
3282//assume that los is ordered ascending by leading term, all non zero
3283static void multi_reduction(red_object* los, int & losl, calc_dat* c)
3284{
3285 
3286  //initialize;
3287  assume(c->strat->sl>=0);
3288  assume(losl>0);
3289  int i;
3290  for(i=0;i<losl;i++){
3291    los[i].sev=pGetShortExpVector(los[i].p);
3292//SetShortExpVector();
3293    los[i].p=kBucketGetLm(los[i].bucket);
3294  }
3295
3296  kStrategy strat=c->strat;
3297  int curr_pos=losl-1;
3298
3299
3300//  nicht reduzierbare einträge in ergebnisliste schreiben
3301  // nullen loeschen
3302  while(curr_pos>=0){
3303   
3304    find_erg erg;
3305    multi_reduction_find(los, losl,c,curr_pos,erg);//last argument should be curr_pos
3306   //  PrintS("\n erg:\n");
3307//     Print("upper:%i\n",erg.to_reduce_u);
3308//     Print("lower:%i\n",erg.to_reduce_l);
3309//     Print("reduce_by:%i\n",erg.reduce_by);
3310//     Print("fromS:%i\n",erg.fromS);
3311    if(erg.reduce_by<0) break;
3312
3313
3314
3315    erg.expand=NULL;
3316    int d=erg.to_reduce_u-erg.to_reduce_l+1;
3317    //if ((!erg.fromS)&&(d>100)){
3318    if (0){
3319      PrintS("L");
3320      if(!erg.fromS){
3321        erg.to_reduce_u=max(erg.to_reduce_u,erg.reduce_by);
3322        if (pLmEqual(los[erg.reduce_by].p,los[erg.to_reduce_l].p))
3323          erg.to_reduce_l=min(erg.to_reduce_l,erg.reduce_by);
3324      }
3325      int pn=erg.to_reduce_u+1-erg.to_reduce_l;
3326      poly* p=(poly*) omalloc((pn)*sizeof(poly));
3327      int i;
3328      for(i=0;i<pn;i++){
3329        int len;
3330        los[erg.to_reduce_l+i].flatten();
3331        kBucketClear(los[erg.to_reduce_l+i].bucket,&p[i],&len);
3332       
3333        redTailShort(p[i],c->strat);
3334      }
3335      pre_comp(p,pn,c);
3336      int j;
3337      for(j=0;j<pn;j++){
3338        los[erg.to_reduce_l+j].p=p[j];
3339        los[erg.to_reduce_l+j].sev=pGetShortExpVector(p[j]);
3340        los[erg.to_reduce_l+j].sum=NULL;
3341        int len=pLength(p[j]);
3342        kBucketInit(los[erg.to_reduce_l+j].bucket,los[erg.to_reduce_l+j].p,len);
3343      }
3344      for(j=erg.to_reduce_l+pn;j<=erg.to_reduce_u;j++){
3345        los[j].p=NULL;
3346       
3347      }
3348
3349      omfree(p);
3350    }
3351    else {
3352    multi_reduction_lls_trick(los,losl,c,erg);
3353    int sum=0;
3354
3355   
3356    int i;
3357    int len;
3358   
3359    multi_reduce_step(erg,los,c);
3360    }
3361//     reduction_step *rs=create_reduction_step(erg, los, c);
3362//     rs->reduce(los,erg.to_reduce_l,erg.to_reduce_u);
3363//     finalize_reduction_step(rs);
3364                 
3365    int deleted=multi_reduction_clear_zeroes(los, losl, erg.to_reduce_l, erg.to_reduce_u);
3366    curr_pos=erg.to_reduce_u;
3367    losl -= deleted;
3368    curr_pos -= deleted;
3369
3370    //Print("deleted %i \n",deleted);
3371    sort_region_down(los, erg.to_reduce_l, erg.to_reduce_u-deleted, c);
3372//   sort_region_down(los, 0, losl-1, c);
3373    //  qsort(los,losl,sizeof(red_object),red_object_better_gen);
3374    if(erg.expand)
3375    {
3376#ifdef FIND_DETERMINISTIC
3377      int i;
3378      for(i=0;c->expandS[i];i++);
3379      c->expandS=(poly*) omrealloc(c->expandS,(i+2)*sizeof(poly));
3380      c->expandS[i]=erg.expand;
3381      c->expandS[i+1]=NULL;
3382#else
3383      add_to_reductors(c,erg.expand,erg.expand_length);
3384#endif
3385    }
3386     
3387  }
3388  return;
3389}
3390void red_object::flatten(){
3391  if (sum!=NULL)
3392  {
3393
3394 
3395    if(kBucketGetLm(sum->ac->bucket)!=NULL){
3396      number mult_my=n_Mult(sum->c_my,sum->ac->multiplied,currRing);
3397      poly add_this;
3398      if(!nIsOne(mult_my))
3399        kBucket_Mult_n(bucket,mult_my);
3400      int len;
3401      poly clear_into;
3402      kBucketClear(sum->ac->bucket,&clear_into,&len);
3403      if(sum->ac->counter>1){
3404        add_this=pCopy(clear_into);
3405        kBucketInit(sum->ac->bucket,clear_into,len);
3406      }
3407      else
3408        add_this=clear_into;
3409      pMult_nn(add_this, sum->c_ac);
3410     
3411      kBucket_Add_q(bucket,add_this, &len);
3412       nDelete(&mult_my);
3413     
3414    }
3415    nDelete(&sum->c_ac);
3416    nDelete(&sum->c_my);
3417   
3418    sum->ac->decrease_counter();
3419    delete sum;
3420    p=kBucketGetLm(bucket);
3421    sum=NULL;
3422  }
3423  assume(p==kBucketGetLm(bucket));
3424  assume(sum==NULL);
3425}
3426void red_object::validate(){
3427  BOOLEAN flattened=FALSE;
3428  if(sum!=NULL)
3429  {
3430    poly lm=kBucketGetLm(bucket);
3431    poly lm_ac=kBucketGetLm(sum->ac->bucket);
3432    if ((lm_ac==NULL)||((lm!=NULL) && (pLmCmp(lm,lm_ac)!=-1))){
3433      flatten();
3434      assume(sum==NULL);
3435      flattened=TRUE;
3436      p=kBucketGetLm(bucket);
3437      if (p!=NULL)
3438        sev=pGetShortExpVector(p);
3439    } 
3440    else
3441    {
3442 
3443      p=lm_ac;
3444      assume(sum->ac->sev==pGetShortExpVector(p));
3445      sev=sum->ac->sev;
3446    }
3447   
3448  }
3449  else{
3450    p=kBucketGetLm(bucket);
3451    if(p)
3452    sev=pGetShortExpVector(p);
3453  }
3454  assume((sum==NULL)||(kBucketGetLm(sum->ac->bucket)!=NULL));
3455}
3456int red_object::clear_to_poly(){
3457  flatten();
3458  int l;
3459  kBucketClear(bucket,&p,&l);
3460  return l;
3461}
3462
3463 
3464
3465void red_object::adjust_coefs(number c_r, number c_ac_r){
3466  assume(this->sum!=NULL);
3467  number n1=nMult(sum->c_my, c_ac_r);
3468  number n2=nMult(sum->c_ac,c_r);
3469  nDelete(&sum->c_my);
3470  nDelete(&sum->c_ac);
3471 
3472  int ct = ksCheckCoeff(&n1, &n2);
3473  sum->c_my=n1;
3474  sum->c_ac=nNeg(n2);
3475  nDelete(&n2);
3476 
3477
3478}
3479int red_object::guess_quality(calc_dat* c){
3480    //works at the moment only for lenvar 1, because in different
3481    //case, you have to look on coefs
3482    int s=0;
3483    if (c->is_char0)
3484      s=kSBucketLength(bucket);
3485    else 
3486      s=bucket_guess(bucket);
3487    if (sum!=NULL){
3488      if (c->is_char0)
3489      s+=kSBucketLength(sum->ac->bucket);
3490    else 
3491      s+=bucket_guess(sum->ac->bucket);
3492    }
3493    return s;
3494}
3495void reduction_step::reduce(red_object* r, int l, int u){}
3496void simple_reducer::target_is_no_sum_reduce(red_object & ro){
3497  kBucketPolyRed(ro.bucket,p,
3498                 p_len,
3499                 c->strat->kNoether);
3500}
3501
3502void simple_reducer::target_is_a_sum_reduce(red_object & ro){
3503  pTest(p);
3504  kbTest(ro.bucket);
3505  kbTest(ro.sum->ac->bucket);
3506  assume(ro.sum!=NULL);
3507  assume(ro.sum->ac!=NULL);
3508  if(ro.sum->ac->last_reduction_id!=reduction_id){
3509    number n1=kBucketPolyRed(ro.sum->ac->bucket,p, p_len, c->strat->kNoether);
3510    number n2=nMult(n1,ro.sum->ac->multiplied);
3511    nDelete(&ro.sum->ac->multiplied);
3512    nDelete(&n1);
3513    ro.sum->ac->multiplied=n2;
3514    poly lm=kBucketGetLm(ro.sum->ac->bucket);
3515    if (lm)
3516      ro.sum->ac->sev=pGetShortExpVector(lm);
3517    ro.sum->ac->last_reduction_id=reduction_id;
3518  }
3519  ro.sev=ro.sum->ac->sev;
3520  ro.p=kBucketGetLm(ro.sum->ac->bucket);
3521}
3522void simple_reducer::reduce(red_object* r, int l, int u){
3523  this->pre_reduce(r,l,u);
3524  int i;
3525//debug start
3526  int im;
3527//  for(im=l;im<=u;im++)
3528  //  assume(is_valid_ro(r[im]));
3529 
3530
3531//debug end
3532
3533  for(i=l;i<=u;i++){
3534 
3535
3536    if(r[i].sum==NULL)
3537      this->target_is_no_sum_reduce(r[i]);
3538
3539    else 
3540    {
3541      this->target_is_a_sum_reduce(r[i]);
3542      //reduce and adjust multiplied
3543      r[i].sum->ac->last_reduction_id=reduction_id;
3544     
3545    }
3546    //most elegant would be multimethods at this point and subclassing
3547    //red_object for sum
3548 
3549  }
3550  for(i=l;i<=u;i++){
3551    r[i].validate();
3552    #ifdef TGB_DEBUG
3553    if (r[i].sum) r[i].sev=r[i].sum->ac->sev;
3554
3555    #endif
3556      }
3557}
3558reduction_step::~reduction_step(){}
3559simple_reducer::~simple_reducer(){
3560  if(fill_back!=NULL)
3561  {
3562    kBucketInit(fill_back,p,p_len);
3563  }
3564  fill_back=NULL;
3565   
3566}
3567 join_simple_reducer::~join_simple_reducer(){
3568   if(fill_back!=NULL)
3569   {
3570     kBucketInit(fill_back,p,p_len);
3571   }
3572   fill_back=NULL;
3573   
3574}
3575void multi_reduce_step(find_erg & erg, red_object* r, calc_dat* c){
3576  static int id=0;
3577  id++;
3578
3579  int rn=erg.reduce_by;
3580  poly red;
3581  int red_len;
3582  simple_reducer* pointer;
3583  BOOLEAN woc=FALSE;
3584  if(erg.fromS){
3585    red=c->strat->S[rn];
3586    red_len=c->strat->lenS[rn];
3587   
3588  }
3589  else
3590  {
3591    r[rn].flatten();
3592    kBucketClear(r[rn].bucket,&red,&red_len);
3593  }
3594  if (erg.to_reduce_u-erg.to_reduce_l>5){
3595    woc=TRUE;
3596    poly m=pOne();
3597    for(int i=1;i<=pVariables;i++)
3598      pSetExp(m,i,(pGetExp(r[erg.to_reduce_l].p, i)-pGetExp(red,i)));
3599    pSetm(m);
3600    poly red_cp=ppMult_mm(red,m);
3601   
3602    if(!erg.fromS){
3603      kBucketInit(r[rn].bucket,red,red_len);
3604    }
3605    //now reduce the copy
3606    //static poly redNF2 (poly h,calc_dat* c , int &len, number&  m,int n)
3607    redTailShort(red_cp,c->strat);
3608    //number mul;
3609    // red_len--;
3610//     red_cp->next=redNF2(red_cp->next,c,red_len,mul,c->average_length);
3611//     pSetCoeff(red_cp,nMult(red_cp->coef,mul));
3612//     nDelete(&mul);
3613//     red_len++;
3614    red=red_cp;
3615    red_len=pLength(red);
3616    pDelete(&m);
3617   
3618  }
3619  int i;
3620
3621
3622  int red_c=0;
3623  if(red_len>2*c->average_length){
3624    for(i=erg.to_reduce_l;i<=erg.to_reduce_u;i++){
3625      if((r[i].sum==NULL) ||(r[i].sum->ac->counter<=AC_FLATTEN)) red_c++;
3626    }
3627  }
3628  if (red_c>=AC_NEW_MIN)
3629    pointer=new join_simple_reducer(red,red_len,r[erg.to_reduce_l].p);
3630  else
3631    pointer=new simple_reducer(red,red_len,c);
3632
3633  if ((!woc) && (!erg.fromS))
3634    pointer->fill_back=r[rn].bucket;
3635  else
3636    pointer->fill_back=NULL;
3637  pointer->reduction_id=id;
3638  pointer->c=c;
3639
3640  pointer->reduce(r,erg.to_reduce_l, erg.to_reduce_u);
3641  if(woc) pDelete(&pointer->p);
3642  delete pointer;
3643 
3644};
3645
3646void join_simple_reducer::target_is_no_sum_reduce(red_object & ro){
3647 
3648  ro.sum=new formal_sum_descriptor();
3649  ro.sum->ac=ac;
3650  ac->counter++;
3651  kBucket_pt bucket=ro.bucket;
3652  poly a1 = pNext(p), lm = kBucketExtractLm(bucket);
3653  BOOLEAN reset_vec=FALSE;
3654  number rn;
3655  assume(a1!=NULL);
3656  number an = pGetCoeff(p), bn = pGetCoeff(lm);
3657  lm->next=NULL;
3658  int ct = ksCheckCoeff(&an, &bn);
3659  ro.sum->c_ac=nNeg(bn);
3660  ro.sum->c_my=an;
3661  assume(nIsZero(nAdd(nMult(ro.sum->c_my,lm->coef),nMult(p->coef,ro.sum->c_ac) )));
3662  if (p_GetComp(p, bucket->bucket_ring) != p_GetComp(lm, bucket->bucket_ring))
3663  {
3664    p_SetCompP(a1, p_GetComp(lm, bucket->bucket_ring), bucket->bucket_ring);
3665    reset_vec = TRUE;
3666    p_SetComp(lm, p_GetComp(p, bucket->bucket_ring), bucket->bucket_ring);
3667    p_Setm(lm, bucket->bucket_ring);
3668  }
3669
3670
3671 
3672
3673  p_DeleteLm(&lm, bucket->bucket_ring);
3674  if (reset_vec) p_SetCompP(a1, 0, bucket->bucket_ring);
3675  kbTest(bucket);
3676
3677}
3678
3679  reduction_accumulator::reduction_accumulator(poly p, int p_len, poly high_to){
3680    //sev needs to be removed from interfaces,makes no sense
3681   
3682
3683    poly my=pOne();
3684    counter=0;
3685   
3686    for(int i=1;i<=pVariables;i++)
3687      pSetExp(my,i,(pGetExp(high_to, i)-pGetExp(p,i)));
3688
3689   
3690   
3691    pSetm(my);
3692    last_reduction_id=-1;
3693    multiplied=nInit(1);
3694    bucket=kBucketCreate(currRing);
3695    poly a=pMult_mm(pCopy(p->next),my);
3696
3697    this->sev=pGetShortExpVector(a);
3698    kBucketInit(bucket, a,p_len-1);
3699    pDelete(&my);
3700  }
3701void simple_reducer:: pre_reduce(red_object* r, int l, int u){}
3702void join_simple_reducer:: pre_reduce(red_object* r, int l, int u){
3703  for(int i=l;i<=u;i++)
3704    {
3705      if (r[i].sum){
3706        if(r[i].sum->ac->counter<=AC_FLATTEN) r[i].flatten();
3707       
3708      }
3709    }
3710}
Note: See TracBrowser for help on using the repository browser.