source: git/kernel/GBEngine/kstd2.cc @ 6b0b413

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