source: git/Singular/tgb.cc @ cb04f4

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