source: git/kernel/GBEngine/kstd1.cc @ 2d223b

fieker-DuValspielwiese
Last change on this file since 2d223b was 2d223b, checked in by Adi Popescu <adi_popescum@…>, 9 years ago
funny stuff
  • Property mode set to 100644
File size: 85.0 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT:
6*/
7
8// TODO: why the following is here instead of mod2.h???
9
10
11// define if buckets should be used
12#define MORA_USE_BUCKETS
13
14#define MYTEST 0
15
16#define ADIDEBUG 0
17#define ADIDEBUG_NF 0
18
19#include <kernel/mod2.h>
20
21#include <omalloc/omalloc.h>
22
23#include <misc/options.h>
24#include <misc/intvec.h>
25
26#if MYTEST
27#ifdef HAVE_TAIL_RING
28#undef HAVE_TAIL_RING
29#endif /* ifdef HAVE_TAIL_RING */
30#endif /* if MYTEST */
31
32#include <polys/weight.h>
33#include <kernel/polys.h>
34
35#include <kernel/GBEngine/kutil.h>
36#include <kernel/GBEngine/kstd1.h>
37#include <kernel/GBEngine/khstd.h>
38#include <kernel/combinatorics/stairc.h>
39//#include "cntrlc.h"
40#include <kernel/ideals.h>
41//#include "../Singular/ipid.h"
42
43//#include "ipprint.h"
44
45#ifdef HAVE_PLURAL
46#include <polys/nc/nc.h>
47#include <polys/nc/sca.h>
48#include <kernel/GBEngine/nc.h>
49#endif
50
51#include <kernel/GBEngine/kInline.h>
52
53
54/* the list of all options which give a warning by test */
55BITSET kOptions=Sy_bit(OPT_PROT)           /*  0 */
56                |Sy_bit(OPT_REDSB)         /*  1 */
57                |Sy_bit(OPT_NOT_SUGAR)     /*  3 */
58                |Sy_bit(OPT_INTERRUPT)     /*  4 */
59                |Sy_bit(OPT_SUGARCRIT)     /*  5 */
60                |Sy_bit(OPT_REDTHROUGH)
61                |Sy_bit(OPT_OLDSTD)
62                |Sy_bit(OPT_FASTHC)        /* 10 */
63                |Sy_bit(OPT_INTSTRATEGY)   /* 26 */
64                |Sy_bit(OPT_INFREDTAIL)    /* 28 */
65                |Sy_bit(OPT_NOTREGULARITY) /* 30 */
66                |Sy_bit(OPT_WEIGHTM);      /* 31 */
67
68/* the list of all options which may be used by option and test */
69/* defintion of ALL options: libpolys/misc/options.h */
70BITSET validOpts=Sy_bit(0)
71                |Sy_bit(1)
72                |Sy_bit(2) // obachman 10/00: replaced by notBucket
73                |Sy_bit(3)
74                |Sy_bit(4)
75                |Sy_bit(5)
76                |Sy_bit(6)
77//                |Sy_bit(7) obachman 11/00 tossed: 12/00 used for redThrough
78                |Sy_bit(7) // OPT_REDTHROUGH
79                |Sy_bit(8) // obachman 11/00 tossed -> motsak 2011 experimental: OPT_NO_SYZ_MINIM
80                |Sy_bit(9)
81                |Sy_bit(10)
82                |Sy_bit(11)
83                |Sy_bit(12)
84                |Sy_bit(13)
85                |Sy_bit(14)
86                |Sy_bit(15)
87                |Sy_bit(16)
88                |Sy_bit(17)
89                |Sy_bit(18)
90                |Sy_bit(19)
91//                |Sy_bit(20) obachman 11/00 tossed: 12/00 used for redOldStd
92                |Sy_bit(OPT_OLDSTD)
93                |Sy_bit(21)
94                |Sy_bit(22)
95                /*|Sy_bit(23)*/
96                /*|Sy_bit(24)*/
97                |Sy_bit(OPT_REDTAIL)
98                |Sy_bit(OPT_INTSTRATEGY)
99                |Sy_bit(27)
100                |Sy_bit(28)
101                |Sy_bit(29)
102                |Sy_bit(30)
103                |Sy_bit(31);
104
105//static BOOLEAN posInLOldFlag;
106           /*FALSE, if posInL == posInL10*/
107// returns TRUE if mora should use buckets, false otherwise
108static BOOLEAN kMoraUseBucket(kStrategy strat);
109
110static void kOptimizeLDeg(pLDegProc ldeg, kStrategy strat)
111{
112//  if (strat->ak == 0 && !rIsSyzIndexRing(currRing))
113    strat->length_pLength = TRUE;
114//  else
115//    strat->length_pLength = FALSE;
116
117  if ((ldeg == pLDeg0c /*&& !rIsSyzIndexRing(currRing)*/) ||
118      (ldeg == pLDeg0 && strat->ak == 0))
119  {
120    strat->LDegLast = TRUE;
121  }
122  else
123  {
124    strat->LDegLast = FALSE;
125  }
126}
127
128
129static int doRed (LObject* h, TObject* with,BOOLEAN intoT,kStrategy strat, bool redMoraNF)
130{
131  int ret;
132#if KDEBUG > 0
133  kTest_L(h);
134  kTest_T(with);
135#endif
136  // Hmmm ... why do we do this -- polys from T should already be normalized
137  if (!TEST_OPT_INTSTRATEGY)
138    with->pNorm();
139#ifdef KDEBUG
140  if (TEST_OPT_DEBUG)
141  {
142    PrintS("reduce ");h->wrp();PrintS(" with ");with->wrp();PrintLn();
143  }
144#endif
145  if (intoT)
146  {
147    // need to do it exacly like this: otherwise
148    // we might get errors
149    LObject L= *h;
150    L.Copy();
151    h->GetP();
152    h->length=h->pLength=pLength(h->p);
153    ret = ksReducePoly(&L, with, strat->kNoetherTail(), NULL, strat);
154    if (ret)
155    {
156      if (ret < 0) return ret;
157      if (h->tailRing != strat->tailRing)
158        h->ShallowCopyDelete(strat->tailRing,
159                             pGetShallowCopyDeleteProc(h->tailRing,
160                                                       strat->tailRing));
161    }
162    if(redMoraNF)
163      enterT_strong(*h,strat);
164    else
165      enterT(*h,strat);
166    *h = L;
167  }
168  else
169    ret = ksReducePoly(h, with, strat->kNoetherTail(), NULL, strat);
170#ifdef KDEBUG
171  if (TEST_OPT_DEBUG)
172  {
173    PrintS("to ");h->wrp();PrintLn();
174  }
175#endif
176  return ret;
177}
178
179int redEcart (LObject* h,kStrategy strat)
180{
181  int i,at,ei,li,ii;
182  int j = 0;
183  int pass = 0;
184  long d,reddeg;
185
186  d = h->GetpFDeg()+ h->ecart;
187  reddeg = strat->LazyDegree+d;
188  h->SetShortExpVector();
189  loop
190  {
191    j = kFindDivisibleByInT(strat, h);
192    if (j < 0)
193    {
194      if (strat->honey) h->SetLength(strat->length_pLength);
195      return 1;
196    }
197
198    ei = strat->T[j].ecart;
199    ii = j;
200
201    if (ei > h->ecart && ii < strat->tl)
202    {
203      li = strat->T[j].length;
204      // the polynomial to reduce with (up to the moment) is;
205      // pi with ecart ei and length li
206      // look for one with smaller ecart
207      i = j;
208      loop
209      {
210        /*- takes the first possible with respect to ecart -*/
211        i++;
212#if 1
213        if (i > strat->tl) break;
214        if ((strat->T[i].ecart < ei || (strat->T[i].ecart == ei &&
215                                        strat->T[i].length < li))
216            &&
217            p_LmShortDivisibleBy(strat->T[i].GetLmTailRing(), strat->sevT[i], h->GetLmTailRing(), ~h->sev, strat->tailRing))
218#else
219          j = kFindDivisibleByInT(strat, h, i);
220        if (j < 0) break;
221        i = j;
222        if (strat->T[i].ecart < ei || (strat->T[i].ecart == ei &&
223                                        strat->T[i].length < li))
224#endif
225        {
226          // the polynomial to reduce with is now
227          ii = i;
228          ei = strat->T[i].ecart;
229          if (ei <= h->ecart) break;
230          li = strat->T[i].length;
231        }
232      }
233    }
234
235    // end of search: have to reduce with pi
236    if (ei > h->ecart)
237    {
238      // It is not possible to reduce h with smaller ecart;
239      // if possible h goes to the lazy-set L,i.e
240      // if its position in L would be not the last one
241      strat->fromT = TRUE;
242      if (!TEST_OPT_REDTHROUGH && strat->Ll >= 0) /*- L is not empty -*/
243      {
244        h->SetLmCurrRing();
245        if (strat->honey && strat->posInLDependsOnLength)
246          h->SetLength(strat->length_pLength);
247        assume(h->FDeg == h->pFDeg());
248        at = strat->posInL(strat->L,strat->Ll,h,strat);
249        if (at <= strat->Ll)
250        {
251          /*- h will not become the next element to reduce -*/
252          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
253#ifdef KDEBUG
254          if (TEST_OPT_DEBUG) Print(" ecart too big; -> L%d\n",at);
255#endif
256          h->Clear();
257          strat->fromT = FALSE;
258          return -1;
259        }
260      }
261    }
262
263    // now we finally can reduce
264    doRed(h,&(strat->T[ii]),strat->fromT,strat,FALSE);
265    strat->fromT=FALSE;
266
267    // are we done ???
268    if (h->IsNull())
269    {
270      assume(!rField_is_Ring(currRing));
271      if (h->lcm!=NULL) pLmFree(h->lcm);
272      h->Clear();
273      return 0;
274    }
275
276    // NO!
277    h->SetShortExpVector();
278    h->SetpFDeg();
279    if (strat->honey)
280    {
281      if (ei <= h->ecart)
282        h->ecart = d-h->GetpFDeg();
283      else
284        h->ecart = d-h->GetpFDeg()+ei-h->ecart;
285    }
286    else
287      // this has the side effect of setting h->length
288      h->ecart = h->pLDeg(strat->LDegLast) - h->GetpFDeg();
289#if 0
290    if (strat->syzComp!=0)
291    {
292      if ((strat->syzComp>0) && (h->Comp() > strat->syzComp))
293      {
294        assume(h->MinComp() > strat->syzComp);
295        if (strat->honey) h->SetLength();
296#ifdef KDEBUG
297        if (TEST_OPT_DEBUG) PrintS(" > syzComp\n");
298#endif
299        return -2;
300      }
301    }
302#endif
303    /*- try to reduce the s-polynomial -*/
304    pass++;
305    d = h->GetpFDeg()+h->ecart;
306    /*
307     *test whether the polynomial should go to the lazyset L
308     *-if the degree jumps
309     *-if the number of pre-defined reductions jumps
310     */
311    if (!TEST_OPT_REDTHROUGH && (strat->Ll >= 0)
312        && ((d >= reddeg) || (pass > strat->LazyPass)))
313    {
314      h->SetLmCurrRing();
315      if (strat->honey && strat->posInLDependsOnLength)
316        h->SetLength(strat->length_pLength);
317      assume(h->FDeg == h->pFDeg());
318      at = strat->posInL(strat->L,strat->Ll,h,strat);
319      if (at <= strat->Ll)
320      {
321        int dummy=strat->sl;
322        if (kFindDivisibleByInS(strat, &dummy, h) < 0)
323        {
324          if (strat->honey && !strat->posInLDependsOnLength)
325            h->SetLength(strat->length_pLength);
326          return 1;
327        }
328        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
329#ifdef KDEBUG
330        if (TEST_OPT_DEBUG) Print(" degree jumped; ->L%d\n",at);
331#endif
332        h->Clear();
333        return -1;
334      }
335    }
336    else if ((TEST_OPT_PROT) && (strat->Ll < 0) && (d >= reddeg))
337    {
338      Print(".%ld",d);mflush();
339      reddeg = d+1;
340      if (h->pTotalDeg()+h->ecart >= (int)strat->tailRing->bitmask)
341      {
342        strat->overflow=TRUE;
343        //Print("OVERFLOW in redEcart d=%ld, max=%ld",d,strat->tailRing->bitmask);
344        h->GetP();
345        at = strat->posInL(strat->L,strat->Ll,h,strat);
346        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
347        h->Clear();
348        return -1;
349      }
350    }
351  }
352}
353
354int redRiloc (LObject* h,kStrategy strat)
355{
356  int i,at,ei,li,ii;
357  int j = 0;
358  int pass = 0;
359  long d,reddeg;
360
361
362#if ADIDEBUG_NF
363  int iii;
364  PrintS("\n---------------------------- NEW REDRILOC COMPUTATION ----------------------------\n");
365  PrintS("    The pair h :\n");
366  PrintS("\n      p1 = "); p_Write(h->p1,strat->tailRing);
367  PrintS("\n      p2 = "); p_Write(h->p2,strat->tailRing);
368  PrintS("\n      p  = "); p_Write(h->p,strat->tailRing);
369  PrintS("\n    The actual reducer T is: ");
370  if(strat->tl<0)
371    {PrintS(" Empty.\n");}
372  else
373  {
374    for (iii=0;iii<=strat->tl;iii++)
375    {
376      Print("\n      T[%i] = ",iii);p_Write(strat->T[iii].p,strat->tailRing);
377    }
378  }
379#endif /* ADIDEBUG_NF */
380
381  d = h->GetpFDeg()+ h->ecart;
382  reddeg = strat->LazyDegree+d;
383  h->SetShortExpVector();
384#if ADIDEBUG_NF
385  Print("\n  Searching for a poly in T that divides h (of ecart %i) ...\n",h->ecart);
386#endif
387  loop
388  {
389    j = kFindDivisibleByInT(strat, h);
390#if ADIDEBUG_NF
391    if(j != -1)
392    {
393      ei = strat->T[j].ecart;
394      Print("\n    Found one: T[%i] of ecart %i: ",j,ei);
395      p_Write(strat->T[j].p,strat->tailRing);
396      PrintS("\n    Try to find another with smaller ecart:\n");
397    }
398    else
399    {
400      PrintS("\n    No poly in T divides h.\n");
401    }
402    //getchar();
403#endif
404    if (j < 0)
405    {
406      // over ZZ: cleanup coefficients by complete reduction with monomials
407      postReduceByMon(h, strat);
408      if(h->p == NULL)
409      {
410        if (h->lcm!=NULL) pLmDelete(h->lcm);
411        h->Clear();
412        return 0;
413      }
414      if (strat->honey) h->SetLength(strat->length_pLength);
415      if(strat->tl >= 0)
416          h->i_r1 = strat->tl;
417      else
418          h->i_r1 = -1;
419      if (h->GetLmTailRing() == NULL)
420      {
421        if (h->lcm!=NULL) pLmDelete(h->lcm);
422        h->Clear();
423        return 0;
424      }
425      return 1;
426    }
427
428    ei = strat->T[j].ecart;
429    ii = j;
430#if ADIDEBUG_NF
431    iii=ii;
432#endif
433    if (ei > h->ecart && ii < strat->tl)
434    {
435      li = strat->T[j].length;
436      // the polynomial to reduce with (up to the moment) is;
437      // pi with ecart ei and length li
438      // look for one with smaller ecart
439      i = j;
440      loop
441      {
442        /*- takes the first possible with respect to ecart -*/
443        i++;
444#if 1
445        if (i > strat->tl) break;
446        if ((strat->T[i].ecart < ei || (strat->T[i].ecart == ei &&
447                                        strat->T[i].length < li))
448            &&
449            p_LmShortDivisibleBy(strat->T[i].GetLmTailRing(), strat->sevT[i], h->GetLmTailRing(), ~h->sev, strat->tailRing)
450            &&
451            n_DivBy(h->p->coef,strat->T[i].p->coef,strat->tailRing))
452#else
453          j = kFindDivisibleByInT(strat, h, i);
454        if (j < 0) break;
455        i = j;
456        if (strat->T[i].ecart < ei || (strat->T[i].ecart == ei &&
457                                        strat->T[i].length < li))
458#endif
459        {
460          // the polynomial to reduce with is now
461          #if ADIDEBUG_NF
462          printf("\n    Intermidiate one, h.ecart = %i < ecart = %i < ei = %i: ",h->ecart,strat->T[i].ecart, ei);
463          pWrite(strat->T[i].p);
464          #endif
465          ii = i;
466          ei = strat->T[i].ecart;
467          if (ei <= h->ecart) break;
468          li = strat->T[i].length;
469        }
470      }
471
472#if ADIDEBUG_NF
473      if(iii == ii)
474      {
475        PrintS("\n    None was found.\n");
476      }
477      else
478      {
479        Print("\n    A better one (ecart = %i): T[%i] = ",ei,ii);
480        p_Write(strat->T[ii].p,strat->tailRing);
481        PrintLn();
482      }
483#endif
484    }
485
486    // end of search: have to reduce with pi
487    if (ei > h->ecart)
488    {
489      #if ADIDEBUG_NF
490      printf("\nHAD TO REDUCE WITH BIGGER ECART!!!\n");
491      #endif
492      // It is not possible to reduce h with smaller ecart;
493      // if possible h goes to the lazy-set L,i.e
494      // if its position in L would be not the last one
495      strat->fromT = TRUE;
496      if (!TEST_OPT_REDTHROUGH && strat->Ll >= 0) /*- L is not empty -*/
497      {
498        h->SetLmCurrRing();
499        if (strat->honey && strat->posInLDependsOnLength)
500          h->SetLength(strat->length_pLength);
501        assume(h->FDeg == h->pFDeg());
502        at = strat->posInL(strat->L,strat->Ll,h,strat);
503        #if 0
504        //#ifdef HAVE_RINGS
505        if(rField_is_Ring(currRing))
506          strat->fromT=FALSE;
507        #endif
508        if (at <= strat->Ll && pLmCmp(h->p, strat->L[strat->Ll].p) != 0 && !nEqual(h->p->coef, strat->L[strat->Ll].p->coef))
509        {
510          /*- h will not become the next element to reduce -*/
511          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
512          #ifdef KDEBUG
513          if (TEST_OPT_DEBUG) Print(" ecart too big; -> L%d\n",at);
514          #endif
515          h->Clear();
516          strat->fromT = FALSE;
517          return -1;
518        }
519      }
520      doRed(h,&(strat->T[ii]),TRUE,strat,TRUE);
521    }
522    else
523    {
524      // now we finally can reduce
525      doRed(h,&(strat->T[ii]),strat->fromT,strat,FALSE);
526    }
527    strat->fromT=FALSE;
528    // are we done ???
529    if (h->IsNull())
530    {
531      #if ADIDEBUG_NF
532      printf("\nReduced to 0. Exit\n");
533      #endif
534      if (h->lcm!=NULL) pLmDelete(h->lcm);
535      h->Clear();
536      return 0;
537    }
538
539    // NO!
540    h->SetShortExpVector();
541    h->SetpFDeg();
542    if (strat->honey)
543    {
544      if (ei <= h->ecart)
545        h->ecart = d-h->GetpFDeg();
546      else
547        h->ecart = d-h->GetpFDeg()+ei-h->ecart;
548    }
549    else
550      // this has the side effect of setting h->length
551      h->ecart = h->pLDeg(strat->LDegLast) - h->GetpFDeg();
552    #if ADIDEBUG_NF
553    printf("\n  Partial Reduced (ecart %i) h = ",h->ecart);p_Write(h->p,strat->tailRing);
554    PrintLn();
555    #endif
556    /*- try to reduce the s-polynomial -*/
557    pass++;
558    d = h->GetpFDeg()+h->ecart;
559    /*
560     *test whether the polynomial should go to the lazyset L
561     *-if the degree jumps
562     *-if the number of pre-defined reductions jumps
563     */
564    if (!TEST_OPT_REDTHROUGH && (strat->Ll >= 0)
565        && ((d >= reddeg) || (pass > strat->LazyPass)))
566    {
567      h->SetLmCurrRing();
568      if (strat->honey && strat->posInLDependsOnLength)
569        h->SetLength(strat->length_pLength);
570      assume(h->FDeg == h->pFDeg());
571      at = strat->posInL(strat->L,strat->Ll,h,strat);
572      if (at <= strat->Ll)
573      {
574        int dummy=strat->sl;
575        if (kFindDivisibleByInS(strat, &dummy, h) < 0)
576        {
577          if (strat->honey && !strat->posInLDependsOnLength)
578            h->SetLength(strat->length_pLength);
579          return 1;
580        }
581        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
582#ifdef KDEBUG
583        if (TEST_OPT_DEBUG) Print(" degree jumped; ->L%d\n",at);
584#endif
585        h->Clear();
586        return -1;
587      }
588    }
589    else if ((TEST_OPT_PROT) && (strat->Ll < 0) && (d >= reddeg))
590    {
591      Print(".%ld",d);mflush();
592      reddeg = d+1;
593      if (h->pTotalDeg()+h->ecart >= (int)strat->tailRing->bitmask)
594      {
595        strat->overflow=TRUE;
596        //Print("OVERFLOW in redEcart d=%ld, max=%ld",d,strat->tailRing->bitmask);
597        h->GetP();
598        at = strat->posInL(strat->L,strat->Ll,h,strat);
599        enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
600        h->Clear();
601        return -1;
602      }
603    }
604  }
605}
606
607/*2
608*reduces h with elements from T choosing  the first possible
609* element in t with respect to the given pDivisibleBy
610*/
611int redFirst (LObject* h,kStrategy strat)
612{
613  if (h->IsNull()) return 0;
614
615  int at;
616  long reddeg,d;
617  int pass = 0;
618  int j = 0;
619
620  if (! strat->homog)
621  {
622    d = h->GetpFDeg() + h->ecart;
623    reddeg = strat->LazyDegree+d;
624  }
625  h->SetShortExpVector();
626  loop
627  {
628    j = kFindDivisibleByInT(strat, h);
629    if (j < 0)
630    {
631      h->SetDegStuffReturnLDeg(strat->LDegLast);
632      return 1;
633    }
634
635    if (!TEST_OPT_INTSTRATEGY)
636      strat->T[j].pNorm();
637#ifdef KDEBUG
638    if (TEST_OPT_DEBUG)
639    {
640      PrintS("reduce ");
641      h->wrp();
642      PrintS(" with ");
643      strat->T[j].wrp();
644    }
645#endif
646    ksReducePoly(h, &(strat->T[j]), strat->kNoetherTail(), NULL, strat);
647#ifdef KDEBUG
648    if (TEST_OPT_DEBUG)
649    {
650      PrintS(" to ");
651      wrp(h->p);
652      PrintLn();
653    }
654#endif
655    if (h->IsNull())
656    {
657      assume(!rField_is_Ring(currRing));
658      if (h->lcm!=NULL) pLmFree(h->lcm);
659      h->Clear();
660      return 0;
661    }
662    h->SetShortExpVector();
663
664#if 0
665    if ((strat->syzComp!=0) && !strat->honey)
666    {
667      if ((strat->syzComp>0) &&
668          (h->Comp() > strat->syzComp))
669      {
670        assume(h->MinComp() > strat->syzComp);
671#ifdef KDEBUG
672        if (TEST_OPT_DEBUG) PrintS(" > syzComp\n");
673#endif
674        if (strat->homog)
675          h->SetDegStuffReturnLDeg(strat->LDegLast);
676        return -2;
677      }
678    }
679#endif
680    if (!strat->homog)
681    {
682      if (!TEST_OPT_OLDSTD && strat->honey)
683      {
684        h->SetpFDeg();
685        if (strat->T[j].ecart <= h->ecart)
686          h->ecart = d - h->GetpFDeg();
687        else
688          h->ecart = d - h->GetpFDeg() + strat->T[j].ecart - h->ecart;
689
690        d = h->GetpFDeg() + h->ecart;
691      }
692      else
693        d = h->SetDegStuffReturnLDeg(strat->LDegLast);
694      /*- try to reduce the s-polynomial -*/
695      pass++;
696      /*
697       *test whether the polynomial should go to the lazyset L
698       *-if the degree jumps
699       *-if the number of pre-defined reductions jumps
700       */
701      if (!TEST_OPT_REDTHROUGH && (strat->Ll >= 0)
702          && ((d >= reddeg) || (pass > strat->LazyPass)))
703      {
704        h->SetLmCurrRing();
705        if (strat->posInLDependsOnLength)
706          h->SetLength(strat->length_pLength);
707        at = strat->posInL(strat->L,strat->Ll,h,strat);
708        if (at <= strat->Ll)
709        {
710          int dummy=strat->sl;
711          if (kFindDivisibleByInS(strat,&dummy, h) < 0)
712            return 1;
713          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
714#ifdef KDEBUG
715          if (TEST_OPT_DEBUG) Print(" degree jumped; ->L%d\n",at);
716#endif
717          h->Clear();
718          return -1;
719        }
720      }
721      if ((TEST_OPT_PROT) && (strat->Ll < 0) && (d >= reddeg))
722      {
723        reddeg = d+1;
724        Print(".%ld",d);mflush();
725        if (h->pTotalDeg()+h->ecart >= (int)strat->tailRing->bitmask)
726        {
727          strat->overflow=TRUE;
728          //Print("OVERFLOW in redFirst d=%ld, max=%ld",d,strat->tailRing->bitmask);
729          h->GetP();
730          at = strat->posInL(strat->L,strat->Ll,h,strat);
731          enterL(&strat->L,&strat->Ll,&strat->Lmax,*h,at);
732          h->Clear();
733          return -1;
734        }
735      }
736    }
737  }
738}
739
740/*2
741* reduces h with elements from T choosing first possible
742* element in T with respect to the given ecart
743* used for computing normal forms outside kStd
744*/
745static poly redMoraNF (poly h,kStrategy strat, int flag)
746{
747  LObject H;
748  H.p = h;
749  int j = 0;
750  int z = 10;
751  int o = H.SetpFDeg();
752  H.ecart = currRing->pLDeg(H.p,&H.length,currRing)-o;
753  if ((flag & 2) == 0) cancelunit(&H,TRUE);
754  H.sev = pGetShortExpVector(H.p);
755  unsigned long not_sev = ~ H.sev;
756  loop
757  {
758    #if ADIDEBUG_NF
759    for(int ii=0;ii<=strat->tl;ii++)
760    {
761      printf("\nT[%i]:\nt^%i ",ii,strat->T[ii].ecart);
762      pWrite(strat->T[ii].p);
763    }
764    //getchar();
765    #endif
766    if (j > strat->tl)
767    {
768      return H.p;
769    }
770    if (TEST_V_DEG_STOP)
771    {
772      if (kModDeg(H.p)>Kstd1_deg) pLmDelete(&H.p);
773      if (H.p==NULL) return NULL;
774    }
775    #if ADIDEBUG_NF
776    printf("\nSearching for a reducer...\n");
777    #endif
778    if (p_LmShortDivisibleBy(strat->T[j].GetLmTailRing(), strat->sevT[j], H.GetLmTailRing(), not_sev, strat->tailRing)
779        #ifdef HAVE_RINGS
780        && (!rField_is_Ring(strat->tailRing) ||
781            n_DivBy(H.p->coef, strat->T[j].p->coef,strat->tailRing))
782        #endif
783        )
784    {
785      /*- remember the found T-poly -*/
786      // poly pi = strat->T[j].p;
787      int ei = strat->T[j].ecart;
788      int li = strat->T[j].length;
789      int ii = j;
790      #if ADIDEBUG_NF
791      printf("\nFound: j = %i, ecart = %i\nTrying to find a better one...\n",j,ei);pWrite(strat->T[j].p);
792      #endif
793      /*
794      * the polynomial to reduce with (up to the moment) is;
795      * pi with ecart ei and length li
796      */
797      loop
798      {
799        /*- look for a better one with respect to ecart -*/
800        /*- stop, if the ecart is small enough (<=ecart(H)) -*/
801        j++;
802        if (j > strat->tl) break;
803        if (ei <= H.ecart) break;
804        if (((strat->T[j].ecart < ei)
805          || ((strat->T[j].ecart == ei)
806        && (strat->T[j].length < li)))
807        && pLmShortDivisibleBy(strat->T[j].p,strat->sevT[j], H.p, not_sev)
808        #ifdef HAVE_RINGS
809        && (!rField_is_Ring(strat->tailRing) ||
810            n_DivBy(H.p->coef, strat->T[j].p->coef,strat->tailRing))
811        #endif
812        )
813        {
814          /*
815          * the polynomial to reduce with is now;
816          */
817          // pi = strat->T[j].p;
818          ei = strat->T[j].ecart;
819          li = strat->T[j].length;
820          ii = j;
821          #if ADIDEBUG_NF
822          printf("\nFound a better one: j = %i, ecart = %i\nTrying to find a better one...\n",j,ei);
823          pWrite(strat->T[j].p);
824          #endif
825        }
826      }
827      /*
828      * end of search: have to reduce with pi
829      */
830      z++;
831      if (z>10)
832      {
833        pNormalize(H.p);
834        z=0;
835      }
836      if ((ei > H.ecart) && (!strat->kHEdgeFound))
837      {
838        /*
839        * It is not possible to reduce h with smaller ecart;
840        * we have to reduce with bad ecart: H has to enter in T
841        */
842        #if ADIDEBUG_NF
843        printf("\nHAVE TO REDUCE IT WITH BIGGER ECART\n");
844        #endif
845        doRed(&H,&(strat->T[ii]),TRUE,strat,TRUE);
846        if (H.p == NULL)
847          return NULL;
848        #if 0
849        //kÃŒrzeste=1, kleinste ecart = 0
850        int dummy=0;
851        int z=-1;
852        for(int ii=0; ii<=strat->tl;ii++)
853        {
854          if(pLmIsConstant(strat->T[ii].p))
855          {
856            printf("\nFound one:\n");pWrite(strat->T[ii].p);
857            if(dummy==0 && strat->T[ii].ecart < strat->T[z].ecart)
858            {
859              z = ii;
860            }
861            if(dummy == 1 && strat->T[ii].length < strat->T[z].length)
862            {
863              z = ii;
864            }
865          }
866        }
867        printf("\n!!!!!!!!!!!!!!!!!   z = %i\n",z);
868        if(z!=-1)
869        {
870          enterOneStrongPoly(z,H.p,H.ecart,0,strat,-1 , TRUE);
871        }
872        #endif
873      }
874      else
875      {
876        /*
877        * we reduce with good ecart, h need not to be put to T
878        */
879        doRed(&H,&(strat->T[ii]),FALSE,strat,TRUE);
880        if (H.p == NULL)
881          return NULL;
882      }
883      #if ADIDEBUG_NF
884      printf("\nAfter the small reduction it looks like this:\n");pWrite(H.p);
885      getchar();
886      #endif
887      /*- try to reduce the s-polynomial -*/
888      o = H.SetpFDeg();
889      if ((flag &2 ) == 0) cancelunit(&H,TRUE);
890      H.ecart = currRing->pLDeg(H.p,&(H.length),currRing)-o;
891      j = 0;
892      H.sev = pGetShortExpVector(H.p);
893      not_sev = ~ H.sev;
894    }
895    else
896    {
897      j++;
898    }
899  }
900}
901
902/*2
903*reorders  L with respect to posInL
904*/
905void reorderL(kStrategy strat)
906{
907  int i,j,at;
908  LObject p;
909
910  for (i=1; i<=strat->Ll; i++)
911  {
912    at = strat->posInL(strat->L,i-1,&(strat->L[i]),strat);
913    if (at != i)
914    {
915      p = strat->L[i];
916      for (j=i-1; j>=at; j--) strat->L[j+1] = strat->L[j];
917      strat->L[at] = p;
918    }
919  }
920}
921
922/*2
923*reorders  T with respect to length
924*/
925void reorderT(kStrategy strat)
926{
927  int i,j,at;
928  TObject p;
929  unsigned long sev;
930
931
932  for (i=1; i<=strat->tl; i++)
933  {
934    if (strat->T[i-1].length > strat->T[i].length)
935    {
936      p = strat->T[i];
937      sev = strat->sevT[i];
938      at = i-1;
939      loop
940      {
941        at--;
942        if (at < 0) break;
943        if (strat->T[i].length > strat->T[at].length) break;
944      }
945      for (j = i-1; j>at; j--)
946      {
947        strat->T[j+1]=strat->T[j];
948        strat->sevT[j+1]=strat->sevT[j];
949        strat->R[strat->T[j+1].i_r] = &(strat->T[j+1]);
950      }
951      strat->T[at+1]=p;
952      strat->sevT[at+1] = sev;
953      strat->R[p.i_r] = &(strat->T[at+1]);
954    }
955  }
956}
957
958/*2
959*looks whether exactly (currRing->N)-1 axis are used
960*returns last != 0 in this case
961*last is the (first) unused axis
962*/
963void missingAxis (int* last,kStrategy strat)
964{
965  int   i = 0;
966  int   k = 0;
967
968  *last = 0;
969  if (!currRing->MixedOrder)
970  {
971    loop
972    {
973      i++;
974      if (i > (currRing->N)) break;
975      if (strat->NotUsedAxis[i])
976      {
977        *last = i;
978        k++;
979      }
980      if (k>1)
981      {
982        *last = 0;
983        break;
984      }
985    }
986  }
987}
988
989/*2
990*last is the only non used axis, it looks
991*for a monomial in p being a pure power of this
992*variable and returns TRUE in this case
993*(*length) gives the length between the pure power and the leading term
994*(should be minimal)
995*/
996BOOLEAN hasPurePower (const poly p,int last, int *length,kStrategy strat)
997{
998  poly h;
999  int i;
1000
1001  if (pNext(p) == strat->tail)
1002    return FALSE;
1003  pp_Test(p, currRing, strat->tailRing);
1004  if (strat->ak <= 0 || p_MinComp(p, currRing, strat->tailRing) == strat->ak)
1005  {
1006    i = p_IsPurePower(p, currRing);
1007    if (i == last)
1008    {
1009      *length = 0;
1010      return TRUE;
1011    }
1012    *length = 1;
1013    h = pNext(p);
1014    while (h != NULL)
1015    {
1016      i = p_IsPurePower(h, strat->tailRing);
1017      if (i==last) return TRUE;
1018      (*length)++;
1019      pIter(h);
1020    }
1021  }
1022  return FALSE;
1023}
1024
1025BOOLEAN hasPurePower (LObject *L,int last, int *length,kStrategy strat)
1026{
1027  if (L->bucket != NULL)
1028  {
1029    poly p = L->CanonicalizeP();
1030    BOOLEAN ret = hasPurePower(p, last, length, strat);
1031    pNext(p) = NULL;
1032    return ret;
1033  }
1034  else
1035  {
1036    return hasPurePower(L->p, last, length, strat);
1037  }
1038}
1039
1040/*2
1041* looks up the position of polynomial p in L
1042* in the case of looking for the pure powers
1043*/
1044int posInL10 (const LSet set,const int length, LObject* p,const kStrategy strat)
1045{
1046  int j,dp,dL;
1047
1048  if (length<0) return 0;
1049  if (hasPurePower(p,strat->lastAxis,&dp,strat))
1050  {
1051    int op= p->GetpFDeg() +p->ecart;
1052    for (j=length; j>=0; j--)
1053    {
1054      if (!hasPurePower(&(set[j]),strat->lastAxis,&dL,strat))
1055        return j+1;
1056      if (dp < dL)
1057        return j+1;
1058      if ((dp == dL)
1059          && (set[j].GetpFDeg()+set[j].ecart >= op))
1060        return j+1;
1061    }
1062  }
1063  j=length;
1064  loop
1065  {
1066    if (j<0) break;
1067    if (!hasPurePower(&(set[j]),strat->lastAxis,&dL,strat)) break;
1068    j--;
1069  }
1070  return strat->posInLOld(set,j,p,strat);
1071}
1072
1073
1074/*2
1075* computes the s-polynomials L[ ].p in L
1076*/
1077void updateL(kStrategy strat)
1078{
1079  LObject p;
1080  int dL;
1081  int j=strat->Ll;
1082  loop
1083  {
1084    if (j<0) break;
1085    if (hasPurePower(&(strat->L[j]),strat->lastAxis,&dL,strat))
1086    {
1087      p=strat->L[strat->Ll];
1088      strat->L[strat->Ll]=strat->L[j];
1089      strat->L[j]=p;
1090      break;
1091    }
1092    j--;
1093  }
1094  if (j<0)
1095  {
1096    j=strat->Ll;
1097    loop
1098    {
1099      if (j<0) break;
1100      if (pNext(strat->L[j].p) == strat->tail)
1101      {
1102#ifdef HAVE_RINGS
1103        if (rField_is_Ring(currRing))
1104          pLmDelete(strat->L[j].p);    /*deletes the short spoly and computes*/
1105        else
1106#else
1107          pLmFree(strat->L[j].p);    /*deletes the short spoly and computes*/
1108#endif
1109        strat->L[j].p = NULL;
1110        poly m1 = NULL, m2 = NULL;
1111        // check that spoly creation is ok
1112        while (strat->tailRing != currRing &&
1113               !kCheckSpolyCreation(&(strat->L[j]), strat, m1, m2))
1114        {
1115          assume(m1 == NULL && m2 == NULL);
1116          // if not, change to a ring where exponents are at least
1117          // large enough
1118          kStratChangeTailRing(strat);
1119        }
1120        /* create the real one */
1121        ksCreateSpoly(&(strat->L[j]), strat->kNoetherTail(), FALSE,
1122                      strat->tailRing, m1, m2, strat->R);
1123
1124        strat->L[j].SetLmCurrRing();
1125        if (!strat->honey)
1126          strat->initEcart(&strat->L[j]);
1127        else
1128          strat->L[j].SetLength(strat->length_pLength);
1129
1130        BOOLEAN pp = hasPurePower(&(strat->L[j]),strat->lastAxis,&dL,strat);
1131
1132        if (strat->use_buckets) strat->L[j].PrepareRed(TRUE);
1133
1134        if (pp)
1135        {
1136          p=strat->L[strat->Ll];
1137          strat->L[strat->Ll]=strat->L[j];
1138          strat->L[j]=p;
1139          break;
1140        }
1141      }
1142      j--;
1143    }
1144  }
1145}
1146
1147/*2
1148* computes the s-polynomials L[ ].p in L and
1149* cuts elements in L above noether
1150*/
1151void updateLHC(kStrategy strat)
1152{
1153
1154  int i = 0;
1155  kTest_TS(strat);
1156  while (i <= strat->Ll)
1157  {
1158    if (pNext(strat->L[i].p) == strat->tail)
1159    {
1160       /*- deletes the int spoly and computes -*/
1161      if (pLmCmp(strat->L[i].p,strat->kNoether) == -1)
1162      {
1163        #ifdef HAVE_RINGS
1164        if (rField_is_Ring(currRing))
1165          pLmDelete(strat->L[i].p);
1166        else
1167        #endif
1168          pLmFree(strat->L[i].p);
1169        strat->L[i].p = NULL;
1170      }
1171      else
1172      {
1173        #ifdef HAVE_RINGS
1174        if (rField_is_Ring(currRing))
1175          pLmDelete(strat->L[i].p);
1176        else
1177        #endif
1178          pLmFree(strat->L[i].p);
1179        strat->L[i].p = NULL;
1180        poly m1 = NULL, m2 = NULL;
1181        // check that spoly creation is ok
1182        while (strat->tailRing != currRing &&
1183               !kCheckSpolyCreation(&(strat->L[i]), strat, m1, m2))
1184        {
1185          assume(m1 == NULL && m2 == NULL);
1186          // if not, change to a ring where exponents are at least
1187          // large enough
1188          kStratChangeTailRing(strat);
1189        }
1190        /* create the real one */
1191        ksCreateSpoly(&(strat->L[i]), strat->kNoetherTail(), FALSE,
1192                      strat->tailRing, m1, m2, strat->R);
1193        if (! strat->L[i].IsNull())
1194        {
1195          strat->L[i].SetLmCurrRing();
1196          strat->L[i].SetpFDeg();
1197          strat->L[i].ecart
1198            = strat->L[i].pLDeg(strat->LDegLast) - strat->L[i].GetpFDeg();
1199          if (strat->use_buckets) strat->L[i].PrepareRed(TRUE);
1200        }
1201      }
1202    }
1203    else
1204      deleteHC(&(strat->L[i]), strat);
1205   if (strat->L[i].IsNull())
1206      deleteInL(strat->L,&strat->Ll,i,strat);
1207    else
1208    {
1209#ifdef KDEBUG
1210      kTest_L(&(strat->L[i]), strat->tailRing, TRUE, i, strat->T, strat->tl);
1211#endif
1212      i++;
1213    }
1214  }
1215  kTest_TS(strat);
1216}
1217
1218/*2
1219* cuts in T above strat->kNoether and tries to cancel a unit
1220*/
1221void updateT(kStrategy strat)
1222{
1223  int i = 0;
1224  LObject p;
1225
1226  while (i <= strat->tl)
1227  {
1228    p = strat->T[i];
1229    deleteHC(&p,strat, TRUE);
1230    /*- tries to cancel a unit: -*/
1231    cancelunit(&p);
1232    if (p.p != strat->T[i].p)
1233    {
1234      strat->sevT[i] = pGetShortExpVector(p.p);
1235      p.SetpFDeg();
1236    }
1237    strat->T[i] = p;
1238    i++;
1239  }
1240}
1241
1242/*2
1243* arranges red, pos and T if strat->kHEdgeFound (first time)
1244*/
1245void firstUpdate(kStrategy strat)
1246{
1247  if (strat->update)
1248  {
1249    kTest_TS(strat);
1250    strat->update = (strat->tl == -1);
1251    if (TEST_OPT_WEIGHTM)
1252    {
1253      pRestoreDegProcs(currRing,strat->pOrigFDeg, strat->pOrigLDeg);
1254      if (strat->tailRing != currRing)
1255      {
1256        strat->tailRing->pFDeg = strat->pOrigFDeg_TailRing;
1257        strat->tailRing->pLDeg = strat->pOrigLDeg_TailRing;
1258      }
1259      int i;
1260      for (i=strat->Ll; i>=0; i--)
1261      {
1262        strat->L[i].SetpFDeg();
1263      }
1264      for (i=strat->tl; i>=0; i--)
1265      {
1266        strat->T[i].SetpFDeg();
1267      }
1268      if (ecartWeights)
1269      {
1270        omFreeSize((ADDRESS)ecartWeights,(rVar(currRing)+1)*sizeof(short));
1271        ecartWeights=NULL;
1272      }
1273    }
1274    if (TEST_OPT_FASTHC)
1275    {
1276      strat->posInL = strat->posInLOld;
1277      strat->lastAxis = 0;
1278    }
1279    if (TEST_OPT_FINDET)
1280      return;
1281
1282#ifndef HAVE_RINGS
1283    strat->red = redFirst;
1284    strat->use_buckets = kMoraUseBucket(strat);
1285#else
1286    if ( (!rField_is_Ring(currRing)) || (rHasGlobalOrdering(currRing)))
1287    {
1288      strat->red = redFirst;
1289      strat->use_buckets = kMoraUseBucket(strat);
1290    }
1291#endif
1292    updateT(strat);
1293
1294#ifndef HAVE_RINGS
1295    strat->posInT = posInT2;
1296    reorderT(strat);
1297#else
1298    if ( (!rField_is_Ring(currRing)) || (rHasGlobalOrdering(currRing)))
1299    {
1300      strat->posInT = posInT2;
1301      reorderT(strat);
1302    }
1303#endif
1304  }
1305  kTest_TS(strat);
1306}
1307
1308/*2
1309*-puts p to the standardbasis s at position at
1310*-reduces the tail of p if TEST_OPT_REDTAIL
1311*-tries to cancel a unit
1312*-HEckeTest
1313*  if TRUE
1314*  - decides about reduction-strategies
1315*  - computes noether
1316*  - stops computation if TEST_OPT_FINDET
1317*  - cuts the tails of the polynomials
1318*    in s,t and the elements in L above noether
1319*    and cancels units if possible
1320*  - reorders s,L
1321*/
1322void enterSMora (LObject &p,int atS,kStrategy strat, int atR = -1)
1323{
1324  enterSBba(p, atS, strat, atR);
1325  #ifdef KDEBUG
1326  if (TEST_OPT_DEBUG)
1327  {
1328    Print("new s%d:",atS);
1329    p_wrp(p.p,currRing,strat->tailRing);
1330    PrintLn();
1331  }
1332  #endif
1333  if ((!strat->kHEdgeFound) || (strat->kNoether!=NULL)) HEckeTest(p.p,strat);
1334  if (strat->kHEdgeFound)
1335  {
1336    if (newHEdge(strat))
1337    {
1338      firstUpdate(strat);
1339      if (TEST_OPT_FINDET)
1340        return;
1341
1342      /*- cuts elements in L above noether and reorders L -*/
1343      updateLHC(strat);
1344      /*- reorders L with respect to posInL -*/
1345      reorderL(strat);
1346    }
1347  }
1348  else if (strat->kNoether!=NULL)
1349    strat->kHEdgeFound = TRUE;
1350  else if (TEST_OPT_FASTHC)
1351  {
1352    if (strat->posInLOldFlag)
1353    {
1354      missingAxis(&strat->lastAxis,strat);
1355      if (strat->lastAxis)
1356      {
1357        strat->posInLOld = strat->posInL;
1358        strat->posInLOldFlag = FALSE;
1359        strat->posInL = posInL10;
1360        strat->posInLDependsOnLength = TRUE;
1361        updateL(strat);
1362        reorderL(strat);
1363      }
1364    }
1365    else if (strat->lastAxis)
1366      updateL(strat);
1367  }
1368}
1369
1370/*2
1371*-puts p to the standardbasis s at position at
1372*-HEckeTest
1373*  if TRUE
1374*  - computes noether
1375*/
1376void enterSMoraNF (LObject &p, int atS,kStrategy strat, int atR = -1)
1377{
1378  enterSBba(p, atS, strat, atR);
1379  if ((!strat->kHEdgeFound) || (strat->kNoether!=NULL)) HEckeTest(p.p,strat);
1380  if (strat->kHEdgeFound)
1381    newHEdge(strat);
1382  else if (strat->kNoether!=NULL)
1383    strat->kHEdgeFound = TRUE;
1384}
1385
1386void initBba(ideal /*F*/,kStrategy strat)
1387{
1388 /* setting global variables ------------------- */
1389  strat->enterS = enterSBba;
1390    strat->red = redHoney;
1391  if (strat->honey)
1392    strat->red = redHoney;
1393  else if (currRing->pLexOrder && !strat->homog)
1394    strat->red = redLazy;
1395  else
1396  {
1397    strat->LazyPass *=4;
1398    strat->red = redHomog;
1399  }
1400#ifdef HAVE_RINGS  //TODO Oliver
1401  if (rField_is_Ring(currRing))
1402  {
1403    strat->red = redRing;
1404  }
1405#endif
1406  if (currRing->pLexOrder && strat->honey)
1407    strat->initEcart = initEcartNormal;
1408  else
1409    strat->initEcart = initEcartBBA;
1410  if (strat->honey)
1411    strat->initEcartPair = initEcartPairMora;
1412  else
1413    strat->initEcartPair = initEcartPairBba;
1414//  if ((TEST_OPT_WEIGHTM)&&(F!=NULL))
1415//  {
1416//    //interred  machen   Aenderung
1417//    strat->pOrigFDeg=pFDeg;
1418//    strat->pOrigLDeg=pLDeg;
1419//    //h=ggetid("ecart");
1420//    //if ((h!=NULL) /*&& (IDTYP(h)==INTVEC_CMD)*/)
1421//    //{
1422//    //  ecartWeights=iv2array(IDINTVEC(h));
1423//    //}
1424//    //else
1425//    {
1426//      ecartWeights=(short *)omAlloc(((currRing->N)+1)*sizeof(short));
1427//      /*uses automatic computation of the ecartWeights to set them*/
1428//      kEcartWeights(F->m,IDELEMS(F)-1,ecartWeights);
1429//    }
1430//    pRestoreDegProcs(currRing,totaldegreeWecart, maxdegreeWecart);
1431//    if (TEST_OPT_PROT)
1432//    {
1433//      for(i=1; i<=(currRing->N); i++)
1434//        Print(" %d",ecartWeights[i]);
1435//      PrintLn();
1436//      mflush();
1437//    }
1438//  }
1439}
1440
1441void initSba(ideal F,kStrategy strat)
1442{
1443  int i;
1444  //idhdl h;
1445 /* setting global variables ------------------- */
1446  strat->enterS = enterSSba;
1447    strat->red2 = redHoney;
1448  if (strat->honey)
1449    strat->red2 = redHoney;
1450  else if (currRing->pLexOrder && !strat->homog)
1451    strat->red2 = redLazy;
1452  else
1453  {
1454    strat->LazyPass *=4;
1455    strat->red2 = redHomog;
1456  }
1457#if defined(HAVE_RINGS)
1458  if (rField_is_Ring(currRing))
1459  {
1460    if(rHasLocalOrMixedOrdering(currRing))
1461      {strat->red = redRiloc;}
1462    else
1463      {strat->red2 = redRing;}
1464  }
1465#endif
1466  if (currRing->pLexOrder && strat->honey)
1467    strat->initEcart = initEcartNormal;
1468  else
1469    strat->initEcart = initEcartBBA;
1470  if (strat->honey)
1471    strat->initEcartPair = initEcartPairMora;
1472  else
1473    strat->initEcartPair = initEcartPairBba;
1474  //strat->kIdeal = NULL;
1475  //if (strat->ak==0) strat->kIdeal->rtyp=IDEAL_CMD;
1476  //else              strat->kIdeal->rtyp=MODUL_CMD;
1477  //strat->kIdeal->data=(void *)strat->Shdl;
1478  if ((TEST_OPT_WEIGHTM)&&(F!=NULL))
1479  {
1480    //interred  machen   Aenderung
1481    strat->pOrigFDeg  = currRing->pFDeg;
1482    strat->pOrigLDeg  = currRing->pLDeg;
1483    //h=ggetid("ecart");
1484    //if ((h!=NULL) /*&& (IDTYP(h)==INTVEC_CMD)*/)
1485    //{
1486    //  ecartWeights=iv2array(IDINTVEC(h));
1487    //}
1488    //else
1489    {
1490      ecartWeights=(short *)omAlloc(((currRing->N)+1)*sizeof(short));
1491      /*uses automatic computation of the ecartWeights to set them*/
1492      kEcartWeights(F->m,IDELEMS(F)-1,ecartWeights, currRing);
1493    }
1494    pRestoreDegProcs(currRing, totaldegreeWecart, maxdegreeWecart);
1495    if (TEST_OPT_PROT)
1496    {
1497      for(i=1; i<=(currRing->N); i++)
1498        Print(" %d",ecartWeights[i]);
1499      PrintLn();
1500      mflush();
1501    }
1502  }
1503  // for sig-safe reductions in signature-based
1504  // standard basis computations
1505  strat->red          = redSig;
1506  //strat->sbaOrder  = 1;
1507  strat->currIdx      = 1;
1508}
1509
1510void initMora(ideal F,kStrategy strat)
1511{
1512  int i,j;
1513
1514  strat->NotUsedAxis = (BOOLEAN *)omAlloc(((currRing->N)+1)*sizeof(BOOLEAN));
1515  for (j=(currRing->N); j>0; j--) strat->NotUsedAxis[j] = TRUE;
1516  strat->enterS = enterSMora;
1517  strat->initEcartPair = initEcartPairMora; /*- ecart approximation -*/
1518  strat->posInLOld = strat->posInL;
1519  strat->posInLOldFlag = TRUE;
1520  strat->initEcart = initEcartNormal;
1521  strat->kHEdgeFound = (currRing->ppNoether) != NULL;
1522  if ( strat->kHEdgeFound )
1523     strat->kNoether = pCopy((currRing->ppNoether));
1524  else if (strat->kHEdgeFound || strat->homog)
1525    strat->red = redFirst;  /*take the first possible in T*/
1526  else
1527    strat->red = redEcart;/*take the first possible in under ecart-restriction*/
1528  if (strat->kHEdgeFound)
1529  {
1530    strat->HCord = currRing->pFDeg((currRing->ppNoether),currRing)+1;
1531    strat->posInT = posInT2;
1532  }
1533  else
1534  {
1535    strat->HCord = 32000;/*- very large -*/
1536  }
1537
1538#ifdef HAVE_RINGS
1539  if (rField_is_Ring(currRing))
1540    strat->red = redRiloc;
1541#endif
1542
1543  /*reads the ecartWeights used for Graebes method from the
1544   *intvec ecart and set ecartWeights
1545   */
1546  if ((TEST_OPT_WEIGHTM)&&(F!=NULL))
1547  {
1548    //interred  machen   Aenderung
1549    strat->pOrigFDeg=currRing->pFDeg;
1550    strat->pOrigLDeg=currRing->pLDeg;
1551    ecartWeights=(short *)omAlloc(((currRing->N)+1)*sizeof(short));
1552    /*uses automatic computation of the ecartWeights to set them*/
1553    kEcartWeights(F->m,IDELEMS(F)-1,ecartWeights,currRing);
1554
1555    pSetDegProcs(currRing,totaldegreeWecart, maxdegreeWecart);
1556    if (TEST_OPT_PROT)
1557    {
1558      for(i=1; i<=(currRing->N); i++)
1559        Print(" %d",ecartWeights[i]);
1560      PrintLn();
1561      mflush();
1562    }
1563  }
1564  kOptimizeLDeg(currRing->pLDeg, strat);
1565}
1566
1567void kDebugPrint(kStrategy strat);
1568
1569ideal mora (ideal F, ideal Q,intvec *w,intvec *hilb,kStrategy strat)
1570{
1571#ifdef HAVE_RINGS
1572#if ADIDEBUG
1573int loop_count;
1574loop_count = 1;
1575#endif
1576#endif
1577  int olddeg = 0;
1578  int reduc = 0;
1579  int red_result = 1;
1580  int hilbeledeg=1,hilbcount=0;
1581  BITSET save1;
1582  SI_SAVE_OPT1(save1);
1583  if (currRing->MixedOrder)
1584  {
1585    si_opt_1 &= ~Sy_bit(OPT_REDSB);
1586    si_opt_1 &= ~Sy_bit(OPT_REDTAIL);
1587  }
1588
1589  strat->update = TRUE;
1590  /*- setting global variables ------------------- -*/
1591  initBuchMoraCrit(strat);
1592  initHilbCrit(F,Q,&hilb,strat);
1593  initMora(F,strat);
1594  initBuchMoraPos(strat);
1595  /*Shdl=*/initBuchMora(F,Q,strat);
1596  if (TEST_OPT_FASTHC) missingAxis(&strat->lastAxis,strat);
1597  /*updateS in initBuchMora has Hecketest
1598  * and could have put strat->kHEdgdeFound FALSE*/
1599  if ((currRing->ppNoether)!=NULL)
1600  {
1601    strat->kHEdgeFound = TRUE;
1602  }
1603  if (strat->kHEdgeFound && strat->update)
1604  {
1605    firstUpdate(strat);
1606    updateLHC(strat);
1607    reorderL(strat);
1608  }
1609  if (TEST_OPT_FASTHC && (strat->lastAxis) && strat->posInLOldFlag)
1610  {
1611    strat->posInLOld = strat->posInL;
1612    strat->posInLOldFlag = FALSE;
1613    strat->posInL = posInL10;
1614    updateL(strat);
1615    reorderL(strat);
1616  }
1617  kTest_TS(strat);
1618  strat->use_buckets = kMoraUseBucket(strat);
1619  /*- compute-------------------------------------------*/
1620
1621#ifdef HAVE_TAIL_RING
1622  if (strat->homog && strat->red == redFirst)
1623    if(!idIs0(F) &&(!rField_is_Ring(currRing)))
1624      kStratInitChangeTailRing(strat);
1625#endif
1626
1627  if (BVERBOSE(23))
1628  {
1629    kDebugPrint(strat);
1630  }
1631
1632  while (strat->Ll >= 0)
1633  {
1634    #if ADIDEBUG
1635    printf("\n      ------------------------NEW LOOP\n");
1636    printf("\nShdl = \n");
1637    for(int iii = 0; iii<= strat->sl; iii++)
1638    {
1639        printf("S[%i]:",iii);
1640        p_Write(strat->S[iii], strat->tailRing);
1641    }
1642    printf("\n   list   L has %i\n", strat->Ll);
1643    int iii;
1644    #if ADIDEBUG
1645    for(iii = 0; iii<= strat->Ll; iii++)
1646    {
1647        printf("L[%i]:",iii);
1648        #if 0
1649        p_Write(strat->L[iii].p, strat->tailRing);
1650        p_Write(strat->L[iii].p1, strat->tailRing);
1651        p_Write(strat->L[iii].p2, strat->tailRing);
1652        #else
1653        pWrite(strat->L[iii].p);
1654        pWrite(strat->L[iii].p1);
1655        pWrite(strat->L[iii].p2);
1656        pWrite(strat->L[iii].lcm);
1657        #endif
1658    }
1659    #endif
1660    getchar();
1661    #endif
1662    #ifdef KDEBUG
1663    if (TEST_OPT_DEBUG) messageSets(strat);
1664    #endif
1665    if (TEST_OPT_DEGBOUND
1666    && (strat->L[strat->Ll].ecart+strat->L[strat->Ll].GetpFDeg()> Kstd1_deg))
1667    {
1668      /*
1669      * stops computation if
1670      * - 24 (degBound)
1671      *   && upper degree is bigger than Kstd1_deg
1672      */
1673      while ((strat->Ll >= 0)
1674        && (strat->L[strat->Ll].p1!=NULL) && (strat->L[strat->Ll].p2!=NULL)
1675        && (strat->L[strat->Ll].ecart+strat->L[strat->Ll].GetpFDeg()> Kstd1_deg)
1676      )
1677      {
1678        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
1679        //if (TEST_OPT_PROT)
1680        //{
1681        //   PrintS("D"); mflush();
1682        //}
1683      }
1684      if (strat->Ll<0) break;
1685      else strat->noClearS=TRUE;
1686    }
1687    strat->P = strat->L[strat->Ll];/*- picks the last element from the lazyset L -*/
1688    if (strat->Ll==0) strat->interpt=TRUE;
1689    strat->Ll--;
1690    //printf("\nThis is P:\n");p_Write(strat->P.p,strat->tailRing);p_Write(strat->P.p1,strat->tailRing);p_Write(strat->P.p2,strat->tailRing);
1691    // create the real Spoly
1692    if (pNext(strat->P.p) == strat->tail)
1693    {
1694      /*- deletes the short spoly and computes -*/
1695#ifdef HAVE_RINGS
1696      if (rField_is_Ring(currRing))
1697        pLmDelete(strat->P.p);
1698      else
1699#endif
1700      pLmFree(strat->P.p);
1701      strat->P.p = NULL;
1702      poly m1 = NULL, m2 = NULL;
1703      // check that spoly creation is ok
1704      while (strat->tailRing != currRing &&
1705             !kCheckSpolyCreation(&(strat->P), strat, m1, m2))
1706      {
1707        assume(m1 == NULL && m2 == NULL);
1708        // if not, change to a ring where exponents are large enough
1709        kStratChangeTailRing(strat);
1710      }
1711      /* create the real one */
1712      ksCreateSpoly(&(strat->P), strat->kNoetherTail(), strat->use_buckets,
1713                    strat->tailRing, m1, m2, strat->R);
1714      if (!strat->use_buckets)
1715        strat->P.SetLength(strat->length_pLength);
1716    }
1717    else if (strat->P.p1 == NULL)
1718    {
1719      // for input polys, prepare reduction (buckets !)
1720      strat->P.SetLength(strat->length_pLength);
1721      strat->P.PrepareRed(strat->use_buckets);
1722    }
1723
1724    if (!strat->P.IsNull())
1725    {
1726      // might be NULL from noether !!!
1727      if (TEST_OPT_PROT)
1728        message(strat->P.ecart+strat->P.GetpFDeg(),&olddeg,&reduc,strat, red_result);
1729      // reduce
1730      #if ADIDEBUG
1731      printf("\nThis is P vor red:\n");p_Write(strat->P.p,strat->tailRing);p_Write(strat->P.p1,strat->tailRing);p_Write(strat->P.p2,strat->tailRing);
1732      printf("\nBefore Ll = %i\n", strat->Ll);
1733      #endif
1734      #ifdef HAVE_RINGS
1735      if(rField_is_Ring(strat->tailRing) && rHasLocalOrMixedOrdering(currRing))
1736      {
1737        //int inittl = strat->tl;
1738        red_result = strat->red(&strat->P,strat);
1739        //strat->tl = inittl;
1740      }
1741      else
1742      #endif
1743        red_result = strat->red(&strat->P,strat);
1744      #if ADIDEBUG
1745      printf("\nThis is P nach red:\n");p_Write(strat->P.p,strat->tailRing);p_Write(strat->P.p1,strat->tailRing);p_Write(strat->P.p2,strat->tailRing);
1746      printf("\nAfter Ll = %i\n", strat->Ll);
1747      #endif
1748    }
1749
1750    if (! strat->P.IsNull())
1751    {
1752      strat->P.GetP();
1753      // statistics
1754      if (TEST_OPT_PROT) PrintS("s");
1755      // normalization
1756      if (!TEST_OPT_INTSTRATEGY)
1757        strat->P.pNorm();
1758      // tailreduction
1759      strat->P.p = redtail(&(strat->P),strat->sl,strat);
1760      if (strat->P.p==NULL)
1761      {
1762        WerrorS("expoent overflow - wrong ordering");
1763        return(idInit(1,1));
1764      }
1765      // set ecart -- might have changed because of tail reductions
1766      if ((!strat->noTailReduction) && (!strat->honey))
1767        strat->initEcart(&strat->P);
1768      // cancel unit
1769      cancelunit(&strat->P);
1770      // for char 0, clear denominators
1771      if (TEST_OPT_INTSTRATEGY)
1772        strat->P.pCleardenom();
1773
1774      // put in T
1775      //if(red_result!=3)
1776      {
1777        #ifdef HAVE_RINGS
1778        if(rField_is_Ring(strat->tailRing) && rHasLocalOrMixedOrdering(currRing))
1779        {
1780            //int inittl = strat->tl;
1781          enterT(strat->P,strat);
1782          //enterT_strong(strat->P,strat);
1783          //strat->tl = inittl+1;
1784        }
1785        else
1786        #endif
1787          enterT(strat->P,strat);
1788          //enterT_strong(strat->P,strat);
1789      }
1790      // build new pairs
1791#ifdef HAVE_RINGS
1792      if (rField_is_Ring(currRing))
1793      {
1794        superenterpairs(strat->P.p,strat->sl,strat->P.ecart,0,strat, strat->tl);
1795      }
1796      else
1797#endif
1798      enterpairs(strat->P.p,strat->sl,strat->P.ecart,0,strat, strat->tl);
1799      // put in S
1800
1801        #if ADIDEBUG
1802        Print("\n    The new pair list L -- after superenterpairs in loop %d -- is:\n",loop_count);
1803        for(int iii=0;iii<=strat->Ll;iii++)
1804        {
1805          printf("\n    L[%d]:\n",iii);
1806          PrintS("         ");p_Write(strat->L[iii].p,strat->tailRing);
1807          PrintS("         ");p_Write(strat->L[iii].p1,strat->tailRing);
1808          PrintS("         ");p_Write(strat->L[iii].p2,strat->tailRing);
1809        }
1810        #endif
1811        //if(red_result!=3)
1812      strat->enterS(strat->P,
1813                    posInS(strat,strat->sl,strat->P.p, strat->P.ecart),
1814                    strat, strat->tl);
1815      #if ADIDEBUG
1816      printf("\nThis pair has been added to S:\n");
1817      pWrite(strat->P.p);
1818      pWrite(strat->P.p1);
1819      pWrite(strat->P.p2);
1820      #endif
1821
1822      // apply hilbert criterion
1823      if (hilb!=NULL)
1824      {
1825        if (strat->homog==isHomog)
1826          khCheck(Q,w,hilb,hilbeledeg,hilbcount,strat);
1827        else
1828          khCheckLocInhom(Q,w,hilb,hilbcount,strat);
1829      }
1830
1831      // clear strat->P
1832      if (strat->P.lcm!=NULL)
1833#if defined(HAVE_RINGS)
1834        pLmDelete(strat->P.lcm);
1835#else
1836        pLmFree(strat->P.lcm);
1837#endif
1838      strat->P.lcm=NULL;
1839#ifdef KDEBUG
1840      // make sure kTest_TS does not complain about strat->P
1841      memset(&strat->P,0,sizeof(strat->P));
1842#endif
1843    }
1844    if (strat->kHEdgeFound)
1845    {
1846      if ((TEST_OPT_FINDET)
1847      || ((TEST_OPT_MULTBOUND) && (scMult0Int(strat->Shdl,NULL,strat->tailRing) < Kstd1_mu)))
1848      {
1849        // obachman: is this still used ???
1850        /*
1851        * stops computation if strat->kHEdgeFound and
1852        * - 27 (finiteDeterminacyTest)
1853        * or
1854        * - 23
1855        *   (multBound)
1856        *   && multiplicity of the ideal is smaller then a predefined number mu
1857        */
1858        while (strat->Ll >= 0) deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
1859      }
1860    }
1861    kTest_TS(strat);
1862
1863#if ADIDEBUG
1864    Print("\n    The new reducer list T -- at the end of loop %d -- is\n",loop_count);
1865    for(int iii=0;iii<=strat->tl;iii++)
1866    {
1867      printf("\n    T[%d]:",iii);
1868      p_Write(strat->T[iii].p,strat->tailRing);
1869    }
1870    PrintLn();
1871
1872    loop_count++;
1873#endif /* ADIDEBUG */
1874  }
1875  /*- complete reduction of the standard basis------------------------ -*/
1876  if (TEST_OPT_REDSB) completeReduce(strat);
1877  else if (TEST_OPT_PROT) PrintLn();
1878  /*- release temp data------------------------------- -*/
1879  exitBuchMora(strat);
1880  /*- polynomials used for HECKE: HC, noether -*/
1881  if (TEST_OPT_FINDET)
1882  {
1883    if (strat->kHEdge!=NULL)
1884      Kstd1_mu=currRing->pFDeg(strat->kHEdge,currRing);
1885    else
1886      Kstd1_mu=-1;
1887  }
1888  pDelete(&strat->kHEdge);
1889  strat->update = TRUE; //???
1890  strat->lastAxis = 0; //???
1891  pDelete(&strat->kNoether);
1892  omFreeSize((ADDRESS)strat->NotUsedAxis,((currRing->N)+1)*sizeof(BOOLEAN));
1893  if ((TEST_OPT_PROT)||(TEST_OPT_DEBUG))  messageStat(hilbcount,strat);
1894//  if (TEST_OPT_WEIGHTM)
1895//  {
1896//    pRestoreDegProcs(currRing,strat->pOrigFDeg, strat->pOrigLDeg);
1897//    if (ecartWeights)
1898//    {
1899//      omFreeSize((ADDRESS)ecartWeights,((currRing->N)+1)*sizeof(short));
1900//      ecartWeights=NULL;
1901//    }
1902//  }
1903#ifdef HAVE_RINGS
1904  if(nCoeff_is_Ring_Z(currRing->cf))
1905    finalReduceByMon(strat);
1906#endif
1907  if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
1908  SI_RESTORE_OPT1(save1);
1909  idTest(strat->Shdl);
1910  return (strat->Shdl);
1911}
1912
1913poly kNF1 (ideal F,ideal Q,poly q, kStrategy strat, int lazyReduce)
1914{
1915  assume(q!=NULL);
1916  assume(!(idIs0(F)&&(Q==NULL)));
1917
1918// lazy_reduce flags: can be combined by |
1919//#define KSTD_NF_LAZY   1
1920  // do only a reduction of the leading term
1921//#define KSTD_NF_ECART  2
1922  // only local: recude even with bad ecart
1923  poly   p;
1924  int   i;
1925  int   j;
1926  int   o;
1927  LObject   h;
1928  BITSET save1;
1929  SI_SAVE_OPT1(save1);
1930
1931  //if ((idIs0(F))&&(Q==NULL))
1932  //  return pCopy(q); /*F=0*/
1933  //strat->ak = si_max(idRankFreeModule(F),pMaxComp(q));
1934  /*- creating temp data structures------------------- -*/
1935  strat->kHEdgeFound = (currRing->ppNoether) != NULL;
1936  strat->kNoether    = pCopy((currRing->ppNoether));
1937  si_opt_1|=Sy_bit(OPT_REDTAIL);
1938  si_opt_1&=~Sy_bit(OPT_INTSTRATEGY);
1939  if (TEST_OPT_STAIRCASEBOUND
1940  && (! TEST_V_DEG_STOP)
1941  && (0<Kstd1_deg)
1942  && ((!strat->kHEdgeFound)
1943    ||(TEST_OPT_DEGBOUND && (pWTotaldegree(strat->kNoether)<Kstd1_deg))))
1944  {
1945    pDelete(&strat->kNoether);
1946    strat->kNoether=pOne();
1947    pSetExp(strat->kNoether,1, Kstd1_deg+1);
1948    pSetm(strat->kNoether);
1949    strat->kHEdgeFound=TRUE;
1950  }
1951  initBuchMoraCrit(strat);
1952  initBuchMoraPos(strat);
1953  initMora(F,strat);
1954  strat->enterS = enterSMoraNF;
1955  /*- set T -*/
1956  strat->tl = -1;
1957  strat->tmax = setmaxT;
1958  strat->T = initT();
1959  strat->R = initR();
1960  strat->sevT = initsevT();
1961  /*- set S -*/
1962  strat->sl = -1;
1963  /*- init local data struct.-------------------------- -*/
1964  /*Shdl=*/initS(F,Q,strat);
1965  if ((strat->ak!=0)
1966  && (strat->kHEdgeFound))
1967  {
1968    if (strat->ak!=1)
1969    {
1970      pSetComp(strat->kNoether,1);
1971      pSetmComp(strat->kNoether);
1972      poly p=pHead(strat->kNoether);
1973      pSetComp(p,strat->ak);
1974      pSetmComp(p);
1975      p=pAdd(strat->kNoether,p);
1976      strat->kNoether=pNext(p);
1977      p_LmFree(p,currRing);
1978    }
1979  }
1980  if ((lazyReduce & KSTD_NF_LAZY)==0)
1981  {
1982    for (i=strat->sl; i>=0; i--)
1983      pNorm(strat->S[i]);
1984  }
1985  /*- puts the elements of S also to T -*/
1986  for (i=0; i<=strat->sl; i++)
1987  {
1988    h.p = strat->S[i];
1989    h.ecart = strat->ecartS[i];
1990    if (strat->sevS[i] == 0) strat->sevS[i] = pGetShortExpVector(h.p);
1991    else assume(strat->sevS[i] == pGetShortExpVector(h.p));
1992    h.length = pLength(h.p);
1993    h.sev = strat->sevS[i];
1994    h.SetpFDeg();
1995    enterT(h,strat);
1996  }
1997#ifdef KDEBUG
1998//  kDebugPrint(strat);
1999#endif
2000  /*- compute------------------------------------------- -*/
2001  p = pCopy(q);
2002  deleteHC(&p,&o,&j,strat);
2003  kTest(strat);
2004  if (TEST_OPT_PROT) { PrintS("r"); mflush(); }
2005  if (BVERBOSE(23)) kDebugPrint(strat);
2006  if (p!=NULL) p = redMoraNF(p,strat, lazyReduce & KSTD_NF_ECART);
2007  if ((p!=NULL)&&((lazyReduce & KSTD_NF_LAZY)==0))
2008  {
2009    if (TEST_OPT_PROT) { PrintS("t"); mflush(); }
2010    p = redtail(p,strat->sl,strat);
2011  }
2012  /*- release temp data------------------------------- -*/
2013  cleanT(strat);
2014  assume(strat->L==NULL); /*strat->L unsed */
2015  assume(strat->B==NULL); /*strat->B unused */
2016  omFreeSize((ADDRESS)strat->T,strat->tmax*sizeof(TObject));
2017  omFreeSize((ADDRESS)strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
2018  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
2019  omFreeSize((ADDRESS)strat->NotUsedAxis,((currRing->N)+1)*sizeof(BOOLEAN));
2020  omFree(strat->sevT);
2021  omFree(strat->S_2_R);
2022  omFree(strat->R);
2023
2024  if ((Q!=NULL)&&(strat->fromQ!=NULL))
2025  {
2026    i=((IDELEMS(Q)+IDELEMS(F)+15)/16)*16;
2027    omFreeSize((ADDRESS)strat->fromQ,i*sizeof(int));
2028    strat->fromQ=NULL;
2029  }
2030  pDelete(&strat->kHEdge);
2031  pDelete(&strat->kNoether);
2032//  if ((TEST_OPT_WEIGHTM)&&(F!=NULL))
2033//  {
2034//    pRestoreDegProcs(currRing,strat->pOrigFDeg, strat->pOrigLDeg);
2035//    if (ecartWeights)
2036//    {
2037//      omFreeSize((ADDRESS *)&ecartWeights,((currRing->N)+1)*sizeof(short));
2038//      ecartWeights=NULL;
2039//    }
2040//  }
2041  idDelete(&strat->Shdl);
2042  SI_RESTORE_OPT1(save1);
2043  if (TEST_OPT_PROT) PrintLn();
2044  return p;
2045}
2046
2047ideal kNF1 (ideal F,ideal Q,ideal q, kStrategy strat, int lazyReduce)
2048{
2049  assume(!idIs0(q));
2050  assume(!(idIs0(F)&&(Q==NULL)));
2051
2052// lazy_reduce flags: can be combined by |
2053//#define KSTD_NF_LAZY   1
2054  // do only a reduction of the leading term
2055//#define KSTD_NF_ECART  2
2056  // only local: recude even with bad ecart
2057  poly   p;
2058  int   i;
2059  int   j;
2060  int   o;
2061  LObject   h;
2062  ideal res;
2063  BITSET save1;
2064  SI_SAVE_OPT1(save1);
2065
2066  //if (idIs0(q)) return idInit(IDELEMS(q),si_max(q->rank,F->rank));
2067  //if ((idIs0(F))&&(Q==NULL))
2068  //  return idCopy(q); /*F=0*/
2069  //strat->ak = si_max(idRankFreeModule(F),idRankFreeModule(q));
2070  /*- creating temp data structures------------------- -*/
2071  strat->kHEdgeFound = (currRing->ppNoether) != NULL;
2072  strat->kNoether=pCopy((currRing->ppNoether));
2073  si_opt_1|=Sy_bit(OPT_REDTAIL);
2074  if (TEST_OPT_STAIRCASEBOUND
2075  && (0<Kstd1_deg)
2076  && ((!strat->kHEdgeFound)
2077    ||(TEST_OPT_DEGBOUND && (pWTotaldegree(strat->kNoether)<Kstd1_deg))))
2078  {
2079    pDelete(&strat->kNoether);
2080    strat->kNoether=pOne();
2081    pSetExp(strat->kNoether,1, Kstd1_deg+1);
2082    pSetm(strat->kNoether);
2083    strat->kHEdgeFound=TRUE;
2084  }
2085  initBuchMoraCrit(strat);
2086  initBuchMoraPos(strat);
2087  initMora(F,strat);
2088  strat->enterS = enterSMoraNF;
2089  /*- set T -*/
2090  strat->tl = -1;
2091  strat->tmax = setmaxT;
2092  strat->T = initT();
2093  strat->R = initR();
2094  strat->sevT = initsevT();
2095  /*- set S -*/
2096  strat->sl = -1;
2097  /*- init local data struct.-------------------------- -*/
2098  /*Shdl=*/initS(F,Q,strat);
2099  if ((strat->ak!=0)
2100  && (strat->kHEdgeFound))
2101  {
2102    if (strat->ak!=1)
2103    {
2104      pSetComp(strat->kNoether,1);
2105      pSetmComp(strat->kNoether);
2106      poly p=pHead(strat->kNoether);
2107      pSetComp(p,strat->ak);
2108      pSetmComp(p);
2109      p=pAdd(strat->kNoether,p);
2110      strat->kNoether=pNext(p);
2111      p_LmFree(p,currRing);
2112    }
2113  }
2114  if (TEST_OPT_INTSTRATEGY && ((lazyReduce & KSTD_NF_LAZY)==0))
2115  {
2116    for (i=strat->sl; i>=0; i--)
2117      pNorm(strat->S[i]);
2118  }
2119  /*- compute------------------------------------------- -*/
2120  res=idInit(IDELEMS(q),strat->ak);
2121  for (i=0; i<IDELEMS(q); i++)
2122  {
2123    if (q->m[i]!=NULL)
2124    {
2125      p = pCopy(q->m[i]);
2126      deleteHC(&p,&o,&j,strat);
2127      if (p!=NULL)
2128      {
2129        /*- puts the elements of S also to T -*/
2130        for (j=0; j<=strat->sl; j++)
2131        {
2132          h.p = strat->S[j];
2133          h.ecart = strat->ecartS[j];
2134          h.pLength = h.length = pLength(h.p);
2135          if (strat->sevS[j] == 0) strat->sevS[j] = pGetShortExpVector(h.p);
2136          else assume(strat->sevS[j] == pGetShortExpVector(h.p));
2137          h.sev = strat->sevS[j];
2138          h.SetpFDeg();
2139          #ifdef HAVE_RINGS
2140          if(rField_is_Ring(currRing) && rHasLocalOrMixedOrdering(currRing))
2141            enterT_strong(h,strat);
2142          else
2143          #endif
2144          enterT(h,strat);
2145        }
2146        if (TEST_OPT_PROT) { PrintS("r"); mflush(); }
2147        p = redMoraNF(p,strat, lazyReduce & KSTD_NF_ECART);
2148        if ((p!=NULL)&&((lazyReduce & KSTD_NF_LAZY)==0))
2149        {
2150          if (TEST_OPT_PROT) { PrintS("t"); mflush(); }
2151          p = redtail(p,strat->sl,strat);
2152        }
2153        cleanT(strat);
2154      }
2155      res->m[i]=p;
2156    }
2157    //else
2158    //  res->m[i]=NULL;
2159  }
2160  /*- release temp data------------------------------- -*/
2161  assume(strat->L==NULL); /*strat->L unsed */
2162  assume(strat->B==NULL); /*strat->B unused */
2163  omFreeSize((ADDRESS)strat->T,strat->tmax*sizeof(TObject));
2164  omFreeSize((ADDRESS)strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
2165  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
2166  omFreeSize((ADDRESS)strat->NotUsedAxis,((currRing->N)+1)*sizeof(BOOLEAN));
2167  omFree(strat->sevT);
2168  omFree(strat->S_2_R);
2169  omFree(strat->R);
2170  if ((Q!=NULL)&&(strat->fromQ!=NULL))
2171  {
2172    i=((IDELEMS(Q)+IDELEMS(F)+15)/16)*16;
2173    omFreeSize((ADDRESS)strat->fromQ,i*sizeof(int));
2174    strat->fromQ=NULL;
2175  }
2176  pDelete(&strat->kHEdge);
2177  pDelete(&strat->kNoether);
2178//  if ((TEST_OPT_WEIGHTM)&&(F!=NULL))
2179//  {
2180//    pFDeg=strat->pOrigFDeg;
2181//    pLDeg=strat->pOrigLDeg;
2182//    if (ecartWeights)
2183//    {
2184//      omFreeSize((ADDRESS *)&ecartWeights,((currRing->N)+1)*sizeof(short));
2185//      ecartWeights=NULL;
2186//    }
2187//  }
2188  idDelete(&strat->Shdl);
2189  SI_RESTORE_OPT1(save1);
2190  if (TEST_OPT_PROT) PrintLn();
2191  return res;
2192}
2193
2194intvec * kModW, * kHomW;
2195
2196long kModDeg(poly p, ring r)
2197{
2198  long o=p_WDegree(p, r);
2199  long i=p_GetComp(p, r);
2200  if (i==0) return o;
2201  //assume((i>0) && (i<=kModW->length()));
2202  if (i<=kModW->length())
2203    return o+(*kModW)[i-1];
2204  return o;
2205}
2206long kHomModDeg(poly p, ring r)
2207{
2208  int i;
2209  long j=0;
2210
2211  for (i=r->N;i>0;i--)
2212    j+=p_GetExp(p,i,r)*(*kHomW)[i-1];
2213  if (kModW == NULL) return j;
2214  i = p_GetComp(p,r);
2215  if (i==0) return j;
2216  return j+(*kModW)[i-1];
2217}
2218
2219ideal kStd(ideal F, ideal Q, tHomog h,intvec ** w, intvec *hilb,int syzComp,
2220          int newIdeal, intvec *vw, s_poly_proc_t sp)
2221{
2222  if(idIs0(F))
2223    return idInit(1,F->rank);
2224
2225  ideal r;
2226  BOOLEAN b=currRing->pLexOrder,toReset=FALSE;
2227  BOOLEAN delete_w=(w==NULL);
2228  kStrategy strat=new skStrategy;
2229
2230  strat->s_poly=sp;
2231  if(!TEST_OPT_RETURN_SB)
2232    strat->syzComp = syzComp;
2233  if (TEST_OPT_SB_1
2234    #ifdef HAVE_RINGS
2235    &&(!rField_is_Ring(currRing))
2236    #endif
2237    )
2238    strat->newIdeal = newIdeal;
2239  if (rField_has_simple_inverse(currRing))
2240    strat->LazyPass=20;
2241  else
2242    strat->LazyPass=2;
2243  strat->LazyDegree = 1;
2244  strat->ak = id_RankFreeModule(F,currRing);
2245  strat->kModW=kModW=NULL;
2246  strat->kHomW=kHomW=NULL;
2247  if (vw != NULL)
2248  {
2249    currRing->pLexOrder=FALSE;
2250    strat->kHomW=kHomW=vw;
2251    strat->pOrigFDeg = currRing->pFDeg;
2252    strat->pOrigLDeg = currRing->pLDeg;
2253    pSetDegProcs(currRing,kHomModDeg);
2254    toReset = TRUE;
2255  }
2256  if (h==testHomog)
2257  {
2258    if (strat->ak == 0)
2259    {
2260      h = (tHomog)idHomIdeal(F,Q);
2261      w=NULL;
2262    }
2263    else if (!TEST_OPT_DEGBOUND)
2264    {
2265      h = (tHomog)idHomModule(F,Q,w);
2266    }
2267  }
2268  currRing->pLexOrder=b;
2269  if (h==isHomog)
2270  {
2271    if (strat->ak > 0 && (w!=NULL) && (*w!=NULL))
2272    {
2273      strat->kModW = kModW = *w;
2274      if (vw == NULL)
2275      {
2276        strat->pOrigFDeg = currRing->pFDeg;
2277        strat->pOrigLDeg = currRing->pLDeg;
2278        pSetDegProcs(currRing,kModDeg);
2279        toReset = TRUE;
2280      }
2281    }
2282    currRing->pLexOrder = TRUE;
2283    if (hilb==NULL) strat->LazyPass*=2;
2284  }
2285  strat->homog=h;
2286#ifdef KDEBUG
2287  idTest(F);
2288  if (Q!=NULL) idTest(Q);
2289
2290#if MYTEST
2291  if (TEST_OPT_DEBUG)
2292  {
2293    PrintS("// kSTD: currRing: ");
2294    rWrite(currRing);
2295  }
2296#endif
2297
2298#endif
2299#ifdef HAVE_PLURAL
2300  if (rIsPluralRing(currRing))
2301  {
2302    const BOOLEAN bIsSCA  = rIsSCA(currRing) && strat->z2homog; // for Z_2 prod-crit
2303    strat->no_prod_crit   = ! bIsSCA;
2304    if (w!=NULL)
2305      r = nc_GB(F, Q, *w, hilb, strat, currRing);
2306    else
2307      r = nc_GB(F, Q, NULL, hilb, strat, currRing);
2308  }
2309  else
2310#endif
2311#ifdef HAVE_RINGS
2312  if (rField_is_Ring(currRing))
2313  {
2314    if(nCoeff_is_Ring_Z(currRing->cf))
2315    {
2316        #if 0
2317        if(nCoeff_is_Ring_Z(currRing->cf))
2318        {
2319            ideal FCopy = idCopy(F);
2320            poly pFmon = preIntegerCheck(FCopy, Q);
2321            if(pFmon != NULL)
2322            {
2323              idInsertPoly(FCopy, pFmon);
2324              #if ADIDEBUG
2325              printf("\nPreintegerCheck found this constant:\n");pWrite(pFmon);
2326              #endif
2327            }
2328            strat->kModW=kModW=NULL;
2329            if (h==testHomog)
2330            {
2331                if (strat->ak == 0)
2332                {
2333                  h = (tHomog)idHomIdeal(FCopy,Q);
2334                  w=NULL;
2335                }
2336                else if (!TEST_OPT_DEGBOUND)
2337                {
2338                    h = (tHomog)idHomModule(FCopy,Q,w);
2339                }
2340            }
2341            currRing->pLexOrder=b;
2342            if (h==isHomog)
2343            {
2344                if (strat->ak > 0 && (w!=NULL) && (*w!=NULL))
2345                {
2346                  strat->kModW = kModW = *w;
2347                  if (vw == NULL)
2348                  {
2349                    strat->pOrigFDeg = currRing->pFDeg;
2350                    strat->pOrigLDeg = currRing->pLDeg;
2351                    pSetDegProcs(currRing,kModDeg);
2352                    toReset = TRUE;
2353                  }
2354                }
2355                currRing->pLexOrder = TRUE;
2356                if (hilb==NULL) strat->LazyPass*=2;
2357            }
2358            strat->homog=h;
2359            omTestMemory(1);
2360            if(rHasLocalOrMixedOrdering(currRing))
2361                r=mora(FCopy,Q,NULL,hilb,strat);
2362            else
2363                r=bba(FCopy,Q,NULL,hilb,strat);
2364        }
2365        else
2366        #endif
2367        {
2368            if(rHasLocalOrMixedOrdering(currRing))
2369                r=mora(F,Q,NULL,hilb,strat);
2370            else
2371                r=bba(F,Q,NULL,hilb,strat);
2372        }
2373    }
2374    else
2375    {
2376      if(rHasLocalOrMixedOrdering(currRing))
2377        r=mora(F,Q,NULL,hilb,strat);
2378      else
2379        r=bba(F,Q,NULL,hilb,strat);
2380    }
2381  }
2382  else
2383#endif
2384  {
2385    if (rHasLocalOrMixedOrdering(currRing))
2386    {
2387      if (w!=NULL)
2388        r=mora(F,Q,*w,hilb,strat);
2389      else
2390        r=mora(F,Q,NULL,hilb,strat);
2391    }
2392    else
2393    {
2394      if (w!=NULL)
2395        r=bba(F,Q,*w,hilb,strat);
2396      else
2397        r=bba(F,Q,NULL,hilb,strat);
2398    }
2399  }
2400#ifdef KDEBUG
2401  idTest(r);
2402#endif
2403  if (toReset)
2404  {
2405    kModW = NULL;
2406    pRestoreDegProcs(currRing,strat->pOrigFDeg, strat->pOrigLDeg);
2407  }
2408  currRing->pLexOrder = b;
2409//Print("%d reductions canceled \n",strat->cel);
2410  HCord=strat->HCord;
2411  delete(strat);
2412  if ((delete_w)&&(w!=NULL)&&(*w!=NULL)) delete *w;
2413  return r;
2414}
2415
2416ideal kSba(ideal F, ideal Q, tHomog h,intvec ** w, int sbaOrder, int arri, intvec *hilb,int syzComp,
2417          int newIdeal, intvec *vw)
2418{
2419  if(idIs0(F))
2420    return idInit(1,F->rank);
2421
2422  ideal r;
2423  BOOLEAN b=currRing->pLexOrder,toReset=FALSE;
2424  BOOLEAN delete_w=(w==NULL);
2425  kStrategy strat=new skStrategy;
2426  strat->sbaOrder = sbaOrder;
2427  if (arri!=0)
2428  {
2429    strat->rewCrit1 = arriRewDummy;
2430    strat->rewCrit2 = arriRewCriterion;
2431    strat->rewCrit3 = arriRewCriterionPre;
2432  }
2433  else
2434  {
2435    strat->rewCrit1 = faugereRewCriterion;
2436    strat->rewCrit2 = faugereRewCriterion;
2437    strat->rewCrit3 = faugereRewCriterion;
2438  }
2439
2440  if(!TEST_OPT_RETURN_SB)
2441    strat->syzComp = syzComp;
2442  if (TEST_OPT_SB_1)
2443    #ifdef HAVE_RINGS
2444    if(!rField_is_Ring(currRing))
2445    #endif
2446    strat->newIdeal = newIdeal;
2447  if (rField_has_simple_inverse(currRing))
2448    strat->LazyPass=20;
2449  else
2450    strat->LazyPass=2;
2451  strat->LazyDegree = 1;
2452  strat->enterOnePair=enterOnePairNormal;
2453  strat->chainCrit=chainCritNormal;
2454  if (TEST_OPT_SB_1) strat->chainCrit=chainCritOpt_1;
2455  strat->ak = id_RankFreeModule(F,currRing);
2456  strat->kModW=kModW=NULL;
2457  strat->kHomW=kHomW=NULL;
2458  if (vw != NULL)
2459  {
2460    currRing->pLexOrder=FALSE;
2461    strat->kHomW=kHomW=vw;
2462    strat->pOrigFDeg = currRing->pFDeg;
2463    strat->pOrigLDeg = currRing->pLDeg;
2464    pSetDegProcs(currRing,kHomModDeg);
2465    toReset = TRUE;
2466  }
2467  if (h==testHomog)
2468  {
2469    if (strat->ak == 0)
2470    {
2471      h = (tHomog)idHomIdeal(F,Q);
2472      w=NULL;
2473    }
2474    else if (!TEST_OPT_DEGBOUND)
2475    {
2476      h = (tHomog)idHomModule(F,Q,w);
2477    }
2478  }
2479  currRing->pLexOrder=b;
2480  if (h==isHomog)
2481  {
2482    if (strat->ak > 0 && (w!=NULL) && (*w!=NULL))
2483    {
2484      strat->kModW = kModW = *w;
2485      if (vw == NULL)
2486      {
2487        strat->pOrigFDeg = currRing->pFDeg;
2488        strat->pOrigLDeg = currRing->pLDeg;
2489        pSetDegProcs(currRing,kModDeg);
2490        toReset = TRUE;
2491      }
2492    }
2493    currRing->pLexOrder = TRUE;
2494    if (hilb==NULL) strat->LazyPass*=2;
2495  }
2496  strat->homog=h;
2497#ifdef KDEBUG
2498  idTest(F);
2499  idTest(Q);
2500
2501#if MYTEST
2502  if (TEST_OPT_DEBUG)
2503  {
2504    PrintS("// kSTD: currRing: ");
2505    rWrite(currRing);
2506  }
2507#endif
2508
2509#endif
2510#ifdef HAVE_PLURAL
2511  if (rIsPluralRing(currRing))
2512  {
2513    const BOOLEAN bIsSCA  = rIsSCA(currRing) && strat->z2homog; // for Z_2 prod-crit
2514    strat->no_prod_crit   = ! bIsSCA;
2515    if (w!=NULL)
2516      r = nc_GB(F, Q, *w, hilb, strat, currRing);
2517    else
2518      r = nc_GB(F, Q, NULL, hilb, strat, currRing);
2519  }
2520  else
2521#endif
2522#ifdef HAVE_RINGS
2523  if (rField_is_Ring(currRing))
2524    r=bba(F,Q,NULL,hilb,strat);
2525  else
2526#endif
2527  {
2528    if (rHasLocalOrMixedOrdering(currRing))
2529    {
2530      if (w!=NULL)
2531        r=mora(F,Q,*w,hilb,strat);
2532      else
2533        r=mora(F,Q,NULL,hilb,strat);
2534    }
2535    else
2536    {
2537      if (w!=NULL)
2538        r=sba(F,Q,*w,hilb,strat);
2539      else
2540        r=sba(F,Q,NULL,hilb,strat);
2541    }
2542  }
2543#ifdef KDEBUG
2544  idTest(r);
2545#endif
2546  if (toReset)
2547  {
2548    kModW = NULL;
2549    pRestoreDegProcs(currRing,strat->pOrigFDeg, strat->pOrigLDeg);
2550  }
2551  currRing->pLexOrder = b;
2552//Print("%d reductions canceled \n",strat->cel);
2553  HCord=strat->HCord;
2554  delete(strat);
2555  if ((delete_w)&&(w!=NULL)&&(*w!=NULL)) delete *w;
2556  return r;
2557}
2558
2559#ifdef HAVE_SHIFTBBA
2560ideal kStdShift(ideal F, ideal Q, tHomog h,intvec ** w, intvec *hilb,int syzComp,
2561                int newIdeal, intvec *vw, int uptodeg, int lV)
2562{
2563  ideal r;
2564  BOOLEAN b=currRing->pLexOrder,toReset=FALSE;
2565  BOOLEAN delete_w=(w==NULL);
2566  kStrategy strat=new skStrategy;
2567
2568  if(!TEST_OPT_RETURN_SB)
2569    strat->syzComp = syzComp;
2570  if (TEST_OPT_SB_1)
2571    #ifdef HAVE_RINGS
2572    if(!rField_is_Ring(currRing))
2573    #endif
2574    strat->newIdeal = newIdeal;
2575  if (rField_has_simple_inverse(currRing))
2576    strat->LazyPass=20;
2577  else
2578    strat->LazyPass=2;
2579  strat->LazyDegree = 1;
2580  strat->ak = id_RankFreeModule(F,currRing);
2581  strat->kModW=kModW=NULL;
2582  strat->kHomW=kHomW=NULL;
2583  if (vw != NULL)
2584  {
2585    currRing->pLexOrder=FALSE;
2586    strat->kHomW=kHomW=vw;
2587    strat->pOrigFDeg = currRing->pFDeg;
2588    strat->pOrigLDeg = currRing->pLDeg;
2589    pSetDegProcs(currRing,kHomModDeg);
2590    toReset = TRUE;
2591  }
2592  if (h==testHomog)
2593  {
2594    if (strat->ak == 0)
2595    {
2596      h = (tHomog)idHomIdeal(F,Q);
2597      w=NULL;
2598    }
2599    else if (!TEST_OPT_DEGBOUND)
2600    {
2601      h = (tHomog)idHomModule(F,Q,w);
2602    }
2603  }
2604  currRing->pLexOrder=b;
2605  if (h==isHomog)
2606  {
2607    if (strat->ak > 0 && (w!=NULL) && (*w!=NULL))
2608    {
2609      strat->kModW = kModW = *w;
2610      if (vw == NULL)
2611      {
2612        strat->pOrigFDeg = currRing->pFDeg;
2613        strat->pOrigLDeg = currRing->pLDeg;
2614        pSetDegProcs(currRing,kModDeg);
2615        toReset = TRUE;
2616      }
2617    }
2618    currRing->pLexOrder = TRUE;
2619    if (hilb==NULL) strat->LazyPass*=2;
2620  }
2621  strat->homog=h;
2622#ifdef KDEBUG
2623  idTest(F);
2624#endif
2625  if (rHasLocalOrMixedOrdering(currRing))
2626  {
2627    /* error: no local ord yet with shifts */
2628    Print("No local ordering possible for shifts");
2629    return(NULL);
2630  }
2631  else
2632  {
2633    /* global ordering */
2634    if (w!=NULL)
2635      r=bbaShift(F,Q,*w,hilb,strat,uptodeg,lV);
2636    else
2637      r=bbaShift(F,Q,NULL,hilb,strat,uptodeg,lV);
2638  }
2639#ifdef KDEBUG
2640  idTest(r);
2641#endif
2642  if (toReset)
2643  {
2644    kModW = NULL;
2645    pRestoreDegProcs(currRing,strat->pOrigFDeg, strat->pOrigLDeg);
2646  }
2647  currRing->pLexOrder = b;
2648//Print("%d reductions canceled \n",strat->cel);
2649  HCord=strat->HCord;
2650  delete(strat);
2651  if ((delete_w)&&(w!=NULL)&&(*w!=NULL)) delete *w;
2652  return r;
2653}
2654#endif
2655
2656//##############################################################
2657//##############################################################
2658//##############################################################
2659//##############################################################
2660//##############################################################
2661
2662ideal kMin_std(ideal F, ideal Q, tHomog h,intvec ** w, ideal &M, intvec *hilb,
2663              int syzComp, int reduced)
2664{
2665  if(idIs0(F))
2666  {
2667    M=idInit(1,F->rank);
2668    return idInit(1,F->rank);
2669  }
2670  #ifdef HAVE_RINGS
2671  if(rField_is_Ring(currRing))
2672  {
2673    ideal sb;
2674    sb = kStd(F, Q, h, w, hilb);
2675    idSkipZeroes(sb);
2676    if(IDELEMS(sb) <= IDELEMS(F))
2677    {
2678        M = idCopy(sb);
2679        idSkipZeroes(M);
2680        return(sb);
2681    }
2682    else
2683    {
2684        M = idCopy(F);
2685        idSkipZeroes(M);
2686        return(sb);
2687    }
2688  }
2689  #endif
2690  ideal r=NULL;
2691  int Kstd1_OldDeg = Kstd1_deg,i;
2692  intvec* temp_w=NULL;
2693  BOOLEAN b=currRing->pLexOrder,toReset=FALSE;
2694  BOOLEAN delete_w=(w==NULL);
2695  BOOLEAN oldDegBound=TEST_OPT_DEGBOUND;
2696  kStrategy strat=new skStrategy;
2697
2698  if(!TEST_OPT_RETURN_SB)
2699     strat->syzComp = syzComp;
2700  if (rField_has_simple_inverse(currRing))
2701    strat->LazyPass=20;
2702  else
2703    strat->LazyPass=2;
2704  strat->LazyDegree = 1;
2705  strat->minim=(reduced % 2)+1;
2706  strat->ak = id_RankFreeModule(F,currRing);
2707  if (delete_w)
2708  {
2709    temp_w=new intvec((strat->ak)+1);
2710    w = &temp_w;
2711  }
2712  if (h==testHomog)
2713  {
2714    if (strat->ak == 0)
2715    {
2716      h = (tHomog)idHomIdeal(F,Q);
2717      w=NULL;
2718    }
2719    else
2720    {
2721      h = (tHomog)idHomModule(F,Q,w);
2722    }
2723  }
2724  if (h==isHomog)
2725  {
2726    if (strat->ak > 0 && (w!=NULL) && (*w!=NULL))
2727    {
2728      kModW = *w;
2729      strat->kModW = *w;
2730      assume(currRing->pFDeg != NULL && currRing->pLDeg != NULL);
2731      strat->pOrigFDeg = currRing->pFDeg;
2732      strat->pOrigLDeg = currRing->pLDeg;
2733      pSetDegProcs(currRing,kModDeg);
2734
2735      toReset = TRUE;
2736      if (reduced>1)
2737      {
2738        Kstd1_OldDeg=Kstd1_deg;
2739        Kstd1_deg = -1;
2740        for (i=IDELEMS(F)-1;i>=0;i--)
2741        {
2742          if ((F->m[i]!=NULL) && (currRing->pFDeg(F->m[i],currRing)>=Kstd1_deg))
2743            Kstd1_deg = currRing->pFDeg(F->m[i],currRing)+1;
2744        }
2745      }
2746    }
2747    currRing->pLexOrder = TRUE;
2748    strat->LazyPass*=2;
2749  }
2750  strat->homog=h;
2751  if (rHasLocalOrMixedOrdering(currRing))
2752  {
2753    if (w!=NULL)
2754      r=mora(F,Q,*w,hilb,strat);
2755    else
2756      r=mora(F,Q,NULL,hilb,strat);
2757  }
2758  else
2759  {
2760    if (w!=NULL)
2761      r=bba(F,Q,*w,hilb,strat);
2762    else
2763      r=bba(F,Q,NULL,hilb,strat);
2764  }
2765#ifdef KDEBUG
2766  {
2767    int i;
2768    for (i=IDELEMS(r)-1; i>=0; i--) pTest(r->m[i]);
2769  }
2770#endif
2771  idSkipZeroes(r);
2772  if (toReset)
2773  {
2774    pRestoreDegProcs(currRing,strat->pOrigFDeg, strat->pOrigLDeg);
2775    kModW = NULL;
2776  }
2777  currRing->pLexOrder = b;
2778  HCord=strat->HCord;
2779  if ((delete_w)&&(temp_w!=NULL)) delete temp_w;
2780  if ((IDELEMS(r)==1) && (r->m[0]!=NULL) && pIsConstant(r->m[0]) && (strat->ak==0))
2781  {
2782    M=idInit(1,F->rank);
2783    M->m[0]=pOne();
2784    //if (strat->ak!=0) { pSetComp(M->m[0],strat->ak); pSetmComp(M->m[0]); }
2785    if (strat->M!=NULL) idDelete(&strat->M);
2786  }
2787  else if (strat->M==NULL)
2788  {
2789    M=idInit(1,F->rank);
2790    Warn("no minimal generating set computed");
2791  }
2792  else
2793  {
2794    idSkipZeroes(strat->M);
2795    M=strat->M;
2796  }
2797  delete(strat);
2798  if (reduced>2)
2799  {
2800    Kstd1_deg=Kstd1_OldDeg;
2801    if (!oldDegBound)
2802      si_opt_1 &= ~Sy_bit(OPT_DEGBOUND);
2803  }
2804  else
2805  {
2806    if (IDELEMS(M)>IDELEMS(r)) {
2807       idDelete(&M);
2808       M=idCopy(r); }
2809  }
2810  return r;
2811}
2812
2813poly kNF(ideal F, ideal Q, poly p,int syzComp, int lazyReduce)
2814{
2815  if (p==NULL)
2816     return NULL;
2817
2818  poly pp = p;
2819
2820#ifdef HAVE_PLURAL
2821  if(rIsSCA(currRing))
2822  {
2823    const unsigned int m_iFirstAltVar = scaFirstAltVar(currRing);
2824    const unsigned int m_iLastAltVar  = scaLastAltVar(currRing);
2825    pp = p_KillSquares(pp, m_iFirstAltVar, m_iLastAltVar, currRing);
2826
2827    if(Q == currRing->qideal)
2828      Q = SCAQuotient(currRing);
2829  }
2830#endif
2831
2832  if ((idIs0(F))&&(Q==NULL))
2833  {
2834#ifdef HAVE_PLURAL
2835    if(p != pp)
2836      return pp;
2837#endif
2838    return pCopy(p); /*F+Q=0*/
2839  }
2840
2841  kStrategy strat=new skStrategy;
2842  strat->syzComp = syzComp;
2843  strat->ak = si_max(id_RankFreeModule(F,currRing),pMaxComp(p));
2844  poly res;
2845
2846  if (rHasLocalOrMixedOrdering(currRing))
2847    res=kNF1(F,Q,pp,strat,lazyReduce);
2848  else
2849    res=kNF2(F,Q,pp,strat,lazyReduce);
2850  delete(strat);
2851
2852#ifdef HAVE_PLURAL
2853  if(pp != p)
2854    p_Delete(&pp, currRing);
2855#endif
2856  return res;
2857}
2858
2859ideal kNF(ideal F, ideal Q, ideal p,int syzComp,int lazyReduce)
2860{
2861  ideal res;
2862  if (TEST_OPT_PROT)
2863  {
2864    Print("(S:%d)",IDELEMS(p));mflush();
2865  }
2866  if (idIs0(p))
2867    return idInit(IDELEMS(p),si_max(p->rank,F->rank));
2868
2869  ideal pp = p;
2870#ifdef HAVE_PLURAL
2871  if(rIsSCA(currRing))
2872  {
2873    const unsigned int m_iFirstAltVar = scaFirstAltVar(currRing);
2874    const unsigned int m_iLastAltVar  = scaLastAltVar(currRing);
2875    pp = id_KillSquares(pp, m_iFirstAltVar, m_iLastAltVar, currRing, false);
2876
2877    if(Q == currRing->qideal)
2878      Q = SCAQuotient(currRing);
2879  }
2880#endif
2881
2882  if ((idIs0(F))&&(Q==NULL))
2883  {
2884#ifdef HAVE_PLURAL
2885    if(p != pp)
2886      return pp;
2887#endif
2888    return idCopy(p); /*F+Q=0*/
2889  }
2890
2891  kStrategy strat=new skStrategy;
2892  strat->syzComp = syzComp;
2893  strat->ak = si_max(id_RankFreeModule(F,currRing),id_RankFreeModule(p,currRing));
2894  if (strat->ak>0) // only for module case, see Tst/Short/bug_reduce.tst
2895  {
2896    strat->ak = si_max(strat->ak,(int)F->rank);
2897  }
2898
2899  if (rHasLocalOrMixedOrdering(currRing))
2900    res=kNF1(F,Q,pp,strat,lazyReduce);
2901  else
2902    res=kNF2(F,Q,pp,strat,lazyReduce);
2903  delete(strat);
2904
2905#ifdef HAVE_PLURAL
2906  if(pp != p)
2907    id_Delete(&pp, currRing);
2908#endif
2909
2910  return res;
2911}
2912
2913poly k_NF (ideal F, ideal Q, poly p,int syzComp, int lazyReduce, const ring _currRing)
2914{
2915  const ring save = currRing;
2916  if( currRing != _currRing ) rChangeCurrRing(_currRing);
2917  poly ret = kNF(F, Q, p, syzComp, lazyReduce);
2918  if( currRing != save )     rChangeCurrRing(save);
2919  return ret;
2920}
2921
2922/*2
2923*interreduces F
2924*/
2925// old version
2926ideal kInterRedOld (ideal F, ideal Q)
2927{
2928  int j;
2929  kStrategy strat = new skStrategy;
2930
2931  ideal tempF = F;
2932  ideal tempQ = Q;
2933
2934#ifdef HAVE_PLURAL
2935  if(rIsSCA(currRing))
2936  {
2937    const unsigned int m_iFirstAltVar = scaFirstAltVar(currRing);
2938    const unsigned int m_iLastAltVar  = scaLastAltVar(currRing);
2939    tempF = id_KillSquares(F, m_iFirstAltVar, m_iLastAltVar, currRing);
2940
2941    // this should be done on the upper level!!! :
2942    //    tempQ = SCAQuotient(currRing);
2943
2944    if(Q == currRing->qideal)
2945      tempQ = SCAQuotient(currRing);
2946  }
2947#endif
2948
2949//  if (TEST_OPT_PROT)
2950//  {
2951//    writeTime("start InterRed:");
2952//    mflush();
2953//  }
2954  //strat->syzComp     = 0;
2955  strat->kHEdgeFound = (currRing->ppNoether) != NULL;
2956  strat->kNoether=pCopy((currRing->ppNoether));
2957  strat->ak = id_RankFreeModule(tempF,currRing);
2958  initBuchMoraCrit(strat);
2959  strat->NotUsedAxis = (BOOLEAN *)omAlloc(((currRing->N)+1)*sizeof(BOOLEAN));
2960  for (j=(currRing->N); j>0; j--) strat->NotUsedAxis[j] = TRUE;
2961  strat->enterS      = enterSBba;
2962  strat->posInT      = posInT17;
2963  strat->initEcart   = initEcartNormal;
2964  strat->sl   = -1;
2965  strat->tl          = -1;
2966  strat->tmax        = setmaxT;
2967  strat->T           = initT();
2968  strat->R           = initR();
2969  strat->sevT        = initsevT();
2970  if (rHasLocalOrMixedOrdering(currRing))   strat->honey = TRUE;
2971  initS(tempF, tempQ, strat);
2972  if (TEST_OPT_REDSB)
2973    strat->noTailReduction=FALSE;
2974  updateS(TRUE,strat);
2975  if (TEST_OPT_REDSB && TEST_OPT_INTSTRATEGY)
2976    completeReduce(strat);
2977  //else if (TEST_OPT_PROT) PrintLn();
2978  pDelete(&strat->kHEdge);
2979  omFreeSize((ADDRESS)strat->T,strat->tmax*sizeof(TObject));
2980  omFreeSize((ADDRESS)strat->ecartS,IDELEMS(strat->Shdl)*sizeof(int));
2981  omFreeSize((ADDRESS)strat->sevS,IDELEMS(strat->Shdl)*sizeof(unsigned long));
2982  omFreeSize((ADDRESS)strat->NotUsedAxis,((currRing->N)+1)*sizeof(BOOLEAN));
2983  omfree(strat->sevT);
2984  omfree(strat->S_2_R);
2985  omfree(strat->R);
2986
2987  if (strat->fromQ)
2988  {
2989    for (j=IDELEMS(strat->Shdl)-1;j>=0;j--)
2990    {
2991      if(strat->fromQ[j]) pDelete(&strat->Shdl->m[j]);
2992    }
2993    omFreeSize((ADDRESS)strat->fromQ,IDELEMS(strat->Shdl)*sizeof(int));
2994  }
2995//  if (TEST_OPT_PROT)
2996//  {
2997//    writeTime("end Interred:");
2998//    mflush();
2999//  }
3000  ideal shdl=strat->Shdl;
3001  idSkipZeroes(shdl);
3002  if (strat->fromQ)
3003  {
3004    strat->fromQ=NULL;
3005    ideal res=kInterRed(shdl,NULL);
3006    idDelete(&shdl);
3007    shdl=res;
3008  }
3009  delete(strat);
3010#ifdef HAVE_PLURAL
3011  if( tempF != F )
3012    id_Delete( &tempF, currRing);
3013#endif
3014  return shdl;
3015}
3016// new version
3017ideal kInterRedBba (ideal F, ideal Q, int &need_retry)
3018{
3019  need_retry=0;
3020  int   red_result = 1;
3021  int   olddeg,reduc;
3022  BOOLEAN withT = FALSE;
3023  // BOOLEAN toReset=FALSE;
3024  kStrategy strat=new skStrategy;
3025  tHomog h;
3026  intvec * w=NULL;
3027
3028  if (rField_has_simple_inverse(currRing))
3029    strat->LazyPass=20;
3030  else
3031    strat->LazyPass=2;
3032  strat->LazyDegree = 1;
3033  strat->ak = id_RankFreeModule(F,currRing);
3034  strat->syzComp = strat->ak;
3035  strat->kModW=kModW=NULL;
3036  strat->kHomW=kHomW=NULL;
3037  if (strat->ak == 0)
3038  {
3039    h = (tHomog)idHomIdeal(F,Q);
3040    w=NULL;
3041  }
3042  else if (!TEST_OPT_DEGBOUND)
3043  {
3044    h = (tHomog)idHomModule(F,Q,&w);
3045  }
3046  if (h==isHomog)
3047  {
3048    if (strat->ak > 0 && (w!=NULL) && (w!=NULL))
3049    {
3050      strat->kModW = kModW = w;
3051      strat->pOrigFDeg = currRing->pFDeg;
3052      strat->pOrigLDeg = currRing->pLDeg;
3053      pSetDegProcs(currRing,kModDeg);
3054      // toReset = TRUE;
3055    }
3056    strat->LazyPass*=2;
3057  }
3058  strat->homog=h;
3059#ifdef KDEBUG
3060  idTest(F);
3061#endif
3062
3063  initBuchMoraCrit(strat); /*set Gebauer, honey, sugarCrit*/
3064  initBuchMoraPos(strat);
3065  initBba(F,strat);
3066  /*set enterS, spSpolyShort, reduce, red, initEcart, initEcartPair*/
3067  strat->posInL=posInL0; /* ord according pComp */
3068
3069  /*Shdl=*/initBuchMora(F, Q, strat);
3070  reduc = olddeg = 0;
3071
3072#ifndef NO_BUCKETS
3073  if (!TEST_OPT_NOT_BUCKETS)
3074    strat->use_buckets = 1;
3075#endif
3076
3077  // redtailBBa against T for inhomogenous input
3078  if (!TEST_OPT_OLDSTD)
3079    withT = ! strat->homog;
3080
3081  // strat->posInT = posInT_pLength;
3082  kTest_TS(strat);
3083
3084#ifdef HAVE_TAIL_RING
3085  kStratInitChangeTailRing(strat);
3086#endif
3087
3088  /* compute------------------------------------------------------- */
3089  while (strat->Ll >= 0)
3090  {
3091    #ifdef KDEBUG
3092      if (TEST_OPT_DEBUG) messageSets(strat);
3093    #endif
3094    if (strat->Ll== 0) strat->interpt=TRUE;
3095    /* picks the last element from the lazyset L */
3096    strat->P = strat->L[strat->Ll];
3097    strat->Ll--;
3098
3099    if (strat->P.p1 == NULL)
3100    {
3101      // for input polys, prepare reduction
3102      strat->P.PrepareRed(strat->use_buckets);
3103    }
3104
3105    if (strat->P.p == NULL && strat->P.t_p == NULL)
3106    {
3107      red_result = 0;
3108    }
3109    else
3110    {
3111      if (TEST_OPT_PROT)
3112        message(strat->P.pFDeg(),
3113                &olddeg,&reduc,strat, red_result);
3114
3115      /* reduction of the element chosen from L */
3116      red_result = strat->red(&strat->P,strat);
3117    }
3118
3119    // reduction to non-zero new poly
3120    if (red_result == 1)
3121    {
3122      /* statistic */
3123      if (TEST_OPT_PROT) PrintS("s");
3124
3125      // get the polynomial (canonicalize bucket, make sure P.p is set)
3126      strat->P.GetP(strat->lmBin);
3127
3128      int pos=posInS(strat,strat->sl,strat->P.p,strat->P.ecart);
3129
3130      // reduce the tail and normalize poly
3131      // in the ring case we cannot expect LC(f) = 1,
3132      // therefore we call pContent instead of pNorm
3133      if ((TEST_OPT_INTSTRATEGY) || (rField_is_Ring(currRing)))
3134      {
3135        strat->P.pCleardenom();
3136        if (0)
3137        //if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
3138        {
3139          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
3140          strat->P.pCleardenom();
3141        }
3142      }
3143      else
3144      {
3145        strat->P.pNorm();
3146        if (0)
3147        //if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
3148          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
3149      }
3150
3151#ifdef KDEBUG
3152      if (TEST_OPT_DEBUG){PrintS("new s:");strat->P.wrp();PrintLn();}
3153#endif
3154
3155      // enter into S, L, and T
3156      if ((!TEST_OPT_IDLIFT) || (pGetComp(strat->P.p) <= strat->syzComp))
3157      {
3158        enterT(strat->P, strat);
3159        // posInS only depends on the leading term
3160        strat->enterS(strat->P, pos, strat, strat->tl);
3161
3162        if (pos<strat->sl)
3163        {
3164          need_retry++;
3165          // move all "larger" elements fromS to L
3166          // remove them from T
3167          int ii=pos+1;
3168          for(;ii<=strat->sl;ii++)
3169          {
3170            LObject h;
3171            memset(&h,0,sizeof(h));
3172            h.tailRing=strat->tailRing;
3173            h.p=strat->S[ii]; strat->S[ii]=NULL;
3174            strat->initEcart(&h);
3175            h.sev=strat->sevS[ii];
3176            int jj=strat->tl;
3177            while (jj>=0)
3178            {
3179              if (strat->T[jj].p==h.p)
3180              {
3181                strat->T[jj].p=NULL;
3182                if (jj<strat->tl)
3183                {
3184                  memmove(&(strat->T[jj]),&(strat->T[jj+1]),
3185                          (strat->tl-jj)*sizeof(strat->T[jj]));
3186                  memmove(&(strat->sevT[jj]),&(strat->sevT[jj+1]),
3187                          (strat->tl-jj)*sizeof(strat->sevT[jj]));
3188                }
3189                strat->tl--;
3190                break;
3191              }
3192              jj--;
3193            }
3194            int lpos=strat->posInL(strat->L,strat->Ll,&h,strat);
3195            enterL(&strat->L,&strat->Ll,&strat->Lmax,h,lpos);
3196            #ifdef KDEBUG
3197            if (TEST_OPT_DEBUG)
3198            {
3199              Print("move S[%d] -> L[%d]: ",ii,pos);
3200              p_wrp(h.p,currRing, strat->tailRing);
3201              PrintLn();
3202            }
3203            #endif
3204          }
3205          if (strat->fromQ!=NULL)
3206          {
3207            for(ii=pos+1;ii<=strat->sl;ii++) strat->fromQ[ii]=0;
3208          }
3209          strat->sl=pos;
3210        }
3211      }
3212      else
3213      {
3214        // clean P
3215      }
3216      if (strat->P.lcm!=NULL)
3217#ifdef HAVE_RINGS
3218        pLmDelete(strat->P.lcm);
3219#else
3220        pLmFree(strat->P.lcm);
3221#endif
3222    }
3223
3224#ifdef KDEBUG
3225    if (TEST_OPT_DEBUG)
3226    {
3227      messageSets(strat);
3228    }
3229    memset(&(strat->P), 0, sizeof(strat->P));
3230#endif
3231    //kTest_TS(strat);: i_r out of sync in kInterRedBba, but not used!
3232  }
3233#ifdef KDEBUG
3234  //if (TEST_OPT_DEBUG) messageSets(strat);
3235#endif
3236  /* complete reduction of the standard basis--------- */
3237
3238  if((need_retry<=0) && (TEST_OPT_REDSB))
3239  {
3240    completeReduce(strat);
3241#ifdef HAVE_TAIL_RING
3242    if (strat->completeReduce_retry)
3243    {
3244      // completeReduce needed larger exponents, retry
3245      // to reduce with S (instead of T)
3246      // and in currRing (instead of strat->tailRing)
3247      cleanT(strat);strat->tailRing=currRing;
3248      int i;
3249      for(i=strat->sl;i>=0;i--) strat->S_2_R[i]=-1;
3250      completeReduce(strat);
3251    }
3252#endif
3253  }
3254  else if (TEST_OPT_PROT) PrintLn();
3255
3256  /* release temp data-------------------------------- */
3257  exitBuchMora(strat);
3258//  if (TEST_OPT_WEIGHTM)
3259//  {
3260//    pRestoreDegProcs(currRing,strat->pOrigFDeg, strat->pOrigLDeg);
3261//    if (ecartWeights)
3262//    {
3263//      omFreeSize((ADDRESS)ecartWeights,((currRing->N)+1)*sizeof(short));
3264//      ecartWeights=NULL;
3265//    }
3266//  }
3267  //if (TEST_OPT_PROT) messageStat(0/*hilbcount*/,strat);
3268  if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
3269  ideal res=strat->Shdl;
3270  strat->Shdl=NULL;
3271  delete strat;
3272  if (w!=NULL) delete w;
3273  return res;
3274}
3275ideal kInterRed (ideal F, ideal Q)
3276{
3277#ifdef HAVE_PLURAL
3278  if(rIsPluralRing(currRing)) return kInterRedOld(F,Q);
3279#endif
3280  if ((rHasLocalOrMixedOrdering(currRing))|| (rField_is_numeric(currRing))
3281  #ifdef HAVE_RINGS
3282  ||(rField_is_Ring(currRing))
3283  #endif
3284  )
3285    return kInterRedOld(F,Q);
3286
3287    //return kInterRedOld(F,Q);
3288
3289  BITSET save1;
3290  SI_SAVE_OPT1(save1);
3291  //si_opt_1|=Sy_bit(OPT_NOT_SUGAR);
3292  si_opt_1|=Sy_bit(OPT_REDTHROUGH);
3293  //si_opt_1&= ~Sy_bit(OPT_REDTAIL);
3294  //si_opt_1&= ~Sy_bit(OPT_REDSB);
3295  //extern char * showOption() ;
3296  //Print("%s\n",showOption());
3297
3298  int need_retry;
3299  int counter=3;
3300  ideal res, res1;
3301  int elems;
3302  ideal null=NULL;
3303  if ((Q==NULL) || (!TEST_OPT_REDSB))
3304  {
3305    elems=idElem(F);
3306    res=kInterRedBba(F,Q,need_retry);
3307  }
3308  else
3309  {
3310    ideal FF=idSimpleAdd(F,Q);
3311    res=kInterRedBba(FF,NULL,need_retry);
3312    idDelete(&FF);
3313    null=idInit(1,1);
3314    if (need_retry)
3315      res1=kNF(null,Q,res,0,KSTD_NF_LAZY);
3316    else
3317      res1=kNF(null,Q,res);
3318    idDelete(&res);
3319    res=res1;
3320    need_retry=1;
3321  }
3322  if (idElem(res)<=1) need_retry=0;
3323  while (need_retry && (counter>0))
3324  {
3325    #ifdef KDEBUG
3326    if (TEST_OPT_DEBUG) { Print("retry counter %d\n",counter); }
3327    #endif
3328    res1=kInterRedBba(res,Q,need_retry);
3329    int new_elems=idElem(res1);
3330    counter -= (new_elems >= elems);
3331    elems = new_elems;
3332    idDelete(&res);
3333    if (idElem(res1)<=1) need_retry=0;
3334    if ((Q!=NULL) && (TEST_OPT_REDSB))
3335    {
3336      if (need_retry)
3337        res=kNF(null,Q,res1,0,KSTD_NF_LAZY);
3338      else
3339        res=kNF(null,Q,res1);
3340      idDelete(&res1);
3341    }
3342    else
3343      res = res1;
3344    if (idElem(res)<=1) need_retry=0;
3345  }
3346  if (null!=NULL) idDelete(&null);
3347  SI_RESTORE_OPT1(save1);
3348  idSkipZeroes(res);
3349  return res;
3350}
3351
3352// returns TRUE if mora should use buckets, false otherwise
3353static BOOLEAN kMoraUseBucket(kStrategy strat)
3354{
3355#ifdef MORA_USE_BUCKETS
3356  if (TEST_OPT_NOT_BUCKETS)
3357    return FALSE;
3358  if (strat->red == redFirst)
3359  {
3360#ifdef NO_LDEG
3361    if (strat->syzComp==0)
3362      return TRUE;
3363#else
3364    if ((strat->homog || strat->honey) && (strat->syzComp==0))
3365      return TRUE;
3366#endif
3367  }
3368  else
3369  {
3370    assume(strat->red == redEcart || strat->red == redRiloc);
3371    if (strat->honey && (strat->syzComp==0))
3372      return TRUE;
3373  }
3374#endif
3375  return FALSE;
3376}
Note: See TracBrowser for help on using the repository browser.