source: git/kernel/kutil.cc @ 854405

spielwiese
Last change on this file since 854405 was 762407, checked in by Oleksandr Motsak <motsak@…>, 12 years ago
config.h is for sources files only FIX: config.h should only be used by source (not from inside kernel/mod2.h!) NOTE: each source file should better include mod2.h right after config.h, while headers should better not include mod2.h.
  • Property mode set to 100644
File size: 196.0 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT: kernel: utils for kStd
6*/
7
8// #define PDEBUG 2
9// #define PDIV_DEBUG
10#define KUTIL_CC
11#include <stdlib.h>
12#include <string.h>
13#include "config.h"
14#include "mod2.h"
15
16#ifndef NDEBUG
17# define MYTEST 0
18#else /* ifndef NDEBUG */
19# define MYTEST 0
20#endif /* ifndef NDEBUG */
21
22
23#include <misc/mylimits.h>
24#include <misc/options.h>
25#include <polys/nc/nc.h>
26#include <polys/nc/sca.h>
27#include <polys/weight.h> /* for kDebugPrint: maxdegreeWecart*/
28#ifdef KDEBUG
29#undef KDEBUG
30#define KDEBUG 2
31#endif
32
33#ifdef HAVE_RINGS
34#include <kernel/ideals.h>
35#endif
36
37// define if enterL, enterT should use memmove instead of doing it manually
38// on topgun, this is slightly faster (see monodromy_l.tst, homog_gonnet.sing)
39#ifndef SunOS_4
40#define ENTER_USE_MEMMOVE
41#endif
42
43// define, if the my_memmove inlines should be used instead of
44// system memmove -- it does not seem to pay off, though
45// #define ENTER_USE_MYMEMMOVE
46
47#include <kernel/kutil.h>
48#include <polys/kbuckets.h>
49#include <kernel/febase.h>
50#include <omalloc/omalloc.h>
51#include <coeffs/numbers.h>
52#include <kernel/polys.h>
53#include <polys/monomials/ring.h>
54#include <kernel/ideals.h>
55#include <kernel/timer.h>
56//#include "cntrlc.h"
57#include <kernel/stairc.h>
58#include <kernel/kstd1.h>
59#include <polys/operations/pShallowCopyDelete.h>
60
61/* shiftgb stuff */
62#include <kernel/shiftgb.h>
63#include <polys/prCopy.h>
64
65#ifdef HAVE_RATGRING
66#include <kernel/ratgring.h>
67#endif
68
69#ifdef KDEBUG
70#undef KDEBUG
71#define KDEBUG 2
72#endif
73
74denominator_list DENOMINATOR_LIST=NULL;
75
76
77#ifdef ENTER_USE_MYMEMMOVE
78inline void _my_memmove_d_gt_s(unsigned long* d, unsigned long* s, long l)
79{
80  register unsigned long* _dl = (unsigned long*) d;
81  register unsigned long* _sl = (unsigned long*) s;
82  register long _i = l - 1;
83
84  do
85  {
86    _dl[_i] = _sl[_i];
87    _i--;
88  }
89  while (_i >= 0);
90}
91
92inline void _my_memmove_d_lt_s(unsigned long* d, unsigned long* s, long l)
93{
94  register long _ll = l;
95  register unsigned long* _dl = (unsigned long*) d;
96  register unsigned long* _sl = (unsigned long*) s;
97  register long _i = 0;
98
99  do
100  {
101    _dl[_i] = _sl[_i];
102    _i++;
103  }
104  while (_i < _ll);
105}
106
107inline void _my_memmove(void* d, void* s, long l)
108{
109  unsigned long _d = (unsigned long) d;
110  unsigned long _s = (unsigned long) s;
111  unsigned long _l = ((l) + SIZEOF_LONG - 1) >> LOG_SIZEOF_LONG;
112
113  if (_d > _s) _my_memmove_d_gt_s(_d, _s, _l);
114  else _my_memmove_d_lt_s(_d, _s, _l);
115}
116
117#undef memmove
118#define memmove(d,s,l) _my_memmove(d, s, l)
119#endif
120
121static poly redMora (poly h,int maxIndex,kStrategy strat);
122static poly redBba (poly h,int maxIndex,kStrategy strat);
123
124#ifdef HAVE_RINGS
125#define pDivComp_EQUAL 2
126#define pDivComp_LESS 1
127#define pDivComp_GREATER -1
128#define pDivComp_INCOMP 0
129/* Checks the relation of LM(p) and LM(q)
130     LM(p) = LM(q) => return pDivComp_EQUAL
131     LM(p) | LM(q) => return pDivComp_LESS
132     LM(q) | LM(p) => return pDivComp_GREATER
133     else return pDivComp_INCOMP */
134static inline int pDivCompRing(poly p, poly q)
135{
136  if (pGetComp(p) == pGetComp(q))
137  {
138    BOOLEAN a=FALSE, b=FALSE;
139    int i;
140    unsigned long la, lb;
141    unsigned long divmask = currRing->divmask;
142    for (i=0; i<currRing->VarL_Size; i++)
143    {
144      la = p->exp[currRing->VarL_Offset[i]];
145      lb = q->exp[currRing->VarL_Offset[i]];
146      if (la != lb)
147      {
148        if (la < lb)
149        {
150          if (b) return pDivComp_INCOMP;
151          if (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))
152            return pDivComp_INCOMP;
153          a = TRUE;
154        }
155        else
156        {
157          if (a) return pDivComp_INCOMP;
158          if (((la & divmask) ^ (lb & divmask)) != ((la - lb) & divmask))
159            return pDivComp_INCOMP;
160          b = TRUE;
161        }
162      }
163    }
164    if (a) return pDivComp_LESS;
165    if (b) return pDivComp_GREATER;
166    if (!a & !b) return pDivComp_EQUAL;
167  }
168  return pDivComp_INCOMP;
169}
170#endif
171
172static inline int pDivComp(poly p, poly q)
173{
174  if (pGetComp(p) == pGetComp(q))
175  {
176#ifdef HAVE_RATGRING
177    if (rIsRatGRing(currRing))
178    {
179      if (_p_LmDivisibleByPart(p,currRing,
180                           q,currRing,
181                           currRing->real_var_start, currRing->real_var_end))
182        return 0;
183      return pLmCmp(q,p); // ONLY FOR GLOBAL ORDER!
184    }
185#endif
186    BOOLEAN a=FALSE, b=FALSE;
187    int i;
188    unsigned long la, lb;
189    unsigned long divmask = currRing->divmask;
190    for (i=0; i<currRing->VarL_Size; i++)
191    {
192      la = p->exp[currRing->VarL_Offset[i]];
193      lb = q->exp[currRing->VarL_Offset[i]];
194      if (la != lb)
195      {
196        if (la < lb)
197        {
198          if (b) return 0;
199          if (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))
200            return 0;
201          a = TRUE;
202        }
203        else
204        {
205          if (a) return 0;
206          if (((la & divmask) ^ (lb & divmask)) != ((la - lb) & divmask))
207            return 0;
208          b = TRUE;
209        }
210      }
211    }
212    if (a) { /*assume(pLmCmp(q,p)==1);*/ return 1; }
213    if (b) { /*assume(pLmCmp(q,p)==-1);*/return -1; }
214    /*assume(pLmCmp(q,p)==0);*/
215  }
216  return 0;
217}
218
219
220int     HCord;
221int     Kstd1_deg;
222int     Kstd1_mu=32000;
223
224/*2
225*deletes higher monomial of p, re-compute ecart and length
226*works only for orderings with ecart =pFDeg(end)-pFDeg(start)
227*/
228void deleteHC(LObject *L, kStrategy strat, BOOLEAN fromNext)
229{
230  if (strat->kHEdgeFound)
231  {
232    kTest_L(L);
233    poly p1;
234    poly p = L->GetLmTailRing();
235    int l = 1;
236    kBucket_pt bucket = NULL;
237    if (L->bucket != NULL)
238    {
239      kBucketClear(L->bucket, &pNext(p), &L->pLength);
240      L->pLength++;
241      bucket = L->bucket;
242      L->bucket = NULL;
243      L->last = NULL;
244    }
245
246    if (!fromNext && p_Cmp(p,strat->kNoetherTail(), L->tailRing) == -1)
247    {
248      L->Delete();
249      L->Clear();
250      L->ecart = -1;
251      if (bucket != NULL) kBucketDestroy(&bucket);
252      return;
253    }
254    p1 = p;
255    while (pNext(p1)!=NULL)
256    {
257      if (p_LmCmp(pNext(p1), strat->kNoetherTail(), L->tailRing) == -1)
258      {
259        L->last = p1;
260        p_Delete(&pNext(p1), L->tailRing);
261        if (p1 == p)
262        {
263          if (L->t_p != NULL)
264          {
265            assume(L->p != NULL && p == L->t_p);
266            pNext(L->p) = NULL;
267          }
268          L->max  = NULL;
269        }
270        else if (fromNext)
271          L->max  = p_GetMaxExpP(pNext(L->p), L->tailRing ); // p1;
272        //if (L->pLength != 0)
273        L->pLength = l;
274        // Hmmm when called from updateT, then only
275        // reset ecart when cut
276        if (fromNext)
277          L->ecart = L->pLDeg() - L->GetpFDeg();
278        break;
279      }
280      l++;
281      pIter(p1);
282    }
283    if (! fromNext)
284    {
285      L->SetpFDeg();
286      L->ecart = L->pLDeg(strat->LDegLast) - L->GetpFDeg();
287    }
288    if (bucket != NULL)
289    {
290      if (L->pLength > 1)
291      {
292        kBucketInit(bucket, pNext(p), L->pLength - 1);
293        pNext(p) = NULL;
294        if (L->t_p != NULL) pNext(L->t_p) = NULL;
295        L->pLength = 0;
296        L->bucket = bucket;
297        L->last = NULL;
298      }
299      else
300        kBucketDestroy(&bucket);
301    }
302    kTest_L(L);
303  }
304}
305
306void deleteHC(poly* p, int* e, int* l,kStrategy strat)
307{
308  LObject L(*p, currRing, strat->tailRing);
309
310  deleteHC(&L, strat);
311  *p = L.p;
312  *e = L.ecart;
313  *l = L.length;
314  if (L.t_p != NULL) p_LmFree(L.t_p, strat->tailRing);
315}
316
317/*2
318*tests if p.p=monomial*unit and cancels the unit
319*/
320void cancelunit (LObject* L,BOOLEAN inNF)
321{
322  int  i;
323  poly h;
324
325  if(rHasGlobalOrdering (currRing)) return;
326  if(TEST_OPT_CANCELUNIT) return;
327
328  ring r = L->tailRing;
329  poly p = L->GetLmTailRing();
330
331#ifdef HAVE_RINGS_LOC
332  // Leading coef have to be a unit
333  if ( !(nIsUnit(p_GetCoeff(p, r))) ) return;
334#endif
335
336  if(p_GetComp(p, r) != 0 && !p_OneComp(p, r)) return;
337
338//    for(i=r->N;i>0;i--)
339//    {
340//      if ((p_GetExp(p,i,r)>0) && (rIsPolyVar(i, r)==TRUE)) return;
341//    }
342  h = pNext(p);
343  loop
344  {
345    if (h==NULL)
346    {
347      p_Delete(&pNext(p), r);
348      if (!inNF)
349      {
350        number eins=nInit(1);
351        if (L->p != NULL)  pSetCoeff(L->p,eins);
352        else if (L->t_p != NULL) nDelete(&pGetCoeff(L->t_p));
353        if (L->t_p != NULL) pSetCoeff0(L->t_p,eins);
354      }
355      L->ecart = 0;
356      L->length = 1;
357      //if (L->pLength > 0)
358      L->pLength = 1;
359      if (L->last != NULL) L->last = p;
360      L->max = NULL;
361
362      if (L->t_p != NULL && pNext(L->t_p) != NULL)
363        pNext(L->t_p) = NULL;
364      if (L->p != NULL && pNext(L->p) != NULL)
365        pNext(L->p) = NULL;
366      return;
367    }
368    i = 0;
369    loop
370    {
371      i++;
372      if (p_GetExp(p,i,r) > p_GetExp(h,i,r)) return ; // does not divide
373      if (i == r->N) break; // does divide, try next monom
374    }
375    pIter(h);
376  }
377}
378
379/*2
380*pp is the new element in s
381*returns TRUE (in strat->kHEdgeFound) if
382*-HEcke is allowed
383*-we are in the last componente of the vector
384*-on all axis are monomials (all elements in NotUsedAxis are FALSE)
385*returns FALSE for pLexOrderings,
386*assumes in module case an ordering of type c* !!
387* HEckeTest is only called with strat->kHEdgeFound==FALSE !
388*/
389void HEckeTest (poly pp,kStrategy strat)
390{
391  int   j,k,p;
392
393  strat->kHEdgeFound=FALSE;
394  if (currRing->pLexOrder || currRing->MixedOrder)
395  {
396    return;
397  }
398  if (strat->ak > 1)           /*we are in the module case*/
399  {
400    return; // until ....
401    //if (!pVectorOut)     /*pVectorOut <=> order = c,* */
402    //  return FALSE;
403    //if (pGetComp(pp) < strat->ak) /* ak is the number of the last component */
404    //  return FALSE;
405  }
406  k = 0;
407  p=pIsPurePower(pp);
408  if (p!=0) strat->NotUsedAxis[p] = FALSE;
409  /*- the leading term of pp is a power of the p-th variable -*/
410  for (j=(currRing->N);j>0; j--)
411  {
412    if (strat->NotUsedAxis[j])
413    {
414      return;
415    }
416  }
417  strat->kHEdgeFound=TRUE;
418}
419
420/*2
421*utilities for TSet, LSet
422*/
423inline static intset initec (const int maxnr)
424{
425  return (intset)omAlloc(maxnr*sizeof(int));
426}
427
428inline static unsigned long* initsevS (const int maxnr)
429{
430  return (unsigned long*)omAlloc0(maxnr*sizeof(unsigned long));
431}
432inline static int* initS_2_R (const int maxnr)
433{
434  return (int*)omAlloc0(maxnr*sizeof(int));
435}
436
437static inline void enlargeT (TSet &T, TObject** &R, unsigned long* &sevT,
438                             int &length, const int incr)
439{
440  assume(T!=NULL);
441  assume(sevT!=NULL);
442  assume(R!=NULL);
443  assume((length+incr) > 0);
444
445  int i;
446  T = (TSet)omRealloc0Size(T, length*sizeof(TObject),
447                           (length+incr)*sizeof(TObject));
448
449  sevT = (unsigned long*) omReallocSize(sevT, length*sizeof(long*),
450                           (length+incr)*sizeof(long*));
451
452  R = (TObject**)omRealloc0Size(R,length*sizeof(TObject*),
453                                (length+incr)*sizeof(TObject*));
454  for (i=length-1;i>=0;i--) R[T[i].i_r] = &(T[i]);
455  length += incr;
456}
457
458void cleanT (kStrategy strat)
459{
460  int i,j;
461  poly  p;
462  assume(currRing == strat->tailRing || strat->tailRing != NULL);
463
464  pShallowCopyDeleteProc p_shallow_copy_delete =
465    (strat->tailRing != currRing ?
466     pGetShallowCopyDeleteProc(strat->tailRing, currRing) :
467     NULL);
468
469  for (j=0; j<=strat->tl; j++)
470  {
471    p = strat->T[j].p;
472    strat->T[j].p=NULL;
473    if (strat->T[j].max != NULL)
474    {
475      p_LmFree(strat->T[j].max, strat->tailRing);
476    }
477    i = -1;
478    loop
479    {
480      i++;
481      if (i>strat->sl)
482      {
483        if (strat->T[j].t_p != NULL)
484        {
485          p_Delete(&(strat->T[j].t_p), strat->tailRing);
486          p_LmFree(p, currRing);
487        }
488        else
489          pDelete(&p);
490        break;
491      }
492      if (p == strat->S[i])
493      {
494        if (strat->T[j].t_p != NULL)
495        {
496          assume(p_shallow_copy_delete != NULL);
497          pNext(p) = p_shallow_copy_delete(pNext(p),strat->tailRing,currRing,
498                                           currRing->PolyBin);
499          p_LmFree(strat->T[j].t_p, strat->tailRing);
500        }
501        break;
502      }
503    }
504  }
505  strat->tl=-1;
506}
507
508//LSet initL ()
509//{
510//  int i;
511//  LSet l = (LSet)omAlloc(setmaxL*sizeof(LObject));
512//  return l;
513//}
514
515static inline void enlargeL (LSet* L,int* length,const int incr)
516{
517  assume((*L)!=NULL);
518  assume((length+incr)>0);
519
520  *L = (LSet)omReallocSize((*L),(*length)*sizeof(LObject),
521                                   ((*length)+incr)*sizeof(LObject));
522  (*length) += incr;
523}
524
525void initPairtest(kStrategy strat)
526{
527  strat->pairtest = (BOOLEAN *)omAlloc0((strat->sl+2)*sizeof(BOOLEAN));
528}
529
530/*2
531*test whether (p1,p2) or (p2,p1) is in L up position length
532*it returns TRUE if yes and the position k
533*/
534BOOLEAN isInPairsetL(int length,poly p1,poly p2,int*  k,kStrategy strat)
535{
536  LObject *p=&(strat->L[length]);
537
538  *k = length;
539  loop
540  {
541    if ((*k) < 0) return FALSE;
542    if (((p1 == (*p).p1) && (p2 == (*p).p2))
543    ||  ((p1 == (*p).p2) && (p2 == (*p).p1)))
544      return TRUE;
545    (*k)--;
546    p--;
547  }
548}
549
550/*2
551*in B all pairs have the same element p on the right
552*it tests whether (q,p) is in B and returns TRUE if yes
553*and the position k
554*/
555BOOLEAN isInPairsetB(poly q,int*  k,kStrategy strat)
556{
557  LObject *p=&(strat->B[strat->Bl]);
558
559  *k = strat->Bl;
560  loop
561  {
562    if ((*k) < 0) return FALSE;
563    if (q == (*p).p1)
564      return TRUE;
565    (*k)--;
566    p--;
567  }
568}
569
570int kFindInT(poly p, TSet T, int tlength)
571{
572  int i;
573
574  for (i=0; i<=tlength; i++)
575  {
576    if (T[i].p == p) return i;
577  }
578  return -1;
579}
580
581int kFindInT(poly p, kStrategy strat)
582{
583  int i;
584  do
585  {
586    i = kFindInT(p, strat->T, strat->tl);
587    if (i >= 0) return i;
588    strat = strat->next;
589  }
590  while (strat != NULL);
591  return -1;
592}
593
594#ifdef KDEBUG
595
596void sTObject::wrp()
597{
598  if (t_p != NULL) p_wrp(t_p, tailRing);
599  else if (p != NULL) p_wrp(p, currRing, tailRing);
600  else ::wrp(NULL);
601}
602
603#define kFalseReturn(x) do { if (!x) return FALSE;} while (0)
604
605// check that Lm's of a poly from T are "equal"
606static const char* kTest_LmEqual(poly p, poly t_p, ring tailRing)
607{
608  int i;
609  for (i=1; i<=tailRing->N; i++)
610  {
611    if (p_GetExp(p, i, currRing) != p_GetExp(t_p, i, tailRing))
612      return "Lm[i] different";
613  }
614  if (p_GetComp(p, currRing) != p_GetComp(t_p, tailRing))
615    return "Lm[0] different";
616  if (pNext(p) != pNext(t_p))
617    return "Lm.next different";
618  if (pGetCoeff(p) != pGetCoeff(t_p))
619    return "Lm.coeff different";
620  return NULL;
621}
622
623static BOOLEAN sloppy_max = FALSE;
624BOOLEAN kTest_T(TObject * T, ring strat_tailRing, int i, char TN)
625{
626  ring tailRing = T->tailRing;
627  if (strat_tailRing == NULL) strat_tailRing = tailRing;
628  r_assume(strat_tailRing == tailRing);
629
630  poly p = T->p;
631  ring r = currRing;
632
633  if (T->p == NULL && T->t_p == NULL && i >= 0)
634    return dReportError("%c[%d].poly is NULL", TN, i);
635
636  if (T->tailRing != currRing)
637  {
638    if (T->t_p == NULL && i > 0)
639      return dReportError("%c[%d].t_p is NULL", TN, i);
640    pFalseReturn(p_Test(T->t_p, T->tailRing));
641    if (T->p != NULL) pFalseReturn(p_LmTest(T->p, currRing));
642    if (T->p != NULL && T->t_p != NULL)
643    {
644      const char* msg = kTest_LmEqual(T->p, T->t_p, T->tailRing);
645      if (msg != NULL)
646        return dReportError("%c[%d] %s", TN, i, msg);
647      r = T->tailRing;
648      p = T->t_p;
649    }
650    if (T->p == NULL)
651    {
652      p = T->t_p;
653      r = T->tailRing;
654    }
655    if (T->t_p != NULL && i >= 0 && TN == 'T')
656    {
657      if (pNext(T->t_p) == NULL)
658      {
659        if (T->max != NULL)
660          return dReportError("%c[%d].max is not NULL as it should be", TN, i);
661      }
662      else
663      {
664        if (T->max == NULL)
665          return dReportError("%c[%d].max is NULL", TN, i);
666        if (pNext(T->max) != NULL)
667          return dReportError("pNext(%c[%d].max) != NULL", TN, i);
668
669        pFalseReturn(p_CheckPolyRing(T->max, tailRing));
670        omCheckBinAddrSize(T->max, (omSizeWOfBin(tailRing->PolyBin))*SIZEOF_LONG);
671#if KDEBUG > 0
672        if (! sloppy_max)
673        {
674          poly test_max = p_GetMaxExpP(pNext(T->t_p), tailRing);
675          p_Setm(T->max, tailRing);
676          p_Setm(test_max, tailRing);
677          BOOLEAN equal = p_ExpVectorEqual(T->max, test_max, tailRing);
678          if (! equal)
679            return dReportError("%c[%d].max out of sync", TN, i);
680          p_LmFree(test_max, tailRing);
681        }
682#endif
683      }
684    }
685  }
686  else
687  {
688    if (T->max != NULL)
689      return dReportError("%c[%d].max != NULL but tailRing == currRing",TN,i);
690    if (T->t_p != NULL)
691      return dReportError("%c[%d].t_p != NULL but tailRing == currRing",TN,i);
692    if (T->p == NULL && i > 0)
693      return dReportError("%c[%d].p is NULL", TN, i);
694    pFalseReturn(p_Test(T->p, currRing));
695  }
696
697  if (i >= 0 && T->pLength != 0
698  && ! rIsSyzIndexRing(currRing) && T->pLength != pLength(p))
699  {
700    int l=T->pLength;
701    T->pLength=pLength(p);
702    return dReportError("%c[%d] pLength error: has %d, specified to have %d",
703                        TN, i , pLength(p), l);
704  }
705
706  // check FDeg,  for elements in L and T
707  if (i >= 0 && (TN == 'T' || TN == 'L'))
708  {
709    // FDeg has ir element from T of L set
710    if (T->FDeg  != T->pFDeg())
711    {
712      int d=T->FDeg;
713      T->FDeg=T->pFDeg();
714      return dReportError("%c[%d] FDeg error: has %d, specified to have %d",
715                          TN, i , T->pFDeg(), d);
716    }
717  }
718
719  // check is_normalized for elements in T
720  if (i >= 0 && TN == 'T')
721  {
722    if (T->is_normalized && ! nIsOne(pGetCoeff(p)))
723      return dReportError("T[%d] is_normalized error", i);
724
725  }
726  return TRUE;
727}
728
729BOOLEAN kTest_L(LObject *L, ring strat_tailRing,
730                BOOLEAN testp, int lpos, TSet T, int tlength)
731{
732  if (testp)
733  {
734    poly pn = NULL;
735    if (L->bucket != NULL)
736    {
737      kFalseReturn(kbTest(L->bucket));
738      r_assume(L->bucket->bucket_ring == L->tailRing);
739      if (L->p != NULL && pNext(L->p) != NULL)
740      {
741        pn = pNext(L->p);
742        pNext(L->p) = NULL;
743      }
744    }
745    kFalseReturn(kTest_T(L, strat_tailRing, lpos, 'L'));
746    if (pn != NULL)
747      pNext(L->p) = pn;
748
749    ring r;
750    poly p;
751    L->GetLm(p, r);
752    if (L->sev != 0 && p_GetShortExpVector(p, r) != L->sev)
753    {
754      return dReportError("L[%d] wrong sev: has %o, specified to have %o",
755                          lpos, p_GetShortExpVector(p, r), L->sev);
756    }
757    if (lpos > 0 && L->last != NULL && pLast(p) != L->last)
758    {
759      return dReportError("L[%d] last wrong: has %p specified to have %p",
760                          lpos, pLast(p), L->last);
761    }
762  }
763  if (L->p1 == NULL)
764  {
765    // L->p2 either NULL or "normal" poly
766    pFalseReturn(pp_Test(L->p2, currRing, L->tailRing));
767  }
768  else if (tlength > 0 && T != NULL && (lpos >=0))
769  {
770    // now p1 and p2 must be != NULL and must be contained in T
771    int i;
772    i = kFindInT(L->p1, T, tlength);
773    if (i < 0)
774      return dReportError("L[%d].p1 not in T",lpos);
775    i = kFindInT(L->p2, T, tlength);
776    if (i < 0)
777      return dReportError("L[%d].p2 not in T",lpos);
778  }
779  return TRUE;
780}
781
782BOOLEAN kTest (kStrategy strat)
783{
784  int i;
785
786  // test P
787  kFalseReturn(kTest_L(&(strat->P), strat->tailRing,
788                       (strat->P.p != NULL && pNext(strat->P.p)!=strat->tail),
789                       -1, strat->T, strat->tl));
790
791  // test T
792  if (strat->T != NULL)
793  {
794    for (i=0; i<=strat->tl; i++)
795    {
796      kFalseReturn(kTest_T(&(strat->T[i]), strat->tailRing, i, 'T'));
797      if (strat->sevT[i] != pGetShortExpVector(strat->T[i].p))
798        return dReportError("strat->sevT[%d] out of sync", i);
799    }
800  }
801
802  // test L
803  if (strat->L != NULL)
804  {
805    for (i=0; i<=strat->Ll; i++)
806    {
807      kFalseReturn(kTest_L(&(strat->L[i]), strat->tailRing,
808                           strat->L[i].Next() != strat->tail, i,
809                           strat->T, strat->tl));
810      // may be unused
811      //if (strat->use_buckets && strat->L[i].Next() != strat->tail &&
812      //    strat->L[i].Next() != NULL && strat->L[i].p1 != NULL)
813      //{
814      //  assume(strat->L[i].bucket != NULL);
815      //}
816    }
817  }
818
819  // test S
820  if (strat->S != NULL)
821    kFalseReturn(kTest_S(strat));
822
823  return TRUE;
824}
825
826BOOLEAN kTest_S(kStrategy strat)
827{
828  int i;
829  BOOLEAN ret = TRUE;
830  for (i=0; i<=strat->sl; i++)
831  {
832    if (strat->S[i] != NULL &&
833        strat->sevS[i] != pGetShortExpVector(strat->S[i]))
834    {
835      return dReportError("S[%d] wrong sev: has %o, specified to have %o",
836                          i , pGetShortExpVector(strat->S[i]), strat->sevS[i]);
837    }
838  }
839  return ret;
840}
841
842
843
844BOOLEAN kTest_TS(kStrategy strat)
845{
846  int i, j;
847  BOOLEAN ret = TRUE;
848  kFalseReturn(kTest(strat));
849
850  // test strat->R, strat->T[i].i_r
851  for (i=0; i<=strat->tl; i++)
852  {
853    if (strat->T[i].i_r < 0 || strat->T[i].i_r > strat->tl)
854      return dReportError("strat->T[%d].i_r == %d out of bounds", i,
855                          strat->T[i].i_r);
856    if (strat->R[strat->T[i].i_r] != &(strat->T[i]))
857      return dReportError("T[%d].i_r with R out of sync", i);
858  }
859  // test containment of S inT
860  if (strat->S != NULL)
861  {
862    for (i=0; i<=strat->sl; i++)
863    {
864      j = kFindInT(strat->S[i], strat->T, strat->tl);
865      if (j < 0)
866        return dReportError("S[%d] not in T", i);
867      if (strat->S_2_R[i] != strat->T[j].i_r)
868        return dReportError("S_2_R[%d]=%d != T[%d].i_r=%d\n",
869                            i, strat->S_2_R[i], j, strat->T[j].i_r);
870    }
871  }
872  // test strat->L[i].i_r1
873  for (i=0; i<=strat->Ll; i++)
874  {
875    if (strat->L[i].p1 != NULL && strat->L[i].p2)
876    {
877      if (strat->L[i].i_r1 < 0 ||
878          strat->L[i].i_r1 > strat->tl ||
879          strat->L[i].T_1(strat)->p != strat->L[i].p1)
880        return dReportError("L[%d].i_r1 out of sync", i);
881      if (strat->L[i].i_r2 < 0 ||
882          strat->L[i].i_r2 > strat->tl ||
883          strat->L[i].T_2(strat)->p != strat->L[i].p2);
884    }
885    else
886    {
887      if (strat->L[i].i_r1 != -1)
888        return dReportError("L[%d].i_r1 out of sync", i);
889      if (strat->L[i].i_r2 != -1)
890        return dReportError("L[%d].i_r2 out of sync", i);
891    }
892    if (strat->L[i].i_r != -1)
893      return dReportError("L[%d].i_r out of sync", i);
894  }
895  return TRUE;
896}
897
898#endif // KDEBUG
899
900/*2
901*cancels the i-th polynomial in the standardbase s
902*/
903void deleteInS (int i,kStrategy strat)
904{
905#ifdef ENTER_USE_MEMMOVE
906  memmove(&(strat->S[i]), &(strat->S[i+1]), (strat->sl - i)*sizeof(poly));
907  memmove(&(strat->ecartS[i]),&(strat->ecartS[i+1]),(strat->sl - i)*sizeof(int));
908  memmove(&(strat->sevS[i]),&(strat->sevS[i+1]),(strat->sl - i)*sizeof(unsigned long));
909  memmove(&(strat->S_2_R[i]),&(strat->S_2_R[i+1]),(strat->sl - i)*sizeof(int));
910#else
911  int j;
912  for (j=i; j<strat->sl; j++)
913  {
914    strat->S[j] = strat->S[j+1];
915    strat->ecartS[j] = strat->ecartS[j+1];
916    strat->sevS[j] = strat->sevS[j+1];
917    strat->S_2_R[j] = strat->S_2_R[j+1];
918  }
919#endif
920  if (strat->lenS!=NULL)
921  {
922#ifdef ENTER_USE_MEMMOVE
923    memmove(&(strat->lenS[i]),&(strat->lenS[i+1]),(strat->sl - i)*sizeof(int));
924#else
925    for (j=i; j<strat->sl; j++) strat->lenS[j] = strat->lenS[j+1];
926#endif
927  }
928  if (strat->lenSw!=NULL)
929  {
930#ifdef ENTER_USE_MEMMOVE
931    memmove(&(strat->lenSw[i]),&(strat->lenSw[i+1]),(strat->sl - i)*sizeof(wlen_type));
932#else
933    for (j=i; j<strat->sl; j++) strat->lenSw[j] = strat->lenSw[j+1];
934#endif
935  }
936  if (strat->fromQ!=NULL)
937  {
938#ifdef ENTER_USE_MEMMOVE
939    memmove(&(strat->fromQ[i]),&(strat->fromQ[i+1]),(strat->sl - i)*sizeof(int));
940#else
941    for (j=i; j<strat->sl; j++)
942    {
943      strat->fromQ[j] = strat->fromQ[j+1];
944    }
945#endif
946  }
947  strat->S[strat->sl] = NULL;
948  strat->sl--;
949}
950
951/*2
952*cancels the j-th polynomial in the set
953*/
954void deleteInL (LSet set, int *length, int j,kStrategy strat)
955{
956  if (set[j].lcm!=NULL)
957  {
958#ifdef HAVE_RINGS
959    if (pGetCoeff(set[j].lcm) != NULL)
960      pLmDelete(set[j].lcm);
961    else
962#endif
963      pLmFree(set[j].lcm);
964  }
965  if (set[j].p!=NULL)
966  {
967    if (pNext(set[j].p) == strat->tail)
968    {
969#ifdef HAVE_RINGS
970      if (pGetCoeff(set[j].p) != NULL)
971        pLmDelete(set[j].p);
972      else
973#endif
974        pLmFree(set[j].p);
975      /*- tail belongs to several int spolys -*/
976    }
977    else
978    {
979      // search p in T, if it is there, do not delete it
980      if (currRing->OrdSgn != -1 || kFindInT(set[j].p, strat) < 0)
981      {
982        // assure that for global orderings kFindInT fails
983        assume(currRing->OrdSgn == -1 || kFindInT(set[j].p, strat) < 0);
984        set[j].Delete();
985      }
986    }
987  }
988  if (*length > 0 && j < *length)
989  {
990#ifdef ENTER_USE_MEMMOVE
991    memmove(&(set[j]), &(set[j+1]), (*length - j)*sizeof(LObject));
992#else
993    int i;
994    for (i=j; i < (*length); i++)
995      set[i] = set[i+1];
996#endif
997  }
998#ifdef KDEBUG
999  memset(&(set[*length]),0,sizeof(LObject));
1000#endif
1001  (*length)--;
1002}
1003
1004/*2
1005*enters p at position at in L
1006*/
1007void enterL (LSet *set,int *length, int *LSetmax, LObject p,int at)
1008{
1009  // this should be corrected
1010  assume(p.FDeg == p.pFDeg());
1011
1012  if ((*length)>=0)
1013  {
1014    if ((*length) == (*LSetmax)-1) enlargeL(set,LSetmax,setmaxLinc);
1015    if (at <= (*length))
1016#ifdef ENTER_USE_MEMMOVE
1017      memmove(&((*set)[at+1]), &((*set)[at]), ((*length)-at+1)*sizeof(LObject));
1018#else
1019    for (i=(*length)+1; i>=at+1; i--) (*set)[i] = (*set)[i-1];
1020#endif
1021  }
1022  else at = 0;
1023  (*set)[at] = p;
1024  (*length)++;
1025}
1026
1027/*2
1028* computes the normal ecart;
1029* used in mora case and if pLexOrder & sugar in bba case
1030*/
1031void initEcartNormal (LObject* h)
1032{
1033  h->FDeg = h->pFDeg();
1034  h->ecart = h->pLDeg() - h->FDeg;
1035  // h->length is set by h->pLDeg
1036  h->length=h->pLength=pLength(h->p);
1037}
1038
1039void initEcartBBA (LObject* h)
1040{
1041  h->FDeg = h->pFDeg();
1042  (*h).ecart = 0;
1043  h->length=h->pLength=pLength(h->p);
1044}
1045
1046void initEcartPairBba (LObject* Lp,poly /*f*/,poly /*g*/,int /*ecartF*/,int /*ecartG*/)
1047{
1048  Lp->FDeg = Lp->pFDeg();
1049  (*Lp).ecart = 0;
1050  (*Lp).length = 0;
1051}
1052
1053void initEcartPairMora (LObject* Lp,poly /*f*/,poly /*g*/,int ecartF,int ecartG)
1054{
1055  Lp->FDeg = Lp->pFDeg();
1056  (*Lp).ecart = si_max(ecartF,ecartG);
1057  (*Lp).ecart = (*Lp).ecart- (Lp->FDeg -p_FDeg((*Lp).lcm,currRing));
1058  (*Lp).length = 0;
1059}
1060
1061/*2
1062*if ecart1<=ecart2 it returns TRUE
1063*/
1064static inline BOOLEAN sugarDivisibleBy(int ecart1, int ecart2)
1065{
1066  return (ecart1 <= ecart2);
1067}
1068
1069#ifdef HAVE_RINGS
1070/*2
1071* put the pair (s[i],p)  into the set B, ecart=ecart(p) (ring case)
1072*/
1073void enterOnePairRing (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
1074{
1075  assume(i<=strat->sl);
1076  int      l,j,compare,compareCoeff;
1077  LObject  Lp;
1078
1079  if (strat->interred_flag) return;
1080#ifdef KDEBUG
1081  Lp.ecart=0; Lp.length=0;
1082#endif
1083  /*- computes the lcm(s[i],p) -*/
1084  Lp.lcm = pInit();
1085  pSetCoeff0(Lp.lcm, n_Lcm(pGetCoeff(p), pGetCoeff(strat->S[i]), currRing->cf));
1086  // Lp.lcm == 0
1087  if (nIsZero(pGetCoeff(Lp.lcm)))
1088  {
1089#ifdef KDEBUG
1090      if (TEST_OPT_DEBUG)
1091      {
1092        PrintS("--- Lp.lcm == 0\n");
1093        PrintS("p:");
1094        wrp(p);
1095        Print("  strat->S[%d]:", i);
1096        wrp(strat->S[i]);
1097        PrintLn();
1098      }
1099#endif
1100      strat->cp++;
1101      pLmDelete(Lp.lcm);
1102      return;
1103  }
1104  // basic product criterion
1105  pLcm(p,strat->S[i],Lp.lcm);
1106  pSetm(Lp.lcm);
1107  assume(!strat->sugarCrit);
1108  if (pHasNotCF(p,strat->S[i]) && n_IsUnit(pGetCoeff(p),currRing->cf)
1109      && n_IsUnit(pGetCoeff(strat->S[i]),currRing->cf))
1110  {
1111#ifdef KDEBUG
1112      if (TEST_OPT_DEBUG)
1113      {
1114        PrintS("--- product criterion func enterOnePairRing type 1\n");
1115        PrintS("p:");
1116        wrp(p);
1117        Print("  strat->S[%d]:", i);
1118        wrp(strat->S[i]);
1119        PrintLn();
1120      }
1121#endif
1122      strat->cp++;
1123      pLmDelete(Lp.lcm);
1124      return;
1125  }
1126  assume(!strat->fromT);
1127  /*
1128  *the set B collects the pairs of type (S[j],p)
1129  *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p) != lcm(r,p)
1130  *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1131  *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1132  */
1133  for(j = strat->Bl;j>=0;j--)
1134  {
1135    compare=pDivCompRing(strat->B[j].lcm,Lp.lcm);
1136    compareCoeff = n_DivComp(pGetCoeff(strat->B[j].lcm), pGetCoeff(Lp.lcm), currRing->cf);
1137    if (compareCoeff == pDivComp_EQUAL || compare == compareCoeff)
1138    {
1139      if (compare == 1)
1140      {
1141        strat->c3++;
1142#ifdef KDEBUG
1143        if (TEST_OPT_DEBUG)
1144        {
1145          PrintS("--- chain criterion type 1\n");
1146          PrintS("strat->B[j]:");
1147          wrp(strat->B[j].lcm);
1148          PrintS("  Lp.lcm:");
1149          wrp(Lp.lcm);
1150          PrintLn();
1151        }
1152#endif
1153        if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1154        {
1155          pLmDelete(Lp.lcm);
1156          return;
1157        }
1158        break;
1159      }
1160      else
1161      if (compare == -1)
1162      {
1163#ifdef KDEBUG
1164        if (TEST_OPT_DEBUG)
1165        {
1166          PrintS("--- chain criterion type 2\n");
1167          Print("strat->B[%d].lcm:",j);
1168          wrp(strat->B[j].lcm);
1169          PrintS("  Lp.lcm:");
1170          wrp(Lp.lcm);
1171          PrintLn();
1172        }
1173#endif
1174        deleteInL(strat->B,&strat->Bl,j,strat);
1175        strat->c3++;
1176      }
1177    }
1178    if ((compare == pDivComp_EQUAL) && (compareCoeff != 2))
1179    {
1180      if (compareCoeff == pDivComp_LESS)
1181      {
1182#ifdef KDEBUG
1183        if (TEST_OPT_DEBUG)
1184        {
1185          PrintS("--- chain criterion type 3\n");
1186          Print("strat->B[%d].lcm:", j);
1187          wrp(strat->B[j].lcm);
1188          PrintS("  Lp.lcm:");
1189          wrp(Lp.lcm);
1190          PrintLn();
1191        }
1192#endif
1193        strat->c3++;
1194        if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1195        {
1196          pLmDelete(Lp.lcm);
1197          return;
1198        }
1199        break;
1200      }
1201      else
1202      // Add hint for same LM and LC (later) (TODO Oliver)
1203      // if (compareCoeff == pDivComp_GREATER)
1204      {
1205#ifdef KDEBUG
1206        if (TEST_OPT_DEBUG)
1207        {
1208          PrintS("--- chain criterion type 4\n");
1209          Print("strat->B[%d].lcm:", j);
1210          wrp(strat->B[j].lcm);
1211          PrintS("  Lp.lcm:");
1212          wrp(Lp.lcm);
1213          PrintLn();
1214        }
1215#endif
1216        deleteInL(strat->B,&strat->Bl,j,strat);
1217        strat->c3++;
1218      }
1219    }
1220  }
1221  /*
1222  *the pair (S[i],p) enters B if the spoly != 0
1223  */
1224  /*-  compute the short s-polynomial -*/
1225  if ((strat->S[i]==NULL) || (p==NULL)) {
1226#ifdef KDEBUG
1227    if (TEST_OPT_DEBUG)
1228    {
1229      PrintS("--- spoly = NULL\n");
1230    }
1231#endif
1232    pLmDelete(Lp.lcm);
1233    return;
1234  }
1235  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
1236  {
1237    // Is from a previous computed GB, therefore we know that spoly will
1238    // reduce to zero. Oliver.
1239    WarnS("Could we come here? 8738947389");
1240    Lp.p=NULL;
1241  }
1242  else
1243  {
1244    Lp.p = ksCreateShortSpoly(strat->S[i], p, strat->tailRing);
1245  }
1246  if (Lp.p == NULL)
1247  {
1248#ifdef KDEBUG
1249    if (TEST_OPT_DEBUG)
1250    {
1251      PrintS("--- spoly = NULL\n");
1252    }
1253#endif
1254    /*- the case that the s-poly is 0 -*/
1255    if (strat->pairtest==NULL) initPairtest(strat);
1256    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
1257    strat->pairtest[strat->sl+1] = TRUE;
1258    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
1259    /*
1260    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
1261    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
1262    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
1263    *term of p devides the lcm(s,r)
1264    *(this canceling should be done here because
1265    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
1266    *the first case is handeled in chainCrit
1267    */
1268    pLmDelete(Lp.lcm);
1269  }
1270  else
1271  {
1272    /*- the pair (S[i],p) enters B -*/
1273    Lp.p1 = strat->S[i];
1274    Lp.p2 = p;
1275
1276    pNext(Lp.p) = strat->tail;
1277
1278    if (atR >= 0)
1279    {
1280      Lp.i_r2 = atR;
1281      Lp.i_r1 = strat->S_2_R[i];
1282    }
1283    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1284    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
1285    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
1286  }
1287}
1288
1289
1290/*2
1291* put the  lcm(s[i],p)  into the set B
1292*/
1293
1294BOOLEAN enterOneStrongPoly (int i,poly p,int /*ecart*/, int /*isFromQ*/,kStrategy strat, int atR = -1)
1295{
1296  number d, s, t;
1297  assume(i<=strat->sl);
1298  assume(atR >= 0);
1299  poly m1, m2, gcd;
1300
1301  d = n_ExtGcd(pGetCoeff(p), pGetCoeff(strat->S[i]), &s, &t, currRing->cf);
1302
1303  if (nIsZero(s) || nIsZero(t))  // evtl. durch divBy tests ersetzen
1304  {
1305    nDelete(&d);
1306    nDelete(&s);
1307    nDelete(&t);
1308    return FALSE;
1309  }
1310
1311  k_GetStrongLeadTerms(p, strat->S[i], currRing, m1, m2, gcd, strat->tailRing);
1312  //p_Test(m1,strat->tailRing);
1313  //p_Test(m2,strat->tailRing);
1314  while (! kCheckStrongCreation(atR, m1, i, m2, strat) )
1315  {
1316    memset(&(strat->P), 0, sizeof(strat->P));
1317    kStratChangeTailRing(strat);
1318    strat->P = *(strat->R[atR]);
1319    p_LmFree(m1, strat->tailRing);
1320    p_LmFree(m2, strat->tailRing);
1321    p_LmFree(gcd, currRing);
1322    k_GetStrongLeadTerms(p, strat->S[i], currRing, m1, m2, gcd, strat->tailRing);
1323  }
1324  pSetCoeff0(m1, s);
1325  pSetCoeff0(m2, t);
1326  pSetCoeff0(gcd, d);
1327  p_Test(m1,strat->tailRing);
1328  p_Test(m2,strat->tailRing);
1329
1330#ifdef KDEBUG
1331  if (TEST_OPT_DEBUG)
1332  {
1333    // Print("t = %d; s = %d; d = %d\n", nInt(t), nInt(s), nInt(d));
1334    PrintS("m1 = ");
1335    p_wrp(m1, strat->tailRing);
1336    PrintS(" ; m2 = ");
1337    p_wrp(m2, strat->tailRing);
1338    PrintS(" ; gcd = ");
1339    wrp(gcd);
1340    PrintS("\n--- create strong gcd poly: ");
1341    Print("\n p: ", i);
1342    wrp(p);
1343    Print("\n strat->S[%d]: ", i);
1344    wrp(strat->S[i]);
1345    PrintS(" ---> ");
1346  }
1347#endif
1348
1349  pNext(gcd) = p_Add_q(pp_Mult_mm(pNext(p), m1, strat->tailRing), pp_Mult_mm(pNext(strat->S[i]), m2, strat->tailRing), strat->tailRing);
1350  p_LmDelete(m1, strat->tailRing);
1351  p_LmDelete(m2, strat->tailRing);
1352
1353#ifdef KDEBUG
1354  if (TEST_OPT_DEBUG)
1355  {
1356    wrp(gcd);
1357    PrintLn();
1358  }
1359#endif
1360
1361  LObject h;
1362  h.p = gcd;
1363  h.tailRing = strat->tailRing;
1364  int posx;
1365  h.pCleardenom();
1366  strat->initEcart(&h);
1367  if (strat->Ll==-1)
1368    posx =0;
1369  else
1370    posx = strat->posInL(strat->L,strat->Ll,&h,strat);
1371  h.sev = pGetShortExpVector(h.p);
1372  if (currRing!=strat->tailRing)
1373    h.t_p = k_LmInit_currRing_2_tailRing(h.p, strat->tailRing);
1374  enterL(&strat->L,&strat->Ll,&strat->Lmax,h,posx);
1375  return TRUE;
1376}
1377#endif
1378
1379/*2
1380* put the pair (s[i],p)  into the set B, ecart=ecart(p)
1381*/
1382
1383void enterOnePairNormal (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
1384{
1385  assume(i<=strat->sl);
1386  if (strat->interred_flag) return;
1387
1388  int      l,j,compare;
1389  LObject  Lp;
1390  Lp.i_r = -1;
1391
1392#ifdef KDEBUG
1393  Lp.ecart=0; Lp.length=0;
1394#endif
1395  /*- computes the lcm(s[i],p) -*/
1396  Lp.lcm = pInit();
1397
1398#ifndef HAVE_RATGRING
1399  pLcm(p,strat->S[i],Lp.lcm);
1400#elif defined(HAVE_RATGRING)
1401  //  if (rIsRatGRing(currRing))
1402  pLcmRat(p,strat->S[i],Lp.lcm, currRing->real_var_start); // int rat_shift
1403#endif
1404  pSetm(Lp.lcm);
1405
1406
1407  if (strat->sugarCrit && ALLOW_PROD_CRIT(strat))
1408  {
1409    if((!((strat->ecartS[i]>0)&&(ecart>0)))
1410    && pHasNotCF(p,strat->S[i]))
1411    {
1412    /*
1413    *the product criterion has applied for (s,p),
1414    *i.e. lcm(s,p)=product of the leading terms of s and p.
1415    *Suppose (s,r) is in L and the leading term
1416    *of p divides lcm(s,r)
1417    *(==> the leading term of p divides the leading term of r)
1418    *but the leading term of s does not divide the leading term of r
1419    *(notice that tis condition is automatically satisfied if r is still
1420    *in S), then (s,r) can be cancelled.
1421    *This should be done here because the
1422    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
1423    *
1424    *Moreover, skipping (s,r) holds also for the noncommutative case.
1425    */
1426      strat->cp++;
1427      pLmFree(Lp.lcm);
1428      Lp.lcm=NULL;
1429      return;
1430    }
1431    else
1432      Lp.ecart = si_max(ecart,strat->ecartS[i]);
1433    if (strat->fromT && (strat->ecartS[i]>ecart))
1434    {
1435      pLmFree(Lp.lcm);
1436      Lp.lcm=NULL;
1437      return;
1438      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
1439    }
1440    /*
1441    *the set B collects the pairs of type (S[j],p)
1442    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
1443    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1444    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1445    */
1446    {
1447      j = strat->Bl;
1448      loop
1449      {
1450        if (j < 0)  break;
1451        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1452        if ((compare==1)
1453        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
1454        {
1455          strat->c3++;
1456          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1457          {
1458            pLmFree(Lp.lcm);
1459            return;
1460          }
1461          break;
1462        }
1463        else
1464        if ((compare ==-1)
1465        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
1466        {
1467          deleteInL(strat->B,&strat->Bl,j,strat);
1468          strat->c3++;
1469        }
1470        j--;
1471      }
1472    }
1473  }
1474  else /*sugarcrit*/
1475  {
1476    if (ALLOW_PROD_CRIT(strat))
1477    {
1478      // if currRing->nc_type!=quasi (or skew)
1479      // TODO: enable productCrit for super commutative algebras...
1480      if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
1481      pHasNotCF(p,strat->S[i]))
1482      {
1483      /*
1484      *the product criterion has applied for (s,p),
1485      *i.e. lcm(s,p)=product of the leading terms of s and p.
1486      *Suppose (s,r) is in L and the leading term
1487      *of p devides lcm(s,r)
1488      *(==> the leading term of p devides the leading term of r)
1489      *but the leading term of s does not devide the leading term of r
1490      *(notice that tis condition is automatically satisfied if r is still
1491      *in S), then (s,r) can be canceled.
1492      *This should be done here because the
1493      *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
1494      */
1495          strat->cp++;
1496          pLmFree(Lp.lcm);
1497          Lp.lcm=NULL;
1498          return;
1499      }
1500      if (strat->fromT && (strat->ecartS[i]>ecart))
1501      {
1502        pLmFree(Lp.lcm);
1503        Lp.lcm=NULL;
1504        return;
1505        /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
1506      }
1507      /*
1508      *the set B collects the pairs of type (S[j],p)
1509      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
1510      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1511      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1512      */
1513      for(j = strat->Bl;j>=0;j--)
1514      {
1515        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1516        if (compare==1)
1517        {
1518          strat->c3++;
1519          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1520          {
1521            pLmFree(Lp.lcm);
1522            return;
1523          }
1524          break;
1525        }
1526        else
1527        if (compare ==-1)
1528        {
1529          deleteInL(strat->B,&strat->Bl,j,strat);
1530          strat->c3++;
1531        }
1532      }
1533    }
1534  }
1535  /*
1536  *the pair (S[i],p) enters B if the spoly != 0
1537  */
1538  /*-  compute the short s-polynomial -*/
1539  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
1540    pNorm(p);
1541
1542  if ((strat->S[i]==NULL) || (p==NULL))
1543    return;
1544
1545  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
1546    Lp.p=NULL;
1547  else
1548  {
1549    #ifdef HAVE_PLURAL
1550    if ( rIsPluralRing(currRing) )
1551    {
1552      if(pHasNotCF(p, strat->S[i]))
1553      {
1554         if(ncRingType(currRing) == nc_lie)
1555         {
1556             // generalized prod-crit for lie-type
1557             strat->cp++;
1558             Lp.p = nc_p_Bracket_qq(pCopy(p),strat->S[i], currRing);
1559         }
1560         else
1561        if( ALLOW_PROD_CRIT(strat) )
1562        {
1563            // product criterion for homogeneous case in SCA
1564            strat->cp++;
1565            Lp.p = NULL;
1566        }
1567        else
1568        {
1569          Lp.p = // nc_CreateSpoly(strat->S[i],p,currRing);
1570                nc_CreateShortSpoly(strat->S[i], p, currRing);
1571
1572          assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
1573          pNext(Lp.p) = strat->tail; // !!!
1574        }
1575      }
1576      else
1577      {
1578        Lp.p = // nc_CreateSpoly(strat->S[i],p,currRing);
1579              nc_CreateShortSpoly(strat->S[i], p, currRing);
1580
1581        assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
1582        pNext(Lp.p) = strat->tail; // !!!
1583
1584      }
1585
1586
1587#if MYTEST
1588      if (TEST_OPT_DEBUG)
1589      {
1590        PrintS("enterOnePairNormal::\n strat->S[i]: "); pWrite(strat->S[i]);
1591        PrintS("p: "); pWrite(p);
1592        PrintS("SPoly: "); pWrite(Lp.p);
1593      }
1594#endif
1595
1596    }
1597    else
1598    #endif
1599    {
1600      assume(!rIsPluralRing(currRing));
1601      Lp.p = ksCreateShortSpoly(strat->S[i], p, strat->tailRing);
1602#if MYTEST
1603      if (TEST_OPT_DEBUG)
1604      {
1605        PrintS("enterOnePairNormal::\n strat->S[i]: "); pWrite(strat->S[i]);
1606        PrintS("p: "); pWrite(p);
1607        PrintS("commutative SPoly: "); pWrite(Lp.p);
1608      }
1609#endif
1610
1611      }
1612  }
1613  if (Lp.p == NULL)
1614  {
1615    /*- the case that the s-poly is 0 -*/
1616    if (strat->pairtest==NULL) initPairtest(strat);
1617    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
1618    strat->pairtest[strat->sl+1] = TRUE;
1619    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
1620    /*
1621    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
1622    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
1623    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
1624    *term of p devides the lcm(s,r)
1625    *(this canceling should be done here because
1626    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
1627    *the first case is handeled in chainCrit
1628    */
1629    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
1630  }
1631  else
1632  {
1633    /*- the pair (S[i],p) enters B -*/
1634    Lp.p1 = strat->S[i];
1635    Lp.p2 = p;
1636
1637    if (
1638        (!rIsPluralRing(currRing))
1639//      ||  (rIsPluralRing(currRing) && (ncRingType(currRing) != nc_lie))
1640       )
1641    {
1642      assume(pNext(Lp.p)==NULL); // TODO: this may be violated whenever ext.prod.crit. for Lie alg. is used
1643      pNext(Lp.p) = strat->tail; // !!!
1644    }
1645
1646    if (atR >= 0)
1647    {
1648      Lp.i_r1 = strat->S_2_R[i];
1649      Lp.i_r2 = atR;
1650    }
1651    else
1652    {
1653      Lp.i_r1 = -1;
1654      Lp.i_r2 = -1;
1655    }
1656    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1657
1658    if (TEST_OPT_INTSTRATEGY)
1659    {
1660      if (!rIsPluralRing(currRing))
1661        nDelete(&(Lp.p->coef));
1662    }
1663
1664    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
1665    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
1666  }
1667}
1668
1669/*2
1670* put the pair (s[i],p) into the set L, ecart=ecart(p)
1671* in the case that s forms a SB of (s)
1672*/
1673void enterOnePairSpecial (int i,poly p,int ecart,kStrategy strat, int atR = -1)
1674{
1675  //PrintS("try ");wrp(strat->S[i]);PrintS(" and ");wrp(p);PrintLn();
1676  if(pHasNotCF(p,strat->S[i]))
1677  {
1678    //PrintS("prod-crit\n");
1679    if(ALLOW_PROD_CRIT(strat))
1680    {
1681      //PrintS("prod-crit\n");
1682      strat->cp++;
1683      return;
1684    }
1685  }
1686
1687  int      l,j,compare;
1688  LObject  Lp;
1689  Lp.i_r = -1;
1690
1691  Lp.lcm = pInit();
1692  pLcm(p,strat->S[i],Lp.lcm);
1693  pSetm(Lp.lcm);
1694  for(j = strat->Ll;j>=0;j--)
1695  {
1696    compare=pDivComp(strat->L[j].lcm,Lp.lcm);
1697    if ((compare==1) || (pLmEqual(strat->L[j].lcm,Lp.lcm)))
1698    {
1699      //PrintS("c3-crit\n");
1700      strat->c3++;
1701      pLmFree(Lp.lcm);
1702      return;
1703    }
1704    else if (compare ==-1)
1705    {
1706      //Print("c3-crit with L[%d]\n",j);
1707      deleteInL(strat->L,&strat->Ll,j,strat);
1708      strat->c3++;
1709    }
1710  }
1711  /*-  compute the short s-polynomial -*/
1712
1713  #ifdef HAVE_PLURAL
1714  if (rIsPluralRing(currRing))
1715  {
1716    Lp.p = nc_CreateShortSpoly(strat->S[i],p, currRing); // ??? strat->tailRing?
1717  }
1718  else
1719  #endif
1720    Lp.p = ksCreateShortSpoly(strat->S[i],p,strat->tailRing);
1721
1722  if (Lp.p == NULL)
1723  {
1724     //PrintS("short spoly==NULL\n");
1725     pLmFree(Lp.lcm);
1726  }
1727  else
1728  {
1729    /*- the pair (S[i],p) enters L -*/
1730    Lp.p1 = strat->S[i];
1731    Lp.p2 = p;
1732    if (atR >= 0)
1733    {
1734      Lp.i_r1 = strat->S_2_R[i];
1735      Lp.i_r2 = atR;
1736    }
1737    else
1738    {
1739      Lp.i_r1 = -1;
1740      Lp.i_r2 = -1;
1741    }
1742    assume(pNext(Lp.p) == NULL);
1743    pNext(Lp.p) = strat->tail;
1744    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1745    if (TEST_OPT_INTSTRATEGY)
1746    {
1747      nDelete(&(Lp.p->coef));
1748    }
1749    l = strat->posInL(strat->L,strat->Ll,&Lp,strat);
1750    //Print("-> L[%d]\n",l);
1751    enterL(&strat->L,&strat->Ll,&strat->Lmax,Lp,l);
1752  }
1753}
1754
1755/*2
1756* merge set B into L
1757*/
1758void kMergeBintoL(kStrategy strat)
1759{
1760  int j=strat->Ll+strat->Bl+1;
1761  if (j>strat->Lmax)
1762  {
1763    j=((j+setmaxLinc-1)/setmaxLinc)*setmaxLinc;
1764    strat->L = (LSet)omReallocSize(strat->L,strat->Lmax*sizeof(LObject),
1765                                 j*sizeof(LObject));
1766    strat->Lmax=j;
1767  }
1768  j = strat->Ll;
1769  int i;
1770  for (i=strat->Bl; i>=0; i--)
1771  {
1772    j = strat->posInL(strat->L,j,&(strat->B[i]),strat);
1773    enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
1774  }
1775  strat->Bl = -1;
1776}
1777/*2
1778*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
1779*using the chain-criterion in B and L and enters B to L
1780*/
1781void chainCritNormal (poly p,int ecart,kStrategy strat)
1782{
1783  int i,j,l;
1784
1785  /*
1786  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
1787  *In this case all elements in B such
1788  *that their lcm is divisible by the leading term of S[i] can be canceled
1789  */
1790  if (strat->pairtest!=NULL)
1791  {
1792    {
1793      /*- i.e. there is an i with pairtest[i]==TRUE -*/
1794      for (j=0; j<=strat->sl; j++)
1795      {
1796        if (strat->pairtest[j])
1797        {
1798          for (i=strat->Bl; i>=0; i--)
1799          {
1800            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
1801            {
1802              deleteInL(strat->B,&strat->Bl,i,strat);
1803              strat->c3++;
1804            }
1805          }
1806        }
1807      }
1808    }
1809    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
1810    strat->pairtest=NULL;
1811  }
1812  if (strat->Gebauer || strat->fromT)
1813  {
1814    if (strat->sugarCrit)
1815    {
1816    /*
1817    *suppose L[j] == (s,r) and p/lcm(s,r)
1818    *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
1819    *and in case the sugar is o.k. then L[j] can be canceled
1820    */
1821      for (j=strat->Ll; j>=0; j--)
1822      {
1823        if (sugarDivisibleBy(ecart,strat->L[j].ecart)
1824        && ((pNext(strat->L[j].p) == strat->tail) || (currRing->OrdSgn==1))
1825        && pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1826        {
1827          if (strat->L[j].p == strat->tail)
1828          {
1829              deleteInL(strat->L,&strat->Ll,j,strat);
1830              strat->c3++;
1831          }
1832        }
1833      }
1834      /*
1835      *this is GEBAUER-MOELLER:
1836      *in B all elements with the same lcm except the "best"
1837      *(i.e. the last one in B with this property) will be canceled
1838      */
1839      j = strat->Bl;
1840      loop /*cannot be changed into a for !!! */
1841      {
1842        if (j <= 0) break;
1843        i = j-1;
1844        loop
1845        {
1846          if (i <  0) break;
1847          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
1848          {
1849            strat->c3++;
1850            if (sugarDivisibleBy(strat->B[j].ecart,strat->B[i].ecart))
1851            {
1852              deleteInL(strat->B,&strat->Bl,i,strat);
1853              j--;
1854            }
1855            else
1856            {
1857              deleteInL(strat->B,&strat->Bl,j,strat);
1858              break;
1859            }
1860          }
1861          i--;
1862        }
1863        j--;
1864      }
1865    }
1866    else /*sugarCrit*/
1867    {
1868      /*
1869      *suppose L[j] == (s,r) and p/lcm(s,r)
1870      *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
1871      *and in case the sugar is o.k. then L[j] can be canceled
1872      */
1873      for (j=strat->Ll; j>=0; j--)
1874      {
1875        if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1876        {
1877          if ((pNext(strat->L[j].p) == strat->tail)||(currRing->OrdSgn==1))
1878          {
1879            deleteInL(strat->L,&strat->Ll,j,strat);
1880            strat->c3++;
1881          }
1882        }
1883      }
1884      /*
1885      *this is GEBAUER-MOELLER:
1886      *in B all elements with the same lcm except the "best"
1887      *(i.e. the last one in B with this property) will be canceled
1888      */
1889      j = strat->Bl;
1890      loop   /*cannot be changed into a for !!! */
1891      {
1892        if (j <= 0) break;
1893        for(i=j-1; i>=0; i--)
1894        {
1895          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
1896          {
1897            strat->c3++;
1898            deleteInL(strat->B,&strat->Bl,i,strat);
1899            j--;
1900          }
1901        }
1902        j--;
1903      }
1904    }
1905    /*
1906    *the elements of B enter L
1907    */
1908    kMergeBintoL(strat);
1909  }
1910  else
1911  {
1912    for (j=strat->Ll; j>=0; j--)
1913    {
1914      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1915      {
1916        if ((pNext(strat->L[j].p) == strat->tail)||(currRing->OrdSgn==1))
1917        {
1918          deleteInL(strat->L,&strat->Ll,j,strat);
1919          strat->c3++;
1920        }
1921      }
1922    }
1923    /*
1924    *this is our MODIFICATION of GEBAUER-MOELLER:
1925    *First the elements of B enter L,
1926    *then we fix a lcm and the "best" element in L
1927    *(i.e the last in L with this lcm and of type (s,p))
1928    *and cancel all the other elements of type (r,p) with this lcm
1929    *except the case the element (s,r) has also the same lcm
1930    *and is on the worst position with respect to (s,p) and (r,p)
1931    */
1932    /*
1933    *B enters to L/their order with respect to B is permutated for elements
1934    *B[i].p with the same leading term
1935    */
1936    kMergeBintoL(strat);
1937    j = strat->Ll;
1938    loop  /*cannot be changed into a for !!! */
1939    {
1940      if (j <= 0)
1941      {
1942        /*now L[0] cannot be canceled any more and the tail can be removed*/
1943        if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
1944        break;
1945      }
1946      if (strat->L[j].p2 == p)
1947      {
1948        i = j-1;
1949        loop
1950        {
1951          if (i < 0)  break;
1952          if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
1953          {
1954            /*L[i] could be canceled but we search for a better one to cancel*/
1955            strat->c3++;
1956            if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
1957            && (pNext(strat->L[l].p) == strat->tail)
1958            && (!pLmEqual(strat->L[i].p,strat->L[l].p))
1959            && pDivisibleBy(p,strat->L[l].lcm))
1960            {
1961              /*
1962              *"NOT equal(...)" because in case of "equal" the element L[l]
1963              *is "older" and has to be from theoretical point of view behind
1964              *L[i], but we do not want to reorder L
1965              */
1966              strat->L[i].p2 = strat->tail;
1967              /*
1968              *L[l] will be canceled, we cannot cancel L[i] later on,
1969              *so we mark it with "tail"
1970              */
1971              deleteInL(strat->L,&strat->Ll,l,strat);
1972              i--;
1973            }
1974            else
1975            {
1976              deleteInL(strat->L,&strat->Ll,i,strat);
1977            }
1978            j--;
1979          }
1980          i--;
1981        }
1982      }
1983      else if (strat->L[j].p2 == strat->tail)
1984      {
1985        /*now L[j] cannot be canceled any more and the tail can be removed*/
1986        strat->L[j].p2 = p;
1987      }
1988      j--;
1989    }
1990  }
1991}
1992#ifdef HAVE_RATGRING
1993void chainCritPart (poly p,int ecart,kStrategy strat)
1994{
1995  int i,j,l;
1996
1997  /*
1998  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
1999  *In this case all elements in B such
2000  *that their lcm is divisible by the leading term of S[i] can be canceled
2001  */
2002  if (strat->pairtest!=NULL)
2003  {
2004    {
2005      /*- i.e. there is an i with pairtest[i]==TRUE -*/
2006      for (j=0; j<=strat->sl; j++)
2007      {
2008        if (strat->pairtest[j])
2009        {
2010          for (i=strat->Bl; i>=0; i--)
2011          {
2012            if (_p_LmDivisibleByPart(strat->S[j],currRing,
2013               strat->B[i].lcm,currRing,
2014               currRing->real_var_start,currRing->real_var_end))
2015            {
2016              if(TEST_OPT_DEBUG)
2017              {
2018                 Print("chain-crit-part: S[%d]=",j);
2019                 p_wrp(strat->S[j],currRing);
2020                 Print(" divide B[%d].lcm=",i);
2021                 p_wrp(strat->B[i].lcm,currRing);
2022                 PrintLn();
2023              }
2024              deleteInL(strat->B,&strat->Bl,i,strat);
2025              strat->c3++;
2026            }
2027          }
2028        }
2029      }
2030    }
2031    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
2032    strat->pairtest=NULL;
2033  }
2034  if (strat->Gebauer || strat->fromT)
2035  {
2036    if (strat->sugarCrit)
2037    {
2038    /*
2039    *suppose L[j] == (s,r) and p/lcm(s,r)
2040    *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
2041    *and in case the sugar is o.k. then L[j] can be canceled
2042    */
2043      for (j=strat->Ll; j>=0; j--)
2044      {
2045        if (sugarDivisibleBy(ecart,strat->L[j].ecart)
2046        && ((pNext(strat->L[j].p) == strat->tail) || (currRing->OrdSgn==1))
2047        && pCompareChainPart(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2048        {
2049          if (strat->L[j].p == strat->tail)
2050          {
2051              if(TEST_OPT_DEBUG)
2052              {
2053                 PrintS("chain-crit-part: pCompareChainPart p=");
2054                 p_wrp(p,currRing);
2055                 Print(" delete L[%d]",j);
2056                 p_wrp(strat->L[j].lcm,currRing);
2057                 PrintLn();
2058              }
2059              deleteInL(strat->L,&strat->Ll,j,strat);
2060              strat->c3++;
2061          }
2062        }
2063      }
2064      /*
2065      *this is GEBAUER-MOELLER:
2066      *in B all elements with the same lcm except the "best"
2067      *(i.e. the last one in B with this property) will be canceled
2068      */
2069      j = strat->Bl;
2070      loop /*cannot be changed into a for !!! */
2071      {
2072        if (j <= 0) break;
2073        i = j-1;
2074        loop
2075        {
2076          if (i <  0) break;
2077          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
2078          {
2079            strat->c3++;
2080            if (sugarDivisibleBy(strat->B[j].ecart,strat->B[i].ecart))
2081            {
2082              if(TEST_OPT_DEBUG)
2083              {
2084                 Print("chain-crit-part: sugar B[%d].lcm=",j);
2085                 p_wrp(strat->B[j].lcm,currRing);
2086                 Print(" delete B[%d]",i);
2087                 p_wrp(strat->B[i].lcm,currRing);
2088                 PrintLn();
2089              }
2090              deleteInL(strat->B,&strat->Bl,i,strat);
2091              j--;
2092            }
2093            else
2094            {
2095              if(TEST_OPT_DEBUG)
2096              {
2097                 Print("chain-crit-part: sugar B[%d].lcm=",i);
2098                 p_wrp(strat->B[i].lcm,currRing);
2099                 Print(" delete B[%d]",j);
2100                 p_wrp(strat->B[j].lcm,currRing);
2101                 PrintLn();
2102              }
2103              deleteInL(strat->B,&strat->Bl,j,strat);
2104              break;
2105            }
2106          }
2107          i--;
2108        }
2109        j--;
2110      }
2111    }
2112    else /*sugarCrit*/
2113    {
2114      /*
2115      *suppose L[j] == (s,r) and p/lcm(s,r)
2116      *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
2117      *and in case the sugar is o.k. then L[j] can be canceled
2118      */
2119      for (j=strat->Ll; j>=0; j--)
2120      {
2121        if (pCompareChainPart(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2122        {
2123          if ((pNext(strat->L[j].p) == strat->tail)||(currRing->OrdSgn==1))
2124          {
2125              if(TEST_OPT_DEBUG)
2126              {
2127                 PrintS("chain-crit-part: sugar:pCompareChainPart p=");
2128                 p_wrp(p,currRing);
2129                 Print(" delete L[%d]",j);
2130                 p_wrp(strat->L[j].lcm,currRing);
2131                 PrintLn();
2132              }
2133            deleteInL(strat->L,&strat->Ll,j,strat);
2134            strat->c3++;
2135          }
2136        }
2137      }
2138      /*
2139      *this is GEBAUER-MOELLER:
2140      *in B all elements with the same lcm except the "best"
2141      *(i.e. the last one in B with this property) will be canceled
2142      */
2143      j = strat->Bl;
2144      loop   /*cannot be changed into a for !!! */
2145      {
2146        if (j <= 0) break;
2147        for(i=j-1; i>=0; i--)
2148        {
2149          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
2150          {
2151              if(TEST_OPT_DEBUG)
2152              {
2153                 Print("chain-crit-part: equal lcm B[%d].lcm=",j);
2154                 p_wrp(strat->B[j].lcm,currRing);
2155                 Print(" delete B[%d]\n",i);
2156              }
2157            strat->c3++;
2158            deleteInL(strat->B,&strat->Bl,i,strat);
2159            j--;
2160          }
2161        }
2162        j--;
2163      }
2164    }
2165    /*
2166    *the elements of B enter L
2167    */
2168    kMergeBintoL(strat);
2169  }
2170  else
2171  {
2172    for (j=strat->Ll; j>=0; j--)
2173    {
2174      if (pCompareChainPart(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2175      {
2176        if ((pNext(strat->L[j].p) == strat->tail)||(currRing->OrdSgn==1))
2177        {
2178              if(TEST_OPT_DEBUG)
2179              {
2180                 PrintS("chain-crit-part: pCompareChainPart p=");
2181                 p_wrp(p,currRing);
2182                 Print(" delete L[%d]",j);
2183                 p_wrp(strat->L[j].lcm,currRing);
2184                 PrintLn();
2185              }
2186          deleteInL(strat->L,&strat->Ll,j,strat);
2187          strat->c3++;
2188        }
2189      }
2190    }
2191    /*
2192    *this is our MODIFICATION of GEBAUER-MOELLER:
2193    *First the elements of B enter L,
2194    *then we fix a lcm and the "best" element in L
2195    *(i.e the last in L with this lcm and of type (s,p))
2196    *and cancel all the other elements of type (r,p) with this lcm
2197    *except the case the element (s,r) has also the same lcm
2198    *and is on the worst position with respect to (s,p) and (r,p)
2199    */
2200    /*
2201    *B enters to L/their order with respect to B is permutated for elements
2202    *B[i].p with the same leading term
2203    */
2204    kMergeBintoL(strat);
2205    j = strat->Ll;
2206    loop  /*cannot be changed into a for !!! */
2207    {
2208      if (j <= 0)
2209      {
2210        /*now L[0] cannot be canceled any more and the tail can be removed*/
2211        if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
2212        break;
2213      }
2214      if (strat->L[j].p2 == p)
2215      {
2216        i = j-1;
2217        loop
2218        {
2219          if (i < 0)  break;
2220          if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
2221          {
2222            /*L[i] could be canceled but we search for a better one to cancel*/
2223            strat->c3++;
2224            if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
2225            && (pNext(strat->L[l].p) == strat->tail)
2226            && (!pLmEqual(strat->L[i].p,strat->L[l].p))
2227            && _p_LmDivisibleByPart(p,currRing,
2228                           strat->L[l].lcm,currRing,
2229                           currRing->real_var_start, currRing->real_var_end))
2230
2231            {
2232              /*
2233              *"NOT equal(...)" because in case of "equal" the element L[l]
2234              *is "older" and has to be from theoretical point of view behind
2235              *L[i], but we do not want to reorder L
2236              */
2237              strat->L[i].p2 = strat->tail;
2238              /*
2239              *L[l] will be canceled, we cannot cancel L[i] later on,
2240              *so we mark it with "tail"
2241              */
2242              if(TEST_OPT_DEBUG)
2243              {
2244                 PrintS("chain-crit-part: divisible_by p=");
2245                 p_wrp(p,currRing);
2246                 Print(" delete L[%d]",l);
2247                 p_wrp(strat->L[l].lcm,currRing);
2248                 PrintLn();
2249              }
2250              deleteInL(strat->L,&strat->Ll,l,strat);
2251              i--;
2252            }
2253            else
2254            {
2255              if(TEST_OPT_DEBUG)
2256              {
2257                 PrintS("chain-crit-part: divisible_by(2) p=");
2258                 p_wrp(p,currRing);
2259                 Print(" delete L[%d]",i);
2260                 p_wrp(strat->L[i].lcm,currRing);
2261                 PrintLn();
2262              }
2263              deleteInL(strat->L,&strat->Ll,i,strat);
2264            }
2265            j--;
2266          }
2267          i--;
2268        }
2269      }
2270      else if (strat->L[j].p2 == strat->tail)
2271      {
2272        /*now L[j] cannot be canceled any more and the tail can be removed*/
2273        strat->L[j].p2 = p;
2274      }
2275      j--;
2276    }
2277  }
2278}
2279#endif
2280
2281/*2
2282*(s[0],h),...,(s[k],h) will be put to the pairset L
2283*/
2284void initenterpairs (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
2285{
2286
2287  if ((strat->syzComp==0)
2288  || (pGetComp(h)<=strat->syzComp))
2289  {
2290    int j;
2291    BOOLEAN new_pair=FALSE;
2292
2293    if (pGetComp(h)==0)
2294    {
2295      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
2296      if ((isFromQ)&&(strat->fromQ!=NULL))
2297      {
2298        for (j=0; j<=k; j++)
2299        {
2300          if (!strat->fromQ[j])
2301          {
2302            new_pair=TRUE;
2303            strat->enterOnePair(j,h,ecart,isFromQ,strat, atR);
2304          //Print("j:%d, Ll:%d\n",j,strat->Ll);
2305          }
2306        }
2307      }
2308      else
2309      {
2310        new_pair=TRUE;
2311        for (j=0; j<=k; j++)
2312        {
2313          strat->enterOnePair(j,h,ecart,isFromQ,strat, atR);
2314          //Print("j:%d, Ll:%d\n",j,strat->Ll);
2315        }
2316      }
2317    }
2318    else
2319    {
2320      for (j=0; j<=k; j++)
2321      {
2322        if ((pGetComp(h)==pGetComp(strat->S[j]))
2323        || (pGetComp(strat->S[j])==0))
2324        {
2325          new_pair=TRUE;
2326          strat->enterOnePair(j,h,ecart,isFromQ,strat, atR);
2327        //Print("j:%d, Ll:%d\n",j,strat->Ll);
2328        }
2329      }
2330    }
2331
2332    if (new_pair)
2333    {
2334#ifdef HAVE_RATGRING
2335      if (currRing->real_var_start>0)
2336        chainCritPart(h,ecart,strat);
2337      else
2338#endif
2339      strat->chainCrit(h,ecart,strat);
2340    }
2341  }
2342}
2343
2344#ifdef HAVE_RINGS
2345/*2
2346*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
2347*using the chain-criterion in B and L and enters B to L
2348*/
2349void chainCritRing (poly p,int, kStrategy strat)
2350{
2351  int i,j,l;
2352  /*
2353  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
2354  *In this case all elements in B such
2355  *that their lcm is divisible by the leading term of S[i] can be canceled
2356  */
2357  if (strat->pairtest!=NULL)
2358  {
2359    {
2360      /*- i.e. there is an i with pairtest[i]==TRUE -*/
2361      for (j=0; j<=strat->sl; j++)
2362      {
2363        if (strat->pairtest[j])
2364        {
2365          for (i=strat->Bl; i>=0; i--)
2366          {
2367            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
2368            {
2369#ifdef KDEBUG
2370              if (TEST_OPT_DEBUG)
2371              {
2372                PrintS("--- chain criterion func chainCritRing type 1\n");
2373                PrintS("strat->S[j]:");
2374                wrp(strat->S[j]);
2375                PrintS("  strat->B[i].lcm:");
2376                wrp(strat->B[i].lcm);
2377                PrintLn();
2378              }
2379#endif
2380              deleteInL(strat->B,&strat->Bl,i,strat);
2381              strat->c3++;
2382            }
2383          }
2384        }
2385      }
2386    }
2387    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
2388    strat->pairtest=NULL;
2389  }
2390  assume(!(strat->Gebauer || strat->fromT));
2391  for (j=strat->Ll; j>=0; j--)
2392  {
2393    if (strat->L[j].lcm != NULL && n_DivBy(pGetCoeff(strat->L[j].lcm), pGetCoeff(p), currRing->cf))
2394    {
2395      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
2396      {
2397        if ((pNext(strat->L[j].p) == strat->tail) || (currRing->OrdSgn==1))
2398        {
2399          deleteInL(strat->L,&strat->Ll,j,strat);
2400          strat->c3++;
2401#ifdef KDEBUG
2402              if (TEST_OPT_DEBUG)
2403              {
2404                PrintS("--- chain criterion func chainCritRing type 2\n");
2405                PrintS("strat->L[j].p:");
2406                wrp(strat->L[j].p);
2407                PrintS("  p:");
2408                wrp(p);
2409                PrintLn();
2410              }
2411#endif
2412        }
2413      }
2414    }
2415  }
2416  /*
2417  *this is our MODIFICATION of GEBAUER-MOELLER:
2418  *First the elements of B enter L,
2419  *then we fix a lcm and the "best" element in L
2420  *(i.e the last in L with this lcm and of type (s,p))
2421  *and cancel all the other elements of type (r,p) with this lcm
2422  *except the case the element (s,r) has also the same lcm
2423  *and is on the worst position with respect to (s,p) and (r,p)
2424  */
2425  /*
2426  *B enters to L/their order with respect to B is permutated for elements
2427  *B[i].p with the same leading term
2428  */
2429  kMergeBintoL(strat);
2430  j = strat->Ll;
2431  loop  /*cannot be changed into a for !!! */
2432  {
2433    if (j <= 0)
2434    {
2435      /*now L[0] cannot be canceled any more and the tail can be removed*/
2436      if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
2437      break;
2438    }
2439    if (strat->L[j].p2 == p) // Was the element added from B?
2440    {
2441      i = j-1;
2442      loop
2443      {
2444        if (i < 0)  break;
2445        // Element is from B and has the same lcm as L[j]
2446        if ((strat->L[i].p2 == p) && n_DivBy(pGetCoeff(strat->L[j].lcm), pGetCoeff(strat->L[i].lcm), currRing->cf)
2447             && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
2448        {
2449          /*L[i] could be canceled but we search for a better one to cancel*/
2450          strat->c3++;
2451#ifdef KDEBUG
2452          if (TEST_OPT_DEBUG)
2453          {
2454            PrintS("--- chain criterion func chainCritRing type 3\n");
2455            PrintS("strat->L[j].lcm:");
2456            wrp(strat->L[j].lcm);
2457            PrintS("  strat->L[i].lcm:");
2458            wrp(strat->L[i].lcm);
2459            PrintLn();
2460          }
2461#endif
2462          if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
2463          && (pNext(strat->L[l].p) == strat->tail)
2464          && (!pLmEqual(strat->L[i].p,strat->L[l].p))
2465          && pDivisibleBy(p,strat->L[l].lcm))
2466          {
2467            /*
2468            *"NOT equal(...)" because in case of "equal" the element L[l]
2469            *is "older" and has to be from theoretical point of view behind
2470            *L[i], but we do not want to reorder L
2471            */
2472            strat->L[i].p2 = strat->tail;
2473            /*
2474            *L[l] will be canceled, we cannot cancel L[i] later on,
2475            *so we mark it with "tail"
2476            */
2477            deleteInL(strat->L,&strat->Ll,l,strat);
2478            i--;
2479          }
2480          else
2481          {
2482            deleteInL(strat->L,&strat->Ll,i,strat);
2483          }
2484          j--;
2485        }
2486        i--;
2487      }
2488    }
2489    else if (strat->L[j].p2 == strat->tail)
2490    {
2491      /*now L[j] cannot be canceled any more and the tail can be removed*/
2492      strat->L[j].p2 = p;
2493    }
2494    j--;
2495  }
2496}
2497#endif
2498
2499#ifdef HAVE_RINGS
2500long ind2(long arg)
2501{
2502  long ind = 0;
2503  if (arg <= 0) return 0;
2504  while (arg%2 == 0)
2505  {
2506    arg = arg / 2;
2507    ind++;
2508  }
2509  return ind;
2510}
2511
2512long ind_fact_2(long arg)
2513{
2514  long ind = 0;
2515  if (arg <= 0) return 0;
2516  if (arg%2 == 1) { arg--; }
2517  while (arg > 0)
2518  {
2519    ind += ind2(arg);
2520    arg = arg - 2;
2521  }
2522  return ind;
2523}
2524#endif
2525
2526#ifdef HAVE_VANIDEAL
2527long twoPow(long arg)
2528{
2529  return 1L << arg;
2530}
2531
2532/*2
2533* put the pair (p, f) in B and f in T
2534*/
2535void enterOneZeroPairRing (poly f, poly t_p, poly p, int ecart, kStrategy strat, int atR = -1)
2536{
2537  int      l,j,compare,compareCoeff;
2538  LObject  Lp;
2539
2540  if (strat->interred_flag) return;
2541#ifdef KDEBUG
2542  Lp.ecart=0; Lp.length=0;
2543#endif
2544  /*- computes the lcm(s[i],p) -*/
2545  Lp.lcm = pInit();
2546
2547  pLcm(p,f,Lp.lcm);
2548  pSetm(Lp.lcm);
2549  pSetCoeff(Lp.lcm, nLcm(pGetCoeff(p), pGetCoeff(f), currRing));
2550  assume(!strat->sugarCrit);
2551  assume(!strat->fromT);
2552  /*
2553  *the set B collects the pairs of type (S[j],p)
2554  *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p) != lcm(r,p)
2555  *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
2556  *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
2557  */
2558  for(j = strat->Bl;j>=0;j--)
2559  {
2560    compare=pDivCompRing(strat->B[j].lcm,Lp.lcm);
2561    compareCoeff = nDivComp(pGetCoeff(strat->B[j].lcm), pGetCoeff(Lp.lcm));
2562    if (compareCoeff == 0 || compare == compareCoeff)
2563    {
2564      if (compare == 1)
2565      {
2566        strat->c3++;
2567        pLmDelete(Lp.lcm);
2568        return;
2569      }
2570      else
2571      if (compare == -1)
2572      {
2573        deleteInL(strat->B,&strat->Bl,j,strat);
2574        strat->c3++;
2575      }
2576    }
2577    if (compare == pDivComp_EQUAL)
2578    {
2579      // Add hint for same LM and direction of LC (later) (TODO Oliver)
2580      if (compareCoeff == 1)
2581      {
2582        strat->c3++;
2583        pLmDelete(Lp.lcm);
2584        return;
2585      }
2586      else
2587      if (compareCoeff == -1)
2588      {
2589        deleteInL(strat->B,&strat->Bl,j,strat);
2590        strat->c3++;
2591      }
2592    }
2593  }
2594  /*
2595  *the pair (S[i],p) enters B if the spoly != 0
2596  */
2597  /*-  compute the short s-polynomial -*/
2598  if ((f==NULL) || (p==NULL)) return;
2599  pNorm(p);
2600  {
2601    Lp.p = ksCreateShortSpoly(f, p, strat->tailRing);
2602  }
2603  if (Lp.p == NULL) //deactivated, as we are adding pairs with zeropoly and not from S
2604  {
2605    /*- the case that the s-poly is 0 -*/
2606//    if (strat->pairtest==NULL) initPairtest(strat);
2607//    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
2608//    strat->pairtest[strat->sl+1] = TRUE;
2609    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
2610    /*
2611    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
2612    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
2613    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
2614    *term of p devides the lcm(s,r)
2615    *(this canceling should be done here because
2616    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
2617    *the first case is handeled in chainCrit
2618    */
2619    if (Lp.lcm!=NULL) pLmDelete(Lp.lcm);
2620  }
2621  else
2622  {
2623    /*- the pair (S[i],p) enters B -*/
2624    Lp.p1 = f;
2625    Lp.p2 = p;
2626
2627    pNext(Lp.p) = strat->tail;
2628
2629    LObject tmp_h(f, currRing, strat->tailRing);
2630    tmp_h.SetShortExpVector();
2631    strat->initEcart(&tmp_h);
2632    tmp_h.sev = pGetShortExpVector(tmp_h.p);
2633    tmp_h.t_p = t_p;
2634
2635    enterT(tmp_h, strat, strat->tl + 1);
2636
2637    if (atR >= 0)
2638    {
2639      Lp.i_r2 = atR;
2640      Lp.i_r1 = strat->tl;
2641    }
2642
2643    strat->initEcartPair(&Lp,f,p,0/*strat->ecartS[i]*/,ecart);     // Attention: TODO: break ecart
2644    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
2645    enterL(&strat->B, &strat->Bl, &strat->Bmax, Lp, l);
2646  }
2647}
2648
2649/* Helper for kCreateZeroPoly
2650 * enumerating the exponents
2651ring r = 2^2, (a, b, c), lp; ideal G0 = system("createG0"); ideal G = interred(G0); ncols(G0); ncols(G);
2652 */
2653
2654int nextZeroSimplexExponent (long exp[], long ind[], long cexp[], long cind[], long* cabsind, long step[], long bound, long N)
2655/* gives the next exponent from the set H_1 */
2656{
2657  long add = ind2(cexp[1] + 2);
2658  if ((*cabsind < bound) && (*cabsind - step[1] + add < bound))
2659  {
2660    cexp[1] += 2;
2661    cind[1] += add;
2662    *cabsind += add;
2663  }
2664  else
2665  {
2666    // cabsind >= habsind
2667    if (N == 1) return 0;
2668    int i = 1;
2669    while (exp[i] == cexp[i] && i <= N) i++;
2670    cexp[i] = exp[i];
2671    *cabsind -= cind[i];
2672    cind[i] = ind[i];
2673    step[i] = 500000;
2674    *cabsind += cind[i];
2675    // Print("in: %d\n", *cabsind);
2676    i += 1;
2677    if (i > N) return 0;
2678    do
2679    {
2680      step[1] = 500000;
2681      for (int j = i + 1; j <= N; j++)
2682      {
2683        if (step[1] > step[j]) step[1] = step[j];
2684      }
2685      add = ind2(cexp[i] + 2);
2686      if (*cabsind - step[1] + add >= bound)
2687      {
2688        cexp[i] = exp[i];
2689        *cabsind -= cind[i];
2690        cind[i] = ind[i];
2691        *cabsind += cind[i];
2692        step[i] = 500000;
2693        i += 1;
2694        if (i > N) return 0;
2695      }
2696      else step[1] = -1;
2697    } while (step[1] != -1);
2698    step[1] = 500000;
2699    cexp[i] += 2;
2700    cind[i] += add;
2701    *cabsind += add;
2702    if (add < step[i]) step[i] = add;
2703    for (i = 2; i <= N; i++)
2704    {
2705      if (step[1] > step[i]) step[1] = step[i];
2706    }
2707  }
2708  return 1;
2709}
2710
2711/*
2712 * Creates the zero Polynomial on position exp
2713 * long exp[] : exponent of leading term
2714 * cabsind    : total 2-ind of exp (if -1 will be computed)
2715 * poly* t_p  : will hold the LT in tailRing
2716 * leadRing   : ring for the LT
2717 * tailRing   : ring for the tail
2718 */
2719
2720poly kCreateZeroPoly(long exp[], long cabsind, poly* t_p, ring leadRing, ring tailRing)
2721{
2722
2723  poly zeroPoly = NULL;
2724
2725  number tmp1;
2726  poly tmp2, tmp3;
2727
2728  if (cabsind == -1)
2729  {
2730    cabsind = 0;
2731    for (int i = 1; i <= leadRing->N; i++)
2732    {
2733      cabsind += ind_fact_2(exp[i]);
2734    }
2735//    Print("cabsind: %d\n", cabsind);
2736  }
2737  if (cabsind < leadRing->ch)
2738  {
2739    zeroPoly = p_ISet(twoPow(leadRing->ch - cabsind), tailRing);
2740  }
2741  else
2742  {
2743    zeroPoly = p_ISet(1, tailRing);
2744  }
2745  for (int i = 1; i <= leadRing->N; i++)
2746  {
2747    for (long j = 1; j <= exp[i]; j++)
2748    {
2749      tmp1 = nInit(j);
2750      tmp2 = p_ISet(1, tailRing);
2751      p_SetExp(tmp2, i, 1, tailRing);
2752      p_Setm(tmp2, tailRing);
2753      if (nIsZero(tmp1))
2754      { // should nowbe obsolet, test ! TODO OLIVER
2755        zeroPoly = p_Mult_q(zeroPoly, tmp2, tailRing);
2756      }
2757      else
2758      {
2759        tmp3 = p_NSet(nCopy(tmp1), tailRing);
2760        zeroPoly = p_Mult_q(zeroPoly, p_Add_q(tmp3, tmp2, tailRing), tailRing);
2761      }
2762    }
2763  }
2764  tmp2 = p_NSet(nCopy(pGetCoeff(zeroPoly)), leadRing);
2765  for (int i = 1; i <= leadRing->N; i++)
2766  {
2767    pSetExp(tmp2, i, p_GetExp(zeroPoly, i, tailRing));
2768  }
2769  p_Setm(tmp2, leadRing);
2770  *t_p = zeroPoly;
2771  zeroPoly = pNext(zeroPoly);
2772  pNext(*t_p) = NULL;
2773  pNext(tmp2) = zeroPoly;
2774  return tmp2;
2775}
2776
2777// #define OLI_DEBUG
2778
2779/*
2780 * Generate the s-polynomial for the virtual set of zero-polynomials
2781 */
2782
2783void initenterzeropairsRing (poly p, int ecart, kStrategy strat, int atR)
2784{
2785  // Initialize
2786  long exp[50];            // The exponent of \hat{X} (basepoint)
2787  long cexp[50];           // The current exponent for iterating over all
2788  long ind[50];            // The power of 2 in the i-th component of exp
2789  long cind[50];           // analog for cexp
2790  long mult[50];           // How to multiply the elements of G
2791  long cabsind = 0;        // The abs. index of cexp, i.e. the sum of cind
2792  long habsind = 0;        // The abs. index of the coefficient of h
2793  long step[50];           // The last increases
2794  for (int i = 1; i <= currRing->N; i++)
2795  {
2796    exp[i] = p_GetExp(p, i, currRing);
2797    if (exp[i] & 1 != 0)
2798    {
2799      exp[i] = exp[i] - 1;
2800      mult[i] = 1;
2801    }
2802    cexp[i] = exp[i];
2803    ind[i] = ind_fact_2(exp[i]);
2804    cabsind += ind[i];
2805    cind[i] = ind[i];
2806    step[i] = 500000;
2807  }
2808  step[1] = 500000;
2809  habsind = ind2((long) p_GetCoeff(p, currRing));
2810  long bound = currRing->ch - habsind;
2811#ifdef OLI_DEBUG
2812  PrintS("-------------\npoly  :");
2813  wrp(p);
2814  Print("\nexp   : (%d, %d)\n", exp[1] + mult[1], exp[2] + mult[1]);
2815  Print("cexp  : (%d, %d)\n", cexp[1], cexp[2]);
2816  Print("cind  : (%d, %d)\n", cind[1], cind[2]);
2817  Print("bound : %d\n", bound);
2818  Print("cind  : %d\n", cabsind);
2819#endif
2820  if (cabsind == 0)
2821  {
2822    if (!(nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N)))
2823    {
2824      return;
2825    }
2826  }
2827  // Now the whole simplex
2828  do
2829  {
2830    // Build s-polynomial
2831    // 2**ind-def * mult * g - exp-def * h
2832    poly t_p;
2833    poly zeroPoly = kCreateZeroPoly(cexp, cabsind, &t_p, currRing, strat->tailRing);
2834#ifdef OLI_DEBUG
2835    Print("%d, (%d, %d), ind = (%d, %d)\n", cabsind, cexp[1], cexp[2], cind[1], cind[2]);
2836    Print("zPoly : ");
2837    wrp(zeroPoly);
2838    Print("\n");
2839#endif
2840    enterOneZeroPairRing(zeroPoly, t_p, p, ecart, strat, atR);
2841  }
2842  while ( nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N) );
2843}
2844
2845/*
2846 * Create the Groebner basis of the vanishing polynomials.
2847 */
2848
2849ideal createG0()
2850{
2851  // Initialize
2852  long exp[50];            // The exponent of \hat{X} (basepoint)
2853  long cexp[50];           // The current exponent for iterating over all
2854  long ind[50];            // The power of 2 in the i-th component of exp
2855  long cind[50];           // analog for cexp
2856  long mult[50];           // How to multiply the elements of G
2857  long cabsind = 0;        // The abs. index of cexp, i.e. the sum of cind
2858  long habsind = 0;        // The abs. index of the coefficient of h
2859  long step[50];           // The last increases
2860  for (int i = 1; i <= currRing->N; i++)
2861  {
2862    exp[i] = 0;
2863    cexp[i] = exp[i];
2864    ind[i] = 0;
2865    step[i] = 500000;
2866    cind[i] = ind[i];
2867  }
2868  long bound = currRing->ch;
2869  step[1] = 500000;
2870#ifdef OLI_DEBUG
2871  PrintS("-------------\npoly  :");
2872//  wrp(p);
2873  Print("\nexp   : (%d, %d)\n", exp[1] + mult[1], exp[2] + mult[1]);
2874  Print("cexp  : (%d, %d)\n", cexp[1], cexp[2]);
2875  Print("cind  : (%d, %d)\n", cind[1], cind[2]);
2876  Print("bound : %d\n", bound);
2877  Print("cind  : %d\n", cabsind);
2878#endif
2879  if (cabsind == 0)
2880  {
2881    if (!(nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N)))
2882    {
2883      return idInit(1, 1);
2884    }
2885  }
2886  ideal G0 = idInit(1, 1);
2887  // Now the whole simplex
2888  do
2889  {
2890    // Build s-polynomial
2891    // 2**ind-def * mult * g - exp-def * h
2892    poly t_p;
2893    poly zeroPoly = kCreateZeroPoly(cexp, cabsind, &t_p, currRing, currRing);
2894#ifdef OLI_DEBUG
2895    Print("%d, (%d, %d), ind = (%d, %d)\n", cabsind, cexp[1], cexp[2], cind[1], cind[2]);
2896    Print("zPoly : ");
2897    wrp(zeroPoly);
2898    Print("\n");
2899#endif
2900    // Add to ideal
2901    pEnlargeSet(&(G0->m), IDELEMS(G0), 1);
2902    IDELEMS(G0) += 1;
2903    G0->m[IDELEMS(G0) - 1] = zeroPoly;
2904  }
2905  while ( nextZeroSimplexExponent(exp, ind, cexp, cind, &cabsind, step, bound, currRing->N) );
2906  idSkipZeroes(G0);
2907  return G0;
2908}
2909#endif
2910
2911#ifdef HAVE_RINGS
2912/*2
2913*(s[0],h),...,(s[k],h) will be put to the pairset L
2914*/
2915void initenterstrongPairs (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
2916{
2917  const unsigned long iCompH = pGetComp(h);
2918  if (!nIsOne(pGetCoeff(h)))
2919  {
2920    int j;
2921    BOOLEAN new_pair=FALSE;
2922
2923    for (j=0; j<=k; j++)
2924    {
2925      // Print("j:%d, Ll:%d\n",j,strat->Ll);
2926//      if (((unsigned long) pGetCoeff(h) % (unsigned long) pGetCoeff(strat->S[j]) != 0) &&
2927//         ((unsigned long) pGetCoeff(strat->S[j]) % (unsigned long) pGetCoeff(h) != 0))
2928      if ( iCompH == pGetComp(strat->S[j]) )
2929      {
2930        {
2931          if (enterOneStrongPoly(j,h,ecart,isFromQ,strat, atR))
2932            new_pair=TRUE;
2933        }
2934      }
2935    }
2936  }
2937/*
2938ring r=256,(x,y,z),dp;
2939ideal I=12xz-133y, 2xy-z;
2940*/
2941
2942}
2943
2944/*2
2945* Generates spoly(0, h) if applicable. Assumes ring in Z/2^n.
2946*/
2947void enterExtendedSpoly(poly h,kStrategy strat)
2948{
2949  if (nIsOne(pGetCoeff(h))) return;
2950  number gcd;
2951  bool go = false;
2952  if (n_DivBy((number) 0, pGetCoeff(h), currRing->cf))
2953  {
2954    gcd = nIntDiv((number) 0, pGetCoeff(h));
2955    go = true;
2956  }
2957  else
2958    gcd = nGcd((number) 0, pGetCoeff(h), strat->tailRing);
2959  if (go || !nIsOne(gcd))
2960  {
2961    poly p = h->next;
2962    if (!go)
2963    {
2964      number tmp = gcd;
2965      gcd = nIntDiv(0, gcd);
2966      nDelete(&tmp);
2967    }
2968    p_Test(p,strat->tailRing);
2969    p = pp_Mult_nn(p, gcd, strat->tailRing);
2970    nDelete(&gcd);
2971
2972    if (p != NULL)
2973    {
2974      if (TEST_OPT_PROT)
2975      {
2976        PrintS("Z");
2977      }
2978#ifdef KDEBUG
2979      if (TEST_OPT_DEBUG)
2980      {
2981        PrintS("--- create zero spoly: ");
2982        p_wrp(h,currRing,strat->tailRing);
2983        PrintS(" ---> ");
2984      }
2985#endif
2986      poly tmp = pInit();
2987      pSetCoeff0(tmp, pGetCoeff(p));
2988      for (int i = 1; i <= rVar(currRing); i++)
2989      {
2990        pSetExp(tmp, i, p_GetExp(p, i, strat->tailRing));
2991      }
2992      if (rRing_has_Comp(currRing) && rRing_has_Comp(strat->tailRing))
2993      {
2994        p_SetComp(tmp, p_GetComp(p, strat->tailRing), currRing);
2995      }
2996      p_Setm(tmp, currRing);
2997      p = p_LmFreeAndNext(p, strat->tailRing);
2998      pNext(tmp) = p;
2999      LObject h;
3000      h.Init();
3001      h.p = tmp;
3002      h.tailRing = strat->tailRing;
3003      int posx;
3004      if (h.p!=NULL)
3005      {
3006        if (TEST_OPT_INTSTRATEGY)
3007        {
3008          //pContent(h.p);
3009          h.pCleardenom(); // also does a pContent
3010        }
3011        else
3012        {
3013          h.pNorm();
3014        }
3015        strat->initEcart(&h);
3016        if (strat->Ll==-1)
3017          posx =0;
3018        else
3019          posx = strat->posInL(strat->L,strat->Ll,&h,strat);
3020        h.sev = pGetShortExpVector(h.p);
3021        if (strat->tailRing != currRing)
3022        {
3023          h.t_p = k_LmInit_currRing_2_tailRing(h.p, strat->tailRing);
3024        }
3025#ifdef KDEBUG
3026        if (TEST_OPT_DEBUG)
3027        {
3028          p_wrp(tmp,currRing,strat->tailRing);
3029          PrintLn();
3030        }
3031#endif
3032        enterL(&strat->L,&strat->Ll,&strat->Lmax,h,posx);
3033      }
3034    }
3035  }
3036  nDelete(&gcd);
3037}
3038
3039void clearSbatch (poly h,int k,int pos,kStrategy strat)
3040{
3041  int j = pos;
3042  if ( (!strat->fromT)
3043  && (1//(strat->syzComp==0)
3044    //||(pGetComp(h)<=strat->syzComp)))
3045  ))
3046  {
3047    // Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
3048    unsigned long h_sev = pGetShortExpVector(h);
3049    loop
3050    {
3051      if (j > k) break;
3052      clearS(h,h_sev, &j,&k,strat);
3053      j++;
3054    }
3055    // Print("end clearS sl=%d\n",strat->sl);
3056  }
3057}
3058
3059/*2
3060* Generates a sufficient set of spolys (maybe just a finite generating
3061* set of the syzygys)
3062*/
3063void superenterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
3064{
3065    assume (rField_is_Ring(currRing));
3066    // enter also zero divisor * poly, if this is non zero and of smaller degree
3067    if (!(rField_is_Domain(currRing))) enterExtendedSpoly(h, strat);
3068    initenterpairs(h, k, ecart, 0, strat, atR);
3069    initenterstrongPairs(h, k, ecart, 0, strat, atR);
3070    clearSbatch(h, k, pos, strat);
3071}
3072#endif
3073
3074/*2
3075*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
3076*superfluous elements in S will be deleted
3077*/
3078void enterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
3079{
3080  int j=pos;
3081
3082#ifdef HAVE_RINGS
3083  assume (!rField_is_Ring(currRing));
3084#endif
3085
3086  initenterpairs(h,k,ecart,0,strat, atR);
3087  if ( (!strat->fromT)
3088  && ((strat->syzComp==0)
3089    ||(pGetComp(h)<=strat->syzComp)))
3090  {
3091    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
3092    unsigned long h_sev = pGetShortExpVector(h);
3093    loop
3094    {
3095      if (j > k) break;
3096      clearS(h,h_sev, &j,&k,strat);
3097      j++;
3098    }
3099    //Print("end clearS sl=%d\n",strat->sl);
3100  }
3101 // PrintS("end enterpairs\n");
3102}
3103
3104/*2
3105*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
3106*superfluous elements in S will be deleted
3107*/
3108void enterpairsSpecial (poly h,int k,int ecart,int pos,kStrategy strat, int atR = -1)
3109{
3110  int j;
3111  const int iCompH = pGetComp(h);
3112
3113  for (j=0; j<=k; j++)
3114  {
3115    const int iCompSj = pGetComp(strat->S[j]);
3116    if ((iCompH==iCompSj)
3117        || (0==iCompH) // TODO: what about this case???
3118        || (0==iCompSj))
3119    {
3120      enterOnePairSpecial(j,h,ecart,strat, atR);
3121    }
3122  }
3123
3124  if (strat->noClearS) return;
3125
3126//   #ifdef HAVE_PLURAL
3127/*
3128  if (rIsPluralRing(currRing))
3129  {
3130    j=pos;
3131    loop
3132    {
3133      if (j > k) break;
3134
3135      if (pLmDivisibleBy(h, strat->S[j]))
3136      {
3137        deleteInS(j, strat);
3138        j--;
3139        k--;
3140      }
3141
3142      j++;
3143    }
3144  }
3145  else
3146*/
3147//   #endif // ??? Why was the following cancelation disabled for non-commutative rings?
3148  {
3149    j=pos;
3150    loop
3151    {
3152      unsigned long h_sev = pGetShortExpVector(h);
3153      if (j > k) break;
3154      clearS(h,h_sev,&j,&k,strat);
3155      j++;
3156    }
3157  }
3158}
3159
3160/*2
3161*reorders  s with respect to posInS,
3162*suc is the first changed index or zero
3163*/
3164
3165void reorderS (int* suc,kStrategy strat)
3166{
3167  int i,j,at,ecart, s2r;
3168  int fq=0;
3169  unsigned long sev;
3170  poly  p;
3171  int new_suc=strat->sl+1;
3172  i= *suc;
3173  if (i<0) i=0;
3174
3175  for (; i<=strat->sl; i++)
3176  {
3177    at = posInS(strat,i-1,strat->S[i],strat->ecartS[i]);
3178    if (at != i)
3179    {
3180      if (new_suc > at) new_suc = at;
3181      p = strat->S[i];
3182      ecart = strat->ecartS[i];
3183      sev = strat->sevS[i];
3184      s2r = strat->S_2_R[i];
3185      if (strat->fromQ!=NULL) fq=strat->fromQ[i];
3186      for (j=i; j>=at+1; j--)
3187      {
3188        strat->S[j] = strat->S[j-1];
3189        strat->ecartS[j] = strat->ecartS[j-1];
3190        strat->sevS[j] = strat->sevS[j-1];
3191        strat->S_2_R[j] = strat->S_2_R[j-1];
3192      }
3193      strat->S[at] = p;
3194      strat->ecartS[at] = ecart;
3195      strat->sevS[at] = sev;
3196      strat->S_2_R[at] = s2r;
3197      if (strat->fromQ!=NULL)
3198      {
3199        for (j=i; j>=at+1; j--)
3200        {
3201          strat->fromQ[j] = strat->fromQ[j-1];
3202        }
3203        strat->fromQ[at]=fq;
3204      }
3205    }
3206  }
3207  if (new_suc <= strat->sl) *suc=new_suc;
3208  else                      *suc=-1;
3209}
3210
3211
3212/*2
3213*looks up the position of p in set
3214*set[0] is the smallest with respect to the ordering-procedure deg/pComp
3215* Assumption: posInS only depends on the leading term
3216*             otherwise, bba has to be changed
3217*/
3218int posInS (const kStrategy strat, const int length,const poly p,
3219            const int ecart_p)
3220{
3221  if(length==-1) return 0;
3222  polyset set=strat->S;
3223  int i;
3224  int an = 0;
3225  int en = length;
3226  int cmp_int = currRing->OrdSgn;
3227  if ((currRing->MixedOrder)
3228#ifdef HAVE_PLURAL
3229  && (currRing->real_var_start==0)
3230#endif
3231#if 0
3232  || ((strat->ak>0) && ((currRing->order[0]==ringorder_c)||((currRing->order[0]==ringorder_C))))
3233#endif
3234  )
3235  {
3236    int o=p_Deg(p,currRing);
3237    int oo=p_Deg(set[length],currRing);
3238
3239    if ((oo<o)
3240    || ((o==oo) && (pLmCmp(set[length],p)!= cmp_int)))
3241      return length+1;
3242
3243    loop
3244    {
3245      if (an >= en-1)
3246      {
3247        if ((p_Deg(set[an],currRing)>=o) && (pLmCmp(set[an],p) == cmp_int))
3248        {
3249          return an;
3250        }
3251        return en;
3252      }
3253      i=(an+en) / 2;
3254      if ((p_Deg(set[i],currRing)>=o) && (pLmCmp(set[i],p) == cmp_int)) en=i;
3255      else                              an=i;
3256    }
3257  }
3258  else
3259  {
3260#ifdef HAVE_RINGS
3261    if (rField_is_Ring(currRing))
3262    {
3263      if (pLmCmp(set[length],p)== -cmp_int)
3264        return length+1;
3265      int cmp;
3266      loop
3267      {
3268        if (an >= en-1)
3269        {
3270          cmp = pLmCmp(set[an],p);
3271          if (cmp == cmp_int)  return an;
3272          if (cmp == -cmp_int) return en;
3273          if (n_DivBy(pGetCoeff(p), pGetCoeff(set[an]), currRing->cf)) return en;
3274          return an;
3275        }
3276        i = (an+en) / 2;
3277        cmp = pLmCmp(set[i],p);
3278        if (cmp == cmp_int)         en = i;
3279        else if (cmp == -cmp_int)   an = i;
3280        else
3281        {
3282          if (n_DivBy(pGetCoeff(p), pGetCoeff(set[i]), currRing->cf)) an = i;
3283          else en = i;
3284        }
3285      }
3286    }
3287    else
3288#endif
3289    if (pLmCmp(set[length],p)== -cmp_int)
3290      return length+1;
3291
3292    loop
3293    {
3294      if (an >= en-1)
3295      {
3296        if (pLmCmp(set[an],p) == cmp_int) return an;
3297        if (pLmCmp(set[an],p) == -cmp_int) return en;
3298        if ((cmp_int!=1)
3299        && ((strat->ecartS[an])>ecart_p))
3300          return an;
3301        return en;
3302      }
3303      i=(an+en) / 2;
3304      if (pLmCmp(set[i],p) == cmp_int) en=i;
3305      else if (pLmCmp(set[i],p) == -cmp_int) an=i;
3306      else
3307      {
3308        if ((cmp_int!=1)
3309        &&((strat->ecartS[i])<ecart_p))
3310          en=i;
3311        else
3312          an=i;
3313      }
3314    }
3315  }
3316}
3317
3318
3319/*2
3320* looks up the position of p in set
3321* the position is the last one
3322*/
3323int posInT0 (const TSet,const int length,LObject &)
3324{
3325  return (length+1);
3326}
3327
3328
3329/*2
3330* looks up the position of p in T
3331* set[0] is the smallest with respect to the ordering-procedure
3332* pComp
3333*/
3334int posInT1 (const TSet set,const int length,LObject &p)
3335{
3336  if (length==-1) return 0;
3337
3338  if (pLmCmp(set[length].p,p.p)!= currRing->OrdSgn) return length+1;
3339
3340  int i;
3341  int an = 0;
3342  int en= length;
3343
3344  loop
3345  {
3346    if (an >= en-1)
3347    {
3348      if (pLmCmp(set[an].p,p.p) == currRing->OrdSgn) return an;
3349      return en;
3350    }
3351    i=(an+en) / 2;
3352    if (pLmCmp(set[i].p,p.p) == currRing->OrdSgn) en=i;
3353    else                                 an=i;
3354  }
3355}
3356
3357/*2
3358* looks up the position of p in T
3359* set[0] is the smallest with respect to the ordering-procedure
3360* length
3361*/
3362int posInT2 (const TSet set,const int length,LObject &p)
3363{
3364  p.GetpLength();
3365  if (length==-1)
3366    return 0;
3367  if (set[length].length<p.length)
3368    return length+1;
3369
3370  int i;
3371  int an = 0;
3372  int en= length;
3373
3374  loop
3375  {
3376    if (an >= en-1)
3377    {
3378      if (set[an].length>p.length) return an;
3379      return en;
3380    }
3381    i=(an+en) / 2;
3382    if (set[i].length>p.length) en=i;
3383    else                        an=i;
3384  }
3385}
3386
3387/*2
3388* looks up the position of p in T
3389* set[0] is the smallest with respect to the ordering-procedure
3390* totaldegree,pComp
3391*/
3392int posInT11 (const TSet set,const int length,LObject &p)
3393/*{
3394 * int j=0;
3395 * int o;
3396 *
3397 * o = p.GetpFDeg();
3398 * loop
3399 * {
3400 *   if ((pFDeg(set[j].p) > o)
3401 *   || ((pFDeg(set[j].p) == o) && (pLmCmp(set[j].p,p.p) == currRing->OrdSgn)))
3402 *   {
3403 *     return j;
3404 *   }
3405 *   j++;
3406 *   if (j > length) return j;
3407 * }
3408 *}
3409 */
3410{
3411  if (length==-1) return 0;
3412
3413  int o = p.GetpFDeg();
3414  int op = set[length].GetpFDeg();
3415
3416  if ((op < o)
3417  || ((op == o) && (pLmCmp(set[length].p,p.p) != currRing->OrdSgn)))
3418    return length+1;
3419
3420  int i;
3421  int an = 0;
3422  int en= length;
3423
3424  loop
3425  {
3426    if (an >= en-1)
3427    {
3428      op= set[an].GetpFDeg();
3429      if ((op > o)
3430      || (( op == o) && (pLmCmp(set[an].p,p.p) == currRing->OrdSgn)))
3431        return an;
3432      return en;
3433    }
3434    i=(an+en) / 2;
3435    op = set[i].GetpFDeg();
3436    if (( op > o)
3437    || (( op == o) && (pLmCmp(set[i].p,p.p) == currRing->OrdSgn)))
3438      en=i;
3439    else
3440      an=i;
3441  }
3442}
3443
3444/*2 Pos for rings T: Here I am
3445* looks up the position of p in T
3446* set[0] is the smallest with respect to the ordering-procedure
3447* totaldegree,pComp
3448*/
3449int posInTrg0 (const TSet set,const int length,LObject &p)
3450{
3451  if (length==-1) return 0;
3452  int o = p.GetpFDeg();
3453  int op = set[length].GetpFDeg();
3454  int i;
3455  int an = 0;
3456  int en = length;
3457  int cmp_int = currRing->OrdSgn;
3458  if ((op < o) || (pLmCmp(set[length].p,p.p)== -cmp_int))
3459    return length+1;
3460  int cmp;
3461  loop
3462  {
3463    if (an >= en-1)
3464    {
3465      op = set[an].GetpFDeg();
3466      if (op > o) return an;
3467      if (op < 0) return en;
3468      cmp = pLmCmp(set[an].p,p.p);
3469      if (cmp == cmp_int)  return an;
3470      if (cmp == -cmp_int) return en;
3471      if (nGreater(pGetCoeff(p.p), pGetCoeff(set[an].p))) return en;
3472      return an;
3473    }
3474    i = (an + en) / 2;
3475    op = set[i].GetpFDeg();
3476    if (op > o)       en = i;
3477    else if (op < o)  an = i;
3478    else
3479    {
3480      cmp = pLmCmp(set[i].p,p.p);
3481      if (cmp == cmp_int)                                     en = i;
3482      else if (cmp == -cmp_int)                               an = i;
3483      else if (nGreater(pGetCoeff(p.p), pGetCoeff(set[i].p))) an = i;
3484      else                                                    en = i;
3485    }
3486  }
3487}
3488/*
3489  int o = p.GetpFDeg();
3490  int op = set[length].GetpFDeg();
3491
3492  if ((op < o)
3493  || ((op == o) && (pLmCmp(set[length].p,p.p) != currRing->OrdSgn)))
3494    return length+1;
3495
3496  int i;
3497  int an = 0;
3498  int en= length;
3499
3500  loop
3501  {
3502    if (an >= en-1)
3503    {
3504      op= set[an].GetpFDeg();
3505      if ((op > o)
3506      || (( op == o) && (pLmCmp(set[an].p,p.p) == currRing->OrdSgn)))
3507        return an;
3508      return en;
3509    }
3510    i=(an+en) / 2;
3511    op = set[i].GetpFDeg();
3512    if (( op > o)
3513    || (( op == o) && (pLmCmp(set[i].p,p.p) == currRing->OrdSgn)))
3514      en=i;
3515    else
3516      an=i;
3517  }
3518}
3519  */
3520/*2
3521* looks up the position of p in T
3522* set[0] is the smallest with respect to the ordering-procedure
3523* totaldegree,pComp
3524*/
3525int posInT110 (const TSet set,const int length,LObject &p)
3526{
3527  p.GetpLength();
3528  if (length==-1) return 0;
3529
3530  int o = p.GetpFDeg();
3531  int op = set[length].GetpFDeg();
3532
3533  if (( op < o)
3534  || (( op == o) && (set[length].length<p.length))
3535  || (( op == o) && (set[length].length == p.length)
3536     && (pLmCmp(set[length].p,p.p) != currRing->OrdSgn)))
3537    return length+1;
3538
3539  int i;
3540  int an = 0;
3541  int en= length;
3542  loop
3543  {
3544    if (an >= en-1)
3545    {
3546      op = set[an].GetpFDeg();
3547      if (( op > o)
3548      || (( op == o) && (set[an].length > p.length))
3549      || (( op == o) && (set[an].length == p.length)
3550         && (pLmCmp(set[an].p,p.p) == currRing->OrdSgn)))
3551        return an;
3552      return en;
3553    }
3554    i=(an+en) / 2;
3555    op = set[i].GetpFDeg();
3556    if (( op > o)
3557    || (( op == o) && (set[i].length > p.length))
3558    || (( op == o) && (set[i].length == p.length)
3559       && (pLmCmp(set[i].p,p.p) == currRing->OrdSgn)))
3560      en=i;
3561    else
3562      an=i;
3563  }
3564}
3565
3566/*2
3567* looks up the position of p in set
3568* set[0] is the smallest with respect to the ordering-procedure
3569* pFDeg
3570*/
3571int posInT13 (const TSet set,const int length,LObject &p)
3572{
3573  if (length==-1) return 0;
3574
3575  int o = p.GetpFDeg();
3576
3577  if (set[length].GetpFDeg() <= o)
3578    return length+1;
3579
3580  int i;
3581  int an = 0;
3582  int en= length;
3583  loop
3584  {
3585    if (an >= en-1)
3586    {
3587      if (set[an].GetpFDeg() > o)
3588        return an;
3589      return en;
3590    }
3591    i=(an+en) / 2;
3592    if (set[i].GetpFDeg() > o)
3593      en=i;
3594    else
3595      an=i;
3596  }
3597}
3598
3599// determines the position based on: 1.) Ecart 2.) pLength
3600int posInT_EcartpLength(const TSet set,const int length,LObject &p)
3601{
3602  int ol = p.GetpLength();
3603  if (length==-1) return 0;
3604
3605  int op=p.ecart;
3606
3607  int oo=set[length].ecart;
3608  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
3609    return length+1;
3610
3611  int i;
3612  int an = 0;
3613  int en= length;
3614  loop
3615    {
3616      if (an >= en-1)
3617      {
3618        int oo=set[an].ecart;
3619        if((oo > op)
3620           || ((oo==op) && (set[an].pLength > ol)))
3621          return an;
3622        return en;
3623      }
3624      i=(an+en) / 2;
3625      int oo=set[i].ecart;
3626      if ((oo > op)
3627          || ((oo == op) && (set[i].pLength > ol)))
3628        en=i;
3629      else
3630        an=i;
3631    }
3632}
3633
3634/*2
3635* looks up the position of p in set
3636* set[0] is the smallest with respect to the ordering-procedure
3637* maximaldegree, pComp
3638*/
3639int posInT15 (const TSet set,const int length,LObject &p)
3640/*{
3641 *int j=0;
3642 * int o;
3643 *
3644 * o = p.GetpFDeg()+p.ecart;
3645 * loop
3646 * {
3647 *   if ((set[j].GetpFDeg()+set[j].ecart > o)
3648 *   || ((set[j].GetpFDeg()+set[j].ecart == o)
3649 *     && (pLmCmp(set[j].p,p.p) == currRing->OrdSgn)))
3650 *   {
3651 *     return j;
3652 *   }
3653 *   j++;
3654 *   if (j > length) return j;
3655 * }
3656 *}
3657 */
3658{
3659  if (length==-1) return 0;
3660
3661  int o = p.GetpFDeg() + p.ecart;
3662  int op = set[length].GetpFDeg()+set[length].ecart;
3663
3664  if ((op < o)
3665  || ((op == o)
3666     && (pLmCmp(set[length].p,p.p) != currRing->OrdSgn)))
3667    return length+1;
3668
3669  int i;
3670  int an = 0;
3671  int en= length;
3672  loop
3673  {
3674    if (an >= en-1)
3675    {
3676      op = set[an].GetpFDeg()+set[an].ecart;
3677      if (( op > o)
3678      || (( op  == o) && (pLmCmp(set[an].p,p.p) == currRing->OrdSgn)))
3679        return an;
3680      return en;
3681    }
3682    i=(an+en) / 2;
3683    op = set[i].GetpFDeg()+set[i].ecart;
3684    if (( op > o)
3685    || (( op == o) && (pLmCmp(set[i].p,p.p) == currRing->OrdSgn)))
3686      en=i;
3687    else
3688      an=i;
3689  }
3690}
3691
3692/*2
3693* looks up the position of p in set
3694* set[0] is the smallest with respect to the ordering-procedure
3695* pFDeg+ecart, ecart, pComp
3696*/
3697int posInT17 (const TSet set,const int length,LObject &p)
3698/*
3699*{
3700* int j=0;
3701* int  o;
3702*
3703*  o = p.GetpFDeg()+p.ecart;
3704*  loop
3705*  {
3706*    if ((pFDeg(set[j].p)+set[j].ecart > o)
3707*    || (((pFDeg(set[j].p)+set[j].ecart == o)
3708*      && (set[j].ecart < p.ecart)))
3709*    || ((pFDeg(set[j].p)+set[j].ecart == o)
3710*      && (set[j].ecart==p.ecart)
3711*      && (pLmCmp(set[j].p,p.p)==currRing->OrdSgn)))
3712*      return j;
3713*    j++;
3714*    if (j > length) return j;
3715*  }
3716* }
3717*/
3718{
3719  if (length==-1) return 0;
3720
3721  int o = p.GetpFDeg() + p.ecart;
3722  int op = set[length].GetpFDeg()+set[length].ecart;
3723
3724  if ((op < o)
3725  || (( op == o) && (set[length].ecart > p.ecart))
3726  || (( op == o) && (set[length].ecart==p.ecart)
3727     && (pLmCmp(set[length].p,p.p) != currRing->OrdSgn)))
3728    return length+1;
3729
3730  int i;
3731  int an = 0;
3732  int en= length;
3733  loop
3734  {
3735    if (an >= en-1)
3736    {
3737      op = set[an].GetpFDeg()+set[an].ecart;
3738      if (( op > o)
3739      || (( op == o) && (set[an].ecart < p.ecart))
3740      || (( op  == o) && (set[an].ecart==p.ecart)
3741         && (pLmCmp(set[an].p,p.p) == currRing->OrdSgn)))
3742        return an;
3743      return en;
3744    }
3745    i=(an+en) / 2;
3746    op = set[i].GetpFDeg()+set[i].ecart;
3747    if ((op > o)
3748    || (( op == o) && (set[i].ecart < p.ecart))
3749    || (( op == o) && (set[i].ecart == p.ecart)
3750       && (pLmCmp(set[i].p,p.p) == currRing->OrdSgn)))
3751      en=i;
3752    else
3753      an=i;
3754  }
3755}
3756/*2
3757* looks up the position of p in set
3758* set[0] is the smallest with respect to the ordering-procedure
3759* pGetComp, pFDeg+ecart, ecart, pComp
3760*/
3761int posInT17_c (const TSet set,const int length,LObject &p)
3762{
3763  if (length==-1) return 0;
3764
3765  int cc = (-1+2*currRing->order[0]==ringorder_c);
3766  /* cc==1 for (c,..), cc==-1 for (C,..) */
3767  int o = p.GetpFDeg() + p.ecart;
3768  unsigned long c = pGetComp(p.p)*cc;
3769
3770  if (pGetComp(set[length].p)*cc < c)
3771    return length+1;
3772  if (pGetComp(set[length].p)*cc == c)
3773  {
3774    int op = set[length].GetpFDeg()+set[length].ecart;
3775    if ((op < o)
3776    || ((op == o) && (set[length].ecart > p.ecart))
3777    || ((op == o) && (set[length].ecart==p.ecart)
3778       && (pLmCmp(set[length].p,p.p) != currRing->OrdSgn)))
3779      return length+1;
3780  }
3781
3782  int i;
3783  int an = 0;
3784  int en= length;
3785  loop
3786  {
3787    if (an >= en-1)
3788    {
3789      if (pGetComp(set[an].p)*cc < c)
3790        return en;
3791      if (pGetComp(set[an].p)*cc == c)
3792      {
3793        int op = set[an].GetpFDeg()+set[an].ecart;
3794        if ((op > o)
3795        || ((op == o) && (set[an].ecart < p.ecart))
3796        || ((op == o) && (set[an].ecart==p.ecart)
3797           && (pLmCmp(set[an].p,p.p) == currRing->OrdSgn)))
3798          return an;
3799      }
3800      return en;
3801    }
3802    i=(an+en) / 2;
3803    if (pGetComp(set[i].p)*cc > c)
3804      en=i;
3805    else if (pGetComp(set[i].p)*cc == c)
3806    {
3807      int op = set[i].GetpFDeg()+set[i].ecart;
3808      if ((op > o)
3809      || ((op == o) && (set[i].ecart < p.ecart))
3810      || ((op == o) && (set[i].ecart == p.ecart)
3811         && (pLmCmp(set[i].p,p.p) == currRing->OrdSgn)))
3812        en=i;
3813      else
3814        an=i;
3815    }
3816    else
3817      an=i;
3818  }
3819}
3820
3821/*2
3822* looks up the position of p in set
3823* set[0] is the smallest with respect to
3824* ecart, pFDeg, length
3825*/
3826int posInT19 (const TSet set,const int length,LObject &p)
3827{
3828  p.GetpLength();
3829  if (length==-1) return 0;
3830
3831  int o = p.ecart;
3832  int op=p.GetpFDeg();
3833
3834  if (set[length].ecart < o)
3835    return length+1;
3836  if (set[length].ecart == o)
3837  {
3838     int oo=set[length].GetpFDeg();
3839     if ((oo < op) || ((oo==op) && (set[length].length < p.length)))
3840       return length+1;
3841  }
3842
3843  int i;
3844  int an = 0;
3845  int en= length;
3846  loop
3847  {
3848    if (an >= en-1)
3849    {
3850      if (set[an].ecart > o)
3851        return an;
3852      if (set[an].ecart == o)
3853      {
3854         int oo=set[an].GetpFDeg();
3855         if((oo > op)
3856         || ((oo==op) && (set[an].length > p.length)))
3857           return an;
3858      }
3859      return en;
3860    }
3861    i=(an+en) / 2;
3862    if (set[i].ecart > o)
3863      en=i;
3864    else if (set[i].ecart == o)
3865    {
3866       int oo=set[i].GetpFDeg();
3867       if ((oo > op)
3868       || ((oo == op) && (set[i].length > p.length)))
3869         en=i;
3870       else
3871        an=i;
3872    }
3873    else
3874      an=i;
3875  }
3876}
3877
3878/*2
3879*looks up the position of polynomial p in set
3880*set[length] is the smallest element in set with respect
3881*to the ordering-procedure pComp
3882*/
3883int posInLSpecial (const LSet set, const int length,
3884                   LObject *p,const kStrategy)
3885{
3886  if (length<0) return 0;
3887
3888  int d=p->GetpFDeg();
3889  int op=set[length].GetpFDeg();
3890
3891  if ((op > d)
3892  || ((op == d) && (p->p1!=NULL)&&(set[length].p1==NULL))
3893  || (pLmCmp(set[length].p,p->p)== currRing->OrdSgn))
3894     return length+1;
3895
3896  int i;
3897  int an = 0;
3898  int en= length;
3899  loop
3900  {
3901    if (an >= en-1)
3902    {
3903      op=set[an].GetpFDeg();
3904      if ((op > d)
3905      || ((op == d) && (p->p1!=NULL) && (set[an].p1==NULL))
3906      || (pLmCmp(set[an].p,p->p)== currRing->OrdSgn))
3907         return en;
3908      return an;
3909    }
3910    i=(an+en) / 2;
3911    op=set[i].GetpFDeg();
3912    if ((op>d)
3913    || ((op==d) && (p->p1!=NULL) && (set[i].p1==NULL))
3914    || (pLmCmp(set[i].p,p->p) == currRing->OrdSgn))
3915      an=i;
3916    else
3917      en=i;
3918  }
3919}
3920
3921/*2
3922*looks up the position of polynomial p in set
3923*set[length] is the smallest element in set with respect
3924*to the ordering-procedure pComp
3925*/
3926int posInL0 (const LSet set, const int length,
3927             LObject* p,const kStrategy)
3928{
3929  if (length<0) return 0;
3930
3931  if (pLmCmp(set[length].p,p->p)== currRing->OrdSgn)
3932    return length+1;
3933
3934  int i;
3935  int an = 0;
3936  int en= length;
3937  loop
3938  {
3939    if (an >= en-1)
3940    {
3941      if (pLmCmp(set[an].p,p->p) == currRing->OrdSgn) return en;
3942      return an;
3943    }
3944    i=(an+en) / 2;
3945    if (pLmCmp(set[i].p,p->p) == currRing->OrdSgn) an=i;
3946    else                                 en=i;
3947    /*aend. fuer lazy == in !=- machen */
3948  }
3949}
3950
3951/*2
3952* looks up the position of polynomial p in set
3953* e is the ecart of p
3954* set[length] is the smallest element in set with respect
3955* to the ordering-procedure totaldegree,pComp
3956*/
3957int posInL11 (const LSet set, const int length,
3958              LObject* p,const kStrategy)
3959/*{
3960 * int j=0;
3961 * int o;
3962 *
3963 * o = p->GetpFDeg();
3964 * loop
3965 * {
3966 *   if (j > length)            return j;
3967 *   if ((set[j].GetpFDeg() < o)) return j;
3968 *   if ((set[j].GetpFDeg() == o) && (pLmCmp(set[j].p,p->p) == -currRing->OrdSgn))
3969 *   {
3970 *     return j;
3971 *   }
3972 *   j++;
3973 * }
3974 *}
3975 */
3976{
3977  if (length<0) return 0;
3978
3979  int o = p->GetpFDeg();
3980  int op = set[length].GetpFDeg();
3981
3982  if ((op > o)
3983  || ((op == o) && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))
3984    return length+1;
3985  int i;
3986  int an = 0;
3987  int en= length;
3988  loop
3989  {
3990    if (an >= en-1)
3991    {
3992      op = set[an].GetpFDeg();
3993      if ((op > o)
3994      || ((op == o) && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))
3995        return en;
3996      return an;
3997    }
3998    i=(an+en) / 2;
3999    op = set[i].GetpFDeg();
4000    if ((op > o)
4001    || ((op == o) && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
4002      an=i;
4003    else
4004      en=i;
4005  }
4006}
4007
4008/*2 Position for rings L: Here I am
4009* looks up the position of polynomial p in set
4010* e is the ecart of p
4011* set[length] is the smallest element in set with respect
4012* to the ordering-procedure totaldegree,pComp
4013*/
4014inline int getIndexRng(long coeff)
4015{
4016  if (coeff == 0) return -1;
4017  long tmp = coeff;
4018  int ind = 0;
4019  while (tmp % 2 == 0)
4020  {
4021    tmp = tmp / 2;
4022    ind++;
4023  }
4024  return ind;
4025}
4026
4027int posInLrg0 (const LSet set, const int length,
4028              LObject* p,const kStrategy)
4029/*          if (nGreater(pGetCoeff(p), pGetCoeff(set[an]))) return en;
4030        if (pLmCmp(set[i],p) == cmp_int)         en = i;
4031        else if (pLmCmp(set[i],p) == -cmp_int)   an = i;
4032        else
4033        {
4034          if (nGreater(pGetCoeff(p), pGetCoeff(set[i]))) an = i;
4035          else en = i;
4036        }*/
4037{
4038  if (length < 0) return 0;
4039
4040  int o = p->GetpFDeg();
4041  int op = set[length].GetpFDeg();
4042
4043  if ((op > o) || ((op == o) && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))
4044    return length + 1;
4045  int i;
4046  int an = 0;
4047  int en = length;
4048  loop
4049  {
4050    if (an >= en - 1)
4051    {
4052      op = set[an].GetpFDeg();
4053      if ((op > o) || ((op == o) && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))
4054        return en;
4055      return an;
4056    }
4057    i = (an+en) / 2;
4058    op = set[i].GetpFDeg();
4059    if ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
4060      an = i;
4061    else
4062      en = i;
4063  }
4064}
4065
4066/*{
4067  if (length < 0) return 0;
4068
4069  int o = p->GetpFDeg();
4070  int op = set[length].GetpFDeg();
4071
4072  int inde = getIndexRng((unsigned long) pGetCoeff(set[length].p));
4073  int indp = getIndexRng((unsigned long) pGetCoeff(p->p));
4074  int inda;
4075  int indi;
4076
4077  if ((inda > indp) || ((inda == inde) && ((op > o) || ((op == o) && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))))
4078    return length + 1;
4079  int i;
4080  int an = 0;
4081  inda = getIndexRng((unsigned long) pGetCoeff(set[an].p));
4082  int en = length;
4083  loop
4084  {
4085    if (an >= en-1)
4086    {
4087      op = set[an].GetpFDeg();
4088      if ((indp > inda) || ((indp == inda) && ((op > o) || ((op == o) && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))))
4089        return en;
4090      return an;
4091    }
4092    i = (an + en) / 2;
4093    indi = getIndexRng((unsigned long) pGetCoeff(set[i].p));
4094    op = set[i].GetpFDeg();
4095    if ((indi > indp) || ((indi == indp) && ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))))
4096    // if ((op > o) || ((op == o) && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
4097    {
4098      an = i;
4099      inda = getIndexRng((unsigned long) pGetCoeff(set[an].p));
4100    }
4101    else
4102      en = i;
4103  }
4104} */
4105
4106/*2
4107* looks up the position of polynomial p in set
4108* set[length] is the smallest element in set with respect
4109* to the ordering-procedure totaldegree,pLength0
4110*/
4111int posInL110 (const LSet set, const int length,
4112               LObject* p,const kStrategy)
4113{
4114  if (length<0) return 0;
4115
4116  int o = p->GetpFDeg();
4117  int op = set[length].GetpFDeg();
4118
4119  if ((op > o)
4120  || ((op == o) && (set[length].length >p->length))
4121  || ((op == o) && (set[length].length <= p->length)
4122     && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))
4123    return length+1;
4124  int i;
4125  int an = 0;
4126  int en= length;
4127  loop
4128  {
4129    if (an >= en-1)
4130    {
4131      op = set[an].GetpFDeg();
4132      if ((op > o)
4133      || ((op == o) && (set[an].length >p->length))
4134      || ((op == o) && (set[an].length <=p->length)
4135         && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))
4136        return en;
4137      return an;
4138    }
4139    i=(an+en) / 2;
4140    op = set[i].GetpFDeg();
4141    if ((op > o)
4142    || ((op == o) && (set[i].length > p->length))
4143    || ((op == o) && (set[i].length <= p->length)
4144       && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
4145      an=i;
4146    else
4147      en=i;
4148  }
4149}
4150
4151/*2
4152* looks up the position of polynomial p in set
4153* e is the ecart of p
4154* set[length] is the smallest element in set with respect
4155* to the ordering-procedure totaldegree
4156*/
4157int posInL13 (const LSet set, const int length,
4158              LObject* p,const kStrategy)
4159{
4160  if (length<0) return 0;
4161
4162  int o = p->GetpFDeg();
4163
4164  if (set[length].GetpFDeg() > o)
4165    return length+1;
4166
4167  int i;
4168  int an = 0;
4169  int en= length;
4170  loop
4171  {
4172    if (an >= en-1)
4173    {
4174      if (set[an].GetpFDeg() >= o)
4175        return en;
4176      return an;
4177    }
4178    i=(an+en) / 2;
4179    if (set[i].GetpFDeg() >= o)
4180      an=i;
4181    else
4182      en=i;
4183  }
4184}
4185
4186/*2
4187* looks up the position of polynomial p in set
4188* e is the ecart of p
4189* set[length] is the smallest element in set with respect
4190* to the ordering-procedure maximaldegree,pComp
4191*/
4192int posInL15 (const LSet set, const int length,
4193              LObject* p,const kStrategy)
4194/*{
4195 * int j=0;
4196 * int o;
4197 *
4198 * o = p->ecart+p->GetpFDeg();
4199 * loop
4200 * {
4201 *   if (j > length)                       return j;
4202 *   if (set[j].GetpFDeg()+set[j].ecart < o) return j;
4203 *   if ((set[j].GetpFDeg()+set[j].ecart == o)
4204 *   && (pLmCmp(set[j].p,p->p) == -currRing->OrdSgn))
4205 *   {
4206 *     return j;
4207 *   }
4208 *   j++;
4209 * }
4210 *}
4211 */
4212{
4213  if (length<0) return 0;
4214
4215  int o = p->GetpFDeg() + p->ecart;
4216  int op = set[length].GetpFDeg() + set[length].ecart;
4217
4218  if ((op > o)
4219  || ((op == o) && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))
4220    return length+1;
4221  int i;
4222  int an = 0;
4223  int en= length;
4224  loop
4225  {
4226    if (an >= en-1)
4227    {
4228      op = set[an].GetpFDeg() + set[an].ecart;
4229      if ((op > o)
4230      || ((op == o) && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))
4231        return en;
4232      return an;
4233    }
4234    i=(an+en) / 2;
4235    op = set[i].GetpFDeg() + set[i].ecart;
4236    if ((op > o)
4237    || ((op == o) && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
4238      an=i;
4239    else
4240      en=i;
4241  }
4242}
4243
4244/*2
4245* looks up the position of polynomial p in set
4246* e is the ecart of p
4247* set[length] is the smallest element in set with respect
4248* to the ordering-procedure totaldegree
4249*/
4250int posInL17 (const LSet set, const int length,
4251              LObject* p,const kStrategy)
4252{
4253  if (length<0) return 0;
4254
4255  int o = p->GetpFDeg() + p->ecart;
4256
4257  if ((set[length].GetpFDeg() + set[length].ecart > o)
4258  || ((set[length].GetpFDeg() + set[length].ecart == o)
4259     && (set[length].ecart > p->ecart))
4260  || ((set[length].GetpFDeg() + set[length].ecart == o)
4261     && (set[length].ecart == p->ecart)
4262     && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))
4263    return length+1;
4264  int i;
4265  int an = 0;
4266  int en= length;
4267  loop
4268  {
4269    if (an >= en-1)
4270    {
4271      if ((set[an].GetpFDeg() + set[an].ecart > o)
4272      || ((set[an].GetpFDeg() + set[an].ecart == o)
4273         && (set[an].ecart > p->ecart))
4274      || ((set[an].GetpFDeg() + set[an].ecart == o)
4275         && (set[an].ecart == p->ecart)
4276         && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))
4277        return en;
4278      return an;
4279    }
4280    i=(an+en) / 2;
4281    if ((set[i].GetpFDeg() + set[i].ecart > o)
4282    || ((set[i].GetpFDeg() + set[i].ecart == o)
4283       && (set[i].ecart > p->ecart))
4284    || ((set[i].GetpFDeg() +set[i].ecart == o)
4285       && (set[i].ecart == p->ecart)
4286       && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
4287      an=i;
4288    else
4289      en=i;
4290  }
4291}
4292/*2
4293* looks up the position of polynomial p in set
4294* e is the ecart of p
4295* set[length] is the smallest element in set with respect
4296* to the ordering-procedure pComp
4297*/
4298int posInL17_c (const LSet set, const int length,
4299                LObject* p,const kStrategy)
4300{
4301  if (length<0) return 0;
4302
4303  int cc = (-1+2*currRing->order[0]==ringorder_c);
4304  /* cc==1 for (c,..), cc==-1 for (C,..) */
4305  unsigned long c = pGetComp(p->p)*cc;
4306  int o = p->GetpFDeg() + p->ecart;
4307
4308  if (pGetComp(set[length].p)*cc > c)
4309    return length+1;
4310  if (pGetComp(set[length].p)*cc == c)
4311  {
4312    if ((set[length].GetpFDeg() + set[length].ecart > o)
4313    || ((set[length].GetpFDeg() + set[length].ecart == o)
4314       && (set[length].ecart > p->ecart))
4315    || ((set[length].GetpFDeg() + set[length].ecart == o)
4316       && (set[length].ecart == p->ecart)
4317       && (pLmCmp(set[length].p,p->p) != -currRing->OrdSgn)))
4318      return length+1;
4319  }
4320  int i;
4321  int an = 0;
4322  int en= length;
4323  loop
4324  {
4325    if (an >= en-1)
4326    {
4327      if (pGetComp(set[an].p)*cc > c)
4328        return en;
4329      if (pGetComp(set[an].p)*cc == c)
4330      {
4331        if ((set[an].GetpFDeg() + set[an].ecart > o)
4332        || ((set[an].GetpFDeg() + set[an].ecart == o)
4333           && (set[an].ecart > p->ecart))
4334        || ((set[an].GetpFDeg() + set[an].ecart == o)
4335           && (set[an].ecart == p->ecart)
4336           && (pLmCmp(set[an].p,p->p) != -currRing->OrdSgn)))
4337          return en;
4338      }
4339      return an;
4340    }
4341    i=(an+en) / 2;
4342    if (pGetComp(set[i].p)*cc > c)
4343      an=i;
4344    else if (pGetComp(set[i].p)*cc == c)
4345    {
4346      if ((set[i].GetpFDeg() + set[i].ecart > o)
4347      || ((set[i].GetpFDeg() + set[i].ecart == o)
4348         && (set[i].ecart > p->ecart))
4349      || ((set[i].GetpFDeg() +set[i].ecart == o)
4350         && (set[i].ecart == p->ecart)
4351         && (pLmCmp(set[i].p,p->p) != -currRing->OrdSgn)))
4352        an=i;
4353      else
4354        en=i;
4355    }
4356    else
4357      en=i;
4358  }
4359}
4360
4361/***************************************************************
4362 *
4363 * Tail reductions
4364 *
4365 ***************************************************************/
4366TObject*
4367kFindDivisibleByInS(kStrategy strat, int pos, LObject* L, TObject *T,
4368                    long ecart)
4369{
4370  int j = 0;
4371  const unsigned long not_sev = ~L->sev;
4372  const unsigned long* sev = strat->sevS;
4373  poly p;
4374  ring r;
4375  L->GetLm(p, r);
4376
4377  assume(~not_sev == p_GetShortExpVector(p, r));
4378
4379  if (r == currRing)
4380  {
4381    loop
4382    {
4383      if (j > pos) return NULL;
4384#if defined(PDEBUG) || defined(PDIV_DEBUG)
4385      if (p_LmShortDivisibleBy(strat->S[j], sev[j], p, not_sev, r) &&
4386          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
4387        break;
4388#else
4389      if (!(sev[j] & not_sev) &&
4390          (ecart== LONG_MAX || ecart>= strat->ecartS[j]) &&
4391          p_LmDivisibleBy(strat->S[j], p, r))
4392        break;
4393
4394#endif
4395      j++;
4396    }
4397    // if called from NF, T objects do not exist:
4398    if (strat->tl < 0 || strat->S_2_R[j] == -1)
4399    {
4400      T->Set(strat->S[j], r, strat->tailRing);
4401      return T;
4402    }
4403    else
4404    {
4405/////      assume (j >= 0 && j <= strat->tl && strat->S_2_T(j) != NULL
4406/////      && strat->S_2_T(j)->p == strat->S[j]); // wrong?
4407//      assume (j >= 0 && j <= strat->sl && strat->S_2_T(j) != NULL && strat->S_2_T(j)->p == strat->S[j]);
4408      return strat->S_2_T(j);
4409    }
4410  }
4411  else
4412  {
4413    TObject* t;
4414    loop
4415    {
4416      if (j > pos) return NULL;
4417      assume(strat->S_2_R[j] != -1);
4418#if defined(PDEBUG) || defined(PDIV_DEBUG)
4419      t = strat->S_2_T(j);
4420      assume(t != NULL && t->t_p != NULL && t->tailRing == r);
4421      if (p_LmShortDivisibleBy(t->t_p, sev[j], p, not_sev, r) &&
4422          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
4423        return t;
4424#else
4425      if (! (sev[j] & not_sev) && (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
4426      {
4427        t = strat->S_2_T(j);
4428        assume(t != NULL && t->t_p != NULL && t->tailRing == r && t->p == strat->S[j]);
4429        if (p_LmDivisibleBy(t->t_p, p, r)) return t;
4430      }
4431#endif
4432      j++;
4433    }
4434  }
4435}
4436
4437poly redtail (LObject* L, int pos, kStrategy strat)
4438{
4439  poly h, hn;
4440  strat->redTailChange=FALSE;
4441
4442  poly p = L->p;
4443  if (strat->noTailReduction || pNext(p) == NULL)
4444    return p;
4445
4446  LObject Ln(strat->tailRing);
4447  TObject* With;
4448  // placeholder in case strat->tl < 0
4449  TObject  With_s(strat->tailRing);
4450  h = p;
4451  hn = pNext(h);
4452  long op = strat->tailRing->pFDeg(hn, strat->tailRing);
4453  long e;
4454  int l;
4455  BOOLEAN save_HE=strat->kHEdgeFound;
4456  strat->kHEdgeFound |=
4457    ((Kstd1_deg>0) && (op<=Kstd1_deg)) || TEST_OPT_INFREDTAIL;
4458
4459  while(hn != NULL)
4460  {
4461    op = strat->tailRing->pFDeg(hn, strat->tailRing);
4462    if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
4463    e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
4464    loop
4465    {
4466      Ln.Set(hn, strat->tailRing);
4467      Ln.sev = p_GetShortExpVector(hn, strat->tailRing);
4468      if (strat->kHEdgeFound)
4469        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
4470      else
4471        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s, e);
4472      if (With == NULL) break;
4473      With->length=0;
4474      With->pLength=0;
4475      strat->redTailChange=TRUE;
4476      if (ksReducePolyTail(L, With, h, strat->kNoetherTail()))
4477      {
4478        // reducing the tail would violate the exp bound
4479        if (kStratChangeTailRing(strat, L))
4480        {
4481          strat->kHEdgeFound = save_HE;
4482          return redtail(L, pos, strat);
4483        }
4484        else
4485          return NULL;
4486      }
4487      hn = pNext(h);
4488      if (hn == NULL) goto all_done;
4489      op = strat->tailRing->pFDeg(hn, strat->tailRing);
4490      if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
4491      e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
4492    }
4493    h = hn;
4494    hn = pNext(h);
4495  }
4496
4497  all_done:
4498  if (strat->redTailChange)
4499  {
4500    L->last = NULL;
4501    L->pLength = 0;
4502  }
4503  strat->kHEdgeFound = save_HE;
4504  return p;
4505}
4506
4507poly redtail (poly p, int pos, kStrategy strat)
4508{
4509  LObject L(p, currRing);
4510  return redtail(&L, pos, strat);
4511}
4512
4513poly redtailBba (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
4514{
4515#define REDTAIL_CANONICALIZE 100
4516  strat->redTailChange=FALSE;
4517  if (strat->noTailReduction) return L->GetLmCurrRing();
4518  poly h, p;
4519  p = h = L->GetLmTailRing();
4520  if ((h==NULL) || (pNext(h)==NULL))
4521    return L->GetLmCurrRing();
4522
4523  TObject* With;
4524  // placeholder in case strat->tl < 0
4525  TObject  With_s(strat->tailRing);
4526
4527  LObject Ln(pNext(h), strat->tailRing);
4528  Ln.pLength = L->GetpLength() - 1;
4529
4530  pNext(h) = NULL;
4531  if (L->p != NULL) pNext(L->p) = NULL;
4532  L->pLength = 1;
4533
4534  Ln.PrepareRed(strat->use_buckets);
4535
4536  int cnt=REDTAIL_CANONICALIZE;
4537  while(!Ln.IsNull())
4538  {
4539    loop
4540    {
4541      Ln.SetShortExpVector();
4542      if (withT)
4543      {
4544        int j;
4545        j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
4546        if (j < 0) break;
4547        With = &(strat->T[j]);
4548      }
4549      else
4550      {
4551        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
4552        if (With == NULL) break;
4553      }
4554      cnt--;
4555      if (cnt==0)
4556      {
4557        cnt=REDTAIL_CANONICALIZE;
4558        /*poly tmp=*/Ln.CanonicalizeP();
4559        if (normalize)
4560        {
4561          Ln.Normalize();
4562          //pNormalize(tmp);
4563          //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
4564        }
4565      }
4566      if (normalize && (!TEST_OPT_INTSTRATEGY) && (!nIsOne(pGetCoeff(With->p))))
4567      {
4568        With->pNorm();
4569      }
4570      strat->redTailChange=TRUE;
4571      if (ksReducePolyTail(L, With, &Ln))
4572      {
4573        // reducing the tail would violate the exp bound
4574        //  set a flag and hope for a retry (in bba)
4575        strat->completeReduce_retry=TRUE;
4576        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
4577        do
4578        {
4579          pNext(h) = Ln.LmExtractAndIter();
4580          pIter(h);
4581          L->pLength++;
4582        } while (!Ln.IsNull());
4583        goto all_done;
4584      }
4585      if (Ln.IsNull()) goto all_done;
4586      if (! withT) With_s.Init(currRing);
4587    }
4588    pNext(h) = Ln.LmExtractAndIter();
4589    pIter(h);
4590    pNormalize(h);
4591    L->pLength++;
4592  }
4593
4594  all_done:
4595  Ln.Delete();
4596  if (L->p != NULL) pNext(L->p) = pNext(p);
4597
4598  if (strat->redTailChange)
4599  {
4600    L->last = NULL;
4601    L->length = 0;
4602  }
4603
4604  //if (TEST_OPT_PROT) { PrintS("N"); mflush(); }
4605  //L->Normalize(); // HANNES: should have a test
4606  kTest_L(L);
4607  return L->GetLmCurrRing();
4608}
4609
4610#ifdef HAVE_RINGS
4611poly redtailBba_Z (LObject* L, int pos, kStrategy strat )
4612// normalize=FALSE, withT=FALSE, coeff=Z
4613{
4614  strat->redTailChange=FALSE;
4615  if (strat->noTailReduction) return L->GetLmCurrRing();
4616  poly h, p;
4617  p = h = L->GetLmTailRing();
4618  if ((h==NULL) || (pNext(h)==NULL))
4619    return L->GetLmCurrRing();
4620
4621  TObject* With;
4622  // placeholder in case strat->tl < 0
4623  TObject  With_s(strat->tailRing);
4624
4625  LObject Ln(pNext(h), strat->tailRing);
4626  Ln.pLength = L->GetpLength() - 1;
4627
4628  pNext(h) = NULL;
4629  if (L->p != NULL) pNext(L->p) = NULL;
4630  L->pLength = 1;
4631
4632  Ln.PrepareRed(strat->use_buckets);
4633
4634  int cnt=REDTAIL_CANONICALIZE;
4635  while(!Ln.IsNull())
4636  {
4637    loop
4638    {
4639      Ln.SetShortExpVector();
4640      With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
4641      if (With == NULL) break;
4642      cnt--;
4643      if (cnt==0)
4644      {
4645        cnt=REDTAIL_CANONICALIZE;
4646        /*poly tmp=*/Ln.CanonicalizeP();
4647      }
4648      // we are in Z, do not call pNorm
4649      strat->redTailChange=TRUE;
4650      // test divisibility of coefs:
4651      poly p_Ln=Ln.GetLmCurrRing();
4652      poly p_With=With->GetLmCurrRing();
4653      number z=n_IntMod(pGetCoeff(p_Ln),pGetCoeff(p_With), currRing->cf);
4654      if (!nIsZero(z))
4655      {
4656        // subtract z*Ln, add z.Ln to L
4657        poly m=pHead(p_Ln);
4658        pSetCoeff(m,z);
4659        poly mm=pHead(m);
4660        pNext(h) = m;
4661        pIter(h);
4662        L->pLength++;
4663        mm=pNeg(mm);
4664        if (Ln.bucket!=NULL)
4665        {
4666          int dummy=1;
4667          kBucket_Add_q(Ln.bucket,mm,&dummy);
4668        }
4669        else
4670        {
4671          if (Ln.p!=NULL) Ln.p=pAdd(Ln.p,mm);
4672          else if (Ln.t_p!=NULL)  Ln.t_p=p_Add_q(Ln.t_p,mm,strat->tailRing);
4673        }
4674      }
4675      else
4676        nDelete(&z);
4677
4678      if (ksReducePolyTail(L, With, &Ln))
4679      {
4680        // reducing the tail would violate the exp bound
4681        //  set a flag and hope for a retry (in bba)
4682        strat->completeReduce_retry=TRUE;
4683        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
4684        do
4685        {
4686          pNext(h) = Ln.LmExtractAndIter();
4687          pIter(h);
4688          L->pLength++;
4689        } while (!Ln.IsNull());
4690        goto all_done;
4691      }
4692      if (Ln.IsNull()) goto all_done;
4693      With_s.Init(currRing);
4694    }
4695    pNext(h) = Ln.LmExtractAndIter();
4696    pIter(h);
4697    pNormalize(h);
4698    L->pLength++;
4699  }
4700
4701  all_done:
4702  Ln.Delete();
4703  if (L->p != NULL) pNext(L->p) = pNext(p);
4704
4705  if (strat->redTailChange)
4706  {
4707    L->last = NULL;
4708    L->length = 0;
4709  }
4710
4711  //if (TEST_OPT_PROT) { PrintS("N"); mflush(); }
4712  //L->Normalize(); // HANNES: should have a test
4713  kTest_L(L);
4714  return L->GetLmCurrRing();
4715}
4716#endif
4717
4718/*2
4719*checks the change degree and write progress report
4720*/
4721void message (int i,int* reduc,int* olddeg,kStrategy strat, int red_result)
4722{
4723  if (i != *olddeg)
4724  {
4725    Print("%d",i);
4726    *olddeg = i;
4727  }
4728  if (TEST_OPT_OLDSTD)
4729  {
4730    if (strat->Ll != *reduc)
4731    {
4732      if (strat->Ll != *reduc-1)
4733        Print("(%d)",strat->Ll+1);
4734      else
4735        PrintS("-");
4736      *reduc = strat->Ll;
4737    }
4738    else
4739      PrintS(".");
4740    mflush();
4741  }
4742  else
4743  {
4744    if (red_result == 0)
4745      PrintS("-");
4746    else if (red_result < 0)
4747      PrintS(".");
4748    if ((red_result > 0) || ((strat->Ll % 100)==99))
4749    {
4750      if (strat->Ll != *reduc && strat->Ll > 0)
4751      {
4752        Print("(%d)",strat->Ll+1);
4753        *reduc = strat->Ll;
4754      }
4755    }
4756  }
4757}
4758
4759/*2
4760*statistics
4761*/
4762void messageStat (int hilbcount,kStrategy strat)
4763{
4764  //PrintS("\nUsage/Allocation of temporary storage:\n");
4765  //Print("%d/%d polynomials in standard base\n",srmax,IDELEMS(Shdl));
4766  //Print("%d/%d polynomials in set L (for lazy alg.)",lrmax+1,strat->Lmax);
4767  Print("product criterion:%d chain criterion:%d\n",strat->cp,strat->c3);
4768  if (hilbcount!=0) Print("hilbert series criterion:%d\n",hilbcount);
4769  /* in usual case strat->cv is 0, it gets changed only in shift routines */
4770  if (strat->cv!=0) Print("shift V criterion:%d\n",strat->cv);
4771  /*mflush();*/
4772}
4773
4774#ifdef KDEBUG
4775/*2
4776*debugging output: all internal sets, if changed
4777*for testing purpuse only/has to be changed for later use
4778*/
4779void messageSets (kStrategy strat)
4780{
4781  int i;
4782  if (strat->news)
4783  {
4784    PrintS("set S");
4785    for (i=0; i<=strat->sl; i++)
4786    {
4787      Print("\n  %d:",i);
4788      p_wrp(strat->S[i], currRing, strat->tailRing);
4789    }
4790    strat->news = FALSE;
4791  }
4792  if (strat->newt)
4793  {
4794    PrintS("\nset T");
4795    for (i=0; i<=strat->tl; i++)
4796    {
4797      Print("\n  %d:",i);
4798      strat->T[i].wrp();
4799      Print(" o:%ld e:%d l:%d",
4800        strat->T[i].pFDeg(),strat->T[i].ecart,strat->T[i].length);
4801    }
4802    strat->newt = FALSE;
4803  }
4804  PrintS("\nset L");
4805  for (i=strat->Ll; i>=0; i--)
4806  {
4807    Print("\n%d:",i);
4808    p_wrp(strat->L[i].p1, currRing, strat->tailRing);
4809    PrintS("  ");
4810    p_wrp(strat->L[i].p2, currRing, strat->tailRing);
4811    PrintS(" lcm: ");p_wrp(strat->L[i].lcm, currRing);
4812    PrintS("\n  p : ");
4813    strat->L[i].wrp();
4814    Print("  o:%ld e:%d l:%d",
4815          strat->L[i].pFDeg(),strat->L[i].ecart,strat->L[i].length);
4816  }
4817  PrintLn();
4818}
4819
4820#endif
4821
4822
4823/*2
4824*construct the set s from F
4825*/
4826void initS (ideal F, ideal Q, kStrategy strat)
4827{
4828  int   i,pos;
4829
4830  if (Q!=NULL) i=((IDELEMS(F)+IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
4831  else         i=((IDELEMS(F)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
4832  strat->ecartS=initec(i);
4833  strat->sevS=initsevS(i);
4834  strat->S_2_R=initS_2_R(i);
4835  strat->fromQ=NULL;
4836  strat->Shdl=idInit(i,F->rank);
4837  strat->S=strat->Shdl->m;
4838  /*- put polys into S -*/
4839  if (Q!=NULL)
4840  {
4841    strat->fromQ=initec(i);
4842    memset(strat->fromQ,0,i*sizeof(int));
4843    for (i=0; i<IDELEMS(Q); i++)
4844    {
4845      if (Q->m[i]!=NULL)
4846      {
4847        LObject h;
4848        h.p = pCopy(Q->m[i]);
4849        if (TEST_OPT_INTSTRATEGY)
4850        {
4851          //pContent(h.p);
4852          h.pCleardenom(); // also does a pContent
4853        }
4854        else
4855        {
4856          h.pNorm();
4857        }
4858        if (currRing->OrdSgn==-1)
4859        {
4860          deleteHC(&h, strat);
4861        }
4862        if (h.p!=NULL)
4863        {
4864          strat->initEcart(&h);
4865          if (strat->sl==-1)
4866            pos =0;
4867          else
4868          {
4869            pos = posInS(strat,strat->sl,h.p,h.ecart);
4870          }
4871          h.sev = pGetShortExpVector(h.p);
4872          strat->enterS(h,pos,strat,-1);
4873          strat->fromQ[pos]=1;
4874        }
4875      }
4876    }
4877  }
4878  for (i=0; i<IDELEMS(F); i++)
4879  {
4880    if (F->m[i]!=NULL)
4881    {
4882      LObject h;
4883      h.p = pCopy(F->m[i]);
4884      if (currRing->OrdSgn==-1)
4885      {
4886        cancelunit(&h);  /*- tries to cancel a unit -*/
4887        deleteHC(&h, strat);
4888      }
4889      if (h.p!=NULL)
4890      // do not rely on the input being a SB!
4891      {
4892        if (TEST_OPT_INTSTRATEGY)
4893        {
4894          //pContent(h.p);
4895          h.pCleardenom(); // also does a pContent
4896        }
4897        else
4898        {
4899          h.pNorm();
4900        }
4901        strat->initEcart(&h);
4902        if (strat->sl==-1)
4903          pos =0;
4904        else
4905          pos = posInS(strat,strat->sl,h.p,h.ecart);
4906        h.sev = pGetShortExpVector(h.p);
4907        strat->enterS(h,pos,strat,-1);
4908      }
4909    }
4910  }
4911  /*- test, if a unit is in F -*/
4912  if ((strat->sl>=0)
4913#ifdef HAVE_RINGS
4914       && n_IsUnit(pGetCoeff(strat->S[0]),currRing->cf)
4915#endif
4916       && pIsConstant(strat->S[0]))
4917  {
4918    while (strat->sl>0) deleteInS(strat->sl,strat);
4919  }
4920}
4921
4922void initSL (ideal F, ideal Q,kStrategy strat)
4923{
4924  int   i,pos;
4925
4926  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
4927  else i=setmaxT;
4928  strat->ecartS=initec(i);
4929  strat->sevS=initsevS(i);
4930  strat->S_2_R=initS_2_R(i);
4931  strat->fromQ=NULL;
4932  strat->Shdl=idInit(i,F->rank);
4933  strat->S=strat->Shdl->m;
4934  /*- put polys into S -*/
4935  if (Q!=NULL)
4936  {
4937    strat->fromQ=initec(i);
4938    memset(strat->fromQ,0,i*sizeof(int));
4939    for (i=0; i<IDELEMS(Q); i++)
4940    {
4941      if (Q->m[i]!=NULL)
4942      {
4943        LObject h;
4944        h.p = pCopy(Q->m[i]);
4945        if (currRing->OrdSgn==-1)
4946        {
4947          deleteHC(&h,strat);
4948        }
4949        if (TEST_OPT_INTSTRATEGY)
4950        {
4951          //pContent(h.p);
4952          h.pCleardenom(); // also does a pContent
4953        }
4954        else
4955        {
4956          h.pNorm();
4957        }
4958        if (h.p!=NULL)
4959        {
4960          strat->initEcart(&h);
4961          if (strat->sl==-1)
4962            pos =0;
4963          else
4964          {
4965            pos = posInS(strat,strat->sl,h.p,h.ecart);
4966          }
4967          h.sev = pGetShortExpVector(h.p);
4968          strat->enterS(h,pos,strat,-1);
4969          strat->fromQ[pos]=1;
4970        }
4971      }
4972    }
4973  }
4974  for (i=0; i<IDELEMS(F); i++)
4975  {
4976    if (F->m[i]!=NULL)
4977    {
4978      LObject h;
4979      h.p = pCopy(F->m[i]);
4980      if (h.p!=NULL)
4981      {
4982        if (currRing->OrdSgn==-1)
4983        {
4984          cancelunit(&h);  /*- tries to cancel a unit -*/
4985          deleteHC(&h, strat);
4986        }
4987        if (h.p!=NULL)
4988        {
4989          if (TEST_OPT_INTSTRATEGY)
4990          {
4991            //pContent(h.p);
4992            h.pCleardenom(); // also does a pContent
4993          }
4994          else
4995          {
4996            h.pNorm();
4997          }
4998          strat->initEcart(&h);
4999          if (strat->Ll==-1)
5000            pos =0;
5001          else
5002            pos = strat->posInL(strat->L,strat->Ll,&h,strat);
5003          h.sev = pGetShortExpVector(h.p);
5004          enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
5005        }
5006      }
5007    }
5008  }
5009  /*- test, if a unit is in F -*/
5010
5011  if ((strat->Ll>=0)
5012#ifdef HAVE_RINGS
5013       && n_IsUnit(pGetCoeff(strat->L[strat->Ll].p), currRing->cf)
5014#endif
5015       && pIsConstant(strat->L[strat->Ll].p))
5016  {
5017    while (strat->Ll>0) deleteInL(strat->L,&strat->Ll,strat->Ll-1,strat);
5018  }
5019}
5020
5021
5022/*2
5023*construct the set s from F and {P}
5024*/
5025void initSSpecial (ideal F, ideal Q, ideal P,kStrategy strat)
5026{
5027  int   i,pos;
5028
5029  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
5030  else i=setmaxT;
5031  i=((i+IDELEMS(F)+IDELEMS(P)+15)/16)*16;
5032  strat->ecartS=initec(i);
5033  strat->sevS=initsevS(i);
5034  strat->S_2_R=initS_2_R(i);
5035  strat->fromQ=NULL;
5036  strat->Shdl=idInit(i,F->rank);
5037  strat->S=strat->Shdl->m;
5038
5039  /*- put polys into S -*/
5040  if (Q!=NULL)
5041  {
5042    strat->fromQ=initec(i);
5043    memset(strat->fromQ,0,i*sizeof(int));
5044    for (i=0; i<IDELEMS(Q); i++)
5045    {
5046      if (Q->m[i]!=NULL)
5047      {
5048        LObject h;
5049        h.p = pCopy(Q->m[i]);
5050        //if (TEST_OPT_INTSTRATEGY)
5051        //{
5052        //  //pContent(h.p);
5053        //  h.pCleardenom(); // also does a pContent
5054        //}
5055        //else
5056        //{
5057        //  h.pNorm();
5058        //}
5059        if (currRing->OrdSgn==-1)
5060        {
5061          deleteHC(&h,strat);
5062        }
5063        if (h.p!=NULL)
5064        {
5065          strat->initEcart(&h);
5066          if (strat->sl==-1)
5067            pos =0;
5068          else
5069          {
5070            pos = posInS(strat,strat->sl,h.p,h.ecart);
5071          }
5072          h.sev = pGetShortExpVector(h.p);
5073          strat->enterS(h,pos,strat, strat->tl+1);
5074          enterT(h, strat);
5075          strat->fromQ[pos]=1;
5076        }
5077      }
5078    }
5079  }
5080  /*- put polys into S -*/
5081  for (i=0; i<IDELEMS(F); i++)
5082  {
5083    if (F->m[i]!=NULL)
5084    {
5085      LObject h;
5086      h.p = pCopy(F->m[i]);
5087      if (currRing->OrdSgn==-1)
5088      {
5089        deleteHC(&h,strat);
5090      }
5091      else
5092      {
5093        h.p=redtailBba(h.p,strat->sl,strat);
5094      }
5095      if (h.p!=NULL)
5096      {
5097        strat->initEcart(&h);
5098        if (strat->sl==-1)
5099          pos =0;
5100        else
5101          pos = posInS(strat,strat->sl,h.p,h.ecart);
5102        h.sev = pGetShortExpVector(h.p);
5103        strat->enterS(h,pos,strat, strat->tl+1);
5104        enterT(h,strat);
5105      }
5106    }
5107  }
5108  for (i=0; i<IDELEMS(P); i++)
5109  {
5110    if (P->m[i]!=NULL)
5111    {
5112      LObject h;
5113      h.p=pCopy(P->m[i]);
5114      if (TEST_OPT_INTSTRATEGY)
5115      {
5116        h.pCleardenom();
5117      }
5118      else
5119      {
5120        h.pNorm();
5121      }
5122      if(strat->sl>=0)
5123      {
5124        if (currRing->OrdSgn==1)
5125        {
5126          h.p=redBba(h.p,strat->sl,strat);
5127          if (h.p!=NULL)
5128          {
5129            h.p=redtailBba(h.p,strat->sl,strat);
5130          }
5131        }
5132        else
5133        {
5134          h.p=redMora(h.p,strat->sl,strat);
5135        }
5136        if(h.p!=NULL)
5137        {
5138          strat->initEcart(&h);
5139          if (TEST_OPT_INTSTRATEGY)
5140          {
5141            h.pCleardenom();
5142          }
5143          else
5144          {
5145            h.is_normalized = 0;
5146            h.pNorm();
5147          }
5148          h.sev = pGetShortExpVector(h.p);
5149          h.SetpFDeg();
5150          pos = posInS(strat,strat->sl,h.p,h.ecart);
5151          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
5152          strat->enterS(h,pos,strat, strat->tl+1);
5153          enterT(h,strat);
5154        }
5155      }
5156      else
5157      {
5158        h.sev = pGetShortExpVector(h.p);
5159        strat->initEcart(&h);
5160        strat->enterS(h,0,strat, strat->tl+1);
5161        enterT(h,strat);
5162      }
5163    }
5164  }
5165}
5166/*2
5167* reduces h using the set S
5168* procedure used in cancelunit1
5169*/
5170static poly redBba1 (poly h,int maxIndex,kStrategy strat)
5171{
5172  int j = 0;
5173  unsigned long not_sev = ~ pGetShortExpVector(h);
5174
5175  while (j <= maxIndex)
5176  {
5177    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j],h, not_sev))
5178       return ksOldSpolyRedNew(strat->S[j],h,strat->kNoetherTail());
5179    else j++;
5180  }
5181  return h;
5182}
5183
5184/*2
5185*tests if p.p=monomial*unit and cancels the unit
5186*/
5187void cancelunit1 (LObject* p,int *suc, int index,kStrategy strat )
5188{
5189  int k;
5190  poly r,h,h1,q;
5191
5192  if (!pIsVector((*p).p) && ((*p).ecart != 0))
5193  {
5194#ifdef HAVE_RINGS_LOC
5195    // Leading coef have to be a unit
5196    if ( !(nIsUnit(p_GetCoeff((*p).p, r))) ) return;
5197#endif
5198    k = 0;
5199    h1 = r = pCopy((*p).p);
5200    h =pNext(r);
5201    loop
5202    {
5203      if (h==NULL)
5204      {
5205        pDelete(&r);
5206        pDelete(&(pNext((*p).p)));
5207        (*p).ecart = 0;
5208        (*p).length = 1;
5209#ifdef HAVE_RINGS_LOC
5210        (*p).pLength = 1;  // Why wasn't this set already?
5211#endif
5212        (*suc)=0;
5213        return;
5214      }
5215      if (!pDivisibleBy(r,h))
5216      {
5217        q=redBba1(h,index ,strat);
5218        if (q != h)
5219        {
5220          k++;
5221          pDelete(&h);
5222          pNext(h1) = h = q;
5223        }
5224        else
5225        {
5226          pDelete(&r);
5227          return;
5228        }
5229      }
5230      else
5231      {
5232        h1 = h;
5233        pIter(h);
5234      }
5235      if (k > 10)
5236      {
5237        pDelete(&r);
5238        return;
5239      }
5240    }
5241  }
5242}
5243
5244#if 0
5245/*2
5246* reduces h using the elements from Q in the set S
5247* procedure used in updateS
5248* must not be used for elements of Q or elements of an ideal !
5249*/
5250static poly redQ (poly h, int j, kStrategy strat)
5251{
5252  int start;
5253  unsigned long not_sev = ~ pGetShortExpVector(h);
5254  while ((j <= strat->sl) && (pGetComp(strat->S[j])!=0)) j++;
5255  start=j;
5256  while (j<=strat->sl)
5257  {
5258    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
5259    {
5260      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
5261      if (h==NULL) return NULL;
5262      j = start;
5263      not_sev = ~ pGetShortExpVector(h);
5264    }
5265    else j++;
5266  }
5267  return h;
5268}
5269#endif
5270
5271/*2
5272* reduces h using the set S
5273* procedure used in updateS
5274*/
5275static poly redBba (poly h,int maxIndex,kStrategy strat)
5276{
5277  int j = 0;
5278  unsigned long not_sev = ~ pGetShortExpVector(h);
5279
5280  while (j <= maxIndex)
5281  {
5282    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
5283    {
5284      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
5285      if (h==NULL) return NULL;
5286      j = 0;
5287      not_sev = ~ pGetShortExpVector(h);    }
5288    else j++;
5289  }
5290  return h;
5291}
5292
5293/*2
5294* reduces h using the set S
5295*e is the ecart of h
5296*procedure used in updateS
5297*/
5298static poly redMora (poly h,int maxIndex,kStrategy strat)
5299{
5300  int  j=0;
5301  int  e,l;
5302  unsigned long not_sev = ~ pGetShortExpVector(h);
5303
5304  if (maxIndex >= 0)
5305  {
5306    e = currRing->pLDeg(h,&l,currRing)-p_FDeg(h,currRing);
5307    do
5308    {
5309      if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev)
5310      && ((e >= strat->ecartS[j]) || strat->kHEdgeFound))
5311      {
5312#ifdef KDEBUG
5313        if (TEST_OPT_DEBUG)
5314          {PrintS("reduce ");wrp(h);Print(" with S[%d] (",j);wrp(strat->S[j]);}
5315#endif
5316        h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
5317#ifdef KDEBUG
5318        if(TEST_OPT_DEBUG)
5319          {PrintS(")\nto "); wrp(h); PrintLn();}
5320#endif
5321        // pDelete(&h);
5322        if (h == NULL) return NULL;
5323        e = currRing->pLDeg(h,&l,currRing)-p_FDeg(h,currRing);
5324        j = 0;
5325        not_sev = ~ pGetShortExpVector(h);
5326      }
5327      else j++;
5328    }
5329    while (j <= maxIndex);
5330  }
5331  return h;
5332}
5333
5334/*2
5335*updates S:
5336*the result is a set of polynomials which are in
5337*normalform with respect to S
5338*/
5339void updateS(BOOLEAN toT,kStrategy strat)
5340{
5341  LObject h;
5342  int i, suc=0;
5343  poly redSi=NULL;
5344  BOOLEAN change,any_change;
5345//  Print("nach initS: updateS start mit sl=%d\n",(strat->sl));
5346//  for (i=0; i<=(strat->sl); i++)
5347//  {
5348//    Print("s%d:",i);
5349//    if (strat->fromQ!=NULL) Print("(Q:%d) ",strat->fromQ[i]);
5350//    pWrite(strat->S[i]);
5351//  }
5352//  Print("currRing->OrdSgn=%d\n", currRing->OrdSgn);
5353  any_change=FALSE;
5354  if (currRing->OrdSgn==1)
5355  {
5356    while (suc != -1)
5357    {
5358      i=suc+1;
5359      while (i<=strat->sl)
5360      {
5361        change=FALSE;
5362        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0)) && (i>0))
5363        {
5364          redSi = pHead(strat->S[i]);
5365          strat->S[i] = redBba(strat->S[i],i-1,strat);
5366          //if ((strat->ak!=0)&&(strat->S[i]!=NULL))
5367          //  strat->S[i]=redQ(strat->S[i],i+1,strat); /*reduce S[i] mod Q*/
5368          if (pCmp(redSi,strat->S[i])!=0)
5369          {
5370            change=TRUE;
5371            any_change=TRUE;
5372            #ifdef KDEBUG
5373            if (TEST_OPT_DEBUG)
5374            {
5375              PrintS("reduce:");
5376              wrp(redSi);PrintS(" to ");p_wrp(strat->S[i], currRing, strat->tailRing);PrintLn();
5377            }
5378            #endif
5379            if (TEST_OPT_PROT)
5380            {
5381              if (strat->S[i]==NULL)
5382                PrintS("V");
5383              else
5384                PrintS("v");
5385              mflush();
5386            }
5387          }
5388          pLmDelete(&redSi);
5389          if (strat->S[i]==NULL)
5390          {
5391            deleteInS(i,strat);
5392            i--;
5393          }
5394          else if (change)
5395          {
5396            if (TEST_OPT_INTSTRATEGY)
5397            {
5398              if (TEST_OPT_CONTENTSB)
5399                {
5400                  number n;
5401                  p_Cleardenom_n(strat->S[i], currRing, n);// also does a pContent
5402                  if (!nIsOne(n))
5403                    {
5404                      denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
5405                      denom->n=nInvers(n);
5406                      denom->next=DENOMINATOR_LIST;
5407                      DENOMINATOR_LIST=denom;
5408                    }
5409                  nDelete(&n);
5410                }
5411              else
5412                {
5413                  //pContent(strat->S[i]);
5414                  strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
5415                }
5416            }
5417            else
5418            {
5419              pNorm(strat->S[i]);
5420            }
5421            strat->sevS[i] = pGetShortExpVector(strat->S[i]);
5422          }
5423        }
5424        i++;
5425      }
5426      if (any_change) reorderS(&suc,strat);
5427      else break;
5428    }
5429    if (toT)
5430    {
5431      for (i=0; i<=strat->sl; i++)
5432      {
5433        if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
5434        {
5435          h.p = redtailBba(strat->S[i],i-1,strat);
5436          if (TEST_OPT_INTSTRATEGY)
5437          {
5438            h.pCleardenom();// also does a pContent
5439          }
5440        }
5441        else
5442        {
5443          h.p = strat->S[i];
5444        }
5445        strat->initEcart(&h);
5446        if (strat->honey)
5447        {
5448          strat->ecartS[i] = h.ecart;
5449        }
5450        if (strat->sevS[i] == 0) {strat->sevS[i] = pGetShortExpVector(h.p);}
5451        else assume(strat->sevS[i] == pGetShortExpVector(h.p));
5452        h.sev = strat->sevS[i];
5453        /*puts the elements of S also to T*/
5454        strat->initEcart(&h);
5455        enterT(h,strat);
5456        strat->S_2_R[i] = strat->tl;
5457      }
5458    }
5459  }
5460  else
5461  {
5462    while (suc != -1)
5463    {
5464      i=suc;
5465      while (i<=strat->sl)
5466      {
5467        change=FALSE;
5468        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0)) && (i>0))
5469        {
5470          redSi=pHead((strat->S)[i]);
5471          (strat->S)[i] = redMora((strat->S)[i],i-1,strat);
5472          if ((strat->S)[i]==NULL)
5473          {
5474            deleteInS(i,strat);
5475            i--;
5476          }
5477          else if (pCmp((strat->S)[i],redSi)!=0)
5478          {
5479            any_change=TRUE;
5480            h.p = strat->S[i];
5481            strat->initEcart(&h);
5482            strat->ecartS[i] = h.ecart;
5483            if (TEST_OPT_INTSTRATEGY)
5484            {
5485              if (TEST_OPT_CONTENTSB)
5486                {
5487                  number n;
5488                  p_Cleardenom_n(strat->S[i], currRing, n);// also does a pContent
5489                  if (!nIsOne(n))
5490                    {
5491                      denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
5492                      denom->n=nInvers(n);
5493                      denom->next=DENOMINATOR_LIST;
5494                      DENOMINATOR_LIST=denom;
5495                    }
5496                  nDelete(&n);
5497                }
5498              else
5499                {
5500                  //pContent(strat->S[i]);
5501                  strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
5502                }
5503            }
5504            else
5505            {
5506              pNorm(strat->S[i]); // == h.p
5507            }
5508            h.sev =  pGetShortExpVector(h.p);
5509            strat->sevS[i] = h.sev;
5510          }
5511          pLmDelete(&redSi);
5512          kTest(strat);
5513        }
5514        i++;
5515      }
5516#ifdef KDEBUG
5517      kTest(strat);
5518#endif
5519      if (any_change) reorderS(&suc,strat);
5520      else { suc=-1; break; }
5521      if (h.p!=NULL)
5522      {
5523        if (!strat->kHEdgeFound)
5524        {
5525          /*strat->kHEdgeFound =*/ HEckeTest(h.p,strat);
5526        }
5527        if (strat->kHEdgeFound)
5528          newHEdge(strat);
5529      }
5530    }
5531    for (i=0; i<=strat->sl; i++)
5532    {
5533      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
5534      {
5535        strat->S[i] = h.p = redtail(strat->S[i],strat->sl,strat);
5536        strat->initEcart(&h);
5537        strat->ecartS[i] = h.ecart;
5538        h.sev = pGetShortExpVector(h.p);
5539        strat->sevS[i] = h.sev;
5540      }
5541      else
5542      {
5543        h.p = strat->S[i];
5544        h.ecart=strat->ecartS[i];
5545        h.sev = strat->sevS[i];
5546        h.length = h.pLength = pLength(h.p);
5547      }
5548      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
5549        cancelunit1(&h,&suc,strat->sl,strat);
5550      h.SetpFDeg();
5551      /*puts the elements of S also to T*/
5552      enterT(h,strat);
5553      strat->S_2_R[i] = strat->tl;
5554    }
5555    if (suc!= -1) updateS(toT,strat);
5556  }
5557#ifdef KDEBUG
5558  kTest(strat);
5559#endif
5560}
5561
5562
5563/*2
5564* -puts p to the standardbasis s at position at
5565* -saves the result in S
5566*/
5567void enterSBba (LObject p,int atS,kStrategy strat, int atR)
5568{
5569  strat->news = TRUE;
5570  /*- puts p to the standardbasis s at position at -*/
5571  if (strat->sl == IDELEMS(strat->Shdl)-1)
5572  {
5573    strat->sevS = (unsigned long*) omRealloc0Size(strat->sevS,
5574                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
5575                                    (IDELEMS(strat->Shdl)+setmaxTinc)
5576                                                  *sizeof(unsigned long));
5577    strat->ecartS = (intset)omReallocSize(strat->ecartS,
5578                                          IDELEMS(strat->Shdl)*sizeof(int),
5579                                          (IDELEMS(strat->Shdl)+setmaxTinc)
5580                                                  *sizeof(int));
5581    strat->S_2_R = (int*) omRealloc0Size(strat->S_2_R,
5582                                         IDELEMS(strat->Shdl)*sizeof(int),
5583                                         (IDELEMS(strat->Shdl)+setmaxTinc)
5584                                                  *sizeof(int));
5585    if (strat->lenS!=NULL)
5586      strat->lenS=(int*)omRealloc0Size(strat->lenS,
5587                                       IDELEMS(strat->Shdl)*sizeof(int),
5588                                       (IDELEMS(strat->Shdl)+setmaxTinc)
5589                                                 *sizeof(int));
5590    if (strat->lenSw!=NULL)
5591      strat->lenSw=(wlen_type*)omRealloc0Size(strat->lenSw,
5592                                       IDELEMS(strat->Shdl)*sizeof(wlen_type),
5593                                       (IDELEMS(strat->Shdl)+setmaxTinc)
5594                                                 *sizeof(wlen_type));
5595    if (strat->fromQ!=NULL)
5596    {
5597      strat->fromQ = (intset)omReallocSize(strat->fromQ,
5598                                    IDELEMS(strat->Shdl)*sizeof(int),
5599                                    (IDELEMS(strat->Shdl)+setmaxTinc)*sizeof(int));
5600    }
5601    pEnlargeSet(&strat->S,IDELEMS(strat->Shdl),setmaxTinc);
5602    IDELEMS(strat->Shdl)+=setmaxTinc;
5603    strat->Shdl->m=strat->S;
5604  }
5605  if (atS <= strat->sl)
5606  {
5607#ifdef ENTER_USE_MEMMOVE
5608// #if 0
5609    memmove(&(strat->S[atS+1]), &(strat->S[atS]),
5610            (strat->sl - atS + 1)*sizeof(poly));
5611    memmove(&(strat->ecartS[atS+1]), &(strat->ecartS[atS]),
5612            (strat->sl - atS + 1)*sizeof(int));
5613    memmove(&(strat->sevS[atS+1]), &(strat->sevS[atS]),
5614            (strat->sl - atS + 1)*sizeof(unsigned long));
5615    memmove(&(strat->S_2_R[atS+1]), &(strat->S_2_R[atS]),
5616            (strat->sl - atS + 1)*sizeof(int));
5617    if (strat->lenS!=NULL)
5618    memmove(&(strat->lenS[atS+1]), &(strat->lenS[atS]),
5619            (strat->sl - atS + 1)*sizeof(int));
5620    if (strat->lenSw!=NULL)
5621    memmove(&(strat->lenSw[atS+1]), &(strat->lenSw[atS]),
5622            (strat->sl - atS + 1)*sizeof(wlen_type));
5623#else
5624    for (i=strat->sl+1; i>=atS+1; i--)
5625    {
5626      strat->S[i] = strat->S[i-1];
5627      strat->ecartS[i] = strat->ecartS[i-1];
5628      strat->sevS[i] = strat->sevS[i-1];
5629      strat->S_2_R[i] = strat->S_2_R[i-1];
5630    }
5631    if (strat->lenS!=NULL)
5632    for (i=strat->sl+1; i>=atS+1; i--)
5633      strat->lenS[i] = strat->lenS[i-1];
5634    if (strat->lenSw!=NULL)
5635    for (i=strat->sl+1; i>=atS+1; i--)
5636      strat->lenSw[i] = strat->lenSw[i-1];
5637#endif
5638  }
5639  if (strat->fromQ!=NULL)
5640  {
5641#ifdef ENTER_USE_MEMMOVE
5642    memmove(&(strat->fromQ[atS+1]), &(strat->fromQ[atS]),
5643                  (strat->sl - atS + 1)*sizeof(int));
5644#else
5645    for (i=strat->sl+1; i>=atS+1; i--)
5646    {
5647      strat->fromQ[i] = strat->fromQ[i-1];
5648    }
5649#endif
5650    strat->fromQ[atS]=0;
5651  }
5652
5653  /*- save result -*/
5654  strat->S[atS] = p.p;
5655  if (strat->honey) strat->ecartS[atS] = p.ecart;
5656  if (p.sev == 0)
5657    p.sev = pGetShortExpVector(p.p);
5658  else
5659    assume(p.sev == pGetShortExpVector(p.p));
5660  strat->sevS[atS] = p.sev;
5661  strat->ecartS[atS] = p.ecart;
5662  strat->S_2_R[atS] = atR;
5663  strat->sl++;
5664}
5665
5666/*2
5667* puts p to the set T at position atT
5668*/
5669void enterT(LObject p, kStrategy strat, int atT)
5670{
5671  int i;
5672
5673  pp_Test(p.p, currRing, p.tailRing);
5674  assume(strat->tailRing == p.tailRing);
5675  // redMoraNF complains about this -- but, we don't really
5676  // neeed this so far
5677  assume(p.pLength == 0 || pLength(p.p) == p.pLength || rIsSyzIndexRing(currRing)); // modulo syzring
5678  assume(p.FDeg == p.pFDeg());
5679  assume(!p.is_normalized || nIsOne(pGetCoeff(p.p)));
5680
5681#ifdef KDEBUG
5682  // do not put an LObject twice into T:
5683  for(i=strat->tl;i>=0;i--)
5684  {
5685    if (p.p==strat->T[i].p)
5686    {
5687      printf("already in T at pos %d of %d, atT=%d\n",i,strat->tl,atT);
5688      return;
5689    }
5690  }
5691#endif
5692  strat->newt = TRUE;
5693  if (atT < 0)
5694    atT = strat->posInT(strat->T, strat->tl, p);
5695  if (strat->tl == strat->tmax-1)
5696    enlargeT(strat->T,strat->R,strat->sevT,strat->tmax,setmaxTinc);
5697  if (atT <= strat->tl)
5698  {
5699#ifdef ENTER_USE_MEMMOVE
5700    memmove(&(strat->T[atT+1]), &(strat->T[atT]),
5701            (strat->tl-atT+1)*sizeof(TObject));
5702    memmove(&(strat->sevT[atT+1]), &(strat->sevT[atT]),
5703            (strat->tl-atT+1)*sizeof(unsigned long));
5704#endif
5705    for (i=strat->tl+1; i>=atT+1; i--)
5706    {
5707#ifndef ENTER_USE_MEMMOVE
5708      strat->T[i] = strat->T[i-1];
5709      strat->sevT[i] = strat->sevT[i-1];
5710#endif
5711      strat->R[strat->T[i].i_r] = &(strat->T[i]);
5712    }
5713  }
5714
5715  if (strat->tailBin != NULL && (pNext(p.p) != NULL))
5716  {
5717    pNext(p.p)=p_ShallowCopyDelete(pNext(p.p),
5718                                   (strat->tailRing != NULL ?
5719                                    strat->tailRing : currRing),
5720                                   strat->tailBin);
5721    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
5722  }
5723  strat->T[atT] = (TObject) p;
5724
5725  if (strat->tailRing != currRing && pNext(p.p) != NULL)
5726    strat->T[atT].max = p_GetMaxExpP(pNext(p.p), strat->tailRing);
5727  else
5728    strat->T[atT].max = NULL;
5729
5730  strat->tl++;
5731  strat->R[strat->tl] = &(strat->T[atT]);
5732  strat->T[atT].i_r = strat->tl;
5733  assume(p.sev == 0 || pGetShortExpVector(p.p) == p.sev);
5734  strat->sevT[atT] = (p.sev == 0 ? pGetShortExpVector(p.p) : p.sev);
5735  kTest_T(&(strat->T[atT]));
5736}
5737
5738void initHilbCrit(ideal/*F*/, ideal /*Q*/, intvec **hilb,kStrategy strat)
5739{
5740  if (strat->homog!=isHomog)
5741  {
5742    *hilb=NULL;
5743  }
5744}
5745
5746void initBuchMoraCrit(kStrategy strat)
5747{
5748  strat->enterOnePair=enterOnePairNormal;
5749  strat->chainCrit=chainCritNormal;
5750#ifdef HAVE_RINGS
5751  if (rField_is_Ring(currRing))
5752  {
5753    strat->enterOnePair=enterOnePairRing;
5754    strat->chainCrit=chainCritRing;
5755  }
5756#endif
5757#ifdef HAVE_RATGRING
5758  if (rIsRatGRing(currRing))
5759  {
5760     strat->chainCrit=chainCritPart;
5761     /* enterOnePairNormal get rational part in it */
5762  }
5763#endif
5764
5765  strat->sugarCrit =        TEST_OPT_SUGARCRIT;
5766  strat->Gebauer =          strat->homog || strat->sugarCrit;
5767  strat->honey =            !strat->homog || strat->sugarCrit || TEST_OPT_WEIGHTM;
5768  if (TEST_OPT_NOT_SUGAR) strat->honey = FALSE;
5769  strat->pairtest = NULL;
5770  /* alway use tailreduction, except:
5771  * - in local rings, - in lex order case, -in ring over extensions */
5772  strat->noTailReduction = !TEST_OPT_REDTAIL;
5773
5774#ifdef HAVE_PLURAL
5775  // and r is plural_ring
5776  //  hence this holds for r a rational_plural_ring
5777  if( rIsPluralRing(currRing) || (rIsSCA(currRing) && !strat->z2homog) )
5778  {    //or it has non-quasi-comm type... later
5779    strat->sugarCrit = FALSE;
5780    strat->Gebauer = FALSE;
5781    strat->honey = FALSE;
5782  }
5783#endif
5784
5785#ifdef HAVE_RINGS
5786  // Coefficient ring?
5787  if (rField_is_Ring(currRing))
5788  {
5789    strat->sugarCrit = FALSE;
5790    strat->Gebauer = FALSE ;
5791    strat->honey = FALSE;
5792  }
5793#endif
5794  #ifdef KDEBUG
5795  if (TEST_OPT_DEBUG)
5796  {
5797    if (strat->homog) PrintS("ideal/module is homogeneous\n");
5798    else              PrintS("ideal/module is not homogeneous\n");
5799  }
5800  #endif
5801}
5802
5803BOOLEAN kPosInLDependsOnLength(int (*pos_in_l)
5804                               (const LSet set, const int length,
5805                                LObject* L,const kStrategy strat))
5806{
5807  if (pos_in_l == posInL110 ||
5808      pos_in_l == posInL10)
5809    return TRUE;
5810
5811  return FALSE;
5812}
5813
5814void initBuchMoraPos (kStrategy strat)
5815{
5816  if (currRing->OrdSgn==1)
5817  {
5818    if (strat->honey)
5819    {
5820      strat->posInL = posInL15;
5821      // ok -- here is the deal: from my experiments for Singular-2-0
5822      // I conclude that that posInT_EcartpLength is the best of
5823      // posInT15, posInT_EcartFDegpLength, posInT_FDegLength, posInT_pLength
5824      // see the table at the end of this file
5825      if (TEST_OPT_OLDSTD)
5826        strat->posInT = posInT15;
5827      else
5828        strat->posInT = posInT_EcartpLength;
5829    }
5830    else if (currRing->pLexOrder && !TEST_OPT_INTSTRATEGY)
5831    {
5832      strat->posInL = posInL11;
5833      strat->posInT = posInT11;
5834    }
5835    else if (TEST_OPT_INTSTRATEGY)
5836    {
5837      strat->posInL = posInL11;
5838      strat->posInT = posInT11;
5839    }
5840    else
5841    {
5842      strat->posInL = posInL0;
5843      strat->posInT = posInT0;
5844    }
5845    //if (strat->minim>0) strat->posInL =posInLSpecial;
5846    if (strat->homog)
5847    {
5848       strat->posInL = posInL110;
5849       strat->posInT = posInT110;
5850    }
5851  }
5852  else
5853  {
5854    if (strat->homog)
5855    {
5856      strat->posInL = posInL11;
5857      strat->posInT = posInT11;
5858    }
5859    else
5860    {
5861      if ((currRing->order[0]==ringorder_c)
5862      ||(currRing->order[0]==ringorder_C))
5863      {
5864        strat->posInL = posInL17_c;
5865        strat->posInT = posInT17_c;
5866      }
5867      else
5868      {
5869        strat->posInL = posInL17;
5870        strat->posInT = posInT17;
5871      }
5872    }
5873  }
5874  if (strat->minim>0) strat->posInL =posInLSpecial;
5875  // for further tests only
5876  if ((BTEST1(11)) || (BTEST1(12)))
5877    strat->posInL = posInL11;
5878  else if ((BTEST1(13)) || (BTEST1(14)))
5879    strat->posInL = posInL13;
5880  else if ((BTEST1(15)) || (BTEST1(16)))
5881    strat->posInL = posInL15;
5882  else if ((BTEST1(17)) || (BTEST1(18)))
5883    strat->posInL = posInL17;
5884  if (BTEST1(11))
5885    strat->posInT = posInT11;
5886  else if (BTEST1(13))
5887    strat->posInT = posInT13;
5888  else if (BTEST1(15))
5889    strat->posInT = posInT15;
5890  else if ((BTEST1(17)))
5891    strat->posInT = posInT17;
5892  else if ((BTEST1(19)))
5893    strat->posInT = posInT19;
5894  else if (BTEST1(12) || BTEST1(14) || BTEST1(16) || BTEST1(18))
5895    strat->posInT = posInT1;
5896#ifdef HAVE_RINGS
5897  if (rField_is_Ring(currRing))
5898  {
5899    strat->posInL = posInL11;
5900    strat->posInT = posInT11;
5901  }
5902#endif
5903  strat->posInLDependsOnLength = kPosInLDependsOnLength(strat->posInL);
5904}
5905
5906void initBuchMora (ideal F,ideal Q,kStrategy strat)
5907{
5908  strat->interpt = BTEST1(OPT_INTERRUPT);
5909  strat->kHEdge=NULL;
5910  if (currRing->OrdSgn==1) strat->kHEdgeFound=FALSE;
5911  /*- creating temp data structures------------------- -*/
5912  strat->cp = 0;
5913  strat->c3 = 0;
5914  strat->tail = pInit();
5915  /*- set s -*/
5916  strat->sl = -1;
5917  /*- set L -*/
5918  strat->Lmax = ((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc;
5919  strat->Ll = -1;
5920  strat->L = initL(((IDELEMS(F)+setmaxLinc-1)/setmaxLinc)*setmaxLinc);
5921  /*- set B -*/
5922  strat->Bmax = setmaxL;
5923  strat->Bl = -1;
5924  strat->B = initL();
5925  /*- set T -*/
5926  strat->tl = -1;
5927  strat->tmax = setmaxT;
5928  strat->T = initT();
5929  strat->R = initR();
5930  strat->sevT = initsevT();
5931  /*- init local data struct.---------------------------------------- -*/
5932  strat->P.ecart=0;
5933  strat->P.length=0;
5934  if (currRing->OrdSgn==-1)
5935  {
5936    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
5937    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
5938  }
5939  if(TEST_OPT_SB_1)
5940  {
5941    int i;
5942    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
5943    for (i=strat->newIdeal;i<IDELEMS(F);i++)
5944    {
5945      P->m[i-strat->newIdeal] = F->m[i];
5946      F->m[i] = NULL;
5947    }
5948    initSSpecial(F,Q,P,strat);
5949    for (i=strat->newIdeal;i<IDELEMS(F);i++)
5950    {
5951      F->m[i] = P->m[i-strat->newIdeal];
5952      P->m[i-strat->newIdeal] = NULL;
5953    }
5954    idDelete(&P);
5955  }
5956  else
5957  {
5958    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
5959    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
5960  }
5961  strat->fromT = FALSE;
5962  strat->noTailReduction = !TEST_OPT_REDTAIL;
5963  if (!TEST_OPT_SB_1)
5964  {
5965    updateS(TRUE,strat);
5966  }
5967  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
5968  strat->fromQ=NULL;
5969}
5970
5971void exitBuchMora (kStrategy strat)
5972{
5973  /*- release temp data -*/
5974  cleanT(strat);
5975  omFreeSize(strat->T,(strat->tmax)*sizeof(TObject));
5976  omFreeSize(strat->R,(strat->tmax)*sizeof(TObject*));
5977  omFreeSize(strat->sevT, (strat->tmax)*sizeof(unsigned long));
5978  omFreeSize(strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
5979  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
5980  omFreeSize(strat->S_2_R,IDELEMS(strat->Shdl)*sizeof(int));
5981  /*- set L: should be empty -*/
5982  omFreeSize(strat->L,(strat->Lmax)*sizeof(LObject));
5983  /*- set B: should be empty -*/
5984  omFreeSize(strat->B,(strat->Bmax)*sizeof(LObject));
5985  pLmDelete(&strat->tail);
5986  strat->syzComp=0;
5987}
5988
5989/*2
5990* in the case of a standardbase of a module over a qring:
5991* replace polynomials in i by ak vectors,
5992* (the polynomial * unit vectors gen(1)..gen(ak)
5993* in every case (also for ideals:)
5994* deletes divisible vectors/polynomials
5995*/
5996void updateResult(ideal r,ideal Q, kStrategy strat)
5997{
5998  int l;
5999  if (strat->ak>0)
6000  {
6001    for (l=IDELEMS(r)-1;l>=0;l--)
6002    {
6003      if ((r->m[l]!=NULL) && (pGetComp(r->m[l])==0))
6004      {
6005        pDelete(&r->m[l]); // and set it to NULL
6006      }
6007    }
6008    int q;
6009    poly p;
6010    for (l=IDELEMS(r)-1;l>=0;l--)
6011    {
6012      if ((r->m[l]!=NULL)
6013      //&& (strat->syzComp>0)
6014      //&& (pGetComp(r->m[l])<=strat->syzComp)
6015      )
6016      {
6017        for(q=IDELEMS(Q)-1; q>=0;q--)
6018        {
6019          if ((Q->m[q]!=NULL)
6020          &&(pLmDivisibleBy(Q->m[q],r->m[l])))
6021          {
6022            if (TEST_OPT_REDSB)
6023            {
6024              p=r->m[l];
6025              r->m[l]=kNF(Q,NULL,p);
6026              pDelete(&p);
6027            }
6028            else
6029            {
6030              pDelete(&r->m[l]); // and set it to NULL
6031            }
6032            break;
6033          }
6034        }
6035      }
6036    }
6037  }
6038  else
6039  {
6040    int q;
6041    poly p;
6042    BOOLEAN reduction_found=FALSE;
6043    for (l=IDELEMS(r)-1;l>=0;l--)
6044    {
6045      if (r->m[l]!=NULL)
6046      {
6047        for(q=IDELEMS(Q)-1; q>=0;q--)
6048        {
6049          if ((Q->m[q]!=NULL)
6050          &&(pLmEqual(r->m[l],Q->m[q])))
6051          {
6052            if (TEST_OPT_REDSB)
6053            {
6054              p=r->m[l];
6055              r->m[l]=kNF(Q,NULL,p);
6056              pDelete(&p);
6057              reduction_found=TRUE;
6058            }
6059            else
6060            {
6061              pDelete(&r->m[l]); // and set it to NULL
6062            }
6063            break;
6064          }
6065        }
6066      }
6067    }
6068    if (/*TEST_OPT_REDSB &&*/ reduction_found)
6069    {
6070      for (l=IDELEMS(r)-1;l>=0;l--)
6071      {
6072        if (r->m[l]!=NULL)
6073        {
6074          for(q=IDELEMS(r)-1;q>=0;q--)
6075          {
6076            if ((l!=q)
6077            && (r->m[q]!=NULL)
6078            &&(pLmDivisibleBy(r->m[l],r->m[q])))
6079            {
6080              pDelete(&r->m[q]);
6081            }
6082          }
6083        }
6084      }
6085    }
6086  }
6087  idSkipZeroes(r);
6088}
6089
6090void completeReduce (kStrategy strat, BOOLEAN withT)
6091{
6092  int i;
6093  int low = (((currRing->OrdSgn==1) && (strat->ak==0)) ? 1 : 0);
6094  LObject L;
6095
6096#ifdef KDEBUG
6097  // need to set this: during tailreductions of T[i], T[i].max is out of
6098  // sync
6099  sloppy_max = TRUE;
6100#endif
6101
6102  strat->noTailReduction = FALSE;
6103  if (TEST_OPT_PROT)
6104  {
6105    PrintLn();
6106    if (timerv) writeTime("standard base computed:");
6107  }
6108  if (TEST_OPT_PROT)
6109  {
6110    Print("(S:%d)",strat->sl);mflush();
6111  }
6112  for (i=strat->sl; i>=low; i--)
6113  {
6114    int end_pos=strat->sl;
6115    if ((strat->fromQ!=NULL) && (strat->fromQ[i])) continue; // do not reduce Q_i
6116    if (strat->ak==0) end_pos=i-1;
6117    TObject* T_j = strat->s_2_t(i);
6118    if ((T_j != NULL)&&(T_j->p==strat->S[i]))
6119    {
6120      L = *T_j;
6121      #ifdef KDEBUG
6122      if (TEST_OPT_DEBUG)
6123      {
6124        Print("test S[%d]:",i);
6125        p_wrp(L.p,currRing,strat->tailRing);
6126        PrintLn();
6127      }
6128      #endif
6129      if (currRing->OrdSgn == 1)
6130        strat->S[i] = redtailBba(&L, end_pos, strat, withT);
6131      else
6132        strat->S[i] = redtail(&L, strat->sl, strat);
6133      #ifdef KDEBUG
6134      if (TEST_OPT_DEBUG)
6135      {
6136        Print("to (tailR) S[%d]:",i);
6137        p_wrp(strat->S[i],currRing,strat->tailRing);
6138        PrintLn();
6139      }
6140      #endif
6141
6142      if (strat->redTailChange && strat->tailRing != currRing)
6143      {
6144        if (T_j->max != NULL) p_LmFree(T_j->max, strat->tailRing);
6145        if (pNext(T_j->p) != NULL)
6146          T_j->max = p_GetMaxExpP(pNext(T_j->p), strat->tailRing);
6147        else
6148          T_j->max = NULL;
6149      }
6150      if (TEST_OPT_INTSTRATEGY)
6151        T_j->pCleardenom();
6152    }
6153    else
6154    {
6155      assume(currRing == strat->tailRing);
6156      #ifdef KDEBUG
6157      if (TEST_OPT_DEBUG)
6158      {
6159        Print("test S[%d]:",i);
6160        p_wrp(strat->S[i],currRing,strat->tailRing);
6161        PrintLn();
6162      }
6163      #endif
6164      if (currRing->OrdSgn == 1)
6165        strat->S[i] = redtailBba(strat->S[i], end_pos, strat, withT);
6166      else
6167        strat->S[i] = redtail(strat->S[i], strat->sl, strat);
6168      if (TEST_OPT_INTSTRATEGY)
6169      {
6170        if (TEST_OPT_CONTENTSB)
6171        {
6172          number n;
6173          p_Cleardenom_n(strat->S[i], currRing, n);// also does a pContent
6174          if (!nIsOne(n))
6175          {
6176            denominator_list denom=(denominator_list)omAlloc(sizeof(denominator_list_s));
6177            denom->n=nInvers(n);
6178            denom->next=DENOMINATOR_LIST;
6179            DENOMINATOR_LIST=denom;
6180          }
6181          nDelete(&n);
6182        }
6183        else
6184        {
6185          //pContent(strat->S[i]);
6186          strat->S[i]=p_Cleardenom(strat->S[i], currRing);// also does a pContent
6187        }
6188      }
6189      #ifdef KDEBUG
6190      if (TEST_OPT_DEBUG)
6191      {
6192        Print("to (-tailR) S[%d]:",i);
6193        p_wrp(strat->S[i],currRing,strat->tailRing);
6194        PrintLn();
6195      }
6196      #endif
6197    }
6198    if (TEST_OPT_PROT)
6199      PrintS("-");
6200  }
6201  if (TEST_OPT_PROT) PrintLn();
6202#ifdef KDEBUG
6203  sloppy_max = FALSE;
6204#endif
6205}
6206
6207
6208/*2
6209* computes the new strat->kHEdge and the new pNoether,
6210* returns TRUE, if pNoether has changed
6211*/
6212BOOLEAN newHEdge(kStrategy strat)
6213{
6214  int i,j;
6215  poly newNoether;
6216
6217#if 0
6218  if (currRing->weight_all_1)
6219    scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
6220  else
6221    scComputeHCw(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
6222#else
6223  scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
6224#endif
6225  if (strat->t_kHEdge != NULL) p_LmFree(strat->t_kHEdge, strat->tailRing);
6226  if (strat->tailRing != currRing)
6227    strat->t_kHEdge = k_LmInit_currRing_2_tailRing(strat->kHEdge, strat->tailRing);
6228  /* compare old and new noether*/
6229  newNoether = pLmInit(strat->kHEdge);
6230  j = p_FDeg(newNoether,currRing);
6231  for (i=1; i<=(currRing->N); i++)
6232  {
6233    if (pGetExp(newNoether, i) > 0) pDecrExp(newNoether,i);
6234  }
6235  pSetm(newNoether);
6236  if (j < strat->HCord) /*- statistics -*/
6237  {
6238    if (TEST_OPT_PROT)
6239    {
6240      Print("H(%d)",j);
6241      mflush();
6242    }
6243    strat->HCord=j;
6244    #ifdef KDEBUG
6245    if (TEST_OPT_DEBUG)
6246    {
6247      Print("H(%d):",j);
6248      wrp(strat->kHEdge);
6249      PrintLn();
6250    }
6251    #endif
6252  }
6253  if (pCmp(strat->kNoether,newNoether)!=1)
6254  {
6255    pDelete(&strat->kNoether);
6256    strat->kNoether=newNoether;
6257    if (strat->t_kNoether != NULL) p_LmFree(strat->t_kNoether, strat->tailRing);
6258    if (strat->tailRing != currRing)
6259      strat->t_kNoether = k_LmInit_currRing_2_tailRing(strat->kNoether, strat->tailRing);
6260
6261    return TRUE;
6262  }
6263  pLmFree(newNoether);
6264  return FALSE;
6265}
6266
6267/***************************************************************
6268 *
6269 * Routines related for ring changes during std computations
6270 *
6271 ***************************************************************/
6272BOOLEAN kCheckSpolyCreation(LObject *L, kStrategy strat, poly &m1, poly &m2)
6273{
6274  if (strat->overflow) return FALSE;
6275  assume(L->p1 != NULL && L->p2 != NULL);
6276  // shift changes: from 0 to -1
6277  assume(L->i_r1 >= -1 && L->i_r1 <= strat->tl);
6278  assume(L->i_r2 >= -1 && L->i_r2 <= strat->tl);
6279  assume(strat->tailRing != currRing);
6280
6281  if (! k_GetLeadTerms(L->p1, L->p2, currRing, m1, m2, strat->tailRing))
6282    return FALSE;
6283  // shift changes: extra case inserted
6284  if ((L->i_r1 == -1) || (L->i_r2 == -1) )
6285  {
6286    return TRUE;
6287  }
6288  poly p1_max = (strat->R[L->i_r1])->max;
6289  poly p2_max = (strat->R[L->i_r2])->max;
6290
6291  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
6292      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
6293  {
6294    p_LmFree(m1, strat->tailRing);
6295    p_LmFree(m2, strat->tailRing);
6296    m1 = NULL;
6297    m2 = NULL;
6298    return FALSE;
6299  }
6300  return TRUE;
6301}
6302
6303#ifdef HAVE_RINGS
6304/***************************************************************
6305 *
6306 * Checks, if we can compute the gcd poly / strong pair
6307 * gcd-poly = m1 * R[atR] + m2 * S[atS]
6308 *
6309 ***************************************************************/
6310BOOLEAN kCheckStrongCreation(int atR, poly m1, int atS, poly m2, kStrategy strat)
6311{
6312  assume(strat->S_2_R[atS] >= -1 && strat->S_2_R[atS] <= strat->tl);
6313  //assume(strat->tailRing != currRing);
6314
6315  poly p1_max = (strat->R[atR])->max;
6316  poly p2_max = (strat->R[strat->S_2_R[atS]])->max;
6317
6318  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
6319      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
6320  {
6321    return FALSE;
6322  }
6323  return TRUE;
6324}
6325#endif
6326
6327BOOLEAN kStratChangeTailRing(kStrategy strat, LObject *L, TObject* T, unsigned long expbound)
6328{
6329  assume((strat->tailRing == currRing) || (strat->tailRing->bitmask < currRing->bitmask));
6330  /* initial setup or extending */
6331
6332  if (expbound == 0) expbound = strat->tailRing->bitmask << 1;
6333  if (expbound >= currRing->bitmask) return FALSE;
6334  strat->overflow=FALSE;
6335  ring new_tailRing = rModifyRing(currRing,
6336                                  // Hmmm .. the condition pFDeg == p_Deg
6337                                  // might be too strong
6338#ifdef HAVE_RINGS
6339                                  (strat->homog && currRing->pFDeg == p_Deg && !(rField_is_Ring(currRing))), // TODO Oliver
6340#else
6341                                  (strat->homog && currRing->pFDeg == p_Deg), // omit_degree
6342#endif
6343                                  (strat->ak==0), // omit_comp if the input is an ideal
6344                                  expbound); // exp_limit
6345
6346  if (new_tailRing == currRing) return TRUE;
6347
6348  strat->pOrigFDeg_TailRing = new_tailRing->pFDeg;
6349  strat->pOrigLDeg_TailRing = new_tailRing->pLDeg;
6350
6351  if (currRing->pFDeg != currRing->pFDegOrig)
6352  {
6353    new_tailRing->pFDeg = currRing->pFDeg;
6354    new_tailRing->pLDeg = currRing->pLDeg;
6355  }
6356
6357  if (TEST_OPT_PROT)
6358    Print("[%lu:%d", (unsigned long) new_tailRing->bitmask, new_tailRing->ExpL_Size);
6359  kTest_TS(strat);
6360  assume(new_tailRing != strat->tailRing);
6361  pShallowCopyDeleteProc p_shallow_copy_delete
6362    = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
6363
6364  omBin new_tailBin = omGetStickyBinOfBin(new_tailRing->PolyBin);
6365
6366  int i;
6367  for (i=0; i<=strat->tl; i++)
6368  {
6369    strat->T[i].ShallowCopyDelete(new_tailRing, new_tailBin,
6370                                  p_shallow_copy_delete);
6371  }
6372  for (i=0; i<=strat->Ll; i++)
6373  {
6374    assume(strat->L[i].p != NULL);
6375    if (pNext(strat->L[i].p) != strat->tail)
6376      strat->L[i].ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
6377  }
6378  if (strat->P.t_p != NULL ||
6379      (strat->P.p != NULL && pNext(strat->P.p) != strat->tail))
6380    strat->P.ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
6381
6382  if (L != NULL && L->tailRing != new_tailRing)
6383  {
6384    if (L->i_r < 0)
6385      L->ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
6386    else
6387    {
6388      assume(L->i_r <= strat->tl);
6389      TObject* t_l = strat->R[L->i_r];
6390      assume(t_l != NULL);
6391      L->tailRing = new_tailRing;
6392      L->p = t_l->p;
6393      L->t_p = t_l->t_p;
6394      L->max = t_l->max;
6395    }
6396  }
6397
6398  if (T != NULL && T->tailRing != new_tailRing && T->i_r < 0)
6399    T->ShallowCopyDelete(new_tailRing, new_tailBin, p_shallow_copy_delete);
6400
6401  omMergeStickyBinIntoBin(strat->tailBin, strat->tailRing->PolyBin);
6402  if (strat->tailRing != currRing)
6403    rKillModifiedRing(strat->tailRing);
6404
6405  strat->tailRing = new_tailRing;
6406  strat->tailBin = new_tailBin;
6407  strat->p_shallow_copy_delete
6408    = pGetShallowCopyDeleteProc(currRing, new_tailRing);
6409
6410  if (strat->kHEdge != NULL)
6411  {
6412    if (strat->t_kHEdge != NULL)
6413      p_LmFree(strat->t_kHEdge, strat->tailRing);
6414    strat->t_kHEdge=k_LmInit_currRing_2_tailRing(strat->kHEdge, new_tailRing);
6415  }
6416
6417  if (strat->kNoether != NULL)
6418  {
6419    if (strat->t_kNoether != NULL)
6420      p_LmFree(strat->t_kNoether, strat->tailRing);
6421    strat->t_kNoether=k_LmInit_currRing_2_tailRing(strat->kNoether,
6422                                                   new_tailRing);
6423  }
6424  kTest_TS(strat);
6425  if (TEST_OPT_PROT)
6426    PrintS("]");
6427  return TRUE;
6428}
6429
6430void kStratInitChangeTailRing(kStrategy strat)
6431{
6432  unsigned long l = 0;
6433  int i;
6434  long e;
6435
6436  assume(strat->tailRing == currRing);
6437
6438  for (i=0; i<= strat->Ll; i++)
6439  {
6440    l = p_GetMaxExpL(strat->L[i].p, currRing, l);
6441  }
6442  for (i=0; i<=strat->tl; i++)
6443  {
6444    // Hmm ... this we could do in one Step
6445    l = p_GetMaxExpL(strat->T[i].p, currRing, l);
6446  }
6447  if (rField_is_Ring(currRing))
6448  {
6449    l *= 2;
6450  }
6451  e = p_GetMaxExp(l, currRing);
6452  if (e <= 1) e = 2;
6453
6454  kStratChangeTailRing(strat, NULL, NULL, e);
6455}
6456
6457skStrategy::skStrategy()
6458{
6459  memset(this, 0, sizeof(skStrategy));
6460#ifndef NDEBUG
6461  strat_nr++;
6462  nr=strat_nr;
6463  if (strat_fac_debug) Print("s(%d) created\n",nr);
6464#endif
6465  tailRing = currRing;
6466  P.tailRing = currRing;
6467  tl = -1;
6468  sl = -1;
6469#ifdef HAVE_LM_BIN
6470  lmBin = omGetStickyBinOfBin(currRing->PolyBin);
6471#endif
6472#ifdef HAVE_TAIL_BIN
6473  tailBin = omGetStickyBinOfBin(currRing->PolyBin);
6474#endif
6475  pOrigFDeg = currRing->pFDeg;
6476  pOrigLDeg = currRing->pLDeg;
6477}
6478
6479
6480skStrategy::~skStrategy()
6481{
6482  if (lmBin != NULL)
6483    omMergeStickyBinIntoBin(lmBin, currRing->PolyBin);
6484  if (tailBin != NULL)
6485    omMergeStickyBinIntoBin(tailBin,
6486                            (tailRing != NULL ? tailRing->PolyBin:
6487                             currRing->PolyBin));
6488  if (t_kHEdge != NULL)
6489    p_LmFree(t_kHEdge, tailRing);
6490  if (t_kNoether != NULL)
6491    p_LmFree(t_kNoether, tailRing);
6492
6493  if (currRing != tailRing)
6494    rKillModifiedRing(tailRing);
6495  pRestoreDegProcs(currRing,pOrigFDeg, pOrigLDeg);
6496}
6497
6498#if 0
6499Timings for the different possibilities of posInT:
6500            T15           EDL         DL          EL            L         1-2-3
6501Gonnet      43.26       42.30       38.34       41.98       38.40      100.04
6502Hairer_2_1   1.11        1.15        1.04        1.22        1.08        4.7
6503Twomat3      1.62        1.69        1.70        1.65        1.54       11.32
6504ahml         4.48        4.03        4.03        4.38        4.96       26.50
6505c7          15.02       13.98       15.16       13.24       17.31       47.89
6506c8         505.09      407.46      852.76      413.21      499.19        n/a
6507f855        12.65        9.27       14.97        8.78       14.23       33.12
6508gametwo6    11.47       11.35       14.57       11.20       12.02       35.07
6509gerhard_3    2.73        2.83        2.93        2.64        3.12        6.24
6510ilias13     22.89       22.46       24.62       20.60       23.34       53.86
6511noon8       40.68       37.02       37.99       36.82       35.59      877.16
6512rcyclic_19  48.22       42.29       43.99       45.35       51.51      204.29
6513rkat9       82.37       79.46       77.20       77.63       82.54      267.92
6514schwarz_11  16.46       16.81       16.76       16.81       16.72       35.56
6515test016     16.39       14.17       14.40       13.50       14.26       34.07
6516test017     34.70       36.01       33.16       35.48       32.75       71.45
6517test042     10.76       10.99       10.27       11.57       10.45       23.04
6518test058      6.78        6.75        6.51        6.95        6.22        9.47
6519test066     10.71       10.94       10.76       10.61       10.56       19.06
6520test073     10.75       11.11       10.17       10.79        8.63       58.10
6521test086     12.23       11.81       12.88       12.24       13.37       66.68
6522test103      5.05        4.80        5.47        4.64        4.89       11.90
6523test154     12.96       11.64       13.51       12.46       14.61       36.35
6524test162     65.27       64.01       67.35       59.79       67.54      196.46
6525test164      7.50        6.50        7.68        6.70        7.96       17.13
6526virasoro     3.39        3.50        3.35        3.47        3.70        7.66
6527#endif
6528
6529
6530//#ifdef HAVE_MORE_POS_IN_T
6531#if 1
6532// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
6533int posInT_EcartFDegpLength(const TSet set,const int length,LObject &p)
6534{
6535
6536  if (length==-1) return 0;
6537
6538  int o = p.ecart;
6539  int op=p.GetpFDeg();
6540  int ol = p.GetpLength();
6541
6542  if (set[length].ecart < o)
6543    return length+1;
6544  if (set[length].ecart == o)
6545  {
6546     int oo=set[length].GetpFDeg();
6547     if ((oo < op) || ((oo==op) && (set[length].length < ol)))
6548       return length+1;
6549  }
6550
6551  int i;
6552  int an = 0;
6553  int en= length;
6554  loop
6555  {
6556    if (an >= en-1)
6557    {
6558      if (set[an].ecart > o)
6559        return an;
6560      if (set[an].ecart == o)
6561      {
6562         int oo=set[an].GetpFDeg();
6563         if((oo > op)
6564         || ((oo==op) && (set[an].pLength > ol)))
6565           return an;
6566      }
6567      return en;
6568    }
6569    i=(an+en) / 2;
6570    if (set[i].ecart > o)
6571      en=i;
6572    else if (set[i].ecart == o)
6573    {
6574       int oo=set[i].GetpFDeg();
6575       if ((oo > op)
6576       || ((oo == op) && (set[i].pLength > ol)))
6577         en=i;
6578       else
6579        an=i;
6580    }
6581    else
6582      an=i;
6583  }
6584}
6585
6586// determines the position based on: 1.) FDeg 2.) pLength
6587int posInT_FDegpLength(const TSet set,const int length,LObject &p)
6588{
6589
6590  if (length==-1) return 0;
6591
6592  int op=p.GetpFDeg();
6593  int ol = p.GetpLength();
6594
6595  int oo=set[length].GetpFDeg();
6596  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
6597    return length+1;
6598
6599  int i;
6600  int an = 0;
6601  int en= length;
6602  loop
6603    {
6604      if (an >= en-1)
6605      {
6606        int oo=set[an].GetpFDeg();
6607        if((oo > op)
6608           || ((oo==op) && (set[an].pLength > ol)))
6609          return an;
6610        return en;
6611      }
6612      i=(an+en) / 2;
6613      int oo=set[i].GetpFDeg();
6614      if ((oo > op)
6615          || ((oo == op) && (set[i].pLength > ol)))
6616        en=i;
6617      else
6618        an=i;
6619    }
6620}
6621
6622
6623// determines the position based on: 1.) pLength
6624int posInT_pLength(const TSet set,const int length,LObject &p)
6625{
6626  int ol = p.GetpLength();
6627  if (length==-1)
6628    return 0;
6629  if (set[length].length<p.length)
6630    return length+1;
6631
6632  int i;
6633  int an = 0;
6634  int en= length;
6635
6636  loop
6637  {
6638    if (an >= en-1)
6639    {
6640      if (set[an].pLength>ol) return an;
6641      return en;
6642    }
6643    i=(an+en) / 2;
6644    if (set[i].pLength>ol) en=i;
6645    else                        an=i;
6646  }
6647}
6648#endif
6649
6650// kstd1.cc:
6651int redFirst (LObject* h,kStrategy strat);
6652int redEcart (LObject* h,kStrategy strat);
6653void enterSMora (LObject p,int atS,kStrategy strat, int atR=-1);
6654void enterSMoraNF (LObject p,int atS,kStrategy strat, int atR=-1);
6655// ../Singular/misc.cc:
6656extern char *  showOption();
6657
6658void kDebugPrint(kStrategy strat)
6659{
6660  PrintS("red: ");
6661    if (strat->red==redFirst) PrintS("redFirst\n");
6662    else if (strat->red==redHoney) PrintS("redHoney\n");
6663    else if (strat->red==redEcart) PrintS("redEcart\n");
6664    else if (strat->red==redHomog) PrintS("redHomog\n");
6665    else  Print("%p\n",(void*)strat->red);
6666  PrintS("posInT: ");
6667    if (strat->posInT==posInT0) PrintS("posInT0\n");
6668    else if (strat->posInT==posInT0) PrintS("posInT0\n");
6669    else if (strat->posInT==posInT1) PrintS("posInT1\n");
6670    else if (strat->posInT==posInT11) PrintS("posInT11\n");
6671    else if (strat->posInT==posInT110) PrintS("posInT110\n");
6672    else if (strat->posInT==posInT13) PrintS("posInT13\n");
6673    else if (strat->posInT==posInT15) PrintS("posInT15\n");
6674    else if (strat->posInT==posInT17) PrintS("posInT17\n");
6675    else if (strat->posInT==posInT17_c) PrintS("posInT17_c\n");
6676    else if (strat->posInT==posInT19) PrintS("posInT19\n");
6677    else if (strat->posInT==posInT2) PrintS("posInT2\n");
6678#ifdef HAVE_MORE_POS_IN_T
6679    else if (strat->posInT==posInT_EcartFDegpLength) PrintS("posInT_EcartFDegpLength\n");
6680    else if (strat->posInT==posInT_FDegpLength) PrintS("posInT_FDegpLength\n");
6681    else if (strat->posInT==posInT_pLength) PrintS("posInT_pLength\n");
6682#endif
6683    else if (strat->posInT==posInT_EcartpLength) PrintS("posInT_EcartpLength\n");
6684    else if (strat->posInT==posInTrg0) PrintS("posInTrg0\n");
6685    else  Print("%p\n",(void*)strat->posInT);
6686  PrintS("posInL: ");
6687    if (strat->posInL==posInL0) PrintS("posInL0\n");
6688    else if (strat->posInL==posInL10) PrintS("posInL10\n");
6689    else if (strat->posInL==posInL11) PrintS("posInL11\n");
6690    else if (strat->posInL==posInL110) PrintS("posInL110\n");
6691    else if (strat->posInL==posInL13) PrintS("posInL13\n");
6692    else if (strat->posInL==posInL15) PrintS("posInL15\n");
6693    else if (strat->posInL==posInL17) PrintS("posInL17\n");
6694    else if (strat->posInL==posInL17_c) PrintS("posInL17_c\n");
6695    else if (strat->posInL==posInLSpecial) PrintS("posInLSpecial\n");
6696    else if (strat->posInL==posInLrg0) PrintS("posInLrg0\n");
6697    else  Print("%p\n",(void*)strat->posInL);
6698  PrintS("enterS: ");
6699    if (strat->enterS==enterSBba) PrintS("enterSBba\n");
6700    else if (strat->enterS==enterSMora) PrintS("enterSMora\n");
6701    else if (strat->enterS==enterSMoraNF) PrintS("enterSMoraNF\n");
6702    else  Print("%p\n",(void*)strat->enterS);
6703  PrintS("initEcart: ");
6704    if (strat->initEcart==initEcartBBA) PrintS("initEcartBBA\n");
6705    else if (strat->initEcart==initEcartNormal) PrintS("initEcartNormal\n");
6706    else  Print("%p\n",(void*)strat->initEcart);
6707  PrintS("initEcartPair: ");
6708    if (strat->initEcartPair==initEcartPairBba) PrintS("initEcartPairBba\n");
6709    else if (strat->initEcartPair==initEcartPairMora) PrintS("initEcartPairMora\n");
6710    else  Print("%p\n",(void*)strat->initEcartPair);
6711  Print("homog=%d, LazyDegree=%d, LazyPass=%d, ak=%d,\n",
6712         strat->homog, strat->LazyDegree,strat->LazyPass, strat->ak);
6713  Print("honey=%d, sugarCrit=%d, Gebauer=%d, noTailReduction=%d, use_buckets=%d\n",
6714         strat->honey,strat->sugarCrit,strat->Gebauer,strat->noTailReduction,strat->use_buckets);
6715  Print("posInLDependsOnLength=%d, use_buckets=%d\n",
6716         strat->posInLDependsOnLength,strat->use_buckets);
6717  PrintS(showOption());PrintLn();
6718  PrintS("LDeg: ");
6719    if (currRing->pLDeg==pLDeg0) PrintS("pLDeg0");
6720    else if (currRing->pLDeg==pLDeg0c) PrintS("pLDeg0c");
6721    else if (currRing->pLDeg==pLDegb) PrintS("pLDegb");
6722    else if (currRing->pLDeg==pLDeg1) PrintS("pLDeg1");
6723    else if (currRing->pLDeg==pLDeg1c) PrintS("pLDeg1c");
6724    else if (currRing->pLDeg==pLDeg1_Deg) PrintS("pLDeg1_Deg");
6725    else if (currRing->pLDeg==pLDeg1c_Deg) PrintS("pLDeg1c_Deg");
6726    else if (currRing->pLDeg==pLDeg1_Totaldegree) PrintS("pLDeg1_Totaldegree");
6727    else if (currRing->pLDeg==pLDeg1c_Totaldegree) PrintS("pLDeg1c_Totaldegree");
6728    else if (currRing->pLDeg==pLDeg1_WFirstTotalDegree) PrintS("pLDeg1_WFirstTotalDegree");
6729    else if (currRing->pLDeg==pLDeg1c_WFirstTotalDegree) PrintS("pLDeg1c_WFirstTotalDegree");
6730    else if (currRing->pLDeg==maxdegreeWecart) PrintS("maxdegreeWecart");
6731    else Print("? (%lx)", (long)currRing->pLDeg);
6732    PrintS(" / ");
6733    if (strat->tailRing->pLDeg==pLDeg0) PrintS("pLDeg0");
6734    else if (strat->tailRing->pLDeg==pLDeg0c) PrintS("pLDeg0c");
6735    else if (strat->tailRing->pLDeg==pLDegb) PrintS("pLDegb");
6736    else if (strat->tailRing->pLDeg==pLDeg1) PrintS("pLDeg1");
6737    else if (strat->tailRing->pLDeg==pLDeg1c) PrintS("pLDeg1c");
6738    else if (strat->tailRing->pLDeg==pLDeg1_Deg) PrintS("pLDeg1_Deg");
6739    else if (strat->tailRing->pLDeg==pLDeg1c_Deg) PrintS("pLDeg1c_Deg");
6740    else if (strat->tailRing->pLDeg==pLDeg1_Totaldegree) PrintS("pLDeg1_Totaldegree");
6741    else if (strat->tailRing->pLDeg==pLDeg1c_Totaldegree) PrintS("pLDeg1c_Totaldegree");
6742    else if (strat->tailRing->pLDeg==pLDeg1_WFirstTotalDegree) PrintS("pLDeg1_WFirstTotalDegree");
6743    else if (strat->tailRing->pLDeg==pLDeg1c_WFirstTotalDegree) PrintS("pLDeg1c_WFirstTotalDegree");
6744    else if (strat->tailRing->pLDeg==maxdegreeWecart) PrintS("maxdegreeWecart");
6745    else Print("? (%lx)", (long)strat->tailRing->pLDeg);
6746    PrintLn();
6747  PrintS("currRing->pFDeg: ");
6748    if (currRing->pFDeg==p_Totaldegree) PrintS("p_Totaldegree");
6749    else if (currRing->pFDeg==p_WFirstTotalDegree) PrintS("pWFirstTotalDegree");
6750    else if (currRing->pFDeg==p_Deg) PrintS("p_Deg");
6751    else if (currRing->pFDeg==kHomModDeg) PrintS("kHomModDeg");
6752    else if (currRing->pFDeg==totaldegreeWecart) PrintS("totaldegreeWecart");
6753    else Print("? (%lx)", (long)currRing->pFDeg);
6754    PrintLn();
6755    Print(" syzring:%d, syzComp(strat):%d limit:%d\n",rIsSyzIndexRing(currRing),strat->syzComp,rGetCurrSyzLimit(currRing));
6756    if(TEST_OPT_DEGBOUND)
6757      Print(" degBound: %d\n", Kstd1_deg);
6758
6759}
6760
6761
6762#ifdef HAVE_SHIFTBBA
6763poly pMove2CurrTail(poly p, kStrategy strat)
6764{
6765  /* assume: p is completely in currRing */
6766  /* produces an object with LM in curring
6767     and TAIL in tailring */
6768  if (pNext(p)!=NULL)
6769  {
6770    pNext(p) = prMoveR(pNext(p), /* src */ currRing, /* dest */ strat->tailRing);
6771  }
6772  return(p);
6773}
6774#endif
6775
6776#ifdef HAVE_SHIFTBBA
6777poly pMoveCurrTail2poly(poly p, kStrategy strat)
6778{
6779  /* assume: p has  LM in curring and TAIL in tailring */
6780  /* convert it to complete currRing */
6781
6782  /* check that LM is in currRing */
6783  assume(p_LmCheckIsFromRing(p, currRing));
6784
6785  if (pNext(p)!=NULL)
6786  {
6787    pNext(p) = prMoveR(pNext(p), /* src */ strat->tailRing, /* dest */currRing);
6788  }
6789  return(p);
6790}
6791#endif
6792
6793#ifdef HAVE_SHIFTBBA
6794poly pCopyL2p(LObject H, kStrategy strat)
6795{
6796    /* restores a poly in currRing from LObject */
6797    LObject h = H;
6798    h.Copy();
6799    poly p;
6800    if (h.p == NULL)
6801    {
6802      if (h.t_p != NULL)
6803      {
6804         p = prMoveR(h.t_p, /* source ring: */ strat->tailRing, /* dest. ring: */ currRing);
6805        return(p);
6806      }
6807      else
6808      {
6809        /* h.tp == NULL -> the object is NULL */
6810        return(NULL);
6811      }
6812    }
6813    /* we're here if h.p != NULL */
6814    if (h.t_p == NULL)
6815    {
6816       /* then h.p is the whole poly in currRing */
6817       p = h.p;
6818      return(p);
6819    }
6820    /* we're here if h.p != NULL and h.t_p != NULL */
6821    // clean h.p, get poly from t_p
6822     pNext(h.p)=NULL;
6823     pDelete(&h.p);
6824     p = prMoveR(h.t_p, /* source ring: */ strat->tailRing,
6825                         /* dest. ring: */ currRing);
6826     // no need to clean h: we re-used the polys
6827    return(p);
6828}
6829#endif
6830
6831//LObject pCopyp2L(poly p, kStrategy strat)
6832//{
6833    /* creates LObject from the poly in currRing */
6834  /* actually put p into L.p and make L.t_p=NULL : does not work */
6835
6836//}
6837
6838// poly pCopyL2p(LObject H, kStrategy strat)
6839// {
6840//   /* restores a poly in currRing from LObject */
6841//   LObject h = H;
6842//   h.Copy();
6843//   poly p;
6844//   if (h.p == NULL)
6845//   {
6846//     if (h.t_p != NULL)
6847//     {
6848//       p = p_ShallowCopyDelete(h.t_p, (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
6849//       return(p);
6850//     }
6851//     else
6852//     {
6853//       /* h.tp == NULL -> the object is NULL */
6854//       return(NULL);
6855//     }
6856//   }
6857//   /* we're here if h.p != NULL */
6858
6859//   if (h.t_p == NULL)
6860//   {
6861//     /* then h.p is the whole poly in tailRing */
6862//     if (strat->tailBin != NULL && (pNext(h.p) != NULL))
6863//     {
6864//       p = p_ShallowCopyDelete(h.p, (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
6865//     }
6866//     return(p);
6867//   }
6868//   /* we're here if h.p != NULL and h.t_p != NULL */
6869//   p = pCopy(pHead(h.p)); // in currRing
6870//   if (strat->tailBin != NULL && (pNext(h.p) != NULL))
6871//   {
6872//     //    pNext(p) = p_ShallowCopyDelete(pNext(h.t_p), (strat->tailRing != NULL ? strat->tailRing : currRing), strat->tailBin);
6873//     poly pp = p_Copy(pNext(h.p), strat->tailRing);
6874//     //    poly p3 = p_Copy(pNext(h.p), currRing); // error
6875//       // p_ShallowCopyDelete(pNext(h.p), currRing, strat->tailBin); // the same as pp
6876//     poly p5 = p_ShallowCopyDelete(pNext(h.p), strat->tailRing, strat->tailBin);
6877//     pNext(p) = p_ShallowCopyDelete(h.t_p, strat->tailRing, strat->tailBin);
6878//     poly p4 = p_Copy(h.t_p, strat->tailRing);
6879//     //    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
6880//   }
6881//   //  pTest(p);
6882//   return(p);
6883// }
6884
6885#ifdef HAVE_SHIFTBBA
6886/* including the self pairs */
6887void updateSShift(kStrategy strat,int uptodeg,int lV)
6888{
6889  /* to use after updateS(toT=FALSE,strat) */
6890  /* fills T with shifted elt's of S */
6891  int i;
6892  LObject h;
6893  int atT = -1; // or figure out smth better
6894  strat->tl = -1; // init
6895  for (i=0; i<=strat->sl; i++)
6896  {
6897    memset(&h,0,sizeof(h));
6898    h.p =  strat->S[i]; // lm in currRing, tail in TR
6899    strat->initEcart(&h);
6900    h.sev = strat->sevS[i];
6901    h.t_p = NULL;
6902    h.GetTP(); // creates correct t_p
6903    /*puts the elements of S with their shifts to T*/
6904    //    int atT, int uptodeg, int lV)
6905    strat->S_2_R[i] = strat->tl + 1; // the el't with shift 0 will be inserted first
6906    // need a small check for above; we insert >=1 elements
6907    // insert this check into kTest_TS ?
6908    enterTShift(h,strat,atT,uptodeg,lV);
6909  }
6910  /* what about setting strat->tl? */
6911}
6912#endif
6913
6914#ifdef HAVE_SHIFTBBA
6915void initBuchMoraShift (ideal F,ideal Q,kStrategy strat)
6916{
6917  strat->interpt = BTEST1(OPT_INTERRUPT);
6918  strat->kHEdge=NULL;
6919  if (currRing->OrdSgn==1) strat->kHEdgeFound=FALSE;
6920  /*- creating temp data structures------------------- -*/
6921  strat->cp = 0;
6922  strat->c3 = 0;
6923  strat->cv = 0;
6924  strat->tail = pInit();
6925  /*- set s -*/
6926  strat->sl = -1;
6927  /*- set L -*/
6928  strat->Lmax = setmaxL;
6929  strat->Ll = -1;
6930  strat->L = initL();
6931  /*- set B -*/
6932  strat->Bmax = setmaxL;
6933  strat->Bl = -1;
6934  strat->B = initL();
6935  /*- set T -*/
6936  strat->tl = -1;
6937  strat->tmax = setmaxT;
6938  strat->T = initT();
6939  strat->R = initR();
6940  strat->sevT = initsevT();
6941  /*- init local data struct.---------------------------------------- -*/
6942  strat->P.ecart=0;
6943  strat->P.length=0;
6944  if (currRing->OrdSgn==-1)
6945  {
6946    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
6947    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
6948  }
6949  if(TEST_OPT_SB_1)
6950  {
6951    int i;
6952    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
6953    for (i=strat->newIdeal;i<IDELEMS(F);i++)
6954    {
6955      P->m[i-strat->newIdeal] = F->m[i];
6956      F->m[i] = NULL;
6957    }
6958    initSSpecial(F,Q,P,strat);
6959    for (i=strat->newIdeal;i<IDELEMS(F);i++)
6960    {
6961      F->m[i] = P->m[i-strat->newIdeal];
6962      P->m[i-strat->newIdeal] = NULL;
6963    }
6964    idDelete(&P);
6965  }
6966  else
6967  {
6968    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
6969    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
6970  }
6971  strat->fromT = FALSE;
6972  strat->noTailReduction = !TEST_OPT_REDTAIL;
6973  if (!TEST_OPT_SB_1)
6974  {
6975    /* the only change: we do not fill the set T*/
6976    updateS(FALSE,strat);
6977  }
6978  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
6979  strat->fromQ=NULL;
6980  /* more changes: fill the set T with all the shifts of elts of S*/
6981  /* is done by other procedure */
6982}
6983#endif
6984
6985#ifdef HAVE_SHIFTBBA
6986/*1
6987* put the pairs (sh \dot s[i],p)  into the set B, ecart=ecart(p)
6988*/
6989void enterOnePairManyShifts (int i, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
6990{
6991  /* p comes from strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
6992
6993  assume(p_LmCheckIsFromRing(p,currRing));
6994  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
6995
6996  /* cycles through all shifts of s[i] until uptodeg - lastVblock(s[i]) */
6997  /* that is create the pairs (f, s \dot g)  */
6998
6999  poly qq = strat->S[i]; //  lm in currRing, tail in tailRing
7000
7001  //  poly q = pCopy(pHead(strat->S[i])); // lm in currRing
7002  //  pNext(q) = prCopyR(pNext(strat->S[i]),strat->tailRing,currRing); // zero shift
7003
7004 /* determine how many elements we have to insert for a given s[i] */
7005  /* x(0)y(1)z(2) : lastVblock-1=2, to add until lastVblock=uptodeg-1 */
7006  /* hence, a total number of elt's to add is: */
7007  /*  int toInsert = 1 + (uptodeg-1) - (pLastVblock(p.p, lV) -1);  */
7008  int toInsert =  itoInsert(qq, uptodeg,  lV, strat->tailRing);
7009
7010#ifdef KDEBUG
7011    if (TEST_OPT_DEBUG)
7012    {
7013      //      Print("entered ManyShifts: with toInsert=%d",toInsert); PrintLn();
7014    }
7015#endif
7016
7017  assume(i<=strat->sl); // from OnePair
7018  if (strat->interred_flag) return; // ?
7019
7020  /* these vars hold for all shifts of s[i] */
7021  int ecartq = 0; //Hans says it's ok; we're in the homog case, no ecart
7022
7023  int qfromQ;
7024  if (strat->fromQ != NULL)
7025  {
7026    qfromQ = strat->fromQ[i];
7027  }
7028  else
7029  {
7030    qfromQ = -1;
7031  }
7032
7033  int j;
7034
7035  poly q, s;
7036
7037  // for the 0th shift: insert the orig. pair
7038  enterOnePairShift(qq, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, 0, i, uptodeg, lV);
7039
7040  for (j=1; j<= toInsert; j++)
7041  {
7042    //    q = pLPshift(strat->S[i],j,uptodeg,lV);
7043    q = p_LPshiftT(qq, j, uptodeg, lV, strat, currRing);
7044    //    q = p_mLPshift(qq,j,uptodeg,lV,currRing); // lm in currRing, shift this monomial
7045    //    s = p_LPshift(pNext(qq), j, uptodeg, lV, strat->tailRing); // from tailRing
7046    //    pNext(q) = s; // in tailRing
7047    /* here we need to call enterOnePair with two polys ... */
7048
7049#ifdef KDEBUG
7050    if (TEST_OPT_DEBUG)
7051    {
7052      //      PrintS("ManyShifts: calling enterOnePairShift(q,p)");      PrintLn();
7053    }
7054#endif
7055    enterOnePairShift(q, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, i, uptodeg, lV);
7056  }
7057}
7058#endif
7059
7060#ifdef HAVE_SHIFTBBA
7061/*1
7062* put the pairs (sh \dot qq,p)  into the set B, ecart=ecart(p)
7063* despite the name, not only self shifts
7064*/
7065void enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
7066{
7067
7068  /* format: p,qq are in LObject form: lm in CR, tail in TR */
7069  /* for true self pairs qq ==p  */
7070  /* we test both qq and p */
7071  assume(p_LmCheckIsFromRing(qq,currRing));
7072  assume(p_CheckIsFromRing(pNext(qq),strat->tailRing));
7073  assume(p_LmCheckIsFromRing(p,currRing));
7074  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
7075
7076  /* since this proc is applied twice for (h, s*g) and (g,s*h), init j with 1 only */
7077
7078  //  int j = 0;
7079  int j = 1;
7080
7081  /* for such self pairs start with 1, not with 0 */
7082  if (qq == p) j=1;
7083
7084  /* should cycle through all shifts of q until uptodeg - lastVblock(q) */
7085  /* that is create the pairs (f, s \dot g)  */
7086
7087  int toInsert =  itoInsert(qq, uptodeg,  lV, strat->tailRing);
7088
7089#ifdef KDEBUG
7090    if (TEST_OPT_DEBUG)
7091    {
7092      //      Print("entered SelfShifts: with toInsert=%d",toInsert); PrintLn();
7093    }
7094#endif
7095
7096  poly q, s;
7097
7098  if (strat->interred_flag) return; // ?
7099
7100  /* these vars hold for all shifts of s[i] */
7101  int ecartq = 0; //Hans says it's ok; we're in the homog case, no ecart
7102  int qfromQ = 0; // strat->fromQ[i];
7103
7104  for (; j<= toInsert; j++)
7105  {
7106    //    q = pLPshift(strat->S[i],j,uptodeg,lV);
7107    /* we increase shifts by one; must delete q there*/
7108    //    q = qq; q = pMoveCurrTail2poly(q,strat);
7109    //    q = pLPshift(q,j,uptodeg,lV); //,currRing);
7110    q = p_LPshiftT(qq, j, uptodeg, lV, strat, currRing);
7111    //    q = p_mLPshift(qq,j,uptodeg,lV,currRing); // lm in currRing, shift this monomial
7112    //    s = p_LPshift(pNext(qq), j, uptodeg, lV, strat->tailRing); // from tailRing
7113    //    pNext(q) = s; // in tailRing
7114    /* here we need to call enterOnePair with two polys ... */
7115#ifdef KDEBUG
7116    if (TEST_OPT_DEBUG)
7117    {
7118      //      PrintS("SelfShifts: calling enterOnePairShift(q,p)");      PrintLn();
7119    }
7120#endif
7121    enterOnePairShift(q, p, ecart, isFromQ, strat, -1, ecartq, qfromQ, j, -1, uptodeg, lV);
7122  }
7123}
7124#endif
7125
7126#ifdef HAVE_SHIFTBBA
7127/*2
7128* put the pair (q,p)  into the set B, ecart=ecart(p), q is the shift of some s[i]
7129*/
7130void enterOnePairShift (poly q, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int ecartq, int qisFromQ, int shiftcount, int ifromS, int uptodeg, int lV)
7131{
7132
7133  /* Format: q and p are like strat->P.p, so lm in CR, tail in TR */
7134
7135  /* check this Formats: */
7136  assume(p_LmCheckIsFromRing(q,currRing));
7137  assume(p_CheckIsFromRing(pNext(q),strat->tailRing));
7138  assume(p_LmCheckIsFromRing(p,currRing));
7139  assume(p_CheckIsFromRing(pNext(p),strat->tailRing));
7140
7141#ifdef KDEBUG
7142    if (TEST_OPT_DEBUG)
7143    {
7144//       PrintS("enterOnePairShift(q,p) invoked with q = ");
7145//       wrp(q); //      wrp(pHead(q));
7146//       PrintS(", p = ");
7147//       wrp(p); //wrp(pHead(p));
7148//       PrintLn();
7149    }
7150#endif
7151
7152  /* poly q stays for s[i], ecartq = ecart(q), qisFromQ = applies to q */
7153
7154  int qfromQ = qisFromQ;
7155
7156  /* need additionally: int up_to_degree, poly V0 with the variables in (0)  or just the number lV = the length of the first block */
7157
7158  if (strat->interred_flag) return;
7159
7160  int      l,j,compare;
7161  LObject  Lp;
7162  Lp.i_r = -1;
7163
7164#ifdef KDEBUG
7165  Lp.ecart=0; Lp.length=0;
7166#endif
7167  /*- computes the lcm(s[i],p) -*/
7168  Lp.lcm = pInit();
7169
7170  pLcm(p,q, Lp.lcm); // q is what was strat->S[i], so a poly in LM/TR presentation
7171  pSetm(Lp.lcm);
7172
7173  /* apply the V criterion */
7174  if (!isInV(Lp.lcm, lV))
7175  {
7176#ifdef KDEBUG
7177    if (TEST_OPT_DEBUG)
7178    {
7179      PrintS("V crit applied to q = ");
7180      wrp(q); //      wrp(pHead(q));
7181      PrintS(", p = ");
7182      wrp(p); //wrp(pHead(p));
7183      PrintLn();
7184    }
7185#endif
7186    pLmFree(Lp.lcm);
7187    Lp.lcm=NULL;
7188    /* + counter for applying the V criterion */
7189    strat->cv++;
7190    return;
7191  }
7192
7193  if (strat->sugarCrit && ALLOW_PROD_CRIT(strat))
7194  {
7195    if((!((ecartq>0)&&(ecart>0)))
7196    && pHasNotCF(p,q))
7197    {
7198    /*
7199    *the product criterion has applied for (s,p),
7200    *i.e. lcm(s,p)=product of the leading terms of s and p.
7201    *Suppose (s,r) is in L and the leading term
7202    *of p divides lcm(s,r)
7203    *(==> the leading term of p divides the leading term of r)
7204    *but the leading term of s does not divide the leading term of r
7205    *(notice that this condition is automatically satisfied if r is still
7206    *in S), then (s,r) can be cancelled.
7207    *This should be done here because the
7208    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
7209    *
7210    *Moreover, skipping (s,r) holds also for the noncommutative case.
7211    */
7212      strat->cp++;
7213      pLmFree(Lp.lcm);
7214      Lp.lcm=NULL;
7215      return;
7216    }
7217    else
7218      Lp.ecart = si_max(ecart,ecartq);
7219    if (strat->fromT && (ecartq>ecart))
7220    {
7221      pLmFree(Lp.lcm);
7222      Lp.lcm=NULL;
7223      return;
7224      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
7225    }
7226    /*
7227    *the set B collects the pairs of type (S[j],p)
7228    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
7229    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
7230    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
7231    */
7232    {
7233      j = strat->Bl;
7234      loop
7235      {
7236        if (j < 0)  break;
7237        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
7238        if ((compare==1)
7239        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
7240        {
7241          strat->c3++;
7242          if ((strat->fromQ==NULL) || (isFromQ==0) || (qfromQ==0))
7243          {
7244            pLmFree(Lp.lcm);
7245            return;
7246          }
7247          break;
7248        }
7249        else
7250        if ((compare ==-1)
7251        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
7252        {
7253          deleteInL(strat->B,&strat->Bl,j,strat);
7254          strat->c3++;
7255        }
7256        j--;
7257      }
7258    }
7259  }
7260  else /*sugarcrit*/
7261  {
7262    if (ALLOW_PROD_CRIT(strat))
7263    {
7264      // if currRing->nc_type!=quasi (or skew)
7265      // TODO: enable productCrit for super commutative algebras...
7266      if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
7267      pHasNotCF(p,q))
7268      {
7269      /*
7270      *the product criterion has applied for (s,p),
7271      *i.e. lcm(s,p)=product of the leading terms of s and p.
7272      *Suppose (s,r) is in L and the leading term
7273      *of p devides lcm(s,r)
7274      *(==> the leading term of p devides the leading term of r)
7275      *but the leading term of s does not devide the leading term of r
7276      *(notice that tis condition is automatically satisfied if r is still
7277      *in S), then (s,r) can be canceled.
7278      *This should be done here because the
7279      *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
7280      */
7281          strat->cp++;
7282          pLmFree(Lp.lcm);
7283          Lp.lcm=NULL;
7284          return;
7285      }
7286      if (strat->fromT && (ecartq>ecart))
7287      {
7288        pLmFree(Lp.lcm);
7289        Lp.lcm=NULL;
7290        return;
7291        /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
7292      }
7293      /*
7294      *the set B collects the pairs of type (S[j],p)
7295      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
7296      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
7297      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
7298      */
7299      for(j = strat->Bl;j>=0;j--)
7300      {
7301        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
7302        if (compare==1)
7303        {
7304          strat->c3++;
7305          if ((strat->fromQ==NULL) || (isFromQ==0) || (qfromQ==0))
7306          {
7307            pLmFree(Lp.lcm);
7308            return;
7309          }
7310          break;
7311        }
7312        else
7313        if (compare ==-1)
7314        {
7315          deleteInL(strat->B,&strat->Bl,j,strat);
7316          strat->c3++;
7317        }
7318      }
7319    }
7320  }
7321  /*
7322  *the pair (S[i],p) enters B if the spoly != 0
7323  */
7324  /*-  compute the short s-polynomial -*/
7325  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
7326    pNorm(p);
7327  if ((q==NULL) || (p==NULL))
7328    return;
7329  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (qfromQ!=0))
7330    Lp.p=NULL;
7331  else
7332  {
7333//     if ( rIsPluralRing(currRing) )
7334//     {
7335//       if(pHasNotCF(p, q))
7336//       {
7337//         if(ncRingType(currRing) == nc_lie)
7338//         {
7339//             // generalized prod-crit for lie-type
7340//             strat->cp++;
7341//             Lp.p = nc_p_Bracket_qq(pCopy(p),q, currRing);
7342//         }
7343//         else
7344//         if( ALLOW_PROD_CRIT(strat) )
7345//         {
7346//             // product criterion for homogeneous case in SCA
7347//             strat->cp++;
7348//             Lp.p = NULL;
7349//         }
7350//         else
7351//           Lp.p = nc_CreateSpoly(q,p,currRing); // ?
7352//       }
7353//       else  Lp.p = nc_CreateSpoly(q,p,currRing);
7354//     }
7355//     else
7356//     {
7357
7358    /* ksCreateShortSpoly needs two Lobject-kind presentations */
7359    /* p is already in this form, so convert q */
7360    //    q = pMove2CurrTail(q, strat);
7361    Lp.p = ksCreateShortSpoly(q, p, strat->tailRing);
7362      //  }
7363  }
7364  if (Lp.p == NULL)
7365  {
7366    /*- the case that the s-poly is 0 -*/
7367    /* TEMPORARILY DISABLED FOR SHIFTS because there is no i*/
7368//      if (strat->pairtest==NULL) initPairtest(strat);
7369//      strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
7370//      strat->pairtest[strat->sl+1] = TRUE;
7371    /* END _ TEMPORARILY DISABLED FOR SHIFTS */
7372    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
7373    /*
7374    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
7375    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
7376    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
7377    *term of p devides the lcm(s,r)
7378    *(this canceling should be done here because
7379    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
7380    *the first case is handeled in chainCrit
7381    */
7382    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
7383  }
7384  else
7385  {
7386    /*- the pair (S[i],p) enters B -*/
7387    /* both of them should have their LM in currRing and TAIL in tailring */
7388    Lp.p1 = q;  // already in the needed form
7389    Lp.p2 = p; // already in the needed form
7390
7391    if ( !rIsPluralRing(currRing) )
7392      pNext(Lp.p) = strat->tail;
7393
7394    /* TEMPORARILY DISABLED FOR SHIFTS because there's no i*/
7395    /* at the beginning we DO NOT set atR = -1 ANYMORE*/
7396    if ( (atR >= 0) && (shiftcount==0) && (ifromS >=0) )
7397    {
7398      Lp.i_r1 = kFindInT(Lp.p1,strat); //strat->S_2_R[ifromS];
7399      Lp.i_r2 = atR;
7400    }
7401    else
7402    {
7403      /* END _ TEMPORARILY DISABLED FOR SHIFTS */
7404      Lp.i_r1 = -1;
7405      Lp.i_r2 = -1;
7406     }
7407    strat->initEcartPair(&Lp,q,p,ecartq,ecart);
7408
7409    if (TEST_OPT_INTSTRATEGY)
7410    {
7411      if (!rIsPluralRing(currRing))
7412        nDelete(&(Lp.p->coef));
7413    }
7414
7415    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
7416    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
7417  }
7418}
7419#endif
7420
7421#ifdef HAVE_SHIFTBBA
7422/*2
7423*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
7424*superfluous elements in S will be deleted
7425*/
7426void enterpairsShift (poly h,int k,int ecart,int pos,kStrategy strat, int atR,int uptodeg, int lV)
7427{
7428  /* h is strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
7429  /* Q: what is exactly the strat->fromT ? A: a local case trick; don't need it yet*/
7430  int j=pos;
7431
7432#ifdef HAVE_RINGS
7433  assume (!rField_is_Ring(currRing));
7434#endif
7435  initenterpairsShift(h,k,ecart,0,strat, atR,uptodeg,lV);
7436  if ( (!strat->fromT)
7437  && ((strat->syzComp==0)
7438    ||(pGetComp(h)<=strat->syzComp)))
7439  {
7440    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
7441    unsigned long h_sev = pGetShortExpVector(h);
7442    loop
7443    {
7444      if (j > k) break;
7445      clearS(h,h_sev, &j,&k,strat);
7446      j++;
7447    }
7448    //Print("end clearS sl=%d\n",strat->sl);
7449  }
7450 // PrintS("end enterpairs\n");
7451}
7452#endif
7453
7454#ifdef HAVE_SHIFTBBA
7455/*3
7456*(s[0], s \dot h),...,(s[k],s \dot h) will be put to the pairset L
7457* also the pairs (h, s\dot s[0]), ..., (h, s\dot s[k]) enter L
7458* additionally we put the pairs (h, s \sdot h) for s>=1 to L
7459*/
7460void initenterpairsShift (poly h,int k,int ecart,int isFromQ, kStrategy strat, int atR, int uptodeg, int lV)
7461{
7462  /* h comes from strat->P.p, that is LObject with LM in currRing and Tail in tailRing */
7463  //  atR = -1;
7464  if ((strat->syzComp==0)
7465  || (pGetComp(h)<=strat->syzComp))
7466  {
7467    int j;
7468    BOOLEAN new_pair=FALSE;
7469
7470    if (pGetComp(h)==0)
7471    {
7472      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
7473      if ((isFromQ)&&(strat->fromQ!=NULL))
7474      {
7475        for (j=0; j<=k; j++)
7476        {
7477          if (!strat->fromQ[j])
7478          {
7479            new_pair=TRUE;
7480            enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR,uptodeg,lV);
7481            // other side pairs:
7482            enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
7483          //Print("j:%d, Ll:%d\n",j,strat->Ll);
7484          }
7485        }
7486      }
7487      else
7488      {
7489        new_pair=TRUE;
7490        for (j=0; j<=k; j++)
7491        {
7492          enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR,uptodeg,lV);
7493          // other side pairs
7494          enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
7495        }
7496        /* HERE we put (h, s*h) pairs */
7497       /* enterOnePairSelfShifts (poly qq, poly p, int ecart, int isFromQ, kStrategy strat, int atR, int uptodeg, int lV); */
7498       enterOnePairSelfShifts (h, h, ecart, isFromQ, strat, atR, uptodeg, lV);
7499      }
7500    }
7501    else
7502    {
7503      for (j=0; j<=k; j++)
7504      {
7505        if ((pGetComp(h)==pGetComp(strat->S[j]))
7506        || (pGetComp(strat->S[j])==0))
7507        {
7508          new_pair=TRUE;
7509          enterOnePairManyShifts(j,h,ecart,isFromQ,strat, atR, uptodeg, lV);
7510          // other side pairs
7511          enterOnePairSelfShifts(h,strat->S[j],ecart,isFromQ,strat, atR,uptodeg,lV);
7512        //Print("j:%d, Ll:%d\n",j,strat->Ll);
7513        }
7514      }
7515      /* HERE we put (h, s*h) pairs */
7516      enterOnePairSelfShifts (h, h, ecart, isFromQ, strat, atR, uptodeg, lV);
7517    }
7518
7519    if (new_pair)
7520    {
7521      strat->chainCrit(h,ecart,strat);
7522    }
7523
7524  }
7525}
7526#endif
7527
7528#ifdef HAVE_SHIFTBBA
7529/*2
7530* puts p to the set T, starting with the at position atT
7531* and inserts all admissible shifts of p
7532*/
7533void enterTShift(LObject p, kStrategy strat, int atT, int uptodeg, int lV)
7534{
7535  /* determine how many elements we have to insert */
7536  /* x(0)y(1)z(2) : lastVblock-1=2, to add until lastVblock=uptodeg-1 */
7537  /* hence, a total number of elt's to add is: */
7538  /*  int toInsert = 1 + (uptodeg-1) - (pLastVblock(p.p, lV) -1);  */
7539
7540  int toInsert =  itoInsert(p.p, uptodeg,  lV, strat->tailRing);
7541
7542#ifdef PDEBUG
7543  //  Print("enterTShift uses toInsert: %d", toInsert);  PrintLn();
7544#endif
7545  int i;
7546
7547  if (atT < 0)
7548    atT = strat->posInT(strat->T, strat->tl, p);
7549
7550  /* can call enterT in a sequence, e.g. */
7551
7552  /* shift0 = it's our model for further shifts */
7553  enterT(p,strat,atT);
7554  LObject qq;
7555  for (i=1; i<=toInsert; i++) // toIns - 1?
7556  {
7557    qq      = p; //qq.Copy();
7558    qq.p    = NULL;
7559    qq.max  = NULL;
7560    qq.t_p = p_LPshift(p_Copy(p.t_p,strat->tailRing), i, uptodeg, lV, strat->tailRing); // direct shift
7561    qq.GetP();
7562    // update q.sev
7563    qq.sev = pGetShortExpVector(qq.p);
7564    /* enter it into T, first el't is with the shift 0 */
7565    // compute the position for qq
7566    atT = strat->posInT(strat->T, strat->tl, qq);
7567    enterT(qq,strat,atT);
7568  }
7569/* Q: what to do with this one in the orig enterT ? */
7570/*  strat->R[strat->tl] = &(strat->T[atT]); */
7571/* Solution: it is done by enterT each time separately */
7572}
7573#endif
7574
7575#ifdef HAVE_SHIFTBBA
7576poly redtailBbaShift (LObject* L, int pos, kStrategy strat, BOOLEAN withT, BOOLEAN normalize)
7577{
7578  /* for the shift case need to run it with withT = TRUE */
7579  strat->redTailChange=FALSE;
7580  if (strat->noTailReduction) return L->GetLmCurrRing();
7581  poly h, p;
7582  p = h = L->GetLmTailRing();
7583  if ((h==NULL) || (pNext(h)==NULL))
7584    return L->GetLmCurrRing();
7585
7586  TObject* With;
7587  // placeholder in case strat->tl < 0
7588  TObject  With_s(strat->tailRing);
7589
7590  LObject Ln(pNext(h), strat->tailRing);
7591  Ln.pLength = L->GetpLength() - 1;
7592
7593  pNext(h) = NULL;
7594  if (L->p != NULL) pNext(L->p) = NULL;
7595  L->pLength = 1;
7596
7597  Ln.PrepareRed(strat->use_buckets);
7598
7599  while(!Ln.IsNull())
7600  {
7601    loop
7602    {
7603      Ln.SetShortExpVector();
7604      if (withT)
7605      {
7606        int j;
7607        j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
7608        if (j < 0) break;
7609        With = &(strat->T[j]);
7610      }
7611      else
7612      {
7613        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
7614        if (With == NULL) break;
7615      }
7616      if (normalize && (!TEST_OPT_INTSTRATEGY) && (!nIsOne(pGetCoeff(With->p))))
7617      {
7618        With->pNorm();
7619        //if (TEST_OPT_PROT) { PrintS("n"); mflush(); }
7620      }
7621      strat->redTailChange=TRUE;
7622      if (ksReducePolyTail(L, With, &Ln))
7623      {
7624        // reducing the tail would violate the exp bound
7625        //  set a flag and hope for a retry (in bba)
7626        strat->completeReduce_retry=TRUE;
7627        if ((Ln.p != NULL) && (Ln.t_p != NULL)) Ln.p=NULL;
7628        do
7629        {
7630          pNext(h) = Ln.LmExtractAndIter();
7631          pIter(h);
7632          L->pLength++;
7633        } while (!Ln.IsNull());
7634        goto all_done;
7635      }
7636      if (Ln.IsNull()) goto all_done;
7637      if (! withT) With_s.Init(currRing);
7638    }
7639    pNext(h) = Ln.LmExtractAndIter();
7640    pIter(h);
7641    L->pLength++;
7642  }
7643
7644  all_done:
7645  Ln.Delete();
7646  if (L->p != NULL) pNext(L->p) = pNext(p);
7647
7648  if (strat->redTailChange)
7649  {
7650    L->last = NULL;
7651    L->length = 0;
7652  }
7653  L->Normalize(); // HANNES: should have a test
7654  kTest_L(L);
7655  return L->GetLmCurrRing();
7656}
7657#endif
Note: See TracBrowser for help on using the repository browser.