source: git/kernel/GBEngine/kstd2.cc @ d249822

fieker-DuValspielwiese
Last change on this file since d249822 was d249822, checked in by Adi Popescu <adi_popescum@…>, 8 years ago
rem: HAVE_RINGS in several places fix: sba over Z_m
  • Property mode set to 100644
File size: 112.0 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5*  ABSTRACT -  Kernel: alg. of Buchberger
6*/
7
8// #define PDEBUG 2
9
10#include <kernel/mod2.h>
11
12#define ADIDEBUG 0
13#define ADIDEBUG_COUNT 0
14#define GCD_SBA 1
15
16// define if no buckets should be used
17// #define NO_BUCKETS
18
19#ifdef HAVE_PLURAL
20#define PLURAL_INTERNAL_DECLARATIONS 1
21#endif
22
23/***********************************************
24 * SBA stuff -- start
25***********************************************/
26#define DEBUGF50  0
27#define DEBUGF51  0
28
29#ifdef DEBUGF5
30#undef DEBUGF5
31//#define DEBUGF5 1
32#endif
33
34#define F5C       1
35#if F5C
36  #define F5CTAILRED 1
37#endif
38
39#define SBA_INTERRED_START                  0
40#define SBA_TAIL_RED                        1
41#define SBA_PRODUCT_CRITERION               0
42#define SBA_PRINT_ZERO_REDUCTIONS           0
43#define SBA_PRINT_REDUCTION_STEPS           0
44#define SBA_PRINT_OPERATIONS                0
45#define SBA_PRINT_SIZE_G                    0
46#define SBA_PRINT_SIZE_SYZ                  0
47#define SBA_PRINT_PRODUCT_CRITERION         0
48
49// counts sba's reduction steps
50#if SBA_PRINT_REDUCTION_STEPS
51long sba_reduction_steps;
52long sba_interreduction_steps;
53#endif
54#if SBA_PRINT_OPERATIONS
55long sba_operations;
56long sba_interreduction_operations;
57#endif
58
59/***********************************************
60 * SBA stuff -- done
61***********************************************/
62
63#include <kernel/GBEngine/kutil.h>
64#include <misc/options.h>
65#include <omalloc/omalloc.h>
66#include <kernel/polys.h>
67#include <kernel/ideals.h>
68#include <kernel/GBEngine/kstd1.h>
69#include <kernel/GBEngine/khstd.h>
70#include <polys/kbuckets.h>
71#include <polys/prCopy.h>
72//#include "cntrlc.h"
73#include <polys/weight.h>
74#include <misc/intvec.h>
75#ifdef HAVE_PLURAL
76#include <polys/nc/nc.h>
77#endif
78// #include "timer.h"
79
80/* shiftgb stuff */
81#include <kernel/GBEngine/shiftgb.h>
82
83  int (*test_PosInT)(const TSet T,const int tl,LObject &h);
84  int (*test_PosInL)(const LSet set, const int length,
85                LObject* L,const kStrategy strat);
86
87// return -1 if no divisor is found
88//        number of first divisor, otherwise
89int kFindDivisibleByInT(const kStrategy strat, const LObject* L, const int start)
90{
91  unsigned long not_sev = ~L->sev;
92  int j = start;
93
94  const TSet T=strat->T;
95  const unsigned long* sevT=strat->sevT;
96  if (L->p!=NULL)
97  {
98    const ring r=currRing;
99    const poly p=L->p;
100
101    pAssume(~not_sev == p_GetShortExpVector(p, r));
102
103    if(rField_is_Ring(r))
104    {
105      loop
106      {
107        if (j > strat->tl) return -1;
108#if defined(PDEBUG) || defined(PDIV_DEBUG)
109        if (p_LmShortDivisibleBy(T[j].p, sevT[j],p, not_sev, r))
110        {
111          if(n_DivBy(p_GetCoeff(p,r), p_GetCoeff(T[j].p,r), r))
112            return j;
113        }
114#else
115        if (!(sevT[j] & not_sev) &&
116          p_LmDivisibleBy(T[j].p, p, r))
117        {
118          if(n_DivBy(p_GetCoeff(p,r), p_GetCoeff(T[j].p,r), r))
119            return j;
120        }
121#endif
122        j++;
123      }
124    }
125    else
126    {
127      loop
128      {
129        if (j > strat->tl) return -1;
130#if defined(PDEBUG) || defined(PDIV_DEBUG)
131        if (p_LmShortDivisibleBy(T[j].p, sevT[j],p, not_sev, r))
132        {
133          return j;
134        }
135#else
136        if (!(sevT[j] & not_sev) &&
137          p_LmDivisibleBy(T[j].p, p, r))
138        {
139          return j;
140        }
141#endif
142        j++;
143      }
144    }
145  }
146  else
147  {
148    const poly p=L->t_p;
149    const ring r=strat->tailRing;
150    if(rField_is_Ring(r))
151    {
152      loop
153      {
154        if (j > strat->tl) return -1;
155#if defined(PDEBUG) || defined(PDIV_DEBUG)
156        if (p_LmShortDivisibleBy(T[j].t_p, sevT[j],
157                               p, not_sev, r))
158        {
159          if(n_DivBy(pGetCoeff(p), pGetCoeff(T[j].t_p), r))
160            return j;
161        }
162#else
163        if (!(sevT[j] & not_sev) &&
164          p_LmDivisibleBy(T[j].t_p, p, r))
165        {
166          if(n_DivBy(pGetCoeff(p), pGetCoeff(T[j].t_p), r))
167            return j;
168        }
169#endif
170        j++;
171      }
172    }
173    else
174    {
175      loop
176      {
177        if (j > strat->tl) return -1;
178#if defined(PDEBUG) || defined(PDIV_DEBUG)
179        if (p_LmShortDivisibleBy(T[j].t_p, sevT[j],
180                               p, not_sev, r))
181        {
182          return j;
183        }
184#else
185        if (!(sevT[j] & not_sev) &&
186          p_LmDivisibleBy(T[j].t_p, p, r))
187        {
188          return j;
189        }
190#endif
191        j++;
192      }
193    }
194  }
195}
196
197// same as above, only with set S
198int kFindDivisibleByInS(const kStrategy strat, int* max_ind, LObject* L)
199{
200  unsigned long not_sev = ~L->sev;
201  poly p = L->GetLmCurrRing();
202  int j = 0;
203
204  pAssume(~not_sev == p_GetShortExpVector(p, currRing));
205#if 1
206  int ende;
207  if ((strat->ak>0) || currRing->pLexOrder || rField_is_Ring(currRing)) ende=strat->sl;
208  else ende=posInS(strat,*max_ind,p,0)+1;
209  if (ende>(*max_ind)) ende=(*max_ind);
210#else
211  int ende=strat->sl;
212#endif
213  (*max_ind)=ende;
214  if(rField_is_Ring(currRing))
215  {
216    loop
217    {
218      if (j > ende) return -1;
219#if defined(PDEBUG) || defined(PDIV_DEBUG)
220      if (p_LmShortDivisibleBy(strat->S[j], strat->sevS[j],
221                             p, not_sev, currRing))
222      {
223        if(n_DivBy(pGetCoeff(p), pGetCoeff(strat->S[j]), currRing))
224          return j;
225      }
226#else
227      if ( !(strat->sevS[j] & not_sev) &&
228         p_LmDivisibleBy(strat->S[j], p, currRing))
229      {
230        if(n_DivBy(pGetCoeff(p), pGetCoeff(strat->S[j]), currRing))
231          return j;
232      }
233#endif
234      j++;
235    }
236  }
237  else
238  {
239    loop
240    {
241      if (j > ende) return -1;
242#if defined(PDEBUG) || defined(PDIV_DEBUG)
243      if (p_LmShortDivisibleBy(strat->S[j], strat->sevS[j],
244                             p, not_sev, currRing))
245      {
246        return j;
247      }
248#else
249      if ( !(strat->sevS[j] & not_sev) &&
250         p_LmDivisibleBy(strat->S[j], p, currRing))
251      {
252        return j;
253      }
254#endif
255      j++;
256    }
257  }
258}
259
260int kFindNextDivisibleByInS(const kStrategy strat, int start,int max_ind, LObject* L)
261{
262  unsigned long not_sev = ~L->sev;
263  poly p = L->GetLmCurrRing();
264  int j = start;
265
266  pAssume(~not_sev == p_GetShortExpVector(p, currRing));
267#if 1
268  int ende=max_ind;
269#else
270  int ende=strat->sl;
271#endif
272  if(rField_is_Ring(currRing))
273  {
274    loop
275    {
276      if (j > ende) return -1;
277#if defined(PDEBUG) || defined(PDIV_DEBUG)
278      if (p_LmShortDivisibleBy(strat->S[j], strat->sevS[j],
279                             p, not_sev, currRing))
280      {
281        if(n_DivBy(pGetCoeff(p), pGetCoeff(strat->S[j]), currRing))
282          return j;
283      }
284#else
285      if ( !(strat->sevS[j] & not_sev) &&
286         p_LmDivisibleBy(strat->S[j], p, currRing))
287      {
288        if(n_DivBy(pGetCoeff(p), pGetCoeff(strat->S[j]), currRing))
289          return j;
290      }
291#endif
292      j++;
293    }
294  }
295  else
296  {
297    loop
298    {
299      if (j > ende) return -1;
300#if defined(PDEBUG) || defined(PDIV_DEBUG)
301      if (p_LmShortDivisibleBy(strat->S[j], strat->sevS[j],
302                             p, not_sev, currRing))
303      {
304        return j;
305      }
306#else
307      if ( !(strat->sevS[j] & not_sev) &&
308         p_LmDivisibleBy(strat->S[j], p, currRing))
309      {
310        return j;
311      }
312#endif
313      j++;
314    }
315  }
316}
317
318#ifdef HAVE_RINGS
319poly kFindZeroPoly(poly input_p, ring leadRing, ring tailRing)
320{
321  // m = currRing->ch
322
323  if (input_p == NULL) return NULL;
324
325  poly p = input_p;
326  poly zeroPoly = NULL;
327  unsigned long a = (unsigned long) pGetCoeff(p);
328
329  int k_ind2 = 0;
330  int a_ind2 = ind2(a);
331
332  // unsigned long k = 1;
333  // of interest is only k_ind2, special routine for improvement ... TODO OLIVER
334  for (int i = 1; i <= leadRing->N; i++)
335  {
336    k_ind2 = k_ind2 + ind_fact_2(p_GetExp(p, i, leadRing));
337  }
338
339  a = (unsigned long) pGetCoeff(p);
340
341  number tmp1;
342  poly tmp2, tmp3;
343  poly lead_mult = p_ISet(1, tailRing);
344  if (n_GetChar(leadRing->cf) <= k_ind2 + a_ind2)
345  {
346    int too_much = k_ind2 + a_ind2 - n_GetChar(leadRing->cf);
347    int s_exp;
348    zeroPoly = p_ISet(a, tailRing);
349    for (int i = 1; i <= leadRing->N; i++)
350    {
351      s_exp = p_GetExp(p, i,leadRing);
352      if (s_exp % 2 != 0)
353      {
354        s_exp = s_exp - 1;
355      }
356      while ( (0 < ind2(s_exp)) && (ind2(s_exp) <= too_much) )
357      {
358        too_much = too_much - ind2(s_exp);
359        s_exp = s_exp - 2;
360      }
361      p_SetExp(lead_mult, i, p_GetExp(p, i,leadRing) - s_exp, tailRing);
362      for (int j = 1; j <= s_exp; j++)
363      {
364        tmp1 = nInit(j);
365        tmp2 = p_ISet(1, tailRing);
366        p_SetExp(tmp2, i, 1, tailRing);
367        p_Setm(tmp2, tailRing);
368        if (nIsZero(tmp1))
369        { // should nowbe obsolet, test ! TODO OLIVER
370          zeroPoly = p_Mult_q(zeroPoly, tmp2, tailRing);
371        }
372        else
373        {
374          tmp3 = p_NSet(nCopy(tmp1), tailRing);
375          zeroPoly = p_Mult_q(zeroPoly, p_Add_q(tmp3, tmp2, tailRing), tailRing);
376        }
377      }
378    }
379    p_Setm(lead_mult, tailRing);
380    zeroPoly = p_Mult_mm(zeroPoly, lead_mult, tailRing);
381    tmp2 = p_NSet(nCopy(pGetCoeff(zeroPoly)), leadRing);
382    for (int i = 1; i <= leadRing->N; i++)
383    {
384      pSetExp(tmp2, i, p_GetExp(zeroPoly, i, tailRing));
385    }
386    p_Setm(tmp2, leadRing);
387    zeroPoly = p_LmDeleteAndNext(zeroPoly, tailRing);
388    pNext(tmp2) = zeroPoly;
389    return tmp2;
390  }
391/*  unsigned long alpha_k = twoPow(leadRing->ch - k_ind2);
392  if (1 == 0 && alpha_k <= a)
393  {  // Temporarly disabled, reducing coefficients not compatible with std TODO Oliver
394    zeroPoly = p_ISet((a / alpha_k)*alpha_k, tailRing);
395    for (int i = 1; i <= leadRing->N; i++)
396    {
397      for (unsigned long j = 1; j <= p_GetExp(p, i, leadRing); j++)
398      {
399        tmp1 = nInit(j);
400        tmp2 = p_ISet(1, tailRing);
401        p_SetExp(tmp2, i, 1, tailRing);
402        p_Setm(tmp2, tailRing);
403        if (nIsZero(tmp1))
404        {
405          zeroPoly = p_Mult_q(zeroPoly, tmp2, tailRing);
406        }
407        else
408        {
409          tmp3 = p_ISet((unsigned long) tmp1, tailRing);
410          zeroPoly = p_Mult_q(zeroPoly, p_Add_q(tmp2, tmp3, tailRing), tailRing);
411        }
412      }
413    }
414    tmp2 = p_ISet((unsigned long) pGetCoeff(zeroPoly), leadRing);
415    for (int i = 1; i <= leadRing->N; i++)
416    {
417      pSetExp(tmp2, i, p_GetExp(zeroPoly, i, tailRing));
418    }
419    p_Setm(tmp2, leadRing);
420    zeroPoly = p_LmDeleteAndNext(zeroPoly, tailRing);
421    pNext(tmp2) = zeroPoly;
422    return tmp2;
423  } */
424  return NULL;
425}
426#endif
427
428
429#ifdef HAVE_RINGS
430/*2
431*  reduction procedure for the ring Z/2^m
432*/
433int redRing (LObject* h,kStrategy strat)
434{
435  if (h->IsNull()) return 0; // spoly is zero (can only occure with zero divisors)
436  if (strat->tl<0) return 1;
437
438  int at/*,i*/;
439  long d;
440  int j = 0;
441  int pass = 0;
442  // poly zeroPoly = NULL;
443
444// TODO warum SetpFDeg notwendig?
445  h->SetpFDeg();
446  assume(h->pFDeg() == h->FDeg);
447  long reddeg = h->GetpFDeg();
448
449  h->SetShortExpVector();
450  loop
451  {
452    j = kFindDivisibleByInT(strat, h);
453    if (j < 0)
454    {
455      // over ZZ: cleanup coefficients by complete reduction with monomials
456      postReduceByMon(h, strat);
457      if(nIsZero(pGetCoeff(h->p))) return 2;
458      j = kFindDivisibleByInT(strat, h);
459      if(j < 0)
460      {
461        if(strat->tl >= 0)
462            h->i_r1 = strat->tl;
463        else
464            h->i_r1 = -1;
465        if (h->GetLmTailRing() == NULL)
466        {
467          if (h->lcm!=NULL) pLmDelete(h->lcm);
468          h->Clear();
469          return 0;
470        }
471        return 1;
472      }
473    }
474    //printf("\nFound one: ");pWrite(strat->T[j].p);
475    //enterT(*h, strat);
476    ksReducePoly(h, &(strat->T[j]), NULL, NULL, strat); // with debug output
477    //printf("\nAfter small red: ");pWrite(h->p);
478    if (h->GetLmTailRing() == NULL)
479    {
480      if (h->lcm!=NULL) pLmDelete(h->lcm);
481#ifdef KDEBUG
482      h->lcm=NULL;
483#endif
484      h->Clear();
485      return 0;
486    }
487    h->SetShortExpVector();
488    d = h->SetpFDeg();
489    /*- try to reduce the s-polynomial -*/
490    pass++;
491    if (!TEST_OPT_REDTHROUGH &&
492        (strat->Ll >= 0) && ((d > reddeg) || (pass > strat->LazyPass)))
493    {
494      h->SetLmCurrRing();
495      if (strat->posInLDependsOnLength)
496        h->SetLength(strat->length_pLength);
497      at = strat->posInL(strat->L,strat->Ll,h,strat);
498      if (at <= strat->Ll)
499      {
500#ifdef KDEBUG
501        if (TEST_OPT_DEBUG) Print(" ->L[%d]\n",at);
502#endif
503        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);     // NOT RING CHECKED OLIVER
504        h->Clear();
505        return -1;
506      }
507    }
508    if (d != reddeg)
509    {
510      if (d >= (long)strat->tailRing->bitmask)
511      {
512        if (h->pTotalDeg() >= (long)strat->tailRing->bitmask)
513        {
514          strat->overflow=TRUE;
515          //Print("OVERFLOW in redRing d=%ld, max=%ld\n",d,strat->tailRing->bitmask);
516          h->GetP();
517          at = strat->posInL(strat->L,strat->Ll,h,strat);
518          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
519          h->Clear();
520          return -1;
521        }
522      }
523      else if ((TEST_OPT_PROT) && (strat->Ll < 0))
524      {
525        Print(".%ld",d);mflush();
526        reddeg = d;
527      }
528    }
529  }
530}
531#endif
532
533/*2
534*  reduction procedure for the homogeneous case
535*  and the case of a degree-ordering
536*/
537int redHomog (LObject* h,kStrategy strat)
538{
539  if (strat->tl<0) return 1;
540  //if (h->GetLmTailRing()==NULL) return 0; // HS: SHOULD NOT BE NEEDED!
541  assume(h->FDeg == h->pFDeg());
542
543  poly h_p;
544  int i,j,at,pass, ii;
545  unsigned long not_sev;
546  // long reddeg,d;
547
548  pass = j = 0;
549  // d = reddeg = h->GetpFDeg();
550  h->SetShortExpVector();
551  int li;
552  h_p = h->GetLmTailRing();
553  not_sev = ~ h->sev;
554  loop
555  {
556    j = kFindDivisibleByInT(strat, h);
557    if (j < 0) return 1;
558
559    li = strat->T[j].pLength;
560    ii = j;
561    /*
562     * the polynomial to reduce with (up to the moment) is;
563     * pi with length li
564     */
565    i = j;
566#if 1
567    if (TEST_OPT_LENGTH)
568    loop
569    {
570      /*- search the shortest possible with respect to length -*/
571      i++;
572      if (i > strat->tl)
573        break;
574      if (li<=1)
575        break;
576      if ((strat->T[i].pLength < li)
577         &&
578          p_LmShortDivisibleBy(strat->T[i].GetLmTailRing(), strat->sevT[i],
579                               h_p, not_sev, strat->tailRing))
580      {
581        /*
582         * the polynomial to reduce with is now;
583         */
584        li = strat->T[i].pLength;
585        ii = i;
586      }
587    }
588#endif
589
590    /*
591     * end of search: have to reduce with pi
592     */
593#ifdef KDEBUG
594    if (TEST_OPT_DEBUG)
595    {
596      PrintS("red:");
597      h->wrp();
598      PrintS(" with ");
599      strat->T[ii].wrp();
600    }
601#endif
602    assume(strat->fromT == FALSE);
603
604    ksReducePoly(h, &(strat->T[ii]), NULL, NULL, strat);
605#if SBA_PRINT_REDUCTION_STEPS
606    sba_interreduction_steps++;
607#endif
608#if SBA_PRINT_OPERATIONS
609    sba_interreduction_operations  +=  pLength(strat->T[ii].p);
610#endif
611
612#ifdef KDEBUG
613    if (TEST_OPT_DEBUG)
614    {
615      PrintS("\nto ");
616      h->wrp();
617      PrintLn();
618    }
619#endif
620
621    h_p = h->GetLmTailRing();
622    if (h_p == NULL)
623    {
624      if (h->lcm!=NULL) pLmFree(h->lcm);
625#ifdef KDEBUG
626      h->lcm=NULL;
627#endif
628      return 0;
629    }
630    h->SetShortExpVector();
631    not_sev = ~ h->sev;
632    /*
633     * try to reduce the s-polynomial h
634     *test first whether h should go to the lazyset L
635     *-if the degree jumps
636     *-if the number of pre-defined reductions jumps
637     */
638    pass++;
639    if (!TEST_OPT_REDTHROUGH && (strat->Ll >= 0) && (pass > strat->LazyPass))
640    {
641      h->SetLmCurrRing();
642      at = strat->posInL(strat->L,strat->Ll,h,strat);
643      if (at <= strat->Ll)
644      {
645        int dummy=strat->sl;
646        if (kFindDivisibleByInS(strat, &dummy, h) < 0)
647          return 1;
648        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
649#ifdef KDEBUG
650        if (TEST_OPT_DEBUG)
651          Print(" lazy: -> L%d\n",at);
652#endif
653        h->Clear();
654        return -1;
655      }
656    }
657  }
658}
659
660KINLINE int ksReducePolyTailSig(LObject* PR, TObject* PW, LObject* Red, kStrategy strat)
661{
662  BOOLEAN ret;
663  number coef;
664  assume(PR->GetLmCurrRing() != PW->GetLmCurrRing());
665  if(!rField_is_Ring(currRing))
666    Red->HeadNormalize();
667  /*
668  printf("------------------------\n");
669  pWrite(Red->GetLmCurrRing());
670  */
671  ret = ksReducePolySig(Red, PW, 1, NULL, &coef, strat);
672  if (!ret)
673  {
674    if (! n_IsOne(coef, currRing->cf) && !rField_is_Ring(currRing))
675    {
676      PR->Mult_nn(coef);
677      // HANNES: mark for Normalize
678    }
679    n_Delete(&coef, currRing->cf);
680  }
681  return ret;
682}
683
684/*2
685*  reduction procedure for signature-based standard
686*  basis algorithms:
687*  all reductions have to be sig-safe!
688*
689*  2 is returned if and only if the pair is rejected by the rewritten criterion
690*  at exactly this point of the computations. This is the last possible point
691*  such a check can be done => checks with the biggest set of available
692*  signatures
693*/
694int redSig (LObject* h,kStrategy strat)
695{
696  //Since reduce is really bad for SBA we use the following idea:
697  // We first check if we can build a gcd pair between h and S
698  //where the sig remains the same and replace h by this gcd poly
699  #if GCD_SBA
700  #if ADIDEBUG
701  printf("\nBefore sbaCheckGcdPair ");pWrite(h->p);
702  #endif
703  //sbaCheckGcdPair(h,strat);
704  while(sbaCheckGcdPair(h,strat)) 
705  {
706    #if ADIDEBUG
707    printf("\nIntermidiate sbaCheckGcdPair ");pWrite(h->p);
708    #endif
709    h->sev = pGetShortExpVector(h->p);
710  }
711  #if ADIDEBUG
712  printf("\nAfter sbaCheckGcdPair ");pWrite(h->p);
713  #endif
714  #endif
715  poly beforeredsig;
716  if(rField_is_Ring(currRing)) 
717    beforeredsig = pCopy(h->sig);
718   
719  if (strat->tl<0) return 1;
720  //if (h->GetLmTailRing()==NULL) return 0; // HS: SHOULD NOT BE NEEDED!
721  //printf("FDEGS: %ld -- %ld\n",h->FDeg, h->pFDeg());
722  assume(h->FDeg == h->pFDeg());
723  #if ADIDEBUG
724  printf("\n--------------------------redSig-------------------------------------\n");
725  printf("\nBefore redSig:\n");
726  p_Write(h->p,strat->tailRing);pWrite(h->sig);
727  #endif
728//#if 1
729#ifdef DEBUGF5
730  Print("------- IN REDSIG -------\n");
731  Print("p: ");
732  pWrite(pHead(h->p));
733  Print("p1: ");
734  pWrite(pHead(h->p1));
735  Print("p2: ");
736  pWrite(pHead(h->p2));
737  Print("---------------------------\n");
738#endif
739  poly h_p;
740  int i,j,at,pass, ii;
741  int start=0;
742  int sigSafe;
743  unsigned long not_sev;
744  // long reddeg,d;
745
746  pass = j = 0;
747  // d = reddeg = h->GetpFDeg();
748  h->SetShortExpVector();
749  int li;
750  h_p = h->GetLmTailRing();
751  not_sev = ~ h->sev;
752  loop
753  {
754    j = kFindDivisibleByInT(strat, h, start);
755    if (j < 0)
756    {
757      #if GCD_SBA
758      #if ADIDEBUG
759      printf("\nBefore sbaCheckGcdPair ");pWrite(h->p);
760      #endif
761      //sbaCheckGcdPair(h,strat);
762      while(sbaCheckGcdPair(h,strat)) 
763      {
764        #if ADIDEBUG
765        printf("\nIntermidiate sbaCheckGcdPair ");pWrite(h->p);
766        #endif
767        h->sev = pGetShortExpVector(h->p);
768        h->is_redundant = FALSE;
769        start = 0;
770      }
771      #if ADIDEBUG
772      printf("\nAfter sbaCheckGcdPair ");pWrite(h->p);
773      #endif
774      #endif
775      // over ZZ: cleanup coefficients by complete reduction with monomials
776      postReduceByMonSig(h, strat);
777      if(h->p == NULL || nIsZero(pGetCoeff(h->p))) return 2;
778      j = kFindDivisibleByInT(strat, h,start);
779      if(j < 0)
780      {
781        if(strat->tl >= 0)
782            h->i_r1 = strat->tl;
783        else
784            h->i_r1 = -1;
785        if (h->GetLmTailRing() == NULL)
786        {
787          if (h->lcm!=NULL) pLmDelete(h->lcm);
788          h->Clear();
789          return 0;
790        }
791        if(rField_is_Ring(currRing))
792        {
793          //Check for sigdrop after reduction
794          if(pLtCmp(beforeredsig,h->sig) == 1)
795          {
796            #if ADIDEBUG
797            printf("\nSigDrop after reduce\n");pWrite(beforeredsig);pWrite(h->sig);
798            #endif
799            strat->sigdrop = TRUE;
800            //Reduce it as much as you can
801            int red_result = redRing(h,strat);
802            if(red_result == 0)
803            {
804              //It reduced to 0, cancel the sigdrop
805              #if ADIDEBUG
806              printf("\nReduced to 0 via redRing. Cancel sigdrop\n");
807              #endif
808              strat->sigdrop = FALSE;
809              p_Delete(&h->sig,currRing);h->sig = NULL;
810              return 0;
811            }
812            else
813            {
814              #if ADIDEBUG
815              printf("\nReduced to this via redRing.SIGDROP\n");pWrite(h->p);
816              #endif
817              //strat->enterS(*h, strat->sl+1, strat, strat->tl);
818              return 0;
819            }
820          }
821          p_Delete(&beforeredsig,currRing);
822        }
823        return 1;
824      }
825    }
826
827    li = strat->T[j].pLength;
828    ii = j;
829    /*
830     * the polynomial to reduce with (up to the moment) is;
831     * pi with length li
832     */
833    i = j;
834    if (TEST_OPT_LENGTH)
835    if(rField_is_Ring(currRing))
836    {
837      loop
838      {
839        /*- search the shortest possible with respect to length -*/
840        i++;
841        if (i > strat->tl)
842          break;
843        if (li<=1)
844          break;
845        if ((strat->T[i].pLength < li)
846           && n_DivBy(pGetCoeff(h_p),pGetCoeff(strat->T[i].p),currRing->cf)
847           && p_LmShortDivisibleBy(strat->T[i].GetLmTailRing(), strat->sevT[i],
848                                 h_p, not_sev, strat->tailRing))
849        {
850          /*
851           * the polynomial to reduce with is now;
852           */
853          li = strat->T[i].pLength;
854          ii = i;
855        }
856      }
857    }
858    else
859    {
860      loop
861      {
862        /*- search the shortest possible with respect to length -*/
863        i++;
864        if (i > strat->tl)
865          break;
866        if (li<=1)
867          break;
868        if ((strat->T[i].pLength < li)
869           && p_LmShortDivisibleBy(strat->T[i].GetLmTailRing(), strat->sevT[i],
870                                 h_p, not_sev, strat->tailRing))
871        {
872          /*
873           * the polynomial to reduce with is now;
874           */
875          li = strat->T[i].pLength;
876          ii = i;
877        }
878      }
879    }
880    start = ii+1;
881
882    /*
883     * end of search: have to reduce with pi
884     */
885#ifdef KDEBUG
886    if (TEST_OPT_DEBUG)
887    {
888      PrintS("red:");
889      h->wrp();
890      PrintS(" with ");
891      strat->T[ii].wrp();
892    }
893#endif
894    assume(strat->fromT == FALSE);
895//#if 1
896#ifdef DEBUGF5
897    Print("BEFORE REDUCTION WITH %d:\n",ii);
898    Print("--------------------------------\n");
899    pWrite(h->sig);
900    pWrite(strat->T[ii].sig);
901    pWrite(h->GetLmCurrRing());
902    pWrite(pHead(h->p1));
903    pWrite(pHead(h->p2));
904    pWrite(pHead(strat->T[ii].p));
905    Print("--------------------------------\n");
906    printf("INDEX OF REDUCER T: %d\n",ii);
907#endif
908    #if ADIDEBUG
909    printf("\nWe reduce it with:\n");p_Write(strat->T[ii].p,strat->tailRing);pWrite(strat->T[ii].sig);
910    #endif
911    sigSafe = ksReducePolySig(h, &(strat->T[ii]), strat->S_2_R[ii], NULL, NULL, strat);
912    #if ADIDEBUG
913    printf("\nAfter small reduction:\n");pWrite(h->p);pWrite(h->sig);
914    #endif
915    if(rField_is_Ring(currRing) && h->p == NULL && h->sig == NULL)
916    {
917      //Trivial case catch
918      strat->sigdrop = FALSE;
919    }
920    #if 0
921    //If the reducer has the same lt (+ or -) as the other one, reduce it via redRing
922    //In some cases this proves to be very bad
923    if(rField_is_Ring(currRing) && h->p != NULL && pLmCmp(h->p,strat->T[ii].p)==0)
924    {
925      #if ADIDEBUG
926      printf("\nReducer and Original have same LT. Force it with redRing!\n");
927      #endif
928      int red_result = redRing(h,strat);
929      if(red_result == 0)
930      {
931        #if ADIDEBUG
932        printf("\nRedRing reduced it to 0. Perfect\n");
933        #endif
934        pDelete(&h->sig);h->sig = NULL;
935        return 0;
936      }
937      else
938      {
939        #if ADIDEBUG
940        printf("\nRedRing reduced it to *.\nHave to sigdrop now\n");pWrite(h->p);
941        #endif
942        strat->sigdrop = TRUE;
943        return 1;
944      }
945    }
946    #endif
947    if(strat->sigdrop)
948      return 1;
949#if SBA_PRINT_REDUCTION_STEPS
950    if (sigSafe != 3)
951      sba_reduction_steps++;
952#endif
953#if SBA_PRINT_OPERATIONS
954    if (sigSafe != 3)
955      sba_operations  +=  pLength(strat->T[ii].p);
956#endif
957    // if reduction has taken place, i.e. the reduction was sig-safe
958    // otherwise start is already at the next position and the loop
959    // searching reducers in T goes on from index start
960//#if 1
961#ifdef DEBUGF5
962    Print("SigSAFE: %d\n",sigSafe);
963#endif
964    if (sigSafe != 3)
965    {
966      // start the next search for reducers in T from the beginning
967      start = 0;
968#ifdef KDEBUG
969      if (TEST_OPT_DEBUG)
970      {
971        PrintS("\nto ");
972        h->wrp();
973        PrintLn();
974      }
975#endif
976
977      h_p = h->GetLmTailRing();
978      if (h_p == NULL)
979      {
980        if (h->lcm!=NULL) pLmFree(h->lcm);
981#ifdef KDEBUG
982        h->lcm=NULL;
983#endif
984        return 0;
985      }
986      h->SetShortExpVector();
987      not_sev = ~ h->sev;
988      /*
989      * try to reduce the s-polynomial h
990      *test first whether h should go to the lazyset L
991      *-if the degree jumps
992      *-if the number of pre-defined reductions jumps
993      */
994      pass++;
995      if (!TEST_OPT_REDTHROUGH && (strat->Ll >= 0) && (pass > strat->LazyPass))
996      {
997        h->SetLmCurrRing();
998        at = strat->posInL(strat->L,strat->Ll,h,strat);
999        if (at <= strat->Ll)
1000        {
1001          int dummy=strat->sl;
1002          if (kFindDivisibleByInS(strat, &dummy, h) < 0)
1003          {
1004            return 1;
1005          }
1006          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
1007#ifdef KDEBUG
1008          if (TEST_OPT_DEBUG)
1009            Print(" lazy: -> L%d\n",at);
1010#endif
1011          h->Clear();
1012          return -1;
1013        }
1014      }
1015    }
1016  }
1017}
1018
1019// tail reduction for SBA
1020poly redtailSba (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
1021{
1022#define REDTAIL_CANONICALIZE 100
1023  strat->redTailChange=FALSE;
1024  if (strat->noTailReduction) return L->GetLmCurrRing();
1025  poly h, p;
1026  p = h = L->GetLmTailRing();
1027  if ((h==NULL) || (pNext(h)==NULL))
1028    return L->GetLmCurrRing();
1029
1030  TObject* With;
1031  // placeholder in case strat->tl < 0
1032  TObject  With_s(strat->tailRing);
1033
1034  LObject Ln(pNext(h), strat->tailRing);
1035  Ln.sig      = L->sig;
1036  Ln.sevSig   = L->sevSig;
1037  Ln.pLength  = L->GetpLength() - 1;
1038
1039  pNext(h) = NULL;
1040  if (L->p != NULL) pNext(L->p) = NULL;
1041  L->pLength = 1;
1042
1043  Ln.PrepareRed(strat->use_buckets);
1044
1045  int cnt=REDTAIL_CANONICALIZE;
1046  while(!Ln.IsNull())
1047  {
1048    loop
1049    {
1050      if(rField_is_Ring(currRing) && strat->sigdrop)
1051        break;
1052      Ln.SetShortExpVector();
1053      if (withT)
1054      {
1055        int j;
1056        j = kFindDivisibleByInT(strat, &Ln);
1057        if (j < 0) break;
1058        With = &(strat->T[j]);
1059      }
1060      else
1061      {
1062        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
1063        if (With == NULL) break;
1064      }
1065      cnt--;
1066      if (cnt==0)
1067      {
1068        cnt=REDTAIL_CANONICALIZE;
1069        /*poly tmp=*/Ln.CanonicalizeP();
1070        if (normalize && !rField_is_Ring(currRing))
1071        {
1072          Ln.Normalize();
1073          //pNormalize(tmp);
1074          //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
1075        }
1076      }
1077      if (normalize && (!TEST_OPT_INTSTRATEGY) && !rField_is_Ring(currRing) && (!nIsOne(pGetCoeff(With->p))))
1078      {
1079        With->pNorm();
1080      }
1081      strat->redTailChange=TRUE;
1082      #if ADIDEBUG
1083      printf("\nWill TAILreduce * with *:\n");pWrite(Ln.p);pWrite(Ln.sig);
1084      pWrite(With->p);pWrite(With->sig);pWrite(L->sig);
1085      #endif
1086      int ret = ksReducePolyTailSig(L, With, &Ln, strat);
1087      if(rField_is_Ring(currRing))
1088        L->sig = Ln.sig;
1089      //Because Ln.sig is set to L->sig, but in ksReducePolyTailSig -> ksReducePolySig
1090      // I delete it an then set Ln.sig. Hence L->sig is lost
1091      #if ADIDEBUG
1092      printf("\nAfter small TAILreduce:\n");pWrite(Ln.p);pWrite(Ln.sig);pWrite(L->sig);
1093      #endif
1094#if SBA_PRINT_REDUCTION_STEPS
1095      if (ret != 3)
1096        sba_reduction_steps++;
1097#endif
1098#if SBA_PRINT_OPERATIONS
1099      if (ret != 3)
1100        sba_operations  +=  pLength(With->p);
1101#endif
1102      if (ret)
1103      {
1104        // reducing the tail would violate the exp bound
1105        //  set a flag and hope for a retry (in bba)
1106        strat->completeReduce_retry=TRUE;
1107        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
1108        do
1109        {
1110          pNext(h) = Ln.LmExtractAndIter();
1111          pIter(h);
1112          L->pLength++;
1113        } while (!Ln.IsNull());
1114        goto all_done;
1115      }
1116      if (Ln.IsNull()) goto all_done;
1117      if (! withT) With_s.Init(currRing);
1118      if(rField_is_Ring(currRing) && strat->sigdrop)
1119      {
1120        //Cannot break the loop here so easily
1121        break;
1122      }
1123    }
1124    pNext(h) = Ln.LmExtractAndIter();
1125    pIter(h);
1126    if(!rField_is_Ring(currRing))
1127      pNormalize(h);
1128    L->pLength++;
1129  }
1130  all_done:
1131  Ln.Delete();
1132  if (L->p != NULL) pNext(L->p) = pNext(p);
1133
1134  if (strat->redTailChange)
1135  {
1136    L->length = 0;
1137  }
1138  //if (TEST_OPT_PROT) { PrintS("N"); mflush(); }
1139  //L->Normalize(); // HANNES: should have a test
1140  kTest_L(L);
1141  return L->GetLmCurrRing();
1142}
1143
1144/*2
1145*  reduction procedure for the inhomogeneous case
1146*  and not a degree-ordering
1147*/
1148int redLazy (LObject* h,kStrategy strat)
1149{
1150  if (strat->tl<0) return 1;
1151  int at,i,ii,li;
1152  int j = 0;
1153  int pass = 0;
1154  assume(h->pFDeg() == h->FDeg);
1155  long reddeg = h->GetpFDeg();
1156  long d;
1157  unsigned long not_sev;
1158
1159  h->SetShortExpVector();
1160  poly h_p = h->GetLmTailRing();
1161  not_sev = ~ h->sev;
1162  loop
1163  {
1164    j = kFindDivisibleByInT(strat, h);
1165    if (j < 0) return 1;
1166
1167    li = strat->T[j].pLength;
1168    #if 0
1169    if (li==0)
1170    {
1171      li=strat->T[j].pLength=pLength(strat->T[j].p);
1172    }
1173    #endif
1174    ii = j;
1175    /*
1176     * the polynomial to reduce with (up to the moment) is;
1177     * pi with length li
1178     */
1179
1180    i = j;
1181#if 1
1182    if (TEST_OPT_LENGTH)
1183    loop
1184    {
1185      /*- search the shortest possible with respect to length -*/
1186      i++;
1187      if (i > strat->tl)
1188        break;
1189      if (li<=1)
1190        break;
1191    #if 0
1192      if (strat->T[i].pLength==0)
1193      {
1194        PrintS("!");
1195        strat->T[i].pLength=pLength(strat->T[i].p);
1196      }
1197   #endif
1198      if ((strat->T[i].pLength < li)
1199         &&
1200          p_LmShortDivisibleBy(strat->T[i].GetLmTailRing(), strat->sevT[i],
1201                               h_p, not_sev, strat->tailRing))
1202      {
1203        /*
1204         * the polynomial to reduce with is now;
1205         */
1206        PrintS("+");
1207        li = strat->T[i].pLength;
1208        ii = i;
1209      }
1210    }
1211#endif
1212
1213    /*
1214     * end of search: have to reduce with pi
1215     */
1216
1217
1218#ifdef KDEBUG
1219    if (TEST_OPT_DEBUG)
1220    {
1221      PrintS("red:");
1222      h->wrp();
1223      PrintS(" with ");
1224      strat->T[ii].wrp();
1225    }
1226#endif
1227
1228    ksReducePoly(h, &(strat->T[ii]), NULL, NULL, strat);
1229#if SBA_PRINT_REDUCTION_STEPS
1230    sba_interreduction_steps++;
1231#endif
1232#if SBA_PRINT_OPERATIONS
1233    sba_interreduction_operations  +=  pLength(strat->T[ii].p);
1234#endif
1235
1236#ifdef KDEBUG
1237    if (TEST_OPT_DEBUG)
1238    {
1239      PrintS("\nto ");
1240      h->wrp();
1241      PrintLn();
1242    }
1243#endif
1244
1245    h_p=h->GetLmTailRing();
1246
1247    if (h_p == NULL)
1248    {
1249      if (h->lcm!=NULL) pLmFree(h->lcm);
1250#ifdef KDEBUG
1251      h->lcm=NULL;
1252#endif
1253      return 0;
1254    }
1255    h->SetShortExpVector();
1256    not_sev = ~ h->sev;
1257    d = h->SetpFDeg();
1258    /*- try to reduce the s-polynomial -*/
1259    pass++;
1260    if (//!TEST_OPT_REDTHROUGH &&
1261        (strat->Ll >= 0) && ((d > reddeg) || (pass > strat->LazyPass)))
1262    {
1263      h->SetLmCurrRing();
1264      at = strat->posInL(strat->L,strat->Ll,h,strat);
1265      if (at <= strat->Ll)
1266      {
1267#if 1
1268        int dummy=strat->sl;
1269        if (kFindDivisibleByInS(strat, &dummy, h) < 0)
1270          return 1;
1271#endif
1272#ifdef KDEBUG
1273        if (TEST_OPT_DEBUG) Print(" ->L[%d]\n",at);
1274#endif
1275        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
1276        h->Clear();
1277        return -1;
1278      }
1279    }
1280    else if (d != reddeg)
1281    {
1282      if (d>=(long)strat->tailRing->bitmask)
1283      {
1284        if (h->pTotalDeg() >= (long)strat->tailRing->bitmask)
1285        {
1286          strat->overflow=TRUE;
1287          //Print("OVERFLOW in redLazy d=%ld, max=%ld\n",d,strat->tailRing->bitmask);
1288          h->GetP();
1289          at = strat->posInL(strat->L,strat->Ll,h,strat);
1290          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
1291          h->Clear();
1292          return -1;
1293        }
1294      }
1295      else if ((TEST_OPT_PROT) && (strat->Ll < 0))
1296      {
1297        Print(".%ld",d);mflush();
1298        reddeg = d;
1299      }
1300    }
1301  }
1302}
1303/*2
1304*  reduction procedure for the sugar-strategy (honey)
1305* reduces h with elements from T choosing first possible
1306* element in T with respect to the given ecart
1307*/
1308int redHoney (LObject* h, kStrategy strat)
1309{
1310  if (strat->tl<0) return 1;
1311  //if (h->GetLmTailRing()==NULL) return 0; // HS: SHOULD NOT BE NEEDED!
1312  assume(h->FDeg == h->pFDeg());
1313  poly h_p;
1314  int i,j,at,pass,ei, ii, h_d;
1315  unsigned long not_sev;
1316  long reddeg,d;
1317
1318  pass = j = 0;
1319  d = reddeg = h->GetpFDeg() + h->ecart;
1320  h->SetShortExpVector();
1321  int li;
1322  h_p = h->GetLmTailRing();
1323  not_sev = ~ h->sev;
1324
1325  h->PrepareRed(strat->use_buckets);
1326  loop
1327  {
1328    j=kFindDivisibleByInT(strat, h);
1329    if (j < 0) return 1;
1330
1331    ei = strat->T[j].ecart;
1332    li = strat->T[j].pLength;
1333    ii = j;
1334    /*
1335     * the polynomial to reduce with (up to the moment) is;
1336     * pi with ecart ei
1337     */
1338    i = j;
1339    if (TEST_OPT_LENGTH)
1340    loop
1341    {
1342      /*- takes the first possible with respect to ecart -*/
1343      i++;
1344      if (i > strat->tl)
1345        break;
1346      //if (ei < h->ecart)
1347      //  break;
1348      if (li<=1)
1349        break;
1350      if ((((strat->T[i].ecart < ei) && (ei> h->ecart))
1351         || ((strat->T[i].ecart <= h->ecart) && (strat->T[i].pLength < li)))
1352         &&
1353          p_LmShortDivisibleBy(strat->T[i].GetLmTailRing(), strat->sevT[i],
1354                               h_p, not_sev, strat->tailRing))
1355      {
1356        /*
1357         * the polynomial to reduce with is now;
1358         */
1359        ei = strat->T[i].ecart;
1360        li = strat->T[i].pLength;
1361        ii = i;
1362      }
1363    }
1364
1365    /*
1366     * end of search: have to reduce with pi
1367     */
1368    if (!TEST_OPT_REDTHROUGH && (pass!=0) && (ei > h->ecart))
1369    {
1370      h->GetTP(); // clears bucket
1371      h->SetLmCurrRing();
1372      /*
1373       * It is not possible to reduce h with smaller ecart;
1374       * if possible h goes to the lazy-set L,i.e
1375       * if its position in L would be not the last one
1376       */
1377      if (strat->Ll >= 0) /* L is not empty */
1378      {
1379        at = strat->posInL(strat->L,strat->Ll,h,strat);
1380        if(at <= strat->Ll)
1381          /*- h will not become the next element to reduce -*/
1382        {
1383          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
1384#ifdef KDEBUG
1385          if (TEST_OPT_DEBUG) Print(" ecart too big: -> L%d\n",at);
1386#endif
1387          h->Clear();
1388          return -1;
1389        }
1390      }
1391    }
1392#ifdef KDEBUG
1393    if (TEST_OPT_DEBUG)
1394    {
1395      PrintS("red:");
1396      h->wrp();
1397      PrintS(" with ");
1398      strat->T[ii].wrp();
1399    }
1400#endif
1401    assume(strat->fromT == FALSE);
1402
1403    number coef;
1404    ksReducePoly(h,&(strat->T[ii]),strat->kNoetherTail(),&coef,strat);
1405#if SBA_PRINT_REDUCTION_STEPS
1406    sba_interreduction_steps++;
1407#endif
1408#if SBA_PRINT_OPERATIONS
1409    sba_interreduction_operations  +=  pLength(strat->T[ii].p);
1410#endif
1411#ifdef KDEBUG
1412    if (TEST_OPT_DEBUG)
1413    {
1414      PrintS("\nto:");
1415      h->wrp();
1416      PrintLn();
1417    }
1418#endif
1419    if(h->IsNull())
1420    {
1421      h->Clear();
1422      if (h->lcm!=NULL) pLmFree(h->lcm);
1423      #ifdef KDEBUG
1424      h->lcm=NULL;
1425      #endif
1426      return 0;
1427    }
1428    if (TEST_OPT_IDLIFT)
1429    {
1430      if (h->p!=NULL)
1431      {
1432        if(p_GetComp(h->p,currRing)>strat->syzComp)
1433        {
1434          h->Delete();
1435          return 0;
1436        }
1437      }
1438      else if (h->t_p!=NULL)
1439      {
1440        if(p_GetComp(h->t_p,strat->tailRing)>strat->syzComp)
1441        {
1442          h->Delete();
1443          return 0;
1444        }
1445      }
1446    }
1447    h->SetShortExpVector();
1448    not_sev = ~ h->sev;
1449    h_d = h->SetpFDeg();
1450    /* compute the ecart */
1451    if (ei <= h->ecart)
1452      h->ecart = d-h_d;
1453    else
1454      h->ecart = d-h_d+ei-h->ecart;
1455
1456    /*
1457     * try to reduce the s-polynomial h
1458     *test first whether h should go to the lazyset L
1459     *-if the degree jumps
1460     *-if the number of pre-defined reductions jumps
1461     */
1462    pass++;
1463    d = h_d + h->ecart;
1464    if (!TEST_OPT_REDTHROUGH && (strat->Ll >= 0) && ((d > reddeg) || (pass > strat->LazyPass)))
1465    {
1466      h->GetTP(); // clear bucket
1467      h->SetLmCurrRing();
1468      at = strat->posInL(strat->L,strat->Ll,h,strat);
1469      if (at <= strat->Ll)
1470      {
1471        int dummy=strat->sl;
1472        if (kFindDivisibleByInS(strat, &dummy, h) < 0)
1473          return 1;
1474        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
1475#ifdef KDEBUG
1476        if (TEST_OPT_DEBUG)
1477          Print(" degree jumped: -> L%d\n",at);
1478#endif
1479        h->Clear();
1480        return -1;
1481      }
1482    }
1483    else if (d > reddeg)
1484    {
1485      if (d>=(long)strat->tailRing->bitmask)
1486      {
1487        if (h->pTotalDeg()+h->ecart >= (long)strat->tailRing->bitmask)
1488        {
1489          strat->overflow=TRUE;
1490          //Print("OVERFLOW in redHoney d=%ld, max=%ld\n",d,strat->tailRing->bitmask);
1491          h->GetP();
1492          at = strat->posInL(strat->L,strat->Ll,h,strat);
1493          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
1494          h->Clear();
1495          return -1;
1496        }
1497      }
1498      else if (TEST_OPT_PROT && (strat->Ll < 0) )
1499      {
1500        //h->wrp(); Print("<%d>\n",h->GetpLength());
1501        reddeg = d;
1502        Print(".%ld",d); mflush();
1503      }
1504    }
1505  }
1506}
1507
1508/*2
1509*  reduction procedure for the normal form
1510*/
1511
1512poly redNF (poly h,int &max_ind,int nonorm,kStrategy strat)
1513{
1514  if (h==NULL) return NULL;
1515  int j;
1516  max_ind=strat->sl;
1517
1518  if (0 > strat->sl)
1519  {
1520    return h;
1521  }
1522  LObject P(h);
1523  P.SetShortExpVector();
1524  P.bucket = kBucketCreate(currRing);
1525  kBucketInit(P.bucket,P.p,pLength(P.p));
1526  kbTest(P.bucket);
1527#ifdef HAVE_RINGS
1528  BOOLEAN is_ring = rField_is_Ring(currRing);
1529#endif
1530#ifdef KDEBUG
1531//  if (TEST_OPT_DEBUG)
1532//  {
1533//    PrintS("redNF: starting S:\n");
1534//    for( j = 0; j <= max_ind; j++ )
1535//    {
1536//      Print("S[%d] (of size: %d): ", j, pSize(strat->S[j]));
1537//      pWrite(strat->S[j]);
1538//    }
1539//  };
1540#endif
1541
1542  loop
1543  {
1544    j=kFindDivisibleByInS(strat,&max_ind,&P);
1545    if (j>=0)
1546    {
1547#ifdef HAVE_RINGS
1548      if (!is_ring)
1549      {
1550#endif
1551        int sl=pSize(strat->S[j]);
1552        int jj=j;
1553        loop
1554        {
1555          int sll;
1556          jj=kFindNextDivisibleByInS(strat,jj+1,max_ind,&P);
1557          if (jj<0) break;
1558          sll=pSize(strat->S[jj]);
1559          if (sll<sl)
1560          {
1561            #ifdef KDEBUG
1562            if (TEST_OPT_DEBUG) Print("better(S%d:%d -> S%d:%d)\n",j,sl,jj,sll);
1563            #endif
1564            //else if (TEST_OPT_PROT) { PrintS("b"); mflush(); }
1565            j=jj;
1566            sl=sll;
1567          }
1568        }
1569        if ((nonorm==0) && (!nIsOne(pGetCoeff(strat->S[j]))))
1570        {
1571          pNorm(strat->S[j]);
1572          //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
1573        }
1574#ifdef HAVE_RINGS
1575      }
1576#endif
1577      nNormalize(pGetCoeff(P.p));
1578#ifdef KDEBUG
1579      if (TEST_OPT_DEBUG)
1580      {
1581        PrintS("red:");
1582        wrp(h);
1583        PrintS(" with ");
1584        wrp(strat->S[j]);
1585      }
1586#endif
1587#ifdef HAVE_PLURAL
1588      if (rIsPluralRing(currRing))
1589      {
1590        number coef;
1591        nc_kBucketPolyRed(P.bucket,strat->S[j],&coef);
1592        nDelete(&coef);
1593      }
1594      else
1595#endif
1596      {
1597        number coef;
1598        coef=kBucketPolyRed(P.bucket,strat->S[j],pLength(strat->S[j]),strat->kNoether);
1599        nDelete(&coef);
1600      }
1601      h = kBucketGetLm(P.bucket);   // FRAGE OLIVER
1602      if (h==NULL)
1603      {
1604        kBucketDestroy(&P.bucket);
1605
1606#ifdef KDEBUG
1607//        if (TEST_OPT_DEBUG)
1608//        {
1609//          PrintS("redNF: starting S:\n");
1610//          for( j = 0; j <= max_ind; j++ )
1611//          {
1612//            Print("S[%d] (of size: %d): ", j, pSize(strat->S[j]));
1613//            pWrite(strat->S[j]);
1614//          }
1615//        };
1616#endif
1617
1618        return NULL;
1619      }
1620      kbTest(P.bucket);
1621      P.p=h;
1622      P.t_p=NULL;
1623      P.SetShortExpVector();
1624#ifdef KDEBUG
1625      if (TEST_OPT_DEBUG)
1626      {
1627        PrintS("\nto:");
1628        wrp(h);
1629        PrintLn();
1630      }
1631#endif
1632    }
1633    else
1634    {
1635      P.p=kBucketClear(P.bucket);
1636      kBucketDestroy(&P.bucket);
1637      pNormalize(P.p);
1638
1639#ifdef KDEBUG
1640//      if (TEST_OPT_DEBUG)
1641//      {
1642//        PrintS("redNF: starting S:\n");
1643//        for( j = 0; j <= max_ind; j++ )
1644//        {
1645//          Print("S[%d] (of size: %d): ", j, pSize(strat->S[j]));
1646//          pWrite(strat->S[j]);
1647//        }
1648//      };
1649#endif
1650
1651      return P.p;
1652    }
1653  }
1654}
1655
1656void kDebugPrint(kStrategy strat);
1657
1658ideal bba (ideal F, ideal Q,intvec *w,intvec *hilb,kStrategy strat)
1659{
1660  int   red_result = 1;
1661  int   olddeg,reduc;
1662  int hilbeledeg=1,hilbcount=0,minimcnt=0;
1663  BOOLEAN withT = FALSE;
1664  BITSET save;
1665  SI_SAVE_OPT1(save);
1666
1667  initBuchMoraCrit(strat); /*set Gebauer, honey, sugarCrit*/
1668  if(rField_is_Ring(currRing))
1669    initBuchMoraPosRing(strat);
1670  else
1671    initBuchMoraPos(strat);
1672  initHilbCrit(F,Q,&hilb,strat);
1673  initBba(strat);
1674  /*set enterS, spSpolyShort, reduce, red, initEcart, initEcartPair*/
1675  /*Shdl=*/initBuchMora(F, Q,strat);
1676  if (strat->minim>0) strat->M=idInit(IDELEMS(F),F->rank);
1677  reduc = olddeg = 0;
1678
1679#ifndef NO_BUCKETS
1680  if (!TEST_OPT_NOT_BUCKETS)
1681    strat->use_buckets = 1;
1682#endif
1683  // redtailBBa against T for inhomogenous input
1684  if (!TEST_OPT_OLDSTD)
1685    withT = ! strat->homog;
1686
1687  // strat->posInT = posInT_pLength;
1688  kTest_TS(strat);
1689
1690#ifdef HAVE_TAIL_RING
1691  if(!idIs0(F) &&(!rField_is_Ring(currRing)))  // create strong gcd poly computes with tailring and S[i] ->to be fixed
1692    kStratInitChangeTailRing(strat);
1693#endif
1694  if (BVERBOSE(23))
1695  {
1696    if (test_PosInT!=NULL) strat->posInT=test_PosInT;
1697    if (test_PosInL!=NULL) strat->posInL=test_PosInL;
1698    kDebugPrint(strat);
1699  }
1700
1701
1702#ifdef KDEBUG
1703  //kDebugPrint(strat);
1704#endif
1705  /* compute------------------------------------------------------- */
1706  while (strat->Ll >= 0)
1707  {
1708    #if ADIDEBUG
1709    printf("\n      ------------------------NEW LOOP\n");
1710    printf("\nShdl = \n");
1711    #if 0
1712    idPrint(strat->Shdl);
1713    #else
1714    for(int ii = 0; ii<=strat->sl;ii++)
1715        p_Write(strat->S[ii],strat->tailRing);
1716    #endif
1717    printf("\n   list   L\n");
1718    int iii;
1719    #if 1
1720    for(iii = 0; iii<= strat->Ll; iii++)
1721    {
1722        printf("L[%i]:",iii);
1723        p_Write(strat->L[iii].p, currRing);
1724        p_Write(strat->L[iii].p1, currRing);
1725        p_Write(strat->L[iii].p2, currRing);
1726    }
1727    #else
1728    {
1729        printf("L[%i]:",strat->Ll);
1730        p_Write(strat->L[strat->Ll].p, strat->tailRing);
1731        p_Write(strat->L[strat->Ll].p1, strat->tailRing);
1732        p_Write(strat->L[strat->Ll].p2, strat->tailRing);
1733    }
1734    #endif
1735    #if 0
1736    for(iii = 0; iii<= strat->Bl; iii++)
1737    {
1738        printf("B[%i]:",iii);
1739        p_Write(strat->B[iii].p, /*strat->tailRing*/currRing);
1740        p_Write(strat->B[iii].p1, /*strat->tailRing*/currRing);
1741        p_Write(strat->B[iii].p2, strat->tailRing);
1742    }
1743    #endif
1744    //getchar();
1745    #endif
1746    #ifdef KDEBUG
1747      if (TEST_OPT_DEBUG) messageSets(strat);
1748    #endif
1749    if (strat->Ll== 0) strat->interpt=TRUE;
1750    if (TEST_OPT_DEGBOUND
1751        && ((strat->honey && (strat->L[strat->Ll].ecart+currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
1752            || ((!strat->honey) && (currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))))
1753    {
1754      /*
1755       *stops computation if
1756       * 24 IN test and the degree +ecart of L[strat->Ll] is bigger then
1757       *a predefined number Kstd1_deg
1758       */
1759      while ((strat->Ll >= 0)
1760        && (strat->L[strat->Ll].p1!=NULL) && (strat->L[strat->Ll].p2!=NULL)
1761        && ((strat->honey && (strat->L[strat->Ll].ecart+currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
1762            || ((!strat->honey) && (currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg)))
1763        )
1764        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
1765      if (strat->Ll<0) break;
1766      else strat->noClearS=TRUE;
1767    }
1768    /* picks the last element from the lazyset L */
1769    strat->P = strat->L[strat->Ll];
1770    strat->Ll--;
1771
1772    if (pNext(strat->P.p) == strat->tail)
1773    {
1774      // deletes the short spoly
1775      if (rField_is_Ring(currRing))
1776        pLmDelete(strat->P.p);
1777      else
1778        pLmFree(strat->P.p);
1779      strat->P.p = NULL;
1780      poly m1 = NULL, m2 = NULL;
1781
1782      // check that spoly creation is ok
1783      while (strat->tailRing != currRing &&
1784             !kCheckSpolyCreation(&(strat->P), strat, m1, m2))
1785      {
1786        assume(m1 == NULL && m2 == NULL);
1787        // if not, change to a ring where exponents are at least
1788        // large enough
1789        if (!kStratChangeTailRing(strat))
1790        {
1791          WerrorS("OVERFLOW...");
1792          break;
1793        }
1794      }
1795      // create the real one
1796      ksCreateSpoly(&(strat->P), NULL, strat->use_buckets,
1797                    strat->tailRing, m1, m2, strat->R);
1798    }
1799    else if (strat->P.p1 == NULL)
1800    {
1801      if (strat->minim > 0)
1802        strat->P.p2=p_Copy(strat->P.p, currRing, strat->tailRing);
1803      // for input polys, prepare reduction
1804      strat->P.PrepareRed(strat->use_buckets);
1805    }
1806
1807    if (strat->P.p == NULL && strat->P.t_p == NULL)
1808    {
1809      red_result = 0;
1810    }
1811    else
1812    {
1813      if (TEST_OPT_PROT)
1814        message((strat->honey ? strat->P.ecart : 0) + strat->P.pFDeg(),
1815                &olddeg,&reduc,strat, red_result);
1816
1817      /* reduction of the element chosen from L */
1818      red_result = strat->red(&strat->P,strat);
1819      if (errorreported)  break;
1820    }
1821
1822    if (strat->overflow)
1823    {
1824      if (!kStratChangeTailRing(strat)) { Werror("OVERFLOW.."); break;}
1825    }
1826
1827    // reduction to non-zero new poly
1828    if (red_result == 1)
1829    {
1830      // get the polynomial (canonicalize bucket, make sure P.p is set)
1831      strat->P.GetP(strat->lmBin);
1832      // in the homogeneous case FDeg >= pFDeg (sugar/honey)
1833      // but now, for entering S, T, we reset it
1834      // in the inhomogeneous case: FDeg == pFDeg
1835      if (strat->homog) strat->initEcart(&(strat->P));
1836
1837      /* statistic */
1838      if (TEST_OPT_PROT) PrintS("s");
1839
1840      int pos=posInS(strat,strat->sl,strat->P.p,strat->P.ecart);
1841
1842      // reduce the tail and normalize poly
1843      // in the ring case we cannot expect LC(f) = 1,
1844      // therefore we call pContent instead of pNorm
1845      if ((TEST_OPT_INTSTRATEGY) || (rField_is_Ring(currRing)))
1846      {
1847        strat->P.pCleardenom();
1848        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
1849        {
1850          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
1851          strat->P.pCleardenom();
1852        }
1853      }
1854      else
1855      {
1856        strat->P.pNorm();
1857        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
1858          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
1859      }
1860
1861#ifdef KDEBUG
1862      if (TEST_OPT_DEBUG){PrintS("new s:");strat->P.wrp();PrintLn();}
1863#endif /* KDEBUG */
1864
1865      // min_std stuff
1866      if ((strat->P.p1==NULL) && (strat->minim>0))
1867      {
1868        if (strat->minim==1)
1869        {
1870          strat->M->m[minimcnt]=p_Copy(strat->P.p,currRing,strat->tailRing);
1871          p_Delete(&strat->P.p2, currRing, strat->tailRing);
1872        }
1873        else
1874        {
1875          strat->M->m[minimcnt]=strat->P.p2;
1876          strat->P.p2=NULL;
1877        }
1878        if (strat->tailRing!=currRing && pNext(strat->M->m[minimcnt])!=NULL)
1879          pNext(strat->M->m[minimcnt])
1880            = strat->p_shallow_copy_delete(pNext(strat->M->m[minimcnt]),
1881                                           strat->tailRing, currRing,
1882                                           currRing->PolyBin);
1883        minimcnt++;
1884      }
1885
1886      // enter into S, L, and T
1887      if ((!TEST_OPT_IDLIFT) || (pGetComp(strat->P.p) <= strat->syzComp))
1888      {
1889        enterT(strat->P, strat);
1890        if (rField_is_Ring(currRing))
1891          superenterpairs(strat->P.p,strat->sl,strat->P.ecart,pos,strat, strat->tl);
1892        else
1893          enterpairs(strat->P.p,strat->sl,strat->P.ecart,pos,strat, strat->tl);
1894        // posInS only depends on the leading term
1895        strat->enterS(strat->P, pos, strat, strat->tl);
1896        #if ADIDEBUG
1897        printf("\nThis element has been added to S:\n");pWrite(strat->P.p);pWrite(strat->P.p1);pWrite(strat->P.p2);
1898        #endif
1899#if 0
1900        int pl=pLength(strat->P.p);
1901        if (pl==1)
1902        {
1903          //if (TEST_OPT_PROT)
1904          //PrintS("<1>");
1905        }
1906        else if (pl==2)
1907        {
1908          //if (TEST_OPT_PROT)
1909          //PrintS("<2>");
1910        }
1911#endif
1912      }
1913      if (hilb!=NULL) khCheck(Q,w,hilb,hilbeledeg,hilbcount,strat);
1914//      Print("[%d]",hilbeledeg);
1915      if (strat->P.lcm!=NULL)
1916      {
1917        if (rField_is_Ring(currRing)) pLmDelete(strat->P.lcm);
1918        else                          pLmFree(strat->P.lcm);
1919        strat->P.lcm=NULL;
1920      }
1921      if (strat->s_poly!=NULL)
1922      {
1923        // the only valid entries are: strat->P.p,
1924        // strat->tailRing (read-only, keep it)
1925        // (and P->p1, P->p2 (read-only, must set to NULL if P.p is changed)
1926        if (strat->s_poly(strat))
1927        {
1928          // we are called AFTER enterS, i.e. if we change P
1929          // we have to add it also to S/T
1930          // and add pairs
1931          int pos=posInS(strat,strat->sl,strat->P.p,strat->P.ecart);
1932          enterT(strat->P, strat);
1933          if (rField_is_Ring(currRing))
1934            superenterpairs(strat->P.p,strat->sl,strat->P.ecart,pos,strat, strat->tl);
1935          else
1936            enterpairs(strat->P.p,strat->sl,strat->P.ecart,pos,strat, strat->tl);
1937          strat->enterS(strat->P, pos, strat, strat->tl);
1938        }
1939      }
1940    }
1941    else if (strat->P.p1 == NULL && strat->minim > 0)
1942    {
1943      p_Delete(&strat->P.p2, currRing, strat->tailRing);
1944    }
1945
1946#ifdef KDEBUG
1947    memset(&(strat->P), 0, sizeof(strat->P));
1948#endif /* KDEBUG */
1949    kTest_TS(strat);
1950  }
1951#ifdef KDEBUG
1952  if (TEST_OPT_DEBUG) messageSets(strat);
1953#endif /* KDEBUG */
1954
1955  if (TEST_OPT_SB_1)
1956  {
1957    if(!rField_is_Ring(currRing))
1958    {
1959      int k=1;
1960      int j;
1961      while(k<=strat->sl)
1962      {
1963        j=0;
1964        loop
1965        {
1966          if (j>=k) break;
1967          clearS(strat->S[j],strat->sevS[j],&k,&j,strat);
1968          j++;
1969        }
1970        k++;
1971      }
1972    }
1973  }
1974  /* complete reduction of the standard basis--------- */
1975  if (TEST_OPT_REDSB)
1976  {
1977    completeReduce(strat);
1978#ifdef HAVE_TAIL_RING
1979    if (strat->completeReduce_retry)
1980    {
1981      // completeReduce needed larger exponents, retry
1982      // to reduce with S (instead of T)
1983      // and in currRing (instead of strat->tailRing)
1984      cleanT(strat);strat->tailRing=currRing;
1985      int i;
1986      for(i=strat->sl;i>=0;i--) strat->S_2_R[i]=-1;
1987      completeReduce(strat);
1988    }
1989#endif
1990  }
1991  else if (TEST_OPT_PROT) PrintLn();
1992  if(nCoeff_is_Ring_Z(currRing->cf))
1993    finalReduceByMon(strat);
1994  if(rField_is_Ring(currRing))
1995  {
1996    for(int i = 0;i<=strat->sl;i++)
1997    {
1998      if(!nGreaterZero(pGetCoeff(strat->S[i])))
1999      {
2000        strat->S[i] = pNeg(strat->S[i]);
2001      }
2002    }
2003  }
2004  /* release temp data-------------------------------- */
2005  exitBuchMora(strat);
2006//  if (TEST_OPT_WEIGHTM)
2007//  {
2008//    pRestoreDegProcs(currRing,pFDegOld, pLDegOld);
2009//    if (ecartWeights)
2010//    {
2011//      omFreeSize((ADDRESS)ecartWeights,((currRing->N)+1)*sizeof(short));
2012//      ecartWeights=NULL;
2013//    }
2014//  }
2015  if ((TEST_OPT_PROT) || (TEST_OPT_DEBUG)) messageStat(hilbcount,strat);
2016  SI_RESTORE_OPT1(save);
2017  if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
2018
2019  idTest(strat->Shdl);
2020
2021  return (strat->Shdl);
2022}
2023
2024ideal sba (ideal F0, ideal Q,intvec *w,intvec *hilb,kStrategy strat)
2025{
2026  // ring order stuff:
2027  // in sba we have (until now) two possibilities:
2028  // 1. an incremental computation w.r.t. (C,monomial order)
2029  // 2. a (possibly non-incremental) computation w.r.t. the
2030  //    induced Schreyer order.
2031  // The corresponding orders are computed in sbaRing(), depending
2032  // on the flag strat->sbaOrder
2033#if SBA_PRINT_ZERO_REDUCTIONS
2034  long zeroreductions           = 0;
2035#endif
2036#if SBA_PRINT_PRODUCT_CRITERION
2037  long product_criterion        = 0;
2038#endif
2039#if SBA_PRINT_SIZE_G
2040  int size_g                    = 0;
2041  int size_g_non_red            = 0;
2042#endif
2043#if SBA_PRINT_SIZE_SYZ
2044  long size_syz                 = 0;
2045#endif
2046  // global variable
2047#if SBA_PRINT_REDUCTION_STEPS
2048  sba_reduction_steps           = 0;
2049  sba_interreduction_steps      = 0;
2050#endif
2051#if SBA_PRINT_OPERATIONS
2052  sba_operations                = 0;
2053  sba_interreduction_operations = 0;
2054#endif
2055 
2056  ideal F1 = F0;
2057  ring sRing, currRingOld;
2058  currRingOld  = currRing;
2059  if (strat->sbaOrder == 1 || strat->sbaOrder == 3)
2060  {
2061    sRing = sbaRing(strat);
2062    if (sRing!=currRingOld)
2063    {
2064      rChangeCurrRing (sRing);
2065      F1 = idrMoveR (F0, currRingOld, currRing);
2066    }
2067  }
2068  ideal F;
2069  // sort ideal F
2070  //Put the SigDrop element on the correct position (think of sbaEnterS)
2071  //We also sort them
2072  if(rField_is_Ring(currRing) && strat->sigdrop)
2073  {
2074    #if 1
2075    F = idInit(IDELEMS(F1),F1->rank);
2076    for (int i=0; i<IDELEMS(F1);++i)
2077      F->m[i] = F1->m[i];
2078    if(strat->sbaEnterS >= 0)
2079    {
2080      poly dummy;
2081      dummy = pCopy(F->m[0]); //the sigdrop element
2082      for(int i = 0;i<strat->sbaEnterS;i++)
2083        F->m[i] = F->m[i+1];
2084      F->m[strat->sbaEnterS] = dummy;
2085    }
2086    #else
2087    F = idInit(1,F1->rank);
2088    //printf("\nBefore the initial block sorting:\n");idPrint(F1);
2089    F->m[0] = F1->m[0];
2090    int pos;
2091    if(strat->sbaEnterS >= 0)
2092    {
2093      for(int i=1;i<=strat->sbaEnterS;i++)
2094      {
2095        pos = posInIdealMonFirst(F,F1->m[i],1,strat->sbaEnterS);
2096        idInsertPolyOnPos(F,F1->m[i],pos);
2097      }
2098      for(int i=strat->sbaEnterS+1;i<IDELEMS(F1);i++)
2099      {
2100        pos = posInIdealMonFirst(F,F1->m[i],strat->sbaEnterS+1,IDELEMS(F));
2101        idInsertPolyOnPos(F,F1->m[i],pos);
2102      }
2103      poly dummy;
2104      dummy = pCopy(F->m[0]); //the sigdrop element
2105      for(int i = 0;i<strat->sbaEnterS;i++)
2106        F->m[i] = F->m[i+1];
2107      F->m[strat->sbaEnterS] = dummy;
2108    }
2109    else
2110    {
2111      for(int i=1;i<IDELEMS(F1);i++)
2112      {
2113        pos = posInIdealMonFirst(F,F1->m[i],1,IDELEMS(F));
2114        idInsertPolyOnPos(F,F1->m[i],pos);
2115      }
2116    }
2117    #endif
2118    //printf("\nAfter the initial block sorting:\n");idPrint(F);getchar();
2119  }
2120  else
2121  {
2122    F       = idInit(IDELEMS(F1),F1->rank);
2123    intvec *sort  = idSort(F1);
2124    for (int i=0; i<sort->length();++i)
2125      F->m[i] = F1->m[(*sort)[i]-1];
2126  // put the monomials after the sbaEnterS polynomials
2127  //printf("\nThis is the ideal before sorting (sbaEnterS = %i)\n",strat->sbaEnterS);idPrint(F);
2128  int nrmon = 0;
2129  for(int i = IDELEMS(F)-1,j;i>strat->sbaEnterS+nrmon+1 ;i--)
2130  {
2131    //pWrite(F->m[i]);
2132    if(F->m[i] != NULL && pNext(F->m[i]) == NULL)
2133    {
2134      poly mon = F->m[i];
2135      for(j = i;j>strat->sbaEnterS+nrmon+1;j--)
2136      {
2137        F->m[j] = F->m[j-1];
2138      }
2139      F->m[j] = mon;
2140      nrmon++;
2141    }
2142    //idPrint(F);
2143  }
2144  }
2145    //printf("\nThis is the ideal after sorting\n");idPrint(F);getchar();
2146  #ifdef HAVE_RINGS
2147  if(rField_is_Ring(currRing))
2148    strat->sigdrop = FALSE;
2149  strat->nrsyzcrit = 0;
2150  strat->nrrewcrit = 0;
2151  #endif
2152#if SBA_INTERRED_START
2153  F = kInterRed(F,NULL);
2154#endif
2155#if F5DEBUG
2156  printf("SBA COMPUTATIONS DONE IN THE FOLLOWING RING:\n");
2157  rWrite (currRing);
2158  printf("ordSgn = %d\n",currRing->OrdSgn);
2159  printf("\n");
2160#endif
2161  int   srmax,lrmax, red_result = 1;
2162  int   olddeg,reduc;
2163  int hilbeledeg=1,hilbcount=0,minimcnt=0;
2164  LObject L;
2165  BOOLEAN withT     = TRUE;
2166  strat->max_lower_index = 0;
2167  //initBuchMoraCrit(strat); /*set Gebauer, honey, sugarCrit*/
2168  initSbaCrit(strat); /*set Gebauer, honey, sugarCrit*/
2169  initSbaPos(strat);
2170  initHilbCrit(F,Q,&hilb,strat);
2171  initSba(F,strat);
2172  /*set enterS, spSpolyShort, reduce, red, initEcart, initEcartPair*/
2173  /*Shdl=*/initSbaBuchMora(F, Q,strat);
2174  if (strat->minim>0) strat->M=idInit(IDELEMS(F),F->rank);
2175  srmax = strat->sl;
2176  reduc = olddeg = lrmax = 0;
2177#ifndef NO_BUCKETS
2178  if (!TEST_OPT_NOT_BUCKETS)
2179    strat->use_buckets = 1;
2180#endif
2181
2182  // redtailBBa against T for inhomogenous input
2183  // if (!TEST_OPT_OLDSTD)
2184  //   withT = ! strat->homog;
2185
2186  // strat->posInT = posInT_pLength;
2187  kTest_TS(strat);
2188
2189#ifdef HAVE_TAIL_RING
2190  if(!idIs0(F) &&(!rField_is_Ring(currRing)))  // create strong gcd poly computes with tailring and S[i] ->to be fixed
2191    kStratInitChangeTailRing(strat);
2192#endif
2193  if (BVERBOSE(23))
2194  {
2195    if (test_PosInT!=NULL) strat->posInT=test_PosInT;
2196    if (test_PosInL!=NULL) strat->posInL=test_PosInL;
2197    kDebugPrint(strat);
2198  }
2199  // We add the elements directly in S from the previous loop
2200  if(rField_is_Ring(currRing) && strat->sbaEnterS >= 0)
2201  {
2202    for(int i = 0;i<strat->sbaEnterS;i++)
2203    {
2204      //Update: now the element is at the corect place
2205      //i+1 because on the 0 position is the sigdrop element
2206      enterT(strat->L[strat->Ll-(i)],strat);
2207      strat->enterS(strat->L[strat->Ll-(i)], strat->sl+1, strat, strat->tl);
2208    }
2209    strat->Ll = strat->Ll - strat->sbaEnterS; 
2210    strat->sbaEnterS = -1;
2211  }
2212  kTest_TS(strat);
2213#ifdef KDEBUG
2214  //kDebugPrint(strat);
2215#endif
2216  /* compute------------------------------------------------------- */
2217  while (strat->Ll >= 0)
2218  {
2219    #if ADIDEBUG
2220    printf("\n      ------------------------NEW LOOP\n");
2221    printf("\nShdl = \n");
2222    #if 0
2223    idPrint(strat->Shdl);
2224    #else
2225    for(int ii = 0; ii<=strat->sl;ii++)
2226    {
2227      printf("\nS[%i]:  ",ii);p_Write(strat->S[ii],strat->tailRing);
2228      printf("sig:   ");pWrite(strat->sig[ii]);
2229    }
2230    #endif
2231    #if 0
2232    for(int iii = 0; iii< strat->syzl; iii++)
2233    {
2234        printf("\nsyz[%i]:\n",iii);
2235        p_Write(strat->syz[iii], currRing);
2236    }
2237    #endif
2238    #if 0
2239    for(int iii = 0; iii<= strat->tl; iii++)
2240    {
2241        printf("\nT[%i]:\n",iii);
2242        p_Write(strat->T[iii].p, currRing);
2243    }
2244    #endif
2245    printf("\n   list   L\n");
2246    int iii;
2247    #if 1
2248    for(iii = 0; iii<= strat->Ll; iii++)
2249    {
2250        printf("\nL[%i]:\n",iii);
2251        p_Write(strat->L[iii].p, currRing);
2252        p_Write(strat->L[iii].p1, currRing);
2253        p_Write(strat->L[iii].p2, currRing);
2254        p_Write(strat->L[iii].sig, currRing);
2255    }
2256    #else
2257    {
2258        printf("L[%i]:",strat->Ll);
2259        p_Write(strat->L[strat->Ll].p, strat->tailRing);
2260        p_Write(strat->L[strat->Ll].p1, strat->tailRing);
2261        p_Write(strat->L[strat->Ll].p2, strat->tailRing);
2262        p_Write(strat->L[strat->Ll].sig, strat->tailRing);
2263    }
2264    #endif
2265    //getchar();
2266    #endif
2267    if (strat->Ll > lrmax) lrmax =strat->Ll;/*stat.*/
2268    #ifdef KDEBUG
2269      if (TEST_OPT_DEBUG) messageSets(strat);
2270    #endif
2271    if (strat->Ll== 0) strat->interpt=TRUE;
2272    /*
2273    if (TEST_OPT_DEGBOUND
2274        && ((strat->honey && (strat->L[strat->Ll].ecart+currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
2275            || ((!strat->honey) && (currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))))
2276    {
2277
2278       //stops computation if
2279       // 24 IN test and the degree +ecart of L[strat->Ll] is bigger then
2280       //a predefined number Kstd1_deg
2281      while ((strat->Ll >= 0)
2282        && (strat->L[strat->Ll].p1!=NULL) && (strat->L[strat->Ll].p2!=NULL)
2283        && ((strat->honey && (strat->L[strat->Ll].ecart+currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
2284            || ((!strat->honey) && (currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg)))
2285        )
2286        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
2287      if (strat->Ll<0) break;
2288      else strat->noClearS=TRUE;
2289    }
2290    */
2291    if (strat->sbaOrder == 1 && pGetComp(strat->L[strat->Ll].sig) != strat->currIdx)
2292    {
2293      strat->currIdx  = pGetComp(strat->L[strat->Ll].sig);
2294#if F5C
2295      // 1. interreduction of the current standard basis
2296      // 2. generation of new principal syzygy rules for syzCriterion
2297      f5c ( strat, olddeg, minimcnt, hilbeledeg, hilbcount, srmax,
2298          lrmax, reduc, Q, w, hilb );
2299#endif
2300      // initialize new syzygy rules for the next iteration step
2301      initSyzRules(strat);
2302    }
2303    /*********************************************************************
2304      * interrreduction step is done, we can go on with the next iteration
2305      * step of the signature-based algorithm
2306      ********************************************************************/
2307    /* picks the last element from the lazyset L */
2308    strat->P = strat->L[strat->Ll];
2309    strat->Ll--;
2310   
2311    if(rField_is_Ring(currRing))
2312      strat->sbaEnterS = pGetComp(strat->P.sig) - 1;
2313   
2314    #if ADIDEBUG
2315    printf("\n-------------------------\nThis is the current element P\n");
2316    pWrite(strat->P.p);
2317    pWrite(strat->P.p1);
2318    pWrite(strat->P.p2);
2319    pWrite(strat->P.sig);
2320    #endif
2321    /* reduction of the element chosen from L */
2322    // We do not delete via RewCrit strong pairs or extended spolys over rings
2323    // these should have .lcm = NULL
2324    if (strat->P.lcm == NULL || !strat->rewCrit2(strat->P.sig, ~strat->P.sevSig, strat->P.GetLmCurrRing(), strat, strat->P.checked+1)) {
2325      //#if 1
2326#ifdef DEBUGF5
2327      Print("SIG OF NEXT PAIR TO HANDLE IN SIG-BASED ALGORITHM\n");
2328      Print("-------------------------------------------------\n");
2329      pWrite(strat->P.sig);
2330      pWrite(pHead(strat->P.p));
2331      pWrite(pHead(strat->P.p1));
2332      pWrite(pHead(strat->P.p2));
2333      Print("-------------------------------------------------\n");
2334#endif
2335      if (pNext(strat->P.p) == strat->tail)
2336      {
2337        // deletes the short spoly
2338        /*
2339        if (rField_is_Ring(currRing))
2340          pLmDelete(strat->P.p);
2341        else
2342          pLmFree(strat->P.p);
2343*/
2344          // TODO: needs some masking
2345          // TODO: masking needs to vanish once the signature
2346          //       sutff is completely implemented
2347          strat->P.p = NULL;
2348        poly m1 = NULL, m2 = NULL;
2349
2350        // check that spoly creation is ok
2351        while (strat->tailRing != currRing &&
2352            !kCheckSpolyCreation(&(strat->P), strat, m1, m2))
2353        {
2354          assume(m1 == NULL && m2 == NULL);
2355          // if not, change to a ring where exponents are at least
2356          // large enough
2357          if (!kStratChangeTailRing(strat))
2358          {
2359            WerrorS("OVERFLOW...");
2360            break;
2361          }
2362        }
2363        // create the real one
2364        ksCreateSpoly(&(strat->P), NULL, strat->use_buckets,
2365            strat->tailRing, m1, m2, strat->R);
2366
2367      }
2368      else if (strat->P.p1 == NULL)
2369      {
2370        if (strat->minim > 0)
2371          strat->P.p2=p_Copy(strat->P.p, currRing, strat->tailRing);
2372        // for input polys, prepare reduction
2373        if(!rField_is_Ring(currRing))
2374          strat->P.PrepareRed(strat->use_buckets);
2375      }
2376      if (strat->P.p == NULL && strat->P.t_p == NULL)
2377      {
2378        red_result = 0;
2379      }
2380      else
2381      {
2382        //#if 1
2383#ifdef DEBUGF5
2384        Print("Poly before red: ");
2385        pWrite(pHead(strat->P.p));
2386        pWrite(strat->P.sig);
2387#endif
2388#if SBA_PRODUCT_CRITERION
2389        if (strat->P.prod_crit) {
2390#if SBA_PRINT_PRODUCT_CRITERION
2391          product_criterion++;
2392#endif
2393          int pos = posInSyz(strat, strat->P.sig);
2394          enterSyz(strat->P, strat, pos);
2395          if (strat->P.lcm!=NULL)
2396            pLmFree(strat->P.lcm);
2397          red_result = 2;
2398        } else {
2399          red_result = strat->red(&strat->P,strat);
2400        }
2401#else
2402        red_result = strat->red(&strat->P,strat);
2403#endif
2404      }
2405    } else {
2406      /*
2407      if (strat->P.lcm != NULL)
2408        pLmFree(strat->P.lcm);
2409        */
2410      red_result = 2;
2411    }
2412    if(rField_is_Ring(currRing))
2413    {
2414      if(strat->P.sig!= NULL && !nGreaterZero(pGetCoeff(strat->P.sig)))
2415      {
2416        strat->P.p = pNeg(strat->P.p);
2417        strat->P.sig = pNeg(strat->P.sig);
2418      }
2419      strat->P.pLength = pLength(strat->P.p);
2420      if(strat->P.sig != NULL)
2421        strat->P.sevSig = pGetShortExpVector(strat->P.sig);
2422      if(strat->P.p != NULL)
2423        strat->P.sev = pGetShortExpVector(strat->P.p);
2424    }
2425    #if ADIDEBUG
2426    printf("\nAfter reduce (redresult=%i): \n",red_result);pWrite(strat->P.p);pWrite(strat->P.sig);
2427    #endif
2428    //sigdrop case
2429    if(rField_is_Ring(currRing) && strat->sigdrop)
2430    {
2431      //First reduce it as much as one can
2432      #if ADIDEBUG
2433      printf("\nSigdrop in the reduce. Trying redring\n");
2434      #endif
2435      red_result = redRing(&strat->P,strat);
2436      if(red_result == 0)
2437      {
2438        #if ADIDEBUG
2439        printf("\nSigdrop cancelled since redRing reduced to 0\n");
2440        #endif
2441        strat->sigdrop = FALSE;
2442        pDelete(&strat->P.sig);
2443        strat->P.sig = NULL;
2444      }
2445      else
2446      {
2447        #if ADIDEBUG
2448        printf("\nStill Sigdrop - redRing reduced to:\n");pWrite(strat->P.p);
2449        #endif
2450        strat->enterS(strat->P, 0, strat, strat->tl);
2451        if (TEST_OPT_PROT)
2452          PrintS("-");
2453        break;
2454      }
2455    }
2456    if(strat->blockred > strat->blockredmax)
2457    {
2458      #if ADIDEBUG
2459      printf("\nToo many blocked reductions\n");
2460      #endif
2461      strat->sigdrop = TRUE;
2462      break;
2463    }
2464   
2465    if (errorreported)  break;
2466
2467//#if 1
2468#ifdef DEBUGF5
2469    if (red_result != 0) {
2470        Print("Poly after red: ");
2471        pWrite(pHead(strat->P.p));
2472        pWrite(strat->P.GetLmCurrRing());
2473        pWrite(strat->P.sig);
2474        printf("%d\n",red_result);
2475    }
2476#endif
2477    if (TEST_OPT_PROT)
2478    {
2479      if(strat->P.p != NULL)
2480        message((strat->honey ? strat->P.ecart : 0) + strat->P.pFDeg(),
2481                &olddeg,&reduc,strat, red_result);
2482      else
2483        message((strat->honey ? strat->P.ecart : 0),
2484                &olddeg,&reduc,strat, red_result);
2485    }
2486
2487    if (strat->overflow)
2488    {
2489        if (!kStratChangeTailRing(strat)) { Werror("OVERFLOW.."); break;}
2490    }
2491    // reduction to non-zero new poly
2492    if (red_result == 1)
2493    {
2494      // get the polynomial (canonicalize bucket, make sure P.p is set)
2495      strat->P.GetP(strat->lmBin);
2496
2497      // sig-safe computations may lead to wrong FDeg computation, thus we need
2498      // to recompute it to make sure everything is alright
2499      (strat->P).FDeg = (strat->P).pFDeg();
2500      // in the homogeneous case FDeg >= pFDeg (sugar/honey)
2501      // but now, for entering S, T, we reset it
2502      // in the inhomogeneous case: FDeg == pFDeg
2503      if (strat->homog) strat->initEcart(&(strat->P));
2504
2505      /* statistic */
2506      if (TEST_OPT_PROT) PrintS("s");
2507
2508      //int pos=posInS(strat,strat->sl,strat->P.p,strat->P.ecart);
2509      // in F5E we know that the last reduced element is already the
2510      // the one with highest signature
2511      int pos = strat->sl+1;
2512
2513      // reduce the tail and normalize poly
2514      // in the ring case we cannot expect LC(f) = 1,
2515      // therefore we call pContent instead of pNorm
2516      #ifdef HAVE_RINGS
2517      poly beforetailred;
2518      if(rField_is_Ring(currRing))
2519        beforetailred = pCopy(strat->P.sig);
2520      #endif
2521#if SBA_TAIL_RED
2522      if(rField_is_Ring(currRing))
2523      { 
2524        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
2525          strat->P.p = redtailSba(&(strat->P),pos-1,strat, withT);
2526      }
2527      else
2528      {
2529        if (strat->sbaOrder != 2) {
2530          if (TEST_OPT_INTSTRATEGY)
2531          {
2532            strat->P.pCleardenom();
2533            if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
2534            {
2535              strat->P.p = redtailSba(&(strat->P),pos-1,strat, withT);
2536              strat->P.pCleardenom();
2537            }
2538          }
2539          else
2540          {
2541            strat->P.pNorm();
2542            if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
2543              strat->P.p = redtailSba(&(strat->P),pos-1,strat, withT);
2544          }
2545        }
2546      }
2547      // It may happen that we have lost the sig in redtailsba
2548      // It cannot reduce to 0 since here we are doing just tail reduction.
2549      // Best case scenerio: remains the leading term
2550      if(rField_is_Ring(currRing) && strat->sigdrop)     
2551      {
2552        #if ADIDEBUG
2553        printf("\n Still sigdrop after redtailSba - it reduced to \n");pWrite(strat->P.p);
2554        #endif
2555        strat->enterS(strat->P, 0, strat, strat->tl);
2556        break;
2557      }
2558#endif
2559    if(rField_is_Ring(currRing))
2560    {
2561      if(strat->P.sig == NULL || pLtCmp(beforetailred,strat->P.sig) == 1)
2562      {
2563        #if ADIDEBUG
2564        printf("\nSigDrop after TAILred\n");pWrite(beforetailred);pWrite(strat->P.sig);
2565        #endif
2566        strat->sigdrop = TRUE;
2567        //Reduce it as much as you can
2568        red_result = redRing(&strat->P,strat);
2569        if(red_result == 0)
2570        {
2571          //It reduced to 0, cancel the sigdrop
2572          #if ADIDEBUG
2573          printf("\nReduced to 0 via redRing. Cancel sigdrop\n");
2574          #endif
2575          strat->sigdrop = FALSE;
2576          p_Delete(&strat->P.sig,currRing);strat->P.sig = NULL;
2577        }
2578        else
2579        {
2580          #if ADIDEBUG
2581          printf("\nReduced to this via redRing.SIGDROP\n");pWrite(strat->P.p);
2582          #endif
2583          strat->enterS(strat->P, 0, strat, strat->tl);
2584          break;
2585        }
2586      }
2587      p_Delete(&beforetailred,currRing);
2588      // strat->P.p = NULL may appear if we had  a sigdrop above and reduced to 0 via redRing
2589      if(strat->P.p == NULL)
2590        goto case_when_red_result_changed;
2591    }
2592    #if ADIDEBUG
2593    printf("\nNach redTailSba: \n");
2594    pWrite(strat->P.p);pWrite(strat->P.sig);
2595    #endif
2596    // remove sigsafe label since it is no longer valid for the next element to
2597    // be reduced
2598    if (strat->sbaOrder == 1)
2599    {
2600      for (int jj = 0; jj<strat->tl+1; jj++)
2601      {
2602        if (pGetComp(strat->T[jj].sig) == strat->currIdx)
2603        {
2604          strat->T[jj].is_sigsafe = FALSE;
2605        }
2606      }
2607    }
2608    else
2609    {
2610      for (int jj = 0; jj<strat->tl+1; jj++)
2611      {
2612        strat->T[jj].is_sigsafe = FALSE;
2613      }
2614    }
2615#ifdef KDEBUG
2616      if (TEST_OPT_DEBUG){PrintS("new s:");strat->P.wrp();PrintLn();}
2617#endif /* KDEBUG */
2618
2619      // min_std stuff
2620      if ((strat->P.p1==NULL) && (strat->minim>0))
2621      {
2622        if (strat->minim==1)
2623        {
2624          strat->M->m[minimcnt]=p_Copy(strat->P.p,currRing,strat->tailRing);
2625          p_Delete(&strat->P.p2, currRing, strat->tailRing);
2626        }
2627        else
2628        {
2629          strat->M->m[minimcnt]=strat->P.p2;
2630          strat->P.p2=NULL;
2631        }
2632        if (strat->tailRing!=currRing && pNext(strat->M->m[minimcnt])!=NULL)
2633          pNext(strat->M->m[minimcnt])
2634            = strat->p_shallow_copy_delete(pNext(strat->M->m[minimcnt]),
2635                                           strat->tailRing, currRing,
2636                                           currRing->PolyBin);
2637        minimcnt++;
2638      }
2639
2640      // enter into S, L, and T
2641      //if ((!TEST_OPT_IDLIFT) || (pGetComp(strat->P.p) <= strat->syzComp))
2642      enterT(strat->P, strat);
2643      strat->T[strat->tl].is_sigsafe = FALSE;
2644      /*
2645      printf("hier\n");
2646      pWrite(strat->P.GetLmCurrRing());
2647      pWrite(strat->P.sig);
2648      */
2649      if (rField_is_Ring(currRing))
2650        superenterpairsSig(strat->P.p,strat->P.sig,strat->sl+1,strat->sl,strat->P.ecart,pos,strat, strat->tl);
2651      else
2652        enterpairsSig(strat->P.p,strat->P.sig,strat->sl+1,strat->sl,strat->P.ecart,pos,strat, strat->tl);
2653      #if ADIDEBUG
2654        printf("\nThis element is added to S\n");
2655        p_Write(strat->P.p, strat->tailRing);p_Write(strat->P.p1, strat->tailRing);p_Write(strat->P.p2, strat->tailRing);pWrite(strat->P.sig);
2656        getchar();
2657        #endif
2658      // posInS only depends on the leading term
2659     
2660      if(rField_is_Ring(currRing) && strat->sigdrop)
2661        break;
2662      strat->P.sevSig = p_GetShortExpVector(strat->P.sig,currRing);
2663      strat->enterS(strat->P, pos, strat, strat->tl);
2664     
2665      if(strat->sbaOrder != 1)
2666      {
2667        BOOLEAN overwrite = FALSE;
2668        for (int tk=0; tk<strat->sl+1; tk++)
2669        {
2670          if (pGetComp(strat->sig[tk]) == pGetComp(strat->P.sig))
2671          {
2672            //printf("TK %d / %d\n",tk,strat->sl);
2673            overwrite = FALSE;
2674            break;
2675          }
2676        }
2677        //printf("OVERWRITE %d\n",overwrite);
2678        if (overwrite)
2679        {
2680          int cmp = pGetComp(strat->P.sig);
2681          int* vv = (int*)omAlloc((currRing->N+1)*sizeof(int));
2682          pGetExpV (strat->P.p,vv);
2683          pSetExpV (strat->P.sig, vv);
2684          pSetComp (strat->P.sig,cmp);
2685
2686          strat->P.sevSig = pGetShortExpVector (strat->P.sig);
2687          int i;
2688          LObject Q;
2689          for(int ps=0;ps<strat->sl+1;ps++)
2690          {
2691
2692            strat->newt = TRUE;
2693            if (strat->syzl == strat->syzmax)
2694            {
2695              pEnlargeSet(&strat->syz,strat->syzmax,setmaxTinc);
2696              strat->sevSyz = (unsigned long*) omRealloc0Size(strat->sevSyz,
2697                  (strat->syzmax)*sizeof(unsigned long),
2698                  ((strat->syzmax)+setmaxTinc)
2699                  *sizeof(unsigned long));
2700              strat->syzmax += setmaxTinc;
2701            }
2702            Q.sig = pCopy(strat->P.sig);
2703            // add LM(F->m[i]) to the signature to get a Schreyer order
2704            // without changing the underlying polynomial ring at all
2705            if (strat->sbaOrder == 0)
2706              p_ExpVectorAdd (Q.sig,strat->S[ps],currRing);
2707            // since p_Add_q() destroys all input
2708            // data we need to recreate help
2709            // each time
2710            // ----------------------------------------------------------
2711            // in the Schreyer order we always know that the multiplied
2712            // module monomial strat->P.sig gives the leading monomial of
2713            // the corresponding principal syzygy
2714            // => we do not need to compute the "real" syzygy completely
2715            poly help = p_Copy(strat->sig[ps],currRing);
2716            p_ExpVectorAdd (help,strat->P.p,currRing);
2717            Q.sig = p_Add_q(Q.sig,help,currRing);
2718            //printf("%d. SYZ  ",i+1);
2719            //pWrite(strat->syz[i]);
2720            Q.sevSig = p_GetShortExpVector(Q.sig,currRing);
2721            i = posInSyz(strat, Q.sig);
2722            enterSyz(Q, strat, i);
2723          }
2724        }
2725      }
2726      // deg - idx - lp/rp
2727      // => we need to add syzygies with indices > pGetComp(strat->P.sig)
2728      if(strat->sbaOrder == 0 || strat->sbaOrder == 3)
2729      {
2730        int cmp     = pGetComp(strat->P.sig);
2731        int max_cmp = IDELEMS(F);
2732        int* vv = (int*)omAlloc((currRing->N+1)*sizeof(int));
2733        pGetExpV (strat->P.p,vv);
2734        LObject Q;
2735        int pos;
2736        int idx = p_GetComp(strat->P.sig,currRing);
2737        //printf("++ -- adding syzygies -- ++\n");
2738        // if new element is the first one in this index
2739        if (strat->currIdx < idx) {
2740          for (int i=0; i<strat->sl; ++i) {
2741            Q.sig = p_Copy(strat->P.sig,currRing);
2742            p_ExpVectorAdd(Q.sig,strat->S[i],currRing);
2743            poly help = p_Copy(strat->sig[i],currRing);
2744            p_ExpVectorAdd(help,strat->P.p,currRing);
2745            Q.sig = p_Add_q(Q.sig,help,currRing);
2746            //pWrite(Q.sig);
2747            pos = posInSyz(strat, Q.sig);
2748            enterSyz(Q, strat, pos);
2749          }
2750          strat->currIdx = idx;
2751        } else {
2752          // if the element is not the first one in the given index we build all
2753          // possible syzygies with elements of higher index
2754          for (int i=cmp+1; i<=max_cmp; ++i) {
2755            pos = -1;
2756            for (int j=0; j<strat->sl; ++j) {
2757              if (p_GetComp(strat->sig[j],currRing) == i) {
2758                pos = j;
2759                break;
2760              }
2761            }
2762            if (pos != -1) {
2763              Q.sig = p_One(currRing);
2764              p_SetExpV(Q.sig, vv, currRing);
2765              // F->m[i-1] corresponds to index i
2766              p_ExpVectorAdd(Q.sig,F->m[i-1],currRing);
2767              p_SetComp(Q.sig, i, currRing);
2768              poly help = p_Copy(strat->P.sig,currRing);
2769              p_ExpVectorAdd(help,strat->S[pos],currRing);
2770              Q.sig = p_Add_q(Q.sig,help,currRing);
2771              if (strat->sbaOrder == 0) {
2772                if (p_LmCmp(Q.sig,strat->syz[strat->syzl-1],currRing) == -currRing->OrdSgn) {
2773                  pos = posInSyz(strat, Q.sig);
2774                  enterSyz(Q, strat, pos);
2775                }
2776              } else {
2777                pos = posInSyz(strat, Q.sig);
2778                enterSyz(Q, strat, pos);
2779              }
2780            }
2781          }
2782          //printf("++ -- done adding syzygies -- ++\n");
2783        }
2784      }
2785//#if 1
2786#if DEBUGF50
2787    printf("---------------------------\n");
2788    Print(" %d. ELEMENT ADDED TO GCURR:\n",strat->sl+1);
2789    Print("LEAD POLY:  "); pWrite(pHead(strat->S[strat->sl]));
2790    Print("SIGNATURE:  "); pWrite(strat->sig[strat->sl]);
2791#endif
2792      /*
2793      if (newrules)
2794      {
2795        newrules  = FALSE;
2796      }
2797      */
2798#if 0
2799      int pl=pLength(strat->P.p);
2800      if (pl==1)
2801      {
2802        //if (TEST_OPT_PROT)
2803        //PrintS("<1>");
2804      }
2805      else if (pl==2)
2806      {
2807        //if (TEST_OPT_PROT)
2808        //PrintS("<2>");
2809      }
2810#endif
2811      if (hilb!=NULL) khCheck(Q,w,hilb,hilbeledeg,hilbcount,strat);
2812//      Print("[%d]",hilbeledeg);
2813      if (strat->P.lcm!=NULL)
2814#ifdef HAVE_RINGS
2815        pLmDelete(strat->P.lcm);
2816#else
2817        pLmFree(strat->P.lcm);
2818#endif
2819      if (strat->sl>srmax) srmax = strat->sl;
2820    }
2821    else
2822    {
2823      case_when_red_result_changed:
2824      // adds signature of the zero reduction to
2825      // strat->syz. This is the leading term of
2826      // syzygy and can be used in syzCriterion()
2827      // the signature is added if and only if the
2828      // pair was not detected by the rewritten criterion in strat->red = redSig
2829      if (red_result!=2) {
2830#if SBA_PRINT_ZERO_REDUCTIONS
2831        zeroreductions++;
2832#endif
2833        if(rField_is_Ring(currRing) && strat->P.p == NULL && strat->P.sig == NULL)
2834        {
2835          //Catch the case when p = 0, sig = 0
2836        }
2837        else
2838        {
2839          int pos = posInSyz(strat, strat->P.sig);
2840          enterSyz(strat->P, strat, pos);
2841  //#if 1
2842  #ifdef DEBUGF5
2843          Print("ADDING STUFF TO SYZ :  ");
2844          //pWrite(strat->P.p);
2845          pWrite(strat->P.sig);
2846  #endif
2847        }
2848      }
2849      if (strat->P.p1 == NULL && strat->minim > 0)
2850      {
2851        p_Delete(&strat->P.p2, currRing, strat->tailRing);
2852      }
2853    }
2854
2855#ifdef KDEBUG
2856    memset(&(strat->P), 0, sizeof(strat->P));
2857#endif /* KDEBUG */
2858    kTest_TS(strat);
2859  }
2860  #if 0
2861  if(strat->sigdrop)
2862    printf("\nSigDrop!\n");
2863  else
2864    printf("\nEnded with no SigDrop\n");
2865  #endif
2866// Clean strat->P for the next sba call
2867  if(rField_is_Ring(currRing) && strat->sigdrop)
2868  {
2869    //This is used to know how many elements can we directly add to S in the next run
2870    if(strat->P.sig != NULL)
2871      strat->sbaEnterS = pGetComp(strat->P.sig)-1;
2872    //else we already set it at the beggining of the loop
2873    #ifdef KDEBUG
2874    memset(&(strat->P), 0, sizeof(strat->P));
2875    #endif /* KDEBUG */
2876  }
2877#ifdef KDEBUG
2878  if (TEST_OPT_DEBUG) messageSets(strat);
2879#endif /* KDEBUG */
2880
2881  if (TEST_OPT_SB_1)
2882  {
2883    if(!rField_is_Ring(currRing))
2884    {
2885      int k=1;
2886      int j;
2887      while(k<=strat->sl)
2888      {
2889        j=0;
2890        loop
2891        {
2892          if (j>=k) break;
2893          clearS(strat->S[j],strat->sevS[j],&k,&j,strat);
2894          j++;
2895        }
2896        k++;
2897      }
2898    }
2899  }
2900  /* complete reduction of the standard basis--------- */
2901  if (TEST_OPT_REDSB)
2902  {
2903    completeReduce(strat);
2904#ifdef HAVE_TAIL_RING
2905    if (strat->completeReduce_retry)
2906    {
2907      // completeReduce needed larger exponents, retry
2908      // to reduce with S (instead of T)
2909      // and in currRing (instead of strat->tailRing)
2910      cleanT(strat);strat->tailRing=currRing;
2911      int i;
2912      for(i=strat->sl;i>=0;i--) strat->S_2_R[i]=-1;
2913      completeReduce(strat);
2914    }
2915#endif
2916  }
2917  else if (TEST_OPT_PROT) PrintLn();
2918
2919#if SBA_PRINT_SIZE_SYZ
2920  // that is correct, syzl is counting one too far
2921  size_syz = strat->syzl;
2922#endif
2923//  if (TEST_OPT_WEIGHTM)
2924//  {
2925//    pRestoreDegProcs(pFDegOld, pLDegOld);
2926//    if (ecartWeights)
2927//    {
2928//      omFreeSize((ADDRESS)ecartWeights,(pVariables+1)*sizeof(short));
2929//      ecartWeights=NULL;
2930//    }
2931//  }
2932  if (TEST_OPT_PROT) messageStatSBA(hilbcount,strat);
2933  if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
2934#if SBA_PRINT_SIZE_G
2935  size_g_non_red  = IDELEMS(strat->Shdl);
2936#endif
2937 
2938  idTest(strat->Shdl);
2939  // I have to add the initial input polynomials which where not used (p1 and p2 = NULL)
2940  #ifdef HAVE_RINGS
2941  int k;
2942  if(rField_is_Ring(currRing))
2943  {
2944    //for(k = strat->sl;k>=0;k--)
2945    //  {printf("\nS[%i] = %p\n",k,strat->Shdl->m[k]);pWrite(strat->Shdl->m[k]);}
2946    k = strat->Ll;
2947    #if 1
2948    // 1 - adds just the unused ones, 0 - adds everthing
2949    for(;k>=0 && (strat->L[k].p1 != NULL || strat->L[k].p2 != NULL);k--)
2950    {
2951      //printf("\nDeleted k = %i, %p\n",k,strat->L[k].p);pWrite(strat->L[k].p);pWrite(strat->L[k].p1);pWrite(strat->L[k].p2);
2952      deleteInL(strat->L,&strat->Ll,k,strat);
2953    }
2954    #endif
2955    //for(int kk = strat->sl;kk>=0;kk--)
2956    //  {printf("\nS[%i] = %p\n",kk,strat->Shdl->m[kk]);pWrite(strat->Shdl->m[kk]);}
2957    //idPrint(strat->Shdl);
2958  idTest(strat->Shdl);
2959    //printf("\nk = %i\n",k);
2960    for(;k>=0 && strat->L[k].p1 == NULL && strat->L[k].p2 == NULL;k--)
2961    {
2962      //printf("\nAdded k = %i\n",k);
2963      strat->enterS(strat->L[k], strat->sl+1, strat, strat->tl);
2964      //printf("\nThis elements was added from L on pos %i\n",strat->sl);pWrite(strat->S[strat->sl]);pWrite(strat->sig[strat->sl]);
2965    }
2966  }
2967  // Find the "sigdrop element" and put the same signature as the previous one - do we really need this?? - now i put it on the 0 position - no more comparing needed
2968  #if 0
2969  if(strat->sigdrop && rField_is_Ring(currRing))
2970  {
2971    for(k=strat->sl;k>=0;k--)
2972    {
2973      printf("\nsig[%i] = ",i);pWrite(strat->sig[k]);
2974      if(strat->sig[k] == NULL)
2975        strat->sig[k] = pCopy(strat->sig[k-1]);
2976    }
2977  }
2978  #endif
2979  #endif
2980  //Never do this - you will damage S
2981  //idSkipZeroes(strat->Shdl);
2982  //idPrint(strat->Shdl);
2983  idTest(strat->Shdl);
2984 
2985  if ((strat->sbaOrder == 1 || strat->sbaOrder == 3) && sRing!=currRingOld)
2986  {
2987    rChangeCurrRing (currRingOld);
2988    F0          = idrMoveR (F1, sRing, currRing);
2989    strat->Shdl = idrMoveR_NoSort (strat->Shdl, sRing, currRing);
2990    rChangeCurrRing (sRing);
2991    exitSba(strat);
2992    rChangeCurrRing (currRingOld);
2993    if(strat->tailRing == sRing)
2994      strat->tailRing = currRing;
2995    rDelete (sRing);
2996  }
2997  if(rField_is_Ring(currRing) && !strat->sigdrop)
2998    id_DelDiv(strat->Shdl, currRing);
2999  idSkipZeroes(strat->Shdl);
3000  idTest(strat->Shdl);
3001
3002#if SBA_PRINT_SIZE_G
3003  size_g   = IDELEMS(strat->Shdl);
3004#endif
3005#ifdef DEBUGF5
3006  printf("SIZE OF SHDL: %d\n",IDELEMS(strat->Shdl));
3007  int oo = 0;
3008  while (oo<IDELEMS(strat->Shdl))
3009  {
3010    printf(" %d.   ",oo+1);
3011    pWrite(pHead(strat->Shdl->m[oo]));
3012    oo++;
3013  }
3014#endif
3015#if SBA_PRINT_ZERO_REDUCTIONS
3016  printf("----------------------------------------------------------\n");
3017  printf("ZERO REDUCTIONS:            %ld\n",zeroreductions);
3018  zeroreductions  = 0;
3019#endif
3020#if SBA_PRINT_REDUCTION_STEPS
3021  printf("----------------------------------------------------------\n");
3022  printf("S-REDUCTIONS:               %ld\n",sba_reduction_steps);
3023#endif
3024#if SBA_PRINT_OPERATIONS
3025  printf("OPERATIONS:                 %ld\n",sba_operations);
3026#endif
3027#if SBA_PRINT_REDUCTION_STEPS
3028  printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n");
3029  printf("INTERREDUCTIONS:            %ld\n",sba_interreduction_steps);
3030#endif
3031#if SBA_PRINT_OPERATIONS
3032  printf("INTERREDUCTION OPERATIONS:  %ld\n",sba_interreduction_operations);
3033#endif
3034#if SBA_PRINT_REDUCTION_STEPS
3035  printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - - - \n");
3036  printf("ALL REDUCTIONS:             %ld\n",sba_reduction_steps+sba_interreduction_steps);
3037  sba_interreduction_steps  = 0;
3038  sba_reduction_steps       = 0;
3039#endif
3040#if SBA_PRINT_OPERATIONS
3041  printf("ALL OPERATIONS:             %ld\n",sba_operations+sba_interreduction_operations);
3042  sba_interreduction_operations = 0;
3043  sba_operations                = 0;
3044#endif
3045#if SBA_PRINT_SIZE_G
3046  printf("----------------------------------------------------------\n");
3047  printf("SIZE OF G:                  %d / %d\n",size_g,size_g_non_red);
3048  size_g          = 0;
3049  size_g_non_red  = 0;
3050#endif
3051#if SBA_PRINT_SIZE_SYZ
3052  printf("SIZE OF SYZ:                %ld\n",size_syz);
3053  printf("----------------------------------------------------------\n");
3054  size_syz  = 0;
3055#endif
3056#if SBA_PRINT_PRODUCT_CRITERION
3057  printf("PRODUCT CRITERIA:           %ld\n",product_criterion);
3058  product_criterion = 0;
3059#endif
3060  return (strat->Shdl);
3061}
3062
3063poly kNF2 (ideal F,ideal Q,poly q,kStrategy strat, int lazyReduce)
3064{
3065  assume(q!=NULL);
3066  assume(!(idIs0(F)&&(Q==NULL))); // NF(q, std(0) in polynomial ring?
3067
3068// lazy_reduce flags: can be combined by |
3069//#define KSTD_NF_LAZY   1
3070  // do only a reduction of the leading term
3071//#define KSTD_NF_NONORM 4
3072  // only global: avoid normalization, return a multiply of NF
3073  poly   p;
3074
3075  //if ((idIs0(F))&&(Q==NULL))
3076  //  return pCopy(q); /*F=0*/
3077  //strat->ak = idRankFreeModule(F);
3078  /*- creating temp data structures------------------- -*/
3079  BITSET save1;
3080  SI_SAVE_OPT1(save1);
3081  si_opt_1|=Sy_bit(OPT_REDTAIL);
3082  initBuchMoraCrit(strat);
3083  strat->initEcart = initEcartBBA;
3084  strat->enterS = enterSBba;
3085#ifndef NO_BUCKETS
3086  strat->use_buckets = (!TEST_OPT_NOT_BUCKETS) && (!rIsPluralRing(currRing));
3087#endif
3088  /*- set S -*/
3089  strat->sl = -1;
3090  /*- init local data struct.---------------------------------------- -*/
3091  /*Shdl=*/initS(F,Q,strat);
3092  /*- compute------------------------------------------------------- -*/
3093  //if ((TEST_OPT_INTSTRATEGY)&&(lazyReduce==0))
3094  //{
3095  //  for (i=strat->sl;i>=0;i--)
3096  //    pNorm(strat->S[i]);
3097  //}
3098  kTest(strat);
3099  if (TEST_OPT_PROT) { PrintS("r"); mflush(); }
3100  if (BVERBOSE(23)) kDebugPrint(strat);
3101  int max_ind;
3102  p = redNF(pCopy(q),max_ind,lazyReduce & KSTD_NF_NONORM,strat);
3103  if ((p!=NULL)&&((lazyReduce & KSTD_NF_LAZY)==0))
3104  {
3105    if (TEST_OPT_PROT) { PrintS("t"); mflush(); }
3106    if (rField_is_Ring(currRing))
3107    {
3108      p = redtailBba_Z(p,max_ind,strat);
3109    }
3110    else
3111    {
3112      si_opt_1 &= ~Sy_bit(OPT_INTSTRATEGY);
3113      p = redtailBba(p,max_ind,strat,(lazyReduce & KSTD_NF_NONORM)==0);
3114    }
3115  }
3116  /*- release temp data------------------------------- -*/
3117  assume(strat->L==NULL); /* strat->L unused */
3118  assume(strat->B==NULL); /* strat->B unused */
3119  omFree(strat->sevS);
3120  omFree(strat->ecartS);
3121  assume(strat->T==NULL);//omfree(strat->T);
3122  assume(strat->sevT==NULL);//omfree(strat->sevT);
3123  assume(strat->R==NULL);//omfree(strat->R);
3124  omfree(strat->S_2_R);
3125  omfree(strat->fromQ);
3126  idDelete(&strat->Shdl);
3127  SI_RESTORE_OPT1(save1);
3128  if (TEST_OPT_PROT) PrintLn();
3129  return p;
3130}
3131
3132ideal kNF2 (ideal F,ideal Q,ideal q,kStrategy strat, int lazyReduce)
3133{
3134  assume(!idIs0(q));
3135  assume(!(idIs0(F)&&(Q==NULL)));
3136// lazy_reduce flags: can be combined by |
3137//#define KSTD_NF_LAZY   1
3138  // do only a reduction of the leading term
3139//#define KSTD_NF_NONORM 4
3140  // only global: avoid normalization, return a multiply of NF
3141  poly   p;
3142  int   i;
3143  ideal res;
3144  int max_ind;
3145
3146  //if (idIs0(q))
3147  //  return idInit(IDELEMS(q),si_max(q->rank,F->rank));
3148  //if ((idIs0(F))&&(Q==NULL))
3149  //  return idCopy(q); /*F=0*/
3150  //strat->ak = idRankFreeModule(F);
3151  /*- creating temp data structures------------------- -*/
3152  BITSET save1;
3153  SI_SAVE_OPT1(save1);
3154  si_opt_1|=Sy_bit(OPT_REDTAIL);
3155  initBuchMoraCrit(strat);
3156  strat->initEcart = initEcartBBA;
3157  strat->enterS = enterSBba;
3158  /*- set S -*/
3159  strat->sl = -1;
3160#ifndef NO_BUCKETS
3161  strat->use_buckets = (!TEST_OPT_NOT_BUCKETS) && (!rIsPluralRing(currRing));
3162#endif
3163  /*- init local data struct.---------------------------------------- -*/
3164  /*Shdl=*/initS(F,Q,strat);
3165  /*- compute------------------------------------------------------- -*/
3166  res=idInit(IDELEMS(q),si_max(q->rank,F->rank));
3167  si_opt_1 &= ~Sy_bit(OPT_INTSTRATEGY);
3168  for (i=IDELEMS(q)-1; i>=0; i--)
3169  {
3170    if (q->m[i]!=NULL)
3171    {
3172      if (TEST_OPT_PROT) { PrintS("r");mflush(); }
3173      p = redNF(pCopy(q->m[i]),max_ind,lazyReduce & KSTD_NF_NONORM,strat);
3174      if ((p!=NULL)&&((lazyReduce & KSTD_NF_LAZY)==0))
3175      {
3176        if (TEST_OPT_PROT) { PrintS("t"); mflush(); }
3177        if (rField_is_Ring(currRing))
3178        {
3179          p = redtailBba_Z(p,max_ind,strat);
3180        }
3181        else
3182        {
3183          p = redtailBba(p,max_ind,strat,(lazyReduce & KSTD_NF_NONORM)==0);
3184        }
3185      }
3186      res->m[i]=p;
3187    }
3188    //else
3189    //  res->m[i]=NULL;
3190  }
3191  /*- release temp data------------------------------- -*/
3192  assume(strat->L==NULL); /* strat->L unused */
3193  assume(strat->B==NULL); /* strat->B unused */
3194  omFree(strat->sevS);
3195  omFree(strat->ecartS);
3196  assume(strat->T==NULL);//omfree(strat->T);
3197  assume(strat->sevT==NULL);//omfree(strat->sevT);
3198  assume(strat->R==NULL);//omfree(strat->R);
3199  omfree(strat->S_2_R);
3200  omfree(strat->fromQ);
3201  idDelete(&strat->Shdl);
3202  SI_RESTORE_OPT1(save1);
3203  if (TEST_OPT_PROT) PrintLn();
3204  return res;
3205}
3206
3207#if F5C
3208/*********************************************************************
3209* interrreduction step of the signature-based algorithm:
3210* 1. all strat->S are interpreted as new critical pairs
3211* 2. those pairs need to be completely reduced by the usual (non sig-
3212*    safe) reduction process (including tail reductions)
3213* 3. strat->S and strat->T are completely new computed in these steps
3214********************************************************************/
3215void f5c (kStrategy strat, int& olddeg, int& minimcnt, int& hilbeledeg,
3216          int& hilbcount, int& srmax, int& lrmax, int& reduc, ideal Q,
3217          intvec *w,intvec *hilb )
3218{
3219  int Ll_old, red_result = 1;
3220  int pos  = 0;
3221  hilbeledeg=1;
3222  hilbcount=0;
3223  minimcnt=0;
3224  srmax = 0; // strat->sl is 0 at this point
3225  reduc = olddeg = lrmax = 0;
3226  // we cannot use strat->T anymore
3227  //cleanT(strat);
3228  //strat->tl = -1;
3229  Ll_old    = strat->Ll;
3230  while (strat->tl >= 0)
3231  {
3232    if(!strat->T[strat->tl].is_redundant)
3233    {
3234      LObject h;
3235      h.p = strat->T[strat->tl].p;
3236      h.tailRing = strat->T[strat->tl].tailRing;
3237      h.t_p = strat->T[strat->tl].t_p;
3238      if (h.p!=NULL)
3239      {
3240        if (currRing->OrdSgn==-1)
3241        {
3242          cancelunit(&h);
3243          deleteHC(&h, strat);
3244        }
3245        if (h.p!=NULL)
3246        {
3247          if (TEST_OPT_INTSTRATEGY)
3248          {
3249            //pContent(h.p);
3250            h.pCleardenom(); // also does a pContent
3251          }
3252          else
3253          {
3254            h.pNorm();
3255          }
3256          strat->initEcart(&h);
3257          if(rField_is_Ring(currRing))
3258            pos = posInLF5CRing(strat->L, Ll_old+1,strat->Ll,&h,strat);
3259          else
3260            pos = strat->Ll+1;
3261          h.sev = pGetShortExpVector(h.p);
3262          enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
3263        }
3264      }
3265    }
3266    strat->tl--;
3267  }
3268  strat->sl = -1;
3269#if 0
3270//#ifdef HAVE_TAIL_RING
3271  if(!rField_is_Ring())  // create strong gcd poly computes with tailring and S[i] ->to be fixed
3272    kStratInitChangeTailRing(strat);
3273#endif
3274  //enterpairs(pOne(),0,0,-1,strat,strat->tl);
3275  //strat->sl = -1;
3276  /* picks the last element from the lazyset L */
3277  while (strat->Ll>Ll_old)
3278  {
3279    strat->P = strat->L[strat->Ll];
3280    strat->Ll--;
3281//#if 1
3282#ifdef DEBUGF5
3283    Print("NEXT PAIR TO HANDLE IN INTERRED ALGORITHM\n");
3284    Print("-------------------------------------------------\n");
3285    pWrite(pHead(strat->P.p));
3286    pWrite(pHead(strat->P.p1));
3287    pWrite(pHead(strat->P.p2));
3288    printf("%d\n",strat->tl);
3289    Print("-------------------------------------------------\n");
3290#endif
3291    if (pNext(strat->P.p) == strat->tail)
3292    {
3293      // deletes the short spoly
3294      if (rField_is_Ring(currRing))
3295        pLmDelete(strat->P.p);
3296      else
3297        pLmFree(strat->P.p);
3298
3299      // TODO: needs some masking
3300      // TODO: masking needs to vanish once the signature
3301      //       sutff is completely implemented
3302      strat->P.p = NULL;
3303      poly m1 = NULL, m2 = NULL;
3304
3305      // check that spoly creation is ok
3306      while (strat->tailRing != currRing &&
3307          !kCheckSpolyCreation(&(strat->P), strat, m1, m2))
3308      {
3309        assume(m1 == NULL && m2 == NULL);
3310        // if not, change to a ring where exponents are at least
3311        // large enough
3312        if (!kStratChangeTailRing(strat))
3313        {
3314          WerrorS("OVERFLOW...");
3315          break;
3316        }
3317      }
3318      // create the real one
3319      ksCreateSpoly(&(strat->P), NULL, strat->use_buckets,
3320          strat->tailRing, m1, m2, strat->R);
3321    }
3322    else if (strat->P.p1 == NULL)
3323    {
3324      if (strat->minim > 0)
3325        strat->P.p2=p_Copy(strat->P.p, currRing, strat->tailRing);
3326      // for input polys, prepare reduction
3327      if(!rField_is_Ring(currRing))
3328        strat->P.PrepareRed(strat->use_buckets);
3329    }
3330
3331    if (strat->P.p == NULL && strat->P.t_p == NULL)
3332    {
3333      red_result = 0;
3334    }
3335    else
3336    {
3337      if (TEST_OPT_PROT)
3338        message((strat->honey ? strat->P.ecart : 0) + strat->P.pFDeg(),
3339            &olddeg,&reduc,strat, red_result);
3340
3341#ifdef DEBUGF5
3342      Print("Poly before red: ");
3343      pWrite(strat->P.p);
3344#endif
3345      /* complete reduction of the element chosen from L */
3346      red_result = strat->red2(&strat->P,strat);
3347      if (errorreported)  break;
3348    }
3349
3350    if (strat->overflow)
3351    {
3352      if (!kStratChangeTailRing(strat)) { Werror("OVERFLOW.."); break;}
3353    }
3354
3355    // reduction to non-zero new poly
3356    if (red_result == 1)
3357    {
3358      // get the polynomial (canonicalize bucket, make sure P.p is set)
3359      strat->P.GetP(strat->lmBin);
3360      // in the homogeneous case FDeg >= pFDeg (sugar/honey)
3361      // but now, for entering S, T, we reset it
3362      // in the inhomogeneous case: FDeg == pFDeg
3363      if (strat->homog) strat->initEcart(&(strat->P));
3364
3365      /* statistic */
3366      if (TEST_OPT_PROT) PrintS("s");
3367      int pos;
3368      #if 1
3369      if(!rField_is_Ring(currRing))
3370        pos = posInS(strat,strat->sl,strat->P.p,strat->P.ecart);
3371      else
3372        pos = posInSMonFirst(strat,strat->sl,strat->P.p,strat->P.ecart);
3373      #else
3374      pos = posInS(strat,strat->sl,strat->P.p,strat->P.ecart);
3375      #endif
3376      // reduce the tail and normalize poly
3377      // in the ring case we cannot expect LC(f) = 1,
3378      // therefore we call pContent instead of pNorm
3379#if F5CTAILRED
3380      BOOLEAN withT = TRUE;
3381      if ((TEST_OPT_INTSTRATEGY) || (rField_is_Ring(currRing)))
3382      {
3383        strat->P.pCleardenom();
3384        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
3385        {
3386          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
3387          strat->P.pCleardenom();
3388        }
3389      }
3390      else
3391      {
3392        strat->P.pNorm();
3393        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
3394          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
3395      }
3396#endif
3397#ifdef KDEBUG
3398      if (TEST_OPT_DEBUG){PrintS("new s:");strat->P.wrp();PrintLn();}
3399#endif /* KDEBUG */
3400
3401      // min_std stuff
3402      if ((strat->P.p1==NULL) && (strat->minim>0))
3403      {
3404        if (strat->minim==1)
3405        {
3406          strat->M->m[minimcnt]=p_Copy(strat->P.p,currRing,strat->tailRing);
3407          p_Delete(&strat->P.p2, currRing, strat->tailRing);
3408        }
3409        else
3410        {
3411          strat->M->m[minimcnt]=strat->P.p2;
3412          strat->P.p2=NULL;
3413        }
3414        if (strat->tailRing!=currRing && pNext(strat->M->m[minimcnt])!=NULL)
3415          pNext(strat->M->m[minimcnt])
3416            = strat->p_shallow_copy_delete(pNext(strat->M->m[minimcnt]),
3417                strat->tailRing, currRing,
3418                currRing->PolyBin);
3419        minimcnt++;
3420      }
3421
3422      // enter into S, L, and T
3423      // here we need to recompute new signatures, but those are trivial ones
3424      if ((!TEST_OPT_IDLIFT) || (pGetComp(strat->P.p) <= strat->syzComp))
3425      {
3426        enterT(strat->P, strat);
3427        // posInS only depends on the leading term
3428        strat->enterS(strat->P, pos, strat, strat->tl);
3429//#if 1
3430#ifdef DEBUGF5
3431        Print("ELEMENT ADDED TO GCURR DURING INTERRED: ");
3432        pWrite(pHead(strat->S[strat->sl]));
3433        pWrite(strat->sig[strat->sl]);
3434#endif
3435        if (hilb!=NULL) khCheck(Q,w,hilb,hilbeledeg,hilbcount,strat);
3436      }
3437      //      Print("[%d]",hilbeledeg);
3438      if (strat->P.lcm!=NULL)
3439#ifdef HAVE_RINGS
3440        pLmDelete(strat->P.lcm);
3441#else
3442      pLmFree(strat->P.lcm);
3443#endif
3444      if (strat->sl>srmax) srmax = strat->sl;
3445    }
3446    else
3447    {
3448      // adds signature of the zero reduction to
3449      // strat->syz. This is the leading term of
3450      // syzygy and can be used in syzCriterion()
3451      // the signature is added if and only if the
3452      // pair was not detected by the rewritten criterion in strat->red = redSig
3453      if (strat->P.p1 == NULL && strat->minim > 0)
3454      {
3455        p_Delete(&strat->P.p2, currRing, strat->tailRing);
3456      }
3457    }
3458
3459#ifdef KDEBUG
3460    memset(&(strat->P), 0, sizeof(strat->P));
3461#endif /* KDEBUG */
3462  }
3463  int cc = 0;
3464  while (cc<strat->tl+1)
3465  {
3466    strat->T[cc].sig        = pOne();
3467    p_SetComp(strat->T[cc].sig,cc+1,currRing);
3468    strat->T[cc].sevSig     = pGetShortExpVector(strat->T[cc].sig);
3469    strat->sig[cc]          = strat->T[cc].sig;
3470    strat->sevSig[cc]       = strat->T[cc].sevSig;
3471    strat->T[cc].is_sigsafe = TRUE;
3472    cc++;
3473  }
3474  strat->max_lower_index = strat->tl;
3475  // set current signature index of upcoming iteration step
3476  // NOTE:  this needs to be set here, as otherwise initSyzRules cannot compute
3477  //        the corresponding syzygy rules correctly
3478  strat->currIdx = cc+1;
3479  for (int cd=strat->Ll; cd>=0; cd--)
3480  {
3481    p_SetComp(strat->L[cd].sig,cc+1,currRing);
3482    cc++;
3483  }
3484  for (cc=strat->sl+1; cc<IDELEMS(strat->Shdl); ++cc)
3485    strat->Shdl->m[cc]  = NULL;
3486  #if 0
3487  printf("\nAfter f5c sorting\n");
3488  for(int i=0;i<=strat->sl;i++)
3489  pWrite(pHead(strat->S[i]));
3490  getchar();
3491  #endif
3492//#if 1
3493#if DEBUGF5
3494  Print("------------------- STRAT S ---------------------\n");
3495  cc = 0;
3496  while (cc<strat->tl+1)
3497  {
3498    pWrite(pHead(strat->S[cc]));
3499    pWrite(strat->sig[cc]);
3500    printf("- - - - - -\n");
3501    cc++;
3502  }
3503  Print("-------------------------------------------------\n");
3504  Print("------------------- STRAT T ---------------------\n");
3505  cc = 0;
3506  while (cc<strat->tl+1)
3507  {
3508    pWrite(pHead(strat->T[cc].p));
3509    pWrite(strat->T[cc].sig);
3510    printf("- - - - - -\n");
3511    cc++;
3512  }
3513  Print("-------------------------------------------------\n");
3514  Print("------------------- STRAT L ---------------------\n");
3515  cc = 0;
3516  while (cc<strat->Ll+1)
3517  {
3518    pWrite(pHead(strat->L[cc].p));
3519    pWrite(pHead(strat->L[cc].p1));
3520    pWrite(pHead(strat->L[cc].p2));
3521    pWrite(strat->L[cc].sig);
3522    printf("- - - - - -\n");
3523    cc++;
3524  }
3525  Print("-------------------------------------------------\n");
3526  printf("F5C DONE\nSTRAT SL: %d -- %d\n",strat->sl, strat->currIdx);
3527#endif
3528
3529}
3530#endif
3531
3532/* shiftgb stuff */
3533#ifdef HAVE_SHIFTBBA
3534
3535
3536ideal bbaShift(ideal F, ideal Q,intvec *w,intvec *hilb,kStrategy strat, int uptodeg, int lV)
3537{
3538  int   red_result = 1;
3539  int   olddeg,reduc;
3540  int hilbeledeg=1,hilbcount=0,minimcnt=0;
3541  BOOLEAN withT = TRUE; // very important for shifts
3542
3543  initBuchMoraCrit(strat); /*set Gebauer, honey, sugarCrit, NO CHANGES */
3544  if(rField_is_Ring(currRing))
3545    initBuchMoraPosRing(strat);
3546  else
3547    initBuchMoraPos(strat); /*NO CHANGES YET: perhaps later*/
3548  initHilbCrit(F,Q,&hilb,strat); /*NO CHANGES*/
3549  initBbaShift(strat); /* DONE */
3550  /*set enterS, spSpolyShort, reduce, red, initEcart, initEcartPair*/
3551  /*Shdl=*/initBuchMoraShift(F, Q,strat); /* updateS with no toT, i.e. no init for T */
3552  updateSShift(strat,uptodeg,lV); /* initializes T */
3553
3554  if (strat->minim>0) strat->M=idInit(IDELEMS(F),F->rank);
3555  reduc = olddeg = 0;
3556  strat->lV=lV;
3557
3558#ifndef NO_BUCKETS
3559  if (!TEST_OPT_NOT_BUCKETS)
3560    strat->use_buckets = 1;
3561#endif
3562
3563  // redtailBBa against T for inhomogenous input
3564  //  if (!TEST_OPT_OLDSTD)
3565  //    withT = ! strat->homog;
3566
3567  // strat->posInT = posInT_pLength;
3568  kTest_TS(strat);
3569
3570#ifdef HAVE_TAIL_RING
3571  kStratInitChangeTailRing(strat);
3572#endif
3573
3574  /* compute------------------------------------------------------- */
3575  while (strat->Ll >= 0)
3576  {
3577#ifdef KDEBUG
3578    if (TEST_OPT_DEBUG) messageSets(strat);
3579#endif
3580    if (strat->Ll== 0) strat->interpt=TRUE;
3581    if (TEST_OPT_DEGBOUND
3582        && ((strat->honey && (strat->L[strat->Ll].ecart+currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
3583            || ((!strat->honey) && (currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))))
3584    {
3585      /*
3586       *stops computation if
3587       * 24 IN test and the degree +ecart of L[strat->Ll] is bigger then
3588       *a predefined number Kstd1_deg
3589       */
3590      while ((strat->Ll >= 0)
3591        && (strat->L[strat->Ll].p1!=NULL) && (strat->L[strat->Ll].p2!=NULL)
3592        && ((strat->honey && (strat->L[strat->Ll].ecart+currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
3593            || ((!strat->honey) && (currRing->pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg)))
3594        )
3595        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
3596      if (strat->Ll<0) break;
3597      else strat->noClearS=TRUE;
3598    }
3599    /* picks the last element from the lazyset L */
3600    strat->P = strat->L[strat->Ll];
3601    strat->Ll--;
3602
3603    if (pNext(strat->P.p) == strat->tail)
3604    {
3605      // deletes the short spoly
3606      pLmFree(strat->P.p);
3607      strat->P.p = NULL;
3608      poly m1 = NULL, m2 = NULL;
3609
3610      // check that spoly creation is ok
3611      while (strat->tailRing != currRing &&
3612             !kCheckSpolyCreation(&(strat->P), strat, m1, m2))
3613      {
3614        assume(m1 == NULL && m2 == NULL);
3615        // if not, change to a ring where exponents are at least
3616        // large enough
3617        kStratChangeTailRing(strat);
3618      }
3619      // create the real one
3620      ksCreateSpoly(&(strat->P), NULL, strat->use_buckets,
3621                    strat->tailRing, m1, m2, strat->R);
3622    }
3623    else if (strat->P.p1 == NULL)
3624    {
3625      if (strat->minim > 0)
3626        strat->P.p2=p_Copy(strat->P.p, currRing, strat->tailRing);
3627      // for input polys, prepare reduction
3628      strat->P.PrepareRed(strat->use_buckets);
3629    }
3630
3631    poly qq;
3632
3633    /* here in the nonhomog case we shrink the new spoly */
3634
3635    if ( ! strat->homog)
3636    {
3637      strat->P.GetP(strat->lmBin); // because shifts are counted with .p structure
3638      /* in the nonhomog case we have to shrink the polynomial */
3639      assume(strat->P.t_p!=NULL);
3640      qq = p_Shrink(strat->P.t_p, lV, strat->tailRing); // direct shrink
3641      if (qq != NULL)
3642      {
3643         /* we're here if Shrink is nonzero */
3644        //         strat->P.p =  NULL;
3645        //        strat->P.Delete(); /* deletes P.p and P.t_p */ //error
3646        strat->P.p   =  NULL; // is not set by Delete
3647        strat->P.t_p =  qq;
3648        strat->P.GetP(strat->lmBin);
3649        // update sev and length
3650        strat->initEcart(&(strat->P));
3651        strat->P.sev = pGetShortExpVector(strat->P.p);
3652//         strat->P.FDeg = strat->P.pFDeg();
3653//         strat->P.length = strat->P.pLDeg();
3654//         strat->P.pLength =strat->P.GetpLength(); //pLength(strat->P.p);
3655      }
3656      else
3657      {
3658         /* Shrink is zero, like y(1)*y(2) - y(1)*y(3)*/
3659#ifdef KDEBUG
3660         if (TEST_OPT_DEBUG){PrintS("nonzero s shrinks to 0");PrintLn();}
3661#endif
3662         //         strat->P.Delete();  // cause error
3663         strat->P.p = NULL;
3664         strat->P.t_p = NULL;
3665           //         strat->P.p = NULL; // or delete strat->P.p ?
3666       }
3667    }
3668      /* end shrinking poly in the nonhomog case */
3669
3670    if (strat->P.p == NULL && strat->P.t_p == NULL)
3671    {
3672      red_result = 0;
3673    }
3674    else
3675    {
3676      if (TEST_OPT_PROT)
3677        message((strat->honey ? strat->P.ecart : 0) + strat->P.pFDeg(),
3678                &olddeg,&reduc,strat, red_result);
3679
3680      /* reduction of the element chosen from L */
3681      red_result = strat->red(&strat->P,strat);
3682    }
3683
3684    // reduction to non-zero new poly
3685    if (red_result == 1)
3686    {
3687      /* statistic */
3688      if (TEST_OPT_PROT) PrintS("s");
3689
3690      // get the polynomial (canonicalize bucket, make sure P.p is set)
3691      strat->P.GetP(strat->lmBin);
3692
3693      int pos=posInS(strat,strat->sl,strat->P.p,strat->P.ecart);
3694
3695      // reduce the tail and normalize poly
3696      if (TEST_OPT_INTSTRATEGY)
3697      {
3698        strat->P.pCleardenom();
3699        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
3700        {
3701          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
3702          strat->P.pCleardenom();
3703        }
3704      }
3705      else
3706      {
3707        strat->P.pNorm();
3708        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
3709          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
3710      }
3711
3712      // here we must shrink again! and optionally reduce again
3713      // or build shrink into redtailBba!
3714
3715#ifdef KDEBUG
3716      if (TEST_OPT_DEBUG){PrintS("new s:");strat->P.wrp();PrintLn();}
3717#endif
3718
3719      // min_std stuff
3720      if ((strat->P.p1==NULL) && (strat->minim>0))
3721      {
3722        if (strat->minim==1)
3723        {
3724          strat->M->m[minimcnt]=p_Copy(strat->P.p,currRing,strat->tailRing);
3725          p_Delete(&strat->P.p2, currRing, strat->tailRing);
3726        }
3727        else
3728        {
3729          strat->M->m[minimcnt]=strat->P.p2;
3730          strat->P.p2=NULL;
3731        }
3732        if (strat->tailRing!=currRing && pNext(strat->M->m[minimcnt])!=NULL)
3733          pNext(strat->M->m[minimcnt])
3734            = strat->p_shallow_copy_delete(pNext(strat->M->m[minimcnt]),
3735                                           strat->tailRing, currRing,
3736                                           currRing->PolyBin);
3737        minimcnt++;
3738      }
3739
3740    /* here in the nonhomog case we shrink the reduced poly AGAIN */
3741
3742    if ( ! strat->homog)
3743    {
3744      strat->P.GetP(strat->lmBin); // because shifts are counted with .p structure
3745      /* assume strat->P.t_p != NULL */
3746      /* in the nonhomog case we have to shrink the polynomial */
3747      assume(strat->P.t_p!=NULL); // poly qq defined above
3748      qq = p_Shrink(strat->P.t_p, lV, strat->tailRing); // direct shrink
3749      if (qq != NULL)
3750      {
3751         /* we're here if Shrink is nonzero */
3752        //         strat->P.p =  NULL;
3753        //        strat->P.Delete(); /* deletes P.p and P.t_p */ //error
3754        strat->P.p   =  NULL; // is not set by Delete
3755        strat->P.t_p =  qq;
3756        strat->P.GetP(strat->lmBin);
3757        // update sev and length
3758        strat->initEcart(&(strat->P));
3759        strat->P.sev = pGetShortExpVector(strat->P.p);
3760      }
3761      else
3762      {
3763         /* Shrink is zero, like y(1)*y(2) - y(1)*y(3)*/
3764#ifdef PDEBUG
3765         if (TEST_OPT_DEBUG){PrintS("nonzero s shrinks to 0");PrintLn();}
3766#endif
3767         //         strat->P.Delete();  // cause error
3768         strat->P.p = NULL;
3769         strat->P.t_p = NULL;
3770           //         strat->P.p = NULL; // or delete strat->P.p ?
3771         goto     red_shrink2zero;
3772       }
3773    }
3774      /* end shrinking poly AGAIN in the nonhomog case */
3775
3776
3777      // enter into S, L, and T
3778      //if ((!TEST_OPT_IDLIFT) || (pGetComp(strat->P.p) <= strat->syzComp))
3779      //        enterT(strat->P, strat); // this was here before Shift stuff
3780      //enterTShift(LObject p, kStrategy strat, int atT, int uptodeg, int lV); // syntax
3781      // the default value for atT = -1 as in bba
3782      /*   strat->P.GetP(); */
3783      // because shifts are counted with .p structure // done before, but ?
3784      enterTShift(strat->P,strat,-1,uptodeg, lV);
3785      enterpairsShift(strat->P.p,strat->sl,strat->P.ecart,pos,strat, strat->tl,uptodeg,lV);
3786      //      enterpairsShift(vw,strat->sl,strat->P.ecart,pos,strat, strat->tl,uptodeg,lV);
3787      // posInS only depends on the leading term
3788      strat->enterS(strat->P, pos, strat, strat->tl);
3789
3790      if (hilb!=NULL) khCheck(Q,w,hilb,hilbeledeg,hilbcount,strat);
3791//      Print("[%d]",hilbeledeg);
3792      if (strat->P.lcm!=NULL) pLmFree(strat->P.lcm);
3793    }
3794    else
3795    {
3796    red_shrink2zero:
3797      if (strat->P.p1 == NULL && strat->minim > 0)
3798      {
3799        p_Delete(&strat->P.p2, currRing, strat->tailRing);
3800      }
3801    }
3802#ifdef KDEBUG
3803    memset(&(strat->P), 0, sizeof(strat->P));
3804#endif
3805    kTest_TS(strat);
3806  }
3807#ifdef KDEBUG
3808  if (TEST_OPT_DEBUG) messageSets(strat);
3809#endif
3810  /* complete reduction of the standard basis--------- */
3811  /*  shift case: look for elt's in S such that they are divisible by elt in T */
3812  //  if (TEST_OPT_SB_1)
3813  if (TEST_OPT_REDSB)
3814  {
3815    int k=0;
3816    int j=-1;
3817    while(k<=strat->sl)
3818    {
3819//       loop
3820//       {
3821//         if (j>=k) break;
3822//         clearS(strat->S[j],strat->sevS[j],&k,&j,strat);
3823//         j++;
3824//       }
3825      LObject Ln (strat->S[k],currRing, strat->tailRing);
3826      Ln.SetShortExpVector();
3827      j = kFindDivisibleByInT(strat, &Ln, j+1);
3828      if (j<0) {  k++; j=-1;}
3829      else
3830      {
3831        if ( pLmCmp(strat->S[k],strat->T[j].p) == 0)
3832        {
3833          j = kFindDivisibleByInT(strat, &Ln, j+1);
3834          if (j<0) {  k++; j=-1;}
3835          else
3836          {
3837            deleteInS(k,strat);
3838          }
3839        }
3840        else
3841        {
3842          deleteInS(k,strat);
3843        }
3844      }
3845    }
3846  }
3847
3848  if (TEST_OPT_REDSB)
3849  {    completeReduce(strat, TRUE); //shift: withT = TRUE
3850    if (strat->completeReduce_retry)
3851    {
3852      // completeReduce needed larger exponents, retry
3853      // to reduce with S (instead of T)
3854      // and in currRing (instead of strat->tailRing)
3855      cleanT(strat);strat->tailRing=currRing;
3856      int i;
3857      for(i=strat->sl;i>=0;i--) strat->S_2_R[i]=-1;
3858      completeReduce(strat, TRUE);
3859    }
3860  }
3861  else if (TEST_OPT_PROT) PrintLn();
3862
3863  /* release temp data-------------------------------- */
3864  exitBuchMora(strat);
3865//  if (TEST_OPT_WEIGHTM)
3866//  {
3867//    pRestoreDegProcs(currRing,pFDegOld, pLDegOld);
3868//    if (ecartWeights)
3869//    {
3870//      omFreeSize((ADDRESS)ecartWeights,((currRing->N)+1)*sizeof(short));
3871//      ecartWeights=NULL;
3872//    }
3873//  }
3874  if (TEST_OPT_PROT) messageStat(hilbcount,strat);
3875  if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
3876  return (strat->Shdl);
3877}
3878
3879
3880ideal freegb(ideal I, int uptodeg, int lVblock)
3881{
3882  /* todo main call */
3883
3884  /* assume: ring is prepared, ideal is copied into shifted ring */
3885  /* uptodeg and lVblock are correct - test them! */
3886
3887  /* check whether the ideal is in V */
3888
3889//  if (0)
3890  if (! ideal_isInV(I,lVblock) )
3891  {
3892    WerrorS("The input ideal contains incorrectly encoded elements! ");
3893    return(NULL);
3894  }
3895
3896  //  kStrategy strat = new skStrategy;
3897  /* ideal bbaShift(ideal F, ideal Q,intvec *w,intvec *hilb,kStrategy strat, int uptodeg, int lV) */
3898  /* at the moment:
3899- no quotient (check)
3900- no *w, no *hilb
3901  */
3902  /* ideal F, ideal Q, tHomog h,intvec ** w, intvec *hilb,int syzComp,
3903     int newIdeal, intvec *vw) */
3904  ideal RS = kStdShift(I,NULL, testHomog, NULL,NULL,0,0,NULL, uptodeg, lVblock);
3905    //bbaShift(I,NULL, NULL, NULL, strat, uptodeg, lVblock);
3906  idSkipZeroes(RS);
3907  return(RS);
3908}
3909
3910/*2
3911*reduces h with elements from T choosing  the first possible
3912* element in t with respect to the given pDivisibleBy
3913*/
3914int redFirstShift (LObject* h,kStrategy strat)
3915{
3916  if (h->IsNull()) return 0;
3917
3918  int at, reddeg,d;
3919  int pass = 0;
3920  int j = 0;
3921
3922  if (! strat->homog)
3923  {
3924    d = h->GetpFDeg() + h->ecart;
3925    reddeg = strat->LazyDegree+d;
3926  }
3927  h->SetShortExpVector();
3928  loop
3929  {
3930    j = kFindDivisibleByInT(strat, h);
3931    if (j < 0)
3932    {
3933      h->SetDegStuffReturnLDeg(strat->LDegLast);
3934      return 1;
3935    }
3936
3937    if (!TEST_OPT_INTSTRATEGY)
3938      strat->T[j].pNorm();
3939#ifdef KDEBUG
3940    if (TEST_OPT_DEBUG)
3941    {
3942      PrintS("reduce ");
3943      h->wrp();
3944      PrintS(" with ");
3945      strat->T[j].wrp();
3946    }
3947#endif
3948    ksReducePoly(h, &(strat->T[j]), strat->kNoetherTail(), NULL, strat);
3949    if (!h->IsNull())
3950    {
3951      poly qq=p_Shrink(h->GetTP(),strat->lV,strat->tailRing);
3952      h->p=NULL;
3953      h->t_p=qq;
3954      if (qq!=NULL) h->GetP(strat->lmBin);
3955    }
3956
3957#ifdef KDEBUG
3958    if (TEST_OPT_DEBUG)
3959    {
3960      PrintS(" to ");
3961      wrp(h->p);
3962      PrintLn();
3963    }
3964#endif
3965    if (h->IsNull())
3966    {
3967      if (h->lcm!=NULL) pLmFree(h->lcm);
3968      h->Clear();
3969      return 0;
3970    }
3971    h->SetShortExpVector();
3972
3973#if 0
3974    if ((strat->syzComp!=0) && !strat->honey)
3975    {
3976      if ((strat->syzComp>0) &&
3977          (h->Comp() > strat->syzComp))
3978      {
3979        assume(h->MinComp() > strat->syzComp);
3980#ifdef KDEBUG
3981        if (TEST_OPT_DEBUG) PrintS(" > syzComp\n");
3982#endif
3983        if (strat->homog)
3984          h->SetDegStuffReturnLDeg(strat->LDegLast);
3985        return -2;
3986      }
3987    }
3988#endif
3989    if (!strat->homog)
3990    {
3991      if (!TEST_OPT_OLDSTD && strat->honey)
3992      {
3993        h->SetpFDeg();
3994        if (strat->T[j].ecart <= h->ecart)
3995          h->ecart = d - h->GetpFDeg();
3996        else
3997          h->ecart = d - h->GetpFDeg() + strat->T[j].ecart - h->ecart;
3998
3999        d = h->GetpFDeg() + h->ecart;
4000      }
4001      else
4002        d = h->SetDegStuffReturnLDeg(strat->LDegLast);
4003      /*- try to reduce the s-polynomial -*/
4004      pass++;
4005      /*
4006       *test whether the polynomial should go to the lazyset L
4007       *-if the degree jumps
4008       *-if the number of pre-defined reductions jumps
4009       */
4010      if (!TEST_OPT_REDTHROUGH && (strat->Ll >= 0)
4011          && ((d >= reddeg) || (pass > strat->LazyPass)))
4012      {
4013        h->SetLmCurrRing();
4014        if (strat->posInLDependsOnLength)
4015          h->SetLength(strat->length_pLength);
4016        at = strat->posInL(strat->L,strat->Ll,h,strat);
4017        if (at <= strat->Ll)
4018        {
4019          //int dummy=strat->sl;
4020          /*          if (kFindDivisibleByInS(strat,&dummy, h) < 0) */
4021          //if (kFindDivisibleByInT(strat->T,strat->sevT, dummy, h) < 0)
4022          if (kFindDivisibleByInT(strat, h) < 0)
4023            return 1;
4024          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
4025#ifdef KDEBUG
4026          if (TEST_OPT_DEBUG) Print(" degree jumped; ->L%d\n",at);
4027#endif
4028          h->Clear();
4029          return -1;
4030        }
4031      }
4032      if ((TEST_OPT_PROT) && (strat->Ll < 0) && (d >= reddeg))
4033      {
4034        reddeg = d+1;
4035        Print(".%d",d);mflush();
4036      }
4037    }
4038  }
4039}
4040
4041void initBbaShift(kStrategy strat)
4042{
4043 /* setting global variables ------------------- */
4044  strat->enterS = enterSBba; /* remains as is, we change enterT! */
4045
4046  strat->red = redFirstShift; /* no redHomog ! */
4047
4048  if (currRing->pLexOrder && strat->honey)
4049    strat->initEcart = initEcartNormal;
4050  else
4051    strat->initEcart = initEcartBBA;
4052  if (strat->honey)
4053    strat->initEcartPair = initEcartPairMora;
4054  else
4055    strat->initEcartPair = initEcartPairBba;
4056//  if ((TEST_OPT_WEIGHTM)&&(F!=NULL))
4057//  {
4058//    //interred  machen   Aenderung
4059//    pFDegOld=currRing->pFDeg;
4060//    pLDegOld=pLDeg;
4061//    //h=ggetid("ecart");
4062//    //if ((h!=NULL) /*&& (IDTYP(h)==INTVEC_CMD)*/)
4063//    //{
4064//    //  ecartWeights=iv2array(IDINTVEC(h));
4065//    //}
4066//    //else
4067//    {
4068//      ecartWeights=(short *)omAlloc(((currRing->N)+1)*sizeof(short));
4069//      /*uses automatic computation of the ecartWeights to set them*/
4070//      kEcartWeights(F->m,IDELEMS(F)-1,ecartWeights,currRing);
4071//    }
4072//    pRestoreDegProcs(currRing,totaldegreeWecart, maxdegreeWecart);
4073//    if (TEST_OPT_PROT)
4074//    {
4075//      for(int i=1; i<=rVar(currRing); i++)
4076//        Print(" %d",ecartWeights[i]);
4077//      PrintLn();
4078//      mflush();
4079//    }
4080//  }
4081}
4082#endif
Note: See TracBrowser for help on using the repository browser.