source: git/kernel/kutil.cc @ cce4a2f

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