source: git/kernel/tgb.cc @ 02e2f7

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