source: git/Singular/kutil.cc @ c16804

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