source: git/kernel/tgb.cc @ 4bbe3b

spielwiese
Last change on this file since 4bbe3b was 35aab3, checked in by Hans Schönemann <hannes@…>, 21 years ago
This commit was generated by cvs2svn to compensate for changes in r6879, which included commits to RCS files with non-trunk default branches. git-svn-id: file:///usr/local/Singular/svn/trunk@6880 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 64.7 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
87
88static int LObject_better_gen(const void* ap, const void* bp)
89{
90  LObject* a=*(LObject**)ap;
91  LObject* b=*(LObject**)bp;
92  return(pLmCmp(a->p,b->p));
93}
94static int red_object_better_gen(const void* ap, const void* bp)
95{
96
97
98  return(pLmCmp(((red_object*) ap)->p,((red_object*) bp)->p));
99}
100static int pair_better_gen2(const void* ap,const void* bp){
101  return(-pair_better_gen(ap,bp));
102}
103static int kFindDivisibleByInS_easy(kStrategy strat,const red_object & obj){
104  int i;
105  long not_sev=~obj.sev;
106  poly p=obj.p;
107  for(i=0;i<=strat->sl;i++){
108    if (pLmShortDivisibleBy(strat->S[i],strat->sevS[i],p,not_sev))
109      return i;
110  }
111  return -1;
112}
113static int posInPairs (sorted_pair_node**  p, int pn, sorted_pair_node* qe,calc_dat* c,int an=0)
114{
115  if(pn==0) return 0;
116
117  int length=pn-1;
118  int i;
119  //int an = 0;
120  int en= length;
121
122  if (pair_better(qe,p[en],c))
123    return length+1;
124
125  while(1)
126    {
127      //if (an >= en-1)
128      if(en-1<=an)
129      {
130        if (pair_better(p[an],qe,c)) return an;
131        return en;
132      }
133      i=(an+en) / 2;
134        if (pair_better(p[i],qe,c))
135          en=i;
136      else an=i;
137    }
138}
139static BOOLEAN  ascending(int* i,int top){
140  if(top<1) return TRUE;
141  if(i[top]<i[top-1]) return FALSE;
142  return ascending(i,top-1);
143}
144
145sorted_pair_node**  merge(sorted_pair_node** p, int pn,sorted_pair_node **q, int qn,calc_dat* c){
146  int i;
147  int* a= (int*) omalloc(qn*sizeof(int));
148//   int mc;
149//   PrintS("Debug\n");
150//   for(mc=0;mc<qn;mc++)
151// {
152
153//     wrp(q[mc]->lcm_of_lm);
154//     PrintS("\n");
155// }
156//    PrintS("Debug they are in\n");
157//   for(mc=0;mc<pn;mc++)
158// {
159
160//     wrp(p[mc]->lcm_of_lm);
161//     PrintS("\n");
162// }
163  int lastpos=0;
164  for(i=0;i<qn;i++){
165    lastpos=posInPairs(p,pn,q[i],c, max(lastpos-1,0));
166    //   cout<<lastpos<<"\n";
167    a[i]=lastpos;
168
169  }
170  if((pn+qn)>c->max_pairs){
171    p=(sorted_pair_node**) omrealloc(p,2*(pn+qn)*sizeof(sorted_pair_node*));
172    c->max_pairs=2*(pn+qn);
173  }
174  for(i=qn-1;i>=0;i--){
175    size_t size;
176    if(qn-1>i)
177      size=(a[i+1]-a[i])*sizeof(sorted_pair_node*);
178    else
179      size=(pn-a[i])*sizeof(sorted_pair_node*); //as indices begin with 0
180    memmove (p+a[i]+(1+i), p+a[i], size);
181    p[a[i]+i]=q[i];
182  }
183  omfree(a);
184  return p;
185}
186
187
188static BOOLEAN trivial_syzygie(int pos1,int pos2,poly bound,calc_dat* c){
189
190
191  poly p1=c->S->m[pos1];
192  poly p2=c->S->m[pos2];
193  ring r=c->r;
194 
195
196  if (pGetComp(p1) > 0 || pGetComp(p2) > 0)
197    return FALSE;
198  int i = 1;
199  poly m=NULL;
200  poly gcd1=c->gcd_of_terms[pos1];
201  poly gcd2=c->gcd_of_terms[pos2];
202 
203  if((gcd1!=NULL) && (gcd2!=NULL)) 
204    {
205      gcd1->next=gcd2; //may ordered incorrect
206      poly m=gcd_of_terms(gcd1,c->r);
207      gcd1->next=NULL;
208     
209    } 
210
211  if (m==NULL) 
212  {
213     loop
214      {
215        if (pGetExp(p1, i)+ pGetExp(p2, i) > pGetExp(bound,i))   return FALSE;
216        if (i == pVariables){
217          PrintS("trivial");
218          return TRUE;
219        }
220        i++;
221      }
222  }
223  else 
224  {
225    loop
226      {
227        if (pGetExp(p1, i)-pGetExp(m,i) + pGetExp(p2, i) > pGetExp(bound,i))   return FALSE;
228        if (i == pVariables){
229          pDelete(&m);
230          PrintS("trivial");
231          return TRUE;
232        }
233        i++;
234      }
235  }
236
237 
238
239 
240}
241
242///returns position sets w as weight
243int find_best(red_object* r,int l, int u, int &w, calc_dat* c){
244  int best=l;
245  int i;
246  w=r[l].guess_quality(c);
247  for(i=l+1;i<=u;i++){
248    int w2=r[i].guess_quality(c);
249    if(w2<w){
250      w=w2;
251      best=i;
252    }
253   
254  }
255 return best;
256}
257
258#if 0 
259int find_best(red_object* r,int l, int u, int &w, calc_dat* c){
260
261  int sz=u-l+1;
262  int n=sz/10+1;
263  int filled=0;
264  int* indizes=(int*) omalloc(n*sizeof(int));
265  int* weight=(int*) omalloc(n*sizeof(int));
266  int worst=-1;
267  int i; 
268  for(i=l;i<=u;i++){
269    int q=r[i].guess_quality(c);
270    if ((filled<n)||(q<worst)){
271      if(filled<n){
272        worst=max(q,worst);
273        indizes[filled]=i;
274        weight[filled]=q;
275        filled++;
276      }
277    }
278    else{
279      int j;
280      for(j=0;j<filled;j++){
281        if (worst==weight[j]){
282          weight[j]=q;
283          indizes[j]=i;
284        }
285      }
286      worst=-1;
287      for(j=0;j<filled;j++){
288        if (worst<weight[j]){
289          worst=weight[j];
290        }
291      }
292    }
293  }
294  assume(filled==n);
295  int pos=0;
296
297  for(i=0;i<filled;i++){ 
298    r[indizes[i]].canonicalize();
299    weight[i]=r[indizes[i]].guess_quality(c);
300    if(weight[i]<weight[pos]) pos=i;
301  }
302  w=weight[pos];
303  pos=indizes[pos];
304
305  omfree(indizes);
306  omfree(weight);
307
308  assume(w==r[pos].guess_quality(c));
309  assume(l<=pos);
310  assume(u>=pos);
311  return pos;
312 
313}
314
315#endif
316void red_object::canonicalize(){
317  kBucketCanonicalize(bucket);
318  if(sum)
319    kBucketCanonicalize(sum->ac->bucket);
320 
321}
322BOOLEAN good_has_t_rep(int i, int j,calc_dat* c){
323  assume(i>=0);
324    assume(j>=0);
325  if (has_t_rep(i,j,c)) return TRUE;
326  poly lm=pOne();
327
328  pLcm(c->S->m[i], c->S->m[j], lm);
329  pSetm(lm);
330  assume(lm!=NULL);
331  int deciding_deg= pTotaldegree(lm);
332  int* i_con =make_connections(i,j,lm,c);
333  p_Delete(&lm,c->r);
334
335
336  for (int n=0;((n<c->n) && (i_con[n]>=0));n++){
337    if (i_con[n]==j){
338      now_t_rep(i,j,c);
339      omfree(i_con);
340
341      return TRUE;
342    }
343  }
344  omfree(i_con);
345
346  return FALSE;
347}
348BOOLEAN lenS_correct(kStrategy strat){
349  int i;
350  for(i=0;i<=strat->sl;i++){
351    if (strat->lenS[i]!=pLength(strat->S[i]))
352      return FALSE;
353  }
354  return TRUE;
355}
356
357static void notice_miss(int i, int j, calc_dat* c){
358  PrintS("-");
359 
360}
361
362static void cleanS(kStrategy strat){
363  int i=0;
364  LObject P;
365  while(i<=strat->sl){
366    P.p=strat->S[i];
367    P.sev=strat->sevS[i];
368    if(kFindDivisibleByInS(strat->S,strat->sevS,strat->sl,&P)!=i){
369      deleteInS(i,strat);
370      //remember destroying poly
371    }
372    else i++;
373  }
374}
375static int bucket_guess(kBucket* bucket){
376  int sum=0;
377  int i;
378  for (i=MAX_BUCKET;i>=0;i--){
379    sum+=bucket->buckets_length[i];
380  }
381  return sum;
382}
383
384
385
386
387
388
389static int add_to_reductors(calc_dat* c, poly h, int len){
390  inDebug(h);
391  assume(lenS_correct(c->strat));
392 
393  int i;
394  if (c->is_char0)
395       i=simple_posInS(c->strat,h,pSLength(h,len),c->is_char0);
396  else
397    i=simple_posInS(c->strat,h,len,c->is_char0);
398 
399  LObject P; memset(&P,0,sizeof(P));
400  P.tailRing=c->r;
401  P.p=h; /*p_Copy(h,c->r);*/
402  P.FDeg=pFDeg(P.p,c->r);
403  if (!rField_is_Zp(c->r)){ 
404    pCleardenom(P.p);
405    pContent(P.p); //is a duplicate call, but belongs here
406  }
407 
408  else                     
409    pNorm(P.p);
410 
411 
412  c->strat->enterS(P,i,c->strat);
413 
414 
415
416  c->strat->lenS[i]=len;
417 
418  if(c->strat->lenSw)
419    c->strat->lenSw[i]=pSLength(P.p,len);
420  return i;
421 
422}
423static void length_one_crit(calc_dat* c, int pos, int len)
424{
425  if (len==1)
426  {
427    int i;
428    for ( i=0;i<pos;i++)
429    {
430      if (c->lengths[i]==1)
431        c->states[pos][i]=HASTREP;
432    }
433    for ( i=pos+1;i<c->n;i++){
434      if (c->lengths[i]==1)
435        c->states[i][pos]=HASTREP;
436    }
437    shorten_tails(c,c->S->m[pos]);
438  }
439}
440static sorted_pair_node* find_next_pair2(calc_dat* c, BOOLEAN go_higher){
441  clean_top_of_pair_list(c);
442  sorted_pair_node* s=pop_pair(c);
443
444
445  return s;
446}
447
448static void move_forward_in_S(int old_pos, int new_pos,kStrategy strat, BOOLEAN is_char0)
449{
450  assume(old_pos>=new_pos);
451  poly p=strat->S[old_pos];
452  int ecart=strat->ecartS[old_pos];
453  long sev=strat->sevS[old_pos];
454  int s_2_r=strat->S_2_R[old_pos];
455  int length=strat->lenS[old_pos];
456  int length_w;
457  if(is_char0)
458    length_w=strat->lenSw[old_pos];
459  int i;
460  for (i=old_pos; i>new_pos; i--)
461  {
462    strat->S[i] = strat->S[i-1];
463    strat->ecartS[i] = strat->ecartS[i-1];
464    strat->sevS[i] = strat->sevS[i-1];
465    strat->S_2_R[i] = strat->S_2_R[i-1];
466  }
467  if (strat->lenS!=NULL)
468    for (i=old_pos; i>new_pos; i--)
469      strat->lenS[i] = strat->lenS[i-1];
470  if (strat->lenSw!=NULL)
471    for (i=old_pos; i>new_pos; i--)
472      strat->lenSw[i] = strat->lenSw[i-1];
473
474  strat->S[new_pos]=p;
475  strat->ecartS[new_pos]=ecart;
476  strat->sevS[new_pos]=sev;
477  strat->S_2_R[new_pos]=s_2_r;
478  strat->lenS[new_pos]=length;
479  if(is_char0)
480    strat->lenSw[new_pos]=length_w;
481  //assume(lenS_correct(strat));
482}
483static void replace_pair(int & i, int & j, calc_dat* c)
484{
485  c->soon_free=NULL;
486  int curr_deg;
487  poly lm=pOne();
488
489  pLcm(c->S->m[i], c->S->m[j], lm);
490  pSetm(lm);
491  int deciding_deg= pTotaldegree(lm);
492  int* i_con =make_connections(i,j,lm,c);
493  int z=0;
494
495  for (int n=0;((n<c->n) && (i_con[n]>=0));n++){
496    if (i_con[n]==j){
497      now_t_rep(i,j,c);
498      omfree(i_con);
499      p_Delete(&lm,c->r);
500      return;
501    }
502  }
503
504  int* j_con =make_connections(j,lm,c);
505  i= i_con[0];
506  j=j_con[0];
507  if(c->n>1){
508    if (i_con[1]>=0)
509      i=i_con[1];
510    else {
511      if (j_con[1]>=0)
512        j=j_con[1];
513    }
514  }
515  pLcm(c->S->m[i], c->S->m[j], lm);
516  pSetm(lm);
517  poly short_s;
518  curr_deg=pTotaldegree(lm);
519  int_pair_node* last=NULL;
520
521  for (int n=0;((n<c->n) && (j_con[n]>=0));n++){
522    for (int m=0;((m<c->n) && (i_con[m]>=0));m++){
523      pLcm(c->S->m[i_con[m]], c->S->m[j_con[n]], lm);
524      pSetm(lm);
525      if (pTotaldegree(lm)>=deciding_deg)
526      {
527        soon_t_rep(i_con[m],j_con[n],c);
528        int_pair_node* h= (int_pair_node*)omalloc(sizeof(int_pair_node));
529        if (last!=NULL)
530          last->next=h;
531        else
532          c->soon_free=h;
533        h->next=NULL;
534        h->a=i_con[m];
535        h->b=j_con[n];
536        last=h;
537      }
538      //      if ((comp_deg<curr_deg)
539      //  ||
540      //  ((comp_deg==curr_deg) &&
541      short_s=ksCreateShortSpoly(c->S->m[i_con[m]],c->S->m[j_con[n]],c->r);
542      if (short_s==NULL) {
543        i=i_con[m];
544        j=j_con[n];
545        now_t_rep(i_con[m],j_con[n],c);
546        p_Delete(&lm,c->r);
547        omfree(i_con);
548        omfree(j_con);
549
550        return;
551      }
552#ifdef QUICK_SPOLY_TEST
553      for (int dz=0;dz<=c->n;dz++){
554        if (dz==c->n) {
555          //have found not head reducing pair
556          i=i_con[m];
557          j=j_con[n];
558          p_Delete(&short_s,c->r);
559          p_Delete(&lm,c->r);
560          omfree(i_con);
561          omfree(j_con);
562
563          return;
564        }
565        if (p_LmDivisibleBy(c->S->m[dz],short_s,c->r)) break;
566      }
567#endif
568      int comp_deg(pTotaldegree(short_s));
569      p_Delete(&short_s,c->r);
570      if ((comp_deg<curr_deg))
571         
572      {
573        curr_deg=comp_deg;
574        i=i_con[m];
575        j=j_con[n];
576      }
577    }
578  }
579  p_Delete(&lm,c->r);
580  omfree(i_con);
581  omfree(j_con);
582  return;
583}
584
585
586static int* make_connections(int from, poly bound, calc_dat* c)
587{
588  ideal I=c->S;
589  int s=pTotaldegree(bound);
590  int* cans=(int*) omalloc(c->n*sizeof(int));
591  int* connected=(int*) omalloc(c->n*sizeof(int));
592  int cans_length=0;
593  connected[0]=from;
594  int connected_length=1;
595  long neg_bounds_short= ~p_GetShortExpVector(bound,c->r);
596  for (int i=0;i<c->n;i++){
597    if (c->T_deg[i]>s) continue;
598    if (i!=from){
599      if(p_LmShortDivisibleBy(I->m[i],c->short_Exps[i],bound,neg_bounds_short,c->r)){
600        cans[cans_length]=i;
601        cans_length++;
602      }
603    }
604  }
605  int not_yet_found=cans_length;
606  int con_checked=0;
607  int pos;
608  while((not_yet_found>0) && (con_checked<connected_length)){
609    pos=connected[con_checked];
610    for(int i=0;i<cans_length;i++){
611      if (cans[i]<0) continue;
612      if (has_t_rep(pos,cans[i],c))
613      {
614        connected[connected_length]=cans[i];
615        connected_length++;
616        cans[i]=-1;
617        --not_yet_found;
618      }
619    }
620    con_checked++;
621  }
622  if (connected_length<c->n){
623    connected[connected_length]=-1;
624  }
625  omfree(cans);
626  return connected;
627}
628static int* make_connections(int from, int to, poly bound, calc_dat* c)
629{
630  ideal I=c->S;
631  int s=pTotaldegree(bound);
632  int* cans=(int*) omalloc(c->n*sizeof(int));
633  int* connected=(int*) omalloc(c->n*sizeof(int));
634  cans[0]=to;
635  int cans_length=1;
636  connected[0]=from;
637  int last_cans_pos=-1;
638  int connected_length=1;
639  long neg_bounds_short= ~p_GetShortExpVector(bound,c->r);
640
641  int not_yet_found=cans_length;
642  int con_checked=0;
643  int pos;
644  BOOLEAN can_find_more=TRUE;
645  while(((not_yet_found>0) && (con_checked<connected_length))||can_find_more){
646    if ((con_checked<connected_length)&& (not_yet_found>0)){
647      pos=connected[con_checked];
648      for(int i=0;i<cans_length;i++){
649        if (cans[i]<0) continue;
650        if (has_t_rep(pos,cans[i],c))//||(trivial_syzygie(pos,cans[i],bound,c))
651{
652
653          connected[connected_length]=cans[i];
654          connected_length++;
655          cans[i]=-1;
656          --not_yet_found;
657
658          if (connected[connected_length-1]==to){
659            if (connected_length<c->n){
660              connected[connected_length]=-1;
661            }
662            omfree(cans);
663            return connected;
664          }
665        }
666      }
667      con_checked++;
668    }
669    else
670    {
671      for(last_cans_pos++;last_cans_pos<=c->n;last_cans_pos++){
672        if (last_cans_pos==c->n){
673          if (connected_length<c->n){
674            connected[connected_length]=-1;
675          }
676          omfree(cans);
677          return connected;
678        }
679        if ((last_cans_pos==from)||(last_cans_pos==to))
680          continue;
681        if(p_LmShortDivisibleBy(I->m[last_cans_pos],c->short_Exps[last_cans_pos],bound,neg_bounds_short,c->r)){
682          cans[cans_length]=last_cans_pos;
683          cans_length++;
684          break;
685        }
686      }
687      not_yet_found++;
688      for (int i=0;i<con_checked;i++){
689        if (has_t_rep(connected[i],last_cans_pos,c)){
690
691          connected[connected_length]=last_cans_pos;
692          connected_length++;
693          cans[cans_length-1]=-1;
694
695          --not_yet_found;
696          if (connected[connected_length-1]==to){
697            if (connected_length<c->n){
698              connected[connected_length]=-1;
699            }
700
701            omfree(cans);
702            return connected;
703          }
704          break;
705        }
706      }
707    }
708  }
709  if (connected_length<c->n){
710    connected[connected_length]=-1;
711  }
712
713  omfree(cans);
714  return connected;
715}
716#ifdef HEAD_BIN
717static inline poly p_MoveHead(poly p, omBin b)
718{
719  poly np;
720  omTypeAllocBin(poly, np, b);
721  memmove(np, p, b->sizeW*sizeof(long));
722  omFreeBinAddr(p);
723  return np;
724}
725#endif
726
727
728
729//len should be weighted length in char 0
730static int simple_posInS (kStrategy strat, poly p,int len, BOOLEAN is_char0)
731{
732
733
734  if(strat->sl==-1) return 0;
735  polyset set=strat->S;
736  intset setL=strat->lenS;
737  if (is_char0) setL=strat->lenSw;
738  int length=strat->sl;
739  int i;
740  int an = 0;
741  int en= length;
742
743  if ((len>setL[length])
744      || ((len==setL[length]) && (pLmCmp(set[length],p)== -1)))
745    return length+1;
746
747  loop
748  {
749    if (an >= en-1)
750    {
751      if ((len<setL[an])
752          || ((len==setL[an]) && (pLmCmp(set[an],p) == 1))) return an;
753      return en;
754    }
755    i=(an+en) / 2;
756    if ((len<setL[i])
757        || ((len==setL[i]) && (pLmCmp(set[i],p) == 1))) en=i;
758    //else if ((len>setL[i])
759    //|| ((len==setL[i]) && (pLmCmp(set[i],p) == -1))) an=i;
760    else an=i;
761  }
762}
763/*2
764 *if the leading term of p
765 *divides the leading term of some S[i] it will be canceled
766 */
767static inline void clearS (poly p, unsigned long p_sev,int l, int* at, int* k,
768                           kStrategy strat)
769{
770  assume(p_sev == pGetShortExpVector(p));
771  if (!pLmShortDivisibleBy(p,p_sev, strat->S[*at], ~ strat->sevS[*at])) return;
772  if (l>=strat->lenS[*at]) return;
773  PrintS("!");mflush();
774  //pDelete(&strat->S[*at]);
775  deleteInS((*at),strat);
776  (*at)--;
777  (*k)--;
778//  assume(lenS_correct(strat));
779}
780static sorted_pair_node** add_to_basis(poly h, int i_pos, int j_pos,calc_dat* c, int* ip)
781{
782
783  assume(h!=NULL);
784//  BOOLEAN corr=lenS_correct(c->strat);
785  BOOLEAN R_found=FALSE;
786  void* hp;
787
788  ++(c->n);
789  ++(c->S->ncols);
790  int i,j;
791  i=c->n-1;
792  sorted_pair_node** nodes=(sorted_pair_node**) omalloc(sizeof(sorted_pair_node*)*i);
793  int spc=0;
794  c->T_deg=(int*) omrealloc(c->T_deg,c->n*sizeof(int));
795  c->T_deg[i]=pTotaldegree(h);
796  hp=omrealloc(c->rep, c->n *sizeof(int));
797  if (hp!=NULL){
798    c->rep=(int*) hp;
799  } else {
800    exit(1);
801  }
802  c->short_Exps=(long *) omrealloc(c->short_Exps ,c->n*sizeof(long));
803
804  hp=omrealloc(c->lengths, c->n *sizeof(int));
805  if (hp!=NULL){
806    c->lengths=(int*) hp;
807  } else {
808    exit(1);
809  }
810  c->lengths[i]=pLength(h);
811  hp=omrealloc(c->states, c->n * sizeof(char*));
812 
813    c->states=(char**) hp;
814  c->gcd_of_terms=(poly*) omrealloc(c->gcd_of_terms, c->n *sizeof(poly));
815  c->gcd_of_terms[i]=gcd_of_terms(h,c->r);
816  c->rep[i]=i;
817  hp=omalloc(i*sizeof(char));
818  if (hp!=NULL){
819    c->states[i]=(char*) hp;
820  } else {
821    exit(1);
822  }
823  hp=omrealloc(c->S->m,c->n*sizeof(poly));
824  if (hp!=NULL){
825    c->S->m=(poly*) hp;
826  } else {
827    exit(1);
828  }
829  c->S->m[i]=h;
830  c->short_Exps[i]=p_GetShortExpVector(h,c->r);
831  for (j=0;j<i;j++){
832    if (c->rep[j]==j){
833      //check product criterion
834
835      c->states[i][j]=UNCALCULATED;
836
837      //lies I[i] under I[j] ?
838      if(p_LmShortDivisibleBy(c->S->m[i],c->short_Exps[i],c->S->m[j],~(c->short_Exps[j]),c->r)){
839        c->rep[j]=i;
840       
841        PrintS("R"); R_found=TRUE;
842
843        c->Rcounter++;
844        if((i_pos>=0) && (j_pos>=0)){
845       
846        }
847        for(int z=0;z<j;z++){
848          if(c->rep[z]!=z) continue;
849          if (c->states[j][z]==UNCALCULATED){
850            c->states[j][z]=UNIMPORTANT;
851          }
852        }
853        for(int z=j+1;z<i;z++){
854          if(c->rep[z]!=z) continue;
855          if (c->states[z][j]==UNCALCULATED){
856            c->states[z][j]=UNIMPORTANT;
857          }
858        }
859      }
860    }
861    else {
862      c->states[i][j]=UNIMPORTANT;
863    }
864    if ((c->lengths[i]==1) && (c->lengths[j]==1))
865      c->states[i][j]=HASTREP;
866    else if (pHasNotCF(c->S->m[i],c->S->m[j])){
867      c->easy_product_crit++;
868      c->states[i][j]=HASTREP;
869    }
870                        else if(extended_product_criterion(c->S->m[i],c->gcd_of_terms[i],c->S->m[j],c->gcd_of_terms[j],c)){
871                                        c->states[i][j]=HASTREP;
872                                        c->extended_product_crit++;
873                                        //PrintS("E");
874                        }
875    if (c->states[i][j]==UNCALCULATED){
876
877     
878//      poly short_s=ksCreateShortSpoly(c->S->m[i],c->S->m[j],c->r);
879      //    if (short_s)
880      //    {
881        sorted_pair_node* s=(sorted_pair_node*) omalloc(sizeof(sorted_pair_node));
882        s->i=max(i,j);
883        s->j=min(i,j);
884        s->expected_length=c->lengths[i]+c->lengths[j]-2;
885     
886        poly lm=pOne();
887
888        pLcm(c->S->m[i], c->S->m[j], lm);
889        pSetm(lm);
890        s->deg=pTotaldegree(lm);
891        s->lcm_of_lm=lm;
892//          pDelete(&short_s);
893        //assume(lm!=NULL);
894        nodes[spc]=s;
895        spc++;
896        // }
897        //else
898        //{
899        //c->states[i][j]=HASTREP;
900        //}
901    }
902  }
903
904  add_to_reductors(c, h, c->lengths[c->n-1]);
905  //i=posInS(c->strat,c->strat->sl,h,0 /*ecart*/);
906
907  if (c->lengths[c->n-1]==1)
908    shorten_tails(c,c->S->m[c->n-1]);
909  //you should really update c->lengths, c->strat->lenS, and the oder of polys in strat if you sort after lengths
910
911  //for(i=c->strat->sl; i>0;i--)
912  //  if(c->strat->lenS[i]<c->strat->lenS[i-1]) printf("fehler bei %d\n",i);
913  if (c->Rcounter>50) {
914    c->Rcounter=0;
915    cleanS(c->strat);
916  }
917  if(!ip){
918    qsort(nodes,spc,sizeof(sorted_pair_node*),pair_better_gen2);
919 
920   
921    c->apairs=merge(c->apairs,c->pair_top+1,nodes,spc,c);
922    c->pair_top+=spc;
923    clean_top_of_pair_list(c);
924    omfree(nodes);
925    return NULL;
926  }
927  {
928    *ip=spc;
929    return nodes;
930  }
931
932 
933
934}
935#if 0
936static poly redNF (poly h,kStrategy strat)
937{
938  int j = 0;
939  int z = 3;
940  unsigned long not_sev;
941
942  if (0 > strat->sl)
943  {
944    return h;
945  }
946  not_sev = ~ pGetShortExpVector(h);
947  loop
948    {
949      if (pLmShortDivisibleBy(strat->S[j], strat->sevS[j], h, not_sev))
950      {
951        //if (strat->interpt) test_int_std(strat->kIdeal);
952        /*- compute the s-polynomial -*/
953#ifdef KDEBUG
954        if (TEST_OPT_DEBUG)
955        {
956          PrintS("red:");
957          wrp(h);
958          PrintS(" with ");
959          wrp(strat->S[j]);
960        }
961#endif
962        h = ksOldSpolyRed(strat->S[j],h,strat->kNoether);
963#ifdef KDEBUG
964        if (TEST_OPT_DEBUG)
965        {
966          PrintS("\nto:");
967          wrp(h);
968          PrintLn();
969        }
970#endif
971        if (h == NULL) return NULL;
972        z++;
973        if (z>=10)
974        {
975          z=0;
976          pNormalize(h);
977        }
978        /*- try to reduce the s-polynomial -*/
979        j = 0;
980        not_sev = ~ pGetShortExpVector(h);
981      }
982      else
983      {
984        if (j >= strat->sl) return h;
985        j++;
986      }
987    }
988}
989#else
990
991static poly redNF2 (poly h,calc_dat* c , int &len, number&  m,int n)
992{
993  m=nInit(1);
994  if (h==NULL) return NULL;
995
996  assume(len==pLength(h));
997  kStrategy strat=c->strat;
998  if (0 > strat->sl)
999  {
1000    return h;
1001  }
1002  int j;
1003 
1004  LObject P(h);
1005  P.SetShortExpVector();
1006  P.bucket = kBucketCreate(currRing);
1007  // BOOLEAN corr=lenS_correct(strat);
1008  kBucketInit(P.bucket,P.p,len /*pLength(P.p)*/);
1009  //int max_pos=simple_posInS(strat,P.p);
1010  loop
1011    {
1012
1013      j=kFindDivisibleByInS(strat->S,strat->sevS,strat->sl,&P);
1014      if ((j>=0) && ((!n)||(strat->lenS[j]<=n)))
1015      {
1016
1017       
1018        nNormalize(pGetCoeff(P.p));
1019#ifdef KDEBUG
1020        if (TEST_OPT_DEBUG)
1021        {
1022          PrintS("red:");
1023          wrp(h);
1024          PrintS(" with ");
1025          wrp(strat->S[j]);
1026        }
1027#endif
1028       
1029        number coef=kBucketPolyRed(P.bucket,strat->S[j],
1030                                   strat->lenS[j]/*pLength(strat->S[j])*/,
1031                                   strat->kNoether);
1032        number m2=nMult(m,coef);
1033        nDelete(&m);
1034        m=m2;
1035        nDelete(&coef);
1036        h = kBucketGetLm(P.bucket);
1037       
1038        if (h==NULL) {
1039          len=0;
1040          return 
1041          NULL;}
1042        P.p=h;
1043        P.t_p=NULL;
1044        P.SetShortExpVector();
1045#ifdef KDEBUG
1046        if (TEST_OPT_DEBUG)
1047        {
1048          PrintS("\nto:");
1049          wrp(h);
1050          PrintLn();
1051        }
1052#endif
1053      }
1054      else
1055      {
1056        kBucketClear(P.bucket,&(P.p),&len);
1057        kBucketDestroy(&P.bucket);
1058        pNormalize(P.p);
1059        assume(len==(pLength(P.p)));
1060        return P.p;
1061      }
1062    }
1063}
1064
1065
1066static poly redTailShort(poly h, kStrategy strat){
1067
1068  int sl=strat->sl;
1069  int i;
1070  int len=pLength(h);
1071  for(i=0;i<=strat->sl;i++){
1072    if(strat->lenS[i]>2)
1073      break;
1074  }
1075  return(redNFTail(h,i-1,strat, len));
1076}
1077
1078static void line_of_extended_prod(int fixpos,calc_dat* c){
1079    if (c->gcd_of_terms[fixpos]==NULL)
1080  {
1081    c->gcd_of_terms[fixpos]=gcd_of_terms(c->S->m[fixpos],c->r);
1082    if (c->gcd_of_terms[fixpos])
1083    {
1084      int i;
1085      for(i=0;i<fixpos;i++)
1086        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)))
1087{
1088          c->states[fixpos][i]=HASTREP;
1089          c->extended_product_crit++;
1090}     
1091      for(i=fixpos+1;i<c->n;i++)
1092        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)))
1093        {        c->states[i][fixpos]=HASTREP;
1094        c->extended_product_crit++;
1095        }
1096    }
1097  }
1098}
1099static void c_S_element_changed_hook(int pos, calc_dat* c){
1100  length_one_crit(c,pos, c->lengths[pos]);
1101  line_of_extended_prod(pos,c);
1102}
1103class poly_tree_node {
1104public:
1105  poly p;
1106  poly_tree_node* l;
1107  poly_tree_node* r;
1108  int n;
1109  poly_tree_node(int sn):l(NULL),r(NULL),n(sn){}
1110};
1111class exp_number_builder{
1112public:
1113  poly_tree_node* top_level;
1114  int n;
1115  int get_n(poly p);
1116  exp_number_builder():top_level(0),n(0){}
1117};
1118int exp_number_builder::get_n(poly p){
1119  poly_tree_node** node=&top_level;
1120  while(*node!=NULL){
1121    int c=pLmCmp(p,(*node)->p);
1122    if (c==0) return (*node)->n;
1123    if (c==-1) node=&((*node)->r);
1124    else
1125      node=&((*node)->l);
1126  }
1127  (*node)= new poly_tree_node(n);
1128  n++;
1129  (*node)->p=pLmInit(p);
1130  return (*node)->n;
1131}
1132class mac_poly_r{
1133public:
1134  number coef;
1135  mac_poly_r* next;
1136  int exp;
1137  mac_poly_r():next(NULL){}
1138};
1139//mac_polys exp are smaller iff they are greater by monomial ordering
1140//corresponding to solving linear equations notation
1141struct int_poly_pair{
1142  poly p;
1143  int n;
1144};
1145typedef mac_poly_r* mac_poly;
1146  void t2ippa_rec(poly* ip,int* ia, poly_tree_node* k, int &offset){
1147    if(!k) return;
1148    t2ippa_rec(ip,ia,k->l,offset);
1149    ip[offset]=k->p;
1150    ia[k->n]=offset;
1151    ++offset;
1152
1153    t2ippa_rec(ip,ia,k->r,offset);
1154    delete k;
1155  }
1156void t2ippa(poly* ip,int* ia,exp_number_builder & e){
1157
1158  int o=0;
1159  t2ippa_rec(ip,ia,e.top_level,o);
1160}
1161int anti_poly_order(const void* a, const void* b){
1162  return -pLmCmp(((int_poly_pair*) a)->p,((int_poly_pair*) b)->p );
1163}
1164mac_poly mac_p_add_ff_qq(mac_poly a, number f,mac_poly b){
1165  mac_poly erg;
1166  mac_poly* set_this;
1167  set_this=&erg;
1168  while((a!=NULL) &&(b!=NULL)){
1169    if (a->exp<b->exp){
1170      (*set_this)=a;
1171      a=a->next;
1172      set_this= &((*set_this)->next);
1173    } 
1174    else{
1175      if (a->exp>b->exp){
1176        mac_poly in =new mac_poly_r();
1177        in->exp=b->exp;
1178        in->coef=nMult(b->coef,f);
1179        (*set_this)=in;
1180        b=b->next;
1181        set_this= &((*set_this)->next);
1182      }
1183      else {
1184        //a->exp==b->ecp
1185        number n=nMult(b->coef,f);
1186        number n2=nAdd(a->coef,n);
1187        nDelete(&n);
1188        nDelete(&(a->coef));
1189        if (nIsZero(n2)){
1190          nDelete(&n2);
1191          mac_poly ao=a;
1192          a=a->next;
1193          delete ao;
1194          b=b->next;
1195         
1196        } else {
1197          a->coef=n2;
1198          b=b->next;
1199          (*set_this)=a;
1200          a=a->next;
1201          set_this= &((*set_this)->next);
1202        }
1203 
1204      }
1205   
1206    }
1207  }
1208  if((a==NULL)&&(b==NULL)){
1209    (*set_this)=NULL;
1210    return erg;
1211  }
1212  if (b==NULL) {
1213    (*set_this=a);
1214    return erg;
1215  }
1216 
1217  //a==NULL
1218  while(b!=NULL){
1219    mac_poly mp= new mac_poly_r();
1220    mp->exp=b->exp;
1221    mp->coef=nMult(f,b->coef);
1222    (*set_this)=mp;
1223    set_this=&(mp->next);
1224    b=b->next;
1225  }
1226  (*set_this)=NULL;
1227  return erg;
1228 
1229}
1230void mac_mult_cons(mac_poly p,number c){
1231  while(p){
1232    number m=nMult(p->coef,c);
1233    nDelete(&(p->coef));
1234    p->coef=m;
1235    p=p->next;
1236  }
1237 
1238}
1239int mac_length(mac_poly p){
1240  int l=0;
1241  while(p){
1242    l++;
1243    p=p->next;
1244  }
1245  return l;
1246}
1247BOOLEAN is_valid_ro(red_object & ro){
1248  red_object r2=ro;
1249  ro.validate();
1250  if ((r2.p!=ro.p)||(r2.sev!=ro.sev)||(r2.sum!=ro.sum)) return FALSE;
1251  return TRUE;
1252}
1253void pre_comp(poly* p,int & pn,calc_dat* c){
1254  if(!(pn))
1255    return;
1256  mac_poly* q=(mac_poly*) omalloc(pn*sizeof(mac_poly)); 
1257  int i;
1258  exp_number_builder e;
1259  for(i=0;i<pn;i++){
1260    assume(p[i]!=NULL);
1261    q[i]=new mac_poly_r();
1262    q[i]->exp=e.get_n(p[i]);
1263    q[i]->coef=nCopy(p[i]->coef);
1264   
1265    mac_poly qa=q[i];
1266    poly pa=p[i];
1267    while(pa->next!=NULL){
1268      qa->next = new mac_poly_r();
1269      qa=qa->next;
1270      pa=pa->next,
1271      qa->exp=e.get_n(pa);
1272      qa->coef=nCopy(pa->coef);
1273     
1274     
1275    }
1276    qa->next=NULL;
1277    pDelete(&p[i]);
1278  }
1279  poly* ip= (poly*)omalloc (e.n*sizeof(poly));
1280  int* ia=(int*) omalloc (e.n*sizeof(int));
1281  t2ippa(ip,ia,e);
1282  for(i=0;i<pn;i++){
1283    mac_poly mp=q[i];
1284    while(mp!=NULL){
1285      mp->exp=ia[mp->exp];
1286      mp=mp->next;
1287    }
1288   
1289  }
1290//gaus reduction start
1291  int col, row;
1292  col=0;
1293  row=0;
1294  assume(pn>0);
1295  while(row<pn-1){
1296    //row is the row where pivot should be
1297    // row== pn-1 means we have only to act on one row so no red nec.
1298    //we assume further all rows till the pn-1 row are non-zero
1299   
1300    //select column
1301    int i;
1302    col=q[row]->exp;
1303    int found_in_row=row;
1304    for(i=row;i<pn;i++){
1305      if(q[i]->exp<col){
1306        col=q[i]->exp;
1307        found_in_row=i;
1308      }
1309     
1310    }
1311    //select pivot
1312    int act_l=mac_length(q[found_in_row]);
1313    for(i=row+1;i<pn;i++){
1314      if((q[i]->exp==col)&&(mac_length(q[i])<act_l)){
1315        found_in_row=i;
1316        act_l=mac_length(q[i]);//should be optimized here
1317      }
1318    }
1319    mac_poly h=q[row];
1320    q[row]=q[found_in_row];
1321    q[found_in_row]=h;
1322
1323    //reduction
1324    for(i=row+1;i<pn;i++){
1325      if(q[i]->exp==q[row]->exp){
1326       
1327        number c1=nNeg(q[i]->coef);
1328        number c2=q[row]->coef;
1329        //use checkcoeff later
1330        mac_mult_cons(q[i],c2);
1331        q[i]=mac_p_add_ff_qq(q[i],c1,q[row]);
1332      }
1333         
1334       
1335       
1336    }
1337    for(i=row+1;i<pn;i++){
1338      if(q[i]==NULL){
1339        q[i]=q[pn-1];
1340        pn--;
1341        if(i!=pn){i--;}
1342      }
1343    }
1344 
1345
1346
1347
1348
1349
1350
1351
1352    row++;
1353  }
1354
1355
1356//gaus reduction end 
1357
1358
1359
1360
1361
1362  for(i=0;i<pn;i++){
1363    poly pa;
1364    mac_poly qa;
1365    p[i]=pLmInit(ip[q[i]->exp]);
1366    pSetCoeff(p[i],q[i]->coef);
1367    pa=p[i];
1368    qa=q[i];
1369    while(qa->next!=NULL){
1370      qa=qa->next;
1371      pa->next=pLmInit(ip[qa->exp]);
1372      pa=pa->next;
1373      pa->coef=qa->coef;
1374    }
1375    pa->next=NULL;
1376  }
1377  for(i=0;i<e.n;i++){
1378    pDelete(&ip[i]); 
1379  }
1380  omfree(ip);
1381  omfree(ia);
1382}
1383
1384static void go_on (calc_dat* c){
1385  //set limit of 1000 for multireductions, at the moment for
1386  //programming reasons
1387  int i=0;
1388  c->average_length=0;
1389  for(i=0;i<c->n;i++){
1390    c->average_length+=c->lengths[i];
1391  }
1392  c->average_length=c->average_length/c->n;
1393  i=0;
1394  poly* p=(poly*) omalloc((PAR_N+1)*sizeof(poly));//nullterminated
1395
1396  int curr_deg=-1;
1397  while(i<PAR_N){
1398    sorted_pair_node* s=top_pair(c);
1399    if (!s) break;
1400    if(curr_deg>=0){
1401      if (s->deg >curr_deg) break;
1402    }
1403
1404    else curr_deg=s->deg;
1405    quick_pop_pair(c);
1406    if(s->i>=0){
1407      //replace_pair(s->i,s->j,c);
1408    if(s->i==s->j) {
1409      free_sorted_pair_node(s,c->r);
1410      continue;
1411        }
1412    }
1413    poly h;
1414    if(s->i>=0)
1415      h=ksOldCreateSpoly(c->S->m[s->i], c->S->m[s->j], NULL, c->r);
1416    else
1417      h=s->lcm_of_lm;
1418    if(s->i>=0)
1419      now_t_rep(s->j,s->i,c);
1420    number coef;
1421    int mlen=pLength(h);
1422    h=redNF2(h,c,mlen,coef,2);
1423    redTailShort(h,c->strat);
1424    nDelete(&coef);
1425
1426    free_sorted_pair_node(s,c->r);
1427    if(!h) continue;
1428    int len=pLength(h);
1429    p[i]=h;
1430   
1431    i++;
1432  }
1433  p[i]=NULL;
1434//  pre_comp(p,i,c);
1435  if(i==0){
1436    omfree(p);
1437    return;
1438  }
1439  red_object* buf=(red_object*) omalloc(i*sizeof(red_object));
1440  c->normal_forms+=i;
1441  int j;
1442  for(j=0;j<i;j++){
1443    buf[j].p=p[j];
1444    buf[j].sev=pGetShortExpVector(p[j]);
1445    buf[j].sum=NULL;
1446    buf[j].bucket = kBucketCreate(currRing);
1447    int len=pLength(p[j]);
1448    kBucketInit(buf[j].bucket,buf[j].p,len);
1449  }
1450  omfree(p);
1451  qsort(buf,i,sizeof(red_object),red_object_better_gen);
1452//    Print("\ncurr_deg:%i\n",curr_deg);
1453  Print("M[%i, ",i); 
1454  multi_reduction(buf, i, c);
1455  Print("%i]",i); 
1456 //  for(j=0;j<i;j++){
1457//     if(buf[j].p==NULL) PrintS("\n ZERO ALERT \n");
1458//     int z;
1459//      for(z=0;z<j;z++){
1460//       if (pLmEqual(buf[z].p, buf[j].p))
1461//      PrintS("\n Critical Warning!!!! \n");
1462     
1463//     }
1464//   }
1465  int* ibuf=(int*) omalloc(i*sizeof(int));
1466  sorted_pair_node*** sbuf=(sorted_pair_node***) omalloc(i*sizeof(sorted_pair_node**));
1467  for(j=0;j<i;j++){
1468 
1469 
1470    int len;
1471    poly p;
1472    buf[j].flatten();
1473    kBucketClear(buf[j].bucket,&p, &len);
1474    kBucketDestroy(&buf[j].bucket);
1475    // delete buf[j];
1476    //remember to free res here
1477    p=redTailShort(p, c->strat);
1478    sbuf[j]=add_to_basis(p,-1,-1,c,ibuf+j);
1479   
1480  }
1481  int sum=0;
1482  for(j=0;j<i;j++){
1483    sum+=ibuf[j];
1484  }
1485  sorted_pair_node** big_sbuf=(sorted_pair_node**) omalloc(sum*sizeof(sorted_pair_node*));
1486  int partsum=0;
1487  for(j=0;j<i;j++){
1488    memmove(big_sbuf+partsum, sbuf[j],ibuf[j]*sizeof(sorted_pair_node*));
1489    omfree(sbuf[j]);
1490    partsum+=ibuf[j];
1491  }
1492
1493  qsort(big_sbuf,sum,sizeof(sorted_pair_node*),pair_better_gen2);
1494  c->apairs=merge(c->apairs,c->pair_top+1,big_sbuf,sum,c);
1495  c->pair_top+=sum;
1496  clean_top_of_pair_list(c);
1497  omfree(big_sbuf);
1498  omfree(sbuf);
1499  omfree(ibuf);
1500  omfree(buf);
1501  return;
1502}
1503
1504static poly redNF (poly h,kStrategy strat, int &len)
1505{
1506  len=0;
1507  if (h==NULL) return NULL;
1508  int j;
1509
1510  len=pLength(h);
1511  if (0 > strat->sl)
1512  {
1513    return h;
1514  }
1515  LObject P(h);
1516  P.SetShortExpVector();
1517  P.bucket = kBucketCreate(currRing);
1518  kBucketInit(P.bucket,P.p,len /*pLength(P.p)*/);
1519  //int max_pos=simple_posInS(strat,P.p);
1520  loop
1521    {
1522      j=kFindDivisibleByInS(strat->S,strat->sevS,strat->sl,&P);
1523      if (j>=0)
1524      {
1525        nNormalize(pGetCoeff(P.p));
1526#ifdef KDEBUG
1527        if (TEST_OPT_DEBUG)
1528        {
1529          PrintS("red:");
1530          wrp(h);
1531          PrintS(" with ");
1532          wrp(strat->S[j]);
1533        }
1534#endif
1535        number coef=kBucketPolyRed(P.bucket,strat->S[j],
1536                                   strat->lenS[j]/*pLength(strat->S[j])*/,
1537                                   strat->kNoether);
1538        nDelete(&coef);
1539        h = kBucketGetLm(P.bucket);
1540        if (h==NULL) return NULL;
1541        P.p=h;
1542        P.t_p=NULL;
1543        P.SetShortExpVector();
1544#ifdef KDEBUG
1545        if (TEST_OPT_DEBUG)
1546        {
1547          PrintS("\nto:");
1548          wrp(h);
1549          PrintLn();
1550        }
1551#endif
1552      }
1553      else
1554      {
1555        kBucketClear(P.bucket,&(P.p),&len);
1556        kBucketDestroy(&P.bucket);
1557        pNormalize(P.p);
1558        return P.p;
1559      }
1560    }
1561}
1562#endif
1563#ifdef REDTAIL_S
1564
1565static poly redNFTail (poly h,const int sl,kStrategy strat, int len)
1566{
1567  if (h==NULL) return NULL;
1568  pTest(h);
1569  if (0 > sl)
1570    return h;
1571  if (pNext(h)==NULL) return h;
1572
1573  int j;
1574  poly res=h;
1575  poly act=res;
1576  LObject P(pNext(h));
1577  pNext(res)=NULL;
1578  P.bucket = kBucketCreate(currRing);
1579  len--;
1580  h=P.p;
1581  if (len <=0) len=pLength(h);
1582  kBucketInit(P.bucket,h /*P.p*/,len /*pLength(P.p)*/);
1583  pTest(h);
1584  loop
1585    {
1586      P.p=h;
1587      P.t_p=NULL;
1588      P.SetShortExpVector();
1589      loop
1590        {
1591          j=kFindDivisibleByInS(strat->S,strat->sevS,sl,&P);
1592          if (j>=0)
1593          {
1594#ifdef REDTAIL_PROT
1595            PrintS("r");
1596#endif
1597            nNormalize(pGetCoeff(P.p));
1598#ifdef KDEBUG
1599            if (TEST_OPT_DEBUG)
1600            {
1601              PrintS("red tail:");
1602              wrp(h);
1603              PrintS(" with ");
1604              wrp(strat->S[j]);
1605            }
1606#endif
1607            number coef;
1608            pTest(strat->S[j]);
1609            coef=kBucketPolyRed(P.bucket,strat->S[j],
1610                                strat->lenS[j]/*pLength(strat->S[j])*/,strat->kNoether);
1611            pMult_nn(res,coef);
1612            nDelete(&coef);
1613            h = kBucketGetLm(P.bucket);
1614            pTest(h);
1615            if (h==NULL)
1616            {
1617#ifdef REDTAIL_PROT
1618              PrintS(" ");
1619#endif
1620              return res;
1621            }
1622            pTest(h);
1623            P.p=h;
1624            P.t_p=NULL;
1625            P.SetShortExpVector();
1626#ifdef KDEBUG
1627            if (TEST_OPT_DEBUG)
1628            {
1629              PrintS("\nto tail:");
1630              wrp(h);
1631              PrintLn();
1632            }
1633#endif
1634          }
1635          else
1636          {
1637#ifdef REDTAIL_PROT
1638            PrintS("n");
1639#endif
1640            break;
1641          }
1642        } /* end loop current mon */
1643      poly tmp=pHead(h /*kBucketGetLm(P.bucket)*/);
1644      act->next=tmp;pIter(act);
1645      poly tmp2=pHead(h);
1646      pNeg(tmp2);
1647      int ltmp2=1;
1648      pTest(tmp2);
1649      kBucket_Add_q(P.bucket, tmp2, &ltmp2);
1650
1651      h = kBucketGetLm(P.bucket);
1652      if (h==NULL)
1653      {
1654#ifdef REDTAIL_PROT
1655        PrintS(" ");
1656#endif
1657        return res;
1658      }
1659      pTest(h);
1660    }
1661}
1662#endif
1663
1664static void do_this_spoly_stuff(int i,int j,calc_dat* c){
1665  poly f=c->S->m[i];
1666  poly g=c->S->m[j];
1667  poly h=ksOldCreateSpoly(f, g, NULL, c->r);
1668  poly hr=NULL;
1669#ifdef FULLREDUCTIONS
1670  if (h!=NULL)
1671  {
1672    int len;
1673
1674//    hr=redNF2(h,c,len);
1675//      hr=redNF(h,c->strat,len);
1676
1677    if (hr!=NULL)
1678#ifdef REDTAIL_S
1679      hr = redNFTail(hr,c->strat->sl,c->strat,len);
1680#else
1681    hr = redtailBba(hr,c->strat->sl,c->strat);
1682#endif
1683
1684  }
1685#else
1686  if (h!=NULL)
1687  {
1688    int len;
1689//    hr=redNF2(h,c,len);
1690  }
1691#endif
1692  c->normal_forms++;
1693  if (hr==NULL)
1694  {
1695    notice_miss(i, j, c);
1696
1697  }
1698  else
1699  {
1700
1701#ifdef HEAD_BIN
1702    hr=p_MoveHead(hr,c->HeadBin);
1703#endif
1704    add_to_basis(hr, i,j,c);
1705  }
1706}
1707//try to fill, return FALSE iff queue is empty
1708
1709static int poly_crit(const void* ap1, const void* ap2){
1710  poly p1,p2;
1711  p1=*((poly*) ap1);
1712  p2=*((poly*)ap2);
1713
1714  int c=pLmCmp(p1,p2);
1715  if (c !=0) return c;
1716  int l1=pLength(p1);
1717  int l2=pLength(p2);
1718  if (l1<l2) return -1;
1719  if (l1>l2) return 1;
1720  return 0;
1721}
1722ideal t_rep_gb(ring r,ideal arg_I, ideal arg_debug_Ideal){
1723  debug_Ideal=arg_debug_Ideal;
1724  if (debug_Ideal) PrintS("DebugIdeal received\n");
1725   Print("Idelems %i \n----------\n",IDELEMS(arg_I));
1726  ideal I=idCompactify(arg_I);
1727  qsort(I->m,IDELEMS(I),sizeof(poly),poly_crit);
1728  Print("Idelems %i \n----------\n",IDELEMS(I));
1729  calc_dat* c=(calc_dat*) omalloc(sizeof(calc_dat));
1730  c->r=currRing;
1731  void* h;
1732  poly hp;
1733  int i,j;
1734  c->easy_product_crit=0;
1735  c->extended_product_crit=0;
1736  c->is_char0=(rChar()==0);
1737  c->reduction_steps=0;
1738  c->last_index=-1;
1739
1740
1741
1742  c->Rcounter=0;
1743
1744  c->soon_free=NULL;
1745
1746
1747  c->normal_forms=0;
1748  c->current_degree=1;
1749 
1750  c->max_pairs=5*I->idelems();
1751 
1752  c->apairs=(sorted_pair_node**) omalloc(sizeof(sorted_pair_node*)*c->max_pairs);
1753  c->pair_top=-1;
1754  int n=I->idelems();
1755  for (i=0;i<n;i++){
1756    wrp(I->m[i]);
1757    PrintS("\n");
1758  }
1759    i=0;
1760  c->n=0;
1761  c->T_deg=(int*) omalloc(n*sizeof(int));
1762 
1763#ifdef HEAD_BIN
1764  c->HeadBin=omGetSpecBin(POLYSIZE + (currRing->ExpL_Size)*sizeof(long));
1765#endif
1766  /* omUnGetSpecBin(&(c->HeadBin)); */
1767  h=omalloc(n*sizeof(char*));
1768  c->states=(char**) h;
1769  h=omalloc(n*sizeof(int));
1770  c->lengths=(int*) h;
1771  h=omalloc(n*sizeof(int));
1772        c->gcd_of_terms=(poly*) omalloc(n*sizeof(poly));
1773  c->rep=(int*) h;
1774  c->short_Exps=(long*) omalloc(n*sizeof(long));
1775  c->S=idInit(n,1);
1776  c->strat=new skStrategy;
1777  c->strat->syzComp = 0;
1778  initBuchMoraCrit(c->strat);
1779  initBuchMoraPos(c->strat);
1780  c->strat->initEcart = initEcartBBA;
1781  c->strat->enterS = enterSBba;
1782  c->strat->sl = -1;
1783  i=n;
1784  /* initS(c->S,NULL,c->strat); */
1785/* intS start: */
1786  i=((i+IDELEMS(c->S)+15)/16)*16;
1787  c->strat->ecartS=(intset)omAlloc(i*sizeof(int)); /*initec(i);*/
1788  c->strat->sevS=(unsigned long*)omAlloc0(i*sizeof(unsigned long));
1789  /*initsevS(i);*/
1790  c->strat->S_2_R=(int*)omAlloc0(i*sizeof(int));/*initS_2_R(i);*/
1791  c->strat->fromQ=NULL;
1792  c->strat->Shdl=idInit(1,1);
1793  c->strat->S=c->strat->Shdl->m;
1794  c->strat->lenS=(int*)omAlloc0(i*sizeof(int));
1795  if(c->is_char0)
1796    c->strat->lenSw=(int*)omAlloc0(i*sizeof(int));
1797  else
1798    c->strat->lenSw=NULL;
1799  sorted_pair_node* si;
1800  assume(n>0);
1801  add_to_basis(I->m[0],-1,-1,c);
1802
1803  assume(c->strat->sl==c->strat->Shdl->idelems()-1);
1804
1805  for (i=1;i<n;i++)//the 1 is wanted, because first element is added to basis
1806   {
1807//     add_to_basis(I->m[i],-1,-1,c);
1808     si=(sorted_pair_node*) omalloc(sizeof(sorted_pair_node));
1809      si->i=-1;
1810      si->j=-1;
1811      si->expected_length=pLength(I->m[i]);
1812      si->deg=pTotaldegree(I->m[i]);
1813      si->lcm_of_lm=I->m[i];
1814
1815//      c->apairs[n-1-i]=si;
1816      c->apairs[n-i-1]=si;
1817      ++(c->pair_top);
1818   }
1819 
1820
1821  while(c->pair_top>=0)
1822    go_on(c);
1823
1824  for(int z=0;z<c->n;z++){
1825    omfree(c->states[z]);
1826  }
1827  omfree(c->states);
1828  omfree(c->lengths);
1829
1830
1831  omfree(c->short_Exps);
1832  omfree(c->T_deg);
1833
1834     omFree(c->strat->ecartS);
1835     omFree(c->strat->sevS);
1836//   /*initsevS(i);*/
1837   omFree(c->strat->S_2_R);
1838   
1839
1840  omFree(c->strat->lenS);
1841
1842   if(c->strat->lenSw)  omFree(c->strat->lenSw);
1843
1844
1845
1846
1847  for(i=0;i<c->n;i++){
1848    if(c->gcd_of_terms[i])
1849      pDelete(&(c->gcd_of_terms[i]));
1850  }
1851  omfree(c->gcd_of_terms);
1852
1853  omfree(c->apairs);
1854  printf("calculated %d NFs\n",c->normal_forms);
1855  printf("applied %i product crit, %i extended_product crit \n", c->easy_product_crit, c->extended_product_crit);
1856  int deleted_form_c_s=0;
1857
1858  for(i=0;i<c->n;i++){
1859    if (c->rep[i]!=i){
1860      for(j=0;j<=c->strat->sl;j++){
1861        if(c->strat->S[j]==c->S->m[i]){
1862          c->strat->S[j]=NULL;
1863          break;
1864        }
1865      }
1866//      PrintS("R_delete");
1867      pDelete(&c->S->m[i]);
1868    }
1869  }
1870  for(i=0;i<=c->strat->sl;i++){
1871    if (!c->strat->S[i]) continue;
1872    BOOLEAN found=FALSE;
1873    for(j=0;j<c->n;j++){
1874      if (c->S->m[j]==c->strat->S[i]){
1875        found=TRUE;
1876        break;
1877      }
1878    }
1879    if(!found) pDelete(&c->strat->S[i]);
1880  }
1881  omfree(c->rep);
1882  I=c->S;
1883 
1884  IDELEMS(I)=c->n;
1885
1886  idSkipZeroes(c->S);
1887  for(i=0;i<=c->strat->sl;i++)
1888    c->strat->S[i]=NULL;
1889  id_Delete(&c->strat->Shdl,c->r);
1890  delete c->strat;
1891  omfree(c);
1892
1893  return(I);
1894}
1895static void now_t_rep(const int & arg_i, const int & arg_j, calc_dat* c){
1896  int i,j;
1897  if (arg_i==arg_j){
1898    return;
1899  }
1900  if (arg_i>arg_j){
1901    i=arg_j;
1902    j=arg_i;
1903  } else {
1904    i=arg_i;
1905    j=arg_j;
1906  }
1907  c->states[j][i]=HASTREP;
1908}
1909static void soon_t_rep(const int& arg_i, const int& arg_j, calc_dat* c)
1910{
1911  assume(0<=arg_i);
1912  assume(0<=arg_j);
1913  assume(arg_i<c->n);
1914  assume(arg_j<c->n);
1915  int i,j;
1916  if (arg_i==arg_j){
1917    return;
1918  }
1919  if (arg_i>arg_j){
1920    i=arg_j;
1921    j=arg_i;
1922  } else {
1923    i=arg_i;
1924    j=arg_j;
1925  }
1926  if (!
1927      (c->states[j][i]==HASTREP))
1928    c->states[j][i]=SOONTREP;
1929}
1930static BOOLEAN has_t_rep(const int & arg_i, const  int & arg_j, calc_dat* state){
1931  assume(0<=arg_i);
1932  assume(0<=arg_j);
1933  assume(arg_i<state->n);
1934  assume(arg_j<state->n);
1935  if (arg_i==arg_j)
1936  {
1937    return (TRUE);
1938  }
1939  if (arg_i>arg_j)
1940  {
1941    return (state->states[arg_i][arg_j]==HASTREP);
1942  } else
1943  {
1944    return (state->states[arg_j][arg_i]==HASTREP);
1945  }
1946}
1947static int pLcmDeg(poly a, poly b)
1948{
1949  int i;
1950  int n=0;
1951  for (i=pVariables; i; i--)
1952  {
1953    n+=max( pGetExp(a,i), pGetExp(b,i));
1954  }
1955  return n;
1956
1957}
1958
1959
1960
1961static void shorten_tails(calc_dat* c, poly monom)
1962{
1963  return;
1964// BOOLEAN corr=lenS_correct(c->strat);
1965  for(int i=0;i<c->n;i++)
1966  {
1967    //enter tail
1968    if (c->rep[i]!=i) continue;
1969    if (c->S->m[i]==NULL) continue;
1970    poly tail=c->S->m[i]->next;
1971    poly prev=c->S->m[i];
1972    BOOLEAN did_something=FALSE;
1973    while((tail!=NULL)&& (pLmCmp(tail, monom)>=0))
1974    {
1975      if (p_LmDivisibleBy(monom,tail,c->r))
1976      {
1977        did_something=TRUE;
1978        prev->next=tail->next;
1979        tail->next=NULL;
1980        p_Delete(& tail,c->r);
1981        tail=prev;
1982        //PrintS("Shortened");
1983        c->lengths[i]--;
1984      }
1985      prev=tail;
1986      tail=tail->next;
1987    }
1988    if (did_something)
1989    {
1990      int new_pos;
1991      int q;
1992      q=quality(c->S->m[i],c->lengths[i],c);
1993      new_pos=simple_posInS(c->strat,c->S->m[i],q,c->is_char0);
1994
1995      int old_pos=-1;
1996      //assume new_pos<old_pos
1997      for (int z=0;z<=c->strat->sl;z++)
1998      {
1999        if (c->strat->S[z]==c->S->m[i])
2000        {
2001          old_pos=z;
2002          break;
2003        }
2004      }
2005      if (old_pos== -1)
2006        for (int z=new_pos-1;z>=0;z--)
2007        {
2008          if (c->strat->S[z]==c->S->m[i])
2009          {
2010            old_pos=z;
2011            break;
2012          }
2013        }
2014      assume(old_pos>=0);
2015      assume(new_pos<=old_pos);
2016      assume(pLength(c->strat->S[old_pos])==c->lengths[i]);
2017      c->strat->lenS[old_pos]=c->lengths[i];
2018      if (c->strat->lenSw)
2019        c->strat->lenSw[old_pos]=q;
2020
2021      if (new_pos<old_pos)
2022        move_forward_in_S(old_pos,new_pos,c->strat, c->is_char0);
2023
2024      length_one_crit(c,i,c->lengths[i]);
2025    }
2026  }
2027}
2028static sorted_pair_node* pop_pair(calc_dat* c){
2029  clean_top_of_pair_list(c);
2030
2031  if(c->pair_top<0) return NULL;
2032  else return (c->apairs[c->pair_top--]);
2033}
2034static sorted_pair_node* top_pair(calc_dat* c){
2035  super_clean_top_of_pair_list(c);//yeah, I know, it's odd that I use a different proc here
2036
2037  if(c->pair_top<0) return NULL;
2038  else return (c->apairs[c->pair_top]);
2039}
2040static sorted_pair_node* quick_pop_pair(calc_dat* c){
2041  if(c->pair_top<0) return NULL;
2042  else return (c->apairs[c->pair_top--]);
2043}
2044static BOOLEAN no_pairs(calc_dat* c){
2045  clean_top_of_pair_list(c);
2046  return (c->pair_top==-1);
2047}
2048
2049
2050static void super_clean_top_of_pair_list(calc_dat* c){
2051  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))){
2052
2053    free_sorted_pair_node(c->apairs[c->pair_top],c->r);
2054    c->pair_top--;
2055
2056  }
2057}
2058static void clean_top_of_pair_list(calc_dat* c){
2059  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))){
2060
2061    free_sorted_pair_node(c->apairs[c->pair_top],c->r);
2062    c->pair_top--;
2063
2064  }
2065}
2066static BOOLEAN state_is(calc_state state, const int & arg_i, const  int & arg_j, calc_dat* c){
2067  assume(0<=arg_i);
2068  assume(0<=arg_j);
2069  assume(arg_i<c->n);
2070  assume(arg_j<c->n);
2071  if (arg_i==arg_j)
2072  {
2073    return (TRUE);
2074  }
2075  if (arg_i>arg_j)
2076  {
2077    return (c->states[arg_i][arg_j]==state);
2078  }
2079  else return(c->states[arg_j][arg_i]==state);
2080}
2081static void free_sorted_pair_node(sorted_pair_node* s, ring r){
2082  if (s->i>=0)
2083    p_Delete(&s->lcm_of_lm,r);
2084  omfree(s);
2085}
2086static BOOLEAN pair_better(sorted_pair_node* a,sorted_pair_node* b, calc_dat* c){
2087  if (a->deg<b->deg) return TRUE;
2088  if (a->deg>b->deg) return FALSE;
2089
2090  if (a->expected_length<b->expected_length) return TRUE;
2091  if (a->expected_length>b->expected_length) return FALSE;
2092  int comp=pLmCmp(a->lcm_of_lm, b->lcm_of_lm);
2093  if (comp==1) return FALSE;
2094  if (-1==comp) return TRUE;
2095  if (a->i<b->i) return TRUE;
2096  if (a->j<b->j) return TRUE;
2097  return FALSE;
2098}
2099
2100static int pair_better_gen(const void* ap,const void* bp){
2101
2102  sorted_pair_node* a=*((sorted_pair_node**)ap);
2103  sorted_pair_node* b=*((sorted_pair_node**)bp);
2104  assume(a->i>a->j);
2105  assume(b->i>b->j);
2106  if (a->deg<b->deg) return -1;
2107  if (a->deg>b->deg) return 1;
2108
2109
2110  if (a->expected_length<b->expected_length) return -1;
2111  if (a->expected_length>b->expected_length) return 1;
2112 int comp=pLmCmp(a->lcm_of_lm, b->lcm_of_lm);
2113 
2114  if (comp==1) return 1;
2115  if (-1==comp) return -1;
2116  if (a->i<b->i) return -1;
2117  if (a->j<b->j) return -1;
2118  return 0;
2119}
2120
2121
2122static poly gcd_of_terms(poly p, ring r){
2123  int max_g_0=0;
2124  assume(p!=NULL);
2125  int i;
2126  poly m=pOne();
2127  poly t;
2128  for (i=pVariables; i; i--)
2129  {
2130      pSetExp(m,i, pGetExp(p,i));
2131      if (max_g_0==0)
2132        if (pGetExp(m,i)>0)
2133          max_g_0=i;
2134  }
2135 
2136  t=p->next;
2137  while (t!=NULL){
2138   
2139    if (max_g_0==0) break;
2140    for (i=pVariables; i; i--)
2141    {
2142      pSetExp(m,i, min(pGetExp(t,i),pGetExp(m,i)));
2143      if (max_g_0==i)
2144        if (pGetExp(m,i)==0)
2145          max_g_0=0;
2146      if ((max_g_0==0) && (pGetExp(m,i)>0)){
2147        max_g_0=i;
2148      }
2149    }
2150                t=t->next;
2151  }
2152        for (i=pVariables;i;i--)
2153        {
2154                if(pGetExp(m,i)>0)
2155                        return m;
2156  }
2157        pDelete(&m);
2158  return NULL;
2159}
2160static BOOLEAN pHasNotCFExtended(poly p1, poly p2, poly m)
2161{
2162
2163  if (pGetComp(p1) > 0 || pGetComp(p2) > 0)
2164    return FALSE;
2165  int i = 1;
2166  loop
2167  {
2168    if ((pGetExp(p1, i)-pGetExp(m,i) >0) && (pGetExp(p2, i) -pGetExp(m,i)> 0))   return FALSE;
2169    if (i == pVariables)                                return TRUE;
2170    i++;
2171  }
2172}
2173
2174
2175//for impl reasons may return false if the the normal product criterion matches
2176static BOOLEAN extended_product_criterion(poly p1, poly gcd1, poly p2, poly gcd2, calc_dat* c){
2177  if(gcd1==NULL) return FALSE;
2178        if(gcd2==NULL) return FALSE;
2179        gcd1->next=gcd2; //may ordered incorrect
2180        poly m=gcd_of_terms(gcd1,c->r);
2181        gcd1->next=NULL;
2182        if (m==NULL) return FALSE;
2183
2184        BOOLEAN erg=pHasNotCFExtended(p1,p2,m);
2185        pDelete(&m);
2186        return erg;
2187}
2188static poly kBucketGcd(kBucket* b, ring r)
2189{
2190  int s=0;
2191  int i;
2192  poly m, n;
2193  BOOLEAN initialized=FALSE;
2194  for (i=MAX_BUCKET-1;i>=0;i--)
2195  { 
2196    if (b->buckets[i]!=NULL){
2197      if (!initialized){
2198        m=gcd_of_terms(b->buckets[i],r);
2199        initialized=TRUE;
2200        if (m==NULL) return NULL;
2201      }
2202      else
2203        {
2204          n=gcd_of_terms(b->buckets[i],r);
2205          if (n==NULL) {
2206            pDelete(&m);
2207            return NULL;   
2208          }
2209          n->next=m;
2210          poly t=gcd_of_terms(n,r);
2211          n->next=NULL;
2212          pDelete(&m);
2213          pDelete(&n);
2214          m=t;
2215          if (m==NULL) return NULL;
2216         
2217        }
2218    }
2219  }
2220  return m;
2221}
2222
2223
2224
2225static int guess_quality(const red_object & p, calc_dat* c){
2226  //looks only on bucket
2227  if (c->is_char0) return kSBucketLength(p.bucket);
2228  return (bucket_guess(p.bucket));
2229}
2230static int quality_of_pos_in_strat_S(int pos, calc_dat* c){
2231  if (c->is_char0) return c->strat->lenSw[pos];
2232  return c->strat->lenS[pos];
2233}
2234static int quality(poly p, int len, calc_dat* c){
2235  if (c->is_char0) return pSLength(p,len);
2236  return pLength(p);
2237}
2238static void multi_reduction_lls_trick(red_object* los, int losl,calc_dat* c,find_erg & erg){
2239  erg.expand=NULL;
2240  BOOLEAN swap_roles; //from reduce_by, to_reduce_u if fromS
2241  if(erg.fromS){
2242    if(pLmEqual(c->strat->S[erg.reduce_by],los[erg.to_reduce_u].p))
2243    {
2244      int i;
2245      int quality_a=quality_of_pos_in_strat_S(erg.reduce_by,c);
2246      int best=erg.to_reduce_u+1;
2247/*
2248      for (i=erg.to_reduce_u;i>=erg.to_reduce_l;i--){
2249        int qc=los[i].guess_quality(c);
2250        if (qc<quality_a){
2251          best=i;
2252          quality_a=qc;
2253        }
2254      }
2255      if(best!=erg.to_reduce_u+1){*/
2256      int qc;
2257      best=find_best(los,erg.to_reduce_l,erg.to_reduce_u,qc,c);
2258      assume(qc==los[best].guess_quality(c));
2259      if(qc<quality_a){
2260        red_object h=los[erg.to_reduce_u];
2261        los[erg.to_reduce_u]=los[best];
2262        los[best]=h;
2263        swap_roles=TRUE;
2264      }
2265      else{
2266       
2267        swap_roles=FALSE;
2268      }
2269 
2270    }
2271      else
2272    {
2273      if (erg.to_reduce_u>erg.to_reduce_l){
2274
2275        int i;
2276        int quality_a=quality_of_pos_in_strat_S(erg.reduce_by,c);
2277        int best=erg.to_reduce_u+1;
2278        int qc;
2279        best=find_best(los,erg.to_reduce_l,erg.to_reduce_u,qc,c);
2280        assume(qc==los[best].guess_quality(c));
2281        if(qc<quality_a){
2282          //(best!=erg.to_reduce_u+1){
2283          red_object h=los[erg.to_reduce_l];
2284          los[erg.to_reduce_l]=los[best];
2285          los[best]=h;
2286          erg.reduce_by=erg.to_reduce_l;
2287          erg.fromS=FALSE;
2288          erg.to_reduce_l++;
2289         
2290        }
2291      }
2292      else 
2293      {
2294        assume(erg.to_reduce_u==erg.to_reduce_l);
2295        int quality_a=quality_of_pos_in_strat_S(erg.reduce_by,c);
2296        int qc=los[erg.to_reduce_u].guess_quality(c);
2297        if(qc<quality_a){
2298          BOOLEAN exp=FALSE;
2299          if(qc<=2)
2300            exp=TRUE;
2301          else {
2302            if (qc<quality_a/2)
2303              exp=TRUE;
2304            else
2305              if(erg.reduce_by<c->n/4)
2306                exp=TRUE;
2307          }
2308          if (exp){
2309            poly clear_into;
2310            los[erg.to_reduce_u].flatten();
2311            kBucketClear(los[erg.to_reduce_u].bucket,&clear_into,&erg.expand_length);
2312            erg.expand=pCopy(clear_into);
2313            kBucketInit(los[erg.to_reduce_u].bucket,clear_into,erg.expand_length);
2314            PrintS("e");
2315           
2316          }
2317        }
2318
2319       
2320      }
2321     
2322      swap_roles=FALSE;
2323      return;
2324      }
2325   
2326  }
2327  else{
2328    if(erg.reduce_by>erg.to_reduce_u){
2329      //then lm(rb)>= lm(tru) so =
2330      assume(erg.reduce_by==erg.to_reduce_u+1);
2331      int best=erg.reduce_by;
2332      int quality_a=los[erg.reduce_by].guess_quality(c);
2333      int qc;
2334      best=find_best(los,erg.to_reduce_l,erg.to_reduce_u,qc,c);
2335     
2336      int i;
2337      if(qc<quality_a){
2338          red_object h=los[erg.reduce_by];
2339          los[erg.reduce_by]=los[best];
2340          los[best]=h;
2341        }
2342        swap_roles=FALSE;
2343        return;
2344       
2345         
2346    }
2347    else
2348    {
2349      assume(!pLmEqual(los[erg.reduce_by].p,los[erg.to_reduce_l].p));
2350      //further assume, that reduce_by is the above all other polys
2351      //with same leading term
2352      int il=erg.reduce_by;
2353      int quality_a =los[erg.reduce_by].guess_quality(c);
2354      int qc;
2355      while((il>0) && pLmEqual(los[il-1].p,los[il].p)){
2356        il--;
2357        qc=los[il].guess_quality(c);
2358        if (qc<quality_a){
2359          quality_a=qc;
2360          erg.reduce_by=il;
2361        }
2362      }
2363      swap_roles=FALSE;
2364    }
2365 
2366  }
2367  if(swap_roles){
2368    PrintS("b");
2369    poly clear_into;
2370    int dummy_len;
2371    int new_length;
2372    int bp=erg.to_reduce_u;//bucket_positon
2373    //kBucketClear(los[bp].bucket,&clear_into,&new_length);
2374    new_length=los[bp].clear_to_poly();
2375    clear_into=los[bp].p;
2376    poly p=c->strat->S[erg.reduce_by];
2377    int j=erg.reduce_by;
2378    int old_length=c->strat->lenS[j];// in view of S
2379    los[bp].p=p;
2380    kBucketInit(los[bp].bucket,p,old_length);
2381    int qal=quality(clear_into,new_length,c);
2382    int pos_in_c=-1;   
2383    int z;
2384    int new_pos;
2385    new_pos=simple_posInS(c->strat,clear_into,qal,c->is_char0);
2386    assume(new_pos<=j);
2387    for (z=c->n;z;z--)
2388    {
2389      if(p==c->S->m[z-1])
2390      {
2391        pos_in_c=z-1;
2392        break;
2393      }
2394    }
2395    if(pos_in_c>=0)
2396    {
2397      c->S->m[pos_in_c]=clear_into;
2398      c->lengths[pos_in_c]=new_length;
2399      c_S_element_changed_hook(pos_in_c,c);
2400    }
2401    c->strat->S[j]=clear_into;
2402    c->strat->lenS[j]=new_length;
2403    if(c->strat->lenSw)
2404      c->strat->lenS[j]=qal;
2405    if(c->is_char0)
2406    {
2407      pContent(clear_into);
2408      pCleardenom(clear_into);
2409    }
2410  else                     
2411    pNorm(clear_into);
2412    if (new_pos<j){
2413      move_forward_in_S(j,new_pos,c->strat,c->is_char0);
2414      erg.reduce_by=new_pos;
2415    }
2416  }
2417}
2418static void multi_reduction_find(red_object* los, int losl,calc_dat* c,int startf,find_erg & erg){
2419  kStrategy strat=c->strat;
2420
2421  assume(startf<=losl);
2422  assume((startf==losl-1)||(pLmCmp(los[startf].p,los[startf+1].p)==-1));
2423  int i=startf;
2424 
2425  int j;
2426  while(i>=0){
2427    assume((i==losl-1)||(pLmCmp(los[i].p,los[i+1].p)<=0));
2428    assume(is_valid_ro(los[i]));
2429    j=kFindDivisibleByInS_easy(strat,los[i]);
2430    if(j>=0){
2431     
2432      erg.to_reduce_u=i;
2433      erg.reduce_by=j;
2434      erg.fromS=TRUE;
2435      int i2;
2436      for(i2=i-1;i2>=0;i2--){
2437        if(!pLmEqual(los[i].p,los[i2].p))
2438          break;
2439      }
2440     
2441      erg.to_reduce_l=i2+1;
2442      assume((i==losl-1)||(pLmCmp(los[i].p,los[i+1].p)==-1));
2443      return;
2444    }
2445    if (j<0){
2446     
2447      //not reduceable, try to use this for reducing higher terms
2448      int i2;
2449      i2=i;
2450      while((i2>0)&&(pLmEqual(los[i].p,los[i2-1].p)))
2451        i2--;
2452      if(i2!=i){
2453       
2454        erg.to_reduce_u=i-1;
2455        erg.to_reduce_l=i2;
2456        erg.reduce_by=i;
2457        erg.fromS=FALSE;
2458        assume((i==losl-1)||(pLmCmp(los[i].p,los[i+1].p)==-1));
2459        return;
2460      }
2461 
2462      for (i2=i+1;i2<losl;i2++){
2463        if (p_LmShortDivisibleBy(los[i].p,los[i].sev,los[i2].p,~los[i2].sev,
2464                                c->r)){
2465          int i3=i2;
2466          while((i3+1<losl) && (pLmEqual(los[i2].p, los[i3+1].p)))
2467            i3++;
2468          erg.to_reduce_u=i3;
2469          erg.to_reduce_l=i2;
2470          erg.reduce_by=i;
2471          erg.fromS=FALSE;
2472          assume((i==losl-1)||(pLmCmp(los[i].p,los[i+1].p)==-1));
2473          return;
2474        }
2475//      else {assume(!p_LmDivisibleBy(los[i].p, los[i2].p,c->r));}
2476      }
2477
2478      i--;
2479    }
2480  }
2481  erg.reduce_by=-1;//error code
2482  return;
2483}
2484
2485 //  nicht reduzierbare eintraege in ergebnisliste schreiben
2486//   nullen loeschen
2487//   while(finde_groessten leitterm reduzierbar(c,erg)){
2488 
2489static int multi_reduction_clear_zeroes(red_object* los, int  losl, int l, int u)
2490{
2491
2492
2493  int deleted=0;
2494  int  i=l;
2495  int last=-1;
2496  while(i<=u)
2497  {
2498   
2499    if(los[i].p==NULL){
2500      kBucketDestroy(&los[i].bucket);
2501//      delete los[i];//here we assume los are constructed with new
2502      //destroy resources, must be added here   
2503     if (last>=0)
2504     {
2505       memmove(los+(int)(last+1-deleted),los+(last+1),sizeof(red_object)*(i-1-last));
2506     }
2507     last=i;
2508     deleted++;
2509    }
2510    i++;
2511  }
2512  if((last>=0)&&(last!=losl-1))
2513      memmove(los+(int)(last+1-deleted),los+last+1,sizeof(red_object)*(losl-1-last));
2514  return deleted;
2515 
2516}
2517
2518static void sort_region_down(red_object* los, int l, int u, calc_dat* c)
2519{
2520  qsort(los+l,u-l+1,sizeof(red_object),red_object_better_gen);
2521  int i;
2522
2523  for(i=l;i<=u;i++)
2524  {
2525    BOOLEAN moved=FALSE;
2526    int j;
2527    for(j=i;j;j--)
2528    {
2529      if(pLmCmp(los[j].p,los[j-1].p)==-1){
2530        red_object h=los[j];
2531        los[j]=los[j-1];
2532        los[j-1]=h;
2533        moved=TRUE;
2534      }
2535      else break;
2536    }
2537    if(!moved) return;
2538  }
2539}
2540
2541//assume that los is ordered ascending by leading term, all non zero
2542static void multi_reduction(red_object* los, int & losl, calc_dat* c)
2543{
2544 
2545  //initialize;
2546  assume(c->strat->sl>=0);
2547  assume(losl>0);
2548  int i;
2549  for(i=0;i<losl;i++){
2550    los[i].sev=pGetShortExpVector(los[i].p);
2551//SetShortExpVector();
2552    los[i].p=kBucketGetLm(los[i].bucket);
2553  }
2554
2555  kStrategy strat=c->strat;
2556  int curr_pos=losl-1;
2557
2558
2559//  nicht reduzierbare einträge in ergebnisliste schreiben
2560  // nullen loeschen
2561  while(curr_pos>=0){
2562   
2563    find_erg erg;
2564    multi_reduction_find(los, losl,c,curr_pos,erg);//last argument should be curr_pos
2565   //  PrintS("\n erg:\n");
2566//     Print("upper:%i\n",erg.to_reduce_u);
2567//     Print("lower:%i\n",erg.to_reduce_l);
2568//     Print("reduce_by:%i\n",erg.reduce_by);
2569//     Print("fromS:%i\n",erg.fromS);
2570    if(erg.reduce_by<0) break;
2571
2572
2573
2574    erg.expand=NULL;
2575    int d=erg.to_reduce_u-erg.to_reduce_l+1;
2576    //if ((!erg.fromS)&&(d>100)){
2577    if (0){
2578      PrintS("L");
2579      if(!erg.fromS){
2580        erg.to_reduce_u=max(erg.to_reduce_u,erg.reduce_by);
2581        if (pLmEqual(los[erg.reduce_by].p,los[erg.to_reduce_l].p))
2582          erg.to_reduce_l=min(erg.to_reduce_l,erg.reduce_by);
2583      }
2584      int pn=erg.to_reduce_u+1-erg.to_reduce_l;
2585      poly* p=(poly*) omalloc((pn)*sizeof(poly));
2586      int i;
2587      for(i=0;i<pn;i++){
2588        int len;
2589        los[erg.to_reduce_l+i].flatten();
2590        kBucketClear(los[erg.to_reduce_l+i].bucket,&p[i],&len);
2591       
2592        redTailShort(p[i],c->strat);
2593      }
2594      pre_comp(p,pn,c);
2595      int j;
2596      for(j=0;j<pn;j++){
2597        los[erg.to_reduce_l+j].p=p[j];
2598        los[erg.to_reduce_l+j].sev=pGetShortExpVector(p[j]);
2599        los[erg.to_reduce_l+j].sum=NULL;
2600        int len=pLength(p[j]);
2601        kBucketInit(los[erg.to_reduce_l+j].bucket,los[erg.to_reduce_l+j].p,len);
2602      }
2603      for(j=erg.to_reduce_l+pn;j<=erg.to_reduce_u;j++){
2604        los[j].p=NULL;
2605       
2606      }
2607
2608      omfree(p);
2609    }
2610    else {
2611    multi_reduction_lls_trick(los,losl,c,erg);
2612    int sum=0;
2613
2614   
2615    int i;
2616    int len;
2617   
2618    multi_reduce_step(erg,los,c);
2619    }
2620//     reduction_step *rs=create_reduction_step(erg, los, c);
2621//     rs->reduce(los,erg.to_reduce_l,erg.to_reduce_u);
2622//     finalize_reduction_step(rs);
2623                 
2624    int deleted=multi_reduction_clear_zeroes(los, losl, erg.to_reduce_l, erg.to_reduce_u);
2625    curr_pos=erg.to_reduce_u;
2626    losl -= deleted;
2627    curr_pos -= deleted;
2628
2629    //Print("deleted %i \n",deleted);
2630    sort_region_down(los, erg.to_reduce_l, erg.to_reduce_u-deleted, c);
2631//   sort_region_down(los, 0, losl-1, c);
2632    //  qsort(los,losl,sizeof(red_object),red_object_better_gen);
2633    if(erg.expand)
2634      add_to_reductors(c,erg.expand,erg.expand_length);
2635  }
2636  return;
2637}
2638void red_object::flatten(){
2639  if (sum!=NULL)
2640  {
2641
2642 
2643    if(kBucketGetLm(sum->ac->bucket)!=NULL){
2644      number mult_my=n_Mult(sum->c_my,sum->ac->multiplied,currRing);
2645      poly add_this;
2646      if(!nIsOne(mult_my))
2647        kBucket_Mult_n(bucket,mult_my);
2648      int len;
2649      poly clear_into;
2650      kBucketClear(sum->ac->bucket,&clear_into,&len);
2651      if(sum->ac->counter>1){
2652        add_this=pCopy(clear_into);
2653        kBucketInit(sum->ac->bucket,clear_into,len);
2654      }
2655      else
2656        add_this=clear_into;
2657      pMult_nn(add_this, sum->c_ac);
2658     
2659      kBucket_Add_q(bucket,add_this, &len);
2660       nDelete(&mult_my);
2661     
2662    }
2663    nDelete(&sum->c_ac);
2664    nDelete(&sum->c_my);
2665   
2666    sum->ac->decrease_counter();
2667    delete sum;
2668    p=kBucketGetLm(bucket);
2669    sum=NULL;
2670  }
2671  assume(p==kBucketGetLm(bucket));
2672  assume(sum==NULL);
2673}
2674void red_object::validate(){
2675  BOOLEAN flattened=FALSE;
2676  if(sum!=NULL)
2677  {
2678    poly lm=kBucketGetLm(bucket);
2679    poly lm_ac=kBucketGetLm(sum->ac->bucket);
2680    if ((lm_ac==NULL)||((lm!=NULL) && (pLmCmp(lm,lm_ac)!=-1))){
2681      flatten();
2682      assume(sum==NULL);
2683      flattened=TRUE;
2684      p=kBucketGetLm(bucket);
2685      if (p!=NULL)
2686        sev=pGetShortExpVector(p);
2687    } 
2688    else
2689    {
2690 
2691      p=lm_ac;
2692      assume(sum->ac->sev==pGetShortExpVector(p));
2693      sev=sum->ac->sev;
2694    }
2695   
2696  }
2697  else{
2698    p=kBucketGetLm(bucket);
2699    if(p)
2700    sev=pGetShortExpVector(p);
2701  }
2702  assume((sum==NULL)||(kBucketGetLm(sum->ac->bucket)!=NULL));
2703}
2704int red_object::clear_to_poly(){
2705  flatten();
2706  int l;
2707  kBucketClear(bucket,&p,&l);
2708  return l;
2709}
2710
2711 
2712
2713void red_object::adjust_coefs(number c_r, number c_ac_r){
2714  assume(this->sum!=NULL);
2715  number n1=nMult(sum->c_my, c_ac_r);
2716  number n2=nMult(sum->c_ac,c_r);
2717  nDelete(&sum->c_my);
2718  nDelete(&sum->c_ac);
2719 
2720  int ct = ksCheckCoeff(&n1, &n2);
2721  sum->c_my=n1;
2722  sum->c_ac=nNeg(n2);
2723  nDelete(&n2);
2724 
2725
2726}
2727int red_object::guess_quality(calc_dat* c){
2728    //works at the moment only for lenvar 1, because in different
2729    //case, you have to look on coefs
2730    int s=0;
2731    if (c->is_char0)
2732      s=kSBucketLength(bucket);
2733    else 
2734      s=bucket_guess(bucket);
2735    if (sum!=NULL){
2736      if (c->is_char0)
2737      s+=kSBucketLength(sum->ac->bucket);
2738    else 
2739      s+=bucket_guess(sum->ac->bucket);
2740    }
2741    return s;
2742}
2743void reduction_step::reduce(red_object* r, int l, int u){}
2744void simple_reducer::target_is_no_sum_reduce(red_object & ro){
2745  kBucketPolyRed(ro.bucket,p,
2746                 p_len,
2747                 c->strat->kNoether);
2748}
2749
2750void simple_reducer::target_is_a_sum_reduce(red_object & ro){
2751  pTest(p);
2752  kbTest(ro.bucket);
2753  kbTest(ro.sum->ac->bucket);
2754  assume(ro.sum!=NULL);
2755  assume(ro.sum->ac!=NULL);
2756  if(ro.sum->ac->last_reduction_id!=reduction_id){
2757    number n1=kBucketPolyRed(ro.sum->ac->bucket,p, p_len, c->strat->kNoether);
2758    number n2=nMult(n1,ro.sum->ac->multiplied);
2759    nDelete(&ro.sum->ac->multiplied);
2760    nDelete(&n1);
2761    ro.sum->ac->multiplied=n2;
2762    poly lm=kBucketGetLm(ro.sum->ac->bucket);
2763    if (lm)
2764      ro.sum->ac->sev=pGetShortExpVector(lm);
2765    ro.sum->ac->last_reduction_id=reduction_id;
2766  }
2767  ro.sev=ro.sum->ac->sev;
2768  ro.p=kBucketGetLm(ro.sum->ac->bucket);
2769}
2770void simple_reducer::reduce(red_object* r, int l, int u){
2771  this->pre_reduce(r,l,u);
2772  int i;
2773//debug start
2774  int im;
2775//  for(im=l;im<=u;im++)
2776  //  assume(is_valid_ro(r[im]));
2777 
2778
2779//debug end
2780
2781  for(i=l;i<=u;i++){
2782 
2783
2784    if(r[i].sum==NULL)
2785      this->target_is_no_sum_reduce(r[i]);
2786
2787    else 
2788    {
2789      this->target_is_a_sum_reduce(r[i]);
2790      //reduce and adjust multiplied
2791      r[i].sum->ac->last_reduction_id=reduction_id;
2792     
2793    }
2794    //most elegant would be multimethods at this point and subclassing
2795    //red_object for sum
2796 
2797  }
2798  for(i=l;i<=u;i++){
2799    r[i].validate();
2800    #ifdef TGB_DEBUG
2801    if (r[i].sum) r[i].sev=r[i].sum->ac->sev;
2802
2803    #endif
2804      }
2805}
2806reduction_step::~reduction_step(){}
2807simple_reducer::~simple_reducer(){
2808  if(fill_back!=NULL)
2809  {
2810    kBucketInit(fill_back,p,p_len);
2811  }
2812  fill_back=NULL;
2813   
2814}
2815 join_simple_reducer::~join_simple_reducer(){
2816   if(fill_back!=NULL)
2817   {
2818     kBucketInit(fill_back,p,p_len);
2819   }
2820   fill_back=NULL;
2821   
2822}
2823void multi_reduce_step(find_erg & erg, red_object* r, calc_dat* c){
2824  static int id=0;
2825  id++;
2826
2827  int rn=erg.reduce_by;
2828  poly red;
2829  int red_len;
2830  simple_reducer* pointer;
2831  BOOLEAN woc=FALSE;
2832  if(erg.fromS){
2833    red=c->strat->S[rn];
2834    red_len=c->strat->lenS[rn];
2835   
2836  }
2837  else
2838  {
2839    r[rn].flatten();
2840    kBucketClear(r[rn].bucket,&red,&red_len);
2841  }
2842  if (erg.to_reduce_u-erg.to_reduce_l>5){
2843    woc=TRUE;
2844    poly m=pOne();
2845    for(int i=1;i<=pVariables;i++)
2846      pSetExp(m,i,(pGetExp(r[erg.to_reduce_l].p, i)-pGetExp(red,i)));
2847    pSetm(m);
2848    poly red_cp=ppMult_mm(red,m);
2849   
2850    if(!erg.fromS){
2851      kBucketInit(r[rn].bucket,red,red_len);
2852    }
2853    //now reduce the copy
2854    //static poly redNF2 (poly h,calc_dat* c , int &len, number&  m,int n)
2855    redTailShort(red_cp,c->strat);
2856    //number mul;
2857    // red_len--;
2858//     red_cp->next=redNF2(red_cp->next,c,red_len,mul,c->average_length);
2859//     pSetCoeff(red_cp,nMult(red_cp->coef,mul));
2860//     nDelete(&mul);
2861//     red_len++;
2862    red=red_cp;
2863    red_len=pLength(red);
2864    pDelete(&m);
2865   
2866  }
2867  int i;
2868
2869
2870  int red_c=0;
2871  if(red_len>2*c->average_length){
2872    for(i=erg.to_reduce_l;i<=erg.to_reduce_u;i++){
2873      if((r[i].sum==NULL) ||(r[i].sum->ac->counter<=AC_FLATTEN)) red_c++;
2874    }
2875  }
2876  if (red_c>=AC_NEW_MIN)
2877    pointer=new join_simple_reducer(red,red_len,r[erg.to_reduce_l].p);
2878  else
2879    pointer=new simple_reducer(red,red_len,c);
2880
2881  if ((!woc) && (!erg.fromS))
2882    pointer->fill_back=r[rn].bucket;
2883  else
2884    pointer->fill_back=NULL;
2885  pointer->reduction_id=id;
2886  pointer->c=c;
2887
2888  pointer->reduce(r,erg.to_reduce_l, erg.to_reduce_u);
2889  if(woc) pDelete(&pointer->p);
2890  delete pointer;
2891 
2892};
2893
2894void join_simple_reducer::target_is_no_sum_reduce(red_object & ro){
2895 
2896  ro.sum=new formal_sum_descriptor();
2897  ro.sum->ac=ac;
2898  ac->counter++;
2899  kBucket_pt bucket=ro.bucket;
2900  poly a1 = pNext(p), lm = kBucketExtractLm(bucket);
2901  BOOLEAN reset_vec=FALSE;
2902  number rn;
2903  assume(a1!=NULL);
2904  number an = pGetCoeff(p), bn = pGetCoeff(lm);
2905  lm->next=NULL;
2906  int ct = ksCheckCoeff(&an, &bn);
2907  ro.sum->c_ac=nNeg(bn);
2908  ro.sum->c_my=an;
2909  assume(nIsZero(nAdd(nMult(ro.sum->c_my,lm->coef),nMult(p->coef,ro.sum->c_ac) )));
2910  if (p_GetComp(p, bucket->bucket_ring) != p_GetComp(lm, bucket->bucket_ring))
2911  {
2912    p_SetCompP(a1, p_GetComp(lm, bucket->bucket_ring), bucket->bucket_ring);
2913    reset_vec = TRUE;
2914    p_SetComp(lm, p_GetComp(p, bucket->bucket_ring), bucket->bucket_ring);
2915    p_Setm(lm, bucket->bucket_ring);
2916  }
2917
2918
2919 
2920
2921  p_DeleteLm(&lm, bucket->bucket_ring);
2922  if (reset_vec) p_SetCompP(a1, 0, bucket->bucket_ring);
2923  kbTest(bucket);
2924
2925}
2926
2927  reduction_accumulator::reduction_accumulator(poly p, int p_len, poly high_to){
2928    //sev needs to be removed from interfaces,makes no sense
2929   
2930    degbound(p);
2931    degbound(p->next);
2932    degbound(high_to);
2933    poly my=pOne();
2934    counter=0;
2935   
2936    for(int i=1;i<=pVariables;i++)
2937      pSetExp(my,i,(pGetExp(high_to, i)-pGetExp(p,i)));
2938    degbound(my);
2939   
2940   
2941    pSetm(my);
2942    last_reduction_id=-1;
2943    multiplied=nInit(1);
2944    bucket=kBucketCreate(currRing);
2945    poly a=pMult_mm(pCopy(p->next),my);
2946    degbound(a);
2947    this->sev=pGetShortExpVector(a);
2948    kBucketInit(bucket, a,p_len-1);
2949    pDelete(&my);
2950  }
2951void simple_reducer:: pre_reduce(red_object* r, int l, int u){}
2952void join_simple_reducer:: pre_reduce(red_object* r, int l, int u){
2953  for(int i=l;i<=u;i++)
2954    {
2955      if (r[i].sum){
2956        if(r[i].sum->ac->counter<=AC_FLATTEN) r[i].flatten();
2957       
2958      }
2959    }
2960}
Note: See TracBrowser for help on using the repository browser.