source: git/kernel/kutil.cc @ 268ece

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