source: git/kernel/tgb.cc @ 81306a

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