source: git/Singular/kutil.cc @ 4508ce5

fieker-DuValspielwiese
Last change on this file since 4508ce5 was 48aa42, checked in by Olaf Bachmann <obachman@…>, 23 years ago
opt(redThrough) etc added git-svn-id: file:///usr/local/Singular/svn/trunk@4905 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 98.2 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: kutil.cc,v 1.83 2000-12-14 16:38:51 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/*2
1889* looks up the position of p in set
1890* set[0] is the smallest with respect to the ordering-procedure
1891* maximaldegree, pComp
1892*/
1893int posInT15 (const TSet set,const int length,const LObject &p)
1894/*{
1895 *int j=0;
1896 * int o;
1897 *
1898 * o = p.GetpFDeg()+p.ecart;
1899 * loop
1900 * {
1901 *   if ((set[j].GetpFDeg()+set[j].ecart > o)
1902 *   || ((set[j].GetpFDeg()+set[j].ecart == o)
1903 *     && (pLmCmp(set[j].p,p.p) == pOrdSgn)))
1904 *   {
1905 *     return j;
1906 *   }
1907 *   j++;
1908 *   if (j > length) return j;
1909 * }
1910 *}
1911 */
1912{
1913  if (length==-1) return 0;
1914
1915  int o = p.GetpFDeg() + p.ecart;
1916  int op = set[length].GetpFDeg()+set[length].ecart;
1917
1918  if ((op < o)
1919  || ((op == o)
1920     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
1921    return length+1;
1922
1923  int i;
1924  int an = 0;
1925  int en= length;
1926  loop
1927  {
1928    if (an >= en-1)
1929    {
1930      op = set[an].GetpFDeg()+set[an].ecart;
1931      if (( op > o)
1932      || (( op  == o) && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
1933        return an;
1934      return en;
1935    }
1936    i=(an+en) / 2;
1937    op = set[i].GetpFDeg()+set[i].ecart;
1938    if (( op > o)
1939    || (( op == o) && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
1940      en=i;
1941    else
1942      an=i;
1943  }
1944}
1945
1946/*2
1947* looks up the position of p in set
1948* set[0] is the smallest with respect to the ordering-procedure
1949* pFDeg+ecart, ecart, pComp
1950*/
1951int posInT17 (const TSet set,const int length,const LObject &p)
1952/*
1953*{
1954* int j=0;
1955* int  o;
1956*
1957*  o = p.GetpFDeg()+p.ecart;
1958*  loop
1959*  {
1960*    if ((pFDeg(set[j].p)+set[j].ecart > o)
1961*    || (((pFDeg(set[j].p)+set[j].ecart == o)
1962*      && (set[j].ecart < p.ecart)))
1963*    || ((pFDeg(set[j].p)+set[j].ecart == o)
1964*      && (set[j].ecart==p.ecart)
1965*      && (pLmCmp(set[j].p,p.p)==pOrdSgn)))
1966*      return j;
1967*    j++;
1968*    if (j > length) return j;
1969*  }
1970* }
1971*/
1972{
1973  if (length==-1) return 0;
1974
1975  int o = p.GetpFDeg() + p.ecart;
1976  int op = set[length].GetpFDeg()+set[length].ecart;
1977
1978  if ((op < o)
1979  || (( op == o) && (set[length].ecart > p.ecart))
1980  || (( op == o) && (set[length].ecart==p.ecart)
1981     && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
1982    return length+1;
1983
1984  int i;
1985  int an = 0;
1986  int en= length;
1987  loop
1988  {
1989    if (an >= en-1)
1990    {
1991      op = set[an].GetpFDeg()+set[an].ecart;
1992      if (( op > o)
1993      || (( op == o) && (set[an].ecart < p.ecart))
1994      || (( op  == o) && (set[an].ecart==p.ecart)
1995         && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
1996        return an;
1997      return en;
1998    }
1999    i=(an+en) / 2;
2000    op = set[i].GetpFDeg()+set[i].ecart;
2001    if ((op > o)
2002    || (( op == o) && (set[i].ecart < p.ecart))
2003    || (( op == o) && (set[i].ecart == p.ecart)
2004       && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
2005      en=i;
2006    else
2007      an=i;
2008  }
2009}
2010/*2
2011* looks up the position of p in set
2012* set[0] is the smallest with respect to the ordering-procedure
2013* pGetComp, pFDeg+ecart, ecart, pComp
2014*/
2015int posInT17_c (const TSet set,const int length,const LObject &p)
2016{
2017  if (length==-1) return 0;
2018
2019  int cc = (-1+2*currRing->order[0]==ringorder_c);
2020  /* cc==1 for (c,..), cc==-1 for (C,..) */
2021  int o = p.GetpFDeg() + p.ecart;
2022  int c = pGetComp(p.p)*cc;
2023
2024  if (pGetComp(set[length].p)*cc < c)
2025    return length+1;
2026  if (pGetComp(set[length].p)*cc == c)
2027  {
2028    int op = set[length].GetpFDeg()+set[length].ecart;
2029    if ((op < o)
2030    || ((op == o) && (set[length].ecart > p.ecart))
2031    || ((op == o) && (set[length].ecart==p.ecart)
2032       && (pLmCmp(set[length].p,p.p) != pOrdSgn)))
2033      return length+1;
2034  }
2035
2036  int i;
2037  int an = 0;
2038  int en= length;
2039  loop
2040  {
2041    if (an >= en-1)
2042    {
2043      if (pGetComp(set[an].p)*cc < c)
2044        return en;
2045      if (pGetComp(set[an].p)*cc == c)
2046      {
2047        int op = set[an].GetpFDeg()+set[an].ecart;
2048        if ((op > o)
2049        || ((op == o) && (set[an].ecart < p.ecart))
2050        || ((op == o) && (set[an].ecart==p.ecart)
2051           && (pLmCmp(set[an].p,p.p) == pOrdSgn)))
2052          return an;
2053      }
2054      return en;
2055    }
2056    i=(an+en) / 2;
2057    if (pGetComp(set[i].p)*cc > c)
2058      en=i;
2059    else if (pGetComp(set[i].p)*cc == c)
2060    {
2061      int op = set[i].GetpFDeg()+set[i].ecart;
2062      if ((op > o)
2063      || ((op == o) && (set[i].ecart < p.ecart))
2064      || ((op == o) && (set[i].ecart == p.ecart)
2065         && (pLmCmp(set[i].p,p.p) == pOrdSgn)))
2066        en=i;
2067      else
2068        an=i;
2069    }
2070    else
2071      an=i;
2072  }
2073}
2074
2075/*2
2076* looks up the position of p in set
2077* set[0] is the smallest with respect to
2078* ecart, pFDeg, length
2079*/
2080int posInT19 (const TSet set,const int length,const LObject &p)
2081{
2082  if (length==-1) return 0;
2083
2084  int o = p.ecart;
2085  int op=p.GetpFDeg();
2086
2087  if (set[length].ecart < o)
2088    return length+1;
2089  if (set[length].ecart == o)
2090  {
2091     int oo=set[length].GetpFDeg();
2092     if ((oo < op) || ((oo==op) && (set[length].length < p.length)))
2093       return length+1;
2094  }
2095
2096  int i;
2097  int an = 0;
2098  int en= length;
2099  loop
2100  {
2101    if (an >= en-1)
2102    {
2103      if (set[an].ecart > o)
2104        return an;
2105      if (set[an].ecart == o)
2106      {
2107         int oo=set[an].GetpFDeg();
2108         if((oo > op)
2109         || ((oo==op) && (set[an].length > p.length)))
2110           return an;
2111      }
2112      return en;
2113    }
2114    i=(an+en) / 2;
2115    if (set[i].ecart > o)
2116      en=i;
2117    else if (set[i].ecart == o)
2118    {
2119       int oo=set[i].GetpFDeg();
2120       if ((oo > op)
2121       || ((oo == op) && (set[i].length > p.length)))
2122         en=i;
2123       else
2124        an=i;
2125    }
2126    else
2127      an=i;
2128  }
2129}
2130
2131/*2
2132*looks up the position of polynomial p in set
2133*set[length] is the smallest element in set with respect
2134*to the ordering-procedure pComp
2135*/
2136int posInLSpecial (const LSet set, const int length,
2137                   LObject *p,const kStrategy strat)
2138{
2139  if (length<0) return 0;
2140
2141  int d=p->GetpFDeg();
2142  int op=set[length].GetpFDeg();
2143
2144  if ((op > d)
2145  || ((op == d) && (p->p1!=NULL)&&(set[length].p1==NULL))
2146  || (pLmCmp(set[length].p,p->p)== pOrdSgn))
2147     return length+1;
2148
2149  int i;
2150  int an = 0;
2151  int en= length;
2152  loop
2153  {
2154    if (an >= en-1)
2155    {
2156      op=set[an].GetpFDeg();
2157      if ((op > d)
2158      || ((op == d) && (p->p1!=NULL) && (set[an].p1==NULL))
2159      || (pLmCmp(set[an].p,p->p)== pOrdSgn))
2160         return en;
2161      return an;
2162    }
2163    i=(an+en) / 2;
2164    op=set[i].GetpFDeg();
2165    if ((op>d)
2166    || ((op==d) && (p->p1!=NULL) && (set[i].p1==NULL))
2167    || (pLmCmp(set[i].p,p->p) == pOrdSgn))
2168      an=i;
2169    else
2170      en=i;
2171  }
2172}
2173
2174/*2
2175*looks up the position of polynomial p in set
2176*set[length] is the smallest element in set with respect
2177*to the ordering-procedure pComp
2178*/
2179int posInL0 (const LSet set, const int length,
2180             LObject* p,const kStrategy strat)
2181{
2182  if (length<0) return 0;
2183
2184  if (pLmCmp(set[length].p,p->p)== pOrdSgn)
2185    return length+1;
2186
2187  int i;
2188  int an = 0;
2189  int en= length;
2190  loop
2191  {
2192    if (an >= en-1)
2193    {
2194      if (pLmCmp(set[an].p,p->p) == pOrdSgn) return en;
2195      return an;
2196    }
2197    i=(an+en) / 2;
2198    if (pLmCmp(set[i].p,p->p) == pOrdSgn) an=i;
2199    else                                 en=i;
2200    /*aend. fuer lazy == in !=- machen */
2201  }
2202}
2203
2204/*2
2205* looks up the position of polynomial p in set
2206* e is the ecart of p
2207* set[length] is the smallest element in set with respect
2208* to the ordering-procedure totaldegree,pComp
2209*/
2210int posInL11 (const LSet set, const int length,
2211              LObject* p,const kStrategy strat)
2212/*{
2213 * int j=0;
2214 * int o;
2215 *
2216 * o = p->GetpFDeg();
2217 * loop
2218 * {
2219 *   if (j > length)            return j;
2220 *   if ((set[j].GetpFDeg() < o)) return j;
2221 *   if ((set[j].GetpFDeg() == o) && (pLmCmp(set[j].p,p->p) == -pOrdSgn))
2222 *   {
2223 *     return j;
2224 *   }
2225 *   j++;
2226 * }
2227 *}
2228 */
2229{
2230  if (length<0) return 0;
2231
2232  int o = p->GetpFDeg();
2233  int op = set[length].GetpFDeg();
2234
2235  if ((op > o)
2236  || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
2237    return length+1;
2238  int i;
2239  int an = 0;
2240  int en= length;
2241  loop
2242  {
2243    if (an >= en-1)
2244    {
2245      op = set[an].GetpFDeg();
2246      if ((op > o)
2247      || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
2248        return en;
2249      return an;
2250    }
2251    i=(an+en) / 2;
2252    op = set[i].GetpFDeg();
2253    if ((op > o)
2254    || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
2255      an=i;
2256    else
2257      en=i;
2258  }
2259}
2260
2261/*2
2262* looks up the position of polynomial p in set
2263* set[length] is the smallest element in set with respect
2264* to the ordering-procedure totaldegree,pLength0
2265*/
2266int posInL110 (const LSet set, const int length,
2267               LObject* p,const kStrategy strat)
2268{
2269  if (length<0) return 0;
2270
2271  int o = p->GetpFDeg();
2272  int op = set[length].GetpFDeg();
2273
2274  if ((op > o)
2275  || ((op == o) && (set[length].length >2*p->length))
2276  || ((op == o) && (set[length].length <= 2*p->length)
2277     && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
2278    return length+1;
2279  int i;
2280  int an = 0;
2281  int en= length;
2282  loop
2283  {
2284    if (an >= en-1)
2285    {
2286      op = set[an].GetpFDeg();
2287      if ((op > o)
2288      || ((op == o) && (set[an].length >2*p->length))
2289      || ((op == o) && (set[an].length <=2*p->length)
2290         && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
2291        return en;
2292      return an;
2293    }
2294    i=(an+en) / 2;
2295    op = set[i].GetpFDeg();
2296    if ((op > o)
2297    || ((op == o) && (set[i].length > 2*p->length))
2298    || ((op == o) && (set[i].length <= 2*p->length)
2299       && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
2300      an=i;
2301    else
2302      en=i;
2303  }
2304}
2305
2306/*2
2307* looks up the position of polynomial p in set
2308* e is the ecart of p
2309* set[length] is the smallest element in set with respect
2310* to the ordering-procedure totaldegree
2311*/
2312int posInL13 (const LSet set, const int length,
2313              LObject* p,const kStrategy strat)
2314{
2315  if (length<0) return 0;
2316
2317  int o = p->GetpFDeg();
2318
2319  if (set[length].GetpFDeg() > o)
2320    return length+1;
2321
2322  int i;
2323  int an = 0;
2324  int en= length;
2325  loop
2326  {
2327    if (an >= en-1)
2328    {
2329      if (set[an].GetpFDeg() >= o)
2330        return en;
2331      return an;
2332    }
2333    i=(an+en) / 2;
2334    if (set[i].GetpFDeg() >= o)
2335      an=i;
2336    else
2337      en=i;
2338  }
2339}
2340
2341/*2
2342* looks up the position of polynomial p in set
2343* e is the ecart of p
2344* set[length] is the smallest element in set with respect
2345* to the ordering-procedure maximaldegree,pComp
2346*/
2347int posInL15 (const LSet set, const int length,
2348              LObject* p,const kStrategy strat)
2349/*{
2350 * int j=0;
2351 * int o;
2352 *
2353 * o = p->ecart+p->GetpFDeg();
2354 * loop
2355 * {
2356 *   if (j > length)                       return j;
2357 *   if (set[j].GetpFDeg()+set[j].ecart < o) return j;
2358 *   if ((set[j].GetpFDeg()+set[j].ecart == o)
2359 *   && (pLmCmp(set[j].p,p->p) == -pOrdSgn))
2360 *   {
2361 *     return j;
2362 *   }
2363 *   j++;
2364 * }
2365 *}
2366 */
2367{
2368  if (length<0) return 0;
2369
2370  int o = p->GetpFDeg() + p->ecart;
2371  int op = set[length].GetpFDeg() + set[length].ecart;
2372
2373  if ((op > o)
2374  || ((op == o) && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
2375    return length+1;
2376  int i;
2377  int an = 0;
2378  int en= length;
2379  loop
2380  {
2381    if (an >= en-1)
2382    {
2383      op = set[an].GetpFDeg() + set[an].ecart;
2384      if ((op > o)
2385      || ((op == o) && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
2386        return en;
2387      return an;
2388    }
2389    i=(an+en) / 2;
2390    op = set[i].GetpFDeg() + set[i].ecart;
2391    if ((op > o)
2392    || ((op == o) && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
2393      an=i;
2394    else
2395      en=i;
2396  }
2397}
2398
2399/*2
2400* looks up the position of polynomial p in set
2401* e is the ecart of p
2402* set[length] is the smallest element in set with respect
2403* to the ordering-procedure totaldegree
2404*/
2405int posInL17 (const LSet set, const int length,
2406              LObject* p,const kStrategy strat)
2407{
2408  if (length<0) return 0;
2409
2410  int o = p->GetpFDeg() + p->ecart;
2411
2412  if ((set[length].GetpFDeg() + set[length].ecart > o)
2413  || ((set[length].GetpFDeg() + set[length].ecart == o)
2414     && (set[length].ecart > p->ecart))
2415  || ((set[length].GetpFDeg() + set[length].ecart == o)
2416     && (set[length].ecart == p->ecart)
2417     && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
2418    return length+1;
2419  int i;
2420  int an = 0;
2421  int en= length;
2422  loop
2423  {
2424    if (an >= en-1)
2425    {
2426      if ((set[an].GetpFDeg() + set[an].ecart > o)
2427      || ((set[an].GetpFDeg() + set[an].ecart == o)
2428         && (set[an].ecart > p->ecart))
2429      || ((set[an].GetpFDeg() + set[an].ecart == o)
2430         && (set[an].ecart == p->ecart)
2431         && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
2432        return en;
2433      return an;
2434    }
2435    i=(an+en) / 2;
2436    if ((set[i].GetpFDeg() + set[i].ecart > o)
2437    || ((set[i].GetpFDeg() + set[i].ecart == o)
2438       && (set[i].ecart > p->ecart))
2439    || ((set[i].GetpFDeg() +set[i].ecart == o)
2440       && (set[i].ecart == p->ecart)
2441       && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
2442      an=i;
2443    else
2444      en=i;
2445  }
2446}
2447/*2
2448* looks up the position of polynomial p in set
2449* e is the ecart of p
2450* set[length] is the smallest element in set with respect
2451* to the ordering-procedure pComp
2452*/
2453int posInL17_c (const LSet set, const int length,
2454                LObject* p,const kStrategy strat)
2455{
2456  if (length<0) return 0;
2457
2458  int cc = (-1+2*currRing->order[0]==ringorder_c);
2459  /* cc==1 for (c,..), cc==-1 for (C,..) */
2460  int c = pGetComp(p->p)*cc;
2461  int o = p->GetpFDeg() + p->ecart;
2462
2463  if (pGetComp(set[length].p)*cc > c)
2464    return length+1;
2465  if (pGetComp(set[length].p)*cc == c)
2466  {
2467    if ((set[length].GetpFDeg() + set[length].ecart > o)
2468    || ((set[length].GetpFDeg() + set[length].ecart == o)
2469       && (set[length].ecart > p->ecart))
2470    || ((set[length].GetpFDeg() + set[length].ecart == o)
2471       && (set[length].ecart == p->ecart)
2472       && (pLmCmp(set[length].p,p->p) != -pOrdSgn)))
2473      return length+1;
2474  }
2475  int i;
2476  int an = 0;
2477  int en= length;
2478  loop
2479  {
2480    if (an >= en-1)
2481    {
2482      if (pGetComp(set[an].p)*cc > c)
2483        return en;
2484      if (pGetComp(set[an].p)*cc == c)
2485      {
2486        if ((set[an].GetpFDeg() + set[an].ecart > o)
2487        || ((set[an].GetpFDeg() + set[an].ecart == o)
2488           && (set[an].ecart > p->ecart))
2489        || ((set[an].GetpFDeg() + set[an].ecart == o)
2490           && (set[an].ecart == p->ecart)
2491           && (pLmCmp(set[an].p,p->p) != -pOrdSgn)))
2492          return en;
2493      }
2494      return an;
2495    }
2496    i=(an+en) / 2;
2497    if (pGetComp(set[i].p)*cc > c)
2498      an=i;
2499    else if (pGetComp(set[i].p)*cc == c)
2500    {
2501      if ((set[i].GetpFDeg() + set[i].ecart > o)
2502      || ((set[i].GetpFDeg() + set[i].ecart == o)
2503         && (set[i].ecart > p->ecart))
2504      || ((set[i].GetpFDeg() +set[i].ecart == o)
2505         && (set[i].ecart == p->ecart)
2506         && (pLmCmp(set[i].p,p->p) != -pOrdSgn)))
2507        an=i;
2508      else
2509        en=i;
2510    }
2511    else
2512      en=i;
2513  }
2514}
2515
2516/***************************************************************
2517 *
2518 * Tail reductions
2519 *
2520 ***************************************************************/
2521static TObject* 
2522kFindDivisibleByInS(kStrategy strat, int pos, LObject* L, TObject *T, 
2523                    long ecart = LONG_MAX)
2524{
2525  int j = 0;
2526  const unsigned long not_sev = ~L->sev;
2527  const unsigned long* sev = strat->sevS;
2528  poly p;
2529  ring r;
2530  L->GetLm(p, r);
2531 
2532  assume(~not_sev == p_GetShortExpVector(p, r));
2533
2534  if (r == currRing)
2535  {
2536    while (1)
2537    {
2538      if (j > pos) return NULL;
2539#if defined(PDEBUG) || defined(PDIV_DEBUG)
2540      if (p_LmShortDivisibleBy(strat->S[j], sev[j], p, not_sev, r) &&
2541          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
2542        break;
2543#else
2544      if (!(sev[j] & not_sev) &&
2545          (ecart== LONG_MAX || ecart>= strat->ecartS[j]) &&
2546          p_LmDivisibleBy(strat->S[j], p, r))
2547        break;
2548     
2549#endif
2550      j++;
2551    }
2552    // if called from NF, T objects do not exist:
2553    if (strat->tl < 0 || strat->S_2_R[j] == -1)
2554    {
2555      T->Set(strat->S[j], r, strat->tailRing);
2556      return T;
2557    }
2558    else
2559    {
2560      assume (j >= 0 && j <= strat->tl && strat->S_2_T(j) != NULL && 
2561              strat->S_2_T(j)->p == strat->S[j]);
2562      return strat->S_2_T(j);
2563    }
2564  }
2565  else
2566  {
2567    TObject* t;
2568    while (1)
2569    {
2570      if (j > pos) return NULL;
2571      assume(strat->S_2_R[j] != -1);
2572#if defined(PDEBUG) || defined(PDIV_DEBUG)
2573      t = strat->S_2_T(j);
2574      assume(t != NULL && t->t_p != NULL && t->tailRing == r);
2575      if (p_LmShortDivisibleBy(t->t_p, sev[j], p, not_sev, r) && 
2576          (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
2577        return t;
2578#else     
2579      if (! (sev[j] & not_sev) && (ecart== LONG_MAX || ecart>= strat->ecartS[j]))
2580      {
2581        t = strat->S_2_T(j);
2582        assume(t != NULL && t->t_p != NULL && t->tailRing == r && t->p == strat->S[j]);
2583        if (p_LmDivisibleBy(t->t_p, p, r)) return t;
2584      }
2585#endif
2586      j++;
2587    }
2588  }
2589}
2590
2591
2592poly redtail (LObject* L, int pos, kStrategy strat)
2593{
2594  poly h, hn;
2595  int j;
2596  unsigned long not_sev;
2597  strat->redTailChange=FALSE;
2598
2599  poly p = L->p;
2600  if (strat->noTailReduction || pNext(p) == NULL)
2601    return p;
2602
2603  LObject Ln(strat->tailRing);
2604  TObject* With;
2605  // placeholder in case strat->tl < 0
2606  TObject  With_s(strat->tailRing);
2607  h = p;
2608  hn = pNext(h);
2609  long op = pFDeg(hn, strat->tailRing);
2610  long e;
2611  int l;
2612  BOOLEAN save_HE=strat->kHEdgeFound;
2613  strat->kHEdgeFound |= 
2614    ((Kstd1_deg>0) && (op<=Kstd1_deg)) || TEST_OPT_INFREDTAIL;
2615
2616  while(hn != NULL)
2617  {
2618    op = pFDeg(hn, strat->tailRing);
2619    if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
2620    e = pLDeg(hn, &l, strat->tailRing) - op;
2621    while (1)
2622    {
2623      Ln.Set(hn, strat->tailRing);
2624      Ln.sev = p_GetShortExpVector(hn, strat->tailRing);
2625      if (strat->kHEdgeFound)
2626        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
2627      else
2628        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s, e);
2629      if (With == NULL) break;
2630      strat->redTailChange=TRUE;
2631      if (ksReducePolyTail(L, With, h, strat->kNoether))
2632      {
2633        // reducing the tail would violate the exp bound
2634        if (kStratChangeTailRing(strat, L))
2635        {
2636          strat->kHEdgeFound = save_HE;
2637          return redtail(L, pos, strat);
2638        }
2639        else
2640          return NULL;
2641      }
2642      hn = pNext(h);
2643      if (hn == NULL) goto all_done;
2644      op = pFDeg(hn, strat->tailRing);
2645      if ((Kstd1_deg>0)&&(op>Kstd1_deg)) goto all_done;
2646      e = pLDeg(hn, &l) - op;
2647    }
2648    h = hn;
2649    hn = pNext(h);
2650  }
2651 
2652  all_done:
2653  if (strat->redTailChange)
2654  {
2655    L->last = 0;
2656    L->pLength = 0;
2657  }
2658  strat->kHEdgeFound = save_HE;
2659  return p;
2660}
2661
2662poly redtail (poly p, int pos, kStrategy strat)
2663{
2664  LObject L(p, currRing);
2665  return redtail(&L, pos, strat);
2666}
2667
2668
2669#ifndef OLD_REDTAIL_BBA
2670poly redtailBba (LObject* L, int pos, kStrategy strat, BOOLEAN withT)
2671{
2672  strat->redTailChange=FALSE;
2673  if (strat->noTailReduction) return L->GetLmCurrRing();
2674  poly h, p;
2675
2676  TObject* With;
2677  // placeholder in case strat->tl < 0
2678  TObject  With_s(strat->tailRing);
2679 
2680  h = L->GetLmTailRing();
2681  p = h;
2682  LObject Ln(pNext(h), strat->tailRing);
2683  Ln.pLength = L->GetpLength() - 1;
2684
2685  pNext(h) = NULL;
2686  if (L->p != NULL) pNext(L->p) = NULL;
2687  L->pLength = 1;
2688
2689#ifdef HAVE_REDTAIL_BUCKETS 
2690  Ln.PrepareRed(strat->use_buckets);
2691#endif
2692
2693  while(!Ln.IsNull())
2694  {
2695    while (1)
2696    {
2697      Ln.SetShortExpVector();
2698      if (! withT)
2699      {
2700        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
2701        if (With == NULL) break;
2702      }
2703      else
2704      {
2705        int j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
2706        if (j < 0) break;
2707        With = &(strat->T[j]);
2708      }
2709      if (ksReducePolyTail(L, With, &Ln))
2710      {
2711        // reducing the tail would violate the exp bound
2712        pNext(h) = Ln.GetTP();
2713        L->pLength += Ln.GetpLength();
2714        if (L->p != NULL) pNext(L->p) = pNext(p);
2715        if (kStratChangeTailRing(strat, L))
2716          return redtailBba(L, pos, strat, withT);
2717        else
2718        { // should never get here -- need to fix this
2719          assume(0);
2720          return NULL;
2721        }
2722      }
2723      strat->redTailChange=TRUE;
2724      if (Ln.IsNull()) goto all_done;
2725    }
2726    pNext(h) = Ln.LmExtractAndIter();
2727    pIter(h);
2728    L->pLength++;
2729  }
2730
2731  all_done:
2732  if (L->p != NULL) pNext(L->p) = pNext(p);
2733  assume(pLength(L->p != NULL ? L->p : L->t_p) == L->pLength);
2734
2735  if (strat->redTailChange)
2736  {
2737    L->last = NULL;
2738    L->length = 0;
2739  }
2740  kTest_L(L);
2741  return L->GetLmCurrRing();
2742}
2743#else
2744poly redtailBba (LObject* L, int pos, kStrategy strat, BOOLEAN withT)
2745{
2746  poly h, hn;
2747  int j;
2748  unsigned long not_sev;
2749  strat->redTailChange=FALSE;
2750  poly p = L->p;
2751  LObject Ln(strat->tailRing);
2752  TObject* With;
2753  // placeholder in case strat->tl < 0
2754  TObject  With_s(strat->tailRing);
2755
2756  if (strat->noTailReduction)
2757    return p;
2758  h = p;
2759  hn = pNext(h);
2760  while(hn != NULL)
2761  {
2762    while (1)
2763    {
2764      Ln.Set(hn, strat->tailRing);
2765      Ln.sev = p_GetShortExpVector(hn, strat->tailRing);
2766      if (! withT)
2767      {
2768        With = kFindDivisibleByInS(strat, pos, &Ln, &With_s);
2769        if (With == NULL) break;
2770      }
2771      else
2772      {
2773        int j = kFindDivisibleByInT(strat->T, strat->sevT, strat->tl, &Ln);
2774        if (j < 0) break;
2775        With = &(strat->T[j]);
2776      }
2777      if (ksReducePolyTail(L, With, h, strat->kNoether))
2778      {
2779        // reducing the tail would violate the exp bound
2780        if (kStratChangeTailRing(strat, L))
2781        {
2782          p = redtailBba(L, pos, strat);
2783          goto all_done;
2784        }
2785        else
2786        {
2787          assume(0);
2788          return NULL;
2789        }
2790      }
2791      strat->redTailChange=TRUE;
2792      hn = pNext(h);
2793      if (hn == NULL) goto all_done;
2794    }
2795    h = hn;
2796    hn = pNext(h);
2797  }
2798
2799  all_done:
2800  if (strat->redTailChange)
2801  {
2802    L->last = NULL;
2803    L->pLength = 0;
2804    L->length = 0;
2805  }
2806  return p;
2807}
2808#endif
2809/*2
2810*checks the change degree and write progress report
2811*/
2812void message (int i,int* reduc,int* olddeg,kStrategy strat)
2813{
2814  if (i != *olddeg)
2815  {
2816    Print("%d",i);
2817    *olddeg = i;
2818  }
2819  if (strat->Ll != *reduc)
2820  {
2821    if (strat->Ll != *reduc-1)
2822      Print("(%d)",strat->Ll+1);
2823    else
2824      PrintS("-");
2825    *reduc = strat->Ll;
2826  }
2827  else
2828    PrintS(".");
2829  mflush();
2830}
2831
2832/*2
2833*statistics
2834*/
2835void messageStat (int srmax,int lrmax,int hilbcount,kStrategy strat)
2836{
2837  //PrintS("\nUsage/Allocation of temporary storage:\n");
2838  //Print("%d/%d polynomials in standard base\n",srmax,IDELEMS(Shdl));
2839  //Print("%d/%d polynomials in set L (for lazy alg.)",lrmax+1,strat->Lmax);
2840  Print("\nproduct criterion:%d chain criterion:%d\n",strat->cp,strat->c3);
2841  if (hilbcount!=0) Print("hilbert series criterion:%d\n",hilbcount);
2842  /*mflush();*/
2843}
2844
2845#ifdef KDEBUG
2846/*2
2847*debugging output: all internal sets, if changed
2848*for testing purpuse only/has to be changed for later use
2849*/
2850void messageSets (kStrategy strat)
2851{
2852  int i;
2853  if (strat->news)
2854  {
2855    PrintS("set S");
2856    for (i=0; i<=strat->sl; i++)
2857    {
2858      Print("\n  %d:",i);
2859      p_wrp(strat->S[i], currRing, strat->tailRing);
2860    }
2861    strat->news = FALSE;
2862  }
2863  if (strat->newt)
2864  {
2865    PrintS("\nset T");
2866    for (i=0; i<=strat->tl; i++)
2867    {
2868      Print("\n  %d:",i);
2869      strat->T[i].wrp();
2870      Print(" o:%d e:%d l:%d",
2871        strat->T[i].pFDeg(),strat->T[i].ecart,strat->T[i].length);
2872    }
2873    strat->newt = FALSE;
2874  }
2875  PrintS("\nset L");
2876  for (i=strat->Ll; i>=0; i--)
2877  {
2878    Print("\n%d:",i);
2879    p_wrp(strat->L[i].p1, currRing, strat->tailRing);
2880    PrintS("  ");
2881    p_wrp(strat->L[i].p2, currRing, strat->tailRing);
2882    PrintS(" lcm: ");p_wrp(strat->L[i].lcm, currRing);
2883    PrintS("\n  p : ");
2884    strat->L[i].wrp();
2885    Print("  o:%d e:%d l:%d",
2886          strat->L[i].pFDeg(),strat->L[i].ecart,strat->L[i].length);
2887  }
2888  PrintLn();
2889}
2890
2891#endif
2892
2893
2894/*2
2895*construct the set s from F
2896*/
2897void initS (ideal F, ideal Q,kStrategy strat)
2898{
2899  int   i,pos;
2900
2901  if (Q!=NULL) i=IDELEMS(Q);
2902  else i=0;
2903  i=((i+IDELEMS(F)+15)/16)*16;
2904  strat->ecartS=initec(i);
2905  strat->sevS=initsevS(i);
2906  strat->S_2_R=initS_2_R(i);
2907  strat->fromQ=NULL;
2908  strat->Shdl=idInit(i,F->rank);
2909  strat->S=strat->Shdl->m;
2910  /*- put polys into S -*/
2911  if (Q!=NULL)
2912  {
2913    strat->fromQ=initec(i);
2914    memset(strat->fromQ,0,i*sizeof(int));
2915    for (i=0; i<IDELEMS(Q); i++)
2916    {
2917      if (Q->m[i]!=NULL)
2918      {
2919        LObject h;
2920        h.p = pCopy(Q->m[i]);
2921        if (TEST_OPT_INTSTRATEGY)
2922        {
2923          //pContent(h.p);
2924          h.pCleardenom(); // also does a pContent
2925        }
2926        else
2927        {
2928          h.pNorm();
2929        }
2930        strat->initEcart(&h);
2931        if (pOrdSgn==-1)
2932        {
2933          deleteHC(&h, strat);
2934        }
2935        if (h.p!=NULL)
2936        {
2937          if (strat->sl==-1)
2938            pos =0;
2939          else
2940          {
2941            pos = posInS(strat->S,strat->sl,h.p);
2942          }
2943          h.sev = pGetShortExpVector(h.p);
2944          strat->enterS(h,pos,strat);
2945          strat->fromQ[pos]=1;
2946        }
2947      }
2948    }
2949  }
2950  for (i=0; i<IDELEMS(F); i++)
2951  {
2952    if (F->m[i]!=NULL)
2953    {
2954      LObject h;
2955      h.p = pCopy(F->m[i]);
2956      if (TEST_OPT_INTSTRATEGY)
2957      {
2958        //pContent(h.p);
2959        h.pCleardenom(); // also does a pContent
2960      }
2961      else
2962      {
2963        h.pNorm();
2964      }
2965      strat->initEcart(&h);
2966      if (pOrdSgn==-1)
2967      {
2968        cancelunit(&h);  /*- tries to cancel a unit -*/
2969        deleteHC(&h, strat);
2970      }
2971      if (TEST_OPT_DEGBOUND
2972          && (((strat->honey) && (h.ecart+pFDeg(h.p)>Kstd1_deg))
2973              || ((!(strat->honey)) && (pFDeg(h.p)>Kstd1_deg))))
2974        pDelete(&h.p);
2975      else
2976        if (h.p!=NULL)
2977        {
2978          if (strat->sl==-1)
2979            pos =0;
2980          else
2981          {
2982            pos = posInS(strat->S,strat->sl,h.p);
2983          }
2984          h.sev = pGetShortExpVector(h.p);
2985          strat->enterS(h,pos,strat);
2986        }
2987    }
2988  }
2989  /*- test, if a unit is in F -*/
2990  if ((strat->sl>=0) && pIsConstant(strat->S[0]))
2991  {
2992    while (strat->sl>0) deleteInS(strat->sl,strat);
2993  }
2994}
2995
2996void initSL (ideal F, ideal Q,kStrategy strat)
2997{
2998  int   i,pos;
2999
3000  if (Q!=NULL) i=IDELEMS(Q);
3001  else i=0;
3002  i=((i+16)/16)*16;
3003  strat->ecartS=initec(i);
3004  strat->sevS=initsevS(i);
3005  strat->S_2_R=initS_2_R(i);
3006  strat->fromQ=NULL;
3007  strat->Shdl=idInit(i,F->rank);
3008  strat->S=strat->Shdl->m;
3009  /*- put polys into S -*/
3010  if (Q!=NULL)
3011  {
3012    strat->fromQ=initec(i);
3013    memset(strat->fromQ,0,i*sizeof(int));
3014    for (i=0; i<IDELEMS(Q); i++)
3015    {
3016      if (Q->m[i]!=NULL)
3017      {
3018        LObject h;
3019        h.p = pCopy(Q->m[i]);
3020        if (TEST_OPT_INTSTRATEGY)
3021        {
3022          //pContent(h.p);
3023          h.pCleardenom(); // also does a pContent
3024        }
3025        else
3026        {
3027          h.pNorm();
3028        }
3029        strat->initEcart(&h);
3030        if (pOrdSgn==-1)
3031        {
3032          deleteHC(&h,strat);
3033        }
3034        if (h.p!=NULL)
3035        {
3036          if (strat->sl==-1)
3037            pos =0;
3038          else
3039          {
3040            pos = posInS(strat->S,strat->sl,h.p);
3041          }
3042          h.sev = pGetShortExpVector(h.p);
3043          strat->enterS(h,pos,strat);
3044          strat->fromQ[pos]=1;
3045        }
3046      }
3047    }
3048  }
3049  for (i=0; i<IDELEMS(F); i++)
3050  {
3051    if (F->m[i]!=NULL)
3052    {
3053      LObject h;
3054      h.p = pCopy(F->m[i]);
3055      if (TEST_OPT_INTSTRATEGY)
3056      {
3057        //pContent(h.p);
3058        h.pCleardenom(); // also does a pContent
3059      }
3060      else
3061      {
3062        h.pNorm();
3063      }
3064      strat->initEcart(&h);
3065      if (pOrdSgn==-1)
3066      {
3067        cancelunit(&h);  /*- tries to cancel a unit -*/
3068        deleteHC(&h, strat);
3069      }
3070      if (TEST_OPT_DEGBOUND
3071          && (((strat->honey) && (h.ecart+pFDeg(h.p)>Kstd1_deg))
3072              || ((!(strat->honey)) && (pFDeg(h.p)>Kstd1_deg))))
3073        pDelete(&h.p);
3074      else
3075        if (h.p!=NULL)
3076        {
3077          if (strat->Ll==-1)
3078            pos =0;
3079          else
3080          {
3081            pos = strat->posInL(strat->L,strat->Ll,&h,strat);
3082          }
3083          h.sev = pGetShortExpVector(h.p);
3084          enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
3085        }
3086    }
3087  }
3088  /*- test, if a unit is in F -*/
3089  if ((strat->Ll>=0) && pIsConstant(strat->L[strat->Ll].p))
3090  {
3091    while (strat->Ll>0) deleteInL(strat->L,&strat->Ll,strat->Ll-1,strat);
3092  }
3093}
3094
3095
3096/*2
3097*construct the set s from F u {P}
3098*/
3099void initSSpecial (ideal F, ideal Q, ideal P,kStrategy strat)
3100{
3101  int   i,pos;
3102
3103  if (Q!=NULL) i=IDELEMS(Q);
3104  else i=0;
3105  i=((i+IDELEMS(F)+15)/16)*16;
3106  strat->ecartS=initec(i);
3107  strat->sevS=initsevS(i);
3108  strat->S_2_R=initS_2_R(i);
3109  strat->fromQ=NULL;
3110  strat->Shdl=idInit(i,F->rank);
3111  strat->S=strat->Shdl->m;
3112
3113  /*- put polys into S -*/
3114  if (Q!=NULL)
3115  {
3116    strat->fromQ=initec(i);
3117    memset(strat->fromQ,0,i*sizeof(int));
3118    for (i=0; i<IDELEMS(Q); i++)
3119    {
3120      if (Q->m[i]!=NULL)
3121      {
3122        LObject h;
3123        h.p = pCopy(Q->m[i]);
3124        //if (TEST_OPT_INTSTRATEGY)
3125        //{
3126        //  //pContent(h.p);
3127        //  h.pCleardenom(); // also does a pContent
3128        //}
3129        //else
3130        //{
3131        //  h.pNorm();
3132        //}
3133        strat->initEcart(&h);
3134        if (pOrdSgn==-1)
3135        {
3136          deleteHC(&h,strat);
3137        }
3138        if (h.p!=NULL)
3139        {
3140          if (strat->sl==-1)
3141            pos =0;
3142          else
3143          {
3144            pos = posInS(strat->S,strat->sl,h.p);
3145          }
3146          h.sev = pGetShortExpVector(h.p);
3147          h.SetpFDeg();
3148          strat->enterS(h,pos,strat, strat->tl+1);
3149          enterT(h, strat);
3150          strat->fromQ[pos]=1;
3151        }
3152      }
3153    }
3154  }
3155  /*- put polys into S -*/
3156  for (i=0; i<IDELEMS(F); i++)
3157  {
3158    if (F->m[i]!=NULL)
3159    {
3160      LObject h;
3161      h.p = pCopy(F->m[i]);
3162      if (pOrdSgn==1)
3163      {
3164        h.p=redtailBba(h.p,strat->sl,strat);
3165      }
3166      strat->initEcart(&h);
3167      if (pOrdSgn==-1)
3168      {
3169        deleteHC(&h,strat);
3170      }
3171      if (TEST_OPT_DEGBOUND
3172      && (((strat->honey) && (h.ecart+pFDeg(h.p)>Kstd1_deg))
3173        || ((!(strat->honey)) && (pFDeg(h.p)>Kstd1_deg))))
3174        pDelete(&h.p);
3175      else
3176      if (h.p!=NULL)
3177      {
3178        if (strat->sl==-1)
3179          pos =0;
3180        else
3181        {
3182          pos = posInS(strat->S,strat->sl,h.p);
3183        }
3184        h.sev = pGetShortExpVector(h.p);
3185        strat->enterS(h,pos,strat, strat->tl+1);
3186        h.length = pLength(h.p);
3187        h.SetpFDeg();
3188        enterT(h,strat);
3189      }
3190    }
3191  }
3192  for (i=0; i<IDELEMS(P); i++)
3193  {
3194    if (P->m[i]!=NULL)
3195    {
3196      LObject h;
3197      h.p=pCopy(P->m[i]);
3198      strat->initEcart(&h);
3199      h.length = pLength(h.p);
3200      if (TEST_OPT_INTSTRATEGY)
3201      {
3202        h.pCleardenom();
3203      }
3204      else
3205      {
3206        h.pNorm();
3207      }
3208      if(strat->sl>=0)
3209      {
3210        if (pOrdSgn==1)
3211        {
3212          h.p=redBba(h.p,strat->sl,strat);
3213          if (h.p!=NULL)
3214            h.p=redtailBba(h.p,strat->sl,strat);
3215        }
3216        else
3217        {
3218          h.p=redMora(h.p,strat->sl,strat);
3219          strat->initEcart(&h);
3220        }
3221        if(h.p!=NULL)
3222        {
3223          if (TEST_OPT_INTSTRATEGY)
3224          {
3225            h.pCleardenom();
3226          }
3227          else
3228          {
3229            h.is_normalized = 0;
3230            h.pNorm();
3231          }
3232          h.sev = pGetShortExpVector(h.p);
3233          h.SetpFDeg();
3234          pos = posInS(strat->S,strat->sl,h.p);
3235          enterpairsSpecial(h.p,strat->sl,h.ecart,pos,strat,strat->tl+1);
3236          strat->enterS(h,pos,strat, strat->tl+1);
3237          enterT(h,strat);
3238        }
3239      }
3240      else
3241      {
3242        h.sev = pGetShortExpVector(h.p);
3243        h.SetpFDeg();
3244        strat->enterS(h,0,strat, strat->tl+1);
3245        enterT(h,strat);
3246      }
3247    }
3248  }
3249}
3250/*2
3251* reduces h using the set S
3252* procedure used in cancelunit1
3253*/
3254static poly redBba1 (poly h,int maxIndex,kStrategy strat)
3255{
3256  int j = 0;
3257  unsigned long not_sev = ~ pGetShortExpVector(h);
3258
3259  while (j <= maxIndex)
3260  {
3261    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j],h, not_sev))
3262       return ksOldSpolyRedNew(strat->S[j],h,strat->kNoether);
3263    else j++;
3264  }
3265  return h;
3266}
3267
3268/*2
3269*tests if p.p=monomial*unit and cancels the unit
3270*/
3271void cancelunit1 (LObject* p,int index,kStrategy strat )
3272{
3273  int k;
3274  poly r,h,h1,q;
3275
3276  if (!pIsVector((*p).p) && ((*p).ecart != 0))
3277  {
3278    k = 0;
3279    h1 = r = pCopy((*p).p);
3280    h =pNext(r);
3281    loop
3282    {
3283      if (h==NULL)
3284      {
3285        pDelete(&r);
3286        pDelete(&(pNext((*p).p)));
3287        (*p).ecart = 0;
3288        (*p).length = 1;
3289        return;
3290      }
3291      if (!pDivisibleBy(r,h))
3292      {
3293        q=redBba1(h,index ,strat);
3294        if (q != h)
3295        {
3296          k++;
3297          pDelete(&h);
3298          pNext(h1) = h = q;
3299        }
3300        else
3301        {
3302          pDelete(&r);
3303          return;
3304        }
3305      }
3306      else
3307      {
3308        h1 = h;
3309        pIter(h);
3310      }
3311      if (k > 10)
3312      {
3313        pDelete(&r);
3314        return;
3315      }
3316    }
3317  }
3318}
3319
3320/*2
3321* reduces h using the elements from Q in the set S
3322* procedure used in updateS
3323* must not be used for elements of Q or elements of an ideal !
3324*/
3325static poly redQ (poly h, int j, kStrategy strat)
3326{
3327  int start;
3328  unsigned long not_sev = ~ pGetShortExpVector(h);
3329  while ((j <= strat->sl) && (pGetComp(strat->S[j])!=0)) j++;
3330  start=j;
3331  while (j<=strat->sl)
3332  {
3333    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
3334    {
3335      h = ksOldSpolyRed(strat->S[j],h,strat->kNoether);
3336      if (h==NULL) return NULL;
3337      j = start;
3338      not_sev = ~ pGetShortExpVector(h);
3339    }
3340    else j++;
3341  }
3342  return h;
3343}
3344
3345/*2
3346* reduces h using the set S
3347* procedure used in updateS
3348*/
3349static poly redBba (poly h,int maxIndex,kStrategy strat)
3350{
3351  int j = 0;
3352  unsigned long not_sev = ~ pGetShortExpVector(h);
3353
3354  while (j <= maxIndex)
3355  {
3356    if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev))
3357    {
3358      h = ksOldSpolyRed(strat->S[j],h,strat->kNoether);
3359      if (h==NULL) return NULL;
3360      j = 0;
3361      not_sev = ~ pGetShortExpVector(h);    }
3362    else j++;
3363  }
3364  return h;
3365}
3366
3367/*2
3368* reduces h using the set S
3369*e is the ecart of h
3370*procedure used in updateS
3371*/
3372static poly redMora (poly h,int maxIndex,kStrategy strat)
3373{
3374  int  j=0;
3375  int  e,l;
3376  unsigned long not_sev = ~ pGetShortExpVector(h);
3377
3378  if (maxIndex >= 0)
3379  {
3380    e = pLDeg(h,&l)-pFDeg(h);
3381    do
3382    {
3383      if (pLmShortDivisibleBy(strat->S[j],strat->sevS[j], h, not_sev)
3384      && ((e >= strat->ecartS[j]) || strat->kHEdgeFound))
3385      {
3386#ifdef KDEBUG
3387        if (TEST_OPT_DEBUG)
3388          {PrintS("reduce ");wrp(h);Print(" with S[%d] (",j);wrp(strat->S[j]);}
3389       
3390#endif         
3391        h = ksOldSpolyRed(strat->S[j],h,strat->kNoether);
3392#ifdef KDEBUG
3393        if(TEST_OPT_DEBUG)
3394          {PrintS(")\nto "); wrp(h); PrintLn();}
3395       
3396#endif
3397        // pDelete(&h);
3398        if (h == NULL) return NULL;
3399        e = pLDeg(h,&l)-pFDeg(h);
3400        j = 0;
3401        not_sev = ~ pGetShortExpVector(h);
3402      }
3403      else j++;
3404    }
3405    while (j <= maxIndex);
3406  }
3407  return h;
3408}
3409
3410/*2
3411*updates S:
3412*the result is a set of polynomials which are in
3413*normalform with respect to S
3414*/
3415void updateS(BOOLEAN toT,kStrategy strat)
3416{
3417  LObject h;
3418  int i, suc=0;
3419  poly redSi=NULL;
3420//Print("nach initS: updateS start mit sl=%d\n",(strat->sl));
3421//  for (i=0; i<=(strat->sl); i++)
3422//  {
3423//    Print("s%d:",i);
3424//    if (strat->fromQ!=NULL) Print("(Q:%d) ",strat->fromQ[i]);
3425//    pWrite(strat->S[i]);
3426//  }
3427  if (pOrdSgn==1)
3428  {
3429    while (suc != -1)
3430    {
3431      i=suc+1;
3432      while (i<=strat->sl)
3433      {
3434        if (((strat->syzComp==0) || (pGetComp(strat->S[i])<=strat->syzComp))
3435        && ((strat->fromQ==NULL) || (strat->fromQ[i]==0)))
3436        {
3437          pDelete(&redSi);
3438          redSi = pHead(strat->S[i]);
3439          strat->S[i] = redBba(strat->S[i],i-1,strat);
3440          if ((strat->ak!=0)&&(strat->S[i]!=NULL))
3441            strat->S[i]=redQ(strat->S[i],i+1,strat); /*reduce S[i] mod Q*/
3442          if (TEST_OPT_DEBUG && (pCmp(redSi,strat->S[i])!=0))
3443          {
3444            PrintS("reduce:");
3445            wrp(redSi);PrintS(" to ");p_wrp(strat->S[i], currRing, strat->tailRing);PrintLn();
3446          }
3447          if (TEST_OPT_PROT && (pCmp(redSi,strat->S[i])!=0))
3448          {
3449            if (strat->S[i]==NULL)
3450              PrintS("V");
3451            else
3452              PrintS("v");
3453            mflush();
3454          }
3455          if (strat->S[i]==NULL)
3456          {
3457            pDelete(&redSi);
3458            deleteInS(i,strat);
3459            i--;
3460          }
3461          else
3462          {
3463            pDelete(&redSi);
3464            if (TEST_OPT_INTSTRATEGY)
3465            {
3466              //pContent(strat->S[i]);
3467              pCleardenom(strat->S[i]);// also does a pContent
3468            }
3469            else
3470            {
3471              pNorm(strat->S[i]);
3472            }
3473            strat->sevS[i] = pGetShortExpVector(strat->S[i]);
3474          }
3475        }
3476        i++;
3477      }
3478      reorderS(&suc,strat);
3479    }
3480    if (toT)
3481    {
3482      for (i=0; i<=strat->sl; i++)
3483      {
3484        if (((strat->fromQ==NULL) || (strat->fromQ[i]==0))
3485        )
3486          h.p = redtailBba(strat->S[i],i-1,strat);
3487        else
3488        {
3489          h.p = strat->S[i];
3490        }
3491        if (strat->honey)
3492        {
3493          strat->initEcart(&h);
3494          strat->ecartS[i] = h.ecart;
3495        }
3496        if (strat->sevS[i] == 0) {strat->sevS[i] = pGetShortExpVector(h.p);}
3497        else assume(strat->sevS[i] == pGetShortExpVector(h.p));
3498        h.sev = strat->sevS[i];
3499        h.SetpFDeg();
3500        /*puts the elements of S also to T*/
3501        enterT(h,strat);
3502        strat->S_2_R[i] = strat->tl;
3503      }
3504    }
3505  }
3506  else
3507  {
3508    while (suc != -1)
3509    {
3510      i=suc+1;
3511      while (i<=strat->sl)
3512      {
3513        if (((strat->syzComp==0) || (pGetComp(strat->S[i])<=strat->syzComp))
3514        && ((strat->fromQ==NULL) || (strat->fromQ[i]==0)))
3515        {
3516          pDelete(&redSi);
3517          redSi=pHead((strat->S)[i]);
3518          (strat->S)[i] = redMora((strat->S)[i],i-1,strat);
3519          if ((strat->S)[i]==NULL)
3520          {
3521            deleteInS(i,strat);
3522            i--;
3523          }
3524          else
3525          {
3526            if (TEST_OPT_INTSTRATEGY)
3527            {
3528              pDelete(&redSi);
3529              pCleardenom(strat->S[i]);// also does a pContent
3530              h.p = strat->S[i];
3531              strat->initEcart(&h);
3532              strat->ecartS[i] = h.ecart;
3533            }
3534            else
3535            {
3536              pDelete(&redSi);
3537              pNorm(strat->S[i]);
3538              h.p = strat->S[i];
3539              strat->initEcart(&h);
3540              strat->ecartS[i] = h.ecart;
3541            }
3542            h.sev =  pGetShortExpVector(h.p);
3543            strat->sevS[i] = h.sev;
3544          }
3545          kTest(strat);
3546        }
3547        i++;
3548      }
3549#ifdef KDEBUG
3550      kTest(strat);
3551#endif
3552      reorderS(&suc,strat);
3553      if (h.p!=NULL)
3554      {
3555        if (!strat->kHEdgeFound)
3556        {
3557          /*strat->kHEdgeFound =*/ HEckeTest(h.p,strat);
3558        }
3559        if (strat->kHEdgeFound)
3560          newHEdge(strat->S,strat->ak,strat);
3561      }
3562    }
3563    for (i=0; i<=strat->sl; i++)
3564    {
3565      if (((strat->fromQ==NULL) || (strat->fromQ[i]==0))
3566      )
3567      {
3568        strat->S[i] = h.p = redtail(strat->S[i],strat->sl,strat);
3569        strat->initEcart(&h);
3570        strat->ecartS[i] = h.ecart;
3571        h.sev = pGetShortExpVector(h.p);
3572        strat->sevS[i] = h.sev;
3573      }
3574      else
3575      {
3576        h.p = strat->S[i];
3577        h.ecart=strat->ecartS[i];
3578        h.sev = strat->sevS[i];
3579      }
3580      if ((strat->fromQ==NULL) || (strat->fromQ[i]==0))
3581        cancelunit1(&h,strat->sl,strat);
3582      h.length = pLength(h.p);
3583      h.SetpFDeg();
3584      /*puts the elements of S also to T*/
3585      enterT(h,strat);
3586      strat->S_2_R[i] = strat->tl;
3587    }
3588  }
3589  if (redSi!=NULL) pDeleteLm(&redSi);
3590#ifdef KDEBUG
3591  kTest(strat);
3592#endif
3593}
3594
3595
3596/*2
3597* -puts p to the standardbasis s at position at
3598* -saves the result in S
3599*/
3600void enterSBba (LObject p,int atS,kStrategy strat, int atR)
3601{
3602  int i;
3603  strat->news = TRUE;
3604  /*- puts p to the standardbasis s at position at -*/
3605  if (strat->sl == IDELEMS(strat->Shdl)-1)
3606  {
3607    strat->sevS = (unsigned long*) omRealloc0Size(strat->sevS,
3608                                    IDELEMS(strat->Shdl)*sizeof(unsigned long),
3609                                    (IDELEMS(strat->Shdl)+setmax)
3610                                                  *sizeof(unsigned long));
3611    strat->ecartS = (intset)omReallocSize(strat->ecartS,
3612                                          IDELEMS(strat->Shdl)*sizeof(int),
3613                                          (IDELEMS(strat->Shdl)+setmax)*sizeof(int));
3614    strat->S_2_R = (int*) omRealloc0Size(strat->S_2_R, 
3615                                         IDELEMS(strat->Shdl)*sizeof(int),
3616                                         (IDELEMS(strat->Shdl)+setmax)
3617                                                  *sizeof(int));
3618    if (strat->fromQ!=NULL)
3619    {
3620      strat->fromQ = (intset)omReallocSize(strat->fromQ,
3621                                    IDELEMS(strat->Shdl)*sizeof(int),
3622                                    (IDELEMS(strat->Shdl)+setmax)*sizeof(int));
3623    }
3624    pEnlargeSet(&strat->S,IDELEMS(strat->Shdl),setmax);
3625    IDELEMS(strat->Shdl)+=setmax;
3626    strat->Shdl->m=strat->S;
3627  }
3628  if (atS <= strat->sl)
3629  {
3630#ifdef ENTER_USE_MEMMOVE
3631// #if 0
3632    memmove(&(strat->S[atS+1]), &(strat->S[atS]), 
3633            (strat->sl - atS + 1)*sizeof(poly));
3634    memmove(&(strat->ecartS[atS+1]), &(strat->ecartS[atS]), 
3635            (strat->sl - atS + 1)*sizeof(int));
3636    memmove(&(strat->sevS[atS+1]), &(strat->sevS[atS]), 
3637            (strat->sl - atS + 1)*sizeof(unsigned long));
3638    memmove(&(strat->S_2_R[atS+1]), &(strat->S_2_R[atS]), 
3639            (strat->sl - atS + 1)*sizeof(int));
3640#else   
3641    for (i=strat->sl+1; i>=atS+1; i--)
3642    {
3643      strat->S[i] = strat->S[i-1];
3644      strat->ecartS[i] = strat->ecartS[i-1];
3645      strat->sevS[i] = strat->sevS[i-1];
3646      strat->S_2_R[i] = strat->S_2_R[i-1];
3647    }
3648#endif
3649  }
3650  if (strat->fromQ!=NULL)
3651  {
3652    for (i=strat->sl+1; i>=atS+1; i--)
3653    {
3654      strat->fromQ[i] = strat->fromQ[i-1];
3655    }
3656    strat->fromQ[atS]=0;
3657  }
3658
3659  /*- save result -*/
3660  strat->S[atS] = p.p;
3661  if (strat->honey) strat->ecartS[atS] = p.ecart;
3662  if (p.sev == 0)
3663    p.sev = pGetShortExpVector(p.p);
3664  else
3665    assume(p.sev == pGetShortExpVector(p.p));
3666  strat->sevS[atS] = p.sev;
3667  strat->ecartS[atS] = p.ecart;
3668  strat->S_2_R[atS] = atR;
3669  strat->sl++;
3670}
3671
3672/*2
3673* puts p to the set T at position atT
3674*/
3675void enterT(LObject p, kStrategy strat, int atT = -1)
3676{
3677  int i;
3678
3679  pp_Test(p.p, currRing, p.tailRing);
3680  assume(strat->tailRing == p.tailRing);
3681  // redMoraNF complains about this -- but, we don't really
3682  // neeed this so far
3683  // assume(p.pLength == 0 || pLength(p.p) == p.pLength);
3684  assume(p.FDeg == p.pFDeg());
3685  assume(!p.is_normalized || nIsOne(pGetCoeff(p.p)));
3686
3687  strat->newt = TRUE;
3688  if (atT < 0)
3689    atT = strat->posInT(strat->T, strat->tl, p);
3690  if (strat->tl == strat->tmax-1) 
3691    enlargeT(strat->T,strat->R,strat->sevT,strat->tmax,setmax);
3692  if (atT <= strat->tl)
3693  {
3694#ifdef ENTER_USE_MEMMOVE
3695    memmove(&(strat->T[atT+1]), &(strat->T[atT]), 
3696            (strat->tl-atT+1)*sizeof(TObject));
3697    memmove(&(strat->sevT[atT+1]), &(strat->sevT[atT]), 
3698            (strat->tl-atT+1)*sizeof(unsigned long));
3699#endif
3700    for (i=strat->tl+1; i>=atT+1; i--)
3701    {
3702#ifndef ENTER_USE_MEMMOVE
3703      strat->T[i] = strat->T[i-1];
3704      strat->sevT[i] = strat->sevT[i-1];
3705#endif
3706      strat->R[strat->T[i].i_r] = &(strat->T[i]);
3707    }
3708  }
3709
3710  if (strat->tailBin != NULL && (pNext(p.p) != NULL))
3711  {
3712    pNext(p.p)=p_ShallowCopyDelete(pNext(p.p),
3713                                   (strat->tailRing != NULL ? 
3714                                    strat->tailRing : currRing),
3715                                   strat->tailBin);
3716    if (p.t_p != NULL) pNext(p.t_p) = pNext(p.p);
3717  }
3718  strat->T[atT] = (TObject) p;
3719
3720  if (strat->tailRing != currRing && pNext(p.p) != NULL)
3721    strat->T[atT].max = p_GetMaxExpP(pNext(p.p), strat->tailRing);
3722  else
3723    strat->T[atT].max = NULL;
3724
3725  strat->tl++;
3726  strat->R[strat->tl] = &(strat->T[atT]);
3727  strat->T[atT].i_r = strat->tl;
3728  assume(p.sev == 0 || pGetShortExpVector(p.p) == p.sev);
3729  strat->sevT[atT] = (p.sev == 0 ? pGetShortExpVector(p.p) : p.sev);
3730  kTest_T(&(strat->T[atT]));
3731}
3732
3733void initHilbCrit(ideal F, ideal Q, intvec **hilb,kStrategy strat)
3734{
3735  if (strat->homog!=isHomog)
3736  {
3737    *hilb=NULL;
3738  }
3739}
3740
3741void initBuchMoraCrit(kStrategy strat)
3742{
3743  strat->sugarCrit =        TEST_OPT_SUGARCRIT;
3744  // obachman: Hmm.. I need BTEST1(2) for notBuckets ..
3745  //  strat->Gebauer =          BTEST1(2) || strat->homog || strat->sugarCrit;
3746  strat->Gebauer =          strat->homog || strat->sugarCrit;
3747  strat->honey =            !strat->homog || strat->sugarCrit || TEST_OPT_WEIGHTM;
3748  if (TEST_OPT_NOT_SUGAR) strat->honey = FALSE;
3749  strat->pairtest = NULL;
3750  /* alway use tailreduction, except:
3751  * - in local rings, - in lex order case, -in ring over extensions */
3752  strat->noTailReduction = !TEST_OPT_REDTAIL;
3753  if (TEST_OPT_DEBUG)
3754  {
3755    if (strat->homog) PrintS("ideal/module is homogeneous\n");
3756    else              PrintS("ideal/module is not homogeneous\n");
3757  }
3758}
3759
3760BOOLEAN kPosInLDependsOnLength(int (*pos_in_l)
3761                               (const LSet set, const int length,
3762                                LObject* L,const kStrategy strat))
3763{
3764  if (pos_in_l == posInL110 ||
3765      pos_in_l == posInL10) 
3766    return TRUE;
3767
3768  return FALSE;
3769}
3770
3771void initBuchMoraPos (kStrategy strat)
3772{
3773  if (pOrdSgn==1)
3774  {
3775    if (strat->honey)
3776    {
3777      strat->posInL = posInL15;
3778      strat->posInT = posInT15;
3779    }
3780    else if (pLexOrder && !TEST_OPT_INTSTRATEGY)
3781    {
3782      strat->posInL = posInL11;
3783      strat->posInT = posInT11;
3784    }
3785    else if (TEST_OPT_INTSTRATEGY)
3786    {
3787      strat->posInL = posInL11;
3788      strat->posInT = posInT11;
3789    }
3790    else
3791    {
3792      strat->posInL = posInL0;
3793      strat->posInT = posInT0;
3794    }
3795    //if (strat->minim>0) strat->posInL =posInLSpecial;
3796  }
3797  else
3798  {
3799    if (strat->homog)
3800    {
3801      strat->posInL = posInL11;
3802      strat->posInT = posInT11;
3803    }
3804    else
3805    {
3806      if ((currRing->order[0]==ringorder_c)
3807      ||(currRing->order[0]==ringorder_C))
3808      {
3809        strat->posInL = posInL17_c;
3810        strat->posInT = posInT17_c;
3811      }
3812      else
3813      {
3814        strat->posInL = posInL17;
3815        strat->posInT = posInT17;
3816      }
3817    }
3818  }
3819  if (strat->minim>0) strat->posInL =posInLSpecial;
3820  // for further tests only
3821  if ((BTEST1(11)) || (BTEST1(12)))
3822    strat->posInL = posInL11;
3823  else if ((BTEST1(13)) || (BTEST1(14)))
3824    strat->posInL = posInL13;
3825  else if ((BTEST1(15)) || (BTEST1(16)))
3826    strat->posInL = posInL15;
3827  else if ((BTEST1(17)) || (BTEST1(18)))
3828    strat->posInL = posInL17;
3829  if (BTEST1(11))
3830    strat->posInT = posInT11;
3831  else if (BTEST1(13))
3832    strat->posInT = posInT13;
3833  else if (BTEST1(15))
3834    strat->posInT = posInT15;
3835  else if ((BTEST1(17)))
3836    strat->posInT = posInT17;
3837  else if ((BTEST1(19)))
3838    strat->posInT = posInT19;
3839  else if (BTEST1(12) || BTEST1(14) || BTEST1(16) || BTEST1(18))
3840    strat->posInT = posInT1;
3841  strat->posInLDependsOnLength = kPosInLDependsOnLength(strat->posInL);
3842}
3843
3844void initBuchMora (ideal F,ideal Q,kStrategy strat)
3845{
3846  strat->interpt = BTEST1(OPT_INTERRUPT);
3847  strat->kHEdge=NULL;
3848  if (pOrdSgn==1) strat->kHEdgeFound=FALSE;
3849  /*- creating temp data structures------------------- -*/
3850  strat->cp = 0;
3851  strat->c3 = 0;
3852  strat->tail = pInit();
3853  /*- set s -*/
3854  strat->sl = -1;
3855  /*- set L -*/
3856  strat->Lmax = setmax;
3857  strat->Ll = -1;
3858  strat->L = initL();
3859  /*- set B -*/
3860  strat->Bmax = setmax;
3861  strat->Bl = -1;
3862  strat->B = initL();
3863  /*- set T -*/
3864  strat->tl = -1;
3865  strat->tmax = setmax;
3866  strat->T = initT();
3867  strat->R = initR();
3868  strat->sevT = initsevT();
3869  /*- init local data struct.---------------------------------------- -*/
3870  strat->P.ecart=0;
3871  strat->P.length=0;
3872  if (pOrdSgn==-1)
3873  {
3874    if (strat->kHEdge!=NULL) pSetComp(strat->kHEdge, strat->ak);
3875    if (strat->kNoether!=NULL) pSetComp(strat->kNoether, strat->ak);
3876  }
3877  if(TEST_OPT_SB_1)
3878  {
3879    int i;
3880    ideal P=idInit(IDELEMS(F)-strat->newIdeal,F->rank);
3881    for (i=strat->newIdeal;i<IDELEMS(F);i++)
3882    {
3883      P->m[i-strat->newIdeal] = F->m[i];
3884      F->m[i] = NULL;
3885    }
3886    initSSpecial(F,Q,P,strat);
3887    for (i=strat->newIdeal;i<IDELEMS(F);i++)
3888    {
3889      F->m[i] = P->m[i-strat->newIdeal];
3890      P->m[i-strat->newIdeal] = NULL;
3891    }
3892    idDelete(&P);
3893  }
3894  else
3895  {
3896    /*Shdl=*/initSL(F, Q,strat); /*sets also S, ecartS, fromQ */
3897    // /*Shdl=*/initS(F, Q,strat); /*sets also S, ecartS, fromQ */
3898  }
3899  strat->kIdeal = NULL;
3900  strat->fromT = FALSE;
3901  strat->noTailReduction = !TEST_OPT_REDTAIL;
3902  if(!TEST_OPT_SB_1)
3903  {
3904    updateS(TRUE,strat);
3905    pairs(strat);
3906  }
3907  if (strat->fromQ!=NULL) omFreeSize(strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
3908  strat->fromQ=NULL;
3909}
3910
3911void exitBuchMora (kStrategy strat)
3912{
3913  /*- release temp data -*/
3914  cleanT(strat);
3915  omFreeSize(strat->T,(strat->tmax)*sizeof(TObject));
3916  omFreeSize(strat->R,(strat->tmax)*sizeof(TObject*));
3917  omFreeSize(strat->sevT, (strat->tmax)*sizeof(unsigned long));
3918  omFreeSize(strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
3919  omFreeSize(strat->sevS,IDELEMS(strat->Shdl)*sizeof(int));
3920  omFreeSize(strat->S_2_R,IDELEMS(strat->Shdl)*sizeof(int));
3921  /*- set L: should be empty -*/
3922  omFreeSize(strat->L,(strat->Lmax)*sizeof(LObject));
3923  /*- set B: should be empty -*/
3924  omFreeSize(strat->B,(strat->Bmax)*sizeof(LObject));
3925  pDeleteLm(&strat->tail);
3926  strat->syzComp=0;
3927  if (strat->kIdeal!=NULL)
3928  {
3929    omFreeBin(strat->kIdeal, sleftv_bin);
3930    strat->kIdeal=NULL;
3931  }
3932}
3933
3934/*2
3935* in the case of a standardbase of a module over a qring:
3936* replace polynomials in i by ak vectors,
3937* (the polynomial * unit vectors gen(1)..gen(ak)
3938* in every case (also for ideals:)
3939* deletes divisible vectors/polynomials
3940*/
3941void updateResult(ideal r,ideal Q,kStrategy strat)
3942{
3943  int l;
3944  if (strat->ak>0)
3945  {
3946    for (l=IDELEMS(r)-1;l>=0;l--)
3947    {
3948      if ((r->m[l]!=NULL) && (pGetComp(r->m[l])==0))
3949      {
3950        pDelete(&r->m[l]); // and set it to NULL
3951      }
3952    }
3953  }
3954  else
3955  {
3956    int q;
3957    poly p;
3958    for (l=IDELEMS(r)-1;l>=0;l--)
3959    {
3960      if (r->m[l]!=NULL)
3961      {
3962        for(q=IDELEMS(Q)-1; q>=0;q--)
3963        {
3964          if ((Q->m[q]!=NULL)
3965          &&(pLmEqual(r->m[l],Q->m[q])))
3966          {
3967            if (TEST_OPT_REDSB)
3968            {
3969              p=r->m[l];
3970              r->m[l]=kNF(Q,NULL,p);
3971              pDelete(&p);
3972            }
3973            else
3974            {
3975              pDelete(&r->m[l]); // and set it to NULL
3976            }
3977            break;
3978          }
3979        }
3980      }
3981    }
3982  }
3983  idSkipZeroes(r);
3984}
3985
3986void completeReduce (kStrategy strat)
3987{
3988  int i;
3989
3990  strat->noTailReduction = FALSE;
3991  if (TEST_OPT_PROT)
3992  {
3993    PrintLn();
3994    if (timerv) writeTime("standard base computed:");
3995  }
3996  if (TEST_OPT_PROT)
3997  {
3998    Print("(S:%d)",strat->sl);mflush();
3999  }
4000  if(pOrdSgn==1)
4001  {
4002    for (i=strat->sl; i>0; i--)
4003    {
4004      //if (strat->interpt) test_int_std(strat->kIdeal);
4005      strat->S[i] = redtailBba(strat->S[i],i-1,strat);
4006      if (TEST_OPT_INTSTRATEGY)
4007      {
4008        //if (strat->redTailChange)
4009          pCleardenom(strat->S[i]);
4010      }
4011      if (TEST_OPT_PROT)
4012      {
4013        PrintS("-");mflush();
4014      }
4015    }
4016  }
4017  else
4018  {
4019    for (i=strat->sl; i>=0; i--)
4020    {
4021      strat->S[i] = redtail(strat->S[i],strat->sl,strat);
4022      // Hmm .. this might also change strat->T[i]
4023      // but, we don't need it any more
4024      if (TEST_OPT_INTSTRATEGY)
4025        pCleardenom(strat->S[i]);
4026      if (TEST_OPT_PROT)
4027        PrintS("-");
4028    }
4029  }
4030}
4031
4032
4033/*2
4034* computes the new strat->kHEdge and the new pNoether,
4035* returns TRUE, if pNoether has changed
4036*/
4037BOOLEAN newHEdge(polyset S, int ak,kStrategy strat)
4038{
4039  int i,j;
4040  poly newNoether;
4041
4042  scComputeHC(strat->Shdl,ak,strat->kHEdge);
4043  /* compare old and new noether*/
4044  newNoether = pLmInit(strat->kHEdge);
4045  j = pFDeg(newNoether);
4046  for (i=1; i<=pVariables; i++)
4047  {
4048    if (pGetExp(newNoether, i) > 0) pDecrExp(newNoether,i);
4049  }
4050  pSetm(newNoether);
4051  if (j < strat->HCord) /*- statistics -*/
4052  {
4053    if (TEST_OPT_PROT)
4054    {
4055      Print("H(%d)",j);
4056      mflush();
4057    }
4058    strat->HCord=j;
4059    if (TEST_OPT_DEBUG)
4060    {
4061      Print("H(%d):",j);
4062      wrp(strat->kHEdge);
4063      PrintLn();
4064    }
4065  }
4066  if (pCmp(strat->kNoether,newNoether)!=1)
4067  {
4068    pDelete(&strat->kNoether);
4069    strat->kNoether=newNoether;
4070    return TRUE;
4071  }
4072  pLmFree(newNoether);
4073  return FALSE;
4074}
4075
4076/***************************************************************
4077 *
4078 * Routines related for ring changes during std computations
4079 *
4080 ***************************************************************/
4081BOOLEAN kCheckSpolyCreation(LObject *L, kStrategy strat, poly &m1, poly &m2)
4082{
4083  assume(L->p1 != NULL && L->p2 != NULL);
4084  assume(L->i_r1 >= 0 && L->i_r1 <= strat->tl);
4085  assume(L->i_r2 >= 0 && L->i_r2 <= strat->tl);
4086  assume(strat->tailRing != currRing);
4087 
4088  if (! k_GetLeadTerms(L->p1, L->p2, currRing, m1, m2, strat->tailRing))
4089    return FALSE;
4090  poly p1_max = (strat->R[L->i_r1])->max;
4091  poly p2_max = (strat->R[L->i_r2])->max;
4092 
4093  if ((p1_max != NULL && !p_LmExpVectorAddIsOk(m1, p1_max, strat->tailRing)) ||
4094      (p2_max != NULL && !p_LmExpVectorAddIsOk(m2, p2_max, strat->tailRing)))
4095  {
4096    p_LmFree(m1, strat->tailRing);
4097    p_LmFree(m2, strat->tailRing);
4098    m1 = NULL;
4099    m2 = NULL;
4100    return FALSE;
4101  }
4102  return TRUE;
4103}
4104                       
4105BOOLEAN kStratChangeTailRing(kStrategy strat, LObject *L, TObject* T, unsigned long expbound)
4106{
4107  if (expbound == 0) expbound = strat->tailRing->bitmask << 1;
4108  if (expbound >= currRing->bitmask) return FALSE;
4109  ring new_tailRing = rModifyRing(currRing,
4110                                  // Hmmm .. the condition pFDeg == pDeg
4111                                  // might be too strong
4112                                  (strat->homog && pFDeg == pDeg && pOrdSgn == 1), 
4113                                  !strat->ak, 
4114                                  expbound);
4115
4116  if (new_tailRing == currRing) return TRUE;
4117  if (TEST_OPT_PROT)
4118    Print("[%d:%d", (long) new_tailRing->bitmask, new_tailRing->ExpL_Size);
4119  kTest_TS(strat);
4120  assume(new_tailRing != strat->tailRing);
4121  pShallowCopyDeleteProc p_shallow_copy_delete
4122    = pGetShallowCopyDeleteProc(strat->tailRing, new_tailRing);
4123 
4124  omBin new_tailBin = omGetStickyBinOfBin(new_tailRing->PolyBin);
4125 
4126  int i;
4127  for (i=0; i<=strat->tl; i++)
4128  {
4129    strat->T[i].ShallowCopyDelete(new_tailRing, new_tailBin, 
4130                                  p_shallow_copy_delete);
4131  }
4132  for (i=0; i<=strat->Ll; i++)
4133  {
4134    assume(strat->L[i].p != NULL);
4135    if (pNext(strat->L[i].p) != strat->tail)
4136      strat->L[i].ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
4137  }
4138  if (strat->P.t_p != NULL || 
4139      (strat->P.p != NULL && pNext(strat->P.p) != strat->tail))
4140    strat->P.ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
4141 
4142  if (L != NULL && L->tailRing != new_tailRing)
4143    L->ShallowCopyDelete(new_tailRing, p_shallow_copy_delete);
4144  if (T != NULL && T->tailRing != new_tailRing)
4145    T->ShallowCopyDelete(new_tailRing, new_tailBin, p_shallow_copy_delete);
4146   
4147  omMergeStickyBinIntoBin(strat->tailBin, strat->tailRing->PolyBin);
4148  if (strat->tailRing != currRing)
4149    rKillModifiedRing(strat->tailRing);
4150 
4151  strat->tailRing = new_tailRing;
4152  strat->tailBin = new_tailBin;
4153  strat->p_shallow_copy_delete
4154    = pGetShallowCopyDeleteProc(currRing, new_tailRing);
4155  kTest_TS(strat);
4156  if (TEST_OPT_PROT)
4157    PrintS("]");
4158  return TRUE;
4159}
4160
4161void kStratInitChangeTailRing(kStrategy strat)
4162{
4163  unsigned long l = 0;
4164  int i;
4165  Exponent_t e;
4166  ring new_tailRing;
4167 
4168  assume(strat->tailRing == currRing);
4169
4170  for (i=0; i<= strat->Ll; i++)
4171  {
4172    l = p_GetMaxExpL(strat->L[i].p, currRing, l);
4173  }
4174  for (i=0; i<=strat->tl; i++)
4175  {
4176    // Hmm ... this we could do in one Step
4177    l = p_GetMaxExpL(strat->T[i].p, currRing, l);
4178  }
4179  e = p_GetMaxExp(l, currRing);
4180  if (e <= 1) e = 2;
4181 
4182  kStratChangeTailRing(strat, NULL, NULL, e);
4183}
4184
4185#endif // KUTIL_CC
Note: See TracBrowser for help on using the repository browser.