source: git/Singular/tgb.cc @ 23e445

fieker-DuValspielwiese
Last change on this file since 23e445 was 23e445, checked in by Michael Brickenstein <bricken@…>, 20 years ago
*bricken: bugfixing, it still does not work git-svn-id: file:///usr/local/Singular/svn/trunk@7454 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 83.6 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(n[z])
1876    {
1877      if(free_numbers)
1878      {
1879        int z2;
1880        for(z2=0;z2<columns;z2++)
1881        {
1882          nDelete(&(n[z][z2]));
1883        }
1884      }
1885      omfree(n[z]);
1886    }
1887  }
1888  omfree(n);
1889}
1890
1891//transfers ownership of n to the matrix
1892void tgb_matrix::set(int i, int j, number n){
1893  assume(i<rows);
1894  assume(j<columns);
1895  this->n[i][j]=n;
1896}
1897int tgb_matrix::get_rows(){
1898  return rows;
1899}
1900int tgb_matrix::get_columns(){
1901  return columns;
1902}
1903number tgb_matrix::get(int i, int j){
1904  assume(i<rows);
1905  assume(j<columns);
1906  return n[i][j];
1907}
1908BOOLEAN tgb_matrix::is_zero_entry(int i, int j){
1909  return (nIsZero(n[i][j]));
1910}
1911void tgb_matrix::perm_rows(int i, int j){
1912  number* h;
1913  h=n[i];
1914  n[i]=n[j];
1915  n[j]=h;
1916}
1917int tgb_matrix::min_col_not_zero_in_row(int row){
1918  int i;
1919  for(i=0;i<columns;i++)
1920  {
1921    if(!(nIsZero(n[row][i])))
1922      return i;
1923  }
1924  return columns;//error code
1925}
1926int tgb_matrix::next_col_not_zero(int row,int pre){
1927  int i;
1928  for(i=pre+1;i<columns;i++)
1929  {
1930    if(!(nIsZero(n[row][i])))
1931      return i;
1932  }
1933  return columns;//error code
1934}
1935BOOLEAN tgb_matrix::zero_row(int row){
1936  int i;
1937  for(i=0;i<columns;i++)
1938  {
1939    if(!(nIsZero(n[row][i])))
1940      return FALSE;
1941  }
1942  return TRUE;
1943}
1944int tgb_matrix::non_zero_entries(int row){
1945  int i;
1946  int z=0;
1947  for(i=0;i<columns;i++)
1948  {
1949    if(!(nIsZero(n[row][i])))
1950      z++;
1951  }
1952  return z;
1953}
1954//row add_to=row add_to +row summand*factor
1955void tgb_matrix::add_lambda_times_row(int add_to,int summand,number factor){
1956  int i;
1957  for(i=0;i<columns;i++){
1958    if(!(nIsZero(n[summand][i])))
1959    {
1960      number n1=n[add_to][i];
1961      number n2=nMult(factor,n[summand][i]);
1962      n[add_to][i]=nAdd(n1,n2);
1963      nDelete(&n1);
1964      nDelete(&n2);
1965    }
1966  }
1967}
1968void tgb_matrix::mult_row(int row,number factor){
1969  int i;
1970  for(i=0;i<columns;i++){
1971    if(!(nIsZero(n[row][i])))
1972    {
1973      number n1=n[row][i];
1974      n[row][i]=nMult(n1,factor);
1975      nDelete(&n1);
1976    }
1977  }
1978}
1979void tgb_matrix::free_row(int row, BOOLEAN free_non_zeros){
1980  int i;
1981  for(i=0;i<columns;i++)
1982    if((free_non_zeros)||(nIsZero(n[row][i])))
1983      nDelete(&(n[row][i]));
1984  omfree(n[row]);
1985  n[row]=NULL;
1986}
1987void simple_gauss(tgb_matrix* mat){
1988  int col, row;
1989  col=0;
1990  row=0;
1991  int i;
1992  int pn=mat->get_rows();
1993  assume(pn>0);
1994  //first clear zeroes
1995  for(i=0;i<pn;i++)
1996  {
1997    if(mat->zero_row(i))
1998    {
1999      mat->perm_rows(i,pn-1);
2000      pn--;
2001      //if(i!=pn){i--;}
2002    }
2003  }
2004  while(row<pn-1){
2005    //row is the row where pivot should be
2006    // row== pn-1 means we have only to act on one row so no red nec.
2007    //we assume further all rows till the pn-1 row are non-zero
2008   
2009    //select column
2010   
2011    col=mat->min_col_not_zero_in_row(row);
2012    assume(col!=mat->get_columns());
2013    int found_in_row;
2014   
2015    found_in_row=row;
2016    assume(pn<mat->get_rows());
2017    for(i=row+1;i<pn;i++){
2018      int first=mat->min_col_not_zero_in_row(i);
2019      if(first<col)
2020      {
2021        col=first;
2022        found_in_row=i;
2023      }
2024    }
2025    //select pivot
2026    int act_l=mat->non_zero_entries(found_in_row);
2027    for(i=row+1;i<pn;i++){
2028      assume(mat->min_col_not_zero_in_row(i)>=col);
2029      if((!(mat->is_zero_entry(i,col)))&&(mat->non_zero_entries(i)<act_l))
2030      {
2031        found_in_row=i;
2032        act_l=mat->non_zero_entries(i);//should be optimized here
2033      }
2034
2035    }
2036    mat->perm_rows(row,found_in_row);
2037
2038   
2039    //reduction
2040    for(i=row+1;i<pn;i++){
2041      assume(mat->min_col_not_zero_in_row(i)>=col);
2042      if(!(mat->is_zero_entry(i,col)))
2043      {
2044       
2045        number c1=nNeg(mat->get(i,col));
2046        number c2=mat->get(row,col);
2047        number n1=c1;
2048        number n2=c2;
2049
2050        ksCheckCoeff(&n1,&n2);
2051        nDelete(&c1);
2052        mat->mult_row(i,n2);
2053        mat->add_lambda_times_row(i,row,n1);
2054        assume(mat->is_zero_entry(i,col));
2055
2056      } 
2057      assume(mat->min_col_not_zero_in_row(i)>col);
2058    }
2059    for(i=row+1;i<pn;i++)
2060    {
2061      if(mat->zero_row(i))
2062      {
2063        mat->perm_rows(i,pn-1);
2064        pn--;
2065      }
2066    }
2067    row++;
2068  }
2069}
2070
2071static tgb_matrix* build_matrix(poly* p,int p_index,poly* done, int done_index, calc_dat* c){
2072  tgb_matrix* t=new tgb_matrix(p_index,done_index);
2073  int i, pos;
2074  for(i=0;i<p_index;i++)
2075  { 
2076    poly p_i=p[i];
2077    while(p_i)
2078    {
2079      int v=-1;
2080      pos=posInPolys (done, done_index, p_i,c);
2081      if((done_index>pos)&&(pLmEqual(p_i,done[pos])))
2082        v=pos;
2083      if((pos>0) &&(pLmEqual(p_i,done[pos-1])))
2084        v=pos-1;
2085      assume(v!=-1);
2086      //v is ascending ordered, we need descending order
2087      v=done_index-1-v;
2088      t->set(i,v,nCopy(p_i->coef));
2089    }
2090  }
2091  return t;
2092}
2093
2094//returns m_index and destroys mat
2095static int retranslate(poly* m,tgb_matrix* mat,poly* done, calc_dat* c){
2096  int i;
2097  int m_index=0;
2098  for(i=0;i<mat->get_rows();i++)
2099  {
2100    if(mat->zero_row(i))
2101    {
2102      mat->free_row(i);
2103      continue;
2104    }
2105   
2106    m[m_index]=pInit();
2107    int v=mat->min_col_not_zero_in_row(i);
2108    //v=done_index-1-pos; => pos=done_index-1-v=mat->get_columns()-1-v
2109    int pos=mat->get_columns()-1-v;
2110    int* ev=(int*) omalloc((c->r->N+1)*sizeof(int));
2111    pGetExpV(done[pos],ev);
2112    pSetExpV(m[m_index],ev);
2113    omfree(ev);
2114   
2115    poly p=m[m_index];
2116    pSetCoeff(p,mat->get(i,v));
2117    while((v=mat->next_col_not_zero(i,v))!=mat->get_columns())
2118    {
2119      poly pn=pInit();
2120     
2121      //v=done_index-1-pos; => pos=done_index-1-v=mat->get_columns()-1-v
2122      pos=mat->get_columns()-1-v;
2123      ev=(int*) omalloc((c->r->N+1)*sizeof(int));
2124      pGetExpV(done[pos],ev);
2125      pSetExpV(pn,ev);
2126      omfree(ev);
2127      pSetCoeff(pn,mat->get(i,v));
2128      p->next=pn;
2129      p=pn;
2130    }
2131    p->next=NULL;
2132    mat->free_row(i, FALSE);
2133    m_index++;
2134  }
2135
2136  delete mat;
2137  return m_index;
2138
2139}
2140static void go_on_F4 (calc_dat* c){
2141  //set limit of 1000 for multireductions, at the moment for
2142  //programming reasons
2143  int done_size=PAR_N_F4*2;
2144  poly* done=(poly*) omalloc(done_size*sizeof(poly));
2145  int done_index=0; //done_index must always be smaller than done_size
2146  int chosen_size=PAR_N_F4*2;
2147  monom_poly* chosen=(monom_poly*) omalloc(done_size*sizeof(monom_poly));
2148  int chosen_index=0;
2149  int i=0;
2150  c->average_length=0;
2151  for(i=0;i<c->n;i++){
2152    c->average_length+=c->lengths[i];
2153  }
2154  c->average_length=c->average_length/c->n;
2155  i=0;
2156  poly* p;
2157  int nfs=0;
2158  int curr_deg=-1;
2159 
2160  //choose pairs and preprocess symbolically
2161  while(chosen_index<PAR_N_F4)
2162  {
2163   
2164    sorted_pair_node* s=top_pair(c);//here is actually chain criterium done
2165    if (!s) break;
2166    nfs++;
2167    if(curr_deg>=0)
2168    {
2169      if (s->deg >curr_deg) break;
2170    }
2171
2172    else curr_deg=s->deg;
2173    quick_pop_pair(c);
2174    if(s->i>=0)
2175    {
2176      //replace_pair(s->i,s->j,c);
2177      if(s->i==s->j) 
2178      {
2179        free_sorted_pair_node(s,c->r);
2180        continue;
2181      }
2182    }
2183    monom_poly h;
2184    BOOLEAN only_free=FALSE;
2185    if(s->i>=0)
2186    {
2187     
2188      poly lcm=pOne();
2189     
2190      pLcm(c->S->m[s->i], c->S->m[s->j], lcm);
2191      pSetm(lcm);
2192      assume(lcm!=NULL);
2193      poly factor1=pCopy(lcm);
2194      pExpVectorSub(factor1,c->S->m[s->i]);
2195      poly factor2=pCopy(lcm);
2196      pExpVectorSub(factor2,c->S->m[s->j]);
2197
2198      if(done_index>=done_size)
2199      {
2200        done_size+=PAR_N_F4;
2201        done=(poly*) omrealloc(done,done_size*sizeof(poly));
2202      }
2203      done[done_index++]=lcm;
2204      if(chosen_index+1>=chosen_size)
2205      {
2206        //PAR_N_F4 must be greater equal 2
2207        chosen_size+=max(PAR_N_F4,2);
2208        chosen=(monom_poly*) omrealloc(chosen,chosen_size*sizeof(monom_poly));
2209      }
2210      h.f=c->S->m[s->i];
2211      h.m=factor1;
2212      chosen[chosen_index++]=h;
2213      h.f=c->S->m[s->j];
2214      h.m=factor2;
2215      chosen[chosen_index++]=h;
2216    }
2217    else
2218    {
2219      if(chosen_index>=chosen_size)
2220      {
2221        chosen_size+=PAR_N_F4;
2222        chosen=(monom_poly*) omrealloc(chosen,chosen_size*sizeof(monom_poly));
2223      }
2224      h.f=s->lcm_of_lm;
2225      h.m=pOne();
2226      pSetm(h.m);
2227      chosen[chosen_index++]=h;
2228      //must carefull remember to destroy such a h;
2229      poly_list_node* next=c->to_destroy;
2230     
2231      c->to_destroy=(poly_list_node*) omalloc(sizeof(poly_list_node));
2232      c->to_destroy->next=next;
2233      only_free=TRUE;
2234    }
2235
2236    if(s->i>=0)
2237      now_t_rep(s->j,s->i,c);
2238
2239    if(!(only_free))
2240      free_sorted_pair_node(s,c->r);
2241    else
2242      omfree(s);
2243   
2244 
2245
2246  }
2247  Print("M[%i, ",nfs);
2248  //next Step, simplify all pairs
2249  for(i=0;i<chosen_index;i++)
2250  {
2251    simplify(chosen[i],c);
2252  }
2253 
2254  //next Step remove duplicate entries
2255  qsort(chosen,chosen_index,sizeof(monom_poly),monom_poly_crit);
2256  int pos=0;
2257  for(i=1;i<chosen_index;i++)
2258  {
2259    if((!(pLmEqual(chosen[i].f,chosen[pos].f)))||(!(pLmEqual(chosen[i].m,chosen[pos].m))))
2260      chosen[++pos]=chosen[i];
2261    else pDelete(&(chosen[i].m));
2262  }
2263  chosen_index=pos;
2264  //next step process polys
2265  int p_size=2*chosen_index;
2266  int p_index=0;
2267  p=(poly*) omalloc(p_size*sizeof(poly));
2268  for(p_index=0;p_index<chosen_index;p_index++)
2269  {
2270    p[p_index]=ppMult_mm(chosen[p_index].f,chosen[p_index].m);
2271  }
2272
2273  qsort(done, done_index,sizeof(poly),pLmCmp_func);
2274  pos=0;
2275  for(i=1;i<done_index;i++)
2276  {
2277    if((!(pLmEqual(done[i],done[pos]))))
2278      done[++pos]=done[i];
2279    else pDelete(&(done[i]));
2280  }
2281  done_index=pos+1;
2282#ifdef TGB_DEBUG
2283  for(i=0;i<done_index;i++)
2284    pTest(done[i]);
2285#endif
2286  poly* m;
2287  int m_index=0;
2288  int m_size=0;
2289  for(i=0;i<p_index;i++)
2290  {
2291    m_size+=pLength(p[i]);
2292  }
2293  //q=(poly*) omalloc(m_size*sizeof(poly));
2294 
2295  for(i=0;i<p_index;i++)
2296  {
2297    poly p_i=p[i];
2298    while(p_i)
2299    {
2300      m[m_index]=pLmInit(p_i);
2301      pSetCoeff(m[m_index],nInit(1));
2302      p_i=p_i->next;
2303      m_index++;
2304    }
2305  }
2306  int q_size=m_index;
2307  poly* q=(poly*) omalloc(q_size*sizeof(poly));
2308  int q_index=0;
2309  //next Step additional reductors
2310  while(m_index>0)
2311  {
2312    qsort(m, m_index,sizeof(poly),pLmCmp_func);
2313
2314   
2315    pos=0;
2316    for(i=1;i<m_index;i++)
2317    {
2318      if((!(pLmEqual(m[i],m[pos]))))
2319        m[++pos]=m[i];
2320      else pDelete(&(m[i]));
2321    }
2322    m_index=pos;
2323    if(done_size<done_index+m_index)
2324    {
2325      done_size=done_index+2*m_index;
2326      done=(poly*) omrealloc(done,done_size*sizeof(poly));
2327    }
2328    if(chosen_size<chosen_index+m_index)
2329    {
2330      chosen_size=chosen_index+2*m_index;
2331      chosen=(monom_poly*) omrealloc(chosen,chosen_size*sizeof(monom_poly));
2332    }
2333    q_index=0;
2334    if(q_size<m_index)
2335    {
2336      q_size=2*m_index;
2337      omfree(q);
2338      q=(poly*) omalloc(q_size*sizeof(poly));
2339    }
2340    for(i=0;i<m_index;i++)
2341    {
2342      BOOLEAN in_done=FALSE;
2343      pos=posInPolys (done, done_index, m[i],c);
2344      if(((done_index>pos)&&(pLmEqual(m[i],done[pos]))) ||(pos>0) &&(pLmEqual(m[i],done[pos-1])))
2345        in_done=TRUE;
2346      if (!(in_done))
2347      {
2348        pos=kFindDivisibleByInS_easy(c->strat,m[i], pGetShortExpVector(m[i]));
2349        if(pos>=0)
2350        {
2351          monom_poly h;
2352          h.f=c->strat->S[pos];
2353          h.m=pOne();
2354          int* ev=(int*) omalloc((c->r->N+1)*sizeof(int));
2355          pGetExpV(m[i],ev);
2356          pSetExpV(h.m,ev);
2357          omfree(ev);
2358          pExpVectorSub(h.m,c->strat->S[pos]);
2359          simplify(h,c);
2360          q[q_index]=ppMult_mm(h.f,h.m);
2361          chosen[chosen_index++]=h;
2362          q_index++;
2363        }
2364        done[done_index++]=m[i];
2365      }
2366      else
2367        pDelete(&m[i]);
2368    }
2369    if(p_size<p_index+q_index)
2370    {
2371      p_size=p_index+2*q_index;
2372      p=(poly*) omrealloc(p,p_size*sizeof(poly));
2373    }
2374    for (i=0;i<q_index;i++)
2375      p[p_index++]=q[i];
2376    m_index=0;
2377    int sum=0;
2378    for(i=0;i<p_index;i++)
2379    {
2380      sum+=pLength(p[i]);
2381    }
2382    if (m_size<sum)
2383    {
2384      omfree(m);
2385      m=(poly*) omalloc(sum*sizeof(poly));
2386    }
2387    m_size=sum;
2388    for(i=0;i<q_index;i++)
2389    {
2390      poly p_i=q[i];
2391      while(p_i)
2392      {
2393        m[m_index]=pLmInit(p_i);
2394        pSetCoeff(m[m_index],nInit(1));
2395        p_i=p_i->next;
2396        m_index++;
2397      }
2398    }
2399    qsort(done, done_index,sizeof(poly),pLmCmp_func);
2400  }
2401  omfree(m);
2402  omfree(q);
2403  Print("%i, ",chosen_index);
2404  //next Step build matrix
2405  assume(p_index==chosen_index);
2406 
2407  tgb_matrix* mat=build_matrix(p,p_index,done, done_index,c);
2408 
2409  //next Step Gauss
2410  simple_gauss(mat);
2411  //next Step retranslate
2412
2413  assume(mat->get_rows()<=p_index);
2414  //new meaning of m
2415  m_size=mat->get_rows();
2416  m=(poly*) omalloc(m_size*sizeof(poly));
2417  m_index=retranslate(m,mat,done,c);
2418  mat=NULL;
2419  omfree(done);
2420  done=NULL;
2421  //next Step addElements to basis
2422  int F_plus_size=m_index;
2423  poly* F_plus=(poly*)omalloc(F_plus_size*sizeof(poly));
2424  int F_plus_index=0;
2425  int F_minus_size=m_index;
2426  poly* F_minus=(poly*) omalloc(F_minus_size*sizeof(poly));
2427  int F_minus_index=0;
2428
2429  //better algorithm replace p by its monoms, qsort,delete duplicates and binary search for testing if monom is contained in array
2430 
2431  for(i=0;i<m_index;i++)
2432  {
2433    int j;
2434    BOOLEAN minus=FALSE;
2435    for(j=0;j<p_index;j++)
2436      if (pLmEqual(p[j],m[i]))
2437      {
2438        minus=TRUE;
2439        break;
2440      }
2441    if(minus)
2442    {
2443      F_minus[F_minus_index++]=m[i];
2444      m[i]=NULL;
2445    }
2446    else
2447    {
2448      F_plus[F_plus_index++]=m[i];
2449      m[i]=NULL;
2450    }
2451  }
2452  Print("%i]", F_plus_index);
2453  for(i=0;i<p_index;i++) 
2454    pDelete(&p[i]);
2455  omfree(p);
2456  p=NULL;
2457  omfree(m);
2458  m=NULL;
2459  //the F_minus list must be cleared separately at the end
2460  mp_array_list** F_i;
2461  poly_array_list** F_m_i;
2462  F_i=&(c->F);
2463  F_m_i=&(c->F_minus);
2464  while((*F_i)!=NULL)
2465  {
2466    assume((*F_minus)!=NULL);
2467    F_i=(&((*F_i)->next));
2468    F_m_i=(&((*F_m_i)->next));
2469  }
2470  assume((*F_minus)==NULL);
2471  //should resize the array to save memory
2472  //F and F_minus
2473  (*F_m_i)=(poly_array_list*) omalloc(sizeof(poly_array_list));
2474  (*F_m_i)->size=F_minus_index;
2475  (*F_m_i)->p=F_minus;
2476  (*F_m_i)->next=NULL;
2477  (*F_i)=(mp_array_list*) omalloc(sizeof(poly_array_list));
2478  (*F_i)->size=chosen_index;
2479  (*F_i)->mp=chosen;
2480  (*F_i)->next=NULL;
2481 
2482  if(F_plus_index>0)
2483  {
2484    int j;
2485    int* ibuf=(int*) omalloc(F_plus_index*sizeof(int));
2486    sorted_pair_node*** sbuf=(sorted_pair_node***) omalloc(F_plus_index*sizeof(sorted_pair_node**));
2487 
2488    for(j=0;j<F_plus_index;j++)
2489    {
2490      int len;
2491      poly p=F_plus[j];
2492   
2493    // delete buf[j];
2494    //remember to free res here
2495    //    p=redTailShort(p, c->strat);
2496      sbuf[j]=add_to_basis(p,-1,-1,c,ibuf+j);
2497   
2498    }
2499    int sum=0;
2500    for(j=0;j<F_plus_index;j++)
2501    {
2502      sum+=ibuf[j];
2503    }
2504    sorted_pair_node** big_sbuf=(sorted_pair_node**) omalloc(sum*sizeof(sorted_pair_node*));
2505    int partsum=0;
2506    for(j=0;j<F_plus_index;j++)
2507    {
2508      memmove(big_sbuf+partsum, sbuf[j],ibuf[j]*sizeof(sorted_pair_node*));
2509      omfree(sbuf[j]);
2510      partsum+=ibuf[j];
2511    }
2512
2513    qsort(big_sbuf,sum,sizeof(sorted_pair_node*),pair_better_gen2);
2514    c->apairs=merge(c->apairs,c->pair_top+1,big_sbuf,sum,c);
2515    c->pair_top+=sum;
2516    clean_top_of_pair_list(c);
2517    omfree(big_sbuf);
2518    omfree(sbuf);
2519    omfree(ibuf);
2520  }
2521  omfree(F_plus);
2522#ifdef TGB_DEBUG
2523  int z;
2524  for(z=1;z<=c->pair_top;z++)
2525  {
2526    assume(pair_better(c->apairs[z],c->apairs[z-1],c));
2527  }
2528#endif
2529
2530  return;
2531}
2532
2533
2534static int poly_crit(const void* ap1, const void* ap2){
2535  poly p1,p2;
2536  p1=*((poly*) ap1);
2537  p2=*((poly*)ap2);
2538
2539  int c=pLmCmp(p1,p2);
2540  if (c !=0) return c;
2541  int l1=pLength(p1);
2542  int l2=pLength(p2);
2543  if (l1<l2) return -1;
2544  if (l1>l2) return 1;
2545  return 0;
2546}
2547
2548ideal t_rep_gb(ring r,ideal arg_I, BOOLEAN F4_mode){
2549  if (F4_mode)
2550    PrintS("F4 Modus \n");
2551   
2552     
2553  //debug_Ideal=arg_debug_Ideal;
2554  //if (debug_Ideal) PrintS("DebugIdeal received\n");
2555  // Print("Idelems %i \n----------\n",IDELEMS(arg_I));
2556  ideal I=idCompactify(arg_I);
2557  qsort(I->m,IDELEMS(I),sizeof(poly),poly_crit);
2558  //Print("Idelems %i \n----------\n",IDELEMS(I));
2559  calc_dat* c=(calc_dat*) omalloc(sizeof(calc_dat));
2560  c->r=currRing;
2561  void* h;
2562  poly hp;
2563  int i,j;
2564  c->to_destroy=NULL;
2565  c->easy_product_crit=0;
2566  c->extended_product_crit=0;
2567  c->is_char0=(rChar()==0);
2568  c->F4_mode=F4_mode;
2569  c->reduction_steps=0;
2570  c->last_index=-1;
2571
2572  c->F=NULL;
2573  c->F_minus=NULL;
2574
2575  c->Rcounter=0;
2576
2577  c->soon_free=NULL;
2578
2579
2580  c->normal_forms=0;
2581  c->current_degree=1;
2582 
2583  c->max_pairs=5*I->idelems();
2584 
2585  c->apairs=(sorted_pair_node**) omalloc(sizeof(sorted_pair_node*)*c->max_pairs);
2586  c->pair_top=-1;
2587  int n=I->idelems();
2588  for (i=0;i<n;i++){
2589    wrp(I->m[i]);
2590    PrintS("\n");
2591  }
2592    i=0;
2593  c->n=0;
2594  c->T_deg=(int*) omalloc(n*sizeof(int));
2595 
2596#ifdef HEAD_BIN
2597  c->HeadBin=omGetSpecBin(POLYSIZE + (currRing->ExpL_Size)*sizeof(long));
2598#endif
2599  /* omUnGetSpecBin(&(c->HeadBin)); */
2600  h=omalloc(n*sizeof(char*));
2601  c->states=(char**) h;
2602  h=omalloc(n*sizeof(int));
2603  c->lengths=(int*) h;
2604  h=omalloc(n*sizeof(int));
2605        c->gcd_of_terms=(poly*) omalloc(n*sizeof(poly));
2606  c->rep=(int*) h;
2607  c->short_Exps=(long*) omalloc(n*sizeof(long));
2608  c->S=idInit(n,1);
2609  c->strat=new skStrategy;
2610  c->strat->syzComp = 0;
2611  initBuchMoraCrit(c->strat);
2612  initBuchMoraPos(c->strat);
2613  c->strat->initEcart = initEcartBBA;
2614  c->strat->enterS = enterSBba;
2615  c->strat->sl = -1;
2616  i=n;
2617  /* initS(c->S,NULL,c->strat); */
2618/* intS start: */
2619  i=((i+IDELEMS(c->S)+15)/16)*16;
2620  c->strat->ecartS=(intset)omAlloc(i*sizeof(int)); /*initec(i);*/
2621  c->strat->sevS=(unsigned long*)omAlloc0(i*sizeof(unsigned long));
2622  /*initsevS(i);*/
2623  c->strat->S_2_R=(int*)omAlloc0(i*sizeof(int));/*initS_2_R(i);*/
2624  c->strat->fromQ=NULL;
2625  c->strat->Shdl=idInit(1,1);
2626  c->strat->S=c->strat->Shdl->m;
2627  c->strat->lenS=(int*)omAlloc0(i*sizeof(int));
2628  if(c->is_char0)
2629    c->strat->lenSw=(int*)omAlloc0(i*sizeof(int));
2630  else
2631    c->strat->lenSw=NULL;
2632  sorted_pair_node* si;
2633  assume(n>0);
2634  add_to_basis(I->m[0],-1,-1,c);
2635
2636  assume(c->strat->sl==c->strat->Shdl->idelems()-1);
2637
2638  for (i=1;i<n;i++)//the 1 is wanted, because first element is added to basis
2639  {
2640    //     add_to_basis(I->m[i],-1,-1,c);
2641    si=(sorted_pair_node*) omalloc(sizeof(sorted_pair_node));
2642    si->i=-1;
2643    si->j=-1;
2644    si->expected_length=pLength(I->m[i]);
2645    si->deg=pTotaldegree(I->m[i]);
2646    si->lcm_of_lm=I->m[i];
2647   
2648//      c->apairs[n-1-i]=si;
2649    c->apairs[n-i-1]=si;
2650    ++(c->pair_top);
2651   }
2652 
2653
2654  while(c->pair_top>=0)
2655  {
2656    if(F4_mode)
2657      go_on_F4(c);
2658    else
2659      go_on(c);
2660  }
2661  while(c->to_destroy)
2662  {
2663    pDelete(&c->to_destroy->p);
2664    poly_list_node* old=c->to_destroy;
2665    c->to_destroy=c->to_destroy->next;
2666    omfree(old);
2667  }
2668  while(c->F)
2669  {
2670    for(i=0;i<c->F->size;i++){
2671      pDelete(&(c->F->mp[i].m));
2672    }
2673    omfree(c->F->mp);
2674    c->F->mp=NULL;
2675    mp_array_list* old=c->F;
2676    c->F=c->F->next;
2677    omfree(old);
2678  }
2679  while(c->F_minus)
2680  {
2681    for(i=0;i<c->F_minus->size;i++){
2682      pDelete(&(c->F_minus->p[i]));
2683    }
2684    omfree(c->F_minus->p);
2685    c->F_minus->p=NULL;
2686    poly_array_list* old=c->F_minus;
2687    c->F=c->F->next;
2688    omfree(old);
2689  }
2690  for(int z=0;z<c->n;z++){
2691    omfree(c->states[z]);
2692  }
2693  omfree(c->states);
2694  omfree(c->lengths);
2695
2696
2697  omfree(c->short_Exps);
2698  omfree(c->T_deg);
2699
2700     omFree(c->strat->ecartS);
2701     omFree(c->strat->sevS);
2702//   /*initsevS(i);*/
2703   omFree(c->strat->S_2_R);
2704   
2705
2706  omFree(c->strat->lenS);
2707
2708   if(c->strat->lenSw)  omFree(c->strat->lenSw);
2709
2710
2711
2712
2713  for(i=0;i<c->n;i++){
2714    if(c->gcd_of_terms[i])
2715      pDelete(&(c->gcd_of_terms[i]));
2716  }
2717  omfree(c->gcd_of_terms);
2718
2719  omfree(c->apairs);
2720  printf("calculated %d NFs\n",c->normal_forms);
2721  printf("applied %i product crit, %i extended_product crit \n", c->easy_product_crit, c->extended_product_crit);
2722  int deleted_form_c_s=0;
2723
2724  for(i=0;i<c->n;i++){
2725    if (c->rep[i]!=i){
2726      for(j=0;j<=c->strat->sl;j++){
2727        if(c->strat->S[j]==c->S->m[i]){
2728          c->strat->S[j]=NULL;
2729          break;
2730        }
2731      }
2732//      PrintS("R_delete");
2733      pDelete(&c->S->m[i]);
2734    }
2735  }
2736  for(i=0;i<=c->strat->sl;i++){
2737    if (!c->strat->S[i]) continue;
2738    BOOLEAN found=FALSE;
2739    for(j=0;j<c->n;j++){
2740      if (c->S->m[j]==c->strat->S[i]){
2741        found=TRUE;
2742        break;
2743      }
2744    }
2745    if(!found) pDelete(&c->strat->S[i]);
2746  }
2747  omfree(c->rep);
2748  for(i=0;i<I->idelems();i++)
2749  {
2750    I->m[i]=NULL;
2751  }
2752  idDelete(&I);
2753  I=c->S;
2754 
2755  IDELEMS(I)=c->n;
2756
2757  idSkipZeroes(c->S);
2758  for(i=0;i<=c->strat->sl;i++)
2759    c->strat->S[i]=NULL;
2760  id_Delete(&c->strat->Shdl,c->r);
2761  delete c->strat;
2762  omfree(c);
2763
2764  return(I);
2765}
2766static void now_t_rep(const int & arg_i, const int & arg_j, calc_dat* c){
2767  int i,j;
2768  if (arg_i==arg_j){
2769    return;
2770  }
2771  if (arg_i>arg_j){
2772    i=arg_j;
2773    j=arg_i;
2774  } else {
2775    i=arg_i;
2776    j=arg_j;
2777  }
2778  c->states[j][i]=HASTREP;
2779}
2780static void soon_t_rep(const int& arg_i, const int& arg_j, calc_dat* c)
2781{
2782  assume(0<=arg_i);
2783  assume(0<=arg_j);
2784  assume(arg_i<c->n);
2785  assume(arg_j<c->n);
2786  int i,j;
2787  if (arg_i==arg_j){
2788    return;
2789  }
2790  if (arg_i>arg_j){
2791    i=arg_j;
2792    j=arg_i;
2793  } else {
2794    i=arg_i;
2795    j=arg_j;
2796  }
2797  if (!
2798      (c->states[j][i]==HASTREP))
2799    c->states[j][i]=SOONTREP;
2800}
2801static BOOLEAN has_t_rep(const int & arg_i, const  int & arg_j, calc_dat* state){
2802  assume(0<=arg_i);
2803  assume(0<=arg_j);
2804  assume(arg_i<state->n);
2805  assume(arg_j<state->n);
2806  if (arg_i==arg_j)
2807  {
2808    return (TRUE);
2809  }
2810  if (arg_i>arg_j)
2811  {
2812    return (state->states[arg_i][arg_j]==HASTREP);
2813  } else
2814  {
2815    return (state->states[arg_j][arg_i]==HASTREP);
2816  }
2817}
2818static int pLcmDeg(poly a, poly b)
2819{
2820  int i;
2821  int n=0;
2822  for (i=pVariables; i; i--)
2823  {
2824    n+=max( pGetExp(a,i), pGetExp(b,i));
2825  }
2826  return n;
2827
2828}
2829
2830
2831
2832static void shorten_tails(calc_dat* c, poly monom)
2833{
2834  return;
2835// BOOLEAN corr=lenS_correct(c->strat);
2836  for(int i=0;i<c->n;i++)
2837  {
2838    //enter tail
2839    if (c->rep[i]!=i) continue;
2840    if (c->S->m[i]==NULL) continue;
2841    poly tail=c->S->m[i]->next;
2842    poly prev=c->S->m[i];
2843    BOOLEAN did_something=FALSE;
2844    while((tail!=NULL)&& (pLmCmp(tail, monom)>=0))
2845    {
2846      if (p_LmDivisibleBy(monom,tail,c->r))
2847      {
2848        did_something=TRUE;
2849        prev->next=tail->next;
2850        tail->next=NULL;
2851        p_Delete(& tail,c->r);
2852        tail=prev;
2853        //PrintS("Shortened");
2854        c->lengths[i]--;
2855      }
2856      prev=tail;
2857      tail=tail->next;
2858    }
2859    if (did_something)
2860    {
2861      int new_pos;
2862      int q;
2863      q=quality(c->S->m[i],c->lengths[i],c);
2864      new_pos=simple_posInS(c->strat,c->S->m[i],q,c->is_char0);
2865
2866      int old_pos=-1;
2867      //assume new_pos<old_pos
2868      for (int z=0;z<=c->strat->sl;z++)
2869      {
2870        if (c->strat->S[z]==c->S->m[i])
2871        {
2872          old_pos=z;
2873          break;
2874        }
2875      }
2876      if (old_pos== -1)
2877        for (int z=new_pos-1;z>=0;z--)
2878        {
2879          if (c->strat->S[z]==c->S->m[i])
2880          {
2881            old_pos=z;
2882            break;
2883          }
2884        }
2885      assume(old_pos>=0);
2886      assume(new_pos<=old_pos);
2887      assume(pLength(c->strat->S[old_pos])==c->lengths[i]);
2888      c->strat->lenS[old_pos]=c->lengths[i];
2889      if (c->strat->lenSw)
2890        c->strat->lenSw[old_pos]=q;
2891
2892      if (new_pos<old_pos)
2893        move_forward_in_S(old_pos,new_pos,c->strat, c->is_char0);
2894
2895      length_one_crit(c,i,c->lengths[i]);
2896    }
2897  }
2898}
2899static sorted_pair_node* pop_pair(calc_dat* c){
2900  clean_top_of_pair_list(c);
2901
2902  if(c->pair_top<0) return NULL;
2903  else return (c->apairs[c->pair_top--]);
2904}
2905static sorted_pair_node* top_pair(calc_dat* c){
2906  super_clean_top_of_pair_list(c);//yeah, I know, it's odd that I use a different proc here
2907
2908  if(c->pair_top<0) return NULL;
2909  else return (c->apairs[c->pair_top]);
2910}
2911static sorted_pair_node* quick_pop_pair(calc_dat* c){
2912  if(c->pair_top<0) return NULL;
2913  else return (c->apairs[c->pair_top--]);
2914}
2915static BOOLEAN no_pairs(calc_dat* c){
2916  clean_top_of_pair_list(c);
2917  return (c->pair_top==-1);
2918}
2919
2920
2921static void super_clean_top_of_pair_list(calc_dat* c){
2922  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))){
2923
2924    free_sorted_pair_node(c->apairs[c->pair_top],c->r);
2925    c->pair_top--;
2926
2927  }
2928}
2929static void clean_top_of_pair_list(calc_dat* c){
2930  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))){
2931
2932    free_sorted_pair_node(c->apairs[c->pair_top],c->r);
2933    c->pair_top--;
2934
2935  }
2936}
2937static BOOLEAN state_is(calc_state state, const int & arg_i, const  int & arg_j, calc_dat* c){
2938  assume(0<=arg_i);
2939  assume(0<=arg_j);
2940  assume(arg_i<c->n);
2941  assume(arg_j<c->n);
2942  if (arg_i==arg_j)
2943  {
2944    return (TRUE);
2945  }
2946  if (arg_i>arg_j)
2947  {
2948    return (c->states[arg_i][arg_j]==state);
2949  }
2950  else return(c->states[arg_j][arg_i]==state);
2951}
2952static void free_sorted_pair_node(sorted_pair_node* s, ring r){
2953  if (s->i>=0)
2954    p_Delete(&s->lcm_of_lm,r);
2955  omfree(s);
2956}
2957static BOOLEAN pair_better(sorted_pair_node* a,sorted_pair_node* b, calc_dat* c){
2958  if (a->deg<b->deg) return TRUE;
2959  if (a->deg>b->deg) return FALSE;
2960
2961//  if (a->expected_length<b->expected_length) return TRUE;
2962  //  if (a->expected_length>b->expected_length) return FALSE;
2963  int comp=pLmCmp(a->lcm_of_lm, b->lcm_of_lm);
2964  if (comp==1) return FALSE;
2965  if (-1==comp) return TRUE;
2966  if (a->i+a->j<b->i+b->j) return TRUE;
2967   if (a->i+a->j>b->i+b->j) return FALSE;
2968  if (a->i<b->i) return TRUE;
2969  if (a->i>b->i) return FALSE;
2970  return TRUE;
2971}
2972
2973static int pair_better_gen(const void* ap,const void* bp){
2974
2975  sorted_pair_node* a=*((sorted_pair_node**)ap);
2976  sorted_pair_node* b=*((sorted_pair_node**)bp);
2977  assume(a->i>a->j);
2978  assume(b->i>b->j);
2979  if (a->deg<b->deg) return -1;
2980  if (a->deg>b->deg) return 1;
2981
2982
2983//  if (a->expected_length<b->expected_length) return -1;
2984  // if (a->expected_length>b->expected_length) return 1;
2985 int comp=pLmCmp(a->lcm_of_lm, b->lcm_of_lm);
2986 
2987  if (comp==1) return 1;
2988  if (-1==comp) return -1;
2989  if (a->i+a->j<b->i+b->j) return -1;
2990   if (a->i+a->j>b->i+b->j) return 1;
2991  if (a->i<b->i) return -1;
2992   if (a->i>b->i) return 1;
2993  return 0;
2994}
2995
2996
2997static poly gcd_of_terms(poly p, ring r){
2998  int max_g_0=0;
2999  assume(p!=NULL);
3000  int i;
3001  poly m=pOne();
3002  poly t;
3003  for (i=pVariables; i; i--)
3004  {
3005      pSetExp(m,i, pGetExp(p,i));
3006      if (max_g_0==0)
3007        if (pGetExp(m,i)>0)
3008          max_g_0=i;
3009  }
3010 
3011  t=p->next;
3012  while (t!=NULL){
3013   
3014    if (max_g_0==0) break;
3015    for (i=pVariables; i; i--)
3016    {
3017      pSetExp(m,i, min(pGetExp(t,i),pGetExp(m,i)));
3018      if (max_g_0==i)
3019        if (pGetExp(m,i)==0)
3020          max_g_0=0;
3021      if ((max_g_0==0) && (pGetExp(m,i)>0)){
3022        max_g_0=i;
3023      }
3024    }
3025                t=t->next;
3026  }
3027        for (i=pVariables;i;i--)
3028        {
3029                if(pGetExp(m,i)>0)
3030                        return m;
3031  }
3032        pDelete(&m);
3033  return NULL;
3034}
3035static BOOLEAN pHasNotCFExtended(poly p1, poly p2, poly m)
3036{
3037
3038  if (pGetComp(p1) > 0 || pGetComp(p2) > 0)
3039    return FALSE;
3040  int i = 1;
3041  loop
3042  {
3043    if ((pGetExp(p1, i)-pGetExp(m,i) >0) && (pGetExp(p2, i) -pGetExp(m,i)> 0))   return FALSE;
3044    if (i == pVariables)                                return TRUE;
3045    i++;
3046  }
3047}
3048
3049
3050//for impl reasons may return false if the the normal product criterion matches
3051static BOOLEAN extended_product_criterion(poly p1, poly gcd1, poly p2, poly gcd2, calc_dat* c){
3052  if(gcd1==NULL) return FALSE;
3053        if(gcd2==NULL) return FALSE;
3054        gcd1->next=gcd2; //may ordered incorrect
3055        poly m=gcd_of_terms(gcd1,c->r);
3056        gcd1->next=NULL;
3057        if (m==NULL) return FALSE;
3058
3059        BOOLEAN erg=pHasNotCFExtended(p1,p2,m);
3060        pDelete(&m);
3061        return erg;
3062}
3063static poly kBucketGcd(kBucket* b, ring r)
3064{
3065  int s=0;
3066  int i;
3067  poly m, n;
3068  BOOLEAN initialized=FALSE;
3069  for (i=MAX_BUCKET-1;i>=0;i--)
3070  { 
3071    if (b->buckets[i]!=NULL){
3072      if (!initialized){
3073        m=gcd_of_terms(b->buckets[i],r);
3074        initialized=TRUE;
3075        if (m==NULL) return NULL;
3076      }
3077      else
3078        {
3079          n=gcd_of_terms(b->buckets[i],r);
3080          if (n==NULL) {
3081            pDelete(&m);
3082            return NULL;   
3083          }
3084          n->next=m;
3085          poly t=gcd_of_terms(n,r);
3086          n->next=NULL;
3087          pDelete(&m);
3088          pDelete(&n);
3089          m=t;
3090          if (m==NULL) return NULL;
3091         
3092        }
3093    }
3094  }
3095  return m;
3096}
3097
3098
3099
3100static int guess_quality(const red_object & p, calc_dat* c){
3101  //looks only on bucket
3102  if (c->is_char0) return kSBucketLength(p.bucket);
3103  return (bucket_guess(p.bucket));
3104}
3105static int quality_of_pos_in_strat_S(int pos, calc_dat* c){
3106  if (c->is_char0) return c->strat->lenSw[pos];
3107  return c->strat->lenS[pos];
3108}
3109static int quality(poly p, int len, calc_dat* c){
3110  if (c->is_char0) return pSLength(p,len);
3111  return pLength(p);
3112}
3113static void multi_reduction_lls_trick(red_object* los, int losl,calc_dat* c,find_erg & erg){
3114  erg.expand=NULL;
3115  BOOLEAN swap_roles; //from reduce_by, to_reduce_u if fromS
3116  if(erg.fromS){
3117    if(pLmEqual(c->strat->S[erg.reduce_by],los[erg.to_reduce_u].p))
3118    {
3119      int i;
3120      int quality_a=quality_of_pos_in_strat_S(erg.reduce_by,c);
3121      int best=erg.to_reduce_u+1;
3122/*
3123      for (i=erg.to_reduce_u;i>=erg.to_reduce_l;i--){
3124        int qc=los[i].guess_quality(c);
3125        if (qc<quality_a){
3126          best=i;
3127          quality_a=qc;
3128        }
3129      }
3130      if(best!=erg.to_reduce_u+1){*/
3131      int qc;
3132      best=find_best(los,erg.to_reduce_l,erg.to_reduce_u,qc,c);
3133      assume(qc==los[best].guess_quality(c));
3134      if(qc<quality_a){
3135        red_object h=los[erg.to_reduce_u];
3136        los[erg.to_reduce_u]=los[best];
3137        los[best]=h;
3138        swap_roles=TRUE;
3139      }
3140      else{
3141       
3142        swap_roles=FALSE;
3143      }
3144 
3145    }
3146      else
3147    {
3148      if (erg.to_reduce_u>erg.to_reduce_l){
3149
3150        int i;
3151        int quality_a=quality_of_pos_in_strat_S(erg.reduce_by,c);
3152        int best=erg.to_reduce_u+1;
3153        int qc;
3154        best=find_best(los,erg.to_reduce_l,erg.to_reduce_u,qc,c);
3155        assume(qc==los[best].guess_quality(c));
3156        if(qc<quality_a){
3157          //(best!=erg.to_reduce_u+1){
3158          red_object h=los[erg.to_reduce_l];
3159          los[erg.to_reduce_l]=los[best];
3160          los[best]=h;
3161          erg.reduce_by=erg.to_reduce_l;
3162          erg.fromS=FALSE;
3163          erg.to_reduce_l++;
3164         
3165        }
3166      }
3167      else 
3168      {
3169        assume(erg.to_reduce_u==erg.to_reduce_l);
3170        int quality_a=quality_of_pos_in_strat_S(erg.reduce_by,c);
3171        int qc=los[erg.to_reduce_u].guess_quality(c);
3172        if(qc<quality_a){
3173          BOOLEAN exp=FALSE;
3174          if(qc<=2)
3175            exp=TRUE;
3176          else {
3177            if (qc<quality_a/2)
3178              exp=TRUE;
3179            else
3180              if(erg.reduce_by<c->n/4)
3181                exp=TRUE;
3182          }
3183          if (exp){
3184            poly clear_into;
3185            los[erg.to_reduce_u].flatten();
3186            kBucketClear(los[erg.to_reduce_u].bucket,&clear_into,&erg.expand_length);
3187            erg.expand=pCopy(clear_into);
3188            kBucketInit(los[erg.to_reduce_u].bucket,clear_into,erg.expand_length);
3189            PrintS("e");
3190           
3191          }
3192        }
3193
3194       
3195      }
3196     
3197      swap_roles=FALSE;
3198      return;
3199      }
3200   
3201  }
3202  else{
3203    if(erg.reduce_by>erg.to_reduce_u){
3204      //then lm(rb)>= lm(tru) so =
3205      assume(erg.reduce_by==erg.to_reduce_u+1);
3206      int best=erg.reduce_by;
3207      int quality_a=los[erg.reduce_by].guess_quality(c);
3208      int qc;
3209      best=find_best(los,erg.to_reduce_l,erg.to_reduce_u,qc,c);
3210     
3211      int i;
3212      if(qc<quality_a){
3213          red_object h=los[erg.reduce_by];
3214          los[erg.reduce_by]=los[best];
3215          los[best]=h;
3216        }
3217        swap_roles=FALSE;
3218        return;
3219       
3220         
3221    }
3222    else
3223    {
3224      assume(!pLmEqual(los[erg.reduce_by].p,los[erg.to_reduce_l].p));
3225      //further assume, that reduce_by is the above all other polys
3226      //with same leading term
3227      int il=erg.reduce_by;
3228      int quality_a =los[erg.reduce_by].guess_quality(c);
3229      int qc;
3230      while((il>0) && pLmEqual(los[il-1].p,los[il].p)){
3231        il--;
3232        qc=los[il].guess_quality(c);
3233        if (qc<quality_a){
3234          quality_a=qc;
3235          erg.reduce_by=il;
3236        }
3237      }
3238      swap_roles=FALSE;
3239    }
3240 
3241  }
3242  if(swap_roles)
3243  {
3244    PrintS("b");
3245    poly clear_into;
3246    int dummy_len;
3247    int new_length;
3248    int bp=erg.to_reduce_u;//bucket_positon
3249    //kBucketClear(los[bp].bucket,&clear_into,&new_length);
3250    new_length=los[bp].clear_to_poly();
3251    clear_into=los[bp].p;
3252    poly p=c->strat->S[erg.reduce_by];
3253    int j=erg.reduce_by;
3254    int old_length=c->strat->lenS[j];// in view of S
3255    los[bp].p=p;
3256    kBucketInit(los[bp].bucket,p,old_length);
3257    int qal=quality(clear_into,new_length,c);
3258    int pos_in_c=-1;   
3259    int z;
3260    int new_pos;
3261    new_pos=simple_posInS(c->strat,clear_into,qal,c->is_char0);
3262    assume(new_pos<=j);
3263    for (z=c->n;z;z--)
3264    {
3265      if(p==c->S->m[z-1])
3266      {
3267        pos_in_c=z-1;
3268        break;
3269      }
3270    }
3271    if(pos_in_c>=0)
3272    {
3273      c->S->m[pos_in_c]=clear_into;
3274      c->lengths[pos_in_c]=new_length;
3275      c_S_element_changed_hook(pos_in_c,c);
3276    }
3277    c->strat->S[j]=clear_into;
3278    c->strat->lenS[j]=new_length;
3279    if(c->strat->lenSw)
3280      c->strat->lenS[j]=qal;
3281    if(c->is_char0)
3282    {
3283      pContent(clear_into);
3284      pCleardenom(clear_into);
3285    }
3286    else                     
3287      pNorm(clear_into);
3288#ifdef FIND_DETERMINISTIC
3289    erg.reduce_by=j;
3290    //resort later see diploma thesis, find_in_S must be deterministic
3291    //during multireduction if spolys are only in the span of the
3292    //input polys
3293#else
3294   
3295    if (new_pos<j)
3296    { 
3297      move_forward_in_S(j,new_pos,c->strat,c->is_char0);
3298      erg.reduce_by=new_pos;
3299    }
3300#endif
3301  }
3302}
3303static void multi_reduction_find(red_object* los, int losl,calc_dat* c,int startf,find_erg & erg){
3304  kStrategy strat=c->strat;
3305
3306  assume(startf<=losl);
3307  assume((startf==losl-1)||(pLmCmp(los[startf].p,los[startf+1].p)==-1));
3308  int i=startf;
3309 
3310  int j;
3311  while(i>=0){
3312    assume((i==losl-1)||(pLmCmp(los[i].p,los[i+1].p)<=0));
3313    assume(is_valid_ro(los[i]));
3314    j=kFindDivisibleByInS_easy(strat,los[i]);
3315    if(j>=0){
3316     
3317      erg.to_reduce_u=i;
3318      erg.reduce_by=j;
3319      erg.fromS=TRUE;
3320      int i2;
3321      for(i2=i-1;i2>=0;i2--){
3322        if(!pLmEqual(los[i].p,los[i2].p))
3323          break;
3324      }
3325     
3326      erg.to_reduce_l=i2+1;
3327      assume((i==losl-1)||(pLmCmp(los[i].p,los[i+1].p)==-1));
3328      return;
3329    }
3330    if (j<0){
3331     
3332      //not reduceable, try to use this for reducing higher terms
3333      int i2;
3334      i2=i;
3335      while((i2>0)&&(pLmEqual(los[i].p,los[i2-1].p)))
3336        i2--;
3337      if(i2!=i){
3338       
3339        erg.to_reduce_u=i-1;
3340        erg.to_reduce_l=i2;
3341        erg.reduce_by=i;
3342        erg.fromS=FALSE;
3343        assume((i==losl-1)||(pLmCmp(los[i].p,los[i+1].p)==-1));
3344        return;
3345      }
3346 
3347      for (i2=i+1;i2<losl;i2++){
3348        if (p_LmShortDivisibleBy(los[i].p,los[i].sev,los[i2].p,~los[i2].sev,
3349                                c->r)){
3350          int i3=i2;
3351          while((i3+1<losl) && (pLmEqual(los[i2].p, los[i3+1].p)))
3352            i3++;
3353          erg.to_reduce_u=i3;
3354          erg.to_reduce_l=i2;
3355          erg.reduce_by=i;
3356          erg.fromS=FALSE;
3357          assume((i==losl-1)||(pLmCmp(los[i].p,los[i+1].p)==-1));
3358          return;
3359        }
3360//      else {assume(!p_LmDivisibleBy(los[i].p, los[i2].p,c->r));}
3361      }
3362
3363      i--;
3364    }
3365  }
3366  erg.reduce_by=-1;//error code
3367  return;
3368}
3369
3370 //  nicht reduzierbare eintraege in ergebnisliste schreiben
3371//   nullen loeschen
3372//   while(finde_groessten leitterm reduzierbar(c,erg)){
3373 
3374static int multi_reduction_clear_zeroes(red_object* los, int  losl, int l, int u)
3375{
3376
3377
3378  int deleted=0;
3379  int  i=l;
3380  int last=-1;
3381  while(i<=u)
3382  {
3383   
3384    if(los[i].p==NULL){
3385      kBucketDestroy(&los[i].bucket);
3386//      delete los[i];//here we assume los are constructed with new
3387      //destroy resources, must be added here   
3388     if (last>=0)
3389     {
3390       memmove(los+(int)(last+1-deleted),los+(last+1),sizeof(red_object)*(i-1-last));
3391     }
3392     last=i;
3393     deleted++;
3394    }
3395    i++;
3396  }
3397  if((last>=0)&&(last!=losl-1))
3398      memmove(los+(int)(last+1-deleted),los+last+1,sizeof(red_object)*(losl-1-last));
3399  return deleted;
3400 
3401}
3402
3403static void sort_region_down(red_object* los, int l, int u, calc_dat* c)
3404{
3405  qsort(los+l,u-l+1,sizeof(red_object),red_object_better_gen);
3406  int i;
3407
3408  for(i=l;i<=u;i++)
3409  {
3410    BOOLEAN moved=FALSE;
3411    int j;
3412    for(j=i;j;j--)
3413    {
3414      if(pLmCmp(los[j].p,los[j-1].p)==-1){
3415        red_object h=los[j];
3416        los[j]=los[j-1];
3417        los[j-1]=h;
3418        moved=TRUE;
3419      }
3420      else break;
3421    }
3422    if(!moved) return;
3423  }
3424}
3425
3426//assume that los is ordered ascending by leading term, all non zero
3427static void multi_reduction(red_object* los, int & losl, calc_dat* c)
3428{
3429 
3430  //initialize;
3431  assume(c->strat->sl>=0);
3432  assume(losl>0);
3433  int i;
3434  for(i=0;i<losl;i++){
3435    los[i].sev=pGetShortExpVector(los[i].p);
3436//SetShortExpVector();
3437    los[i].p=kBucketGetLm(los[i].bucket);
3438  }
3439
3440  kStrategy strat=c->strat;
3441  int curr_pos=losl-1;
3442
3443
3444//  nicht reduzierbare einträge in ergebnisliste schreiben
3445  // nullen loeschen
3446  while(curr_pos>=0){
3447   
3448    find_erg erg;
3449    multi_reduction_find(los, losl,c,curr_pos,erg);//last argument should be curr_pos
3450   //  PrintS("\n erg:\n");
3451//     Print("upper:%i\n",erg.to_reduce_u);
3452//     Print("lower:%i\n",erg.to_reduce_l);
3453//     Print("reduce_by:%i\n",erg.reduce_by);
3454//     Print("fromS:%i\n",erg.fromS);
3455    if(erg.reduce_by<0) break;
3456
3457
3458
3459    erg.expand=NULL;
3460    int d=erg.to_reduce_u-erg.to_reduce_l+1;
3461    //if ((!erg.fromS)&&(d>100)){
3462    if (0){
3463      PrintS("L");
3464      if(!erg.fromS){
3465        erg.to_reduce_u=max(erg.to_reduce_u,erg.reduce_by);
3466        if (pLmEqual(los[erg.reduce_by].p,los[erg.to_reduce_l].p))
3467          erg.to_reduce_l=min(erg.to_reduce_l,erg.reduce_by);
3468      }
3469      int pn=erg.to_reduce_u+1-erg.to_reduce_l;
3470      poly* p=(poly*) omalloc((pn)*sizeof(poly));
3471      int i;
3472      for(i=0;i<pn;i++){
3473        int len;
3474        los[erg.to_reduce_l+i].flatten();
3475        kBucketClear(los[erg.to_reduce_l+i].bucket,&p[i],&len);
3476       
3477        redTailShort(p[i],c->strat);
3478      }
3479      pre_comp(p,pn,c);
3480      int j;
3481      for(j=0;j<pn;j++){
3482        los[erg.to_reduce_l+j].p=p[j];
3483        los[erg.to_reduce_l+j].sev=pGetShortExpVector(p[j]);
3484        los[erg.to_reduce_l+j].sum=NULL;
3485        int len=pLength(p[j]);
3486        kBucketInit(los[erg.to_reduce_l+j].bucket,los[erg.to_reduce_l+j].p,len);
3487      }
3488      for(j=erg.to_reduce_l+pn;j<=erg.to_reduce_u;j++){
3489        los[j].p=NULL;
3490       
3491      }
3492
3493      omfree(p);
3494    }
3495    else {
3496    multi_reduction_lls_trick(los,losl,c,erg);
3497    int sum=0;
3498
3499   
3500    int i;
3501    int len;
3502   
3503    multi_reduce_step(erg,los,c);
3504    }
3505//     reduction_step *rs=create_reduction_step(erg, los, c);
3506//     rs->reduce(los,erg.to_reduce_l,erg.to_reduce_u);
3507//     finalize_reduction_step(rs);
3508                 
3509    int deleted=multi_reduction_clear_zeroes(los, losl, erg.to_reduce_l, erg.to_reduce_u);
3510    curr_pos=erg.to_reduce_u;
3511    losl -= deleted;
3512    curr_pos -= deleted;
3513
3514    //Print("deleted %i \n",deleted);
3515    sort_region_down(los, erg.to_reduce_l, erg.to_reduce_u-deleted, c);
3516//   sort_region_down(los, 0, losl-1, c);
3517    //  qsort(los,losl,sizeof(red_object),red_object_better_gen);
3518    if(erg.expand)
3519    {
3520#ifdef FIND_DETERMINISTIC
3521      int i;
3522      for(i=0;c->expandS[i];i++);
3523      c->expandS=(poly*) omrealloc(c->expandS,(i+2)*sizeof(poly));
3524      c->expandS[i]=erg.expand;
3525      c->expandS[i+1]=NULL;
3526#else
3527      add_to_reductors(c,erg.expand,erg.expand_length);
3528#endif
3529    }
3530     
3531  }
3532  return;
3533}
3534void red_object::flatten(){
3535  if (sum!=NULL)
3536  {
3537
3538 
3539    if(kBucketGetLm(sum->ac->bucket)!=NULL){
3540      number mult_my=n_Mult(sum->c_my,sum->ac->multiplied,currRing);
3541      poly add_this;
3542      if(!nIsOne(mult_my))
3543        kBucket_Mult_n(bucket,mult_my);
3544      int len;
3545      poly clear_into;
3546      kBucketClear(sum->ac->bucket,&clear_into,&len);
3547      if(sum->ac->counter>1){
3548        add_this=pCopy(clear_into);
3549        kBucketInit(sum->ac->bucket,clear_into,len);
3550      }
3551      else
3552        add_this=clear_into;
3553      pMult_nn(add_this, sum->c_ac);
3554     
3555      kBucket_Add_q(bucket,add_this, &len);
3556       nDelete(&mult_my);
3557     
3558    }
3559    nDelete(&sum->c_ac);
3560    nDelete(&sum->c_my);
3561   
3562    sum->ac->decrease_counter();
3563    delete sum;
3564    p=kBucketGetLm(bucket);
3565    sum=NULL;
3566  }
3567  assume(p==kBucketGetLm(bucket));
3568  assume(sum==NULL);
3569}
3570void red_object::validate(){
3571  BOOLEAN flattened=FALSE;
3572  if(sum!=NULL)
3573  {
3574    poly lm=kBucketGetLm(bucket);
3575    poly lm_ac=kBucketGetLm(sum->ac->bucket);
3576    if ((lm_ac==NULL)||((lm!=NULL) && (pLmCmp(lm,lm_ac)!=-1))){
3577      flatten();
3578      assume(sum==NULL);
3579      flattened=TRUE;
3580      p=kBucketGetLm(bucket);
3581      if (p!=NULL)
3582        sev=pGetShortExpVector(p);
3583    } 
3584    else
3585    {
3586 
3587      p=lm_ac;
3588      assume(sum->ac->sev==pGetShortExpVector(p));
3589      sev=sum->ac->sev;
3590    }
3591   
3592  }
3593  else{
3594    p=kBucketGetLm(bucket);
3595    if(p)
3596    sev=pGetShortExpVector(p);
3597  }
3598  assume((sum==NULL)||(kBucketGetLm(sum->ac->bucket)!=NULL));
3599}
3600int red_object::clear_to_poly(){
3601  flatten();
3602  int l;
3603  kBucketClear(bucket,&p,&l);
3604  return l;
3605}
3606
3607 
3608
3609void red_object::adjust_coefs(number c_r, number c_ac_r){
3610  assume(this->sum!=NULL);
3611  number n1=nMult(sum->c_my, c_ac_r);
3612  number n2=nMult(sum->c_ac,c_r);
3613  nDelete(&sum->c_my);
3614  nDelete(&sum->c_ac);
3615 
3616  int ct = ksCheckCoeff(&n1, &n2);
3617  sum->c_my=n1;
3618  sum->c_ac=nNeg(n2);
3619  nDelete(&n2);
3620 
3621
3622}
3623int red_object::guess_quality(calc_dat* c){
3624    //works at the moment only for lenvar 1, because in different
3625    //case, you have to look on coefs
3626    int s=0;
3627    if (c->is_char0)
3628      s=kSBucketLength(bucket);
3629    else 
3630      s=bucket_guess(bucket);
3631    if (sum!=NULL){
3632      if (c->is_char0)
3633      s+=kSBucketLength(sum->ac->bucket);
3634    else 
3635      s+=bucket_guess(sum->ac->bucket);
3636    }
3637    return s;
3638}
3639void reduction_step::reduce(red_object* r, int l, int u){}
3640void simple_reducer::target_is_no_sum_reduce(red_object & ro){
3641  kBucketPolyRed(ro.bucket,p,
3642                 p_len,
3643                 c->strat->kNoether);
3644}
3645
3646void simple_reducer::target_is_a_sum_reduce(red_object & ro){
3647  pTest(p);
3648  kbTest(ro.bucket);
3649  kbTest(ro.sum->ac->bucket);
3650  assume(ro.sum!=NULL);
3651  assume(ro.sum->ac!=NULL);
3652  if(ro.sum->ac->last_reduction_id!=reduction_id){
3653    number n1=kBucketPolyRed(ro.sum->ac->bucket,p, p_len, c->strat->kNoether);
3654    number n2=nMult(n1,ro.sum->ac->multiplied);
3655    nDelete(&ro.sum->ac->multiplied);
3656    nDelete(&n1);
3657    ro.sum->ac->multiplied=n2;
3658    poly lm=kBucketGetLm(ro.sum->ac->bucket);
3659    if (lm)
3660      ro.sum->ac->sev=pGetShortExpVector(lm);
3661    ro.sum->ac->last_reduction_id=reduction_id;
3662  }
3663  ro.sev=ro.sum->ac->sev;
3664  ro.p=kBucketGetLm(ro.sum->ac->bucket);
3665}
3666void simple_reducer::reduce(red_object* r, int l, int u){
3667  this->pre_reduce(r,l,u);
3668  int i;
3669//debug start
3670  int im;
3671//  for(im=l;im<=u;im++)
3672  //  assume(is_valid_ro(r[im]));
3673 
3674
3675//debug end
3676
3677  for(i=l;i<=u;i++){
3678 
3679
3680    if(r[i].sum==NULL)
3681      this->target_is_no_sum_reduce(r[i]);
3682
3683    else 
3684    {
3685      this->target_is_a_sum_reduce(r[i]);
3686      //reduce and adjust multiplied
3687      r[i].sum->ac->last_reduction_id=reduction_id;
3688     
3689    }
3690    //most elegant would be multimethods at this point and subclassing
3691    //red_object for sum
3692 
3693  }
3694  for(i=l;i<=u;i++){
3695    r[i].validate();
3696    #ifdef TGB_DEBUG
3697    if (r[i].sum) r[i].sev=r[i].sum->ac->sev;
3698
3699    #endif
3700      }
3701}
3702reduction_step::~reduction_step(){}
3703simple_reducer::~simple_reducer(){
3704  if(fill_back!=NULL)
3705  {
3706    kBucketInit(fill_back,p,p_len);
3707  }
3708  fill_back=NULL;
3709   
3710}
3711 join_simple_reducer::~join_simple_reducer(){
3712   if(fill_back!=NULL)
3713   {
3714     kBucketInit(fill_back,p,p_len);
3715   }
3716   fill_back=NULL;
3717   
3718}
3719void multi_reduce_step(find_erg & erg, red_object* r, calc_dat* c){
3720  static int id=0;
3721  id++;
3722
3723  int rn=erg.reduce_by;
3724  poly red;
3725  int red_len;
3726  simple_reducer* pointer;
3727  BOOLEAN woc=FALSE;
3728  if(erg.fromS){
3729    red=c->strat->S[rn];
3730    red_len=c->strat->lenS[rn];
3731   
3732  }
3733  else
3734  {
3735    r[rn].flatten();
3736    kBucketClear(r[rn].bucket,&red,&red_len);
3737  }
3738  if (erg.to_reduce_u-erg.to_reduce_l>5){
3739    woc=TRUE;
3740    poly m=pOne();
3741    for(int i=1;i<=pVariables;i++)
3742      pSetExp(m,i,(pGetExp(r[erg.to_reduce_l].p, i)-pGetExp(red,i)));
3743    pSetm(m);
3744    poly red_cp=ppMult_mm(red,m);
3745   
3746    if(!erg.fromS){
3747      kBucketInit(r[rn].bucket,red,red_len);
3748    }
3749    //now reduce the copy
3750    //static poly redNF2 (poly h,calc_dat* c , int &len, number&  m,int n)
3751    redTailShort(red_cp,c->strat);
3752    //number mul;
3753    // red_len--;
3754//     red_cp->next=redNF2(red_cp->next,c,red_len,mul,c->average_length);
3755//     pSetCoeff(red_cp,nMult(red_cp->coef,mul));
3756//     nDelete(&mul);
3757//     red_len++;
3758    red=red_cp;
3759    red_len=pLength(red);
3760    pDelete(&m);
3761   
3762  }
3763  int i;
3764
3765
3766  int red_c=0;
3767  if(red_len>2*c->average_length){
3768    for(i=erg.to_reduce_l;i<=erg.to_reduce_u;i++){
3769      if((r[i].sum==NULL) ||(r[i].sum->ac->counter<=AC_FLATTEN)) red_c++;
3770    }
3771  }
3772  if (red_c>=AC_NEW_MIN)
3773    pointer=new join_simple_reducer(red,red_len,r[erg.to_reduce_l].p);
3774  else
3775    pointer=new simple_reducer(red,red_len,c);
3776
3777  if ((!woc) && (!erg.fromS))
3778    pointer->fill_back=r[rn].bucket;
3779  else
3780    pointer->fill_back=NULL;
3781  pointer->reduction_id=id;
3782  pointer->c=c;
3783
3784  pointer->reduce(r,erg.to_reduce_l, erg.to_reduce_u);
3785  if(woc) pDelete(&pointer->p);
3786  delete pointer;
3787 
3788};
3789
3790void join_simple_reducer::target_is_no_sum_reduce(red_object & ro){
3791 
3792  ro.sum=new formal_sum_descriptor();
3793  ro.sum->ac=ac;
3794  ac->counter++;
3795  kBucket_pt bucket=ro.bucket;
3796  poly a1 = pNext(p), lm = kBucketExtractLm(bucket);
3797  BOOLEAN reset_vec=FALSE;
3798  number rn;
3799  assume(a1!=NULL);
3800  number an = pGetCoeff(p), bn = pGetCoeff(lm);
3801  lm->next=NULL;
3802  int ct = ksCheckCoeff(&an, &bn);
3803  ro.sum->c_ac=nNeg(bn);
3804  ro.sum->c_my=an;
3805  assume(nIsZero(nAdd(nMult(ro.sum->c_my,lm->coef),nMult(p->coef,ro.sum->c_ac) )));
3806  if (p_GetComp(p, bucket->bucket_ring) != p_GetComp(lm, bucket->bucket_ring))
3807  {
3808    p_SetCompP(a1, p_GetComp(lm, bucket->bucket_ring), bucket->bucket_ring);
3809    reset_vec = TRUE;
3810    p_SetComp(lm, p_GetComp(p, bucket->bucket_ring), bucket->bucket_ring);
3811    p_Setm(lm, bucket->bucket_ring);
3812  }
3813
3814
3815 
3816
3817  p_DeleteLm(&lm, bucket->bucket_ring);
3818  if (reset_vec) p_SetCompP(a1, 0, bucket->bucket_ring);
3819  kbTest(bucket);
3820
3821}
3822
3823  reduction_accumulator::reduction_accumulator(poly p, int p_len, poly high_to){
3824    //sev needs to be removed from interfaces,makes no sense
3825   
3826
3827    poly my=pOne();
3828    counter=0;
3829   
3830    for(int i=1;i<=pVariables;i++)
3831      pSetExp(my,i,(pGetExp(high_to, i)-pGetExp(p,i)));
3832
3833   
3834   
3835    pSetm(my);
3836    last_reduction_id=-1;
3837    multiplied=nInit(1);
3838    bucket=kBucketCreate(currRing);
3839    poly a=pMult_mm(pCopy(p->next),my);
3840
3841    this->sev=pGetShortExpVector(a);
3842    kBucketInit(bucket, a,p_len-1);
3843    pDelete(&my);
3844  }
3845void simple_reducer:: pre_reduce(red_object* r, int l, int u){}
3846void join_simple_reducer:: pre_reduce(red_object* r, int l, int u){
3847  for(int i=l;i<=u;i++)
3848    {
3849      if (r[i].sum){
3850        if(r[i].sum->ac->counter<=AC_FLATTEN) r[i].flatten();
3851       
3852      }
3853    }
3854}
Note: See TracBrowser for help on using the repository browser.