source: git/Singular/tgb.cc @ dd20b4

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