source: git/kernel/syz1.cc @ 6a649d

fieker-DuValspielwiese
Last change on this file since 6a649d was 5be7db, checked in by Hans Schönemann <hannes@…>, 14 years ago
idrec -> idrec.h git-svn-id: file:///usr/local/Singular/svn/trunk@12707 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 69.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id$ */
5/*
6* ABSTRACT: resolutions
7*/
8
9#include "mod2.h"
10#include <mylimits.h>
11#include "options.h"
12#include "omalloc.h"
13#include "polys.h"
14#include "febase.h"
15#include "kstd1.h"
16#include "kutil.h"
17#include "stairc.h"
18//#include "cntrlc.h"
19#include "intvec.h"
20#include "numbers.h"
21#include "modulop.h"
22#include "ideals.h"
23#include "intvec.h"
24#include "ring.h"
25#include "syz.h"
26#include "kbuckets.h"
27#include "prCopy.h"
28#include "idrec.h"
29
30extern void p_Setm_Syz(poly p, ring r,
31                       int* Components, long* ShiftedComponents);
32
33/*--------------static variables------------------------*/
34/*---points to the real components, shifted of the actual module-*/
35int *  currcomponents=NULL;
36long *  currShiftedComponents=NULL;
37
38
39/*---head-term-polynomials for the reduction------------*/
40static poly redpol=NULL;
41/*---counts number of applications of GM-criteria-------*/
42//static int crit;
43//static int euler;
44
45/*3
46* deletes all entres of a pair
47*/
48void syDeletePair(SObject * so)
49{
50  pDelete(&(*so).p);
51  pDelete(&(*so).lcm);
52  pDelete(&(*so).syz);
53  (*so).p1 = NULL;
54  (*so).p2 = NULL;
55  (*so).ind1 = 0;
56  (*so).ind2 = 0;
57  (*so).syzind = -1;
58  (*so).order = 0;
59  (*so).isNotMinimal = NULL;
60  (*so).length = -1;
61  (*so).reference = -1;
62}
63
64/*3
65* initializes all entres of a pair
66*/
67void syInitializePair(SObject * so)
68{
69  (*so).p = NULL;
70  (*so).lcm = NULL;
71  (*so).syz = NULL;
72  (*so).p1 = NULL;
73  (*so).p2 = NULL;
74  (*so).ind1 = 0;
75  (*so).ind2 = 0;
76  (*so).syzind = -1;
77  (*so).order = 0;
78  (*so).isNotMinimal = NULL;
79  (*so).length = -1;
80  (*so).reference = -1;
81}
82
83/*3
84* puts all entres of a pair to another
85*/
86void syCopyPair(SObject * argso, SObject * imso)
87{
88  *imso=*argso;
89  (*argso).p = NULL;
90  (*argso).p1 = NULL;
91  (*argso).p2 = NULL;
92  (*argso).lcm = NULL;
93  (*argso).syz = NULL;
94  (*argso).ind1 = 0;
95  (*argso).ind2 = 0;
96  (*argso).syzind = -1;
97  (*argso).order = 0;
98  (*argso).isNotMinimal = NULL;
99  (*argso).length = -1;
100  (*argso).reference = -1;
101}
102
103/*3
104* deletes empty objects from a pair set beginning with
105* pair first
106* assumes a pair to be empty if .lcm does so
107*/
108void syCompactifyPairSet(SSet sPairs, int sPlength, int first)
109{
110  int k=first,kk=0;
111
112  while (k+kk<sPlength)
113  {
114    if (sPairs[k+kk].lcm!=NULL)
115    {
116      if (kk>0) syCopyPair(&sPairs[k+kk],&sPairs[k]);
117      k++;
118    }
119    else
120    {
121      kk++;
122    }
123  }
124  while (k<sPlength)
125  {
126    syInitializePair(&sPairs[k]);
127    k++;
128  }
129}
130
131/*3
132* deletes empty objects from a pair set beginning with
133* pair first
134* assumes a pair to be empty if .lcm does so
135*/
136void syCompactify1(SSet sPairs, int* sPlength, int first)
137{
138  int k=first,kk=0;
139
140  while (k+kk<*sPlength)
141  {
142    if (sPairs[k+kk].lcm!=NULL)
143    {
144      if (kk>0) syCopyPair(&sPairs[k+kk],&sPairs[k]);
145      k++;
146    }
147    else
148    {
149      kk++;
150    }
151  }
152  while (k<*sPlength)
153  {
154    syInitializePair(&sPairs[k]);
155    k++;
156  }
157  *sPlength -= kk;
158}
159
160/*3
161* replaces comp1dpc during homogeneous syzygy-computations
162* compares with components of currcomponents instead of the
163* exp[0]
164*/
165static int syzcomp0dpc(poly p1, poly p2)
166{
167  /*4 compare monomials by order then revlex*/
168    int i = pVariables;
169    if ((pGetExp(p1,i) == pGetExp(p2,i)))
170    {
171      do
172      {
173        i--;
174        if (i <= 1)
175        {
176           /*4 handle module case:*/
177           if (pGetComp(p1)==pGetComp(p2)) return 0;
178           else if
179              (currcomponents[pGetComp(p1)]>currcomponents[pGetComp(p2)])
180                return 1;
181           else return -1;
182        }
183      } while ((pGetExp(p1,i) == pGetExp(p2,i)));
184    }
185    if (pGetExp(p1,i) < pGetExp(p2,i)) return 1;
186    return -1;
187}
188
189/*3
190* replaces comp1dpc during homogeneous syzygy-computations
191* compares with components of currcomponents instead of the
192* exp[0]
193*/
194int syzcomp1dpc(poly p1, poly p2)
195{
196  int i = pVariables;
197  while ((i>1) && (pGetExp(p1,i)==pGetExp(p2,i)))
198    i--;
199  if (i>1)
200  {
201    if (pGetExp(p1,i) < pGetExp(p2,i)) return 1;
202    return -1;
203  }
204  int o1=pGetComp(p1);
205  int o2=pGetComp(p2);
206  if (o1==o2/*pGetComp(p1)==pGetComp(p2)*/) return 0;
207  if (currcomponents[o1]>currcomponents[o2]) return 1;
208  return -1;
209
210}
211
212/*3
213* replaces comp1dpc during homogeneous syzygy-computations
214* compares with components of currcomponents instead of the
215* exp[0]
216*/
217
218#ifdef PDEBUG
219static int syzcomp2dpc_test(poly p1, poly p2)
220{
221  long c1, c2, cc1, cc2, ccc1, ccc2, ec1, ec2;
222  c1 = pGetComp(p1);
223  c2 = pGetComp(p2);
224  cc1 = currcomponents[c1];
225  cc2 = currcomponents[c2];
226  ccc1 = currShiftedComponents[cc1];
227  ccc2 = currShiftedComponents[cc2];
228  ec1 = p1->exp[currRing->typ[1].data.syzcomp.place];
229  ec2 = p2->exp[currRing->typ[1].data.syzcomp.place];
230
231  if (ec1 != ccc1)
232  {
233    Warn("Shifted comp of p1 out of sync. should %d, is %d", ccc1, ec1);
234    //mmDBInfoBlock(p1);
235  }
236  if (ec2 != ccc2)
237  {
238    Warn("Shifted comp of p2 out of sync. should %d, is %d", ccc2, ec2);
239    //mmDBInfoBlock(p2);
240  }
241
242  if (c1 == c2)
243  {
244    assume(ccc1 == ccc2);
245  }
246  else if (cc1 > cc2)
247  {
248    assume(ccc1 > ccc2);
249  }
250  else
251  {
252    assume (cc1 < cc2);
253    assume (ccc1 < ccc2);
254  }
255  int o1=pGetOrder(p1), o2=pGetOrder(p2);
256  if (o1 > o2) return 1;
257  if (o1 < o2) return -1;
258
259  //if (o1>0)
260  {
261    int i = pVariables;
262    while ((i>1) && (pGetExp(p1,i)==pGetExp(p2,i)))
263      i--;
264    //(*orderingdepth)[pVariables-i]++;
265    if (i>1)
266    {
267      if (pGetExp(p1,i) < pGetExp(p2,i)) return 1;
268      return -1;
269    }
270  }
271  o1=pGetComp(p1);
272  o2=pGetComp(p2);
273  if (o1==o2/*pGetComp(p1)==pGetComp(p2)*/) return 0;
274  if (currcomponents[o1]>currcomponents[o2]) return 1;
275  return -1;
276}
277#endif // PDEBUG
278
279/*3
280* compares only the monomial without component
281*/
282static int syzcompmonomdp(poly p1, poly p2)
283{
284  int i;
285
286  /*4 compare monomials by order then revlex*/
287  if (pGetOrder(p1) == pGetOrder(p2))
288  {
289    i = pVariables;
290    if ((pGetExp(p1,i) == pGetExp(p2,i)))
291    {
292      do
293      {
294        i--;
295        if (i <= 1)
296          return 0;
297      } while ((pGetExp(p1,i) == pGetExp(p2,i)));
298    }
299    if (pGetExp(p1,i) < pGetExp(p2,i)) return 1;
300    return -1;
301  }
302  else if (pGetOrder(p1) > pGetOrder(p2)) return 1;
303  return -1;
304}
305
306poly syRedtail (poly p, syStrategy syzstr, int index)
307{
308  poly h, hn;
309  int j,pos;
310  ideal redWith=syzstr->orderedRes[index];
311
312  h = p;
313  hn = pNext(h);
314  while(hn != NULL)
315  {
316    j = syzstr->Firstelem[index-1][pGetComp(hn)]-1;
317    if (j>=0)
318    {
319      pos = j+syzstr->Howmuch[index-1][pGetComp(hn)];
320      while (j < pos)
321      {
322        if (pLmDivisibleByNoComp(redWith->m[j], hn))
323        {
324          //hn = sySPolyRed(hn,redWith->m[j]);
325          hn = ksOldSpolyRed(redWith->m[j],hn);
326          if (hn == NULL)
327          {
328            pNext(h) = NULL;
329            return p;
330          }
331          j = syzstr->Firstelem[index-1][pGetComp(hn)]-1;
332          pos = j+syzstr->Howmuch[index-1][pGetComp(hn)];
333        }
334        else
335        {
336          j++;
337        }
338      }
339    }
340    h = pNext(h) = hn;
341    hn = pNext(h);
342  }
343  return p;
344}
345
346
347/*3
348* local procedure for of syInitRes for the module case
349*/
350static int syChMin(intvec * iv)
351{
352  int i,j=-1,r=-1;
353
354  for (i=iv->length()-1;i>=0;i--)
355  {
356    if ((*iv)[i]>=0)
357    {
358      if ((j<0) || ((*iv)[i]<j))
359      {
360        j = (*iv)[i];
361        r = i;
362      }
363    }
364  }
365  return r;
366}
367
368/*3
369* initialize the resolution and puts in the argument as
370* zeroth entre, length must be > 0
371* assumes that the basering is degree-compatible
372*/
373SRes syInitRes(ideal arg,int * length, intvec * Tl, intvec * cw)
374{
375  if (idIs0(arg)) return NULL;
376  SRes resPairs = (SRes)omAlloc0(*length*sizeof(SSet));
377  resPairs[0] = (SSet)omAlloc0(IDELEMS(arg)*sizeof(SObject));
378  intvec * iv=NULL;
379  int i,j;
380
381  if (idRankFreeModule(arg)==0)
382  {
383    iv = idSort(arg);
384    for (i=0;i<IDELEMS(arg);i++)
385    {
386      (resPairs[0])[i].syz = /*pCopy*/(arg->m[(*iv)[i]-1]);
387      arg->m[(*iv)[i]-1] = NULL;
388      (resPairs[0])[i].order = pTotaldegree((resPairs[0])[i].syz);
389    }
390  }
391  else
392  {
393    iv = new intvec(IDELEMS(arg),1,-1);
394    for (i=0;i<IDELEMS(arg);i++)
395    {
396      (*iv)[i] = pTotaldegree(arg->m[i])+(*cw)[pGetComp(arg->m[i])-1];
397    }
398    for (i=0;i<IDELEMS(arg);i++)
399    {
400      j = syChMin(iv);
401      if (j<0) break;
402      (resPairs[0])[i].syz = arg->m[j];
403      arg->m[j] = NULL;
404      (resPairs[0])[i].order = (*iv)[j];
405      (*iv)[j] = -1;
406    }
407  }
408  if (iv!=NULL)  delete iv;
409  (*Tl)[0] = IDELEMS(arg);
410  return resPairs;
411}
412
413// rearrange shifted components
414long syReorderShiftedComponents(long * sc, int n)
415{
416  long holes = 0;
417  int i;
418  long new_comps = 0, new_space, max;
419
420  // count number of holes
421  for (i=1; i<n; i++)
422  {
423    if (sc[i-1] + 1 < sc[i]) holes++;
424  }
425
426  if (LONG_MAX - SYZ_SHIFT_BASE <= sc[n-1])
427  {
428    // need new components
429    new_comps = (((long) 1) << SYZ_SHIFT_MAX_NEW_COMP_ESTIMATE) - 1;
430    max = LONG_MAX;
431  }
432  else
433  {
434    max = sc[n-1] + SYZ_SHIFT_BASE;
435  }
436
437  // no we arrange things such that
438  // (n - holes) + holes*new_space + new_comps*SYZ_SHIFT_BASE= LONG_MAX
439  new_space = (max - n + holes - new_comps*SYZ_SHIFT_BASE) / holes;
440
441  assume(new_space < SYZ_SHIFT_BASE && new_space >= 4);
442
443  long* tc = ( long*) omAlloc(n*sizeof(long));
444  tc[0] = sc[0];
445  // rearrange things
446  for (i=1; i<n; i++)
447  {
448    if (sc[i-1] + 1 < sc[i])
449    {
450      tc[i] = tc[i-1] + new_space;
451    }
452    else
453    {
454      tc[i] = tc[i-1] + 1;
455    }
456    assume(tc[i] > tc[i-1]);
457  }
458
459  assume(LONG_MAX -  SYZ_SHIFT_BASE > tc[n-1]);
460#ifdef HAVE_ASSUME
461  for (i=1; i<n; i++)
462  {
463    assume(tc[i] >= 0);
464    assume(tc[i-1] + 1 <= tc[i]);
465  }
466#endif
467
468  omMemcpyW(sc, tc, n);
469  omFreeSize(tc, n*sizeof(long));
470  return new_space;
471}
472
473// this make a Setm on p
474static void pResetSetm(poly p)
475{
476#ifdef PDEBUG
477  poly q = p;
478#endif
479  while (p!= NULL)
480  {
481    pSetm(p);
482    pIter(p);
483  }
484#ifdef PDEBUG
485  pTest(q);
486#endif
487}
488
489void syResetShiftedComponents(syStrategy syzstr, int index,int hilb)
490{
491  assume(index > 0);
492  int i;
493  if (syzstr->res[index] != NULL)
494  {
495    long * prev_s;
496    int* prev_c;
497    int p_length;
498    rGetSComps(&prev_c, &prev_s, &p_length);
499    currcomponents = syzstr->truecomponents[index-1];
500    currShiftedComponents = syzstr->ShiftedComponents[index-1];
501    rChangeSComps(currcomponents,
502                  currShiftedComponents,
503                  IDELEMS(syzstr->res[index-1]));
504    if (hilb==0)
505    {
506      ideal id = syzstr->res[index];
507      for (i=0; i<IDELEMS(id); i++)
508      {
509        pResetSetm(id->m[i]);
510      }
511    }
512    else if (hilb==1)
513    {
514      assume (index>1);
515      assume (syzstr->resPairs[index-1]!=NULL);
516      SSet Pairs=syzstr->resPairs[index-1];
517      SSet Pairs1=syzstr->resPairs[index];
518      int till=(*syzstr->Tl)[index-1];
519      for (i=0;i<till;i++)
520      {
521        if (Pairs[i].syz!=NULL)
522          pResetSetm(Pairs[i].syz);
523      }
524      till=(*syzstr->Tl)[index];
525      for (i=0;i<till;i++)
526      {
527        if (Pairs1[i].p!=NULL)
528          pResetSetm(Pairs1[i].p);
529      }
530    }
531    currcomponents  = prev_c;
532    currShiftedComponents = prev_s;
533    rChangeSComps(prev_c, prev_s, p_length);
534  }
535}
536
537/*3
538* determines the place of a polynomial in the right ordered resolution
539* set the vectors of truecomponents
540*/
541static BOOLEAN syOrder(poly p,syStrategy syzstr,int index,
542                    int realcomp)
543{
544  int i=IDELEMS(syzstr->res[index-1])+1,j=0,k,tc,orc,ie=realcomp-1;
545  int *trind1=syzstr->truecomponents[index-1];
546  int *trind=syzstr->truecomponents[index];
547  long *shind=syzstr->ShiftedComponents[index];
548  int *bc=syzstr->backcomponents[index];
549  int *F1=syzstr->Firstelem[index-1];
550  int *H1=syzstr->Howmuch[index-1];
551  poly pp;
552  polyset o_r=syzstr->orderedRes[index]->m;
553  polyset or1=syzstr->orderedRes[index-1]->m;
554  BOOLEAN ret = FALSE;
555
556  // if != 0, then new element can go into same component
557  // i.e., we do not need to leave space in shifted components
558  long same_comp = 0;
559
560  if (p==NULL) return FALSE;
561  if (realcomp==0) realcomp=1;
562
563  if (index>1)
564    tc = trind1[pGetComp(p)]-1;
565  else
566    tc = pGetComp(p)-1;
567  loop         //while ((j<ie) && (trind1[orc]<=tc+1))
568  {
569    if (j>=ie)
570      break;
571    else
572    {
573      orc = pGetComp(o_r[j]);
574      if (trind1[orc]>tc+1) break;
575      else if (trind1[orc] == tc+1)
576      {
577        same_comp = 1;
578      }
579      else
580      {
581        assume(same_comp == 0);
582      }
583      j += H1[orc];
584    }
585  }
586  if (j>ie)
587  {
588    WerrorS("orderedRes to small");
589    return FALSE;
590  }
591  ie++;
592  if (j == (ie -1))
593  {
594    // new element is the last in ordered module
595    if (same_comp == 0)
596      same_comp = SYZ_SHIFT_BASE;
597
598    // test wheter we have enough space for new shifted component
599    if ((LONG_MAX - same_comp) <= shind[ie-1])
600    {
601      long new_space = syReorderShiftedComponents(shind, ie);
602      assume((LONG_MAX - same_comp) > shind[ie-1]);
603      ret = TRUE;
604      if (TEST_OPT_PROT) Print("(T%ld)", new_space);
605    }
606
607    // yes, then set new shifted component
608    assume(ie == 1 || shind[ie-1] > 0);
609    shind[ie] = shind[ie-1] + same_comp;
610  }
611  else
612  {
613    // new element must come in between
614    // i.e. at place j+1
615    long prev, next;
616
617    // test whether new component can get shifted value
618    prev = shind[j];
619    next = shind[j+1];
620    assume(next > prev);
621    if ((same_comp && prev + 2 >= next) || (!same_comp && next - prev < 4))
622    {
623       long new_space = syReorderShiftedComponents(shind, ie);
624      prev = shind[j];
625      next = shind[j+1];
626      assume((same_comp && prev + 2 < next) || (!same_comp && next - prev >= 4));
627      ret = TRUE;
628     if (TEST_OPT_PROT) Print("(B%ld)", new_space);
629    }
630
631    // make room for insertion of j+1 shifted component
632    for (k=ie; k > j+1; k--) shind[k] = shind[k-1];
633
634    if (same_comp)
635    {
636      // can simply add one
637      shind[j+1] = prev + 1;
638      assume(shind[j+1] + 1 < shind[j+2]);
639    }
640    else
641    {
642      // need to leave more breathing room - i.e. value goes in
643      // between
644      shind[j+1]  = prev + ((next - prev) >> 1);
645      assume (shind[j] + 1 < shind[j+1] && shind[j+1] + 1 < shind[j+2]);
646    }
647  }
648
649  if (o_r[j]!=NULL)
650  {
651    for (k=ie-1;k>j;k--)
652    {
653      o_r[k] = o_r[k-1];
654      bc[k] = bc[k-1];
655    }
656  }
657  o_r[j] = p;
658  bc[j] = realcomp-1;
659  (H1[pGetComp(p)])++;
660  for (k=0;k<i;k++)
661  {
662    if (F1[k]>j)
663      (F1[k])++;
664  }
665  if (F1[pGetComp(p)]==0)
666    F1[pGetComp(p)]=j+1;
667  for (k=0;k<IDELEMS((syzstr->res)[index]);k++)
668  {
669    if (trind[k]>j)
670      trind[k] += 1;
671  }
672  for (k=IDELEMS((syzstr->res)[index])-1;k>realcomp;k--)
673    trind[k] = trind[k-1];
674  trind[realcomp] = j+1;
675  return ret;
676}
677
678//#define OLD_PAIR_ORDER
679#ifdef OLD_PAIR_ORDER
680static intvec* syLinStrat(SSet nextPairs, syStrategy syzstr,
681                          int howmuch, int index)
682{
683  int i=howmuch-1,i1=0,l,ll;
684  int ** Fin=syzstr->Firstelem;
685  int ** Hin=syzstr->Howmuch;
686  int ** bin=syzstr->backcomponents;
687  ideal o_r=syzstr->orderedRes[index+1];
688  intvec *result=new intvec(howmuch+1);
689  BOOLEAN isDivisible;
690  SObject tso;
691
692  while (i>=0)
693  {
694    tso = nextPairs[i];
695    isDivisible = FALSE;
696    if (syzstr->res[index+1]!=NULL)
697    {
698      l = Fin[index][pGetComp(tso.lcm)]-1;
699      if (l>=0)
700      {
701        ll = l+Hin[index][pGetComp(tso.lcm)];
702        while ((l<ll) && (!isDivisible))
703        {
704          if (o_r->m[l]!=NULL)
705          {
706            isDivisible = isDivisible ||
707              pLmDivisibleByNoComp(o_r->m[l],tso.lcm);
708          }
709          l++;
710        }
711      }
712    }
713    if (isDivisible)
714    {
715      syDeletePair(&nextPairs[i]);
716      //crit++;
717    }
718    else
719    {
720      nextPairs[i].p =
721        //sySPoly(tso.p1, tso.p2,tso.lcm);
722        spSpolyCreate(tso.p2, tso.p1,NULL,spSpolyLoop_General);
723      (*result)[i1] = i+1;
724      i1++;
725    }
726    i--;
727  }
728  return result;
729}
730#else
731static intvec* syLinStrat(SSet nextPairs, syStrategy syzstr,
732                          int howmuch, int index)
733{
734  int i=howmuch-1,i1=0,i2,i3,l,ll;
735  int ** Fin=syzstr->Firstelem;
736  int ** Hin=syzstr->Howmuch;
737  int ** bin=syzstr->backcomponents;
738  ideal o_r=syzstr->orderedRes[index+1];
739  intvec *result=new intvec(howmuch+1);
740  intvec *spl=new intvec(howmuch,1,-1);
741  BOOLEAN isDivisible;
742  SObject tso;
743
744  while (i>=0)
745  {
746    tso = nextPairs[i];
747    isDivisible = FALSE;
748    if (syzstr->res[index+1]!=NULL)
749    {
750      l = Fin[index][pGetComp(tso.lcm)]-1;
751      if (l>=0)
752      {
753        ll = l+Hin[index][pGetComp(tso.lcm)];
754        while ((l<ll) && (!isDivisible))
755        {
756          if (o_r->m[l]!=NULL)
757          {
758            isDivisible = isDivisible ||
759              pLmDivisibleByNoComp(o_r->m[l],tso.lcm);
760          }
761          l++;
762        }
763      }
764    }
765    if (isDivisible)
766    {
767      syDeletePair(&nextPairs[i]);
768      //crit++;
769    }
770    else
771    {
772      pTest(tso.p2);
773      pTest(tso.p1);
774      nextPairs[i].p =
775        ksOldCreateSpoly(tso.p2, tso.p1,NULL);
776      (*spl)[i] = pLength(nextPairs[i].p);
777    }
778    i--;
779  }
780  i3 = 0;
781  loop
782  {
783    i2 = -1;
784    for (i1=0;i1<howmuch;i1++)
785    {
786      if (i2==-1)
787      {
788        if ((*spl)[i1]!=-1)
789        {
790          i2 = i1;
791        }
792      }
793      else
794      {
795        if (((*spl)[i1]>=0) && ((*spl)[i1]<(*spl)[i2]))
796        {
797          i2 = i1;
798        }
799      }
800    }
801    if (i2>=0)
802    {
803      (*result)[i3] = i2+1;
804      (*spl)[i2] = -1;
805      i3++;
806    }
807    else
808    {
809      break;
810    }
811  }
812  delete spl;
813  return result;
814}
815#endif
816
817void syEnlargeFields(syStrategy syzstr,int index)
818{
819  pEnlargeSet(&(syzstr->res[index]->m),IDELEMS(syzstr->res[index]),16);
820  syzstr->truecomponents[index]=(int*)omRealloc0Size((ADDRESS)syzstr->truecomponents[index],
821                               (IDELEMS(syzstr->res[index])+1)*sizeof(int),
822                               (IDELEMS(syzstr->res[index])+17)*sizeof(int));
823  syzstr->ShiftedComponents[index]
824    =(long*)omRealloc0Size((ADDRESS)syzstr->ShiftedComponents[index],
825                              (IDELEMS(syzstr->res[index])+1)*sizeof(long),
826                              (IDELEMS(syzstr->res[index])+17)*sizeof(long));
827  syzstr->backcomponents[index]=(int*)omRealloc0Size((ADDRESS)syzstr->backcomponents[index],
828                               (IDELEMS(syzstr->res[index])+1)*sizeof(int),
829                               (IDELEMS(syzstr->res[index])+17)*sizeof(int));
830  syzstr->Howmuch[index]=(int*)omRealloc0Size((ADDRESS)syzstr->Howmuch[index],
831                               (IDELEMS(syzstr->res[index])+1)*sizeof(int),
832                               (IDELEMS(syzstr->res[index])+17)*sizeof(int));
833  syzstr->Firstelem[index]=(int*)omRealloc0Size((ADDRESS)syzstr->Firstelem[index],
834                               (IDELEMS(syzstr->res[index])+1)*sizeof(int),
835                               (IDELEMS(syzstr->res[index])+17)*sizeof(int));
836  syzstr->elemLength[index]=(int*)omRealloc0Size((ADDRESS)syzstr->elemLength[index],
837                               (IDELEMS(syzstr->res[index])+1)*sizeof(int),
838                               (IDELEMS(syzstr->res[index])+17)*sizeof(int));
839  syzstr->sev[index]=(unsigned long*)omRealloc0Size((ADDRESS)syzstr->sev[index],
840                                    (IDELEMS(syzstr->res[index])+1)*sizeof(unsigned long),
841                               (IDELEMS(syzstr->res[index])+17)*sizeof(unsigned long));
842  IDELEMS(syzstr->res[index]) += 16;
843  pEnlargeSet(&(syzstr->orderedRes[index]->m),IDELEMS(syzstr->orderedRes[index]),16);
844  IDELEMS(syzstr->orderedRes[index]) += 16;
845}
846/*3
847* reduces all pairs of degree deg in the module index
848* put the reduced generators to the resolvente which contains
849* the truncated kStd
850*/
851static void syRedNextPairs(SSet nextPairs, syStrategy syzstr,
852               int howmuch, int index)
853{
854  int i,j,k=IDELEMS(syzstr->res[index]);
855  int ks=IDELEMS(syzstr->res[index+1]),kk,l,ll;
856  int * Fin=syzstr->Firstelem[index-1];
857  int * Hin=syzstr->Howmuch[index-1];
858  int * bin=syzstr->backcomponents[index];
859  int * elL=syzstr->elemLength[index];
860  number coefgcd,n;
861  polyset redset=syzstr->orderedRes[index]->m;
862  poly p=NULL,q;
863  intvec *spl1;
864  SObject tso;
865  long * ShiftedComponents = syzstr->ShiftedComponents[index];
866  int* Components = syzstr->truecomponents[index];
867  assume(Components != NULL && ShiftedComponents != NULL);
868  BOOLEAN need_reset;
869
870  if ((nextPairs==NULL) || (howmuch==0)) return;
871  while ((k>0) && (syzstr->res[index]->m[k-1]==NULL)) k--;
872  while ((ks>0) && (syzstr->res[index+1]->m[ks-1]==NULL)) ks--;
873  spl1 = syLinStrat(nextPairs,syzstr,howmuch,index);
874  i=0;
875  while ((*spl1)[i]>0)
876  {
877    need_reset = FALSE;
878    tso = nextPairs[(*spl1)[i]-1];
879    if ((tso.p1!=NULL) && (tso.p2!=NULL))
880    {
881      nNormalize(pGetCoeff(tso.p1));
882      nNormalize(pGetCoeff(tso.p2));
883      coefgcd =
884        nGcd(pGetCoeff(tso.p1),pGetCoeff(tso.p2),currRing);
885      tso.syz = pHead(tso.lcm);
886      p = tso.syz;
887      pSetCoeff(p,nDiv(pGetCoeff(tso.p1),coefgcd));
888      pGetCoeff(p) = nNeg(pGetCoeff(p));
889      pSetComp(p,tso.ind2+1);
890      p_Setm_Syz(p, currRing, Components, ShiftedComponents); // actueller index
891      pNext(p) = pHead(tso.lcm);
892      pIter(p);
893      pSetComp(p,tso.ind1+1);
894      p_Setm_Syz(p, currRing, Components, ShiftedComponents); // actueller index
895      pSetCoeff(p,nDiv(pGetCoeff(tso.p2),coefgcd));
896      nDelete(&coefgcd);
897      if (tso.p != NULL)
898      {
899        kBucketInit(syzstr->bucket,tso.p,-1);
900        q = kBucketGetLm(syzstr->bucket);
901        j = Fin[pGetComp(q)]-1;
902        int pos = j+Hin[pGetComp(q)];
903        loop
904        {
905          if (j<0) break;
906          if (pLmDivisibleByNoComp(redset[j],q))
907          {
908            pNext(p) = pHead(q);
909            pIter(p);
910            pSetComp(p,bin[j]+1);
911            p_Setm_Syz(p, currRing, Components, ShiftedComponents); // actueller index
912//if (pLength(redset[j])!=syzstr->elemLength[index][bin[j]])
913//Print("Halt");
914//if (pLength(redset[j])!=syzstr->elemLength[index][bin[j]])
915//Print("Halt");
916            pGetCoeff(p) = nNeg(pGetCoeff(p));
917            number up = kBucketPolyRed(syzstr->bucket,redset[j],elL[bin[j]],
918                                       NULL);
919            // Thomas: Check whether you need number here
920            nDelete(&up);
921            q = kBucketGetLm(syzstr->bucket);
922            if (q==NULL) break;
923            j = Fin[pGetComp(q)]-1;
924            pos = j+Hin[pGetComp(q)];
925          }
926          else
927          {
928            j++;
929            if (j==pos) break;
930          }
931        }
932        int lb;
933        kBucketClear(syzstr->bucket,&tso.p,&lb);
934      }
935      if (tso.p != NULL)
936      {
937        if (TEST_OPT_PROT) PrintS("g");
938        if (k==IDELEMS((syzstr->res)[index]))
939        {
940          syEnlargeFields(syzstr,index);
941          bin=syzstr->backcomponents[index];
942          elL=syzstr->elemLength[index];
943          redset=syzstr->orderedRes[index]->m;
944          Components = syzstr->truecomponents[index];
945          ShiftedComponents = syzstr->ShiftedComponents[index];
946        }
947        pNext(p) = pHead(tso.p);
948        pIter(p);
949
950        assume(p!= NULL);
951        k++;
952        syzstr->res[index]->m[k-1] = tso.p;
953        syzstr->elemLength[index][k-1] = pLength(tso.p);
954        pNorm(syzstr->res[index]->m[k-1]);
955        need_reset = syOrder(syzstr->res[index]->m[k-1],syzstr,index,k);
956        pSetComp(p,k); // actueller index
957        p_Setm_Syz(p, currRing, Components, ShiftedComponents);
958        pGetCoeff(p) = nNeg(pGetCoeff(p));
959
960        tso.isNotMinimal = p;
961        tso.p = NULL;
962      }
963      else
964      {
965        if (TEST_OPT_PROT) PrintS(".");
966        //if (index % 2==0)
967          //euler++;
968        //else
969          //euler--;
970      }
971      if (ks==IDELEMS(syzstr->res[index+1]))
972      {
973        syEnlargeFields(syzstr,index+1);
974      }
975      syzstr->res[index+1]->m[ks] = tso.syz;
976      syzstr->elemLength[index+1][ks] = pLength(tso.syz);
977      pNorm(syzstr->res[index+1]->m[ks]);
978      tso.syz =NULL;
979      tso.syzind = ks;
980      if (need_reset)
981        syResetShiftedComponents(syzstr, index+1);
982      if (syOrder(syzstr->res[index+1]->m[ks],syzstr,index+1,ks+1))
983         syResetShiftedComponents(syzstr, index+2);
984      ks++;
985      p = NULL;
986      nextPairs[(*spl1)[i]-1] = tso;
987    }
988    i++;
989  }
990  delete spl1;
991}
992
993/*3
994* reduces the generators of the module index in degree deg
995* (which are actual syzygies of the module index-1)
996* wrt. the ideal generated by elements of lower degrees
997*/
998static void syRedGenerOfCurrDeg(syStrategy syzstr, int deg, int index)
999{
1000  ideal res=syzstr->res[index];
1001  int i=0,j,k=IDELEMS(res),kk;
1002  SSet sPairs=syzstr->resPairs[index-1];
1003
1004  while ((k>0) && (res->m[k-1]==NULL)) k--;
1005  while ((i<(*syzstr->Tl)[index-1]) && (((sPairs)[i].syz==NULL) ||
1006          ((sPairs)[i].order<deg)))
1007    i++;
1008  if ((i>=(*syzstr->Tl)[index-1]) || ((sPairs)[i].order>deg)) return;
1009  while ((i<(*syzstr->Tl)[index-1]) && (((sPairs)[i].syz==NULL) ||
1010         ((sPairs)[i].order==deg)))
1011  {
1012    if ((sPairs)[i].syz!=NULL)
1013    {
1014      j = k-1;
1015      while ((j>=0) && (res->m[j]!=NULL) &&
1016             ((sPairs)[i].syz!=NULL))
1017      {
1018        if (pLmDivisibleBy(res->m[j],(sPairs)[i].syz))
1019        {
1020          (sPairs)[i].syz =
1021            ksOldSpolyRed(res->m[j],(sPairs)[i].syz);
1022            //sySPolyRed((sPairs)[i].syz,res->m[j]);
1023          j = k-1;
1024        }
1025        else
1026        {
1027          j--;
1028        }
1029      }
1030      if ((sPairs)[i].syz != NULL)
1031      {
1032        if (k==IDELEMS(res))
1033        {
1034          syEnlargeFields(syzstr,index);
1035          res=syzstr->res[index];
1036        }
1037        if (TEST_OPT_DEBUG)
1038        {
1039          if ((sPairs)[i].isNotMinimal==NULL)
1040          {
1041            PrintLn();
1042            PrintS("minimal generator: ");pWrite((syzstr->resPairs[index-1])[i].syz);
1043            PrintS("comes from: ");pWrite((syzstr->resPairs[index-1])[i].p1);
1044            PrintS("and: ");pWrite((syzstr->resPairs[index-1])[i].p2);
1045          }
1046        }
1047        //res->m[k] = (sPairs)[i].syz;
1048        res->m[k] = syRedtail((sPairs)[i].syz,syzstr,index);
1049        (sPairs)[i].syzind = k;
1050        syzstr->elemLength[index][k] = pLength((sPairs)[i].syz);
1051        pNorm(res->m[k]);
1052  //      (sPairs)[i].syz = NULL;
1053        k++;
1054        if (syOrder(res->m[k-1],syzstr,index,k))
1055          syResetShiftedComponents(syzstr, index);
1056        //euler++;
1057      }
1058      else
1059        (sPairs)[i].syzind = -1;
1060    }
1061    i++;
1062  }
1063}
1064
1065/*3
1066* puts a pair into the right place in resPairs
1067*/
1068void syEnterPair(SSet sPairs, SObject * so, int * sPlength,int index)
1069{
1070  int ll,k,no=(*so).order,sP=*sPlength,i;
1071  poly p=(*so).lcm;
1072
1073  if ((sP==0) || (sPairs[sP-1].order<=no))
1074    ll = sP;
1075  else if (sP==1)
1076    ll = 0;
1077  else
1078  {
1079    int an=0,en=sP-1;
1080    loop
1081    {
1082      if (an>=en-1)
1083      {
1084        if ((sPairs[an].order<=no) && (sPairs[an+1].order>no))
1085        {
1086          ll = an+1;
1087          break;
1088        }
1089        else if ((sPairs[en].order<=no) && (sPairs[en+1].order>no))
1090        {
1091          ll = en+1;
1092          break;
1093        }
1094        else if (sPairs[an].order>no)
1095        {
1096          ll = an;
1097          break;
1098        }
1099        else
1100        {
1101          PrintS("Hier ist was faul!\n");
1102          break;
1103        }
1104      }
1105      i=(an+en) / 2;
1106      if (sPairs[i].order <= no)
1107        an=i;
1108      else
1109        en=i;
1110    }
1111  }
1112  for (k=(*sPlength);k>ll;k--)
1113  {
1114    syCopyPair(&sPairs[k-1],&sPairs[k]);
1115  }
1116  syCopyPair(so,&sPairs[ll]);
1117  (*sPlength)++;
1118}
1119void syEnterPair(syStrategy syzstr, SObject * so, int * sPlength,int index)
1120{
1121  int ll;
1122
1123  if (*sPlength>=(*syzstr->Tl)[index])
1124  {
1125    SSet temp = (SSet)omAlloc0(((*syzstr->Tl)[index]+16)*sizeof(SObject));
1126    for (ll=0;ll<(*syzstr->Tl)[index];ll++)
1127    {
1128      temp[ll].p = (syzstr->resPairs[index])[ll].p;
1129      temp[ll].p1 = (syzstr->resPairs[index])[ll].p1;
1130      temp[ll].p2 = (syzstr->resPairs[index])[ll].p2;
1131      temp[ll].syz = (syzstr->resPairs[index])[ll].syz;
1132      temp[ll].lcm = (syzstr->resPairs[index])[ll].lcm;
1133      temp[ll].ind1 = (syzstr->resPairs[index])[ll].ind1;
1134      temp[ll].ind2 = (syzstr->resPairs[index])[ll].ind2;
1135      temp[ll].syzind = (syzstr->resPairs[index])[ll].syzind;
1136      temp[ll].order = (syzstr->resPairs[index])[ll].order;
1137      temp[ll].isNotMinimal = (syzstr->resPairs[index])[ll].isNotMinimal;
1138      temp[ll].length = (syzstr->resPairs[index])[ll].length;
1139      temp[ll].reference = (syzstr->resPairs[index])[ll].reference;
1140    }
1141    if (syzstr->resPairs[index] != NULL) // OB: ?????
1142      omFreeSize((ADDRESS)syzstr->resPairs[index],(*syzstr->Tl)[index]*sizeof(SObject));
1143    (*syzstr->Tl)[index] += 16;
1144    syzstr->resPairs[index] = temp;
1145  }
1146  syEnterPair(syzstr->resPairs[index],so,sPlength,index);
1147}
1148
1149/*3
1150* computes pairs from the new elements (beginning with the element newEl)
1151* in the module index
1152*/
1153static void syCreateNewPairs(syStrategy syzstr, int index, int newEl)
1154{
1155  SSet temp;
1156  SObject tso;
1157  int i,ii,j,k=IDELEMS(syzstr->res[index]),l=(*syzstr->Tl)[index],ll;
1158  int qc,first,pos,jj,j1;
1159  int * bci=syzstr->backcomponents[index];
1160  poly p,q;
1161  polyset rs=syzstr->res[index]->m,nPm;
1162
1163
1164  while ((k>0) && (rs[k-1]==NULL)) k--;
1165  if (newEl>=k) return;
1166
1167  long * ShiftedComponents = syzstr->ShiftedComponents[index];
1168  int* Components = syzstr->truecomponents[index];
1169
1170  ideal nP=idInit(k,syzstr->res[index]->rank);
1171  nPm=nP->m;
1172  while ((l>0) && ((syzstr->resPairs[index])[l-1].p1==NULL)) l--;
1173  for (j=newEl;j<k;j++)
1174  {
1175    q = rs[j];
1176    qc = pGetComp(q);
1177    first = syzstr->Firstelem[index-1][pGetComp(q)]-1;
1178    pos = first+syzstr->Howmuch[index-1][pGetComp(q)];
1179    for (i=first;i<pos;i++)
1180    {
1181      jj = bci[i];
1182      if (jj>=j) break;
1183      p = pOne();
1184      pLcm(rs[jj],q,p);
1185      pSetComp(p,j+1);
1186      p_Setm_Syz(p, currRing, Components, ShiftedComponents);
1187      ii = first;
1188      loop
1189      {
1190        j1 = bci[ii];
1191        if (nPm[j1]!=NULL)
1192        {
1193          if (pLmDivisibleByNoComp(nPm[j1],p))
1194          {
1195            pDelete(&p);
1196            break;
1197          }
1198          else if (pLmDivisibleByNoComp(p,nPm[j1]))
1199          {
1200            pDelete(&(nPm[j1]));
1201            //break;
1202          }
1203        }
1204        ii++;
1205        if (ii>=pos) break;
1206      }
1207      if (p!=NULL)
1208      {
1209        nPm[jj] = p;
1210      }
1211    }
1212    for (i=first;i<pos;i++)
1213    {
1214      ii = bci[i];
1215      if (nPm[ii]!=NULL)
1216      {
1217        if (l>=(*syzstr->Tl)[index])
1218        {
1219          temp = (SSet)omAlloc0(((*syzstr->Tl)[index]+16)*sizeof(SObject));
1220          for (ll=0;ll<(*syzstr->Tl)[index];ll++)
1221          {
1222            temp[ll].p = (syzstr->resPairs[index])[ll].p;
1223            temp[ll].p1 = (syzstr->resPairs[index])[ll].p1;
1224            temp[ll].p2 = (syzstr->resPairs[index])[ll].p2;
1225            temp[ll].syz = (syzstr->resPairs[index])[ll].syz;
1226            temp[ll].lcm = (syzstr->resPairs[index])[ll].lcm;
1227            temp[ll].ind1 = (syzstr->resPairs[index])[ll].ind1;
1228            temp[ll].ind2 = (syzstr->resPairs[index])[ll].ind2;
1229            temp[ll].syzind = (syzstr->resPairs[index])[ll].syzind;
1230            temp[ll].order = (syzstr->resPairs[index])[ll].order;
1231            temp[ll].isNotMinimal = (syzstr->resPairs[index])[ll].isNotMinimal;
1232          }
1233          if (syzstr->resPairs[index] != NULL) // OB: ????
1234            omFreeSize((ADDRESS)syzstr->resPairs[index],(*syzstr->Tl)[index]*sizeof(SObject));
1235          (*syzstr->Tl)[index] += 16;
1236          syzstr->resPairs[index] = temp;
1237        }
1238        tso.lcm = p = nPm[ii];
1239        nPm[ii] = NULL;
1240        //#ifdef HAVE_SHIFTED_EXPONENTS
1241        //tso.order = pTotaldegree(p);
1242        //p->exp[currRing->pOrdIndex]=tso.order+0x40000000;
1243        //#else
1244        tso.order = pTotaldegree(p);
1245        pSetOrder(p, tso.order);
1246        //#endif
1247        if ((syzstr->cw!=NULL) && (index>0) && (pGetComp(q)>0))
1248        {
1249          int ii=index-1,jj=pGetComp(q);
1250          while (ii>0)
1251          {
1252            jj = pGetComp(syzstr->res[ii]->m[jj-1]);
1253            ii--;
1254          }
1255          tso.order += (*syzstr->cw)[jj-1];
1256        }
1257        tso.p1 = rs[ii];
1258        tso.p2 = q;
1259        tso.ind1 = ii;
1260        tso.ind2 = j;
1261        tso.syzind = -1;
1262        tso.isNotMinimal = NULL;
1263        tso.p = NULL;
1264        tso.syz = NULL;
1265        syEnterPair(syzstr->resPairs[index],&tso,&l,index);
1266      }
1267    }
1268  }
1269  idDelete(&nP);
1270}
1271
1272static SSet syChosePairsPutIn(syStrategy syzstr, int *index,
1273               int *howmuch, int * actdeg, int an, int en)
1274{
1275  int newdeg=*actdeg,newindex=-1,i,t,sldeg;
1276  poly p;
1277  SSet result;
1278  SRes resPairs=syzstr->resPairs;
1279
1280  if (an>syzstr->length) return NULL;
1281  if (en>syzstr->length) en=syzstr->length;
1282  while (*index<en)
1283  {
1284    if (resPairs[*index]!=NULL)
1285    {
1286      sldeg = (*actdeg)+*index;
1287      i = 0;
1288      if (*index!=0)
1289      {
1290        while ((i<(*syzstr->Tl)[*index]))
1291        {
1292          if ((resPairs[*index])[i].lcm!=NULL)
1293          {
1294            if ((resPairs[*index])[i].order == sldeg)
1295            {
1296              result = &(resPairs[*index])[i];
1297              *howmuch =1;
1298              i++;
1299              while ((i<(*syzstr->Tl)[*index]) && ((resPairs[*index])[i].lcm!=NULL)
1300                      && ((resPairs[*index])[i].order == sldeg))
1301              {
1302                i++;
1303                (*howmuch)++;
1304              }
1305              return result;
1306            }
1307          }
1308          i++;
1309        }
1310      }
1311      else
1312      {
1313        while ((i<(*syzstr->Tl)[*index]))
1314        {
1315          if ((resPairs[*index])[i].syz!=NULL)
1316          {
1317            if ((resPairs[*index])[i].order == sldeg)
1318            {
1319              result = &(resPairs[*index])[i];
1320              (*howmuch) =1;
1321              i++;
1322              while ((i<(*syzstr->Tl)[*index]) && ((resPairs[*index])[i].syz!=NULL)
1323                      && ((resPairs[*index])[i].order == *actdeg))
1324              {
1325                i++;
1326                (*howmuch)++;
1327              }
1328              return result;
1329            }
1330          }
1331          i++;
1332        }
1333      }
1334    }
1335    (*index)++;
1336  }
1337  *index = an;
1338  //if (TEST_OPT_PROT) Print("(Euler:%d)",euler);
1339  while (*index<en)
1340  {
1341    if (resPairs[*index]!=NULL)
1342    {
1343      i = 0;
1344      while ((i<(*syzstr->Tl)[*index]))
1345      {
1346        t = *actdeg+*index;
1347        if (((resPairs[*index])[i].lcm!=NULL) ||
1348              ((resPairs[*index])[i].syz!=NULL))
1349        {
1350          if ((resPairs[*index])[i].order > t)
1351            t = (resPairs[*index])[i].order;
1352        }
1353        if ((t>*actdeg+*index) && ((newdeg==*actdeg) || (t<newdeg+*index)))
1354        {
1355          newdeg = t-*index;
1356          newindex = *index;
1357          break;
1358        }
1359        i++;
1360      }
1361    }
1362    (*index)++;
1363  }
1364  if (newdeg>*actdeg)
1365  {
1366    *actdeg = newdeg;
1367    *index = newindex;
1368    return syChosePairsPutIn(syzstr,index,howmuch,actdeg,an,en);
1369  }
1370  else return NULL;
1371}
1372
1373/*3
1374* FOR THE HOMOGENEOUS CASE ONLY!
1375* looks through the pair set and the given module for
1376* remaining pairs or generators to consider
1377* returns a pointer to the first pair and the number of them in the given module
1378* works with slanted degree (i.e. deg=realdeg-index)
1379*/
1380SSet syChosePairs(syStrategy syzstr, int *index, int *howmuch, int * actdeg)
1381{
1382  return syChosePairsPutIn(syzstr,index,howmuch,actdeg,0,syzstr->length);
1383}
1384
1385/*3
1386* FOR THE INHOMOGENEOUS CASE ONLY!
1387* looks through the pair set and the given module for
1388* remaining pairs or generators to consider
1389* returns a pointer to the first pair and the number of them in the given module
1390* works with slanted degree (i.e. deg=realdeg-index)
1391* looks first through the 0 and 1 module then through the other
1392*/
1393static SSet syChosePairsIH(syStrategy syzstr, int *index,
1394               int *howmuch, int * actdeg, int mindeg)
1395{
1396  SSet result=NULL;
1397
1398  result = syChosePairsPutIn(syzstr,index,howmuch,actdeg,0,2);
1399  if (result == NULL)
1400  {
1401    *actdeg = mindeg;
1402    result = syChosePairsPutIn(syzstr,index,howmuch,actdeg,2,syzstr->length);
1403  }
1404  return result;
1405}
1406
1407/*3
1408* looks through the pair set and the given module for
1409* remaining pairs or generators to consider
1410* returns a pointer to the first pair and the number of them in the given module
1411* works deg by deg
1412*/
1413/*
1414*static SSet syChosePairs1(SRes resPairs,intvec * Tl, int *index, int *howmuch,
1415*                   int length,int * actdeg)
1416*{
1417*  int newdeg=*actdeg,newindex=-1,i,t;
1418*  SSet result;
1419*
1420*  while (*index>=0)
1421*  {
1422*    if (resPairs[*index]!=NULL)
1423*    {
1424*      i = 0;
1425*      if (*index!=0)
1426*      {
1427*        while ((i<(*Tl)[*index]))
1428*        {
1429*          if ((resPairs[*index])[i].lcm!=NULL)
1430*          {
1431*            if (pGetOrder((resPairs[*index])[i].lcm) == *actdeg)
1432*            {
1433*              result = &(resPairs[*index])[i];
1434*              *howmuch =1;
1435*              i++;
1436*              while ((i<(*Tl)[*index]) && ((resPairs[*index])[i].lcm!=NULL)
1437*                      && (pGetOrder((resPairs[*index])[i].lcm) == *actdeg))
1438*              {
1439*                i++;
1440*                (*howmuch)++;
1441*              }
1442*              return result;
1443*            }
1444*          }
1445*          i++;
1446*        }
1447*      }
1448*      else
1449*      {
1450*        while ((i<(*Tl)[*index]))
1451*        {
1452*          if ((resPairs[*index])[i].syz!=NULL)
1453*          {
1454*            if ((resPairs[*index])[i].order == *actdeg)
1455*            {
1456*              result = &(resPairs[*index])[i];
1457*              (*howmuch) =1;
1458*              i++;
1459*              while ((i<(*Tl)[*index]) && ((resPairs[*index])[i].syz!=NULL)
1460*                      && ((resPairs[*index])[i].order == *actdeg))
1461*              {
1462*                i++;
1463*                (*howmuch)++;
1464*              }
1465*              return result;
1466*            }
1467*          }
1468*          i++;
1469*        }
1470*      }
1471*    }
1472*    (*index)--;
1473*  }
1474*  *index = length-1;
1475*  while (*index>=0)
1476*  {
1477*    if (resPairs[*index]!=NULL)
1478*    {
1479*      i = 0;
1480*      while ((i<(*Tl)[*index]))
1481*      {
1482*        t = *actdeg;
1483*        if ((resPairs[*index])[i].lcm!=NULL)
1484*        {
1485*          if (pGetOrder((resPairs[*index])[i].lcm) > *actdeg)
1486*            t = pGetOrder((resPairs[*index])[i].lcm);
1487*        }
1488*        else if ((resPairs[*index])[i].syz!=NULL)
1489*        {
1490*          if ((resPairs[*index])[i].order > *actdeg)
1491*            t = (resPairs[*index])[i].order;
1492*        }
1493*        if ((t>*actdeg) && ((newdeg==*actdeg) || (t<newdeg)))
1494*        {
1495*          newdeg = t;
1496*          newindex = *index;
1497*          break;
1498*        }
1499*        i++;
1500*      }
1501*    }
1502*    (*index)--;
1503*  }
1504*  if (newdeg>*actdeg)
1505*  {
1506*    *actdeg = newdeg;
1507*    *index = newindex;
1508*    return syChosePairs1(resPairs,Tl,index,howmuch,length,actdeg);
1509*  }
1510*  else return NULL;
1511*}
1512*/
1513/*3
1514* statistics of the resolution
1515*/
1516static void syStatistics(resolvente res,int length)
1517{
1518  int i,j=1,k;
1519  long deg = 0;
1520
1521  PrintLn();
1522  while ((j<length) && (res[j]!=NULL))
1523  {
1524    Print("In module %d: \n",j);
1525    k = 0;
1526    while ((k<IDELEMS(res[j])) && (res[j]->m[k]!=NULL))
1527    {
1528      i = 1;
1529      deg = pGetOrder(res[j]->m[k]);
1530      k++;
1531      while ((k<IDELEMS(res[j])) && (res[j]->m[k]!=NULL) &&
1532              (pGetOrder(res[j]->m[k])==deg))
1533      {
1534        i++;
1535        k++;
1536      }
1537      Print("%d elements of degree %ld\n",i,deg);
1538    }
1539    j++;
1540  }
1541}
1542
1543/*3
1544* initialize a module
1545*/
1546int syInitSyzMod(syStrategy syzstr, int index, int init)
1547{
1548  int result;
1549
1550  if (syzstr->res[index]==NULL)
1551  {
1552    syzstr->res[index] = idInit(init-1,1);
1553    syzstr->truecomponents[index] = (int*)omAlloc0(init*sizeof(int));
1554    syzstr->ShiftedComponents[index] = (long*)omAlloc0(init*sizeof(long));
1555    if (index==0)
1556    {
1557      for (int i=0;i<init;i++)
1558      {
1559        syzstr->truecomponents[0][i] = i;
1560        syzstr->ShiftedComponents[0][i] = (i)*SYZ_SHIFT_BASE;
1561      }
1562    }
1563    syzstr->backcomponents[index] = (int*)omAlloc0(init*sizeof(int));
1564    syzstr->Howmuch[index] = (int*)omAlloc0(init*sizeof(int));
1565    syzstr->Firstelem[index] = (int*)omAlloc0(init*sizeof(int));
1566    syzstr->elemLength[index] = (int*)omAlloc0(init*sizeof(int));
1567    syzstr->orderedRes[index] = idInit(init-1,1);
1568    syzstr->sev[index] = (unsigned long*) omAlloc0(init*sizeof(unsigned long));
1569    result = 0;
1570  }
1571  else
1572  {
1573    result = IDELEMS(syzstr->res[index]);
1574    while ((result>0) && (syzstr->res[index]->m[result-1]==NULL)) result--;
1575  }
1576  return result;
1577}
1578
1579/*3
1580* deletes a resolution
1581*/
1582void syKillComputation(syStrategy syzstr, ring r)
1583{
1584  if (syzstr->references>0)
1585  {
1586    (syzstr->references)--;
1587  }
1588  else
1589  {
1590    int i,j;
1591    if (syzstr->minres!=NULL)
1592    {
1593      for (i=0;i<syzstr->length;i++)
1594      {
1595        if (syzstr->minres[i]!=NULL)
1596        {
1597          for (j=0;j<IDELEMS(syzstr->minres[i]);j++)
1598          {
1599            if (syzstr->minres[i]->m[j]!=NULL)
1600              p_Delete(&(syzstr->minres[i]->m[j]),r);
1601          }
1602        }
1603        id_Delete(&(syzstr->minres[i]),r);
1604      }
1605      omFreeSize((ADDRESS)syzstr->minres,(syzstr->length+1)*sizeof(ideal));
1606    }
1607    if (syzstr->fullres!=NULL)
1608    {
1609      for (i=0;i<syzstr->length;i++)
1610      {
1611        if (syzstr->fullres[i]!=NULL)
1612        {
1613          for (j=0;j<IDELEMS(syzstr->fullres[i]);j++)
1614          {
1615            if (syzstr->fullres[i]->m[j]!=NULL)
1616              p_Delete(&(syzstr->fullres[i]->m[j]),r);
1617          }
1618        }
1619        id_Delete(&(syzstr->fullres[i]),r);
1620      }
1621      omFreeSize((ADDRESS)syzstr->fullres,(syzstr->length+1)*sizeof(ideal));
1622    }
1623    if (syzstr->weights!=0)
1624    {
1625      for (i=0;i<syzstr->length;i++)
1626      {
1627        if (syzstr->weights[i]!=NULL)
1628        {
1629          delete syzstr->weights[i];
1630        }
1631      }
1632      omFreeSize((ADDRESS)syzstr->weights,syzstr->length*sizeof(intvec*));
1633    }
1634
1635    ring sr=syzstr->syRing;
1636    if (sr==NULL) sr=r;
1637
1638    if (syzstr->resPairs!=NULL)
1639    {
1640      for (i=0;i<syzstr->length;i++)
1641      {
1642        for (j=0;j<(*syzstr->Tl)[i];j++)
1643        {
1644          if ((syzstr->resPairs[i])[j].lcm!=NULL)
1645            p_Delete(&((syzstr->resPairs[i])[j].lcm),sr);
1646          if ((i>0) && ((syzstr->resPairs[i])[j].syz!=NULL))
1647            p_Delete(&((syzstr->resPairs[i])[j].syz),sr);
1648        }
1649        if (syzstr->orderedRes[i]!=NULL)
1650        {
1651          for (j=0;j<IDELEMS(syzstr->orderedRes[i]);j++)
1652          {
1653            syzstr->orderedRes[i]->m[j] = NULL;
1654          }
1655        }
1656        id_Delete(&(syzstr->orderedRes[i]),sr);
1657        if (syzstr->truecomponents[i]!=NULL)
1658        {
1659          omFreeSize((ADDRESS)syzstr->truecomponents[i],(IDELEMS(syzstr->res[i])+1)*sizeof(int));
1660          syzstr->truecomponents[i]=NULL;
1661          omFreeSize((ADDRESS)syzstr->ShiftedComponents[i],(IDELEMS(syzstr->res[i])+1)*sizeof(long));
1662          syzstr->ShiftedComponents[i]=NULL;
1663        }
1664        if (syzstr->backcomponents[i]!=NULL)
1665        {
1666          omFreeSize((ADDRESS)syzstr->backcomponents[i],(IDELEMS(syzstr->res[i])+1)*sizeof(int));
1667          syzstr->backcomponents[i]=NULL;
1668        }
1669        if (syzstr->Howmuch[i]!=NULL)
1670        {
1671          omFreeSize((ADDRESS)syzstr->Howmuch[i],(IDELEMS(syzstr->res[i])+1)*sizeof(int));
1672          syzstr->Howmuch[i]=NULL;
1673        }
1674        if (syzstr->Firstelem[i]!=NULL)
1675        {
1676          omFreeSize((ADDRESS)syzstr->Firstelem[i],(IDELEMS(syzstr->res[i])+1)*sizeof(int));
1677          syzstr->Firstelem[i]=NULL;
1678        }
1679        if (syzstr->elemLength[i]!=NULL)
1680        {
1681          omFreeSize((ADDRESS)syzstr->elemLength[i],(IDELEMS(syzstr->res[i])+1)*sizeof(int));
1682          syzstr->elemLength[i]=NULL;
1683        }
1684        if (syzstr->res[i]!=NULL)
1685        {
1686          for (j=0;j<IDELEMS(syzstr->res[i]);j++)
1687          {
1688            if (syzstr->res[i]->m[j]!=NULL)
1689              p_Delete(&(syzstr->res[i]->m[j]),sr);
1690          }
1691        }
1692        if ((syzstr->hilb_coeffs!=NULL)
1693        && (syzstr->hilb_coeffs[i]!=NULL))
1694          delete syzstr->hilb_coeffs[i];
1695        if (syzstr->sev[i] != NULL)
1696          omFreeSize((ADDRESS)syzstr->sev[i], (IDELEMS(syzstr->res[i])+1)*sizeof(unsigned long));
1697        id_Delete(&(syzstr->res[i]),sr);
1698        if (syzstr->resPairs[i] != NULL) // OB: ????
1699          omFreeSize((ADDRESS)syzstr->resPairs[i],(*syzstr->Tl)[i]*sizeof(SObject));
1700      }
1701      omFreeSize((ADDRESS)syzstr->resPairs,syzstr->length*sizeof(SObject*));
1702      omFreeSize((ADDRESS)syzstr->res,(syzstr->length+1)*sizeof(ideal));
1703      omFreeSize((ADDRESS)syzstr->orderedRes,(syzstr->length+1)*sizeof(ideal));
1704      omFreeSize((ADDRESS)syzstr->elemLength,(syzstr->length+1)*sizeof(int*));
1705      omFreeSize((ADDRESS)syzstr->truecomponents,(syzstr->length+1)*sizeof(int*));
1706      omFreeSize((ADDRESS)syzstr->ShiftedComponents,(syzstr->length+1)*sizeof(long*));
1707      if (syzstr->sev != NULL)
1708        omFreeSize(((ADDRESS)syzstr->sev), (syzstr->length+1)*sizeof(unsigned long*));
1709      omFreeSize((ADDRESS)syzstr->backcomponents,(syzstr->length+1)*sizeof(int*));
1710      omFreeSize((ADDRESS)syzstr->Howmuch,(syzstr->length+1)*sizeof(int*));
1711      omFreeSize((ADDRESS)syzstr->Firstelem,(syzstr->length+1)*sizeof(int*));
1712      if (syzstr->hilb_coeffs!=NULL)
1713        omFreeSize((ADDRESS)syzstr->hilb_coeffs,(syzstr->length+1)*sizeof(intvec*));
1714    }
1715    if (syzstr->cw!=NULL)
1716      delete syzstr->cw;
1717    if (syzstr->betti!=NULL)
1718      delete syzstr->betti;
1719    if (syzstr->resolution!=NULL)
1720      delete syzstr->resolution;
1721    if (syzstr->Tl!=NULL)
1722      delete syzstr->Tl;
1723    if ((syzstr->syRing != NULL) && (syzstr->syRing != r))
1724    {
1725      rKill(syzstr->syRing);
1726    }
1727    omFreeSize((ADDRESS)syzstr, sizeof(ssyStrategy));
1728  }
1729}
1730
1731/*2
1732* divides out the weight monomials (given by the Schreyer-ordering)
1733* from the LaScala-resolution
1734*/
1735resolvente syReorder(resolvente res,int length,
1736        syStrategy syzstr,BOOLEAN toCopy,resolvente totake)
1737{
1738  int i,j,l;
1739  poly p,q,tq;
1740  polyset ri1;
1741  resolvente fullres;
1742  ring origR=syzstr->syRing;
1743  fullres = (resolvente)omAlloc0((length+1)*sizeof(ideal));
1744  if (totake==NULL)
1745    totake = res;
1746  for (i=length-1;i>0;i--)
1747  {
1748    if (res[i]!=NULL)
1749    {
1750      if (i>1)
1751      {
1752        j = IDELEMS(res[i-1]);
1753        while ((j>0) && (res[i-1]->m[j-1]==NULL)) j--;
1754        fullres[i-1] = idInit(IDELEMS(res[i]),j);
1755        ri1 = totake[i-1]->m;
1756        for (j=IDELEMS(res[i])-1;j>=0;j--)
1757        {
1758          p = res[i]->m[j];
1759          q = NULL;
1760          while (p!=NULL)
1761          {
1762            if (toCopy)
1763            {
1764              if (origR!=NULL)
1765                tq = prHeadR(p,origR);
1766              else
1767                tq = pHead(p);
1768              pIter(p);
1769            }
1770            else
1771            {
1772              res[i]->m[j] = NULL;
1773              if (origR!=NULL)
1774              {
1775                poly pp=p;
1776                pIter(p);
1777                pNext(pp)=NULL;
1778                tq = prMoveR(pp, origR);
1779              }
1780              else
1781              {
1782                tq = p;
1783                pIter(p);
1784                pNext(tq) = NULL;
1785              }
1786            }
1787//            pWrite(tq);
1788            pTest(tq);
1789            for (l=pVariables;l>0;l--)
1790            {
1791              if (origR!=NULL)
1792                pSubExp(tq,l, p_GetExp(ri1[pGetComp(tq)-1],l,origR));
1793              else
1794                pSubExp(tq,l, pGetExp(ri1[pGetComp(tq)-1],l));
1795            }
1796            pSetm(tq);
1797            pTest(tq);
1798            q = pAdd(q,tq);
1799            pTest(q);
1800          }
1801          fullres[i-1]->m[j] = q;
1802        }
1803      }
1804      else
1805      {
1806        if (origR!=NULL)
1807        {
1808          fullres[i-1] = idInit(IDELEMS(res[i]),res[i]->rank);
1809          for (j=IDELEMS(res[i])-1;j>=0;j--)
1810          {
1811            if (toCopy)
1812              fullres[i-1]->m[j] = prCopyR(res[i]->m[j], origR);
1813            else
1814            {
1815              fullres[i-1]->m[j] = prMoveR(res[i]->m[j], origR);
1816              res[i]->m[j] = NULL;
1817            }
1818          }
1819        }
1820        else
1821        {
1822          if (toCopy)
1823            fullres[i-1] = idCopy(res[i]);
1824          else
1825          {
1826            fullres[i-1] = res[i];
1827            res[i] = NULL;
1828          }
1829        }
1830        for (j=IDELEMS(fullres[i-1])-1;j>=0;j--)
1831          fullres[i-1]->m[j] = pSortCompCorrect(fullres[i-1]->m[j]);
1832      }
1833      if (!toCopy)
1834      {
1835        if (res[i]!=NULL) idDelete(&res[i]);
1836      }
1837    }
1838  }
1839  if (!toCopy)
1840    omFreeSize((ADDRESS)res,(length+1)*sizeof(ideal));
1841  //syzstr->length = length;
1842  return fullres;
1843}
1844
1845/*3
1846* read out the Betti numbers from resolution
1847* (if not LaScala calls the traditional Betti procedure)
1848*/
1849intvec * syBettiOfComputation(syStrategy syzstr, BOOLEAN minim,int * row_shift,
1850                              intvec* weights)
1851{
1852  int dummy;
1853  BOOLEAN std_weights=TRUE;
1854  if ((weights!=NULL)
1855  && (syzstr->betti!=NULL)
1856  && (syzstr->weights!=NULL) && (syzstr->weights[0]!=NULL))
1857  {
1858    int i;
1859    for(i=weights->length()-1; i>=0; i--)
1860    {
1861      //Print("test %d: %d - %d\n",i,(*weights)[i], (*(syzstr->weights[0]))[i]);
1862      if ((*weights)[i]!=(*(syzstr->weights[0]))[i])
1863      {
1864        std_weights=FALSE;
1865        break;
1866      }
1867    }
1868  }
1869  if ((syzstr->betti!=NULL)
1870  && (std_weights))
1871  {
1872    if (minim || (syzstr->resPairs!=NULL))
1873      return ivCopy(syzstr->betti);
1874  }
1875  if ((syzstr->fullres==NULL) && (syzstr->minres==NULL))
1876  {
1877     if (syzstr->hilb_coeffs==NULL)
1878     {
1879        syzstr->fullres = syReorder(syzstr->res,syzstr->length,syzstr);
1880     }
1881     else
1882     {
1883        syzstr->minres = syReorder(syzstr->orderedRes,syzstr->length,syzstr);
1884        syKillEmptyEntres(syzstr->minres,syzstr->length);
1885     }
1886   }
1887  intvec *result=NULL;
1888  if (syzstr->fullres!=NULL)
1889    result = syBetti(syzstr->fullres,syzstr->length,&dummy,weights,minim,row_shift);
1890  else
1891    result = syBetti(syzstr->minres,syzstr->length,&dummy,weights,minim,row_shift);
1892  if ((result!=NULL)
1893  && ((minim) || (syzstr->resPairs!=NULL))
1894  && std_weights)
1895  {
1896    syzstr->betti = ivCopy(result);
1897  }
1898  return result;
1899}
1900
1901/*3
1902* computes the allocated length of the resolution
1903*/
1904int syLength(syStrategy syzstr)
1905{
1906  return syzstr->length;
1907}
1908
1909/*3
1910* computes the real length of the resolution
1911*/
1912int sySize(syStrategy syzstr)
1913{
1914  resolvente r=syzstr->res;
1915  if (r==NULL)
1916    r = syzstr->fullres;
1917  if (r==NULL)
1918    r = syzstr->minres;
1919  if (r==NULL)
1920  {
1921    WerrorS("No resolution found");
1922    return 0;
1923  }
1924  int i=syzstr->length;
1925  while ((i>0) && (r[i-1]==NULL)) i--;
1926  return i;
1927}
1928
1929/*3
1930* computes the cohomological dimension of res[1]
1931*/
1932int syDim(syStrategy syzstr)
1933{
1934  int i,j=-1,l;
1935  if (syzstr->resPairs!=NULL)
1936  {
1937    SRes rP=syzstr->resPairs;
1938
1939    l = syzstr->length;
1940    while ((l>0) && (rP[l-1]==NULL)) l--;
1941    if (l==0) return -1;
1942    l--;
1943    while (l>=0)
1944    {
1945      i = 0;
1946      while ((i<(*syzstr->Tl)[l]) &&
1947        ((rP[l][i].lcm!=NULL) || (rP[l][i].syz!=NULL)) &&
1948        (rP[l][i].isNotMinimal!=NULL))
1949      {
1950        i++;
1951      }
1952      if ((i<(*syzstr->Tl)[l]) &&
1953        ((rP[l][i].lcm!=NULL) || (rP[l][i].syz!=NULL)) &&
1954        (rP[l][i].isNotMinimal==NULL))
1955        return l;
1956      l--;
1957    }
1958    return l;
1959  }
1960  else
1961    return sySize(syzstr);
1962}
1963
1964/*3
1965* copies the resolution (by increment the reference counter)
1966*/
1967syStrategy syCopy(syStrategy syzstr)
1968{
1969  syStrategy result=syzstr;
1970  (result->references)++;
1971  return result;
1972}
1973
1974/*2
1975* local print procedure used in syPrint
1976*/
1977static void syPrintEmptySpaces(int i)
1978{
1979  if (i!=0)
1980  {
1981    PrintS(" ");
1982    syPrintEmptySpaces(i/10);
1983  }
1984}
1985
1986/*2
1987* local print procedure used in syPrint
1988*/
1989static void syPrintEmptySpaces1(int i)
1990{
1991  if (i!=0)
1992  {
1993    PrintS(" ");
1994    syPrintEmptySpaces1(i-1);
1995  }
1996}
1997
1998/*2
1999* local print procedure used in syPrint
2000*/
2001static int syLengthInt(int i)
2002{
2003  int j=0;
2004
2005  if (i==0) return 1;
2006  while (i!=0)
2007  {
2008    j++;
2009    i = i/10;
2010  }
2011  return j;
2012}
2013
2014/*3
2015* prints the resolution as sequence of free modules
2016*/
2017void syPrint(syStrategy syzstr)
2018{
2019  if ((syzstr->resPairs==NULL) && (syzstr->fullres==NULL)
2020     && (syzstr->minres==NULL))
2021  {
2022    PrintS("No resolution defined\n");
2023    return;
2024  }
2025  int l=0;
2026  if (syzstr->resolution==NULL)
2027  {
2028    int j;
2029    if (syzstr->resPairs!=NULL)
2030    {
2031      syzstr->resolution = new intvec(syzstr->length+1);
2032      SRes rP=syzstr->resPairs;
2033      assume(idRankFreeModule(syzstr->res[1],
2034                                 (syzstr->syRing != NULL ? syzstr->syRing : currRing))==syzstr->res[1]->rank);
2035      (*syzstr->resolution)[0] = syzstr->res[1]->rank;
2036      while ((l<syzstr->length) && (rP[l]!=NULL))
2037      {
2038        j=0;
2039        while ((j<(*syzstr->Tl)[l]) &&
2040          ((rP[l][j].lcm!=NULL) || (rP[l][j].syz!=NULL)))
2041        {
2042          if (rP[l][j].isNotMinimal==NULL)
2043            ((*syzstr->resolution)[l+1])++;
2044          j++;
2045        }
2046        l++;
2047      }
2048    }
2049    else
2050    {
2051      resolvente rr;
2052      syzstr->resolution = new intvec(syzstr->length+2);
2053      if (syzstr->minres!=NULL)
2054        rr = syzstr->minres;
2055      else
2056        rr = syzstr->fullres;
2057      (*syzstr->resolution)[0]
2058        = si_max(1,(int)idRankFreeModule(rr[0],
2059                                 (syzstr->syRing != NULL ? syzstr->syRing : currRing)));
2060      while ((l<syzstr->length) && (rr[l]!=NULL))
2061      {
2062        j = IDELEMS(rr[l]);
2063        while ((j>0) && (rr[l]->m[j-1]==NULL)) j--;
2064        ((*syzstr->resolution)[l+1]) = j;
2065        l++;
2066      }
2067    }
2068  }
2069  const char *sn=currRingHdl->id;
2070  int sl=strlen(sn);
2071  syPrintEmptySpaces1(sl);
2072  l = 0;
2073  loop
2074  {
2075    if ((l>=syzstr->resolution->length()) || ((*syzstr->resolution)[l]==0))
2076      break;
2077    Print("%d",(*syzstr->resolution)[l]);
2078    syPrintEmptySpaces1(sl+5);
2079    l++;
2080  }
2081  PrintLn();
2082  l = 0;
2083  loop
2084  {
2085    if ((l>=syzstr->resolution->length()) || ((*syzstr->resolution)[l]==0))
2086      break;
2087    PrintS(sn);
2088    if (((l+1)>=syzstr->resolution->length()) || ((*syzstr->resolution)[(l+1)]==0))
2089      break;
2090    PrintS(" <-- ");
2091    syPrintEmptySpaces((*syzstr->resolution)[l]);
2092    l++;
2093  }
2094  PrintLn();
2095  PrintLn();
2096  l = 0;
2097  loop
2098  {
2099    if ((l>=syzstr->resolution->length()) || ((*syzstr->resolution)[l]==0))
2100      break;
2101    Print("%d",l);
2102    syPrintEmptySpaces1(sl+5+syLengthInt((*syzstr->resolution)[l])-
2103                         syLengthInt(l));
2104    l++;
2105  }
2106  PrintLn();
2107  if (syzstr->minres==NULL)
2108  {
2109    PrintS("resolution not minimized yet");
2110    PrintLn();
2111  }
2112}
2113
2114/*2
2115* deleting all monomials the component of which correspond
2116* to non-minimal generators
2117*/
2118static poly syStripOut(poly p,intvec * toStrip)
2119{
2120  if (toStrip==NULL) return p;
2121  poly pp=p;
2122
2123  while ((pp!=NULL) && ((*toStrip)[pGetComp(pp)]!=0))
2124    pDeleteLm(&pp);
2125  p = pp;
2126  if (pp!=NULL)
2127  {
2128    while (pNext(pp)!=NULL)
2129    {
2130      if ((*toStrip)[pGetComp(pNext(pp))]!=0)
2131        pDeleteLm(&pNext(pp));
2132      else
2133        pIter(pp);
2134    }
2135  }
2136  return p;
2137}
2138
2139/*2
2140* copies only those monomials the component of which correspond
2141* to minimal generators
2142*/
2143static poly syStripOutCopy(poly p,intvec * toStrip)
2144{
2145  if (toStrip==NULL) return pCopy(p);
2146  poly result=NULL,pp;
2147
2148  while (p!=NULL)
2149  {
2150    if ((*toStrip)[pGetComp(p)]==0)
2151    {
2152      if (result==NULL)
2153      {
2154        result = pp = pHead(p);
2155      }
2156      else
2157      {
2158        pNext(pp) = pHead(p);
2159        pIter(pp);
2160      }
2161    }
2162    pIter(p);
2163  }
2164  return result;
2165}
2166
2167/*2
2168* minimizes toMin
2169*/
2170static poly syMinimizeP(int toMin,syStrategy syzstr,intvec * ordn,int index,
2171                        intvec * toStrip)
2172{
2173  int ii=0,i,j,tc;
2174  poly p,pp,q=NULL,tq,pisN;
2175  SSet sPairs=syzstr->resPairs[index];
2176  poly tempStripped=NULL;
2177
2178  //pp=pCopy(syzstr->res[index+1]->m[toMin]);
2179  pp = syStripOutCopy(syzstr->res[index+1]->m[toMin],toStrip);
2180  while ((ii<ordn->length()) && ((*ordn)[ii]!=-1) &&
2181             (sPairs[(*ordn)[ii]].syzind!=toMin))
2182  {
2183    ii++;
2184  }
2185  while (ii>=0)
2186  {
2187    i = (*ordn)[ii];
2188    if (sPairs[i].isNotMinimal!=NULL)
2189    {
2190      tempStripped =
2191        syStripOutCopy(syzstr->res[index+1]->m[sPairs[i].syzind],toStrip);
2192      pisN = sPairs[i].isNotMinimal;
2193      tc = pGetComp(pisN);
2194      p = pp;
2195      while (p!=NULL)
2196      {
2197        if (pGetComp(p)==tc)
2198        {
2199          tq = pInit();
2200          for(j=pVariables; j>0; j--)
2201            pSetExp(tq,j, pGetExp(p,j)-pGetExp(pisN,j));
2202          pSetComp(tq, 0);
2203          pSetCoeff0(tq,nDiv(pGetCoeff(p),pGetCoeff(pisN)));
2204          pGetCoeff(tq) = nNeg(pGetCoeff(tq));
2205          pSetm(tq);
2206          q = pAdd(q,pMult_mm(pCopy(tempStripped),tq));
2207          pDelete(&tq);
2208        }
2209        pIter(p);
2210      }
2211      if (q!=NULL)
2212      {
2213        pp = pAdd(pp,q);
2214        q = NULL;
2215      }
2216      pDelete(&tempStripped);
2217    }
2218    ii--;
2219  }
2220  return pp;
2221}
2222
2223/*2
2224* minimizes toMin
2225*/
2226static poly syMinimizeP1(int toMin,syStrategy syzstr,intvec * ordn,int index,
2227                        intvec * toStrip)
2228{
2229  int ii=0,i,j,tc,lp,ltS=-1;
2230  poly p,mp=NULL,pp,q=NULL,tq,pisN;
2231  SSet sPairs=syzstr->resPairs[index];
2232  poly tempStripped=NULL;
2233
2234  pp = syStripOutCopy(syzstr->res[index+1]->m[toMin],toStrip);
2235  kBucketInit(syzstr->bucket,pp,-1);
2236  while ((ii<ordn->length()) && ((*ordn)[ii]!=-1) &&
2237             (sPairs[(*ordn)[ii]].syzind!=toMin))
2238  {
2239    ii++;
2240  }
2241  while (ii>=0)
2242  {
2243    i = (*ordn)[ii];
2244    if (sPairs[i].isNotMinimal!=NULL)
2245    {
2246      tempStripped =
2247        syStripOutCopy(syzstr->res[index+1]->m[sPairs[i].syzind],toStrip);
2248      tc = pGetComp(sPairs[i].isNotMinimal);
2249      //p = pTakeOutComp1(&tempStripped,tc);
2250      int lu;
2251      pTakeOutComp(&tempStripped,tc,&p,&lu);
2252      kBucketTakeOutComp(syzstr->bucket,tc,&mp,&lp);
2253      mp = pDivideM(mp,p);
2254      while (mp!=NULL)
2255      {
2256        p = pNext(mp);
2257        pNext(mp) = NULL;
2258        ltS = -1;
2259        kBucket_Minus_m_Mult_p(syzstr->bucket,mp,tempStripped,&ltS);
2260        mp = p;
2261      }
2262      pDelete(&mp);
2263      pDelete(&tempStripped);
2264    }
2265    ii--;
2266  }
2267  kBucketClear(syzstr->bucket,&pp,&lp);
2268  return pp;
2269}
2270
2271/*2
2272* deletes empty components after minimization
2273*/
2274void syKillEmptyEntres(resolvente res,int length)
2275{
2276  int i,j,jj,k,rj;
2277  intvec * changes;
2278  poly p;
2279  ideal ri;
2280
2281  for (i=0;i<length;i++)
2282  {
2283    ri = res[i];
2284    if (ri!=NULL)
2285    {
2286      rj = IDELEMS(ri);
2287      changes = new intvec(rj+1,1,-1);
2288      while ((rj>0) && (ri->m[rj-1]==NULL)) rj--;
2289      j = k = 0;
2290      while (j+k<rj)
2291      {
2292        if (ri->m[j+k]!=NULL)
2293        {
2294          ri->m[j] = ri->m[j+k];
2295          (*changes)[j+k+1] = j+1;
2296          j++;
2297        }
2298        else
2299        {
2300          k++;
2301        }
2302      }
2303      for (jj=j;jj<rj;jj++)
2304        ri->m[jj] = NULL;
2305      if (res[i+1]!=NULL)
2306      {
2307        ri = res[i+1];
2308        for (j=IDELEMS(ri)-1;j>=0;j--)
2309        {
2310          p = ri->m[j];
2311          while (p!=NULL)
2312          {
2313            pSetComp(p,(*changes)[pGetComp(p)]);
2314            pSetm(p);
2315            pIter(p);
2316          }
2317        }
2318      }
2319      delete changes;
2320    }
2321  }
2322}
2323
2324/*2
2325* determines the components for minimization
2326*/
2327static intvec * syToStrip(syStrategy syzstr, int index)
2328{
2329  intvec * result=NULL;
2330
2331  if ((syzstr->resPairs[index-1]!=NULL) && (!idIs0(syzstr->res[index])))
2332  {
2333    result=new intvec(IDELEMS(syzstr->res[index])+1);
2334    for (int i=(*syzstr->Tl)[index-1]-1;i>=0;i--)
2335    {
2336      if (syzstr->resPairs[index-1][i].isNotMinimal!=NULL)
2337      {
2338        (*result)[syzstr->resPairs[index-1][i].syzind+1] = 1;
2339      }
2340    }
2341  }
2342  return result;
2343}
2344
2345/*2
2346* re-computes the order of pairs during the algorithm
2347* this ensures to procede with a triangular matrix
2348*/
2349static intvec * syOrdPairs(SSet sPairs, int length)
2350{
2351  intvec * result=new intvec(length,1,-1);
2352  int i,j=0,k=-1,l,ii;
2353
2354  loop
2355  {
2356    l = -1;
2357    for(i=0;i<length;i++)
2358    {
2359      if (sPairs[i].syzind>k)
2360      {
2361        if (l==-1)
2362        {
2363          l = sPairs[i].syzind;
2364          ii = i;
2365        }
2366        else
2367        {
2368          if (sPairs[i].syzind<l)
2369          {
2370            l = sPairs[i].syzind;
2371            ii = i;
2372          }
2373        }
2374      }
2375    }
2376    if (l==-1) break;
2377    (*result)[j] = ii;
2378    j++;
2379    k = l;
2380  }
2381  return result;
2382}
2383
2384/*2
2385* minimizes the output of LaScala
2386*/
2387static resolvente syReadOutMinimalRes(syStrategy syzstr,
2388           BOOLEAN computeStd=FALSE)
2389{
2390  intvec * Strip, * ordn;
2391  resolvente tres=(resolvente)omAlloc0((syzstr->length+1)*sizeof(ideal));
2392  ring tmpR = NULL;
2393  ring origR = currRing;
2394
2395//Print("Hier ");
2396  if (computeStd)
2397  {
2398    tres[0] = syzstr->res[1];
2399    syzstr->res[1] = idInit(IDELEMS(tres[0]),tres[0]->rank);
2400    return tres;
2401  }
2402  int i,j,l,index,ii,i1;
2403  poly p;
2404  ideal rs;
2405  SSet sPairs;
2406  int * ord,*b0,*b1;
2407
2408  assume(syzstr->syRing != NULL);
2409  rChangeCurrRing(syzstr->syRing);
2410//Print("laeufts ");
2411  syzstr->bucket = kBucketCreate();
2412  for (index=syzstr->length-1;index>0;index--)
2413  {
2414    if (syzstr->resPairs[index]!=NULL)
2415    {
2416//Print("ideal %d: \n",index);
2417      currcomponents = syzstr->truecomponents[index];
2418      currShiftedComponents = syzstr->ShiftedComponents[index];
2419      rChangeSComps(currcomponents, currShiftedComponents,
2420                    IDELEMS(syzstr->res[index]));
2421      sPairs = syzstr->resPairs[index];
2422      Strip = syToStrip(syzstr,index);
2423      tres[index+1] = idInit(IDELEMS(syzstr->res[index+1]),syzstr->res[index+1]->rank);
2424      i1 = (*syzstr->Tl)[index];
2425//Print("i1= %d\n",i1);
2426      ordn = syOrdPairs(sPairs,i1);
2427      for (i=0;i<i1;i++)
2428      {
2429        if ((sPairs[i].isNotMinimal==NULL) && (sPairs[i].lcm!=NULL))
2430        {
2431          l = sPairs[i].syzind;
2432//Print("Minimiere Poly %d: ",l);pWrite(syzstr->res[index+1]->m[l]);
2433          tres[index+1]->m[l] =
2434            syMinimizeP1(l,syzstr,ordn,index,Strip);
2435        }
2436      }
2437      delete Strip;
2438      Strip = NULL;
2439    }
2440  }
2441  currcomponents = syzstr->truecomponents[0];
2442  currShiftedComponents = syzstr->ShiftedComponents[0];
2443  rChangeSComps( currcomponents, currShiftedComponents,
2444                 IDELEMS(syzstr->res[0]));
2445  tres[1] = idInit(IDELEMS(syzstr->res[1]),syzstr->res[1]->rank);
2446  sPairs = syzstr->resPairs[0];
2447  for (i=(*syzstr->Tl)[0]-1;i>=0;i--)
2448  {
2449    if (sPairs[i].syzind>=0)
2450    {
2451      tres[1]->m[sPairs[i].syzind] = pCopy(syzstr->res[1]->m[sPairs[i].syzind]);
2452    }
2453  }
2454/*--- changes to the original ring------------------*/
2455  kBucketDestroy(&syzstr->bucket);
2456  if (syzstr->syRing != NULL)
2457  {
2458    rChangeCurrRing(origR);
2459    // Thomas: now make sure that all data which you need is pFetchCopied
2460    // maybe incoporate it into syReorder ??
2461  }
2462  tres = syReorder(tres,syzstr->length,syzstr,FALSE,syzstr->res);
2463  syKillEmptyEntres(tres,syzstr->length);
2464  idSkipZeroes(tres[0]);
2465  return tres;
2466}
2467
2468/*3
2469* minimizes any kind of resolution
2470*/
2471syStrategy syMinimize(syStrategy syzstr)
2472{
2473  if (syzstr->minres==NULL)
2474  {
2475    if (syzstr->resPairs!=NULL)
2476    {
2477      if (syzstr->hilb_coeffs==NULL)
2478      {
2479        syzstr->minres = syReadOutMinimalRes(syzstr);
2480      }
2481      else
2482      {
2483        syzstr->minres = syReorder(syzstr->orderedRes,syzstr->length,syzstr);
2484      }
2485    }
2486    else if (syzstr->fullres!=NULL)
2487    {
2488      syMinimizeResolvente(syzstr->fullres,syzstr->length,1);
2489      syzstr->minres = syzstr->fullres;
2490      syzstr->fullres = NULL;
2491    }
2492  }
2493  (syzstr->references)++;
2494  return syzstr;
2495}
2496
2497/*2
2498* implementation of LaScala's algorithm
2499* assumes that the given module is homogeneous
2500* works with slanted degree, uses syChosePairs
2501*/
2502syStrategy syLaScala3(ideal arg,int * length)
2503{
2504  BOOLEAN noPair=FALSE;
2505  int i,j,actdeg=32000,index=0,reg=-1;
2506  int startdeg,howmuch;
2507  poly p;
2508  ideal temp;
2509  SSet nextPairs;
2510  syStrategy syzstr=(syStrategy)omAlloc0(sizeof(ssyStrategy));
2511  ring origR = currRing;
2512
2513  if ((idIs0(arg)) ||
2514      ((idRankFreeModule(arg)>0) && (!idHomModule(arg,NULL,&(syzstr->cw)))))
2515  {
2516    syzstr->minres = (resolvente)omAlloc0Bin(char_ptr_bin);
2517    syzstr->length = 1;
2518    syzstr->minres[0] = idInit(1,arg->rank);
2519    return syzstr;
2520  }
2521
2522  //crit = 0;
2523  //euler = -1;
2524  redpol = pInit();
2525  syzstr->length = *length = pVariables+2;
2526
2527  // Creare dp,S ring and change to it
2528  syzstr->syRing = rCurrRingAssure_dp_S();
2529  assume(syzstr->syRing != origR);
2530
2531  // set initial ShiftedComps
2532  currcomponents = (int*)omAlloc0((arg->rank+1)*sizeof(int));
2533  currShiftedComponents = (long*)omAlloc0((arg->rank+1)*sizeof(long));
2534  for (i=0;i<=arg->rank;i++)
2535  {
2536    currShiftedComponents[i] = (i)*SYZ_SHIFT_BASE;
2537    currcomponents[i] = i;
2538  }
2539  rChangeSComps(currcomponents, currShiftedComponents, arg->rank);
2540/*--- initializes the data structures---------------*/
2541  syzstr->Tl = new intvec(*length);
2542  temp = idInit(IDELEMS(arg),arg->rank);
2543  for (i=0;i<IDELEMS(arg);i++)
2544  {
2545    temp->m[i] = prCopyR( arg->m[i], origR);
2546    if (temp->m[i]!=NULL)
2547    {
2548      j = pTotaldegree(temp->m[i]);
2549      if (j<actdeg) actdeg = j;
2550    }
2551  }
2552  idTest(temp);
2553  idSkipZeroes(temp);
2554  idTest(temp);
2555  syzstr->resPairs = syInitRes(temp,length,syzstr->Tl,syzstr->cw);
2556  omFreeSize((ADDRESS)currcomponents,(arg->rank+1)*sizeof(int));
2557  omFreeSize((ADDRESS)currShiftedComponents,(arg->rank+1)*sizeof(long));
2558  syzstr->res = (resolvente)omAlloc0((*length+1)*sizeof(ideal));
2559  syzstr->orderedRes = (resolvente)omAlloc0((*length+1)*sizeof(ideal));
2560  syzstr->elemLength = (int**)omAlloc0((*length+1)*sizeof(int*));
2561  syzstr->truecomponents = (int**)omAlloc0((*length+1)*sizeof(int*));
2562  syzstr->ShiftedComponents = (long**)omAlloc0((*length+1)*sizeof(long*));
2563  syzstr->backcomponents = (int**)omAlloc0((*length+1)*sizeof(int*));
2564  syzstr->Howmuch = (int**)omAlloc0((*length+1)*sizeof(int*));
2565  syzstr->Firstelem = (int**)omAlloc0((*length+1)*sizeof(int*));
2566  syzstr->sev = (unsigned long **) omAlloc0((*length+1)*sizeof(unsigned long *));
2567  syzstr->bucket = kBucketCreate();
2568  int len0=idRankFreeModule(temp)+1;
2569
2570  startdeg = actdeg;
2571  nextPairs = syChosePairs(syzstr,&index,&howmuch,&actdeg);
2572  //if (TEST_OPT_PROT) Print("(%d,%d)",howmuch,index);
2573/*--- computes the resolution ----------------------*/
2574  while (nextPairs!=NULL)
2575  {
2576    if (TEST_OPT_PROT) Print("%d",actdeg);
2577    if (TEST_OPT_PROT) Print("(m%d)",index);
2578    if (index==0)
2579      i = syInitSyzMod(syzstr,index,len0);
2580    else
2581      i = syInitSyzMod(syzstr,index);
2582    currcomponents = syzstr->truecomponents[si_max(index-1,0)];
2583    currShiftedComponents = syzstr->ShiftedComponents[si_max(index-1,0)];
2584    rChangeSComps(currcomponents, currShiftedComponents,
2585                  IDELEMS(syzstr->res[si_max(index-1,0)]));
2586    j = syInitSyzMod(syzstr,index+1);
2587    if (index>0)
2588    {
2589      syRedNextPairs(nextPairs,syzstr,howmuch,index);
2590      syCompactifyPairSet(syzstr->resPairs[index],(*syzstr->Tl)[index],0);
2591    }
2592    else
2593      syRedGenerOfCurrDeg(syzstr,actdeg,index+1);
2594/*--- creates new pairs -----------------------------*/
2595    syCreateNewPairs(syzstr,index,i);
2596    if (index<(*length)-1)
2597    {
2598      syCreateNewPairs(syzstr,index+1,j);
2599    }
2600    index++;
2601    nextPairs = syChosePairs(syzstr,&index,&howmuch,&actdeg);
2602    //if (TEST_OPT_PROT) Print("(%d,%d)",howmuch,index);
2603  }
2604  if (temp!=NULL) idDelete(&temp);
2605  kBucketDestroy(&(syzstr->bucket));
2606  if (origR != syzstr->syRing)
2607    rChangeCurrRing(origR);
2608  pDeleteLm(&redpol);
2609  if (TEST_OPT_PROT) PrintLn();
2610  return syzstr;
2611}
2612
2613
2614
2615/*2
2616* more general implementation of LaScala's algorithm
2617* assumes that the given module is (quasi-)homogeneous
2618* works with slanted degree, uses syChosePairs
2619*/
2620syStrategy syLaScala(ideal arg, int& maxlength, intvec* weights)
2621{
2622  BOOLEAN noPair=FALSE;
2623  int i,j,actdeg=32000,index=0,reg=-1;
2624  int startdeg,howmuch;
2625  poly p;
2626  ideal temp;
2627  SSet nextPairs;
2628  syStrategy syzstr=(syStrategy)omAlloc0(sizeof(ssyStrategy));
2629  ring origR = currRing;
2630
2631  if(weights!= NULL) 
2632    syzstr->cw = new intvec(weights);
2633  else
2634    syzstr->cw = NULL;
2635
2636  if ((idIs0(arg)) ||
2637      ((idRankFreeModule(arg)>0) && (!idTestHomModule(arg, NULL, syzstr->cw))))
2638  {
2639    syzstr->minres = (resolvente)omAlloc0Bin(char_ptr_bin);
2640    syzstr->length = 1;
2641    syzstr->minres[0] = idInit(1,arg->rank);
2642    return syzstr;
2643  }
2644
2645
2646  //crit = 0;
2647  //euler = -1;
2648  redpol = pInit();
2649 
2650  if( maxlength > 0 )
2651    syzstr->length = maxlength; //  = pVariables+2;
2652  else
2653    syzstr->length = maxlength = pVariables+2; 
2654
2655  // Creare dp,S ring and change to it
2656  syzstr->syRing = rCurrRingAssure_dp_S();
2657  assume(syzstr->syRing != origR);
2658
2659  // set initial ShiftedComps
2660  currcomponents = (int*)omAlloc0((arg->rank+1)*sizeof(int));
2661  currShiftedComponents = (long*)omAlloc0((arg->rank+1)*sizeof(long));
2662  for (i=0;i<=arg->rank;i++)
2663  {
2664    currShiftedComponents[i] = (i)*SYZ_SHIFT_BASE;
2665    currcomponents[i] = i;
2666  }
2667  rChangeSComps(currcomponents, currShiftedComponents, arg->rank);
2668/*--- initializes the data structures---------------*/
2669  syzstr->Tl = new intvec(maxlength);
2670  temp = idInit(IDELEMS(arg),arg->rank);
2671  for (i=0;i<IDELEMS(arg);i++)
2672  {
2673    temp->m[i] = prCopyR( arg->m[i], origR);
2674    if (temp->m[i]!=NULL)
2675    {
2676      j = pTotaldegree(temp->m[i]);
2677      if (j<actdeg) actdeg = j;
2678    }
2679  }
2680  idTest(temp);
2681  idSkipZeroes(temp);
2682  idTest(temp);
2683  syzstr->resPairs = syInitRes(temp,&maxlength,syzstr->Tl,syzstr->cw);
2684  omFreeSize((ADDRESS)currcomponents,(arg->rank+1)*sizeof(int));
2685  omFreeSize((ADDRESS)currShiftedComponents,(arg->rank+1)*sizeof(long));
2686  syzstr->res = (resolvente)omAlloc0((maxlength+1)*sizeof(ideal));
2687  syzstr->orderedRes = (resolvente)omAlloc0((maxlength+1)*sizeof(ideal));
2688  syzstr->elemLength = (int**)omAlloc0((maxlength+1)*sizeof(int*));
2689  syzstr->truecomponents = (int**)omAlloc0((maxlength+1)*sizeof(int*));
2690  syzstr->ShiftedComponents = (long**)omAlloc0((maxlength+1)*sizeof(long*));
2691  syzstr->backcomponents = (int**)omAlloc0((maxlength+1)*sizeof(int*));
2692  syzstr->Howmuch = (int**)omAlloc0((maxlength+1)*sizeof(int*));
2693  syzstr->Firstelem = (int**)omAlloc0((maxlength+1)*sizeof(int*));
2694  syzstr->sev = (unsigned long **) omAlloc0((maxlength+1)*sizeof(unsigned long *));
2695  syzstr->bucket = kBucketCreate();
2696  int len0=idRankFreeModule(temp)+1;
2697
2698  startdeg = actdeg;
2699  nextPairs = syChosePairs(syzstr,&index,&howmuch,&actdeg);
2700  //if (TEST_OPT_PROT) Print("(%d,%d)",howmuch,index);
2701/*--- computes the resolution ----------------------*/
2702  while (nextPairs!=NULL)
2703  {
2704    if (TEST_OPT_PROT) Print("%d",actdeg);
2705    if (TEST_OPT_PROT) Print("(m%d)",index);
2706    if (index==0)
2707      i = syInitSyzMod(syzstr,index,len0);
2708    else
2709      i = syInitSyzMod(syzstr,index);
2710    currcomponents = syzstr->truecomponents[si_max(index-1,0)];
2711    currShiftedComponents = syzstr->ShiftedComponents[si_max(index-1,0)];
2712    rChangeSComps(currcomponents, currShiftedComponents,
2713                  IDELEMS(syzstr->res[si_max(index-1,0)]));
2714    j = syInitSyzMod(syzstr,index+1);
2715    if (index>0)
2716    {
2717      syRedNextPairs(nextPairs,syzstr,howmuch,index);
2718      syCompactifyPairSet(syzstr->resPairs[index],(*syzstr->Tl)[index],0);
2719    }
2720    else
2721      syRedGenerOfCurrDeg(syzstr,actdeg,index+1);
2722/*--- creates new pairs -----------------------------*/
2723    syCreateNewPairs(syzstr,index,i);
2724    if (index<(maxlength-1))
2725    {
2726      syCreateNewPairs(syzstr,index+1,j);
2727    }
2728    index++;
2729    nextPairs = syChosePairs(syzstr,&index,&howmuch,&actdeg);
2730    //if (TEST_OPT_PROT) Print("(%d,%d)",howmuch,index);
2731  }
2732  if (temp!=NULL) idDelete(&temp);
2733  kBucketDestroy(&(syzstr->bucket));
2734  if (origR != syzstr->syRing)
2735    rChangeCurrRing(origR);
2736  pDeleteLm(&redpol);
2737  if (TEST_OPT_PROT) PrintLn();
2738  return syzstr;
2739}
2740
Note: See TracBrowser for help on using the repository browser.