source: git/Singular/kutil.cc @ bef194

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