source: git/Singular/syz1.cc @ 734b9a

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