source: git/kernel/tgb.cc @ 9cd599

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