source: git/kernel/kutil.cc @ f0d4069

spielwiese
Last change on this file since f0d4069 was f0d4069, checked in by Oliver Wienand <wienand@…>, 17 years ago
[oliver] kutil.cc, polys.cc, ringgb.cc: * clean up git-svn-id: file:///usr/local/Singular/svn/trunk@9197 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 126.5 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: kutil.cc,v 1.26 2006-06-12 00:35:13 wienand Exp $ */
5/*
6* ABSTRACT: kernel: utils for kStd
7*/
8
9#ifndef KUTIL_CC
10#define KUTIL_CC
11
12// #define PDEBUG 2
13// #define PDIV_DEBUG
14#include <stdlib.h>
15#include <string.h>
16#include "mod2.h"
17#include <mylimits.h>
18#include "structs.h"
19#ifdef HAVE_PLURAL
20#include "gring.h"
21#endif
22#ifdef KDEBUG
23#undef KDEBUG
24#define KDEBUG 2
25#endif
26
27// define if enterL, enterT should use memmove instead of doing it manually
28// on topgun, this is slightly faster (see monodromy_l.tst, homog_gonnet.sing)
29#ifndef SunOS_4
30#define ENTER_USE_MEMMOVE
31#endif
32
33// define, if the my_memmove inlines should be used instead of
34// system memmove -- it does not seem to pay off, though
35// #define ENTER_USE_MYMEMMOVE
36
37#include "kutil.h"
38#include "febase.h"
39#include "omalloc.h"
40#include "numbers.h"
41#include "polys.h"
42#include "ring.h"
43#include "ideals.h"
44#include "timer.h"
45//#include "cntrlc.h"
46#include "stairc.h"
47#include "kstd1.h"
48#include "pShallowCopyDelete.h"
49
50#ifdef KDEBUG
51#undef KDEBUG
52#define KDEBUG 2
53#endif
54#define pDivComp_EQUAL 2
55#define pDivComp_LESS 1
56#define pDivComp_GREATER -1
57#define pDivComp_INCOMP 0
58
59
60#ifdef ENTER_USE_MYMEMMOVE
61inline void _my_memmove_d_gt_s(unsigned long* d, unsigned long* s, long l)
62{
63  register unsigned long* _dl = (unsigned long*) d;
64  register unsigned long* _sl = (unsigned long*) s;
65  register long _i = l - 1;
66
67  do
68  {
69    _dl[_i] = _sl[_i];
70    _i--;
71  }
72  while (_i >= 0);
73}
74
75inline void _my_memmove_d_lt_s(unsigned long* d, unsigned long* s, long l)
76{
77  register long _ll = l;
78  register unsigned long* _dl = (unsigned long*) d;
79  register unsigned long* _sl = (unsigned long*) s;
80  register long _i = 0;
81
82  do
83  {
84    _dl[_i] = _sl[_i];
85    _i++;
86  }
87  while (_i < _ll);
88}
89
90inline void _my_memmove(void* d, void* s, long l)
91{
92  unsigned long _d = (unsigned long) d;
93  unsigned long _s = (unsigned long) s;
94  unsigned long _l = ((l) + SIZEOF_LONG - 1) >> LOG_SIZEOF_LONG;
95
96  if (_d > _s) _my_memmove_d_gt_s(_d, _s, _l);
97  else _my_memmove_d_lt_s(_d, _s, _l);
98}
99
100#undef memmove
101#define memmove(d,s,l) _my_memmove(d, s, l)
102#endif
103
104static poly redMora (poly h,int maxIndex,kStrategy strat);
105static poly redBba (poly h,int maxIndex,kStrategy strat);
106
107/* Checks the relation of LM(p) and LM(q)
108     LM(p) = LM(q) => return pDivComp_EQUAL
109     LM(p) | LM(q) => return pDivComp_LESS
110     LM(q) | LM(p) => return pDivComp_GREATER
111     else return pDivComp_INCOMP */
112static inline int pDivComp(poly p, poly q)
113{
114  if (pGetComp(p) == pGetComp(q))
115  {
116    BOOLEAN a=FALSE, b=FALSE;
117    int i;
118    unsigned long la, lb;
119    unsigned long divmask = currRing->divmask;
120    for (i=0; i<currRing->VarL_Size; i++)
121    {
122      la = p->exp[currRing->VarL_Offset[i]];
123      lb = q->exp[currRing->VarL_Offset[i]];
124      if (la != lb)
125      {
126        if (la < lb)
127        {
128          if (b) return 0;
129          if (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask))
130            return 0;
131          a = TRUE;
132        }
133        else
134        {
135          if (a) return 0;
136          if (((la & divmask) ^ (lb & divmask)) != ((la - lb) & divmask))
137            return 0;
138          b = TRUE;
139        }
140      }
141    }
142    if (a) return 1;
143    if (b) return -1;
144    if (!a & !b) return pDivComp_EQUAL;
145  }
146  return 0;
147}
148
149
150BITSET  test=(BITSET)0;
151int     HCord;
152int     Kstd1_deg;
153int     mu=32000;
154
155/*2
156*deletes higher monomial of p, re-compute ecart and length
157*works only for orderings with ecart =pFDeg(end)-pFDeg(start)
158*/
159void deleteHC(LObject *L, kStrategy strat, BOOLEAN fromNext)
160{
161  if (strat->kHEdgeFound)
162  {
163    kTest_L(L);
164    poly p1;
165    poly p = L->GetLmTailRing();
166    int l = 1;
167    kBucket_pt bucket = NULL;
168    if (L->bucket != NULL)
169    {
170      kBucketClear(L->bucket, &pNext(p), &L->pLength);
171      L->pLength++;
172      bucket = L->bucket;
173      L->bucket = NULL;
174      L->last = NULL;
175    }
176
177    if (!fromNext && p_Cmp(p,strat->kNoetherTail(), L->tailRing) == -1)
178    {
179      L->Delete();
180      L->Clear();
181      L->ecart = -1;
182      if (bucket != NULL) kBucketDestroy(&bucket);
183      return;
184    }
185    p1 = p;
186    while (pNext(p1)!=NULL)
187    {
188      if (p_LmCmp(pNext(p1), strat->kNoetherTail(), L->tailRing) == -1)
189      {
190        L->last = p1;
191        p_Delete(&pNext(p1), L->tailRing);
192        if (p1 == p)
193        {
194          if (L->t_p != NULL)
195          {
196            assume(L->p != NULL && p == L->t_p);
197            pNext(L->p) = NULL;
198          }
199          L->max  = NULL;
200        }
201        else if (fromNext)
202          L->max  = p_GetMaxExpP(pNext(L->p), L->tailRing ); // p1;
203        if (L->pLength != 0) L->pLength = l;
204        // Hmmm when called from updateT, then only
205        // reset ecart when cut
206        if (fromNext)
207          L->ecart = L->pLDeg() - L->GetpFDeg();
208        break;
209      }
210      l++;
211      pIter(p1);
212    }
213    if (! fromNext)
214    {
215      L->SetpFDeg();
216      L->ecart = L->pLDeg(strat->LDegLast) - L->GetpFDeg();
217    }
218    if (bucket != NULL)
219    {
220      if (L->pLength > 1)
221      {
222        kBucketInit(bucket, pNext(p), L->pLength - 1);
223        pNext(p) = NULL;
224        if (L->t_p != NULL) pNext(L->t_p) = NULL;
225        L->pLength = 0;
226        L->bucket = bucket;
227        L->last = NULL;
228      }
229      else
230        kBucketDestroy(&bucket);
231    }
232    kTest_L(L);
233  }
234}
235
236void deleteHC(poly* p, int* e, int* l,kStrategy strat)
237{
238  LObject L(*p, currRing, strat->tailRing);
239
240  deleteHC(&L, strat);
241  *p = L.p;
242  *e = L.ecart;
243  *l = L.length;
244  if (L.t_p != NULL) p_LmFree(L.t_p, strat->tailRing);
245}
246
247/*2
248*tests if p.p=monomial*unit and cancels the unit
249*/
250void cancelunit (LObject* L)
251{
252  int  i;
253  poly h;
254
255  if(currRing->OrdSgn != -1) return;
256  if(TEST_OPT_CANCELUNIT) return;
257
258  ring r = L->tailRing;
259  poly p = L->GetLmTailRing();
260
261  if(p_GetComp(p, r) != 0 && !p_OneComp(p, r)) return;
262
263  if (L->ecart != 0)
264  {
265//    for(i=r->N;i>0;i--)
266//    {
267//      if ((p_GetExp(p,i,r)>0) && (rIsPolyVar(i, r)==TRUE)) return;
268//    }
269    h = pNext(p);
270    loop
271    {
272      if (h==NULL)
273      {
274        p_Delete(&pNext(p), r);
275        number eins=nInit(1);
276        if (L->p != NULL)  pSetCoeff(L->p,eins);
277        else if (L->t_p != NULL) nDelete(&pGetCoeff(L->t_p));
278        if (L->t_p != NULL) pSetCoeff0(L->t_p,eins);
279        L->ecart = 0;
280        L->length = 1;
281        if (L->pLength > 0) L->pLength = 1;
282        if (L->last != NULL) L->last = p;
283
284        if (L->t_p != NULL && pNext(L->t_p) != NULL)
285          pNext(L->t_p) = NULL;
286        if (L->p != NULL && pNext(L->p) != NULL)
287          pNext(L->p) = NULL;
288        return;
289      }
290      i = 0;
291      loop
292      {
293        i++;
294        if (p_GetExp(p,i,r) > p_GetExp(h,i,r)) return ; // does not divide
295        if (i == r->N) break; // does divide, try next monom
296      }
297      pIter(h);
298    }
299  }
300}
301
302/*2
303*pp is the new element in s
304*returns TRUE (in strat->kHEdgeFound) if
305*-HEcke is allowed
306*-we are in the last componente of the vector
307*-on all axis are monomials (all elements in NotUsedAxis are FALSE)
308*returns FALSE for pLexOrderings,
309*assumes in module case an ordering of type c* !!
310* HEckeTest is only called with strat->kHEdgeFound==FALSE !
311*/
312void HEckeTest (poly pp,kStrategy strat)
313{
314  int   j,k,p;
315
316  strat->kHEdgeFound=FALSE;
317  if (pLexOrder || currRing->MixedOrder)
318  {
319    return;
320  }
321  if (strat->ak > 1)           /*we are in the module case*/
322  {
323    return; // until ....
324    //if (!pVectorOut)     /*pVectorOut <=> order = c,* */
325    //  return FALSE;
326    //if (pGetComp(pp) < strat->ak) /* ak is the number of the last component */
327    //  return FALSE;
328  }
329  k = 0;
330  p=pIsPurePower(pp);
331  if (p!=0) strat->NotUsedAxis[p] = FALSE;
332  /*- the leading term of pp is a power of the p-th variable -*/
333  for (j=pVariables;j>0; j--)
334  {
335    if (strat->NotUsedAxis[j])
336    {
337      return;
338    }
339  }
340  strat->kHEdgeFound=TRUE;
341}
342
343/*2
344*utilities for TSet, LSet
345*/
346inline static intset initec (const int maxnr)
347{
348  return (intset)omAlloc(maxnr*sizeof(int));
349}
350
351inline static unsigned long* initsevS (const int maxnr)
352{
353  return (unsigned long*)omAlloc0(maxnr*sizeof(unsigned long));
354}
355inline static int* initS_2_R (const int maxnr)
356{
357  return (int*)omAlloc0(maxnr*sizeof(int));
358}
359
360static inline void enlargeT (TSet &T, TObject** &R, unsigned long* &sevT,
361                             int &length, const int incr)
362{
363  assume(T!=NULL);
364  assume(sevT!=NULL);
365  assume(R!=NULL);
366  assume((length+incr) > 0);
367
368  int i;
369  T = (TSet)omRealloc0Size(T, length*sizeof(TObject),
370                           (length+incr)*sizeof(TObject));
371
372  sevT = (unsigned long*) omReallocSize(sevT, length*sizeof(long*),
373                           (length+incr)*sizeof(long*));
374
375  R = (TObject**)omRealloc0Size(R,length*sizeof(TObject*),
376                                (length+incr)*sizeof(TObject*));
377  for (i=length-1;i>=0;i--) R[T[i].i_r] = &(T[i]);
378  length += incr;
379}
380
381void cleanT (kStrategy strat)
382{
383  int i,j;
384  poly  p;
385  assume(currRing == strat->tailRing || strat->tailRing != NULL);
386
387  pShallowCopyDeleteProc p_shallow_copy_delete =
388    (strat->tailRing != currRing ?
389     pGetShallowCopyDeleteProc(strat->tailRing, currRing) :
390     NULL);
391
392  for (j=0; j<=strat->tl; j++)
393  {
394    p = strat->T[j].p;
395    strat->T[j].p=NULL;
396    if (strat->T[j].max != NULL)
397      p_LmFree(strat->T[j].max, strat->tailRing);
398    i = -1;
399    loop
400    {
401      i++;
402      if (i>strat->sl)
403      {
404        if (strat->T[j].t_p != NULL)
405        {
406          p_Delete(&(strat->T[j].t_p), strat->tailRing);
407          p_LmFree(p, currRing);
408        }
409        else
410          pDelete(&p);
411        break;
412      }
413      if (p == strat->S[i])
414      {
415        if (strat->T[j].t_p != NULL)
416        {
417          assume(p_shallow_copy_delete != NULL);
418          pNext(p) = p_shallow_copy_delete(pNext(p),strat->tailRing,currRing,
419                                           currRing->PolyBin);
420          p_LmFree(strat->T[j].t_p, strat->tailRing);
421        }
422        break;
423      }
424    }
425  }
426  strat->tl=-1;
427}
428
429//LSet initL ()
430//{
431//  int i;
432//  LSet l = (LSet)omAlloc(setmaxL*sizeof(LObject));
433//  return l;
434//}
435
436static inline void enlargeL (LSet* L,int* length,const int incr)
437{
438  assume((*L)!=NULL);
439  assume((length+incr)>0);
440
441  *L = (LSet)omReallocSize((*L),(*length)*sizeof(LObject),
442                                   ((*length)+incr)*sizeof(LObject));
443  (*length) += incr;
444}
445
446void initPairtest(kStrategy strat)
447{
448  strat->pairtest = (BOOLEAN *)omAlloc0((strat->sl+2)*sizeof(BOOLEAN));
449}
450
451#ifdef HAVE_RING2TOM
452//void initLMtest(kStrategy strat)
453//{
454//  strat->lmtest = (unsigned int *)omAlloc0((strat->sl*strat->sl/2+2)*sizeof(BOOLEAN));
455//}
456#endif
457
458/*2
459*test whether (p1,p2) or (p2,p1) is in L up position length
460*it returns TRUE if yes and the position k
461*/
462BOOLEAN isInPairsetL(int length,poly p1,poly p2,int*  k,kStrategy strat)
463{
464  LObject *p=&(strat->L[length]);
465
466  *k = length;
467  loop
468  {
469    if ((*k) < 0) return FALSE;
470    if (((p1 == (*p).p1) && (p2 == (*p).p2))
471    ||  ((p1 == (*p).p2) && (p2 == (*p).p1)))
472      return TRUE;
473    (*k)--;
474    p--;
475  }
476}
477
478/*2
479*in B all pairs have the same element p on the right
480*it tests whether (q,p) is in B and returns TRUE if yes
481*and the position k
482*/
483BOOLEAN isInPairsetB(poly q,int*  k,kStrategy strat)
484{
485  LObject *p=&(strat->B[strat->Bl]);
486
487  *k = strat->Bl;
488  loop
489  {
490    if ((*k) < 0) return FALSE;
491    if (q == (*p).p1)
492      return TRUE;
493    (*k)--;
494    p--;
495  }
496}
497
498int kFindInT(poly p, TSet T, int tlength)
499{
500  int i;
501
502  for (i=0; i<=tlength; i++)
503  {
504    if (T[i].p == p) return i;
505  }
506  return -1;
507}
508
509int kFindInT(poly p, kStrategy strat)
510{
511  int i;
512  do
513  {
514    i = kFindInT(p, strat->T, strat->tl);
515    if (i >= 0) return i;
516    strat = strat->next;
517  }
518  while (strat != NULL);
519  return -1;
520}
521
522#ifdef KDEBUG
523
524void sTObject::wrp()
525{
526  if (t_p != NULL) p_wrp(t_p, tailRing);
527  else if (p != NULL) p_wrp(p, currRing, tailRing);
528  else ::wrp(NULL);
529}
530
531#define kFalseReturn(x) do { if (!x) return FALSE;} while (0)
532
533// check that Lm's of a poly from T are "equal"
534static const char* kTest_LmEqual(poly p, poly t_p, ring tailRing)
535{
536  int i;
537  for (i=1; i<=tailRing->N; i++)
538  {
539    if (p_GetExp(p, i, currRing) != p_GetExp(t_p, i, tailRing))
540      return "Lm[i] different";
541  }
542  if (p_GetComp(p, currRing) != p_GetComp(t_p, tailRing))
543    return "Lm[0] different";
544  if (pNext(p) != pNext(t_p))
545    return "Lm.next different";
546  if (pGetCoeff(p) != pGetCoeff(t_p))
547    return "Lm.coeff different";
548  return NULL;
549}
550
551static BOOLEAN sloppy_max = FALSE;
552BOOLEAN kTest_T(TObject * T, ring strat_tailRing, int i, char TN)
553{
554  ring tailRing = T->tailRing;
555  if (strat_tailRing == NULL) strat_tailRing = tailRing;
556  r_assume(strat_tailRing == tailRing);
557
558  poly p = T->p;
559  ring r = currRing;
560
561  if (T->p == NULL && T->t_p == NULL && i >= 0)
562    return dReportError("%c[%d].poly is NULL", TN, i);
563
564  if (T->tailRing != currRing)
565  {
566    if (T->t_p == NULL && i > 0)
567      return dReportError("%c[%d].t_p is NULL", TN, i);
568    pFalseReturn(p_Test(T->t_p, T->tailRing));
569    if (T->p != NULL) pFalseReturn(p_LmTest(T->p, currRing));
570    if (T->p != NULL && T->t_p != NULL)
571    {
572      const char* msg = kTest_LmEqual(T->p, T->t_p, T->tailRing);
573      if (msg != NULL)
574        return dReportError("%c[%d] %s", TN, i, msg);
575      r = T->tailRing;
576      p = T->t_p;
577    }
578    if (T->p == NULL)
579    {
580      p = T->t_p;
581      r = T->tailRing;
582    }
583    if (T->t_p != NULL && i >= 0 && TN == 'T')
584    {
585      if (pNext(T->t_p) == NULL)
586      {
587        if (T->max != NULL)
588          return dReportError("%c[%d].max is not NULL as it should be", TN, i);
589      }
590      else
591      {
592        if (T->max == NULL)
593          return dReportError("%c[%d].max is NULL", TN, i);
594        if (pNext(T->max) != NULL)
595          return dReportError("pNext(%c[%d].max) != NULL", TN, i);
596
597        pFalseReturn(p_CheckPolyRing(T->max, tailRing));
598        omCheckBinAddrSize(T->max, (tailRing->PolyBin->sizeW)*SIZEOF_LONG);
599#if KDEBUG > 0
600        if (! sloppy_max)
601        {
602          poly test_max = p_GetMaxExpP(pNext(T->t_p), tailRing);
603          p_Setm(T->max, tailRing);
604          p_Setm(test_max, tailRing);
605          BOOLEAN equal = p_ExpVectorEqual(T->max, test_max, tailRing);
606          if (! equal)
607            return dReportError("%c[%d].max out of sync", TN, i);
608          p_LmFree(test_max, tailRing);
609        }
610#endif
611      }
612    }
613  }
614  else
615  {
616    if (T->max != NULL)
617      return dReportError("%c[%d].max != NULL but tailRing == currRing",TN,i);
618    if (T->t_p != NULL)
619      return dReportError("%c[%d].t_p != NULL but tailRing == currRing",TN,i);
620    if (T->p == NULL && i > 0)
621      return dReportError("%c[%d].p is NULL", TN, i);
622    pFalseReturn(p_Test(T->p, currRing));
623  }
624
625  if (i >= 0 && T->pLength != 0 && T->pLength != pLength(p))
626  {
627    return dReportError("%c[%d] pLength error: has %d, specified to have %d",
628                        TN, i , pLength(p), T->pLength);
629  }
630
631  // check FDeg,  for elements in L and T
632  if (i >= 0 && (TN == 'T' || TN == 'L'))
633  {
634    // FDeg has ir element from T of L set
635    if (T->FDeg  != T->pFDeg())
636      return dReportError("%c[%d] FDeg error: has %d, specified to have %d",
637                          TN, i , T->pFDeg(), T->FDeg);
638  }
639
640  // check is_normalized for elements in T
641  if (i >= 0 && TN == 'T')
642  {
643    if (T->is_normalized && ! nIsOne(pGetCoeff(p)))
644      return dReportError("T[%d] is_normalized error", i);
645
646  }
647  return TRUE;
648}
649
650BOOLEAN kTest_L(LObject *L, ring strat_tailRing,
651                BOOLEAN testp, int lpos, TSet T, int tlength)
652{
653  if (testp)
654  {
655    poly pn = NULL;
656    if (L->bucket != NULL)
657    {
658      kFalseReturn(kbTest(L->bucket));
659      r_assume(L->bucket->bucket_ring == L->tailRing);
660      if (L->p != NULL && pNext(L->p) != NULL)
661      {
662        pn = pNext(L->p);
663        pNext(L->p) = NULL;
664      }
665    }
666    kFalseReturn(kTest_T(L, strat_tailRing, lpos, 'L'));
667    if (pn != NULL)
668      pNext(L->p) = pn;
669
670    ring r;
671    poly p;
672    L->GetLm(p, r);
673    if (L->sev != 0 && p_GetShortExpVector(p, r) != L->sev)
674    {
675      return dReportError("L[%d] wrong sev: has %o, specified to have %o",
676                          lpos, p_GetShortExpVector(p, r), L->sev);
677    }
678    if (lpos > 0 && L->last != NULL && pLast(p) != L->last)
679    {
680      return dReportError("L[%d] last wrong: has %p specified to have %p",
681                          lpos, pLast(p), L->last);
682    }
683  }
684  if (L->p1 == NULL)
685  {
686    // L->p2 either NULL or "normal" poly
687    pFalseReturn(pp_Test(L->p2, currRing, L->tailRing));
688  }
689  else if (tlength > 0 && T != NULL && (lpos >=0))
690  {
691    // now p1 and p2 must be != NULL and must be contained in T
692    int i;
693    i = kFindInT(L->p1, T, tlength);
694    if (i < 0)
695      return dReportError("L[%d].p1 not in T",lpos);
696    i = kFindInT(L->p2, T, tlength);
697    if (i < 0)
698      return dReportError("L[%d].p2 not in T",lpos);
699  }
700  return TRUE;
701}
702
703BOOLEAN kTest (kStrategy strat)
704{
705  int i;
706
707  // test P
708  kFalseReturn(kTest_L(&(strat->P), strat->tailRing,
709                       (strat->P.p != NULL && pNext(strat->P.p)!=strat->tail),
710                       -1, strat->T, strat->tl));
711
712  // test T
713  if (strat->T != NULL)
714  {
715    for (i=0; i<=strat->tl; i++)
716    {
717      kFalseReturn(kTest_T(&(strat->T[i]), strat->tailRing, i, 'T'));
718      if (strat->sevT[i] != pGetShortExpVector(strat->T[i].p))
719        return dReportError("strat->sevT[%d] out of sync", i);
720    }
721  }
722
723  // test L
724  if (strat->L != NULL)
725  {
726    for (i=0; i<=strat->Ll; i++)
727    {
728      kFalseReturn(kTest_L(&(strat->L[i]), strat->tailRing,
729                           strat->L[i].Next() != strat->tail, i,
730                           strat->T, strat->tl));
731      if (strat->use_buckets && strat->L[i].Next() != strat->tail &&
732          strat->L[i].Next() != NULL && strat->L[i].p1 != NULL)
733      {
734        assume(strat->L[i].bucket != NULL);
735      }
736    }
737  }
738
739  // test S
740  if (strat->S != NULL)
741    kFalseReturn(kTest_S(strat));
742
743  return TRUE;
744}
745
746BOOLEAN kTest_S(kStrategy strat)
747{
748  int i;
749  BOOLEAN ret = TRUE;
750  for (i=0; i<=strat->sl; i++)
751  {
752    if (strat->S[i] != NULL &&
753        strat->sevS[i] != pGetShortExpVector(strat->S[i]))
754    {
755      return dReportError("S[%d] wrong sev: has %o, specified to have %o",
756                          i , pGetShortExpVector(strat->S[i]), strat->sevS[i]);
757    }
758  }
759  return ret;
760}
761
762
763
764BOOLEAN kTest_TS(kStrategy strat)
765{
766  int i, j;
767  BOOLEAN ret = TRUE;
768  kFalseReturn(kTest(strat));
769
770  // test strat->R, strat->T[i].i_r
771  for (i=0; i<=strat->tl; i++)
772  {
773    if (strat->T[i].i_r < 0 || strat->T[i].i_r > strat->tl)
774      return dReportError("strat->T[%d].i_r == %d out of bounds", i,
775                          strat->T[i].i_r);
776    if (strat->R[strat->T[i].i_r] != &(strat->T[i]))
777      return dReportError("T[%d].i_r with R out of sync", i);
778  }
779  // test containment of S inT
780  if (strat->S != NULL)
781  {
782    for (i=0; i<=strat->sl; i++)
783    {
784      j = kFindInT(strat->S[i], strat->T, strat->tl);
785      if (j < 0)
786        return dReportError("S[%d] not in T", i);
787      if (strat->S_2_R[i] != strat->T[j].i_r)
788        return dReportError("S_2_R[%d]=%d != T[%d].i_r=%d\n",
789                            i, strat->S_2_R[i], j, strat->T[j].i_r);
790    }
791  }
792  // test strat->L[i].i_r1
793  for (i=0; i<=strat->Ll; i++)
794  {
795    if (strat->L[i].p1 != NULL && strat->L[i].p2)
796    {
797      if (strat->L[i].i_r1 < 0 ||
798          strat->L[i].i_r1 > strat->tl ||
799          strat->L[i].T_1(strat)->p != strat->L[i].p1)
800        return dReportError("L[%d].i_r1 out of sync", i);
801      if (strat->L[i].i_r2 < 0 ||
802          strat->L[i].i_r2 > strat->tl ||
803          strat->L[i].T_2(strat)->p != strat->L[i].p2);
804    }
805    else
806    {
807      if (strat->L[i].i_r1 != -1)
808        return dReportError("L[%d].i_r1 out of sync", i);
809      if (strat->L[i].i_r2 != -1)
810        return dReportError("L[%d].i_r2 out of sync", i);
811    }
812    if (strat->L[i].i_r != -1)
813      return dReportError("L[%d].i_r out of sync", i);
814  }
815  return TRUE;
816}
817
818#endif // KDEBUG
819
820/*2
821*cancels the i-th polynomial in the standardbase s
822*/
823void deleteInS (int i,kStrategy strat)
824{
825#ifdef ENTER_USE_MEMMOVE
826  memmove(&(strat->S[i]), &(strat->S[i+1]), (strat->sl - i)*sizeof(poly));
827  memmove(&(strat->ecartS[i]),&(strat->ecartS[i+1]),(strat->sl - i)*sizeof(int));
828  memmove(&(strat->sevS[i]),&(strat->sevS[i+1]),(strat->sl - i)*sizeof(long));
829  memmove(&(strat->S_2_R[i]),&(strat->S_2_R[i+1]),(strat->sl - i)*sizeof(int));
830#else
831  int j;
832  for (j=i; j<strat->sl; j++)
833  {
834    strat->S[j] = strat->S[j+1];
835    strat->ecartS[j] = strat->ecartS[j+1];
836    strat->sevS[j] = strat->sevS[j+1];
837    strat->S_2_R[j] = strat->S_2_R[j+1];
838  }
839#endif
840  if (strat->lenS!=NULL)
841  {
842#ifdef ENTER_USE_MEMMOVE
843    memmove(&(strat->lenS[i]),&(strat->lenS[i+1]),(strat->sl - i)*sizeof(int));
844#else
845    for (j=i; j<strat->sl; j++) strat->lenS[j] = strat->lenS[j+1];
846#endif
847  }
848  if (strat->lenSw!=NULL)
849  {
850#ifdef ENTER_USE_MEMMOVE
851    memmove(&(strat->lenSw[i]),&(strat->lenSw[i+1]),(strat->sl - i)*sizeof(wlen_type));
852#else
853    for (j=i; j<strat->sl; j++) strat->lenSw[j] = strat->lenSw[j+1];
854#endif
855  }
856  if (strat->fromQ!=NULL)
857  {
858#ifdef ENTER_USE_MEMMOVE
859    memmove(&(strat->fromQ[i]),&(strat->fromQ[i+1]),(strat->sl - i)*sizeof(int));
860#else
861    for (j=i; j<strat->sl; j++)
862    {
863      strat->fromQ[j] = strat->fromQ[j+1];
864    }
865#endif
866  }
867  strat->S[strat->sl] = NULL;
868  strat->sl--;
869}
870
871/*2
872*cancels the j-th polynomial in the set
873*/
874void deleteInL (LSet set, int *length, int j,kStrategy strat)
875{
876  if (set[j].lcm!=NULL)
877    pLmFree(set[j].lcm);
878  if (set[j].p!=NULL)
879  {
880    if (pNext(set[j].p) == strat->tail)
881    {
882      pLmFree(set[j].p);
883      /*- tail belongs to several int spolys -*/
884    }
885    else
886    {
887      // search p in T, if it is there, do not delete it
888      if (pOrdSgn != -1 || kFindInT(set[j].p, strat) < 0)
889      {
890        // assure that for global ordereings kFindInT fails
891        assume(pOrdSgn == -1 || kFindInT(set[j].p, strat) < 0);
892        set[j].Delete();
893      }
894    }
895  }
896  if (*length > 0 && j < *length)
897  {
898#ifdef ENTER_USE_MEMMOVE
899    memmove(&(set[j]), &(set[j+1]), (*length - j)*sizeof(LObject));
900#else
901    int i;
902    for (i=j; i < (*length); i++)
903      set[i] = set[i+1];
904#endif
905  }
906#ifdef KDEBUG
907  memset(&(set[*length]),0,sizeof(LObject));
908#endif
909  (*length)--;
910}
911
912/*2
913*is used after updating the pairset,if the leading term of p
914*divides the leading term of some S[i] it will be canceled
915*/
916static inline void clearS (poly p, unsigned long p_sev, int* at, int* k,
917                    kStrategy strat)
918{
919  assume(p_sev == pGetShortExpVector(p));
920  if (strat->noClearS) return;
921  if (!pLmShortDivisibleBy(p,p_sev, strat->S[*at], ~ strat->sevS[*at])) return;
922  deleteInS((*at),strat);
923  (*at)--;
924  (*k)--;
925}
926
927/*2
928*enters p at position at in L
929*/
930#ifdef PDEBUG
931/* int zaehler=0; */
932/* for counting number of pairs in Plural */
933#endif /*PDEBUG*/
934
935void enterL (LSet *set,int *length, int *LSetmax, LObject p,int at)
936{
937#ifdef PDEBUG
938  /*  zaehler++; */
939#endif /*PDEBUG*/
940  int i;
941  // this should be corrected
942  assume(p.FDeg == p.pFDeg());
943
944  if ((*length)>=0)
945  {
946    if ((*length) == (*LSetmax)-1) enlargeL(set,LSetmax,setmaxLinc);
947    if (at <= (*length))
948#ifdef ENTER_USE_MEMMOVE
949      memmove(&((*set)[at+1]), &((*set)[at]), ((*length)-at+1)*sizeof(LObject));
950#else
951    for (i=(*length)+1; i>=at+1; i--) (*set)[i] = (*set)[i-1];
952#endif
953  }
954  else at = 0;
955  (*set)[at] = p;
956  (*length)++;
957}
958
959/*2
960* computes the normal ecart;
961* used in mora case and if pLexOrder & sugar in bba case
962*/
963void initEcartNormal (LObject* h)
964{
965  h->FDeg = h->pFDeg();
966  h->ecart = h->pLDeg() - h->FDeg;
967}
968
969void initEcartBBA (LObject* h)
970{
971  h->FDeg = h->pFDeg();
972  (*h).ecart = 0;
973  (*h).length = 0;
974}
975
976void initEcartPairBba (LObject* Lp,poly f,poly g,int ecartF,int ecartG)
977{
978  Lp->FDeg = Lp->pFDeg();
979  (*Lp).ecart = 0;
980  (*Lp).length = 0;
981}
982
983void initEcartPairMora (LObject* Lp,poly f,poly g,int ecartF,int ecartG)
984{
985  Lp->FDeg = Lp->pFDeg();
986  (*Lp).ecart = si_max(ecartF,ecartG);
987  (*Lp).ecart = (*Lp).ecart- (Lp->FDeg -pFDeg((*Lp).lcm,currRing));
988  (*Lp).length = 0;
989}
990
991/*2
992*if ecart1<=ecart2 it returns TRUE
993*/
994BOOLEAN sugarDivisibleBy(int ecart1, int ecart2)
995{
996  return (ecart1 <= ecart2);
997}
998
999#ifdef HAVE_RING2TOM
1000/* TODO move to numbers.cc
1001 */
1002inline int nComp(long a, long b)
1003{
1004  assume(a != 0 && b != 0);
1005  while (a % 2 == 0 && b % 2 == 0)
1006  {
1007    a = a / 2;
1008    b = b / 2;
1009  }
1010  if (a % 2 == 0)
1011  {
1012    return -1;
1013  }
1014  else
1015  {
1016    if (b % 2 == 1)
1017    {
1018      return 0;
1019    }
1020    else
1021    {
1022      return 1;
1023    }
1024  }
1025}
1026
1027/*2
1028* put the pair (s[i],p)  into the set B, ecart=ecart(p) (ring case)
1029*/
1030void enterOnePairRing (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
1031{
1032  assume(i<=strat->sl);
1033  int      l,j,compare,compareCoeff;
1034  LObject  Lp;
1035
1036  if (strat->interred_flag) return;
1037#ifdef KDEBUG
1038  Lp.ecart=0; Lp.length=0;
1039#endif
1040  /*- computes the lcm(s[i],p) -*/
1041  Lp.lcm = pInit();
1042
1043  pLcm(p,strat->S[i],Lp.lcm);
1044  pSetm(Lp.lcm);
1045  pSetCoeff(Lp.lcm, nLcm(pGetCoeff(p), pGetCoeff(strat->S[i]), currRing));
1046  assume(!strat->sugarCrit);
1047  // basic product criterion
1048  if (pHasNotCF(p,strat->S[i]) && (long) pGetCoeff(p) % 2 == 1 && (long) pGetCoeff(strat->S[i]) % 2 == 1)
1049  {
1050      strat->cp++;
1051      pLmFree(Lp.lcm);
1052      Lp.lcm=NULL;
1053      return;
1054  }
1055  assume(!strat->fromT);
1056  /*
1057  *the set B collects the pairs of type (S[j],p)
1058  *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p) != lcm(r,p)
1059  *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1060  *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1061  */
1062  for(j = strat->Bl;j>=0;j--)
1063  {
1064    compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1065    compareCoeff = nComp((long) pGetCoeff(strat->B[j].lcm), (long) pGetCoeff(Lp.lcm));
1066    if (compareCoeff == 0 || compare == compareCoeff)
1067    {
1068      if (compare == 1)
1069      {
1070        strat->c3++;
1071        if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1072        {
1073          pLmFree(Lp.lcm);
1074          return;
1075        }
1076        break;
1077      }
1078      else
1079      if (compare == -1)
1080      {
1081        deleteInL(strat->B,&strat->Bl,j,strat);
1082        strat->c3++;
1083      }
1084    }
1085    if (compare == pDivComp_EQUAL)
1086    {
1087      // Add hint for same LM and direction of LC (later) (TODO Oliver)
1088      if (compareCoeff == 1)
1089      {
1090        strat->c3++;
1091        if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1092        {
1093          pLmFree(Lp.lcm);
1094          return;
1095        }
1096        break;
1097      }
1098      else
1099      if (compareCoeff == -1)
1100      {
1101        deleteInL(strat->B,&strat->Bl,j,strat);
1102        strat->c3++;
1103      }
1104    }
1105  }
1106  /*
1107  *the pair (S[i],p) enters B if the spoly != 0
1108  */
1109  /*-  compute the short s-polynomial -*/
1110  if ((strat->S[i]==NULL) || (p==NULL)) return;
1111  pNorm(p);
1112  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
1113  {
1114    // Is from a previous computed GB, therefore we know that spoly will
1115    // reduce to zero. Oliver.
1116    Lp.p=NULL;
1117  }
1118  else
1119  {
1120    Lp.p = ksCreateShortSpoly(strat->S[i],p, strat->tailRing);
1121  }
1122  if (Lp.p == NULL)
1123  {
1124    /*- the case that the s-poly is 0 -*/
1125    if (strat->pairtest==NULL) initPairtest(strat);
1126    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
1127    strat->pairtest[strat->sl+1] = TRUE;
1128    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
1129    /*
1130    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
1131    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
1132    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
1133    *term of p devides the lcm(s,r)
1134    *(this canceling should be done here because
1135    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
1136    *the first case is handeled in chainCrit
1137    */
1138    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
1139  }
1140  else
1141  {
1142    /*- the pair (S[i],p) enters B -*/
1143    Lp.p1 = strat->S[i];
1144    Lp.p2 = p;
1145
1146    pNext(Lp.p) = strat->tail;
1147
1148    if (atR >= 0)
1149    {
1150      Lp.i_r2 = atR;
1151      Lp.i_r1 = strat->S_2_R[i];
1152    }
1153    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1154    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
1155    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
1156  }
1157}
1158#endif
1159
1160/*2
1161* put the pair (s[i],p)  into the set B, ecart=ecart(p)
1162*/
1163
1164void enterOnePair (int i,poly p,int ecart, int isFromQ,kStrategy strat, int atR = -1)
1165{
1166  assume(i<=strat->sl);
1167  if (strat->interred_flag) return;
1168
1169  int      l,j,compare;
1170  LObject  Lp;
1171  Lp.i_r = -1;
1172
1173#ifdef KDEBUG
1174  Lp.ecart=0; Lp.length=0;
1175#endif
1176  /*- computes the lcm(s[i],p) -*/
1177  Lp.lcm = pInit();
1178
1179  pLcm(p,strat->S[i],Lp.lcm);
1180  pSetm(Lp.lcm);
1181  if (strat->sugarCrit)
1182  {
1183    if(
1184    (!((strat->ecartS[i]>0)&&(ecart>0)))
1185    && pHasNotCF(p,strat->S[i]))
1186    {
1187    /*
1188    *the product criterion has applied for (s,p),
1189    *i.e. lcm(s,p)=product of the leading terms of s and p.
1190    *Suppose (s,r) is in L and the leading term
1191    *of p divides lcm(s,r)
1192    *(==> the leading term of p divides the leading term of r)
1193    *but the leading term of s does not divide the leading term of r
1194    *(notice that tis condition is automatically satisfied if r is still
1195    *in S), then (s,r) can be cancelled.
1196    *This should be done here because the
1197    *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
1198    *
1199    *Moreover, skipping (s,r) holds also for the noncommutative case.
1200    */
1201      strat->cp++;
1202      pLmFree(Lp.lcm);
1203      Lp.lcm=NULL;
1204      return;
1205    }
1206    else
1207      Lp.ecart = si_max(ecart,strat->ecartS[i]);
1208    if (strat->fromT && (strat->ecartS[i]>ecart))
1209    {
1210      pLmFree(Lp.lcm);
1211      Lp.lcm=NULL;
1212      return;
1213      /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
1214    }
1215    /*
1216    *the set B collects the pairs of type (S[j],p)
1217    *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
1218    *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1219    *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1220    */
1221    {
1222      j = strat->Bl;
1223      loop
1224      {
1225        if (j < 0)  break;
1226        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1227        if ((compare==1)
1228        &&(sugarDivisibleBy(strat->B[j].ecart,Lp.ecart)))
1229        {
1230          strat->c3++;
1231          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1232          {
1233            pLmFree(Lp.lcm);
1234            return;
1235          }
1236          break;
1237        }
1238        else
1239        if ((compare ==-1)
1240        && sugarDivisibleBy(Lp.ecart,strat->B[j].ecart))
1241        {
1242          deleteInL(strat->B,&strat->Bl,j,strat);
1243          strat->c3++;
1244        }
1245        j--;
1246      }
1247    }
1248  }
1249  else /*sugarcrit*/
1250  {
1251#ifdef HAVE_PLURAL
1252    if (!rIsPluralRing(currRing))
1253    {
1254      // if currRing->nc_type!=quasi (or skew)
1255#endif
1256      if(/*(strat->ak==0) && productCrit(p,strat->S[i])*/
1257      pHasNotCF(p,strat->S[i]))
1258      {
1259      /*
1260      *the product criterion has applied for (s,p),
1261      *i.e. lcm(s,p)=product of the leading terms of s and p.
1262      *Suppose (s,r) is in L and the leading term
1263      *of p devides lcm(s,r)
1264      *(==> the leading term of p devides the leading term of r)
1265      *but the leading term of s does not devide the leading term of r
1266      *(notice that tis condition is automatically satisfied if r is still
1267      *in S), then (s,r) can be canceled.
1268      *This should be done here because the
1269      *case lcm(s,r)=lcm(s,p) is not covered by chainCrit.
1270      */
1271          strat->cp++;
1272          pLmFree(Lp.lcm);
1273          Lp.lcm=NULL;
1274          return;
1275      }
1276      if (strat->fromT && (strat->ecartS[i]>ecart))
1277      {
1278        pLmFree(Lp.lcm);
1279        Lp.lcm=NULL;
1280        return;
1281        /*the pair is (s[i],t[.]), discard it if the ecart is too big*/
1282      }
1283      /*
1284      *the set B collects the pairs of type (S[j],p)
1285      *suppose (r,p) is in B and (s,p) is the new pair and lcm(s,p)#lcm(r,p)
1286      *if the leading term of s devides lcm(r,p) then (r,p) will be canceled
1287      *if the leading term of r devides lcm(s,p) then (s,p) will not enter B
1288      */
1289      for(j = strat->Bl;j>=0;j--)
1290      {
1291        compare=pDivComp(strat->B[j].lcm,Lp.lcm);
1292        if (compare==1)
1293        {
1294          strat->c3++;
1295          if ((strat->fromQ==NULL) || (isFromQ==0) || (strat->fromQ[i]==0))
1296          {
1297            pLmFree(Lp.lcm);
1298            return;
1299          }
1300          break;
1301        }
1302        else
1303        if (compare ==-1)
1304        {
1305          deleteInL(strat->B,&strat->Bl,j,strat);
1306          strat->c3++;
1307        }
1308      }
1309    }
1310#ifdef HAVE_PLURAL
1311  }
1312#endif
1313  /*
1314  *the pair (S[i],p) enters B if the spoly != 0
1315  */
1316  /*-  compute the short s-polynomial -*/
1317  if (strat->fromT && !TEST_OPT_INTSTRATEGY)
1318    pNorm(p);
1319  if ((strat->S[i]==NULL) || (p==NULL))
1320    return;
1321  if ((strat->fromQ!=NULL) && (isFromQ!=0) && (strat->fromQ[i]!=0))
1322    Lp.p=NULL;
1323  else
1324  {
1325#ifdef HAVE_PLURAL
1326    if (currRing->nc!=NULL)
1327    {
1328      if ((currRing->nc->type==nc_lie) && (pHasNotCF(p,strat->S[i])))
1329        /* generalized prod-crit for lie-type */
1330      {
1331          strat->cp++;
1332          Lp.p = nc_p_Bracket_qq(pCopy(p),strat->S[i]);
1333      }
1334      else  Lp.p = nc_CreateSpoly(strat->S[i],p,NULL,currRing);
1335    }
1336    else
1337    {
1338#endif
1339    Lp.p = ksCreateShortSpoly(strat->S[i],p, strat->tailRing);
1340#ifdef HAVE_PLURAL
1341    }
1342#endif
1343  }
1344  if (Lp.p == NULL)
1345  {
1346    /*- the case that the s-poly is 0 -*/
1347    if (strat->pairtest==NULL) initPairtest(strat);
1348    strat->pairtest[i] = TRUE;/*- hint for spoly(S^[i],p)=0 -*/
1349    strat->pairtest[strat->sl+1] = TRUE;
1350    /*hint for spoly(S[i],p) == 0 for some i,0 <= i <= sl*/
1351    /*
1352    *suppose we have (s,r),(r,p),(s,p) and spoly(s,p) == 0 and (r,p) is
1353    *still in B (i.e. lcm(r,p) == lcm(s,p) or the leading term of s does not
1354    *devide lcm(r,p)). In the last case (s,r) can be canceled if the leading
1355    *term of p devides the lcm(s,r)
1356    *(this canceling should be done here because
1357    *the case lcm(s,p) == lcm(s,r) is not covered in chainCrit)
1358    *the first case is handeled in chainCrit
1359    */
1360    if (Lp.lcm!=NULL) pLmFree(Lp.lcm);
1361  }
1362  else
1363  {
1364    /*- the pair (S[i],p) enters B -*/
1365    Lp.p1 = strat->S[i];
1366    Lp.p2 = p;
1367
1368#ifdef HAVE_PLURAL
1369    if (currRing->nc==NULL)
1370    {
1371#endif
1372
1373     pNext(Lp.p) = strat->tail;
1374
1375#ifdef HAVE_PLURAL
1376    }
1377#endif
1378
1379    if (atR >= 0)
1380    {
1381      Lp.i_r1 = strat->S_2_R[i];
1382      Lp.i_r2 = atR;
1383    }
1384    else
1385    {
1386      Lp.i_r1 = -1;
1387      Lp.i_r2 = -1;
1388    }
1389    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1390    if (TEST_OPT_INTSTRATEGY)
1391    {
1392
1393#ifdef HAVE_PLURAL
1394      if (currRing->nc==NULL)
1395      {
1396#endif
1397
1398      nDelete(&(Lp.p->coef));
1399
1400#ifdef HAVE_PLURAL
1401      }
1402#endif
1403
1404    }
1405    l = strat->posInL(strat->B,strat->Bl,&Lp,strat);
1406    enterL(&strat->B,&strat->Bl,&strat->Bmax,Lp,l);
1407  }
1408}
1409
1410/*2
1411* put the pair (s[i],p) into the set L, ecart=ecart(p)
1412* in the case that s forms a SB of (s)
1413*/
1414void enterOnePairSpecial (int i,poly p,int ecart,kStrategy strat, int atR = -1)
1415{
1416  //PrintS("try ");wrp(strat->S[i]);PrintS(" and ");wrp(p);PrintLn();
1417  if(pHasNotCF(p,strat->S[i]))
1418  {
1419    //PrintS("prod-crit\n");
1420      if (!rIsPluralRing(currRing))
1421      {
1422        strat->cp++;
1423        return;
1424      }
1425  }
1426
1427  int      l,j,compare;
1428  LObject  Lp;
1429  Lp.i_r = -1;
1430
1431  Lp.lcm = pInit();
1432  pLcm(p,strat->S[i],Lp.lcm);
1433  pSetm(Lp.lcm);
1434  for(j = strat->Ll;j>=0;j--)
1435  {
1436    compare=pDivComp(strat->L[j].lcm,Lp.lcm);
1437    if ((compare==1) || (pLmEqual(strat->L[j].lcm,Lp.lcm)))
1438    {
1439      //PrintS("c3-crit\n");
1440      strat->c3++;
1441      pLmFree(Lp.lcm);
1442      return;
1443    }
1444    else if (compare ==-1)
1445    {
1446      //Print("c3-crit with L[%d]\n",j);
1447      deleteInL(strat->L,&strat->Ll,j,strat);
1448      strat->c3++;
1449    }
1450  }
1451  /*-  compute the short s-polynomial -*/
1452
1453  Lp.p = ksCreateShortSpoly(strat->S[i],p,strat->tailRing);
1454  if (Lp.p == NULL)
1455  {
1456     pLmFree(Lp.lcm);
1457  }
1458  else
1459  {
1460    /*- the pair (S[i],p) enters L -*/
1461    Lp.p1 = strat->S[i];
1462    Lp.p2 = p;
1463    if (atR >= 0)
1464    {
1465      Lp.i_r1 = strat->S_2_R[i];
1466      Lp.i_r2 = atR;
1467    }
1468    else
1469    {
1470      Lp.i_r1 = -1;
1471      Lp.i_r2 = -1;
1472    }
1473    pNext(Lp.p) = strat->tail;
1474    strat->initEcartPair(&Lp,strat->S[i],p,strat->ecartS[i],ecart);
1475    if (TEST_OPT_INTSTRATEGY)
1476    {
1477      nDelete(&(Lp.p->coef));
1478    }
1479    l = strat->posInL(strat->L,strat->Ll,&Lp,strat);
1480    //Print("-> L[%d]\n",l);
1481    enterL(&strat->L,&strat->Ll,&strat->Lmax,Lp,l);
1482  }
1483}
1484
1485/*2
1486*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
1487*using the chain-criterion in B and L and enters B to L
1488*/
1489void chainCrit (poly p,int ecart,kStrategy strat)
1490{
1491  int i,j,l;
1492
1493  /*
1494  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
1495  *In this case all elements in B such
1496  *that their lcm is divisible by the leading term of S[i] can be canceled
1497  */
1498  if (strat->pairtest!=NULL)
1499  {
1500    {
1501      /*- i.e. there is an i with pairtest[i]==TRUE -*/
1502      for (j=0; j<=strat->sl; j++)
1503      {
1504        if (strat->pairtest[j])
1505        {
1506          for (i=strat->Bl; i>=0; i--)
1507          {
1508            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
1509            {
1510              deleteInL(strat->B,&strat->Bl,i,strat);
1511              strat->c3++;
1512            }
1513          }
1514        }
1515      }
1516    }
1517    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
1518    strat->pairtest=NULL;
1519  }
1520  if (strat->Gebauer || strat->fromT)
1521  {
1522    if (strat->sugarCrit)
1523    {
1524    /*
1525    *suppose L[j] == (s,r) and p/lcm(s,r)
1526    *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
1527    *and in case the sugar is o.k. then L[j] can be canceled
1528    */
1529      for (j=strat->Ll; j>=0; j--)
1530      {
1531        if (sugarDivisibleBy(ecart,strat->L[j].ecart)
1532        && ((pNext(strat->L[j].p) == strat->tail) || (pOrdSgn==1))
1533        && pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1534        {
1535          if (strat->L[j].p == strat->tail)
1536          {
1537              deleteInL(strat->L,&strat->Ll,j,strat);
1538              strat->c3++;
1539          }
1540        }
1541      }
1542      /*
1543      *this is GEBAUER-MOELLER:
1544      *in B all elements with the same lcm except the "best"
1545      *(i.e. the last one in B with this property) will be canceled
1546      */
1547      j = strat->Bl;
1548      loop /*cannot be changed into a for !!! */
1549      {
1550        if (j <= 0) break;
1551        i = j-1;
1552        loop
1553        {
1554          if (i <  0) break;
1555          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
1556          {
1557            strat->c3++;
1558            if (sugarDivisibleBy(strat->B[j].ecart,strat->B[i].ecart))
1559            {
1560              deleteInL(strat->B,&strat->Bl,i,strat);
1561              j--;
1562            }
1563            else
1564            {
1565              deleteInL(strat->B,&strat->Bl,j,strat);
1566              break;
1567            }
1568          }
1569          i--;
1570        }
1571        j--;
1572      }
1573    }
1574    else /*sugarCrit*/
1575    {
1576      /*
1577      *suppose L[j] == (s,r) and p/lcm(s,r)
1578      *and lcm(s,r)#lcm(s,p) and lcm(s,r)#lcm(r,p)
1579      *and in case the sugar is o.k. then L[j] can be canceled
1580      */
1581      for (j=strat->Ll; j>=0; j--)
1582      {
1583        if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1584        {
1585          if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
1586          {
1587            deleteInL(strat->L,&strat->Ll,j,strat);
1588            strat->c3++;
1589          }
1590        }
1591      }
1592      /*
1593      *this is GEBAUER-MOELLER:
1594      *in B all elements with the same lcm except the "best"
1595      *(i.e. the last one in B with this property) will be canceled
1596      */
1597      j = strat->Bl;
1598      loop   /*cannot be changed into a for !!! */
1599      {
1600        if (j <= 0) break;
1601        for(i=j-1; i>=0; i--)
1602        {
1603          if (pLmEqual(strat->B[j].lcm,strat->B[i].lcm))
1604          {
1605            strat->c3++;
1606            deleteInL(strat->B,&strat->Bl,i,strat);
1607            j--;
1608          }
1609        }
1610        j--;
1611      }
1612    }
1613    /*
1614    *the elements of B enter L/their order with respect to B is kept
1615    *j = posInL(L,j,B[i]) would permutate the order
1616    *if once B is ordered different from L
1617    *then one should use j = posInL(L,Ll,B[i])
1618    */
1619    j = strat->Ll+1;
1620    for (i=strat->Bl; i>=0; i--)
1621    {
1622      j = strat->posInL(strat->L,j-1,&(strat->B[i]),strat);
1623      enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
1624    }
1625    strat->Bl = -1;
1626  }
1627  else
1628  {
1629    for (j=strat->Ll; j>=0; j--)
1630    {
1631      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1632      {
1633        if ((pNext(strat->L[j].p) == strat->tail)||(pOrdSgn==1))
1634        {
1635          deleteInL(strat->L,&strat->Ll,j,strat);
1636          strat->c3++;
1637        }
1638      }
1639    }
1640    /*
1641    *this is our MODIFICATION of GEBAUER-MOELLER:
1642    *First the elements of B enter L,
1643    *then we fix a lcm and the "best" element in L
1644    *(i.e the last in L with this lcm and of type (s,p))
1645    *and cancel all the other elements of type (r,p) with this lcm
1646    *except the case the element (s,r) has also the same lcm
1647    *and is on the worst position with respect to (s,p) and (r,p)
1648    */
1649    /*
1650    *B enters to L/their order with respect to B is permutated for elements
1651    *B[i].p with the same leading term
1652    */
1653    j = strat->Ll;
1654    for (i=strat->Bl; i>=0; i--)
1655    {
1656      j = strat->posInL(strat->L,j,&(strat->B[i]),strat);
1657      enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
1658    }
1659    strat->Bl = -1;
1660    j = strat->Ll;
1661    loop  /*cannot be changed into a for !!! */
1662    {
1663      if (j <= 0)
1664      {
1665        /*now L[0] cannot be canceled any more and the tail can be removed*/
1666        if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
1667        break;
1668      }
1669      if (strat->L[j].p2 == p)
1670      {
1671        i = j-1;
1672        loop
1673        {
1674          if (i < 0)  break;
1675          if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm))
1676          {
1677            /*L[i] could be canceled but we search for a better one to cancel*/
1678            strat->c3++;
1679            if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
1680            && (pNext(strat->L[l].p) == strat->tail)
1681            && (!pLmEqual(strat->L[i].p,strat->L[l].p))
1682            && pDivisibleBy(p,strat->L[l].lcm))
1683            {
1684              /*
1685              *"NOT equal(...)" because in case of "equal" the element L[l]
1686              *is "older" and has to be from theoretical point of view behind
1687              *L[i], but we do not want to reorder L
1688              */
1689              strat->L[i].p2 = strat->tail;
1690              /*
1691              *L[l] will be canceled, we cannot cancel L[i] later on,
1692              *so we mark it with "tail"
1693              */
1694              deleteInL(strat->L,&strat->Ll,l,strat);
1695              i--;
1696            }
1697            else
1698            {
1699              deleteInL(strat->L,&strat->Ll,i,strat);
1700            }
1701            j--;
1702          }
1703          i--;
1704        }
1705      }
1706      else if (strat->L[j].p2 == strat->tail)
1707      {
1708        /*now L[j] cannot be canceled any more and the tail can be removed*/
1709        strat->L[j].p2 = p;
1710      }
1711      j--;
1712    }
1713  }
1714}
1715
1716/*2
1717*(s[0],h),...,(s[k],h) will be put to the pairset L
1718*/
1719void initenterpairs (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
1720{
1721
1722  if ((strat->syzComp==0)
1723  || (pGetComp(h)<=strat->syzComp))
1724  {
1725    int j;
1726    BOOLEAN new_pair=FALSE;
1727
1728    if (pGetComp(h)==0)
1729    {
1730      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
1731      if ((isFromQ)&&(strat->fromQ!=NULL))
1732      {
1733        for (j=0; j<=k; j++)
1734        {
1735          if (!strat->fromQ[j])
1736          {
1737            new_pair=TRUE;
1738            enterOnePair(j,h,ecart,isFromQ,strat, atR);
1739          //Print("j:%d, Ll:%d\n",j,strat->Ll);
1740          }
1741        }
1742      }
1743      else
1744      {
1745        new_pair=TRUE;
1746        for (j=0; j<=k; j++)
1747        {
1748          enterOnePair(j,h,ecart,isFromQ,strat, atR);
1749          //Print("j:%d, Ll:%d\n",j,strat->Ll);
1750        }
1751      }
1752    }
1753    else
1754    {
1755      for (j=0; j<=k; j++)
1756      {
1757        if ((pGetComp(h)==pGetComp(strat->S[j]))
1758        || (pGetComp(strat->S[j])==0))
1759        {
1760          new_pair=TRUE;
1761          enterOnePair(j,h,ecart,isFromQ,strat, atR);
1762        //Print("j:%d, Ll:%d\n",j,strat->Ll);
1763        }
1764      }
1765    }
1766
1767    if (new_pair) chainCrit(h,ecart,strat);
1768
1769  }
1770}
1771
1772#ifdef HAVE_RING2TOM
1773/*2
1774*the pairset B of pairs of type (s[i],p) is complete now. It will be updated
1775*using the chain-criterion in B and L and enters B to L
1776*/
1777void chainCritRing (poly p,int ecart,kStrategy strat)
1778{
1779  int i,j,l;
1780  /*
1781  *pairtest[i] is TRUE if spoly(S[i],p) == 0.
1782  *In this case all elements in B such
1783  *that their lcm is divisible by the leading term of S[i] can be canceled
1784  */
1785  if (strat->pairtest!=NULL)
1786  {
1787    {
1788      /*- i.e. there is an i with pairtest[i]==TRUE -*/
1789      for (j=0; j<=strat->sl; j++)
1790      {
1791        if (strat->pairtest[j])
1792        {
1793          for (i=strat->Bl; i>=0; i--)
1794          {
1795            if (pDivisibleBy(strat->S[j],strat->B[i].lcm))
1796            {
1797              deleteInL(strat->B,&strat->Bl,i,strat);
1798              strat->c3++;
1799            }
1800          }
1801        }
1802      }
1803    }
1804    omFreeSize(strat->pairtest,(strat->sl+2)*sizeof(BOOLEAN));
1805    strat->pairtest=NULL;
1806  }
1807  assume(!(strat->Gebauer || strat->fromT));
1808  for (j=strat->Ll; j>=0; j--)
1809  {
1810    if (strat->L[j].lcm != NULL && nGreater(pGetCoeff(strat->L[j].lcm), pGetCoeff(p)))
1811    {
1812      if (pCompareChain(p,strat->L[j].p1,strat->L[j].p2,strat->L[j].lcm))
1813      {
1814        if ((pNext(strat->L[j].p) == strat->tail) || (pOrdSgn==1))
1815        {
1816          deleteInL(strat->L,&strat->Ll,j,strat);
1817          strat->c3++;
1818          Print("|UL|");
1819        }
1820      }
1821    }
1822  }
1823  /*
1824  *this is our MODIFICATION of GEBAUER-MOELLER:
1825  *First the elements of B enter L,
1826  *then we fix a lcm and the "best" element in L
1827  *(i.e the last in L with this lcm and of type (s,p))
1828  *and cancel all the other elements of type (r,p) with this lcm
1829  *except the case the element (s,r) has also the same lcm
1830  *and is on the worst position with respect to (s,p) and (r,p)
1831  */
1832  /*
1833  *B enters to L/their order with respect to B is permutated for elements
1834  *B[i].p with the same leading term
1835  */
1836  j = strat->Ll;
1837  for (i=strat->Bl; i>=0; i--)
1838  {
1839    j = strat->posInL(strat->L,j,&(strat->B[i]),strat);
1840    enterL(&strat->L,&strat->Ll,&strat->Lmax,strat->B[i],j);
1841  }
1842  strat->Bl = -1;
1843  j = strat->Ll;
1844  loop  /*cannot be changed into a for !!! */
1845  {
1846    if (j <= 0)
1847    {
1848      /*now L[0] cannot be canceled any more and the tail can be removed*/
1849      if (strat->L[0].p2 == strat->tail) strat->L[0].p2 = p;
1850      break;
1851    }
1852    if (strat->L[j].p2 == p) // Was the element added from B?
1853    {
1854      i = j-1;
1855      loop
1856      {
1857        if (i < 0)  break;
1858        // Element is from B and has the same lcm as L[j]
1859        if ((strat->L[i].p2 == p) && pLmEqual(strat->L[j].lcm,strat->L[i].lcm)
1860#ifdef HAVE_RING2TOM
1861          && nGreater(pGetCoeff(strat->L[j].lcm), pGetCoeff(strat->L[i].lcm))
1862#endif
1863        )
1864        {
1865          /*L[i] could be canceled but we search for a better one to cancel*/
1866          strat->c3++;
1867          Print("|EP|");
1868          if (isInPairsetL(i-1,strat->L[j].p1,strat->L[i].p1,&l,strat)
1869          && (pNext(strat->L[l].p) == strat->tail)
1870          && (!pLmEqual(strat->L[i].p,strat->L[l].p))
1871#ifdef HAVE_RING2TOM
1872//        && 1 == 0
1873#endif
1874          && pDivisibleBy(p,strat->L[l].lcm))
1875          {
1876            /*
1877            *"NOT equal(...)" because in case of "equal" the element L[l]
1878            *is "older" and has to be from theoretical point of view behind
1879            *L[i], but we do not want to reorder L
1880            */
1881            strat->L[i].p2 = strat->tail;
1882            /*
1883            *L[l] will be canceled, we cannot cancel L[i] later on,
1884            *so we mark it with "tail"
1885            */
1886            deleteInL(strat->L,&strat->Ll,l,strat);
1887            i--;
1888          }
1889          else
1890          {
1891            deleteInL(strat->L,&strat->Ll,i,strat);
1892          }
1893          j--;
1894        }
1895        i--;
1896      }
1897    }
1898    else if (strat->L[j].p2 == strat->tail)
1899    {
1900      /*now L[j] cannot be canceled any more and the tail can be removed*/
1901      strat->L[j].p2 = p;
1902    }
1903    j--;
1904  }
1905}
1906
1907long twoPow(long arg)
1908{
1909  return 1L << arg;
1910}
1911
1912/*2
1913*(s[0],h),...,(s[k],h) will be put to the pairset L
1914*/
1915void initenterpairsRing (poly h,int k,int ecart,int isFromQ,kStrategy strat, int atR = -1)
1916{
1917
1918  if ((strat->syzComp==0) || (pGetComp(h)<=strat->syzComp))
1919  {
1920    int j;
1921    BOOLEAN new_pair=FALSE;
1922
1923    if (pGetComp(h)==0)
1924    {
1925      /* for Q!=NULL: build pairs (f,q),(f1,f2), but not (q1,q2)*/
1926      if ((isFromQ)&&(strat->fromQ!=NULL))
1927      {
1928        for (j=0; j<=k; j++)
1929        {
1930          if (!strat->fromQ[j])
1931          {
1932            new_pair=TRUE;
1933            enterOnePairRing(j,h,ecart,isFromQ,strat, atR);
1934            Print("j:%d, Ll:%d\n",j,strat->Ll);
1935          }
1936        }
1937      }
1938      else
1939      {
1940        new_pair=TRUE;
1941        for (j=0; j<=k; j++)
1942        {
1943          enterOnePairRing(j,h,ecart,isFromQ,strat, atR);
1944          // Print("j:%d, Ll:%d\n",j,strat->Ll);
1945        }
1946      }
1947    }
1948    else
1949    {
1950      for (j=0; j<=k; j++)
1951      {
1952        if ((pGetComp(h)==pGetComp(strat->S[j])) || (pGetComp(strat->S[j])==0))
1953        {
1954          new_pair=TRUE;
1955          enterOnePairRing(j,h,ecart,isFromQ,strat, atR);
1956          Print("j:%d, Ll:%d\n",j,strat->Ll);
1957        }
1958      }
1959    }
1960
1961    if (new_pair) chainCritRing(h,ecart,strat);
1962
1963  }
1964/*
1965ring r=256,(x,y,z),dp;
1966ideal I=12xz-133y, 2xy-z;
1967*/
1968
1969}
1970
1971/*2
1972* Generates spoly(0, h) if applicable. Assumes ring in Z/2^n.
1973*/
1974void enterExtendedSpoly(poly h,kStrategy strat)
1975{
1976  if (((long) ((h)->coef)) % 2 == 0)
1977  {
1978    long a = ((long) ((h)->coef)) / 2;
1979    long b = currRing->ch - 1;
1980    poly p = p_Copy(h->next, strat->tailRing);
1981    while (a % 2 == 0)
1982    {
1983      a = a / 2;
1984      b--;
1985    }
1986    p = p_Mult_nn(p, (number) twoPow(b), strat->tailRing);
1987
1988    if (p != NULL)
1989    {
1990      if (TEST_OPT_PROT)
1991      {
1992        PrintS("Z");
1993      }
1994      poly tmp = p_ISet((long) ((p)->coef), currRing);
1995      for (int i = 1; i <= currRing->N; i++) {
1996        pSetExp(tmp, i, p_GetExp(p, i, strat->tailRing));
1997      }
1998      p_Setm(tmp, currRing);
1999      p = p_LmDeleteAndNext(p, strat->tailRing);
2000      pNext(tmp) = p;
2001
2002      LObject h;
2003      h.p = tmp;
2004      h.tailRing = strat->tailRing;
2005      if (TEST_OPT_INTSTRATEGY)
2006      {
2007        //pContent(h.p);
2008        h.pCleardenom(); // also does a pContent
2009      }
2010      else
2011      {
2012        h.pNorm();
2013      }
2014      strat->initEcart(&h);
2015      int posx;
2016      if (h.p!=NULL)
2017      {
2018        if (strat->Ll==-1)
2019          posx =0;
2020        else
2021          posx = strat->posInL(strat->L,strat->Ll,&h,strat);
2022        h.sev = pGetShortExpVector(h.p);
2023        h.t_p = k_LmInit_currRing_2_tailRing(h.p, strat->tailRing);
2024        if (pNext(p) != NULL)
2025        {
2026          // What does this? (Oliver)
2027          // pShallowCopyDeleteProc p_shallow_copy_delete
2028          //      = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
2029          // pNext(p) = p_shallow_copy_delete(pNext(p),
2030          //              currRing, strat->tailRing, strat->tailRing->PolyBin);
2031        }
2032        enterL(&strat->L,&strat->Ll,&strat->Lmax,h,posx);
2033      }
2034    }
2035  }
2036}
2037
2038void clearSbatch (poly h,int k,int pos,kStrategy strat)
2039{
2040  int j = pos;
2041  if ( (!strat->fromT)
2042  && ((strat->syzComp==0)
2043    ||(pGetComp(h)<=strat->syzComp)))
2044  {
2045    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
2046    unsigned long h_sev = pGetShortExpVector(h);
2047    loop
2048    {
2049      if (j > k) break;
2050      clearS(h,h_sev, &j,&k,strat);
2051      j++;
2052    }
2053    //Print("end clearS sl=%d\n",strat->sl);
2054  }
2055}
2056
2057/*2
2058* Generates a sufficient set of spolys (maybe just a finite generating
2059* set of the syzygys)
2060*/
2061void superenterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
2062{
2063  if (currRing->cring == 1)
2064  {
2065    // enter also zero divisor * poly, if this is non zero and of smaller degree
2066    enterExtendedSpoly(h, strat);
2067    initenterpairsRing(h, k, ecart, 0, strat, atR);
2068  }
2069  else
2070  {
2071    initenterpairs(h, k, ecart, 0, strat, atR);
2072  }
2073  clearSbatch(h, k, pos, strat);
2074}
2075#endif
2076
2077/*2
2078*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
2079*superfluous elements in S will be deleted
2080*/
2081void enterpairs (poly h,int k,int ecart,int pos,kStrategy strat, int atR)
2082{
2083  int j=pos;
2084
2085  initenterpairs(h,k,ecart,0,strat, atR);
2086  if ( (!strat->fromT)
2087  && ((strat->syzComp==0)
2088    ||(pGetComp(h)<=strat->syzComp)))
2089  {
2090    //Print("start clearS k=%d, pos=%d, sl=%d\n",k,pos,strat->sl);
2091    unsigned long h_sev = pGetShortExpVector(h);
2092    loop
2093    {
2094      if (j > k) break;
2095      clearS(h,h_sev, &j,&k,strat);
2096      j++;
2097    }
2098    //Print("end clearS sl=%d\n",strat->sl);
2099  }
2100 // PrintS("end enterpairs\n");
2101}
2102
2103/*2
2104*(s[0],h),...,(s[k],h) will be put to the pairset L(via initenterpairs)
2105*superfluous elements in S will be deleted
2106*/
2107void enterpairsSpecial (poly h,int k,int ecart,int pos,kStrategy strat, int atR = -1)
2108{
2109  int j;
2110
2111  for (j=0; j<=k; j++)
2112  {
2113    if ((pGetComp(h)==pGetComp(strat->S[j]))
2114    || (0==pGetComp(strat->S[j])))
2115    {
2116      enterOnePairSpecial(j,h,ecart,strat, atR);
2117    }
2118  }
2119  j=pos;
2120  loop
2121  {
2122    unsigned long h_sev = pGetShortExpVector(h);
2123    if (j > k) break;
2124    clearS(h,h_sev,&j,&k,strat);
2125    j++;
2126  }
2127}
2128
2129/*2
2130*constructs the pairset at the beginning
2131*of the buchberger/mora algorithm
2132*/
2133void pairs (kStrategy strat)
2134{
2135  int j,i;
2136//  Print("pairs:sl=%d\n",strat->sl);
2137//  for (i=0; i<=strat->sl; i++)
2138//  {
2139//    Print("s%d:",i);pWrite(strat->S[i]);
2140//  }
2141  if (strat->fromQ!=NULL)
2142  {
2143    for (i=1; i<=strat->sl; i++)
2144    {
2145      initenterpairs(strat->S[i],i-1,strat->ecartS[i],strat->fromQ[i],strat);
2146    }
2147  }
2148  else
2149  {
2150    for (i=1; i<=strat->sl; i++)
2151    {
2152      initenterpairs(strat->S[i],i-1,strat->ecartS[i],0,strat);
2153    }
2154  }
2155  /*deletes superfluous elements in S*/
2156  i = -1;
2157  loop
2158  {
2159    i++;
2160    if (i >= strat->sl) break;
2161    if ((strat->syzComp==0) || (pGetComp(strat->S[i])<=strat->syzComp))
2162    {
2163      j=i;
2164      loop
2165      {
2166        j++;
2167        if (j > strat->sl) break;
2168        if (pLmShortDivisibleBy(strat->S[i], strat->sevS[i],
2169                              strat->S[j], ~ strat->sevS[j]))
2170        {
2171        //  Print("delete %d=",j);
2172        //  wrp(strat->S[j]);
2173        //  Print(" wegen %d=",i);
2174        //  wrp(strat->S[i]);
2175        //  Print("( fromQ=%d)\n", (strat->fromQ) ? strat->fromQ[j]:0);
2176          if ((strat->fromQ==NULL) || (strat->fromQ[j]==0))
2177          {
2178            deleteInS(j,strat);
2179            j--;
2180          }
2181        }
2182      }
2183    }
2184  }
2185}
2186
2187/*2
2188*reorders  s with respect to posInS,
2189*suc is the first changed index or zero
2190*/
2191void reorderS (int* suc,kStrategy strat)
2192{
2193  int i,j,at,ecart, s2r;
2194  int fq=0;
2195  unsigned long sev;
2196  poly  p;
2197
2198  *suc = -1;
2199  for (i=1; i<=strat->sl; i++)
2200  {
2201    at = posInS(strat,i-1,strat->S[i],strat->ecartS[i]);
2202    if (at != i)
2203    {
2204      if ((*suc > at) || (*suc == -1)) *suc = at;
2205      p = strat->S[i];
2206      ecart = strat->ecartS[i];
2207      sev = strat->sevS[i];
2208      s2r = strat->S_2_R[i];
2209      if (strat->fromQ!=NULL) fq=strat->fromQ[i];
2210      for (j=i; j>=at+1; j--)
2211      {
2212        strat->S[j] = strat->S[j-1];
2213        strat->ecartS[j] = strat->ecartS[j-1];
2214        strat->sevS[j] = strat->sevS[j-1];
2215        strat->S_2_R[j] = strat->S_2_R[j-1];
2216      }
2217      strat->S[at] = p;
2218      strat->ecartS[at] = ecart;
2219      strat->sevS[at] = sev;
2220      strat->S_2_R[at] = s2r;
2221      if (strat->fromQ!=NULL)
2222      {
2223        for (j=i; j>=at+1; j--)
2224        {
2225          strat->fromQ[j] = strat->fromQ[j-1];
2226        }
2227        strat->fromQ[at]=fq;
2228      }
2229    }
2230  }
2231}
2232
2233
2234/*2
2235*looks up the position of p in set
2236*set[0] is the smallest with respect to the ordering-procedure
2237*pComp
2238* Assumption: posInS only depends on the leading term
2239*             otherwise, bba has to be changed
2240*/
2241int posInS (kStrategy strat, int length,poly p, int ecart_p)
2242{
2243  if(length==-1) return 0;
2244  polyset set=strat->S;
2245  int i;
2246  int an = 0;
2247  int en= length;
2248  int cmp_int=pOrdSgn;
2249  if (currRing->MixedOrder)
2250  {
2251    int o=pWTotaldegree(p);
2252    int oo=pWTotaldegree(set[length]);
2253
2254    if ((oo<o)
2255    || ((o==oo) && (pLmCmp(set[length],p)!= cmp_int)))
2256      return length+1;
2257
2258    loop
2259    {
2260      if (an >= en-1)
2261      {
2262        if ((pWTotaldegree(set[an])>=o) && (pLmCmp(set[an],p) == cmp_int))
2263        {
2264          return an;
2265        }
2266        return en;
2267      }
2268      i=(an+en) / 2;
2269      if ((pWTotaldegree(set[an])>=o)
2270      && (pLmCmp(set[i],p) == cmp_int)) en=i;
2271      else                              an=i;
2272    }
2273  }
2274  else
2275  {
2276#ifdef HAVE_RING2TOM
2277    if (currRing->cring == 1)
2278    {
2279      if (pLmCmp(set[length],p)== -cmp_int)
2280        return length+1;
2281
2282      loop
2283      {
2284        if (an >= en-1)
2285        {
2286          if (pLmCmp(set[an],p) == cmp_int)  return an;
2287          if (pLmCmp(set[an],p) == -cmp_int) return en;
2288          if (currRing->cring == 1) {
2289              if (nGreater(pGetCoeff(p), pGetCoeff(set[an]))) return en;
2290              return an;
2291          }
2292          if ((cmp_int!=1) && ((strat->ecartS[an])>ecart_p)) return an;
2293          return en;
2294        }
2295        i=(an+en) / 2;
2296        if (pLmCmp(set[i],p) == cmp_int)         en=i;
2297        else if (pLmCmp(set[i],p) == -cmp_int)   an=i;
2298        else
2299        {
2300          if (currRing->cring == 1) {
2301              if (nGreater(pGetCoeff(p), pGetCoeff(set[i]))) an = i;
2302              else en = i;
2303          }
2304          else
2305          {
2306            if ((cmp_int!=1) && ((strat->ecartS[i])<ecart_p))
2307              en=i;
2308            else
2309              an=i;
2310          }
2311        }
2312      }
2313    }
2314    else
2315#endif
2316    if (pLmCmp(set[length],p)== -cmp_int)
2317      return length+1;
2318
2319    loop
2320    {
2321      if (an >= en-1)
2322      {
2323        if (pLmCmp(set[an],p) == cmp_int) return an;
2324        if (pLmCmp(set[an],p) == -cmp_int) return en;
2325        if ((cmp_int!=1)
2326        && ((strat->ecartS[an])>ecart_p))
2327          return an;
2328        return en;
2329      }
2330      i=(an+en) / 2;
2331      if (pLmCmp(set[i],p) == cmp_int) en=i;
2332      else if (pLmCmp(set[i],p) == -cmp_int) an=i;
2333      else
2334      {
2335        if ((cmp_int!=1)
2336        &&((strat->ecartS[i])<ecart_p))
2337          en=i;
2338        else
2339          an=i;
2340      }
2341    }
2342  }
2343}
2344
2345
2346/*2
2347* looks up the position of p in set
2348* the position is the last one
2349*/
2350int posInT0 (const TSet set,const int length,LObject &p)
2351{
2352  return (length+1);
2353}
2354
2355
2356/*2
2357* looks up the position of p in T
2358* set[0] is the smallest with respect to the ordering-procedure
2359* pComp
2360*/
2361int posInT1 (const TSet set,const int length,LObject &p)
2362{
2363  if (length==-1) return 0;
2364
2365  if (pLmCmp(set[length].p,p.p)!= pOrdSgn) return length+1;
2366
2367  int i;
2368  int an = 0;
2369  int en= length;
2370
2371  loop
2372  {
2373    if (an >= en-1)
2374    {
2375      if (pLmCmp(set[an].p,p.p) == pOrdSgn) return an;
2376      return en;
2377    }
2378    i=(an+en) / 2;
2379    if (pLmCmp(set[i].p,p.p) == pOrdSgn) en=i;
2380    else                                 an=i;
2381  }
2382}
2383
2384/*2
2385* looks up the position of p in T
2386* set[0] is the smallest with respect to the ordering-procedure
2387* length
2388*/
2389int posInT2 (const TSet set,const int length,LObject &p)
2390{
2391  if (length==-1)
2392    return 0;
2393  if (set[length].length<p.length)
2394    return length+1;
2395
2396  int i;
2397  int an = 0;
2398  int en= length;
2399
2400  loop
2401  {
2402    if (an >= en-1)
2403    {
2404      if (set[an].length>p.length) return an;
2405      return en;
2406    }
2407    i=(an+en) / 2;
2408    if (set[i].length>p.length) en=i;
2409    else                        an=i;
2410  }
2411}
2412
2413/*2
2414* looks up the position of p in T
2415* set[0] is the smallest with respect to the ordering-procedure
2416* totaldegree,pComp
2417*/
2418int posInT11 (const TSet set,const int length,LObject &p)
2419/*{
2420 * int j=0;
2421 * int o;
2422 *
2423 * o = p.GetpFDeg();
2424 * loop
2425 * {
2426 *   if ((pFDeg(set[j].p) > o)
2427 *   || ((pFDeg(set[j].p) == o) && (pLmCmp(set[j].p,p.p) == pOrdSgn)))
2428 *   {
2429 *     return j;
2430 *   }
2431 *   j++;
2432 *   if (j > length) return j;
2433 * }
2434 *}
2435 */
2436{
2437  if (length==-1) return 0;
2438
2439  int o = p.GetpFDeg();
2440  int op = set[length].GetpFDeg();
2441
2442  if ((op < o)
2443  || ((op == o) && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
2444    return length+1;
2445
2446  int i;
2447  int an = 0;
2448  int en= length;
2449
2450  loop
2451  {
2452    if (an >= en-1)
2453    {
2454      op= set[an].GetpFDeg();
2455      if ((op > o)
2456      || (( op == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
2457        return an;
2458      return en;
2459    }
2460    i=(an+en) / 2;
2461    op = set[i].GetpFDeg();
2462    if (( op > o)
2463    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
2464      en=i;
2465    else
2466      an=i;
2467  }
2468}
2469
2470/*2
2471* looks up the position of p in T
2472* set[0] is the smallest with respect to the ordering-procedure
2473* totaldegree,pComp
2474*/
2475int posInT110 (const TSet set,const int length,LObject &p)
2476{
2477  if (length==-1) return 0;
2478
2479  int o = p.GetpFDeg();
2480  int op = set[length].GetpFDeg();
2481
2482  if (( op < o)
2483  || (( op == o) && (set[length].length<p.length))
2484  || (( op == o) && (set[length].length == p.length)
2485     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
2486    return length+1;
2487
2488  int i;
2489  int an = 0;
2490  int en= length;
2491  loop
2492  {
2493    if (an >= en-1)
2494    {
2495      op = set[an].GetpFDeg();
2496      if (( op > o)
2497      || (( op == o) && (set[an].length > p.length))
2498      || (( op == o) && (set[an].length == p.length)
2499         && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
2500        return an;
2501      return en;
2502    }
2503    i=(an+en) / 2;
2504    op = set[i].GetpFDeg();
2505    if (( op > o)
2506    || (( op == o) && (set[i].length > p.length))
2507    || (( op == o) && (set[i].length == p.length)
2508       && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
2509      en=i;
2510    else
2511      an=i;
2512  }
2513}
2514
2515/*2
2516* looks up the position of p in set
2517* set[0] is the smallest with respect to the ordering-procedure
2518* pFDeg
2519*/
2520int posInT13 (const TSet set,const int length,LObject &p)
2521{
2522  if (length==-1) return 0;
2523
2524  int o = p.GetpFDeg();
2525
2526  if (set[length].GetpFDeg() <= o)
2527    return length+1;
2528
2529  int i;
2530  int an = 0;
2531  int en= length;
2532  loop
2533  {
2534    if (an >= en-1)
2535    {
2536      if (set[an].GetpFDeg() > o)
2537        return an;
2538      return en;
2539    }
2540    i=(an+en) / 2;
2541    if (set[i].GetpFDeg() > o)
2542      en=i;
2543    else
2544      an=i;
2545  }
2546}
2547
2548// determines the position based on: 1.) Ecart 2.) pLength
2549int posInT_EcartpLength(const TSet set,const int length,LObject &p)
2550{
2551  if (length==-1) return 0;
2552
2553  int op=p.ecart;
2554  int ol = p.GetpLength();
2555
2556  int oo=set[length].ecart;
2557  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
2558    return length+1;
2559
2560  int i;
2561  int an = 0;
2562  int en= length;
2563  loop
2564    {
2565      if (an >= en-1)
2566      {
2567        int oo=set[an].ecart;
2568        if((oo > op)
2569           || ((oo==op) && (set[an].pLength > ol)))
2570          return an;
2571        return en;
2572      }
2573      i=(an+en) / 2;
2574      int oo=set[i].ecart;
2575      if ((oo > op)
2576          || ((oo == op) && (set[i].pLength > ol)))
2577        en=i;
2578      else
2579        an=i;
2580    }
2581}
2582
2583/*2
2584* looks up the position of p in set
2585* set[0] is the smallest with respect to the ordering-procedure
2586* maximaldegree, pComp
2587*/
2588int posInT15 (const TSet set,const int length,LObject &p)
2589/*{
2590 *int j=0;
2591 * int o;
2592 *
2593 * o = p.GetpFDeg()+p.ecart;
2594 * loop
2595 * {
2596 *   if ((set[j].GetpFDeg()+set[j].ecart > o)
2597 *   || ((set[j].GetpFDeg()+set[j].ecart == o)
2598 *     && (pLmCmp(set[j].p,p.p) == pOrdSgn)))
2599 *   {
2600 *     return j;
2601 *   }
2602 *   j++;
2603 *   if (j > length) return j;
2604 * }
2605 *}
2606 */
2607{
2608  if (length==-1) return 0;
2609
2610  int o = p.GetpFDeg() + p.ecart;
2611  int op = set[length].GetpFDeg()+set[length].ecart;
2612
2613  if ((op < o)
2614  || ((op == o)
2615     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
2616    return length+1;
2617
2618  int i;
2619  int an = 0;
2620  int en= length;
2621  loop
2622  {
2623    if (an >= en-1)
2624    {
2625      op = set[an].GetpFDeg()+set[an].ecart;
2626      if (( op > o)
2627      || (( op  == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
2628        return an;
2629      return en;
2630    }
2631    i=(an+en) / 2;
2632    op = set[i].GetpFDeg()+set[i].ecart;
2633    if (( op > o)
2634    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
2635      en=i;
2636    else
2637      an=i;
2638  }
2639}
2640
2641/*2
2642* looks up the position of p in set
2643* set[0] is the smallest with respect to the ordering-procedure
2644* pFDeg+ecart, ecart, pComp
2645*/
2646int posInT17 (const TSet set,const int length,LObject &p)
2647/*
2648*{
2649* int j=0;
2650* int  o;
2651*
2652*  o = p.GetpFDeg()+p.ecart;
2653*  loop
2654*  {
2655*    if ((pFDeg(set[j].p)+set[j].ecart > o)
2656*    || (((pFDeg(set[j].p)+set[j].ecart == o)
2657*      && (set[j].ecart < p.ecart)))
2658*    || ((pFDeg(set[j].p)+set[j].ecart == o)
2659*      && (set[j].ecart==p.ecart)
2660*      && (pLmCmp(set[j].p,p.p)==pOrdSgn)))
2661*      return j;
2662*    j++;
2663*    if (j > length) return j;
2664*  }
2665* }
2666*/
2667{
2668  if (length==-1) return 0;
2669
2670  int o = p.GetpFDeg() + p.ecart;
2671  int op = set[length].GetpFDeg()+set[length].ecart;
2672
2673  if ((op < o)
2674  || (( op == o) && (set[length].ecart > p.ecart))
2675  || (( op == o) && (set[length].ecart==p.ecart)
2676     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
2677    return length+1;
2678
2679  int i;
2680  int an = 0;
2681  int en= length;
2682  loop
2683  {
2684    if (an >= en-1)
2685    {
2686      op = set[an].GetpFDeg()+set[an].ecart;
2687      if (( op > o)
2688      || (( op == o) && (set[an].ecart < p.ecart))
2689      || (( op  == o) && (set[an].ecart==p.ecart)
2690         && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
2691        return an;
2692      return en;
2693    }
2694    i=(an+en) / 2;
2695    op = set[i].GetpFDeg()+set[i].ecart;
2696    if ((op > o)
2697    || (( op == o) && (set[i].ecart < p.ecart))
2698    || (( op == o) && (set[i].ecart == p.ecart)
2699       && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
2700      en=i;
2701    else
2702      an=i;
2703  }
2704}
2705/*2
2706* looks up the position of p in set
2707* set[0] is the smallest with respect to the ordering-procedure
2708* pGetComp, pFDeg+ecart, ecart, pComp
2709*/
2710int posInT17_c (const TSet set,const int length,LObject &p)
2711{
2712  if (length==-1) return 0;
2713
2714  int cc = (-1+2*currRing->order[0]==ringorder_c);
2715  /* cc==1 for (c,..), cc==-1 for (C,..) */
2716  int o = p.GetpFDeg() + p.ecart;
2717  int c = pGetComp(p.p)*cc;
2718
2719  if (pGetComp(set[length].p)*cc < c)
2720    return length+1;
2721  if (pGetComp(set[length].p)*cc == c)
2722  {
2723    int op = set[length].GetpFDeg()+set[length].ecart;
2724    if ((op < o)
2725    || ((op == o) && (set[length].ecart > p.ecart))
2726    || ((op == o) && (set[length].ecart==p.ecart)
2727       && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
2728      return length+1;
2729  }
2730
2731  int i;
2732  int an = 0;
2733  int en= length;
2734  loop
2735  {
2736    if (an >= en-1)
2737    {
2738      if (pGetComp(set[an].p)*cc < c)
2739        return en;
2740      if (pGetComp(set[an].p)*cc == c)
2741      {
2742        int op = set[an].GetpFDeg()+set[an].ecart;
2743        if ((op > o)
2744        || ((op == o) && (set[an].ecart < p.ecart))
2745        || ((op == o) && (set[an].ecart==p.ecart)
2746           && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
2747          return an;
2748      }
2749      return en;
2750    }
2751    i=(an+en) / 2;
2752    if (pGetComp(set[i].p)*cc > c)
2753      en=i;
2754    else if (pGetComp(set[i].p)*cc == c)
2755    {
2756      int op = set[i].GetpFDeg()+set[i].ecart;
2757      if ((op > o)
2758      || ((op == o) && (set[i].ecart < p.ecart))
2759      || ((op == o) && (set[i].ecart == p.ecart)
2760         && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
2761        en=i;
2762      else
2763        an=i;
2764    }
2765    else
2766      an=i;
2767  }
2768}
2769
2770/*2
2771* looks up the position of p in set
2772* set[0] is the smallest with respect to
2773* ecart, pFDeg, length
2774*/
2775int posInT19 (const TSet set,const int length,LObject &p)
2776{
2777  if (length==-1) return 0;
2778
2779  int o = p.ecart;
2780  int op=p.GetpFDeg();
2781
2782  if (set[length].ecart < o)
2783    return length+1;
2784  if (set[length].ecart == o)
2785  {
2786     int oo=set[length].GetpFDeg();
2787     if ((oo < op) || ((oo==op) && (set[length].length < p.length)))
2788       return length+1;
2789  }
2790
2791  int i;
2792  int an = 0;
2793  int en= length;
2794  loop
2795  {
2796    if (an >= en-1)
2797    {
2798      if (set[an].ecart > o)
2799        return an;
2800      if (set[an].ecart == o)
2801      {
2802         int oo=set[an].GetpFDeg();
2803         if((oo > op)
2804         || ((oo==op) && (set[an].length > p.length)))
2805           return an;
2806      }
2807      return en;
2808    }
2809    i=(an+en) / 2;
2810    if (set[i].ecart > o)
2811      en=i;
2812    else if (set[i].ecart == o)
2813    {
2814       int oo=set[i].GetpFDeg();
2815       if ((oo > op)
2816       || ((oo == op) && (set[i].length > p.length)))
2817         en=i;
2818       else
2819        an=i;
2820    }
2821    else
2822      an=i;
2823  }
2824}
2825
2826/*2
2827*looks up the position of polynomial p in set
2828*set[length] is the smallest element in set with respect
2829*to the ordering-procedure pComp
2830*/
2831int posInLSpecial (const LSet set, const int length,
2832                   LObject *p,const kStrategy strat)
2833{
2834  if (length<0) return 0;
2835
2836  int d=p->GetpFDeg();
2837  int op=set[length].GetpFDeg();
2838
2839  if ((op > d)
2840  || ((op == d) && (p->p1!=NULL)&&(set[length].p1==NULL))
2841  || (pLmCmp(set[length].p,p->p)== pOrdSgn))
2842     return length+1;
2843
2844  int i;
2845  int an = 0;
2846  int en= length;
2847  loop
2848  {
2849    if (an >= en-1)
2850    {
2851      op=set[an].GetpFDeg();
2852      if ((op > d)
2853      || ((op == d) && (p->p1!=NULL) && (set[an].p1==NULL))
2854      || (pLmCmp(set[an].p,p->p)== pOrdSgn))
2855         return en;
2856      return an;
2857    }
2858    i=(an+en) / 2;
2859    op=set[i].GetpFDeg();
2860    if ((op>d)
2861    || ((op==d) && (p->p1!=NULL) && (set[i].p1==NULL))
2862    || (pLmCmp(set[i].p,p->p) == pOrdSgn))
2863      an=i;
2864    else
2865      en=i;
2866  }
2867}
2868
2869/*2
2870*looks up the position of polynomial p in set
2871*set[length] is the smallest element in set with respect
2872*to the ordering-procedure pComp
2873*/
2874int posInL0 (const LSet set, const int length,
2875             LObject* p,const kStrategy strat)
2876{
2877  if (length<0) return 0;
2878
2879  if (pLmCmp(set[length].p,p->p)== pOrdSgn)
2880    return length+1;
2881
2882  int i;
2883  int an = 0;
2884  int en= length;
2885  loop
2886  {
2887    if (an >= en-1)
2888    {
2889      if (pLmCmp(set[an].p,p->p) == pOrdSgn) return en;
2890      return an;
2891    }
2892    i=(an+en) / 2;
2893    if (pLmCmp(set[i].p,p->p) == pOrdSgn) an=i;
2894    else                                 en=i;
2895    /*aend. fuer lazy == in !=- machen */
2896  }
2897}
2898
2899/*2
2900* looks up the position of polynomial p in set
2901* e is the ecart of p
2902* set[length] is the smallest element in set with respect
2903* to the ordering-procedure totaldegree,pComp
2904*/
2905int posInL11 (const LSet set, const int length,
2906              LObject* p,const kStrategy strat)
2907/*{
2908 * int j=0;
2909 * int o;
2910 *
2911 * o = p->GetpFDeg();
2912 * loop
2913 * {
2914 *   if (j > length)            return j;
2915 *   if ((set[j].GetpFDeg() < o)) return j;
2916 *   if ((set[j].GetpFDeg() == o) && (pLmCmp(set[j].p,p->p) == -pOrdSgn))
2917 *   {
2918 *     return j;
2919 *   }
2920 *   j++;
2921 * }
2922 *}
2923 */
2924{
2925  if (length<0) return 0;
2926
2927  int o = p->GetpFDeg();
2928  int op = set[length].GetpFDeg();
2929
2930  if ((op > o)
2931  || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
2932    return length+1;
2933  int i;
2934  int an = 0;
2935  int en= length;
2936  loop
2937  {
2938    if (an >= en-1)
2939    {
2940      op = set[an].GetpFDeg();
2941      if ((op > o)
2942      || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
2943        return en;
2944      return an;
2945    }
2946    i=(an+en) / 2;
2947    op = set[i].GetpFDeg();
2948    if ((op > o)
2949    || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
2950      an=i;
2951    else
2952      en=i;
2953  }
2954}
2955
2956/*2
2957* looks up the position of polynomial p in set
2958* set[length] is the smallest element in set with respect
2959* to the ordering-procedure totaldegree,pLength0
2960*/
2961int posInL110 (const LSet set, const int length,
2962               LObject* p,const kStrategy strat)
2963{
2964  if (length<0) return 0;
2965
2966  int o = p->GetpFDeg();
2967  int op = set[length].GetpFDeg();
2968
2969  if ((op > o)
2970  || ((op == o) && (set[length].length >p->length))
2971  || ((op == o) && (set[length].length <= p->length)
2972     && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
2973    return length+1;
2974  int i;
2975  int an = 0;
2976  int en= length;
2977  loop
2978  {
2979    if (an >= en-1)
2980    {
2981      op = set[an].GetpFDeg();
2982      if ((op > o)
2983      || ((op == o) && (set[an].length >p->length))
2984      || ((op == o) && (set[an].length <=p->length)
2985         && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
2986        return en;
2987      return an;
2988    }
2989    i=(an+en) / 2;
2990    op = set[i].GetpFDeg();
2991    if ((op > o)
2992    || ((op == o) && (set[i].length > p->length))
2993    || ((op == o) && (set[i].length <= p->length)
2994       && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
2995      an=i;
2996    else
2997      en=i;
2998  }
2999}
3000
3001/*2
3002* looks up the position of polynomial p in set
3003* e is the ecart of p
3004* set[length] is the smallest element in set with respect
3005* to the ordering-procedure totaldegree
3006*/
3007int posInL13 (const LSet set, const int length,
3008              LObject* p,const kStrategy strat)
3009{
3010  if (length<0) return 0;
3011
3012  int o = p->GetpFDeg();
3013
3014  if (set[length].GetpFDeg() > o)
3015    return length+1;
3016
3017  int i;
3018  int an = 0;
3019  int en= length;
3020  loop
3021  {
3022    if (an >= en-1)
3023    {
3024      if (set[an].GetpFDeg() >= o)
3025        return en;
3026      return an;
3027    }
3028    i=(an+en) / 2;
3029    if (set[i].GetpFDeg() >= o)
3030      an=i;
3031    else
3032      en=i;
3033  }
3034}
3035
3036/*2
3037* looks up the position of polynomial p in set
3038* e is the ecart of p
3039* set[length] is the smallest element in set with respect
3040* to the ordering-procedure maximaldegree,pComp
3041*/
3042int posInL15 (const LSet set, const int length,
3043              LObject* p,const kStrategy strat)
3044/*{
3045 * int j=0;
3046 * int o;
3047 *
3048 * o = p->ecart+p->GetpFDeg();
3049 * loop
3050 * {
3051 *   if (j > length)                       return j;
3052 *   if (set[j].GetpFDeg()+set[j].ecart < o) return j;
3053 *   if ((set[j].GetpFDeg()+set[j].ecart == o)
3054 *   && (pLmCmp(set[j].p,p->p) == -pOrdSgn))
3055 *   {
3056 *     return j;
3057 *   }
3058 *   j++;
3059 * }
3060 *}
3061 */
3062{
3063  if (length<0) return 0;
3064
3065  int o = p->GetpFDeg() + p->ecart;
3066  int op = set[length].GetpFDeg() + set[length].ecart;
3067
3068  if ((op > o)
3069  || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
3070    return length+1;
3071  int i;
3072  int an = 0;
3073  int en= length;
3074  loop
3075  {
3076    if (an >= en-1)
3077    {
3078      op = set[an].GetpFDeg() + set[an].ecart;
3079      if ((op > o)
3080      || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3081        return en;
3082      return an;
3083    }
3084    i=(an+en) / 2;
3085    op = set[i].GetpFDeg() + set[i].ecart;
3086    if ((op > o)
3087    || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3088      an=i;
3089    else
3090      en=i;
3091  }
3092}
3093
3094/*2
3095* looks up the position of polynomial p in set
3096* e is the ecart of p
3097* set[length] is the smallest element in set with respect
3098* to the ordering-procedure totaldegree
3099*/
3100int posInL17 (const LSet set, const int length,
3101              LObject* p,const kStrategy strat)
3102{
3103  if (length<0) return 0;
3104
3105  int o = p->GetpFDeg() + p->ecart;
3106
3107  if ((set[length].GetpFDeg() + set[length].ecart > o)
3108  || ((set[length].GetpFDeg() + set[length].ecart == o)
3109     && (set[length].ecart > p->ecart))
3110  || ((set[length].GetpFDeg() + set[length].ecart == o)
3111     && (set[length].ecart == p->ecart)
3112     && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
3113    return length+1;
3114  int i;
3115  int an = 0;
3116  int en= length;
3117  loop
3118  {
3119    if (an >= en-1)
3120    {
3121      if ((set[an].GetpFDeg() + set[an].ecart > o)
3122      || ((set[an].GetpFDeg() + set[an].ecart == o)
3123         && (set[an].ecart > p->ecart))
3124      || ((set[an].GetpFDeg() + set[an].ecart == o)
3125         && (set[an].ecart == p->ecart)
3126         && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3127        return en;
3128      return an;
3129    }
3130    i=(an+en) / 2;
3131    if ((set[i].GetpFDeg() + set[i].ecart > o)
3132    || ((set[i].GetpFDeg() + set[i].ecart == o)
3133       && (set[i].ecart > p->ecart))
3134    || ((set[i].GetpFDeg() +set[i].ecart == o)
3135       && (set[i].ecart == p->ecart)
3136       && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3137      an=i;
3138    else
3139      en=i;
3140  }
3141}
3142/*2
3143* looks up the position of polynomial p in set
3144* e is the ecart of p
3145* set[length] is the smallest element in set with respect
3146* to the ordering-procedure pComp
3147*/
3148int posInL17_c (const LSet set, const int length,
3149                LObject* p,const kStrategy strat)
3150{
3151  if (length<0) return 0;
3152
3153  int cc = (-1+2*currRing->order[0]==ringorder_c);
3154  /* cc==1 for (c,..), cc==-1 for (C,..) */
3155  int c = pGetComp(p->p)*cc;
3156  int o = p->GetpFDeg() + p->ecart;
3157
3158  if (pGetComp(set[length].p)*cc > c)
3159    return length+1;
3160  if (pGetComp(set[length].p)*cc == c)
3161  {
3162    if ((set[length].GetpFDeg() + set[length].ecart > o)
3163    || ((set[length].GetpFDeg() + set[length].ecart == o)
3164       && (set[length].ecart > p->ecart))
3165    || ((set[length].GetpFDeg() + set[length].ecart == o)
3166       && (set[length].ecart == p->ecart)
3167       && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
3168      return length+1;
3169  }
3170  int i;
3171  int an = 0;
3172  int en= length;
3173  loop
3174  {
3175    if (an >= en-1)
3176    {
3177      if (pGetComp(set[an].p)*cc > c)
3178        return en;
3179      if (pGetComp(set[an].p)*cc == c)
3180      {
3181        if ((set[an].GetpFDeg() + set[an].ecart > o)
3182        || ((set[an].GetpFDeg() + set[an].ecart == o)
3183           && (set[an].ecart > p->ecart))
3184        || ((set[an].GetpFDeg() + set[an].ecart == o)
3185           && (set[an].ecart == p->ecart)
3186           && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
3187          return en;
3188      }
3189      return an;
3190    }
3191    i=(an+en) / 2;
3192    if (pGetComp(set[i].p)*cc > c)
3193      an=i;
3194    else if (pGetComp(set[i].p)*cc == c)
3195    {
3196      if ((set[i].GetpFDeg() + set[i].ecart > o)
3197      || ((set[i].GetpFDeg() + set[i].ecart == o)
3198         && (set[i].ecart > p->ecart))
3199      || ((set[i].GetpFDeg() +set[i].ecart == o)
3200         && (set[i].ecart == p->ecart)
3201         && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
3202        an=i;
3203      else
3204        en=i;
3205    }
3206    else
3207      en=i;
3208  }
3209}
3210
3211/***************************************************************
3212 *
3213 * Tail reductions
3214 *
3215 ***************************************************************/
3216TObject*
3217kFindDivisibleByInS(kStrategy strat, int pos, LObject* L, TObject *T,
3218                    long ecart)
3219{
3220  int j = 0;
3221  const unsigned long not_sev = ~L->sev;
3222  const unsigned long* sev = strat->sevS;
3223  poly p;
3224  ring r;
3225  L->GetLm(p, r);
3226
3227  assume(~not_sev == p_GetShortExpVector(p, r));
3228
3229  if (r == currRing)
3230  {
3231    loop
3232    {
3233      if (j > pos) return NULL;
3234#if defined(PDEBUG) || defined(PDIV_DEBUG)
3235      if (p_LmShortDivisibleBy(strat->S[j], sev[j], p, not_sev, r) &&
3236          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
3237        break;
3238#else
3239      if (!(sev[j] & not_sev) &&
3240          (ecart== LONG_MAX || ecart>= strat->ecartS[j]) &&
3241          p_LmDivisibleBy(strat->S[j], p, r))
3242        break;
3243
3244#endif
3245      j++;
3246    }
3247    // if called from NF, T objects do not exist:
3248    if (strat->tl < 0 || strat->S_2_R[j] == -1)
3249    {
3250      T->Set(strat->S[j], r, strat->tailRing);
3251      return T;
3252    }
3253    else
3254    {
3255      assume (j >= 0 && j <= strat->tl && strat->S_2_T(j) != NULL &&
3256              strat->S_2_T(j)->p == strat->S[j]);
3257      return strat->S_2_T(j);
3258    }
3259  }
3260  else
3261  {
3262    TObject* t;
3263    loop
3264    {
3265      if (j > pos) return NULL;
3266      assume(strat->S_2_R[j] != -1);
3267#if defined(PDEBUG) || defined(PDIV_DEBUG)
3268      t = strat->S_2_T(j);
3269      assume(t != NULL && t->t_p != NULL && t->tailRing == r);
3270      if (p_LmShortDivisibleBy(t->t_p, sev[j], p, not_sev, r) &&
3271          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
3272        return t;
3273#else
3274      if (! (sev[j] & not_sev) && (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
3275      {
3276        t = strat->S_2_T(j);
3277        assume(t != NULL && t->t_p != NULL && t->tailRing == r && t->p == strat->S[j]);
3278        if (p_LmDivisibleBy(t->t_p, p, r)) return t;
3279      }
3280#endif
3281      j++;
3282    }
3283  }
3284}
3285/*
3286#ifdef HAVE_RING2TOM
3287TObject*
3288kRingFindDivisibleByInS(kStrategy strat, int pos, LObject* L, TObject *T,
3289                    long ecart)
3290{
3291  int j = 0;
3292  const unsigned long not_sev = ~L->sev;
3293  const unsigned long* sev = strat->sevS;
3294  poly p;
3295  ring r;
3296  L->GetLm(p, r);
3297
3298  assume(~not_sev == p_GetShortExpVector(p, r));
3299
3300  if (r == currRing)
3301  {
3302    loop
3303    {
3304      if (j > pos) return NULL;
3305#if defined(PDEBUG) || defined(PDIV_DEBUG)
3306      if (p_LmRingShortDivisibleBy(strat->S[j], sev[j], p, not_sev, r) &&
3307          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
3308        break;
3309#else
3310      if (!(sev[j] & not_sev) &&
3311          (ecart== LONG_MAX || ecart>= strat->ecartS[j]) &&
3312          p_LmRingDivisibleBy(strat->S[j], p, r))
3313        break;
3314
3315#endif
3316      j++;
3317    }
3318    // if called from NF, T objects do not exist:
3319    if (strat->tl < 0 || strat->S_2_R[j] == -1)
3320    {
3321      T->Set(strat->S[j], r, strat->tailRing);
3322      return T;
3323    }
3324    else
3325    {
3326      assume (j >= 0 && j <= strat->tl && strat->S_2_T(j) != NULL &&
3327              strat->S_2_T(j)->p == strat->S[j]);
3328      return strat->S_2_T(j);
3329    }
3330  }
3331  else
3332  {
3333    TObject* t;
3334    loop
3335    {
3336      if (j > pos) return NULL;
3337      assume(strat->S_2_R[j] != -1);
3338#if defined(PDEBUG) || defined(PDIV_DEBUG)
3339      t = strat->S_2_T(j);
3340      assume(t != NULL && t->t_p != NULL && t->tailRing == r);
3341      if (p_LmRingShortDivisibleBy(t->t_p, sev[j], p, not_sev, r) &&
3342          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
3343        return t;
3344#else
3345      if (! (sev[j] & not_sev) && (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
3346      {
3347        t = strat->S_2_T(j);
3348        assume(t != NULL && t->t_p != NULL && t->tailRing == r && t->p == strat->S[j]);
3349        if (p_LmRingDivisibleBy(t->t_p, p, r)) return t;
3350      }
3351#endif
3352      j++;
3353    }
3354  }
3355}
3356#endif
3357*/
3358
3359poly redtail (LObject* L, int pos, kStrategy strat)
3360{
3361  poly h, hn;
3362  int j;
3363  unsigned long not_sev;
3364  strat->redTailChange=FALSE;
3365
3366  poly p = L->p;
3367  if (strat->noTailReduction || pNext(p) == NULL)
3368    return p;
3369
3370  LObject Ln(strat->tailRing);
3371  TObject* With;
3372  // placeholder in case strat->tl < 0
3373  TObject  With_s(strat->tailRing);
3374  h = p;
3375  hn = pNext(h);
3376  long op = strat->tailRing->pFDeg(hn, strat->tailRing);
3377  long e;
3378  int l;
3379  BOOLEAN save_HE=strat->kHEdgeFound;
3380  strat->kHEdgeFound |=
3381    ((Kstd1_deg>0) && (op<=Kstd1_deg)) || TEST_OPT_INFREDTAIL;
3382
3383  while(hn != NULL)
3384  {
3385    op = strat->tailRing->pFDeg(hn, strat->tailRing);
3386    if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
3387    e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
3388    loop
3389    {
3390      Ln.Set(hn, strat->tailRing);
3391      Ln.sev = p_GetShortExpVector(hn, strat->tailRing);
3392      if (strat->kHEdgeFound)
3393        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
3394      else
3395        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s, e);
3396      if (With == NULL) break;
3397      strat->redTailChange=TRUE;
3398      if (ksReducePolyTail(L, With, h, strat->kNoetherTail()))
3399      {
3400        // reducing the tail would violate the exp bound
3401        if (kStratChangeTailRing(strat, L))
3402        {
3403          strat->kHEdgeFound = save_HE;
3404          return redtail(L, pos, strat);
3405        }
3406        else
3407          return NULL;
3408      }
3409      hn = pNext(h);
3410      if (hn == NULL) goto all_done;
3411      op = strat->tailRing->pFDeg(hn, strat->tailRing);
3412      if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
3413      e = strat->tailRing->pLDeg(hn, &l, strat->tailRing) - op;
3414    }
3415    h = hn;
3416    hn = pNext(h);
3417  }
3418
3419  all_done:
3420  if (strat->redTailChange)
3421  {
3422    L->last = 0;
3423    L->pLength = 0;
3424  }
3425  strat->kHEdgeFound = save_HE;
3426  return p;
3427}
3428
3429poly redtail (poly p, int pos, kStrategy strat)
3430{
3431  LObject L(p, currRing);
3432  return redtail(&L, pos, strat);
3433}
3434
3435poly redtailBba (LObject* L, int pos, kStrategy strat, BOOLEAN withT)
3436{
3437  strat->redTailChange=FALSE;
3438  if (strat->noTailReduction) return L->GetLmCurrRing();
3439  poly h, p;
3440  p = h = L->GetLmTailRing();
3441  if ((h==NULL) || (pNext(h)==NULL))
3442    return L->GetLmCurrRing();
3443
3444  TObject* With;
3445  // placeholder in case strat->tl < 0
3446  TObject  With_s(strat->tailRing);
3447
3448  LObject Ln(pNext(h), strat->tailRing);
3449  Ln.pLength = L->GetpLength() - 1;
3450
3451  pNext(h) = NULL;
3452  if (L->p != NULL) pNext(L->p) = NULL;
3453  L->pLength = 1;
3454
3455  Ln.PrepareRed(strat->use_buckets);
3456
3457  while(!Ln.IsNull())
3458  {
3459    loop
3460    {
3461      Ln.SetShortExpVector();
3462      if (! withT)
3463      {
3464/* obsolete
3465#ifdef HAVE_RING2TOM
3466        if (currRing->cring == 1) {
3467            With = kRingFindDivisibleByInS(strat, pos, &Ln, &With_s);
3468        } else
3469#endif
3470*/
3471            With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
3472        if (With == NULL) break;
3473      }
3474      else
3475      {
3476        int j;
3477/* Obsolete
3478#ifdef HAVE_RING2TOM
3479        if (currRing->cring == 1) {
3480           j = kRingFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
3481        } else
3482#endif
3483*/
3484           j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
3485        if (j < 0) break;
3486        With = &(strat->T[j]);
3487      }
3488      if (ksReducePolyTail(L, With, &Ln))
3489      {
3490        // reducing the tail would violate the exp bound
3491        pNext(h) = Ln.GetTP();
3492        L->pLength += Ln.GetpLength();
3493        if (L->p != NULL) pNext(L->p) = pNext(p);
3494        if (kStratChangeTailRing(strat, L))
3495          return redtailBba(L, pos, strat, withT);
3496        else
3497        { // should never get here -- need to fix this
3498          assume(0);
3499          return NULL;
3500        }
3501      }
3502      strat->redTailChange=TRUE;
3503      if (Ln.IsNull()) goto all_done;
3504      if (! withT) With_s.Init(currRing);
3505    }
3506    pNext(h) = Ln.LmExtractAndIter();
3507    pIter(h);
3508    L->pLength++;
3509  }
3510
3511  all_done:
3512  if (L->p != NULL) pNext(L->p) = pNext(p);
3513  assume(pLength(L->p != NULL ? L->p : L->t_p) == L->pLength);
3514
3515  if (strat->redTailChange)
3516  {
3517    L->last = NULL;
3518    L->length = 0;
3519  }
3520  L->Normalize(); // HANNES: should have a test
3521  kTest_L(L);
3522  return L->GetLmCurrRing();
3523}
3524
3525/*2
3526*checks the change degree and write progress report
3527*/
3528void message (int i,int* reduc,int* olddeg,kStrategy strat, int red_result)
3529{
3530  if (i != *olddeg)
3531  {
3532    Print("%d",i);
3533    *olddeg = i;
3534  }
3535  if (K_TEST_OPT_OLDSTD)
3536  {
3537    if (strat->Ll != *reduc)
3538    {
3539      if (strat->Ll != *reduc-1)
3540        Print("(%d)",strat->Ll+1);
3541      else
3542        PrintS("-");
3543      *reduc = strat->Ll;
3544    }
3545    else
3546      PrintS(".");
3547    mflush();
3548  }
3549  else
3550  {
3551    if (red_result == 0)
3552      PrintS("-");
3553    else if (red_result < 0)
3554      PrintS(".");
3555    if ((red_result > 0) || ((strat->Ll % 100)==99))
3556    {
3557      if (strat->Ll != *reduc && strat->Ll > 0)
3558      {
3559        Print("(%d)",strat->Ll+1);
3560        *reduc = strat->Ll;
3561      }
3562    }
3563  }
3564}
3565
3566/*2
3567*statistics
3568*/
3569void messageStat (int srmax,int lrmax,int hilbcount,kStrategy strat)
3570{
3571  //PrintS("\nUsage/Allocation of temporary storage:\n");
3572  //Print("%d/%d polynomials in standard base\n",srmax,IDELEMS(Shdl));
3573  //Print("%d/%d polynomials in set L (for lazy alg.)",lrmax+1,strat->Lmax);
3574  Print("\nproduct criterion:%d chain criterion:%d\n",strat->cp,strat->c3);
3575  if (hilbcount!=0) Print("hilbert series criterion:%d\n",hilbcount);
3576  /*mflush();*/
3577}
3578
3579#ifdef KDEBUG
3580/*2
3581*debugging output: all internal sets, if changed
3582*for testing purpuse only/has to be changed for later use
3583*/
3584void messageSets (kStrategy strat)
3585{
3586  int i;
3587  if (strat->news)
3588  {
3589    PrintS("set S");
3590    for (i=0; i<=strat->sl; i++)
3591    {
3592      Print("\n  %d:",i);
3593      p_wrp(strat->S[i], currRing, strat->tailRing);
3594    }
3595    strat->news = FALSE;
3596  }
3597  if (strat->newt)
3598  {
3599    PrintS("\nset T");
3600    for (i=0; i<=strat->tl; i++)
3601    {
3602      Print("\n  %d:",i);
3603      strat->T[i].wrp();
3604      Print(" o:%d e:%d l:%d",
3605        strat->T[i].pFDeg(),strat->T[i].ecart,strat->T[i].length);
3606    }
3607    strat->newt = FALSE;
3608  }
3609  PrintS("\nset L");
3610  for (i=strat->Ll; i>=0; i--)
3611  {
3612    Print("\n%d:",i);
3613    p_wrp(strat->L[i].p1, currRing, strat->tailRing);
3614    PrintS("  ");
3615    p_wrp(strat->L[i].p2, currRing, strat->tailRing);
3616    PrintS(" lcm: ");p_wrp(strat->L[i].lcm, currRing);
3617    PrintS("\n  p : ");
3618    strat->L[i].wrp();
3619    Print("  o:%d e:%d l:%d",
3620          strat->L[i].pFDeg(),strat->L[i].ecart,strat->L[i].length);
3621  }
3622  PrintLn();
3623}
3624
3625#endif
3626
3627
3628/*2
3629*construct the set s from F
3630*/
3631void initS (ideal F, ideal Q,kStrategy strat)
3632{
3633  int   i,pos;
3634
3635  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
3636  else i=setmaxT;
3637  strat->ecartS=initec(i);
3638  strat->sevS=initsevS(i);
3639  strat->S_2_R=initS_2_R(i);
3640  strat->fromQ=NULL;
3641  strat->Shdl=idInit(i,F->rank);
3642  strat->S=strat->Shdl->m;
3643  /*- put polys into S -*/
3644  if (Q!=NULL)
3645  {
3646    strat->fromQ=initec(i);
3647    memset(strat->fromQ,0,i*sizeof(int));
3648    for (i=0; i<IDELEMS(Q); i++)
3649    {
3650      if (Q->m[i]!=NULL)
3651      {
3652        LObject h;
3653        h.p = pCopy(Q->m[i]);
3654        if (TEST_OPT_INTSTRATEGY)
3655        {
3656          //pContent(h.p);
3657          h.pCleardenom(); // also does a pContent
3658        }
3659        else
3660        {
3661          h.pNorm();
3662        }
3663        strat->initEcart(&h);
3664        if (pOrdSgn==-1)
3665        {
3666          deleteHC(&h, strat);
3667        }
3668        if (h.p!=NULL)
3669        {
3670          if (strat->sl==-1)
3671            pos =0;
3672          else
3673          {
3674            pos = posInS(strat,strat->sl,h.p,h.ecart);
3675          }
3676          h.sev = pGetShortExpVector(h.p);
3677          strat->enterS(h,pos,strat,-1);
3678          strat->fromQ[pos]=1;
3679        }
3680      }
3681    }
3682  }
3683  for (i=0; i<IDELEMS(F); i++)
3684  {
3685    if (F->m[i]!=NULL)
3686    {
3687      LObject h;
3688      h.p = pCopy(F->m[i]);
3689      if (TEST_OPT_INTSTRATEGY)
3690      {
3691        //pContent(h.p);
3692        h.pCleardenom(); // also does a pContent
3693      }
3694      else
3695      {
3696        h.pNorm();
3697      }
3698      strat->initEcart(&h);
3699      if (pOrdSgn==-1)
3700      {
3701        cancelunit(&h);  /*- tries to cancel a unit -*/
3702        deleteHC(&h, strat);
3703      }
3704      if (h.p!=NULL)
3705      {
3706        if (strat->sl==-1)
3707          pos =0;
3708        else
3709          pos = posInS(strat,strat->sl,h.p,h.ecart);
3710        h.sev = pGetShortExpVector(h.p);
3711        strat->enterS(h,pos,strat,-1);
3712      }
3713    }
3714  }
3715  /*- test, if a unit is in F -*/
3716  if ((strat->sl>=0) && pIsConstant(strat->S[0]))
3717  {
3718    while (strat->sl>0) deleteInS(strat->sl,strat);
3719  }
3720}
3721
3722void initSL (ideal F, ideal Q,kStrategy strat)
3723{
3724  int   i,pos;
3725
3726  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
3727  else i=setmaxT;
3728  strat->ecartS=initec(i);
3729  strat->sevS=initsevS(i);
3730  strat->S_2_R=initS_2_R(i);
3731  strat->fromQ=NULL;
3732  strat->Shdl=idInit(i,F->rank);
3733  strat->S=strat->Shdl->m;
3734  /*- put polys into S -*/
3735  if (Q!=NULL)
3736  {
3737    strat->fromQ=initec(i);
3738    memset(strat->fromQ,0,i*sizeof(int));
3739    for (i=0; i<IDELEMS(Q); i++)
3740    {
3741      if (Q->m[i]!=NULL)
3742      {
3743        LObject h;
3744        h.p = pCopy(Q->m[i]);
3745        if (TEST_OPT_INTSTRATEGY)
3746        {
3747          //pContent(h.p);
3748          h.pCleardenom(); // also does a pContent
3749        }
3750        else
3751        {
3752          h.pNorm();
3753        }
3754        strat->initEcart(&h);
3755        if (pOrdSgn==-1)
3756        {
3757          deleteHC(&h,strat);
3758        }
3759        if (h.p!=NULL)
3760        {
3761          if (strat->sl==-1)
3762            pos =0;
3763          else
3764          {
3765            pos = posInS(strat,strat->sl,h.p,h.ecart);
3766          }
3767          h.sev = pGetShortExpVector(h.p);
3768          strat->enterS(h,pos,strat,-1);
3769          strat->fromQ[pos]=1;
3770        }
3771      }
3772    }
3773  }
3774  for (i=0; i<IDELEMS(F); i++)
3775  {
3776    if (F->m[i]!=NULL)
3777    {
3778      LObject h;
3779      h.p = pCopy(F->m[i]);
3780      if (TEST_OPT_INTSTRATEGY)
3781      {
3782        //pContent(h.p);
3783        h.pCleardenom(); // also does a pContent
3784      }
3785      else
3786      {
3787        h.pNorm();
3788      }
3789      strat->initEcart(&h);
3790      if (pOrdSgn==-1)
3791      {
3792        cancelunit(&h);  /*- tries to cancel a unit -*/
3793        deleteHC(&h, strat);
3794      }
3795      if (h.p!=NULL)
3796      {
3797        if (strat->Ll==-1)
3798          pos =0;
3799        else
3800          pos = strat->posInL(strat->L,strat->Ll,&h,strat);
3801        h.sev = pGetShortExpVector(h.p);
3802        enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
3803      }
3804    }
3805  }
3806  /*- test, if a unit is in F -*/
3807  if ((strat->Ll>=0) && pIsConstant(strat->L[strat->Ll].p))
3808  {
3809    while (strat->Ll>0) deleteInL(strat->L,&strat->Ll,strat->Ll-1,strat);
3810  }
3811}
3812
3813
3814/*2
3815*construct the set s from F and {P}
3816*/
3817void initSSpecial (ideal F, ideal Q, ideal P,kStrategy strat)
3818{
3819  int   i,pos;
3820
3821  if (Q!=NULL) i=((IDELEMS(Q)+(setmaxTinc-1))/setmaxTinc)*setmaxTinc;
3822  else i=setmaxT;
3823  i=((i+IDELEMS(F)+15)/16)*16;
3824  strat->ecartS=initec(i);
3825  strat->sevS=initsevS(i);
3826  strat->S_2_R=initS_2_R(i);
3827  strat->fromQ=NULL;
3828  strat->Shdl=idInit(i,F->rank);
3829  strat->S=strat->Shdl->m;
3830
3831  /*- put polys into S -*/
3832  if (Q!=NULL)
3833  {
3834    strat->fromQ=initec(i);
3835    memset(strat->fromQ,0,i*sizeof(int));
3836    for (i=0; i<IDELEMS(Q); i++)
3837    {
3838      if (Q->m[i]!=NULL)
3839      {
3840        LObject h;
3841        h.p = pCopy(Q->m[i]);
3842        //if (TEST_OPT_INTSTRATEGY)
3843        //{
3844        //  //pContent(h.p);
3845        //  h.pCleardenom(); // also does a pContent
3846        //}
3847        //else
3848        //{
3849        //  h.pNorm();
3850        //}
3851        strat->initEcart(&h);
3852        if (pOrdSgn==-1)
3853        {
3854          deleteHC(&h,strat);
3855        }
3856        if (h.p!=NULL)
3857        {
3858          if (strat->sl==-1)
3859            pos =0;
3860          else
3861          {
3862            pos = posInS(strat,strat->sl,h.p,h.ecart);
3863          }
3864          h.sev = pGetShortExpVector(h.p);
3865          h.SetpFDeg();
3866          strat->enterS(h,pos,strat, strat->tl+1);
3867          enterT(h, strat);
3868          strat->fromQ[pos]=1;
3869        }
3870      }
3871    }
3872  }
3873  /*- put polys into S -*/
3874  for (i=0; i<IDELEMS(F); i++)
3875  {
3876    if (F->m[i]!=NULL)
3877    {
3878      LObject h;
3879      h.p = pCopy(F->m[i]);
3880      if (pOrdSgn==1)
3881      {
3882        h.p=redtailBba(h.p,strat->sl,strat);
3883      }
3884      strat->initEcart(&h);
3885      if (pOrdSgn==-1)
3886      {
3887        deleteHC(&h,strat);
3888      }
3889      if (h.p!=NULL)
3890      {
3891        if (strat->sl==-1)
3892          pos =0;
3893        else
3894          pos = posInS(strat,strat->sl,h.p,h.ecart);
3895        h.sev = pGetShortExpVector(h.p);
3896        strat->enterS(h,pos,strat, strat->tl+1);
3897        h.length = pLength(h.p);
3898        h.SetpFDeg();
3899        enterT(h,strat);
3900      }
3901    }
3902  }
3903  for (i=0; i<IDELEMS(P); i++)
3904  {
3905    if (P->m[i]!=NULL)
3906    {
3907      LObject h;
3908      h.p=pCopy(P->m[i]);
3909      strat->initEcart(&h);
3910      h.length = pLength(h.p);
3911      if (TEST_OPT_INTSTRATEGY)
3912      {
3913        h.pCleardenom();
3914      }
3915      else
3916      {
3917        h.pNorm();
3918      }
3919      if(strat->sl>=0)
3920      {
3921        if (pOrdSgn==1)
3922        {
3923          h.p=redBba(h.p,strat->sl,strat);
3924          if (h.p!=NULL)
3925            h.p=redtailBba(h.p,strat->sl,strat);
3926        }
3927        else
3928        {
3929          h.p=redMora(h.p,strat->sl,strat);
3930          strat->initEcart(&h);
3931        }
3932        if(h.p!=NULL)
3933        {
3934          if (TEST_OPT_INTSTRATEGY)
3935          {
3936            h.pCleardenom();
3937          }
3938          else
3939          {
3940            h.is_normalized = 0;
3941            h.pNorm();
3942          }
3943          h.sev = pGetShortExpVector(h.p);
3944          h.SetpFDeg();
3945          pos = posInS(strat,strat->sl,h.p,h.ecart);
3946          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
3947          strat->enterS(h,pos,strat, strat->tl+1);
3948          enterT(h,strat);
3949        }
3950      }
3951      else
3952      {
3953        h.sev = pGetShortExpVector(h.p);
3954        h.SetpFDeg();
3955        strat->enterS(h,0,strat, strat->tl+1);
3956        enterT(h,strat);
3957      }
3958    }
3959  }
3960}
3961/*2
3962* reduces h using the set S
3963* procedure used in cancelunit1
3964*/
3965static poly redBba1 (poly h,int maxIndex,kStrategy strat)
3966{
3967  int j = 0;
3968  unsigned long not_sev = ~ pGetShortExpVector(h);
3969
3970  while (j <= maxIndex)
3971  {
3972    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j],h, not_sev))
3973       return ksOldSpolyRedNew(strat->S[j],h,strat->kNoetherTail());
3974    else j++;
3975  }
3976  return h;
3977}
3978
3979/*2
3980*tests if p.p=monomial*unit and cancels the unit
3981*/
3982void cancelunit1 (LObject* p,int *suc, int index,kStrategy strat )
3983{
3984  int k;
3985  poly r,h,h1,q;
3986
3987  if (!pIsVector((*p).p) && ((*p).ecart != 0))
3988  {
3989    k = 0;
3990    h1 = r = pCopy((*p).p);
3991    h =pNext(r);
3992    loop
3993    {
3994      if (h==NULL)
3995      {
3996        pDelete(&r);
3997        pDelete(&(pNext((*p).p)));
3998        (*p).ecart = 0;
3999        (*p).length = 1;
4000        (*suc)=0;
4001        return;
4002      }
4003      if (!pDivisibleBy(r,h))
4004      {
4005        q=redBba1(h,index ,strat);
4006        if (q != h)
4007        {
4008          k++;
4009          pDelete(&h);
4010          pNext(h1) = h = q;
4011        }
4012        else
4013        {
4014          pDelete(&r);
4015          return;
4016        }
4017      }
4018      else
4019      {
4020        h1 = h;
4021        pIter(h);
4022      }
4023      if (k > 10)
4024      {
4025        pDelete(&r);
4026        return;
4027      }
4028    }
4029  }
4030}
4031
4032/*2
4033* reduces h using the elements from Q in the set S
4034* procedure used in updateS
4035* must not be used for elements of Q or elements of an ideal !
4036*/
4037static poly redQ (poly h, int j, kStrategy strat)
4038{
4039  int start;
4040  unsigned long not_sev = ~ pGetShortExpVector(h);
4041  while ((j <= strat->sl) && (pGetComp(strat->S[j])!=0)) j++;
4042  start=j;
4043  while (j<=strat->sl)
4044  {
4045    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
4046    {
4047      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
4048      if (h==NULL) return NULL;
4049      j = start;
4050      not_sev = ~ pGetShortExpVector(h);
4051    }
4052    else j++;
4053  }
4054  return h;
4055}
4056
4057/*2
4058* reduces h using the set S
4059* procedure used in updateS
4060*/
4061static poly redBba (poly h,int maxIndex,kStrategy strat)
4062{
4063  int j = 0;
4064  unsigned long not_sev = ~ pGetShortExpVector(h);
4065
4066  while (j <= maxIndex)
4067  {
4068#ifdef HAVE_RING2TOM
4069    if ((currRing->cring == 1 && pLmRingShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev)) ||
4070        (currRing->cring == 0 && pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev)))
4071#else
4072    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
4073#endif
4074    {
4075      h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
4076      if (h==NULL) return NULL;
4077      j = 0;
4078      not_sev = ~ pGetShortExpVector(h);    }
4079    else j++;
4080  }
4081  return h;
4082}
4083
4084/*2
4085* reduces h using the set S
4086*e is the ecart of h
4087*procedure used in updateS
4088*/
4089static poly redMora (poly h,int maxIndex,kStrategy strat)
4090{
4091  int  j=0;
4092  int  e,l;
4093  unsigned long not_sev = ~ pGetShortExpVector(h);
4094
4095  if (maxIndex >= 0)
4096  {
4097    e = pLDeg(h,&l,currRing)-pFDeg(h,currRing);
4098    do
4099    {
4100      if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev)
4101      && ((e >= strat->ecartS[j]) || strat->kHEdgeFound))
4102      {
4103#ifdef KDEBUG
4104        if (TEST_OPT_DEBUG)
4105          {PrintS("reduce ");wrp(h);Print(" with S[%d] (",j);wrp(strat->S[j]);}
4106
4107#endif
4108        h = ksOldSpolyRed(strat->S[j],h,strat->kNoetherTail());
4109#ifdef KDEBUG
4110        if(TEST_OPT_DEBUG)
4111          {PrintS(")\nto "); wrp(h); PrintLn();}
4112
4113#endif
4114        // pDelete(&h);
4115        if (h == NULL) return NULL;
4116        e = pLDeg(h,&l,currRing)-pFDeg(h,currRing);
4117        j = 0;
4118        not_sev = ~ pGetShortExpVector(h);
4119      }
4120      else j++;
4121    }
4122    while (j <= maxIndex);
4123  }
4124  return h;
4125}
4126
4127/*2
4128*updates S:
4129*the result is a set of polynomials which are in
4130*normalform with respect to S
4131*/
4132void updateS(BOOLEAN toT,kStrategy strat)
4133{
4134  LObject h;
4135  int i, suc=0;
4136  poly redSi=NULL;
4137//  Print("nach initS: updateS start mit sl=%d\n",(strat->sl));
4138//  for (i=0; i<=(strat->sl); i++)
4139//  {
4140//    Print("s%d:",i);
4141//    if (strat->fromQ!=NULL) Print("(Q:%d) ",strat->fromQ[i]);
4142//    pWrite(strat->S[i]);
4143//  }
4144//  Print("pOrdSgn=%d\n", pOrdSgn);
4145  if (pOrdSgn==1)
4146  {
4147    while (suc != -1)
4148    {
4149      i=suc+1;
4150      while (i<=strat->sl)
4151      {
4152        if (((strat->syzComp==0) || (pGetComp(strat->S[i])<=strat->syzComp))
4153        && ((strat->fromQ==NULL) || (strat->fromQ[i]==0)))
4154        {
4155          pDelete(&redSi);
4156          redSi = pHead(strat->S[i]);
4157          strat->S[i] = redBba(strat->S[i],i-1,strat);
4158          if ((strat->ak!=0)&&(strat->S[i]!=NULL))
4159            strat->S[i]=redQ(strat->S[i],i+1,strat); /*reduce S[i] mod Q*/
4160          if (TEST_OPT_DEBUG && (pCmp(redSi,strat->S[i])!=0))
4161          {
4162            PrintS("reduce:");
4163            wrp(redSi);PrintS(" to ");p_wrp(strat->S[i], currRing, strat->tailRing);PrintLn();
4164          }
4165          if (TEST_OPT_PROT && (pCmp(redSi,strat->S[i])!=0))
4166          {
4167            if (strat->S[i]==NULL)
4168              PrintS("V");
4169            else
4170              PrintS("v");
4171            mflush();
4172          }
4173          if (strat->S[i]==NULL)
4174          {
4175            pDelete(&redSi);
4176            deleteInS(i,strat);
4177            i--;
4178          }
4179          else
4180          {
4181            pDelete(&redSi);
4182            if (TEST_OPT_INTSTRATEGY)
4183            {
4184              //pContent(strat->S[i]);
4185              pCleardenom(strat->S[i]);// also does a pContent
4186            }
4187            else
4188            {
4189              pNorm(strat->S[i]);
4190            }
4191            strat->sevS[i] = pGetShortExpVector(strat->S[i]);
4192          }
4193        }
4194        i++;
4195      }
4196      reorderS(&suc,strat);
4197    }
4198    if (toT)
4199    {
4200      for (i=0; i<=strat->sl; i++)
4201      {
4202        if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
4203        {
4204          h.p = redtailBba(strat->S[i],i-1,strat);
4205          if (TEST_OPT_INTSTRATEGY)
4206          {
4207            pCleardenom(h.p);// also does a pContent
4208          }
4209        }
4210        else
4211        {
4212          h.p = strat->S[i];
4213        }
4214        if (strat->honey)
4215        {
4216          strat->initEcart(&h);
4217          strat->ecartS[i] = h.ecart;
4218        }
4219        if (strat->sevS[i] == 0) {strat->sevS[i] = pGetShortExpVector(h.p);}
4220        else assume(strat->sevS[i] == pGetShortExpVector(h.p));
4221        h.sev = strat->sevS[i];
4222        h.SetpFDeg();
4223        /*puts the elements of S also to T*/
4224        enterT(h,strat);
4225        strat->S_2_R[i] = strat->tl;
4226      }
4227    }
4228  }
4229  else
4230  {
4231    while (suc != -1)
4232    {
4233      i=suc;
4234      while (i<=strat->sl)
4235      {
4236        if (((strat->syzComp==0) || (pGetComp(strat->S[i])<=strat->syzComp))
4237        && ((strat->fromQ==NULL) || (strat->fromQ[i]==0)))
4238        {
4239          pDelete(&redSi);
4240          redSi=pHead((strat->S)[i]);
4241          (strat->S)[i] = redMora((strat->S)[i],i-1,strat);
4242          if ((strat->S)[i]==NULL)
4243          {
4244            deleteInS(i,strat);
4245            i--;
4246          }
4247          else
4248          {
4249            if (TEST_OPT_INTSTRATEGY)
4250            {
4251              pDelete(&redSi);
4252              pCleardenom(strat->S[i]);// also does a pContent
4253              h.p = strat->S[i];
4254              strat->initEcart(&h);
4255              strat->ecartS[i] = h.ecart;
4256            }
4257            else
4258            {
4259              pDelete(&redSi);
4260              pNorm(strat->S[i]);
4261              h.p = strat->S[i];
4262              strat->initEcart(&h);
4263              strat->ecartS[i] = h.ecart;
4264            }
4265            h.sev =  pGetShortExpVector(h.p);
4266            strat->sevS[i] = h.sev;
4267          }
4268          kTest(strat);
4269        }
4270        i++;
4271      }
4272#ifdef KDEBUG
4273      kTest(strat);
4274#endif
4275      reorderS(&suc,strat);
4276      if (h.p!=NULL)
4277      {
4278        if (!strat->kHEdgeFound)
4279        {
4280          /*strat->kHEdgeFound =*/ HEckeTest(h.p,strat);
4281        }
4282        if (strat->kHEdgeFound)
4283          newHEdge(strat->S,strat);
4284      }
4285    }
4286    for (i=0; i<=strat->sl; i++)
4287    {
4288      if (((strat->fromQ==NULL) || (strat->fromQ[i]==0))
4289      )
4290      {
4291        strat->S[i] = h.p = redtail(strat->S[i],strat->sl,strat);
4292        strat->initEcart(&h);
4293        strat->ecartS[i] = h.ecart;
4294        h.sev = pGetShortExpVector(h.p);
4295        strat->sevS[i] = h.sev;
4296      }
4297      else
4298      {
4299        h.p = strat->S[i];
4300        h.ecart=strat->ecartS[i];
4301        h.sev = strat->sevS[i];
4302      }
4303      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
4304        cancelunit1(&h,&suc,strat->sl,strat);
4305      h.length = pLength(h.p);
4306      h.SetpFDeg();
4307      /*puts the elements of S also to T*/
4308      enterT(h,strat);
4309      strat->S_2_R[i] = strat->tl;
4310    }
4311    if (suc!= -1) updateS(toT,strat);
4312  }
4313  if (redSi!=NULL) pDeleteLm(&redSi);
4314#ifdef KDEBUG
4315  kTest(strat);
4316#endif
4317}
4318
4319
4320/*2
4321* -puts p to the standardbasis s at position at
4322* -saves the result in S
4323*/
4324void enterSBba (LObject p,int atS,kStrategy strat, int atR)
4325{
4326  int i;
4327  strat->news = TRUE;
4328  /*- puts p to the standardbasis s at position at -*/
4329  if (strat->sl == IDELEMS(strat->Shdl)-1)
4330  {
4331    strat->sevS = (unsigned long*) omRealloc0Size(strat->sevS,
4332                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
4333                                    (IDELEMS(strat->Shdl)+setmaxTinc)
4334                                                  *sizeof(unsigned long));
4335    strat->ecartS = (intset)omReallocSize(strat->ecartS,
4336                                          IDELEMS(strat->Shdl)*sizeof(int),
4337                                          (IDELEMS(strat->Shdl)+setmaxTinc)
4338                                                  *sizeof(int));
4339    strat->S_2_R = (int*) omRealloc0Size(strat->S_2_R,
4340                                         IDELEMS(strat->Shdl)*sizeof(int),
4341                                         (IDELEMS(strat->Shdl)+setmaxTinc)
4342                                                  *sizeof(int));
4343    if (strat->lenS!=NULL)
4344      strat->lenS=(int*)omRealloc0Size(strat->lenS,
4345                                       IDELEMS(strat->Shdl)*sizeof(int),
4346                                       (IDELEMS(strat->Shdl)+setmaxTinc)
4347                                                 *sizeof(int));
4348    if (strat->lenSw!=NULL)
4349      strat->lenSw=(wlen_type*)omRealloc0Size(strat->lenSw,
4350                                       IDELEMS(strat->Shdl)*sizeof(wlen_type),
4351                                       (IDELEMS(strat->Shdl)+setmaxTinc)
4352                                                 *sizeof(wlen_type));
4353    if (strat->fromQ!=NULL)
4354    {
4355      strat->fromQ = (intset)omReallocSize(strat->fromQ,
4356                                    IDELEMS(strat->Shdl)*sizeof(int),
4357                                    (IDELEMS(strat->Shdl)+setmaxTinc)*sizeof(int));
4358    }
4359    pEnlargeSet(&strat->S,IDELEMS(strat->Shdl),setmaxTinc);
4360    IDELEMS(strat->Shdl)+=setmaxTinc;
4361    strat->Shdl->m=strat->S;
4362  }
4363  if (atS <= strat->sl)
4364  {
4365#ifdef ENTER_USE_MEMMOVE
4366// #if 0
4367    memmove(&(strat->S[atS+1]), &(strat->S[atS]),
4368            (strat->sl - atS + 1)*sizeof(poly));
4369    memmove(&(strat->ecartS[atS+1]), &(strat->ecartS[atS]),
4370            (strat->sl - atS + 1)*sizeof(int));
4371    memmove(&(strat->sevS[atS+1]), &(strat->sevS[atS]),
4372            (strat->sl - atS + 1)*sizeof(unsigned long));
4373    memmove(&(strat->S_2_R[atS+1]), &(strat->S_2_R[atS]),
4374            (strat->sl - atS + 1)*sizeof(int));
4375    if (strat->lenS!=NULL)
4376    memmove(&(strat->lenS[atS+1]), &(strat->lenS[atS]),
4377            (strat->sl - atS + 1)*sizeof(int));
4378    if (strat->lenSw!=NULL)
4379    memmove(&(strat->lenSw[atS+1]), &(strat->lenSw[atS]),
4380            (strat->sl - atS + 1)*sizeof(wlen_type));
4381#else
4382    for (i=strat->sl+1; i>=atS+1; i--)
4383    {
4384      strat->S[i] = strat->S[i-1];
4385      strat->ecartS[i] = strat->ecartS[i-1];
4386      strat->sevS[i] = strat->sevS[i-1];
4387      strat->S_2_R[i] = strat->S_2_R[i-1];
4388    }
4389    if (strat->lenS!=NULL)
4390    for (i=strat->sl+1; i>=atS+1; i--)
4391      strat->lenS[i] = strat->lenS[i-1];
4392    if (strat->lenSw!=NULL)
4393    for (i=strat->sl+1; i>=atS+1; i--)
4394      strat->lenSw[i] = strat->lenSw[i-1];
4395#endif
4396  }
4397  if (strat->fromQ!=NULL)
4398  {
4399#ifdef ENTER_USE_MEMMOVE
4400    memmove(&(strat->fromQ[atS+1]), &(strat->fromQ[atS]),
4401                  (strat->sl - atS + 1)*sizeof(int));
4402#else
4403    for (i=strat->sl+1; i>=atS+1; i--)
4404    {
4405      strat->fromQ[i] = strat->fromQ[i-1];
4406    }
4407#endif
4408    strat->fromQ[atS]=0;
4409  }
4410
4411  /*- save result -*/
4412  strat->S[atS] = p.p;
4413  if (strat->honey) strat->ecartS[atS] = p.ecart;
4414  if (p.sev == 0)
4415    p.sev = pGetShortExpVector(p.p);
4416  else
4417    assume(p.sev == pGetShortExpVector(p.p));
4418  strat->sevS[atS] = p.sev;
4419  strat->ecartS[atS] = p.ecart;
4420  strat->S_2_R[atS] = atR;
4421  strat->sl++;
4422}
4423
4424/*2
4425* puts p to the set T at position atT
4426*/
4427void enterT(LObject p, kStrategy strat, int atT)
4428{
4429  int i;
4430
4431  pp_Test(p.p, currRing, p.tailRing);
4432  assume(strat->tailRing == p.tailRing);
4433  // redMoraNF complains about this -- but, we don't really
4434  // neeed this so far
4435  // assume(p.pLength == 0 || pLength(p.p) == p.pLength);
4436  assume(p.FDeg == p.pFDeg());
4437  assume(!p.is_normalized || nIsOne(pGetCoeff(p.p)));
4438
4439  strat->newt = TRUE;
4440  if (atT < 0)
4441    atT = strat->posInT(strat->T, strat->tl, p);
4442  if (strat->tl == strat->tmax-1)
4443    enlargeT(strat->T,strat->R,strat->sevT,strat->tmax,setmaxTinc);
4444  if (atT <= strat->tl)
4445  {
4446#ifdef ENTER_USE_MEMMOVE
4447    memmove(&(strat->T[atT+1]), &(strat->T[atT]),
4448            (strat->tl-atT+1)*sizeof(TObject));
4449    memmove(&(strat->sevT[atT+1]), &(strat->sevT[atT]),
4450            (strat->tl-atT+1)*sizeof(unsigned long));
4451#endif
4452    for (i=strat->tl+1; i>=atT+1; i--)
4453    {
4454#ifndef ENTER_USE_MEMMOVE
4455      strat->T[i] = strat->T[i-1];
4456      strat->sevT[i] = strat->sevT[i-1];
4457#endif
4458      strat->R[strat->T[i].i_r] = &(strat->T[i]);
4459    }
4460  }
4461
4462  if (strat->tailBin != NULL && (pNext(p.p) != NULL))
4463  {
4464    pNext(p.p)=p_ShallowCopyDelete(pNext(p.p),
4465                                   (strat->tailRing != NULL ?
4466                                    strat->tailRing : currRing),
4467                                   strat->tailBin);
4468    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
4469  }
4470  strat->T[atT] = (TObject) p;
4471
4472  if (strat->tailRing != currRing && pNext(p.p) != NULL)
4473    strat->T[atT].max = p_GetMaxExpP(pNext(p.p), strat->tailRing);
4474  else
4475    strat->T[atT].max = NULL;
4476
4477  strat->tl++;
4478  strat->R[strat->tl] = &(strat->T[atT]);
4479  strat->T[atT].i_r = strat->tl;
4480  assume(p.sev == 0 || pGetShortExpVector(p.p) == p.sev);
4481  strat->sevT[atT] = (p.sev == 0 ? pGetShortExpVector(p.p) : p.sev);
4482  kTest_T(&(strat->T[atT]));
4483}
4484
4485void initHilbCrit(ideal F, ideal Q, intvec **hilb,kStrategy strat)
4486{
4487  if (strat->homog!=isHomog)
4488  {
4489    *hilb=NULL;
4490  }
4491}
4492
4493void initBuchMoraCrit(kStrategy strat)
4494{
4495  strat->sugarCrit =        TEST_OPT_SUGARCRIT;
4496  // obachman: Hmm.. I need BTEST1(2) for notBuckets ..
4497  //  strat->Gebauer =          BTEST1(2) || strat->homog || strat->sugarCrit;
4498  strat->Gebauer =          strat->homog || strat->sugarCrit;
4499  strat->honey =            !strat->homog || strat->sugarCrit || TEST_OPT_WEIGHTM;
4500  if (TEST_OPT_NOT_SUGAR) strat->honey = FALSE;
4501  strat->pairtest = NULL;
4502  /* alway use tailreduction, except:
4503  * - in local rings, - in lex order case, -in ring over extensions */
4504  strat->noTailReduction = !TEST_OPT_REDTAIL;
4505#ifdef HAVE_PLURAL
4506  // and r is plural_ring
4507  if (currRing->nc!=NULL)
4508    //or it has non-quasi-comm type... later
4509  {
4510    strat->sugarCrit = FALSE;
4511    strat->Gebauer = FALSE ;
4512    strat->honey = FALSE;
4513  }
4514#endif
4515#ifdef HAVE_RING2TOM
4516  // Coefficient ring?
4517  if (currRing->cring == 1)
4518  {
4519    strat->sugarCrit = FALSE;
4520    strat->Gebauer = FALSE ;
4521    strat->honey = FALSE;
4522  }
4523#endif
4524  if (TEST_OPT_DEBUG)
4525  {
4526    if (strat->homog) PrintS("ideal/module is homogeneous\n");
4527    else              PrintS("ideal/module is not homogeneous\n");
4528  }
4529}
4530
4531BOOLEAN kPosInLDependsOnLength(int (*pos_in_l)
4532                               (const LSet set, const int length,
4533                                LObject* L,const kStrategy strat))
4534{
4535  if (pos_in_l == posInL110 ||
4536      pos_in_l == posInL10)
4537    return TRUE;
4538
4539  return FALSE;
4540}
4541
4542void initBuchMoraPos (kStrategy strat)
4543{
4544  if (pOrdSgn==1)
4545  {
4546    if (strat->honey)
4547    {
4548      strat->posInL = posInL15;
4549      // ok -- here is the deal: from my experiments for Singular-2-0
4550      // I conclude that that posInT_EcartpLength is the best of
4551      // posInT15, posInT_EcartFDegpLength, posInT_FDegLength, posInT_pLength
4552      // see the table at the end of this file
4553      if (K_TEST_OPT_OLDSTD)
4554        strat->posInT = posInT15;
4555      else
4556        strat->posInT = posInT_EcartpLength;
4557    }
4558    else if (pLexOrder && !TEST_OPT_INTSTRATEGY)
4559    {
4560      strat->posInL = posInL11;
4561      strat->posInT = posInT11;
4562    }
4563    else if (TEST_OPT_INTSTRATEGY)
4564    {
4565      strat->posInL = posInL11;
4566      strat->posInT = posInT11;
4567    }
4568    else
4569    {
4570      strat->posInL = posInL0;
4571      strat->posInT = posInT0;
4572    }
4573    //if (strat->minim>0) strat->posInL =posInLSpecial;
4574    if (strat->homog)
4575    {
4576       strat->posInL = posInL110;
4577       strat->posInT = posInT110;
4578    }
4579  }
4580  else
4581  {
4582    if (strat->homog)
4583    {
4584      strat->posInL = posInL11;
4585      strat->posInT = posInT11;
4586    }
4587    else
4588    {
4589      if ((currRing->order[0]==ringorder_c)
4590      ||(currRing->order[0]==ringorder_C))
4591      {
4592        strat->posInL = posInL17_c;
4593        strat->posInT = posInT17_c;
4594      }
4595      else
4596      {
4597        strat->posInL = posInL17;
4598        strat->posInT = posInT17;
4599      }
4600    }
4601  }
4602  if (strat->minim>0) strat->posInL =posInLSpecial;
4603  // for further tests only
4604  if ((BTEST1(11)) || (BTEST1(12)))
4605    strat->posInL = posInL11;
4606  else if ((BTEST1(13)) || (BTEST1(14)))
4607    strat->posInL = posInL13;
4608  else if ((BTEST1(15)) || (BTEST1(16)))
4609    strat->posInL = posInL15;
4610  else if ((BTEST1(17)) || (BTEST1(18)))
4611    strat->posInL = posInL17;
4612  if (BTEST1(11))
4613    strat->posInT = posInT11;
4614  else if (BTEST1(13))
4615    strat->posInT = posInT13;
4616  else if (BTEST1(15))
4617    strat->posInT = posInT15;
4618  else if ((BTEST1(17)))
4619    strat->posInT = posInT17;
4620  else if ((BTEST1(19)))
4621    strat->posInT = posInT19;
4622  else if (BTEST1(12) || BTEST1(14) || BTEST1(16) || BTEST1(18))
4623    strat->posInT = posInT1;
4624  strat->posInLDependsOnLength = kPosInLDependsOnLength(strat->posInL);
4625}
4626
4627void initBuchMora (ideal F,ideal Q,kStrategy strat)
4628{
4629  strat->interpt = BTEST1(OPT_INTERRUPT);
4630  strat->kHEdge=NULL;
4631  if (pOrdSgn==1) strat->kHEdgeFound=FALSE;
4632  /*- creating temp data structures------------------- -*/
4633  strat->cp = 0;
4634  strat->c3 = 0;
4635  strat->tail = pInit();
4636  /*- set s -*/
4637  strat->sl = -1;
4638  /*- set L -*/
4639  strat->Lmax = setmaxL;
4640  strat->Ll = -1;
4641  strat->L = initL();
4642  /*- set B -*/
4643  strat->Bmax = setmaxL;
4644  strat->Bl = -1;
4645  strat->B = initL();
4646  /*- set T -*/
4647  strat->tl = -1;
4648  strat->tmax = setmaxT;
4649  strat->T = initT();
4650  strat->R = initR();
4651  strat->sevT = initsevT();
4652  /*- init local data struct.---------------------------------------- -*/
4653  strat->P.ecart=0;
4654  strat->P.length=0;
4655  if (pOrdSgn==-1)
4656  {
4657    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
4658    if (strat->kNoether!=NULL) pSetComp(strat->kNoetherTail(), strat->ak);
4659  }
4660  if(TEST_OPT_SB_1)
4661  {
4662    int i;
4663    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
4664    for (i=strat->newIdeal;i<IDELEMS(F);i++)
4665    {
4666      P->m[i-strat->newIdeal] = F->m[i];
4667      F->m[i] = NULL;
4668    }
4669    initSSpecial(F,Q,P,strat);
4670    for (i=strat->newIdeal;i<IDELEMS(F);i++)
4671    {
4672      F->m[i] = P->m[i-strat->newIdeal];
4673      P->m[i-strat->newIdeal] = NULL;
4674    }
4675    idDelete(&P);
4676  }
4677  else
4678  {
4679    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
4680    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
4681  }
4682  strat->kIdeal = NULL;
4683  strat->fromT = FALSE;
4684  strat->noTailReduction = !TEST_OPT_REDTAIL;
4685  if(!TEST_OPT_SB_1)
4686  {
4687    updateS(TRUE,strat);
4688    pairs(strat);
4689  }
4690  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
4691  strat->fromQ=NULL;
4692}
4693
4694void exitBuchMora (kStrategy strat)
4695{
4696  /*- release temp data -*/
4697  cleanT(strat);
4698  omFreeSize(strat->T,(strat->tmax)*sizeof(TObject));
4699  omFreeSize(strat->R,(strat->tmax)*sizeof(TObject*));
4700  omFreeSize(strat->sevT, (strat->tmax)*sizeof(unsigned long));
4701  omFreeSize(strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
4702  omFreeSize(strat->sevS,IDELEMS(strat->Shdl)*sizeof(int));
4703  omFreeSize(strat->S_2_R,IDELEMS(strat->Shdl)*sizeof(int));
4704  /*- set L: should be empty -*/
4705  omFreeSize(strat->L,(strat->Lmax)*sizeof(LObject));
4706  /*- set B: should be empty -*/
4707  omFreeSize(strat->B,(strat->Bmax)*sizeof(LObject));
4708  pDeleteLm(&strat->tail);
4709  strat->syzComp=0;
4710  if (strat->kIdeal!=NULL)
4711  {
4712    omFreeBin(strat->kIdeal, sleftv_bin);
4713    strat->kIdeal=NULL;
4714  }
4715}
4716
4717/*2
4718* in the case of a standardbase of a module over a qring:
4719* replace polynomials in i by ak vectors,
4720* (the polynomial * unit vectors gen(1)..gen(ak)
4721* in every case (also for ideals:)
4722* deletes divisible vectors/polynomials
4723*/
4724void updateResult(ideal r,ideal Q, kStrategy strat)
4725{
4726  int l;
4727  if (strat->ak>0)
4728  {
4729    for (l=IDELEMS(r)-1;l>=0;l--)
4730    {
4731      if ((r->m[l]!=NULL) && (pGetComp(r->m[l])==0))
4732      {
4733        pDelete(&r->m[l]); // and set it to NULL
4734      }
4735    }
4736    int q;
4737    poly p;
4738    for (l=IDELEMS(r)-1;l>=0;l--)
4739    {
4740      if ((r->m[l]!=NULL)
4741      && (strat->syzComp>0)
4742      && (pGetComp(r->m[l])<=strat->syzComp))
4743      {
4744        for(q=IDELEMS(Q)-1; q>=0;q--)
4745        {
4746          if ((Q->m[q]!=NULL)
4747          &&(pLmDivisibleBy(Q->m[q],r->m[l])))
4748          {
4749            if (TEST_OPT_REDSB)
4750            {
4751              p=r->m[l];
4752              r->m[l]=kNF(Q,NULL,p);
4753              pDelete(&p);
4754            }
4755            else
4756            {
4757              pDelete(&r->m[l]); // and set it to NULL
4758            }
4759            break;
4760          }
4761        }
4762      }
4763    }
4764  }
4765  else
4766  {
4767    int q;
4768    poly p;
4769    for (l=IDELEMS(r)-1;l>=0;l--)
4770    {
4771      if (r->m[l]!=NULL)
4772      {
4773        for(q=IDELEMS(Q)-1; q>=0;q--)
4774        {
4775          if ((Q->m[q]!=NULL)
4776          &&(pLmEqual(r->m[l],Q->m[q])))
4777          {
4778            if (TEST_OPT_REDSB)
4779            {
4780              p=r->m[l];
4781              r->m[l]=kNF(Q,NULL,p);
4782              pDelete(&p);
4783            }
4784            else
4785            {
4786              pDelete(&r->m[l]); // and set it to NULL
4787            }
4788            break;
4789          }
4790        }
4791      }
4792    }
4793  }
4794  idSkipZeroes(r);
4795}
4796
4797void completeReduce (kStrategy strat)
4798{
4799  int i;
4800  int low = (pOrdSgn == 1 ? 1 : 0);
4801  LObject L;
4802
4803#ifdef KDEBUG
4804  // need to set this: during tailreductions of T[i], T[i].max is out of
4805  // sync
4806  sloppy_max = TRUE;
4807#endif
4808
4809  strat->noTailReduction = FALSE;
4810  if (TEST_OPT_PROT)
4811  {
4812    PrintLn();
4813    if (timerv) writeTime("standard base computed:");
4814  }
4815  if (TEST_OPT_PROT)
4816  {
4817    Print("(S:%d)",strat->sl);mflush();
4818  }
4819  for (i=strat->sl; i>=low; i--)
4820  {
4821    TObject* T_j = strat->s_2_t(i);
4822    if (T_j != NULL)
4823    {
4824      L = *T_j;
4825      poly p;
4826      if (pOrdSgn == 1)
4827        strat->S[i] = redtailBba(&L, i-1, strat, FALSE);
4828      else
4829        strat->S[i] = redtail(&L, strat->sl, strat);
4830
4831      if (strat->redTailChange && strat->tailRing != currRing)
4832      {
4833        if (T_j->max != NULL) p_LmFree(T_j->max, strat->tailRing);
4834        if (pNext(T_j->p) != NULL)
4835          T_j->max = p_GetMaxExpP(pNext(T_j->p), strat->tailRing);
4836        else
4837          T_j->max = NULL;
4838      }
4839      if (TEST_OPT_INTSTRATEGY)
4840        T_j->pCleardenom();
4841    }
4842    else
4843    {
4844      assume(currRing == strat->tailRing);
4845      if (pOrdSgn == 1)
4846        strat->S[i] = redtailBba(strat->S[i], i-1, strat);
4847      else
4848        strat->S[i] = redtail(strat->S[i], strat->sl, strat);
4849      if (TEST_OPT_INTSTRATEGY)
4850        pCleardenom(strat->S[i]);
4851    }
4852    if (TEST_OPT_PROT)
4853      PrintS("-");
4854  }
4855#ifdef KDEBUG
4856  sloppy_max = FALSE;
4857#endif
4858}
4859
4860
4861/*2
4862* computes the new strat->kHEdge and the new pNoether,
4863* returns TRUE, if pNoether has changed
4864*/
4865BOOLEAN newHEdge(polyset S, kStrategy strat)
4866{
4867  int i,j;
4868  poly newNoether;
4869
4870  scComputeHC(strat->Shdl,NULL,strat->ak,strat->kHEdge, strat->tailRing);
4871  if (strat->t_kHEdge != NULL) p_LmFree(strat->t_kHEdge, strat->tailRing);
4872  if (strat->tailRing != currRing)
4873    strat->t_kHEdge = k_LmInit_currRing_2_tailRing(strat->kHEdge, strat->tailRing);
4874  /* compare old and new noether*/
4875  newNoether = pLmInit(strat->kHEdge);
4876  j = pFDeg(newNoether,currRing);
4877  for (i=1; i<=pVariables; i++)
4878  {
4879    if (pGetExp(newNoether, i) > 0) pDecrExp(newNoether,i);
4880  }
4881  pSetm(newNoether);
4882  if (j < strat->HCord) /*- statistics -*/
4883  {
4884    if (TEST_OPT_PROT)
4885    {
4886      Print("H(%d)",j);
4887      mflush();
4888    }
4889    strat->HCord=j;
4890    if (TEST_OPT_DEBUG)
4891    {
4892      Print("H(%d):",j);
4893      wrp(strat->kHEdge);
4894      PrintLn();
4895    }
4896  }
4897  if (pCmp(strat->kNoether,newNoether)!=1)
4898  {
4899    pDelete(&strat->kNoether);
4900    strat->kNoether=newNoether;
4901    if (strat->t_kNoether != NULL) p_LmFree(strat->t_kNoether, strat->tailRing);
4902    if (strat->tailRing != currRing)
4903      strat->t_kNoether = k_LmInit_currRing_2_tailRing(strat->kNoether, strat->tailRing);
4904
4905    return TRUE;
4906  }
4907  pLmFree(newNoether);
4908  return FALSE;
4909}
4910
4911/***************************************************************
4912 *
4913 * Routines related for ring changes during std computations
4914 *
4915 ***************************************************************/
4916BOOLEAN kCheckSpolyCreation(LObject *L, kStrategy strat, poly &m1, poly &m2)
4917{
4918  assume(L->p1 != NULL && L->p2 != NULL);
4919  assume(L->i_r1 >= 0 && L->i_r1 <= strat->tl);
4920  assume(L->i_r2 >= 0 && L->i_r2 <= strat->tl);
4921  assume(strat->tailRing != currRing);
4922
4923  if (! k_GetLeadTerms(L->p1, L->p2, currRing, m1, m2, strat->tailRing))
4924    return FALSE;
4925  poly p1_max = (strat->R[L->i_r1])->max;
4926  poly p2_max = (strat->R[L->i_r2])->max;
4927
4928  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
4929      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
4930  {
4931    p_LmFree(m1, strat->tailRing);
4932    p_LmFree(m2, strat->tailRing);
4933    m1 = NULL;
4934    m2 = NULL;
4935    return FALSE;
4936  }
4937  return TRUE;
4938}
4939
4940BOOLEAN kStratChangeTailRing(kStrategy strat, LObject *L, TObject* T, unsigned long expbound)
4941{
4942  if (expbound == 0) expbound = strat->tailRing->bitmask << 1;
4943  if (expbound >= currRing->bitmask) return FALSE;
4944  ring new_tailRing = rModifyRing(currRing,
4945                                  // Hmmm .. the condition pFDeg == pDeg
4946                                  // might be too strong
4947#ifdef HAVE_RING2TOM
4948                                  (strat->homog && pFDeg == pDeg && currRing->cring == 0), // TODO Oliver
4949#else
4950                                  (strat->homog && pFDeg == pDeg),
4951#endif
4952                                  !strat->ak,
4953                                  expbound);
4954  if (new_tailRing == currRing) return TRUE;
4955
4956  strat->pOrigFDeg_TailRing = new_tailRing->pFDeg;
4957  strat->pOrigLDeg_TailRing = new_tailRing->pLDeg;
4958
4959  if (currRing->pFDeg != currRing->pFDegOrig)
4960  {
4961    new_tailRing->pFDeg = currRing->pFDeg;
4962    new_tailRing->pLDeg = currRing->pLDeg;
4963  }
4964
4965  if (TEST_OPT_PROT)
4966    Print("[%lu:%d", (unsigned long) new_tailRing->bitmask, new_tailRing->ExpL_Size);
4967  kTest_TS(strat);
4968  assume(new_tailRing != strat->tailRing);
4969  pShallowCopyDeleteProc p_shallow_copy_delete
4970    = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
4971
4972  omBin new_tailBin = omGetStickyBinOfBin(new_tailRing->PolyBin);
4973
4974  int i;
4975  for (i=0; i<=strat->tl; i++)
4976  {
4977    strat->T[i].ShallowCopyDelete(new_tailRing, new_tailBin,
4978                                  p_shallow_copy_delete);
4979  }
4980  for (i=0; i<=strat->Ll; i++)
4981  {
4982    assume(strat->L[i].p != NULL);
4983    if (pNext(strat->L[i].p) != strat->tail)
4984      strat->L[i].ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
4985  }
4986  if (strat->P.t_p != NULL ||
4987      (strat->P.p != NULL && pNext(strat->P.p) != strat->tail))
4988    strat->P.ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
4989
4990  if (L != NULL && L->tailRing != new_tailRing)
4991  {
4992    if (L->i_r < 0)
4993      L->ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
4994    else
4995    {
4996      assume(L->i_r <= strat->tl);
4997      TObject* t_l = strat->R[L->i_r];
4998      assume(t_l != NULL);
4999      L->tailRing = new_tailRing;
5000      L->p = t_l->p;
5001      L->t_p = t_l->t_p;
5002      L->max = t_l->max;
5003    }
5004  }
5005
5006  if (T != NULL && T->tailRing != new_tailRing && T->i_r < 0)
5007    T->ShallowCopyDelete(new_tailRing, new_tailBin, p_shallow_copy_delete);
5008
5009  omMergeStickyBinIntoBin(strat->tailBin, strat->tailRing->PolyBin);
5010  if (strat->tailRing != currRing)
5011    rKillModifiedRing(strat->tailRing);
5012
5013  strat->tailRing = new_tailRing;
5014  strat->tailBin = new_tailBin;
5015  strat->p_shallow_copy_delete
5016    = pGetShallowCopyDeleteProc(currRing, new_tailRing);
5017
5018  if (strat->kHEdge != NULL)
5019  {
5020    if (strat->t_kHEdge != NULL)
5021      p_LmFree(strat->t_kHEdge, strat->tailRing);
5022    strat->t_kHEdge=k_LmInit_currRing_2_tailRing(strat->kHEdge, new_tailRing);
5023  }
5024
5025  if (strat->kNoether != NULL)
5026  {
5027    if (strat->t_kNoether != NULL)
5028      p_LmFree(strat->t_kNoether, strat->tailRing);
5029    strat->t_kNoether=k_LmInit_currRing_2_tailRing(strat->kNoether,
5030                                                   new_tailRing);
5031  }
5032  kTest_TS(strat);
5033  if (TEST_OPT_PROT)
5034    PrintS("]");
5035  return TRUE;
5036}
5037
5038void kStratInitChangeTailRing(kStrategy strat)
5039{
5040  unsigned long l = 0;
5041  int i;
5042  Exponent_t e;
5043  ring new_tailRing;
5044
5045  assume(strat->tailRing == currRing);
5046
5047  for (i=0; i<= strat->Ll; i++)
5048  {
5049    l = p_GetMaxExpL(strat->L[i].p, currRing, l);
5050  }
5051  for (i=0; i<=strat->tl; i++)
5052  {
5053    // Hmm ... this we could do in one Step
5054    l = p_GetMaxExpL(strat->T[i].p, currRing, l);
5055  }
5056  e = p_GetMaxExp(l, currRing);
5057  if (e <= 1) e = 2;
5058
5059  kStratChangeTailRing(strat, NULL, NULL, e);
5060}
5061
5062skStrategy::skStrategy()
5063{
5064  memset(this, 0, sizeof(skStrategy));
5065#ifndef NDEBUG
5066  strat_nr++;
5067  nr=strat_nr;
5068  if (strat_fac_debug) Print("s(%d) created\n",nr);
5069#endif
5070  tailRing = currRing;
5071  P.tailRing = currRing;
5072  tl = -1;
5073  sl = -1;
5074#ifdef HAVE_LM_BIN
5075  lmBin = omGetStickyBinOfBin(currRing->PolyBin);
5076#endif
5077#ifdef HAVE_TAIL_BIN
5078  tailBin = omGetStickyBinOfBin(currRing->PolyBin);
5079#endif
5080  pOrigFDeg = pFDeg;
5081  pOrigLDeg = pLDeg;
5082}
5083
5084
5085skStrategy::~skStrategy()
5086{
5087  if (lmBin != NULL)
5088    omMergeStickyBinIntoBin(lmBin, currRing->PolyBin);
5089  if (tailBin != NULL)
5090    omMergeStickyBinIntoBin(tailBin,
5091                            (tailRing != NULL ? tailRing->PolyBin:
5092                             currRing->PolyBin));
5093  if (t_kHEdge != NULL)
5094    p_LmFree(t_kHEdge, tailRing);
5095  if (t_kNoether != NULL)
5096    p_LmFree(t_kNoether, tailRing);
5097
5098  if (currRing != tailRing)
5099    rKillModifiedRing(tailRing);
5100  pRestoreDegProcs(pOrigFDeg, pOrigLDeg);
5101}
5102
5103#if 0
5104Timings for the different possibilities of posInT:
5105            T15           EDL         DL          EL            L         1-2-3
5106Gonnet      43.26       42.30       38.34       41.98       38.40      100.04
5107Hairer_2_1   1.11        1.15        1.04        1.22        1.08        4.7
5108Twomat3      1.62        1.69        1.70        1.65        1.54       11.32
5109ahml         4.48        4.03        4.03        4.38        4.96       26.50
5110c7          15.02       13.98       15.16       13.24       17.31       47.89
5111c8         505.09      407.46      852.76      413.21      499.19        n/a
5112f855        12.65        9.27       14.97        8.78       14.23       33.12
5113gametwo6    11.47       11.35       14.57       11.20       12.02       35.07
5114gerhard_3    2.73        2.83        2.93        2.64        3.12        6.24
5115ilias13     22.89       22.46       24.62       20.60       23.34       53.86
5116noon8       40.68       37.02       37.99       36.82       35.59      877.16
5117rcyclic_19  48.22       42.29       43.99       45.35       51.51      204.29
5118rkat9       82.37       79.46       77.20       77.63       82.54      267.92
5119schwarz_11  16.46       16.81       16.76       16.81       16.72       35.56
5120test016     16.39       14.17       14.40       13.50       14.26       34.07
5121test017     34.70       36.01       33.16       35.48       32.75       71.45
5122test042     10.76       10.99       10.27       11.57       10.45       23.04
5123test058      6.78        6.75        6.51        6.95        6.22        9.47
5124test066     10.71       10.94       10.76       10.61       10.56       19.06
5125test073     10.75       11.11       10.17       10.79        8.63       58.10
5126test086     12.23       11.81       12.88       12.24       13.37       66.68
5127test103      5.05        4.80        5.47        4.64        4.89       11.90
5128test154     12.96       11.64       13.51       12.46       14.61       36.35
5129test162     65.27       64.01       67.35       59.79       67.54      196.46
5130test164      7.50        6.50        7.68        6.70        7.96       17.13
5131virasoro     3.39        3.50        3.35        3.47        3.70        7.66
5132#endif
5133
5134
5135#ifdef HAVE_MORE_POS_IN_T
5136// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
5137int posInT_EcartFDegpLength(const TSet set,const int length,LObject &p)
5138{
5139
5140  if (length==-1) return 0;
5141
5142  int o = p.ecart;
5143  int op=p.GetpFDeg();
5144  int ol = p.GetpLength();
5145
5146  if (set[length].ecart < o)
5147    return length+1;
5148  if (set[length].ecart == o)
5149  {
5150     int oo=set[length].GetpFDeg();
5151     if ((oo < op) || ((oo==op) && (set[length].length < ol)))
5152       return length+1;
5153  }
5154
5155  int i;
5156  int an = 0;
5157  int en= length;
5158  loop
5159  {
5160    if (an >= en-1)
5161    {
5162      if (set[an].ecart > o)
5163        return an;
5164      if (set[an].ecart == o)
5165      {
5166         int oo=set[an].GetpFDeg();
5167         if((oo > op)
5168         || ((oo==op) && (set[an].pLength > ol)))
5169           return an;
5170      }
5171      return en;
5172    }
5173    i=(an+en) / 2;
5174    if (set[i].ecart > o)
5175      en=i;
5176    else if (set[i].ecart == o)
5177    {
5178       int oo=set[i].GetpFDeg();
5179       if ((oo > op)
5180       || ((oo == op) && (set[i].pLength > ol)))
5181         en=i;
5182       else
5183        an=i;
5184    }
5185    else
5186      an=i;
5187  }
5188}
5189
5190// determines the position based on: 1.) FDeg 2.) pLength
5191int posInT_FDegpLength(const TSet set,const int length,LObject &p)
5192{
5193
5194  if (length==-1) return 0;
5195
5196  int op=p.GetpFDeg();
5197  int ol = p.GetpLength();
5198
5199  int oo=set[length].GetpFDeg();
5200  if ((oo < op) || ((oo==op) && (set[length].length < ol)))
5201    return length+1;
5202
5203  int i;
5204  int an = 0;
5205  int en= length;
5206  loop
5207    {
5208      if (an >= en-1)
5209      {
5210        int oo=set[an].GetpFDeg();
5211        if((oo > op)
5212           || ((oo==op) && (set[an].pLength > ol)))
5213          return an;
5214        return en;
5215      }
5216      i=(an+en) / 2;
5217      int oo=set[i].GetpFDeg();
5218      if ((oo > op)
5219          || ((oo == op) && (set[i].pLength > ol)))
5220        en=i;
5221      else
5222        an=i;
5223    }
5224}
5225
5226
5227// determines the position based on: 1.) Ecart 2.) FDeg 3.) pLength
5228int posInT_pLength(const TSet set,const int length,LObject &p)
5229{
5230  if (length==-1)
5231    return 0;
5232  if (set[length].length<p.length)
5233    return length+1;
5234
5235  int i;
5236  int an = 0;
5237  int en= length;
5238  int ol = p.GetpLength();
5239
5240  loop
5241  {
5242    if (an >= en-1)
5243    {
5244      if (set[an].pLength>ol) return an;
5245      return en;
5246    }
5247    i=(an+en) / 2;
5248    if (set[i].pLength>ol) en=i;
5249    else                        an=i;
5250  }
5251}
5252
5253#endif
5254
5255#endif // KUTIL_CC
Note: See TracBrowser for help on using the repository browser.