source: git/Singular/ideals.cc @ a18fae

spielwiese
Last change on this file since a18fae was a18fae, checked in by Hans Schönemann <hannes@…>, 26 years ago
* hannes: fixed echo handling (febase.h febase.inc, silink.cc) updated documentation (doc/*.doc) git-svn-id: file:///usr/local/Singular/svn/trunk@1187 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 63.7 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: ideals.cc,v 1.20 1998-02-27 16:27:58 Singular Exp $ */
5/*
6* ABSTRACT - all basic methods to manipulate ideals
7*/
8
9/* includes */
10#include "mod2.h"
11#include "tok.h"
12#include "mmemory.h"
13#include "febase.h"
14#include "numbers.h"
15#include "polys.h"
16#include "ipid.h"
17#include "ring.h"
18#include "kstd1.h"
19#include "matpol.h"
20#include "weight.h"
21#include "intvec.h"
22#include "syz.h"
23#include "ideals.h"
24#include "lists.h"
25
26
27static poly * idpower;
28/*collects the monomials in makemonoms, must be allocated befor*/
29static int idpowerpoint;
30/*index of the actual monomial in idpower*/
31static poly * givenideal;
32/*the ideal from which a power is computed*/
33
34/*0 implementation*/
35
36/*2
37* initialise an ideal
38*/
39#ifdef MDEBUG
40ideal idDBInit(int idsize, int rank, char *f, int l)
41#else
42ideal idInit(int idsize, int rank)
43#endif
44{
45  /*- initialise an ideal -*/
46#ifdef MDEBUG
47  ideal hh = (ideal )mmDBAllocBlock(sizeof(*hh),f,l);
48#else
49  ideal hh = (ideal )Alloc(sizeof(*hh));
50#endif
51  hh->nrows = 1;
52  hh->rank = rank;
53  IDELEMS(hh) = idsize;
54  if (idsize>0)
55  {
56#ifdef MDEBUG
57    hh->m = (poly *)mmDBAllocBlock0(idsize*sizeof(poly),f,l);
58#else
59    hh->m = (poly *)Alloc0(idsize*sizeof(poly));
60#endif
61  }
62  else
63    hh->m=NULL;
64  return hh;
65}
66
67/*2
68* initialise the maximal ideal (at 0)
69*/
70ideal idMaxIdeal (void)
71{
72  int l;
73  ideal hh=NULL;
74
75  hh=idInit(pVariables,1);
76  for (l=0; l<pVariables; l++)
77  {
78    hh->m[l] = pOne();
79    pSetExp(hh->m[l],l+1,1);
80    pSetm(hh->m[l]);
81  }
82  return hh;
83}
84
85/*2
86* deletes an ideal/matrix
87*/
88#ifdef MDEBUG
89void idDBDelete (ideal* h, char *f, int l)
90#else
91void idDelete (ideal * h)
92#endif
93{
94  int j,elems;
95  if (*h == NULL)
96    return;
97  elems=j=(*h)->nrows*(*h)->ncols;
98  if (j>0)
99  {
100    do
101    {
102      #ifdef MDEBUG
103      pDBDelete(&((*h)->m[--j]),f,l);
104      #else
105      pDelete(&((*h)->m[--j]));
106      #endif
107    }
108    while (j>0);
109    #ifdef MDEBUG
110    mmDBFreeBlock((ADDRESS)((*h)->m),sizeof(poly)*elems,f,l);
111    #else
112    Free((ADDRESS)((*h)->m),sizeof(poly)*elems);
113    #endif
114  }
115  #ifdef MDEBUG
116  mmDBFreeBlock((ADDRESS)(*h),sizeof(**h),f,l);
117  #else
118  Free((ADDRESS)*h,sizeof(**h));
119  #endif
120  *h=NULL;
121}
122
123/*2
124*gives an ideal the minimal possible size
125*/
126void idSkipZeroes (ideal ide)
127{
128  int k;
129  int j = -1;
130  BOOLEAN change=FALSE;
131  for (k=0; k<IDELEMS(ide); k++)
132  {
133    if (ide->m[k] != NULL)
134    {
135      j++;
136      if (change)
137      {
138        ide->m[j] = ide->m[k];
139      }
140    }
141    else
142    {
143      change=TRUE;
144    }
145  }
146  if (change)
147  {
148    if (j == -1)
149      j = 0;
150    else
151    { 
152      for (k=j+1; k<IDELEMS(ide); k++)
153        ide->m[k] = NULL;
154    }
155    pEnlargeSet(&(ide->m),IDELEMS(ide),j+1-IDELEMS(ide));
156    IDELEMS(ide) = j+1;
157  }
158}
159
160/*2
161* ideal id = (id[i])
162* result is leadcoeff(id[i]) = 1
163*/
164void idNorm(ideal id)
165{
166  for (int i=0; i<IDELEMS(id); i++)
167  {
168    if (id->m[i] != NULL)
169    {
170      pNorm(id->m[i]);
171    }
172  }
173}
174
175/*2
176* ideal id = (id[i]), c any number
177* if id[i] = c*id[j] then id[j] is deleted for j > i
178*/
179void idDelMultiples(ideal id)
180{
181  int i, j, t;
182  int k = IDELEMS(id), l = k;
183  for (i=k-2; i>=0; i--)
184  {
185    if (id->m[i]!=NULL)
186    {
187      for (j=l-1; j>i; j--)
188      {
189        if ((id->m[j]!=NULL)
190        && (pComparePolys(id->m[i], id->m[j])))
191        {
192          pDelete(&id->m[j]);
193          l--;
194          for(t=j; t<l; t++)
195          {
196            id->m[t] = id->m[t+1];
197          }
198        }
199      }
200    }
201  }
202  if (l != k)
203  {
204    pEnlargeSet(&id->m, k, l-k);
205    IDELEMS(id) = l;
206  }
207}
208
209/*2
210* ideal id = (id[i])
211* if id[i] = id[j] then id[j] is deleted for j > i
212*/
213void idDelEquals(ideal id)
214{
215  int i, j, t;
216  int k = IDELEMS(id), l = k;
217  for (i=k-2; i>=0; i--)
218  {
219    for (j=l-1; j>i; j--)
220    {
221      if (pEqualPolys(id->m[i], id->m[j]))
222      {
223        pDelete(&id->m[j]);
224        l--;
225        for(t=j; t<l; t++)
226        {
227          id->m[t] = id->m[t+1];
228        }
229      }
230    }
231  }
232  if (l != k)
233  {
234    pEnlargeSet(&id->m, k, l-k);
235    IDELEMS(id) = l;
236  }
237}
238
239/*2
240* copy an ideal
241*/
242#ifdef MDEBUG
243ideal idDBCopy(ideal h1,char *f,int l)
244#else
245ideal idCopy (ideal h1)
246#endif
247{
248  int i;
249  ideal h2;
250
251//#ifdef TEST
252  if (h1 == NULL)
253  {
254#ifdef MDEBUG
255    h2=idDBInit(1,1,f,l);
256#else
257    h2=idInit(1,1);
258#endif
259  }
260  else
261//#endif
262  {
263#ifdef MDEBUG
264    h2=idDBInit(IDELEMS(h1),h1->rank,f,l);
265#else
266    h2=idInit(IDELEMS(h1),h1->rank);
267#endif
268    for (i=IDELEMS(h1)-1; i>=0; i--)
269#ifdef MDEBUG
270      h2->m[i] = pDBCopy(h1->m[i],f,l);
271#else
272      h2->m[i] = pCopy(h1->m[i]);
273#endif
274  }
275  return h2;
276}
277
278#ifdef PDEBUG
279void idDBTest(ideal h1,char *f,int l)
280{
281  int i;
282
283  if (h1 != NULL)
284  {
285    #ifdef MDEBUG
286    mmDBTestBlock(h1,sizeof(*h1),f,l);
287    #endif
288    for (i=IDELEMS(h1)-1; i>=0; i--)
289      pDBTest(h1->m[i],f,l);
290  }
291}
292#endif
293
294/*3
295* for idSort: compare a and b revlex inclusive module comp.
296*/
297static int pComp_RevLex(poly a, poly b)
298{
299 int l=pVariables;
300 while ((l>=0) && (pGetExp(a,l)==pGetExp(b,l))) l--;
301 if (l<0)
302   return 0;
303 else if (pGetExp(a,l)>pGetExp(b,l))
304   return 1;
305 else
306   return -1;
307}
308
309/*2
310*sorts the ideal w.r.t. the actual ringordering
311*uses lex-ordering when nolex = FALSE
312*/
313intvec *idSort(ideal id,BOOLEAN nolex)
314{
315  poly p,q;
316  intvec * result = new intvec(IDELEMS(id));
317  int i, j, actpos=0, newpos, l;
318  int diff, olddiff, lastcomp, newcomp;
319  BOOLEAN notFound;
320
321  pCompProc oldComp=pComp0;
322
323  if (!nolex) pComp0=pComp_RevLex;
324
325  for (i=0;i<IDELEMS(id);i++)
326  {
327    if (id->m[i]!=NULL)
328    {
329      notFound = TRUE;
330      newpos = actpos / 2;
331      diff = (actpos+1) / 2;
332      diff = (diff+1) / 2;
333      lastcomp = pComp0(id->m[i],id->m[(*result)[newpos]]);
334      if (lastcomp<0)
335      {
336        newpos -= diff;
337      }
338      else if (lastcomp>0)
339      {
340        newpos += diff;
341      }
342      else
343      {
344        notFound = FALSE;
345      }
346      while ((newpos>=0) && (newpos<actpos) && (notFound))
347      {
348        newcomp = pComp0(id->m[i],id->m[(*result)[newpos]]);
349        olddiff = diff;
350        if (diff>1)
351        {
352          diff = (diff+1) / 2;
353          if ((newcomp==1)
354          && (actpos-newpos>1)
355          && (diff>1)
356          && (newpos+diff>=actpos))
357          {
358            diff = actpos-newpos-1;
359          }
360          else if ((newcomp==-1)
361          && (diff>1)
362          && (newpos<diff))
363          {
364            diff = newpos;
365          }
366        }
367        if (newcomp<0)
368        {
369          if ((olddiff==1) && (lastcomp>0))
370            notFound = FALSE;
371          else
372            newpos -= diff;
373        }
374        else if (newcomp>0)
375        {
376          if ((olddiff==1) && (lastcomp<0))
377          {
378            notFound = FALSE;
379            newpos++;
380          }
381          else
382          {
383            newpos += diff;
384          }
385        }
386        else
387        {
388          notFound = FALSE;
389        }
390        lastcomp = newcomp;
391        if (diff==0) notFound=FALSE; /*hs*/
392      }
393      if (newpos<0) newpos = 0;
394      if (newpos>=actpos)
395      {
396        (*result)[actpos] = i;
397      }
398      else
399      {
400        for (j=actpos;j>newpos;j--)
401        {
402          (*result)[j] = (*result)[j-1];
403        }
404        (*result)[newpos] = i;
405      }
406      actpos++;
407    }
408  }
409  for (j=0;j<actpos;j++) (*result)[j]++;
410  pComp0=oldComp;
411  return result;
412}
413
414/*2
415* concat the lists h1 and h2 without zeros
416*/
417ideal idSimpleAdd (ideal h1,ideal h2)
418{
419  int i,j,r,l;
420  ideal result;
421
422  if (h1==NULL) return idCopy(h2);
423  if (h2==NULL) return idCopy(h1);
424  j = IDELEMS(h1);
425  while ((j > 0) && (h1->m[j-1] == NULL)) j--;
426  i = IDELEMS(h2);
427  while ((i > 0) && (h2->m[i-1] == NULL)) i--;
428  if (i+j==0)
429    result = idInit(1,1);
430  else
431    result=idInit(i+j,1);
432  if (h1->rank<h2->rank)
433    result->rank = h2->rank;
434  else
435    result->rank = h1->rank;
436  if (i+j==0) return result;
437  r = 0;
438  for (l=0; l<j; l++)
439  {
440    result->m[r] = pCopy(h1->m[l]);
441    r++;
442  }
443  for (l=0; l<i; l++)
444  {
445    result->m[r] = pCopy(h2->m[l]);
446    r++;
447  }
448  return result;
449}
450
451/*2
452* h1 + h2
453*/
454ideal idAdd (ideal h1,ideal h2)
455{
456  ideal result = idSimpleAdd(h1,h2);
457  ideal tmp = idCompactify(result);
458
459  idDelete(&result);
460  return tmp;
461}
462
463/*2
464* h1 * h2
465*/
466ideal  idMult (ideal h1,ideal  h2)
467{
468  int i,j,k;
469  ideal  hh;
470
471  j = IDELEMS(h1);
472  while ((j > 0) && (h1->m[j-1] == NULL)) j--;
473  i = IDELEMS(h2);
474  while ((i > 0) && (h2->m[i-1] == NULL)) i--;
475  j = j * i;
476  if (j == 0)
477    hh = idInit(1,1);
478  else
479    hh=idInit(j,1);
480  if (h1->rank<h2->rank)
481    hh->rank = h2->rank;
482  else
483    hh->rank = h1->rank;
484  if (j==0) return hh;
485  k = 0;
486  for (i=0; i<IDELEMS(h1); i++)
487  {
488    if (h1->m[i] != NULL)
489    {
490      for (j=0; j<IDELEMS(h2); j++)
491      {
492        if (h2->m[j] != NULL)
493        {
494          hh->m[k] = pMult(pCopy(h1->m[i]),pCopy(h2->m[j]));
495          k++;
496        }
497      }
498    }
499  }
500  {
501    ideal tmp = idCompactify(hh);
502    idDelete(&hh);
503    return tmp;
504    return hh;
505  }
506}
507
508/*2
509*returns true if h is the zero ideal
510*/
511BOOLEAN idIs0 (ideal h)
512{
513  int i;
514
515  if (h == NULL) return TRUE;
516  i = IDELEMS(h);
517  while ((i > 0) && (h->m[i-1] == NULL))
518  {
519    i--;
520  }
521  if (i == 0)
522    return TRUE;
523  else
524    return FALSE;
525}
526
527/*2
528* return the maximal component number found in any polynomial in s
529*/
530int idRankFreeModule (ideal s)
531{
532  if (s!=NULL)
533  {
534    int  j=0;
535    int  l=IDELEMS(s);
536    poly *p=s->m;
537    int  k;
538
539    for (; l != 0; l--)
540    {
541      if (*p!=NULL)
542      {
543        k = pMaxComp(*p);
544        if (k>j) j = k;
545      }
546      p++;
547    }
548    return j;
549  }
550  return -1;
551}
552
553/*2
554*returns true if id is homogenous with respect to the aktual weights
555*/
556BOOLEAN idHomIdeal (ideal id, ideal Q)
557{
558  int i;
559  BOOLEAN     b;
560  if ((id == NULL) || (IDELEMS(id) == 0)) return TRUE;
561  i = 0;
562  b = TRUE;
563  while ((i < IDELEMS(id)) && b)
564  {
565    b = pIsHomogeneous(id->m[i]);
566    i++;
567  }
568  if ((b) && (Q!=NULL) && (IDELEMS(Q)>0))
569  {
570    i=0;
571    while ((i < IDELEMS(Q)) && b)
572    {
573      b = pIsHomogeneous(Q->m[i]);
574      i++;
575    }
576  }
577  return b;
578}
579
580/*2
581*returns a minimized set of generators of h1
582*/
583ideal idMinBase (ideal h1)
584{
585  ideal h2, h3,h4,e;
586  int j,k;
587  int i,l,ll;
588  intvec * wth;
589  BOOLEAN homog;
590
591  homog = idHomModule(h1,currQuotient,&wth);
592  if ((currRing->OrdSgn == 1) && (!homog))
593  {
594    Warn("minbase applies only to the local or homogeneous case");
595    e=idCopy(h1);
596    return e;
597  }
598  if ((currRing->OrdSgn == 1) && (homog))
599  {
600    lists re=min_std(h1,currQuotient,(tHomog)homog,&wth,NULL,0,2);
601    h2 = (ideal)re->m[1].data;
602    re->m[1].data = NULL;
603    re->m[1].rtyp = NONE;
604    re->Clean();
605    return h2;
606  }
607  e=idInit(1,h1->rank);
608  if (idIs0(h1))
609  {
610    return e;
611  }
612  pEnlargeSet(&(e->m),IDELEMS(e),15);
613  IDELEMS(e) = 16;
614  h2 = std(h1,currQuotient,isNotHomog,NULL);
615  h3 = idMaxIdeal();
616  h4=idMult(h2,h3);
617  idDelete(&h3);
618  h3=std(h4,currQuotient,isNotHomog,NULL);
619  k = IDELEMS(h3);
620  while ((k > 0) && (h3->m[k-1] == NULL)) k--;
621  j = -1;
622  l = IDELEMS(h2);
623  while ((l > 0) && (h2->m[l-1] == NULL)) l--;
624  for (i=l-1; i>=0; i--)
625  {
626    if (h2->m[i] != NULL)
627    {
628      ll = 0;
629      while ((ll < k) && ((h3->m[ll] == NULL)
630      || !pDivisibleBy(h3->m[ll],h2->m[i])))
631        ll++;
632      if (ll >= k)
633      {
634        j++;
635        if (j > IDELEMS(e)-1)
636        {
637          pEnlargeSet(&(e->m),IDELEMS(e),16);
638          IDELEMS(e) += 16;
639        }
640        e->m[j] = pCopy(h2->m[i]);
641      }
642    }
643  }
644  idDelete(&h2);
645  idDelete(&h3);
646  idDelete(&h4);
647  if (currQuotient!=NULL)
648  {
649    h3=idInit(1,e->rank);
650    h2=kNF(h3,currQuotient,e);
651    idDelete(&h3);
652    idDelete(&e);
653    e=h2;
654  }
655  idSkipZeroes(e);
656  return e;
657}
658
659/*2
660*the minimal index of used variables - 1
661*/
662int pLowVar (poly p)
663{
664  int k,l,lex;
665
666  if (p == NULL) return -1;
667
668  k = 32000;/*a very large dummy value*/
669  while (p != NULL)
670  {
671    l = 1;
672    lex = pGetExp(p,l);
673    while ((l <= pVariables) && (lex == 0))
674    {
675      l++;
676      lex = pGetExp(p,l);
677    }
678    l--;
679    if (l < k) k = l;
680    pIter(p);
681  }
682  return k;
683}
684
685/*3
686*multiplies p with t (!cas) or  (t-1)
687*the index of t is:1, so we have to shift all variables
688*p is NOT in the actual ring, it has no t
689*/
690static poly pMultWithT (poly p,BOOLEAN cas)
691{
692  /*qp is the working pointer in p*/
693  /*result is the result, qresult is the working pointer*/
694  /*pp is p in the actual ring(shifted), qpp the working pointer*/
695  poly result,qp,pp;
696  poly qresult=NULL;
697  poly qpp=NULL;
698  int  i,j,lex;
699  number n;
700
701  pp = NULL;
702  result = NULL;
703  qp = p;
704  while (qp != NULL)
705  {
706    i = 0;
707    if (result == NULL)
708    {/*first monomial*/
709      result = pInit();
710      qresult = result;
711    }
712    else
713    {
714      qresult->next = pInit();
715      pIter(qresult);
716    }
717    for (j=pVariables-1; j>0; j--)
718    {
719      lex = pGetExp(qp,j);
720      pSetExp(qresult,j+1,lex);/*copy all variables*/
721    }
722    lex = pGetComp(qp);
723    pSetComp(qresult,lex);
724    n=nCopy(pGetCoeff(qp));
725    pSetCoeff0(qresult,n);
726    qresult->next = NULL;
727    pSetm(qresult);
728    /*qresult is now qp brought into the actual ring*/
729    if (cas)
730    { /*case: mult with t-1*/
731      pSetExp(qresult,1,0);
732      pSetm(qresult);
733      if (pp == NULL)
734      { /*first monomial*/
735        pp = pCopy(qresult);
736        qpp = pp;
737      }
738      else
739      {
740        qpp->next = pCopy(qresult);
741        pIter(qpp);
742      }
743      pGetCoeff(qpp)=nNeg(pGetCoeff(qpp));
744      /*now qpp contains -1*qp*/
745    }
746    pSetExp(qresult,1,1);/*this is mult. by t*/
747    pSetm(qresult);
748    pIter(qp);
749  }
750  /*
751  *now p is processed:
752  *result contains t*p
753  * if cas: pp contains -1*p (in the new ring)
754  */
755  if (cas)  qresult->next = pp;
756  /*  else      qresult->next = NULL;*/
757  return result;
758}
759
760/*3
761*deletes the place of t in p (t: variable with index 1)
762*p is NOT in the actual ring: it has pVariables+1 variables
763*/
764static poly pDivByT (poly * p,int size)
765{
766
767  poly result=NULL,
768       resultp=NULL , /** working pointer in result **/
769       pp;
770  int  i,j;
771
772  while (*p != NULL)
773  {
774    i = 0;
775    if (result == NULL)
776    {/*the first monomial*/
777      result = pInit();
778      resultp = result;
779      resultp->next = NULL;
780    }
781    else
782    {
783      resultp->next = pInit();
784      pIter(resultp);
785      resultp->next = NULL;
786    }
787    for (j=1; j<=pVariables; j++)
788    {
789      pSetExp(resultp,j,pGetExp(*p,j+1));
790    }
791    pSetComp(resultp,pGetComp(*p));
792    pSetCoeff0(resultp,pGetCoeff(*p));
793    pSetm(resultp);
794    pp = (*p)->next;
795    Free((ADDRESS)*p,size);
796    *p = pp;
797  }
798  return result;
799}
800
801/*2
802*dehomogenized the generators of the ideal id1 with the leading
803*monomial of p replaced by n
804*/
805ideal idDehomogen (ideal id1,poly p,number n)
806{
807  int i;
808  ideal result;
809
810  if (idIs0(id1))
811  {
812    return idInit(1,id1->rank);
813  }
814  result=idInit(IDELEMS(id1),id1->rank);
815  for (i=0; i<IDELEMS(id1); i++)
816  {
817    result->m[i] = pDehomogen(id1->m[i],p,n);
818  }
819  return result;
820}
821
822/*2
823* verschiebt die Indizees der Modulerzeugenden um i
824*/
825void pShift (poly * p,int i)
826{
827  poly qp1 = *p,qp2 = *p;/*working pointers*/
828  int     j = pMaxComp(*p),k = pMinComp(*p);
829
830  if (j+i < 0) return ;
831  while (qp1 != NULL)
832  {
833    if ((pGetComp(qp1)+i > 0) || ((j == -i) && (j == k)))
834    {
835      pSetComp(qp1,pGetComp(qp1)+i);
836      qp2 = qp1;
837      pIter(qp1);
838    }
839    else
840    {
841      if (qp2 == *p)
842      {
843        pIter(*p);
844        qp2->next = NULL;
845        pDelete(&qp2);
846        qp2 = *p;
847        qp1 = *p;
848      }
849      else
850      {
851        qp2->next = qp1->next;
852        qp1->next = NULL;
853        pDelete(&qp1);
854        qp1 = qp2->next;
855      }
856    }
857  }
858}
859
860/*2
861*initialized a field with r numbers between beg and end for the
862*procedure idNextChoise
863*/
864void idInitChoise (int r,int beg,int end,BOOLEAN  *endch,int * choise)
865{
866  /*returns the first choise of r numbers between beg and end*/
867  int i;
868  for (i=0; i<r; i++)
869  {
870    choise[i] = 0;
871  }
872  if (r <= end-beg+1)
873    for (i=0; i<r; i++)
874    {
875      choise[i] = beg+i;
876    }
877  if (r > end-beg+1)
878    *endch = TRUE;
879  else
880    *endch = FALSE;
881}
882
883/*2
884*returns the next choise of r numbers between beg and end
885*/
886void idGetNextChoise (int r,int end,BOOLEAN  *endch,int * choise)
887{
888  int i = r-1,j;
889  while ((i >= 0) && (choise[i] == end))
890  {
891    i--;
892    end--;
893  }
894  if (i == -1)
895    *endch = TRUE;
896  else
897  {
898    choise[i]++;
899    for (j=i+1; j<r; j++)
900    {
901      choise[j] = choise[i]+j-i;
902    }
903    *endch = FALSE;
904  }
905}
906
907/*2
908*takes the field choise of d numbers between beg and end, cancels the t-th
909*entree and searches for the ordinal number of that d-1 dimensional field
910* w.r.t. the algorithm of construction
911*/
912int idGetNumberOfChoise(int t, int d, int begin, int end, int * choise)
913{
914  int * localchoise,i,result=0;
915  BOOLEAN b=FALSE;
916
917  if (d<=1) return 1;
918  localchoise=(int*)Alloc((d-1)*sizeof(int));
919  idInitChoise(d-1,begin,end,&b,localchoise);
920  while (!b)
921  {
922    result++;
923    i = 0;
924    while ((i<t) && (localchoise[i]==choise[i])) i++;
925    if (i>=t)
926    {
927      i = t+1;
928      while ((i<d) && (localchoise[i-1]==choise[i])) i++;
929      if (i>=d)
930      {
931        Free((ADDRESS)localchoise,(d-1)*sizeof(int));
932        return result;
933      }
934    }
935    idGetNextChoise(d-1,end,&b,localchoise);
936  }
937  Free((ADDRESS)localchoise,(d-1)*sizeof(int));
938  return 0;
939}
940
941/*2
942*computes the binomial coefficient
943*/
944int binom (int n,int r)
945{
946  int i,result;
947
948  if (r==0) return 1;
949  if (n-r<r) return binom(n,n-r);
950  result = n-r+1;
951  for (i=2;i<=r;i++)
952  {
953    result *= n-r+i;
954    result /= i;
955  }
956  return result;
957}
958
959/*2
960*the free module of rank i
961*/
962ideal idFreeModule (int i)
963{
964  int j;
965  ideal h;
966
967  h=idInit(i,i);
968  for (j=0; j<i; j++)
969  {
970    h->m[j] = pOne();
971    pSetComp(h->m[j],j+1);
972  }
973  return h;
974}
975
976/*2
977* h3 := h1 intersect h2
978*/
979ideal idSect (ideal h1,ideal h2)
980{
981  ideal first=h2,second=h1,temp,temp1,result;
982  int i,j,k,flength,slength,length,rank=min(h1->rank,h2->rank);
983  intvec *w;
984  poly p,q;
985
986  if ((idIs0(h1)) && (idIs0(h2)))  return idInit(1,rank);
987  if (IDELEMS(h1)<IDELEMS(h2))
988  {
989    first = h1;
990    second = h2;
991  }
992  flength = idRankFreeModule(first);
993  slength = idRankFreeModule(second);
994  length  = max(flength,slength);
995  if (length==0)
996  {
997    length = 1;
998  }
999  temp = idInit(IDELEMS(first),1);
1000  j = IDELEMS(temp);
1001  while ((j>0) && (first->m[j-1]==NULL)) j--;
1002  k = 0;
1003  for (i=0;i<j;i++)
1004  {
1005    if (first->m[i]!=NULL)
1006    {
1007      temp->m[k] = pCopy(first->m[i]);
1008      q = pOne();
1009      pSetComp(q,i+1+length);
1010      if (flength==0) pShift(&(temp->m[k]),1);
1011      p = temp->m[k];
1012      while (pNext(p)) pIter(p);
1013      pNext(p) = q;
1014      k++;
1015    }
1016  }
1017  pEnlargeSet(&(temp->m),IDELEMS(temp),j+IDELEMS(second)-IDELEMS(temp));
1018  IDELEMS(temp) = j+IDELEMS(second);
1019  for (i=0;i<IDELEMS(second);i++)
1020  {
1021    if (second->m[i]!=NULL)
1022    {
1023      temp->m[k] = pCopy(second->m[i]);
1024      if (slength==0) pShift(&(temp->m[k]),1);
1025      k++;
1026    }
1027  }
1028  pSetSyzComp(length);
1029  temp1 = std(temp,currQuotient,testHomog,&w,NULL,length);
1030  if (w!=NULL) delete w;
1031  pSetSyzComp(0);
1032  idDelete(&temp);
1033  result = idInit(IDELEMS(temp1),rank);
1034  j = 0;
1035  for (i=0;i<IDELEMS(temp1);i++)
1036  {
1037    if ((temp1->m[i]!=NULL)
1038    && (pGetComp(temp1->m[i])>length))
1039    {
1040      p = temp1->m[i];
1041//PrintS("die Syzygie ist: ");pWrite(p);
1042      temp1->m[i] = NULL;
1043      while (p!=NULL)
1044      {
1045        q = pNext(p);
1046        pNext(p) = NULL;
1047        k = pGetComp(p)-1-length;
1048        pSetComp(p,0);
1049//PrintS("das %d-te Element: ",k);pWrite(first->m[k]);
1050        result->m[j] = pAdd(result->m[j],pMult(pCopy(first->m[k]),p));
1051        p = q;
1052      }
1053//PrintS("Generator ist: ");pWrite(result->m[j]);
1054      j++;
1055    }
1056  }
1057  idSkipZeroes(result);
1058  return result;
1059}
1060
1061/*2
1062* ideal/module intersection for a list of objects
1063* given as 'resolvente'
1064*/
1065ideal idMultSect(resolvente arg, int length)
1066{
1067  int i,j=0,k=0,syzComp,l,maxrk=-1,realrki;
1068  ideal bigmat,tempstd,result;
1069  poly p;
1070  int isIdeal=0;
1071  intvec * w=NULL;
1072
1073  /* find 0-ideals and max rank -----------------------------------*/
1074  for (i=0;i<length;i++)
1075  {
1076    if (!idIs0(arg[i]))
1077    {
1078      realrki=idRankFreeModule(arg[i]);
1079      k++;
1080      j += IDELEMS(arg[i]);
1081      if (realrki>maxrk) maxrk = realrki;
1082    }
1083    else
1084    {
1085      if (arg[i]!=NULL)
1086      {
1087        return idInit(1,arg[i]->rank);
1088      }
1089    }
1090  }
1091  if (maxrk == 0)
1092  {
1093    isIdeal = 1;
1094    maxrk = 1;
1095  }
1096  /* init -----------------------------------------------------------*/
1097  j += maxrk;
1098  bigmat = idInit(j,(k+1)*maxrk);
1099  syzComp = k*maxrk;
1100  pSetSyzComp(syzComp);
1101  /* create unit matrices ------------------------------------------*/
1102  for (i=0;i<maxrk;i++)
1103  {
1104    for (j=0;j<=k;j++)
1105    {
1106      p = pOne();
1107      pSetComp(p,i+1+j*maxrk);
1108      pSetm(p);
1109      bigmat->m[i] = pAdd(bigmat->m[i],p);
1110    }
1111  }
1112  /* enter given ideals ------------------------------------------*/
1113  i = maxrk;
1114  k = 0;
1115  for (j=0;j<length;j++)
1116  {
1117    if (arg[j]!=NULL)
1118    {
1119      for (l=0;l<IDELEMS(arg[j]);l++)
1120      {
1121        if (arg[j]->m[l]!=NULL)
1122        {
1123          bigmat->m[i] = pCopy(arg[j]->m[l]);
1124          pShift(&(bigmat->m[i]),k*maxrk+isIdeal);
1125          i++;
1126        }
1127      }
1128      k++;
1129    }
1130  }
1131  /* std computation --------------------------------------------*/
1132  tempstd = std(bigmat,currQuotient,testHomog,&w,NULL,syzComp);
1133  if (w!=NULL) delete w;
1134  idDelete(&bigmat);
1135  pSetSyzComp(0);
1136  /* interprete result ----------------------------------------*/
1137  result = idInit(8,maxrk);
1138  k = 0;
1139  for (j=0;j<IDELEMS(tempstd);j++)
1140  {
1141    if ((tempstd->m[j]!=NULL) && (pGetComp(tempstd->m[j])>syzComp))
1142    {
1143      if (k>=IDELEMS(result))
1144      {
1145        pEnlargeSet(&(result->m),IDELEMS(result),8);
1146        IDELEMS(result) += 8;
1147      }
1148      p = tempstd->m[j];
1149      tempstd->m[j] = NULL;
1150      pShift(&p,-syzComp-isIdeal);
1151      result->m[k] = p;
1152      k++;
1153    }
1154  }
1155  /* clean up ----------------------------------------------------*/
1156  idDelete(&tempstd);
1157  idSkipZeroes(result);
1158  return result;
1159}
1160
1161/*2
1162*computes the rank of the free module in which h1 embeds
1163*/
1164int lengthFreeModule (ideal  h1)
1165{
1166  int     i,j,k;
1167
1168  if (idIs0(h1)) return 0;
1169  k = -1;
1170  for (i=0; i<IDELEMS(h1); i++)
1171  {
1172    j = pMaxComp(h1->m[i]);
1173    if (j>k) k = j;
1174  }
1175  return k;
1176}
1177
1178/*2
1179*computes syzygies of h1,
1180*if quot != NULL it computes in the quotient ring modulo "quot"
1181*/
1182ideal  idPrepare (ideal  h1,ideal  quot, tHomog h,
1183  int* syzcomp, int *quotgen, int *quotdim, intvec **w)
1184{
1185  ideal   h2, h3;
1186  int     i;
1187  int     j,k;
1188  poly    p,q;
1189  BOOLEAN orderChanged=FALSE;
1190
1191  if (idIs0(h1)) return NULL;
1192  k = lengthFreeModule(h1);
1193  if (*syzcomp<k) *syzcomp = k;
1194  h2 = NULL;
1195  h2=idCopy(h1);
1196  i = IDELEMS(h2)-1;
1197  //while ((i >= 0) && (h2->m[i] == NULL)) i--;
1198  if (k == 0)
1199  {
1200    for (j=0; j<=i; j++) pShift(&(h2->m[j]),1);
1201    *syzcomp = 1;
1202  }
1203  h2->rank = *syzcomp+i+1;
1204  for (j=0; j<=i; j++)
1205  {
1206    p = h2->m[j];
1207    q = pOne();
1208#ifdef DRING
1209    if (pDRING) { pdDFlag(q)=1; pSetm(q); }
1210#endif
1211    pSetComp(q,*syzcomp+1+j);
1212    if (p!=NULL)
1213    {
1214      while (pNext(p)) pIter(p);
1215      p->next = q;
1216    }
1217    else
1218      h2->m[j]=q;
1219  }
1220  if ((pOrdSgn!=1) || (h!=TRUE) || (*syzcomp>1)|| (pLexOrder))
1221  {
1222    pSetSyzComp(*syzcomp);
1223    orderChanged=TRUE;
1224  }
1225  else
1226  {
1227    for(j=0;(j<IDELEMS(h2) && (!orderChanged));j++)
1228    {
1229      if (h2->m[j] != NULL)
1230      {
1231        p=h2->m[j];
1232        while ((p!=NULL)
1233        && (pGetComp(p)<=*syzcomp))
1234        {
1235          if (pIsConstantComp(p))
1236          {
1237            pSetSyzComp(*syzcomp);
1238            orderChanged=TRUE;
1239            break;
1240          }
1241          pIter(p);
1242        }
1243      }
1244    }
1245  }
1246//  if (orderChanged) PrintS("order changed\n");
1247//  else PrintS("order not changed\n");
1248#ifdef PDEBUG
1249  for(j=0;j<IDELEMS(h2);j++) pTest(h2->m[j]);
1250#endif
1251  h3=std(h2,quot,h,w,NULL,*syzcomp);
1252  //h3->rank = h2->rank; done by std -> initBuchMora -> initS
1253  h3->rank-=*syzcomp;
1254  idDelete(&h2);
1255  if (orderChanged) pSetSyzComp(0);
1256  return h3;
1257}
1258
1259ideal idSyzygies (ideal  h1,ideal  quot, tHomog h,intvec **w)
1260{
1261  int d;
1262  return idSyzygies(h1,quot,h,w,FALSE,d);
1263}
1264
1265ideal idSyzygies (ideal  h1,ideal  quot, tHomog h,intvec **w,
1266                  BOOLEAN setRegularity, int &deg)
1267{
1268  ideal e, h3;
1269  poly  p;
1270  int   i, j, k=0, quotdim, quotgen,length=0,reg;
1271  BOOLEAN isMonomial=TRUE;
1272
1273#ifdef PDEBUG
1274  int ii;
1275  for(ii=0;ii<IDELEMS(h1);ii++) pTest(h1->m[ii]);
1276  if (quot!=NULL)
1277  {
1278    for(ii=0;ii<IDELEMS(quot);ii++) pTest(quot->m[ii]);
1279  }
1280#endif
1281  if (idIs0(h1))
1282    return idFreeModule(IDELEMS(h1));
1283  h3=idPrepare(h1,quot,h,&k,&quotgen,&quotdim,w);
1284  if (h3==NULL)
1285    return idFreeModule(IDELEMS(h1));
1286  i = -1;
1287  e=idInit(16,h3->rank);
1288  for (j=0; j<IDELEMS(h3); j++)
1289  {
1290    if (h3->m[j] != NULL)
1291    {
1292      if (pMinComp(h3->m[j]) > k)
1293      {
1294        p = h3->m[j];
1295        h3->m[j]=NULL;
1296        pShift(&p,-k);
1297        if (p!=NULL)
1298        {
1299          i++;
1300          if (i+1 >= IDELEMS(e))
1301          {
1302            pEnlargeSet(&(e->m),IDELEMS(e),16);
1303            IDELEMS(e) += 16;
1304          }
1305          e->m[i] = p;
1306        }
1307      }
1308      else
1309      {
1310        isMonomial=isMonomial && (pNext(h3->m[j])==NULL);
1311        pDelete(&pNext(h3->m[j]));
1312      }
1313    }
1314  }
1315  if ((!isMonomial) && (!TEST_OPT_NOTREGULARITY) && (setRegularity) && (h==isHomog))
1316  {
1317    idSkipZeroes(h3);
1318    resolvente res = sySchreyerResolvente(h3,-1,&length,TRUE);
1319    intvec * dummy = syBetti(res,length,&reg, *w);
1320    deg = reg+2;
1321    delete dummy;
1322    for (j=0;j<length;j++)
1323    {
1324      if (res[j]!=NULL) idDelete(&(res[j]));
1325    }
1326    Free((ADDRESS)res,length*sizeof(ideal));
1327  }
1328  idDelete(&h3);
1329  idSkipZeroes(e);
1330  return e;
1331}
1332
1333/*2
1334* computes syzygies and minimizes the input (h1)
1335* ONLY used in syMinRes
1336*/
1337ideal idSyzMin (ideal h1,ideal  quot, tHomog h,intvec **w,
1338                  BOOLEAN setRegularity, int &deg)
1339{
1340  ideal e, h3;
1341  poly  p;
1342  intvec * reord;
1343  int   i, l=0, j, k=0, quotdim, quotgen,length=0,reg;
1344  BOOLEAN isMonomial=TRUE;
1345
1346  if (idIs0(h1))
1347    return idFreeModule(1);
1348//PrintS("h1 vorher\n");
1349//for (i=0;i<IDELEMS(h1);i++)
1350//{
1351//Print("Element %d: ",i);pWrite(h1->m[i]);
1352//}
1353  idSkipZeroes(h1);
1354  h3=idPrepare(h1,quot,h,&k,&quotgen,&quotdim,w);
1355//PrintS("h1 nachher\n");
1356//for (i=0;i<IDELEMS(h3);i++)
1357//{
1358//Print("Element %d: ",i);pWrite(h3->m[i]);
1359//}
1360  if (h3==NULL)
1361    return idFreeModule(1);
1362  for (i=IDELEMS(h1);i!=0;i--)
1363    pDelete(&(h1->m[i-1]));
1364  reord = new intvec(IDELEMS(h1)+1);
1365  i = -1;
1366  e=idInit(16,h3->rank);
1367  for (j=0; j<IDELEMS(h3); j++)
1368  {
1369    if (h3->m[j] != NULL)
1370    {
1371      p = h3->m[j];
1372      if (pGetComp(p) > k)
1373      {
1374        h3->m[j]=NULL;
1375        pShift(&p,-k);
1376        if (p!=NULL)
1377        {
1378          i++;
1379          if (i+1 >= IDELEMS(e))
1380          {
1381            pEnlargeSet(&(e->m),IDELEMS(e),16);
1382            IDELEMS(e) += 16;
1383          }
1384          e->m[i] = p;
1385        }
1386      }
1387      else
1388      {
1389        while ((pNext(p)!=NULL) && (pGetComp(pNext(p))<=k)) pIter(p);
1390        if (pIsConstantComp(pNext(p)))
1391        {
1392          (*reord)[pGetComp(pNext(p))-k] = l+1;
1393//Print("Element %d mit Comp %d: ",j,pGetComp(pNext(p))-k);
1394//pWrite(h3->m[j]);
1395          h1->m[l] = h3->m[j];
1396          h3->m[j] = pCopy(h1->m[l]);
1397          pDelete(&pNext(p));
1398          l++;
1399        }
1400        isMonomial=isMonomial && (pGetComp(pNext(h3->m[j]))>k);
1401        pDelete(&pNext(h3->m[j]));
1402      }
1403    }
1404  }
1405  if ((!isMonomial) && (!TEST_OPT_NOTREGULARITY) && (setRegularity) && (h==isHomog))
1406  {
1407    idSkipZeroes(h3);
1408    resolvente res = sySchreyerResolvente(h3,0,&length);
1409    intvec * dummy = syBetti(res,length,&reg, *w);
1410    deg = reg+2;
1411    delete dummy;
1412    for (j=0;j<length;j++)
1413    {
1414      if (res[j]!=NULL) idDelete(&(res[j]));
1415    }
1416    Free((ADDRESS)res,length*sizeof(ideal));
1417  }
1418  idDelete(&h3);
1419//PrintS("Komponententransformation: ");
1420//reord->show();
1421//PrintLn();
1422  for (i=IDELEMS(e);i!=0;i--)
1423  {
1424    if (e->m[i-1]!=NULL)
1425    {
1426      p = e->m[i-1];
1427      while (p!=NULL)
1428      {
1429        j = pGetComp(p);
1430        pSetComp(p,(*reord)[j]);
1431        pIter(p);
1432      }
1433      e->m[i-1] = pOrdPolyMerge(e->m[i-1]);
1434    }
1435  }
1436  idSkipZeroes(e);
1437  delete reord;
1438  return e;
1439}
1440
1441/*
1442*computes a standard basis for h1 and stores the transformation matrix
1443* in ma
1444*/
1445ideal idLiftStd (ideal  h1,ideal  quot, matrix* ma, tHomog h)
1446{
1447  int   i, j, k=0, t, quotgen, inputIsIdeal=lengthFreeModule(h1);
1448  ideal e, h3;
1449  poly  p=NULL, q, qq;
1450  intvec *w=NULL;
1451
1452  idDelete((ideal*)ma);
1453  *ma=mpNew(1,0);
1454  if (idIs0(h1))
1455    return idInit(1,h1->rank);
1456  h3=idPrepare(h1,quot,h,&k,&quotgen,&i,&w);
1457  if (w!=NULL) delete w;
1458  i = 0;
1459  for (j=0;j<IDELEMS(h3);j++)
1460  {
1461    if ((h3->m[j] != NULL) && (pMinComp(h3->m[j]) <= k))
1462      i++;
1463  }
1464  j = IDELEMS(h1);
1465  idDelete((ideal*)ma);
1466  *ma = mpNew(j,i);
1467  i = -1;
1468  e=idInit(16,h1->rank);
1469  for (j=0; j<IDELEMS(h3); j++)
1470  {
1471    if ((h3->m[j] != NULL) && (pMinComp(h3->m[j]) <= k))
1472    {
1473      q = h3->m[j];
1474      qq=q;
1475      h3->m[j]=NULL;
1476      while (pNext(q) != NULL)
1477      {
1478        if (pGetComp(pNext(q)) > k)
1479        {
1480          p = pNext(q);
1481          pNext(q) = pNext(pNext(q));
1482          pNext(p) = NULL;
1483          t=pGetComp(p);
1484          pSetComp(p,0);
1485          MATELEM(*ma,t-k,i+2) = pAdd(MATELEM(*ma,t-k,i+2),p);
1486        }
1487        else
1488        {
1489          pIter(q);
1490        }
1491      }
1492      if (!inputIsIdeal) pShift(&qq,-1);
1493      //if (quotgen != 0)
1494      //{
1495      //  q = kNF(quot,qq);
1496      //  pDelete(&qq);
1497      //}
1498      //else
1499        q = qq;
1500      if (q !=NULL)
1501      {
1502        i++;
1503        if (i+1 >= IDELEMS(e))
1504        {
1505          pEnlargeSet(&(e->m),IDELEMS(e),16);
1506          IDELEMS(e) += 16;
1507        }
1508        e->m[i] = q;
1509      }
1510    }
1511  }
1512  idDelete(&h3);
1513  idSkipZeroes(e);
1514  return e;
1515}
1516
1517/*2
1518*computes a representation of the generators of submod with respect to those
1519* of mod
1520*/
1521ideal idLiftNonStB (ideal  mod, ideal submod)
1522{
1523  int   lsmod =idRankFreeModule(submod), i, j, k, quotgen;
1524  ideal result, h3, temp;
1525
1526  if (idIs0(mod))
1527    return idInit(1,mod->rank);
1528
1529  if  ((idRankFreeModule(mod)!=0) && (lsmod==0)) lsmod=1;
1530  k=lsmod;
1531  //idSkipZeroes(mod);
1532  h3=idPrepare(mod,currQuotient,(tHomog)FALSE,&k,&quotgen,&i,NULL);
1533  for (j=0;j<IDELEMS(h3);j++)
1534  {
1535    if ((h3->m[j] != NULL) && (pMinComp(h3->m[j]) > k))
1536      pDelete(&(h3->m[j]));
1537  }
1538  idSkipZeroes(h3);
1539  if (lsmod==0)
1540  {
1541    temp = idCopy(submod);
1542    for (j=IDELEMS(temp);j>0;j--)
1543    {
1544      if (temp->m[j-1]!=NULL)
1545        pShift(&(temp->m[j-1]),1);
1546    }
1547  }
1548  else
1549  {
1550    temp = submod;
1551  }
1552  pSetSyzComp(k);
1553  result = kNF(h3,currQuotient,temp,k);
1554  result->rank = h3->rank;
1555  idDelete(&h3);
1556  if (lsmod==0)
1557    idDelete(&temp);
1558  pSetSyzComp(0);
1559  for (j=0;j<IDELEMS(result);j++)
1560  {
1561    if (result->m[j]!=NULL)
1562    {
1563      if (pGetComp(result->m[j])<=k)
1564      {
1565        WerrorS("2nd module lies not in the first");
1566        idDelete(&result);
1567        return idInit(1,1);
1568      }
1569      else
1570      {
1571        pShift(&(result->m[j]),-k);
1572        pNeg(result->m[j]);
1573      }
1574    }
1575  }
1576  return result;
1577}
1578
1579/*2
1580*computes a representation of the generators of submod with respect to those
1581* of mod which is given as standardbasis,
1582* uses currQuotient as the quotient ideal (if not NULL)
1583*/
1584ideal  idLift (ideal  mod,ideal submod)
1585{
1586  ideal temp, result;
1587  int   j,k;
1588  poly  p,q;
1589  BOOLEAN reported=FALSE;
1590
1591  if (idIs0(mod)) return idInit(1,mod->rank);
1592  k = lengthFreeModule(mod);
1593  temp=idCopy(mod);
1594  if (k == 0)
1595  {
1596    for (j=0; j<IDELEMS(temp); j++)
1597    {
1598      if (temp->m[j]!=NULL) pSetCompP(temp->m[j],1);
1599    }
1600    k = 1;
1601  }
1602  for (j=0; j<IDELEMS(temp); j++)
1603  {
1604    if (temp->m[j]!=NULL)
1605    {
1606      p = temp->m[j];
1607      q = pOne();
1608      pGetCoeff(q)=nNeg(pGetCoeff(q));   //set q to -1
1609      pSetComp(q,k+1+j);
1610      while (pNext(p)) pIter(p);
1611      pNext(p) = q;
1612    }
1613  }
1614  result=idInit(IDELEMS(submod),submod->rank);
1615  pSetSyzComp(k);
1616  for (j=0; j<IDELEMS(submod); j++)
1617  {
1618    if (submod->m[j]!=NULL)
1619    {
1620      p = pCopy(submod->m[j]);
1621      if (pGetComp(p)==0) pSetCompP(p,1);
1622      q = kNF(temp,currQuotient,p);
1623      pDelete(&p);
1624      if (q!=NULL)
1625      {
1626        if (pMinComp(q)<=k)
1627        {
1628          if (!reported)
1629          {
1630            Warn("first module not a standardbasis");
1631            Warn("or second not a proper submodule");
1632            reported=TRUE;
1633          }
1634          pDelete(&q);
1635        }
1636        else
1637        {
1638          pShift(&q,-k);
1639          result->m[j] = q;
1640        }
1641      }
1642    }
1643  }
1644  pSetSyzComp(0);
1645  //idSkipZeroes(result);
1646  idDelete(&temp);
1647  return result;
1648}
1649
1650/*2
1651*computes the quotient of h1,h2
1652*/
1653#ifdef OLD_QUOT
1654ideal idQuot (ideal  h1, ideal h2, BOOLEAN h1IsSB)
1655{
1656  int i,j = 0,l,ll,k,kkk,k1,k2,kmax;
1657  ideal h3,h4;
1658  poly     p,q = NULL;
1659  BOOLEAN     b = FALSE;
1660
1661  k1 = lengthFreeModule(h1);
1662  k2 = lengthFreeModule(h2);
1663  k=max(k1,k2);
1664  if (k==0) { k = 1; b=TRUE; }
1665  h4 = idInit(1,1);
1666  for (i=0; i<IDELEMS(h2); i++)
1667  {
1668    if (h2->m[i] != NULL)
1669    {
1670      p = pCopy(h2->m[i]);
1671      if (k2 == 0)
1672        pShift(&p,j*k+1);
1673      else
1674        pShift(&p,j*k);
1675      q = pAdd(q,p);
1676      j++;
1677    }
1678  }
1679  kmax = j*k+1;
1680  p = pOne();
1681  pSetComp(p,kmax);
1682  pSetSyzComp(kmax-1);
1683  q = pAdd(q,p);
1684  h4->m[0] = q;
1685  if (k2 == 0)
1686  {
1687    if (k > IDELEMS(h4))
1688    {
1689      pEnlargeSet(&(h4->m),IDELEMS(h4),k-IDELEMS(h4));
1690      IDELEMS(h4) = k;
1691    }
1692    for (i=1; i<k; i++)
1693    {
1694      p = pCopy(h4->m[i-1]);
1695      pShift(&p,1);
1696      h4->m[i] = p;
1697    }
1698  }
1699  kkk = IDELEMS(h4);
1700  i = IDELEMS(h1);
1701  while (h1->m[i-1] == NULL) i--;
1702  for (l=0; l<i; l++)
1703  {
1704    if(h1->m[l]!=NULL)
1705    {
1706      for (ll=0; ll<j; ll++)
1707      {
1708        p = pCopy(h1->m[l]);
1709        if (k1 == 0)
1710          pShift(&p,ll*k+1);
1711        else
1712          pShift(&p,ll*k);
1713        if (kkk >= IDELEMS(h4))
1714        {
1715          pEnlargeSet(&(h4->m),IDELEMS(h4),16);
1716          IDELEMS(h4) += 16;
1717        }
1718        h4->m[kkk] = p;
1719        kkk++;
1720      }
1721    }
1722  }
1723  h3 = std(h4,currQuotient,(tHomog)FALSE,NULL,NULL,kmax-1);
1724  pSetSyzComp(0);
1725  idDelete(&h4);
1726  for (i=0;i<IDELEMS(h3);i++)
1727  {
1728    if ((h3->m[i]!=NULL) && (pGetComp(h3->m[i])>=kmax))
1729    {
1730      if (b)
1731        pShift(&h3->m[i],-kmax);
1732      else
1733        pShift(&h3->m[i],-kmax+1);
1734    }
1735    else
1736      pDelete(&h3->m[i]);
1737  }
1738  if (b)
1739    h3->rank = 1;
1740  else
1741    h3->rank = h1->rank;
1742  h4=idCompactify(h3);
1743  idDelete(&h3);
1744  return h4;
1745}
1746#else
1747ideal idQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb)
1748{
1749  int i,j = 0,l,ll,k,kkk,k1,k2,kmax;
1750  intvec * weights,* weights1;
1751  ideal h3,h4,temph1;
1752  poly     p,q = NULL;
1753  BOOLEAN  resultIsIdeal = FALSE,addOnlyOne=TRUE;
1754  tHomog   hom=isNotHomog;
1755  BITSET old_test=test;
1756
1757  k1 = lengthFreeModule(h1);
1758  k2 = lengthFreeModule(h2);
1759  if (idIs0(h2))
1760  {
1761    if (k1==0)
1762    {
1763      h3 = idInit(1,1);
1764      h3->m[0] = pOne();
1765    }
1766    else
1767      h3 = idFreeModule(h1->rank);
1768    return h3;
1769  }
1770  k=max(k1,k2);
1771  if (k==0)
1772  {
1773    k = 1;
1774    resultIsIdeal=TRUE;
1775  }
1776  else if ((k1>0)&&(k2>0))
1777  {
1778    resultIsIdeal=TRUE;
1779  }
1780  hom = (tHomog)idHomModule(h1,currQuotient,&weights) ;
1781  h4 = idInit(1,1);
1782  for (i=0; i<IDELEMS(h2); i++)
1783  {
1784    if (h2->m[i] != NULL)
1785    {
1786      p = pCopy(h2->m[i]);
1787      if (k2 == 0)
1788        pShift(&p,j*k+1);
1789      else
1790        pShift(&p,j*k);
1791      q = pAdd(q,p);
1792      j++;
1793    }
1794  }
1795  kmax = j*k+1;
1796  p = pOne();
1797  pSetComp(p,kmax);
1798  pSetSyzComp(kmax-1);
1799  q = pAdd(q,p);
1800  h4->m[0] = q;
1801  if (k2 == 0)
1802  {
1803    if (k > IDELEMS(h4))
1804    {
1805      pEnlargeSet(&(h4->m),IDELEMS(h4),k-IDELEMS(h4));
1806      IDELEMS(h4) = k;
1807    }
1808    if (k>1) addOnlyOne = FALSE;
1809    for (i=1; i<k; i++)
1810    {
1811      p = pCopy(h4->m[i-1]);
1812      pShift(&p,1);
1813      h4->m[i] = p;
1814    }
1815  }
1816  kkk = IDELEMS(h4);
1817  if (addOnlyOne && (!h1IsStb))
1818    temph1 = std(h1,currQuotient,hom,&weights,NULL);
1819  else
1820    temph1 = h1;
1821  idTest(temph1);
1822  i = IDELEMS(temph1);
1823  while ((i>0) && (temph1->m[i-1]==NULL)) i--;
1824  for (l=0; l<i; l++)
1825  {
1826    if(temph1->m[l]!=NULL)
1827    {
1828      for (ll=0; ll<j; ll++)
1829      {
1830        p = pCopy(temph1->m[l]);
1831        if (k1 == 0)
1832          pShift(&p,ll*k+1);
1833        else
1834          pShift(&p,ll*k);
1835        if (kkk >= IDELEMS(h4))
1836        {
1837          pEnlargeSet(&(h4->m),IDELEMS(h4),16);
1838          IDELEMS(h4) += 16;
1839        }
1840        h4->m[kkk] = p;
1841        kkk++;
1842      }
1843    }
1844  }
1845  idTest(h4);
1846  if (addOnlyOne)
1847  {
1848    p = h4->m[0];
1849    for (i=0;i<IDELEMS(h4)-1;i++)
1850    {
1851      h4->m[i] = h4->m[i+1];
1852    }
1853    h4->m[IDELEMS(h4)-1] = p;
1854    idSkipZeroes(h4);
1855    test |= Sy_bit(OPT_SB_1);
1856  }
1857  idTest(h4);
1858  hom = (tHomog)idHomModule(h4,currQuotient,&weights1);
1859  if (addOnlyOne)
1860  {
1861    h3 = std(h4,currQuotient,hom,&weights1,NULL,kmax-1,IDELEMS(h4)-1);
1862  }
1863  else
1864  {
1865    h3 = std(h4,currQuotient,hom,&weights1,NULL,kmax-1);
1866  }
1867  idTest(h3);
1868  idDelete(&h4);
1869  pSetSyzComp(0);
1870  for (i=0;i<IDELEMS(h3);i++)
1871  {
1872    if ((h3->m[i]!=NULL) && (pGetComp(h3->m[i])>=kmax))
1873    {
1874      if (resultIsIdeal)
1875        pShift(&h3->m[i],-kmax);
1876      else
1877        pShift(&h3->m[i],-kmax+1);
1878    }
1879    else
1880      pDelete(&h3->m[i]);
1881  }
1882  if (resultIsIdeal)
1883    h3->rank = 1;
1884  else
1885    h3->rank = h1->rank;
1886  idTest(h3);
1887  idSkipZeroes(h3);
1888  //h4=idCompactify(h3);
1889  //idDelete(&h3);
1890  if ((addOnlyOne) && (!h1IsStb))
1891    idDelete(&temph1);
1892  if (weights!=NULL) delete weights;
1893  if (weights1!=NULL) delete weights1;
1894  test = old_test;
1895  return h3;
1896}
1897#endif
1898
1899/*2
1900*computes recursively all monomials of a certain degree
1901*in every step the actvar-th entry in the exponential
1902*vector is incremented and the other variables are
1903*computed by recursive calls of makemonoms
1904*if the last variable is reached, the difference to the
1905*degree is computed directly
1906*vars is the number variables
1907*actvar is the actual variable to handle
1908*deg is the degree of the monomials to compute
1909*monomdeg is the actual degree of the monomial in consideration
1910*/
1911static void makemonoms(int vars,int actvar,int deg,int monomdeg)
1912{
1913  poly p;
1914  int i=0;
1915
1916  if ((idpowerpoint == 0) && (actvar ==1))
1917  {
1918    idpower[idpowerpoint] = pOne();
1919    monomdeg = 0;
1920  }
1921  while (i<=deg)
1922  {
1923    if (deg == monomdeg)
1924    {
1925      pSetm(idpower[idpowerpoint]);
1926      idpowerpoint++;
1927      return;
1928    }
1929    if (actvar == vars)
1930    {
1931      pSetExp(idpower[idpowerpoint],actvar,deg-monomdeg);
1932      pSetm(idpower[idpowerpoint]);
1933      idpowerpoint++;
1934      return;
1935    }
1936    else
1937    {
1938      p = pCopy(idpower[idpowerpoint]);
1939      makemonoms(vars,actvar+1,deg,monomdeg);
1940      idpower[idpowerpoint] = p;
1941    }
1942    monomdeg++;
1943    pSetExp(idpower[idpowerpoint],actvar,pGetExp(idpower[idpowerpoint],actvar)+1);
1944    pSetm(idpower[idpowerpoint]);
1945    i++;
1946  }
1947}
1948
1949/*2
1950*returns the deg-th power of the maximal ideal of 0
1951*/
1952ideal idMaxIdeal(int deg)
1953{
1954  if (deg < 0)
1955  {
1956    WarnS("maxideal: power must be non-negative");
1957  }
1958  if (deg < 1)
1959  {
1960    ideal I=idInit(1,1);
1961    I->m[0]=pOne();
1962    return I;
1963  }
1964  if (deg == 1)
1965  {
1966    return idMaxIdeal();
1967  }
1968
1969  int vars = currRing->N;
1970  int i = binom(vars+deg-1,deg);
1971  ideal id=idInit(i,1);
1972  idpower = id->m;
1973  idpowerpoint = 0;
1974  makemonoms(vars,1,deg,0);
1975  idpower = NULL;
1976  idpowerpoint = 0;
1977  return id;
1978}
1979
1980/*2
1981*computes recursively all generators of a certain degree
1982*of the ideal "givenideal"
1983*elms is the number elements in the given ideal
1984*actelm is the actual element to handle
1985*deg is the degree of the power to compute
1986*gendeg is the actual degree of the generator in consideration
1987*/
1988static void makepotence(int elms,int actelm,int deg,int gendeg)
1989{
1990  poly p;
1991  int i=0;
1992
1993  if ((idpowerpoint == 0) && (actelm ==1))
1994  {
1995    idpower[idpowerpoint] = pOne();
1996    gendeg = 0;
1997  }
1998  while (i<=deg)
1999  {
2000    if (deg == gendeg)
2001    {
2002      idpowerpoint++;
2003      return;
2004    }
2005    if (actelm == elms)
2006    {
2007      p=pPower(pCopy(givenideal[actelm-1]),deg-gendeg);
2008      idpower[idpowerpoint]=pMult(idpower[idpowerpoint],p);
2009      idpowerpoint++;
2010      return;
2011    }
2012    else
2013    {
2014      p = pCopy(idpower[idpowerpoint]);
2015      makepotence(elms,actelm+1,deg,gendeg);
2016      idpower[idpowerpoint] = p;
2017    }
2018    gendeg++;
2019    idpower[idpowerpoint]=pMult(idpower[idpowerpoint],pCopy(givenideal[actelm-1]));
2020    i++;
2021  }
2022}
2023
2024/*2
2025*returns the deg-th power of the ideal gid
2026*/
2027//ideal idPower(ideal gid,int deg)
2028//{
2029//  int i;
2030//  ideal id;
2031//
2032//  if (deg < 1) deg = 1;
2033//  i = binom(IDELEMS(gid)+deg-1,deg);
2034//  id=idInit(i,1);
2035//  idpower = id->m;
2036//  givenideal = gid->m;
2037//  idpowerpoint = 0;
2038//  makepotence(IDELEMS(gid),1,deg,0);
2039//  idpower = NULL;
2040//  givenideal = NULL;
2041//  idpowerpoint = 0;
2042//  return id;
2043//}
2044static void idNextPotence(ideal given, ideal result,
2045  int begin, int end, int deg, int restdeg, poly ap)
2046{
2047  poly p;
2048  int i;
2049
2050  p = pPower(pCopy(given->m[begin]),restdeg);
2051  i = result->nrows;
2052  result->m[i] = pMult(pCopy(ap),p);
2053//PrintS(".");
2054  (result->nrows)++;
2055  if (result->nrows >= IDELEMS(result))
2056  {
2057    pEnlargeSet(&(result->m),IDELEMS(result),16);
2058    IDELEMS(result) += 16;
2059  }
2060  if (begin == end) return;
2061  for (i=restdeg-1;i>=0;i--)
2062  {
2063    p = pPower(pCopy(given->m[begin]),i);
2064    p = pMult(pCopy(ap),p);
2065    idNextPotence(given, result, begin+1, end, deg, restdeg-i, p);
2066    pDelete(&p);
2067  }
2068}
2069
2070ideal idPower(ideal given,int exp)
2071{
2072  ideal result,temp;
2073  poly p1;
2074  int i;
2075
2076  if (idIs0(given)) return idInit(1,1);
2077  temp = idCopy(given);
2078  idSkipZeroes(temp);
2079  i = binom(IDELEMS(temp)+exp-1,exp);
2080  result = idInit(i,1);
2081  result->nrows = 0;
2082//Print("ideal contains %d elements\n",i);
2083  p1=pOne();
2084  idNextPotence(temp,result,0,IDELEMS(temp)-1,exp,exp,p1);
2085  pDelete(&p1);
2086  idDelete(&temp);
2087  idSkipZeroes(result);
2088  result->nrows = 1;
2089  return result;
2090}
2091
2092/*2
2093* eliminate delVar (product of vars) in h1
2094*/
2095ideal idElimination (ideal h1,poly delVar,intvec *hilb)
2096{
2097  int    i,j=0,k,l;
2098  ideal  h,hh, h3;
2099  int    *ord,*block0,*block1;
2100  int    ordersize=2;
2101  short  **wv;
2102  tHomog hom;
2103  intvec * w;
2104  sip_sring tmpR;
2105  ring origR = currRing;
2106
2107  if (delVar==NULL)
2108  {
2109    return idCopy(h1);
2110  }
2111  if (currQuotient!=NULL)
2112  {
2113    WerrorS("cannot eliminate in a qring");
2114    return idCopy(h1);
2115  }
2116  if (idIs0(h1)) return idInit(1,h1->rank);
2117  hom=(tHomog)idHomModule(h1,NULL,&w); //sets w to weight vector or NULL
2118  h3=idInit(16,h1->rank);
2119  for (k=0;; k++)
2120  {
2121    if (currRing->order[k]!=0) ordersize++;
2122    else break;
2123  }
2124  ord=(int*)Alloc0(ordersize*sizeof(int));
2125  block0=(int*)Alloc(ordersize*sizeof(int));
2126  block1=(int*)Alloc(ordersize*sizeof(int));
2127  for (k=0;; k++)
2128  {
2129    if (currRing->order[k]!=0)
2130    {
2131      block0[k+1] = currRing->block0[k];
2132      block1[k+1] = currRing->block1[k];
2133      ord[k+1] = currRing->order[k];
2134    }
2135    else
2136      break;
2137  }
2138  block0[0] = 1;
2139  block1[0] = pVariables;
2140  wv=(short**) Alloc0(ordersize*sizeof(short**));
2141  memcpy4(wv+1,currRing->wvhdl,(ordersize-1)*sizeof(short**));
2142  wv[0]=(short*)Alloc0((pVariables+1)*sizeof(short));
2143  for (j=0;j<pVariables;j++)
2144    if (pGetExp(delVar,j+1)!=0) wv[0][j]=1;
2145  ord[0] = ringorder_a;
2146
2147  // fill in tmp ring to get back the data later on
2148  tmpR  = *origR;
2149  tmpR.order = ord;
2150  tmpR.block0 = block0;
2151  tmpR.block1 = block1;
2152  tmpR.wvhdl = wv;
2153  rComplete(&tmpR);
2154 
2155  // change into the new ring
2156  pChangeRing(pVariables,currRing->OrdSgn,ord,block0,block1,wv);
2157  //  rChangeCurrRing(&tmpR, FALSE);
2158  currRing = &tmpR;
2159  h = idInit(IDELEMS(h1),1);
2160  // fetch data from the old ring
2161  for (k=0;k<IDELEMS(h1);k++) h->m[k] = pFetchCopy(origR, h1->m[k]);
2162  // compute std
2163  hh = std(h,NULL,hom,&w,hilb);
2164  idDelete(&h);
2165
2166  // go back to the original ring
2167  rChangeCurrRing(origR,FALSE);
2168  i = IDELEMS(hh)-1;
2169  while ((i >= 0) && (hh->m[i] == NULL)) i--;
2170  j = -1;
2171  // fetch data from temp ring
2172  for (k=0; k<=i; k++)
2173  {
2174    l=pVariables;
2175    while ((l>0) && (pRingGetExp(&tmpR, hh->m[k],l)*pGetExp(delVar,l)==0)) l--;
2176    if (l==0)
2177    {
2178      j++;
2179      if (j >= IDELEMS(h3))
2180      {
2181        pEnlargeSet(&(h3->m),IDELEMS(h3),16);
2182        IDELEMS(h3) += 16;
2183      }
2184      h3->m[j] = pFetchCopy(&tmpR, hh->m[k]);
2185    }
2186  }
2187  idDelete(&hh);
2188  idSkipZeroes(h3);
2189  Free((ADDRESS)wv[0],(pVariables+1)*sizeof(short));
2190  Free((ADDRESS)wv,ordersize*sizeof(short**));
2191  Free((ADDRESS)ord,ordersize*sizeof(int));
2192  Free((ADDRESS)block0,ordersize*sizeof(int));
2193  Free((ADDRESS)block1,ordersize*sizeof(int));
2194  if (w!=NULL)
2195    delete w;
2196  return h3;
2197}
2198
2199/*2
2200* compute all ar-minors of the matrix a
2201*/
2202ideal idMinors(matrix a, int ar)
2203{
2204  if(ar<=0)
2205  {
2206    Werror("%d-th minor ",ar);
2207    return NULL;
2208  }
2209  int     i,j,k,size;
2210  int *rowchoise,*colchoise;
2211  BOOLEAN rowch,colch;
2212  ideal result;
2213  matrix tmp;
2214  poly p;
2215
2216  i = binom(a->rows(),ar);
2217  j = binom(a->cols(),ar);
2218
2219  rowchoise=(int *)Alloc(ar*sizeof(int));
2220  colchoise=(int *)Alloc(ar*sizeof(int));
2221  if ((i>512) || (j>512) || (i*j >512)) size=512;
2222  else size=i*j;
2223  result=idInit(size,1);
2224  tmp=mpNew(ar,ar);
2225  k = 0; /* the index in result*/
2226  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
2227  while (!rowch)
2228  {
2229    idInitChoise(ar,1,a->cols(),&colch,colchoise);
2230    while (!colch)
2231    {
2232      for (i=1; i<=ar; i++)
2233      {
2234        for (j=1; j<=ar; j++)
2235        {
2236          MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
2237        }
2238      }
2239      p = mpDet(tmp);
2240      if (p!=NULL)
2241      {
2242        if (k>=size)
2243        {
2244          pEnlargeSet(&result->m,size,32);
2245          size += 32;
2246        }
2247        result->m[k] = p;
2248        k++;
2249      }
2250      idGetNextChoise(ar,a->cols(),&colch,colchoise);
2251    }
2252    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
2253  }
2254  /*delete the matrix tmp*/
2255  for (i=1; i<=ar; i++)
2256  {
2257    for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
2258  }
2259  idDelete((ideal*)&tmp);
2260  if (k==0)
2261  {
2262    k=1;
2263    result->m[0]=NULL;
2264  }
2265  Free((ADDRESS)rowchoise,ar*sizeof(int));
2266  Free((ADDRESS)colchoise,ar*sizeof(int));
2267  pEnlargeSet(&result->m,size,k-size);
2268  IDELEMS(result) = k;
2269  return (result);
2270}
2271
2272/*3
2273* produces recursively the ideal of all arxar-minors of a
2274*/
2275static void idRecMin(matrix a,int ar,poly *barDiv,ideal result,
2276              int * nextPlace, intvec * pfRows, intvec * iv)
2277{
2278//Print("Level: %d\n",ar);
2279/*--- there is no non-zero minor coming from a------------*/
2280  if((ar<0) || (ar>min(a->ncols,a->nrows)-1))
2281  {
2282    return;
2283  }
2284
2285/*--- initializing temporary structures-------------------*/
2286  int i,j,r,c,newi,newp,k;
2287  poly p=NULL,pp;
2288  BOOLEAN justChosen=FALSE;
2289
2290  if (ar==0)
2291  {
2292/*--- ar is 0, the matrix-entres are minors---------------*/
2293    for (i=a->nrows;i>0;i--)
2294    {
2295      for (j=a->ncols;j>0;j--)
2296      {
2297        p = MATELEM(a,i,j);
2298        if (p!=NULL)
2299        {
2300          if (*nextPlace>=IDELEMS(result))
2301          {
2302            pEnlargeSet(&(result->m),IDELEMS(result),16);
2303            IDELEMS(result) += 16;
2304          }
2305          MATELEM(a,i,j) = NULL;
2306//if ((*nextPlace==21) || (*nextPlace==37))
2307//{
2308//  Print("Hier sind sie!\n");
2309//}
2310//pWrite(p);
2311          result->m[*nextPlace] = p;
2312          (*nextPlace)++;
2313        }
2314      }
2315    }
2316    idDelete((ideal*)&a);
2317    return;
2318  }
2319/*--- ar>0, we perform one step of the Bareiss algorithm--*/
2320  p = pCopy(*barDiv);   //we had to store barDiv for the remaining loops
2321  pp = pCopy(p);   //we had to store barDiv for the remaining loops
2322  matrix nextStep = mpOneStepBareiss(a,barDiv,&r,&c);
2323/*--- we compute the row-index of the chosen row r -------*/
2324  newi = 0;
2325  while ((newi<iv->length()) && ((*iv)[newi]!=0)) newi++;
2326  k = (*iv)[newi] = r;
2327  for (j=newi-1;j>0;j--)
2328  {
2329    if (k>=(*iv)[j]) k++;
2330  }
2331  newp = 0;
2332  while ((newp<pfRows->length()) && ((*pfRows)[newp]!=0)) 
2333  {
2334    if ((*pfRows)[newp]==k) 
2335    {
2336      justChosen = TRUE;
2337//Print("just chosen\n");
2338      break;
2339    }
2340    newp++;
2341  }
2342  if (!justChosen) (*pfRows)[newp] = k;
2343//Print("Chosen: ");pfRows->show();PrintLn();
2344//Print("Deleted: ");iv->show();PrintLn();
2345/*--- we read out the r-1 x c-1 matrix for the next step--*/
2346  if ((a->nrows-1)*(a->ncols-1)>0)
2347  {
2348    matrix next = mpNew(a->nrows-1,a->ncols-1);
2349    for (i=a->nrows-1;i>0;i--)
2350    {
2351      for (j=a->ncols-1;j>0;j--)
2352      {
2353        MATELEM(next,i,j) = MATELEM(nextStep,i,j);
2354        MATELEM(nextStep,i,j) =NULL;
2355      }
2356    }
2357    idDelete((ideal*)&nextStep);
2358/*--- we call the next Step------------------------------*/
2359    idRecMin(next,ar-1,barDiv,result,nextPlace,pfRows,iv);
2360    next = NULL;
2361  }
2362/*--- now we have to take out the r-th row...------------*/
2363//Print("back for rows on Level: %d\n",ar);
2364//Print("The actual row was %d\n",k);
2365//Print("Chosen: ");pfRows->show();PrintLn();
2366//Print("Deleted: ");iv->show();PrintLn();
2367  if (((a->nrows)>1) && (!justChosen))
2368  {
2369    nextStep = mpNew(a->nrows-1,a->ncols);
2370    for (i=r-1;i>0;i--)
2371    {
2372      for (j=a->ncols;j>0;j--)
2373      {
2374        MATELEM(nextStep,i,j) = pCopy(MATELEM(a,i,j));
2375      }
2376    }
2377    for (i=a->nrows;i>r;i--)
2378    {
2379      for (j=a->ncols;j>0;j--)
2380      {
2381        MATELEM(nextStep,i-1,j) = pCopy(MATELEM(a,i,j));
2382      }
2383    }
2384/*--- and to perform the algorithm with the rest---------*/
2385    idRecMin(nextStep,ar,&p,result,nextPlace,pfRows,iv);
2386    nextStep = NULL;
2387  }
2388/*--- now we have to take out the c-th col...------------*/
2389//Print("back for cols on Level: %d\n",ar);
2390//Print("Chosen: ");pfRows->show();PrintLn();
2391//Print("Deleted: ");iv->show();PrintLn();
2392  if ((a->nrows)>1)
2393  {
2394    nextStep = mpNew(a->nrows,a->ncols-1);
2395    for (i=a->nrows;i>0;i--)
2396    {
2397      for (j=c-1;j>0;j--)
2398      {
2399        MATELEM(nextStep,i,j) = MATELEM(a,i,j);
2400        MATELEM(a,i,j) = NULL;
2401      }
2402    }
2403    for (i=a->nrows;i>0;i--)
2404    {
2405      for (j=a->ncols;j>c;j--)
2406      {
2407        MATELEM(nextStep,i,j-1) = MATELEM(a,i,j);
2408        MATELEM(a,i,j) = NULL;
2409      }
2410    }
2411    idDelete((ideal*)&a);
2412/*--- and to perform the algorithm with the rest---------*/
2413    (*iv)[newi] = 0;
2414    idRecMin(nextStep,ar,&p,result,nextPlace,pfRows,iv);
2415    nextStep = NULL;
2416  }
2417/*--- deleting temporary structures and returns----------*/
2418  if (!justChosen) (*pfRows)[newp] = 0;
2419  pDelete(barDiv);
2420  pDelete(&p);
2421  pDelete(&pp);
2422  return;
2423}
2424
2425/*2
2426* compute all ar-minors of the matrix a
2427* the caller of idRecMin
2428*/
2429ideal idMinors1(matrix a, int ar)
2430{
2431  if((ar<=0) || (ar>min(a->ncols,a->nrows)))
2432  {
2433    Werror("%d-th minor ",ar);
2434    return NULL;
2435  }
2436  int i=0;
2437  intvec * iv=new intvec(a->nrows+1);
2438  intvec * pv=new intvec(a->nrows+1);
2439  poly barDiv=NULL;
2440  ideal result=idInit(16,0);
2441
2442  idRecMin(mpCopy(a),ar-1,&barDiv,result,&i,pv,iv);
2443  idSkipZeroes(result);
2444  delete iv;
2445  delete pv;
2446  return result;
2447}
2448
2449/*2
2450*returns TRUE if p is a unit element in the current ring
2451*/
2452BOOLEAN pIsUnit(poly p)
2453{
2454  int i;
2455
2456  if (p == NULL) return FALSE;
2457  i = 1;
2458  while (i<=pVariables && pGetExp(p,i) == 0) i++;
2459  if (i > pVariables && (pGetComp(p) == 0))
2460  {
2461    if (currRing->OrdSgn == 1 && pNext(p) !=NULL) return FALSE;
2462    return TRUE;
2463  }
2464  return FALSE;
2465}
2466
2467/*2
2468*skips all zeroes and double elements, searches also for units
2469*/
2470ideal idCompactify(ideal id)
2471{
2472  ideal result = NULL;
2473  int i,j;
2474  BOOLEAN b=FALSE;
2475
2476  result=idCopy(id);
2477  i = 0;
2478  while ((! b) && (i<IDELEMS(result)))
2479  {
2480    b=pIsUnit(result->m[i]);
2481    i++;
2482  }
2483  if (b)
2484  {
2485    for (i=0;i<IDELEMS(result);i++)
2486      pDelete(&result->m[i]);
2487    result->m[0]=pOne();
2488  }
2489  else
2490  {
2491    for (i=1;i<IDELEMS(result);i++)
2492    {
2493      if (result->m[i]!=NULL)
2494      {
2495        for (j=0;j<i;j++)
2496        {
2497          if ((result->m[j]!=NULL)
2498          && (pComparePolys(result->m[i],result->m[j])))
2499          {
2500            pDelete(&(result->m[j]));
2501          }
2502        }
2503      }
2504    }
2505  }
2506  idSkipZeroes(result);
2507  return result;
2508}
2509
2510/*2
2511*returns TRUE if id1 is a submodule of id2
2512*/
2513BOOLEAN idIsSubModule(ideal id1,ideal id2)
2514{
2515  int i;
2516  poly p;
2517
2518  if (idIs0(id1)) return TRUE;
2519  for (i=0;i<IDELEMS(id1);i++)
2520  {
2521    if (id1->m[i] != NULL)
2522    {
2523      p = kNF(id2,currQuotient,id1->m[i]);
2524      if (p != NULL)
2525      {
2526        pDelete(&p);
2527        return FALSE;
2528      }
2529    }
2530  }
2531  return TRUE;
2532}
2533
2534/*2
2535* returns the ideals of initial terms
2536*/
2537ideal idHead(ideal h)
2538{
2539  ideal m = idInit(IDELEMS(h),h->rank);
2540  int i;
2541
2542  for (i=0; i< IDELEMS(h); i++)
2543  {
2544    if (h->m[i]) m->m[i]=pHead(h->m[i]);
2545  }
2546  return m;
2547}
2548
2549ideal idHomogen(ideal h, int varnum)
2550{
2551  ideal m = idInit(IDELEMS(h),h->rank);
2552  int i;
2553
2554  for (i=0; i< IDELEMS(h); i++)
2555  {
2556    m->m[i]=pHomogen(h->m[i],varnum);
2557  }
2558  return m;
2559}
2560
2561/*------------------type conversions----------------*/
2562ideal idVec2Ideal(poly vec)
2563{
2564   ideal result=idInit(1,1);
2565   Free((ADDRESS)result->m,sizeof(poly));
2566   result->m=NULL; // remove later
2567   pVec2Polys(vec, &(result->m), &(IDELEMS(result)));
2568   return result;
2569}
2570
2571ideal idMatrix2Module(matrix mat)
2572{
2573  ideal result = idInit(MATCOLS(mat),MATROWS(mat));
2574  int i,j;
2575  poly h;
2576#ifdef DRING
2577  poly p;
2578#endif
2579
2580  for(j=0;j<MATCOLS(mat);j++) /* j is also index in result->m */
2581  {
2582    for (i=1;i<=MATROWS(mat);i++)
2583    {
2584      h = MATELEM(mat,i,j+1);
2585      if (h!=NULL)
2586      {
2587        MATELEM(mat,i,j+1)=NULL;
2588        pSetCompP(h,i);
2589#ifdef DRING
2590        pdSetDFlag(h,0);
2591#endif
2592        result->m[j] = pAdd(result->m[j],h);
2593      }
2594    }
2595  }
2596  return result;
2597}
2598
2599/*2
2600* converts a module into a matrix, destroyes the input
2601*/
2602matrix idModule2Matrix(ideal mod)
2603{
2604  matrix result = mpNew(mod->rank,IDELEMS(mod));
2605  int i,cp;
2606  poly p,h;
2607
2608  for(i=0;i<IDELEMS(mod);i++)
2609  {
2610    p=mod->m[i];
2611    mod->m[i]=NULL;
2612    while (p!=NULL)
2613    {
2614      h=p;
2615      pIter(p);
2616      pNext(h)=NULL;
2617//      cp = max(1,pGetComp(h));     // if used for ideals too
2618      cp = pGetComp(h);
2619      pSetComp(h,0);
2620#ifdef TEST
2621      if (cp>mod->rank)
2622      {
2623        Print("## inv. rank %d -> %d\n",mod->rank,cp);
2624        int k,l,o=mod->rank;
2625        mod->rank=cp;
2626        matrix d=mpNew(mod->rank,IDELEMS(mod));
2627        for (l=1; l<=o; l++)
2628        {
2629          for (k=1; k<=IDELEMS(mod); k++)
2630          {
2631            MATELEM(d,l,k)=MATELEM(result,l,k);
2632            MATELEM(result,l,k)=NULL;
2633          }
2634        }
2635        idDelete((ideal *)&result);
2636        result=d;
2637      }
2638#endif
2639      MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
2640    }
2641  }
2642  return result;
2643}
2644
2645matrix idModule2formatedMatrix(ideal mod,int rows, int cols)
2646{
2647  matrix result = mpNew(rows,cols);
2648  int i,cp,r=idRankFreeModule(mod),c=IDELEMS(mod);
2649  poly p,h;
2650
2651  if (r>rows) r = rows;
2652  if (c>cols) c = cols;
2653  for(i=0;i<c;i++)
2654  {
2655    p=mod->m[i];
2656    mod->m[i]=NULL;
2657    while (p!=NULL)
2658    {
2659      h=p;
2660      pIter(p);
2661      pNext(h)=NULL;
2662      cp = pGetComp(h);
2663      if (cp<=r)
2664      {
2665        pSetComp(h,0);
2666        MATELEM(result,cp,i+1) = pAdd(MATELEM(result,cp,i+1),h);
2667      }
2668      else
2669        pDelete(&h);
2670    }
2671  }
2672  idDelete(&mod);
2673  return result;
2674}
2675
2676/*2
2677* substitute the n-th variable by the monomial e in id
2678* destroy id
2679*/
2680ideal  idSubst(ideal id, int n, poly e)
2681{
2682  int k=MATROWS((matrix)id)*MATCOLS((matrix)id);
2683  ideal res=(ideal)mpNew(MATROWS((matrix)id),MATCOLS((matrix)id));
2684
2685  res->rank = id->rank;
2686  for(k--;k>=0;k--)
2687  {
2688    res->m[k]=pSubst(id->m[k],n,e);
2689    id->m[k]=NULL;
2690  }
2691  idDelete(&id);
2692  return res;
2693}
2694
2695BOOLEAN idHomModule(ideal m, ideal Q, intvec **w)
2696{
2697  if (w!=NULL) *w=NULL;
2698  if ((Q!=NULL) && (!idHomIdeal(Q,NULL))) return FALSE;
2699  if (idIs0(m)) return TRUE;
2700
2701  int i,j,cmax=2,order=0,ord,* diff,* iscom,diffmin=32000;
2702  poly p=NULL;
2703  int length=IDELEMS(m);
2704  polyset P=m->m;
2705  polyset F=(polyset)Alloc(length*sizeof(poly));
2706  for (i=length-1;i>=0;i--)
2707  {
2708    p=F[i]=P[i];
2709    cmax=max(cmax,pMaxComp(p)+1);
2710  }
2711  diff = (int *)Alloc0(cmax*sizeof(int));
2712  if (w!=NULL) *w=new intvec(cmax-1);
2713  iscom = (int *)Alloc0(cmax*sizeof(int));
2714  i=0;
2715  while (i<=length)
2716  {
2717    if (i<length)
2718    {
2719      p=F[i];
2720      while ((p!=NULL) && (!iscom[pGetComp(p)])) pIter(p);
2721    }
2722    if ((p==NULL) && (i<length))
2723    {
2724      i++;
2725    }
2726    else
2727    {
2728      if (p==NULL)
2729      {
2730        i=0;
2731        while ((i<length) && (F[i]==NULL)) i++;
2732        if (i>=length) break;
2733        p = F[i];
2734      }
2735      if (pLexOrder)
2736        order=pTotaldegree(p);
2737      else
2738      //  order = p->order;
2739        order = pFDeg(p);
2740      order += diff[pGetComp(p)];
2741      p = F[i];
2742//Print("Actual p=F[%d]: ",i);pWrite(p);
2743      F[i] = NULL;
2744      i=0;
2745    }
2746    while (p!=NULL)
2747    {
2748      //if (pLexOrder)
2749      //  ord=pTotaldegree(p);
2750      //else
2751      //  ord = p->order;
2752      ord = pFDeg(p);
2753      if (!iscom[pGetComp(p)])
2754      {
2755        diff[pGetComp(p)] = order-ord;
2756        iscom[pGetComp(p)] = 1;
2757/*
2758*PrintS("new diff: ");
2759*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
2760*PrintLn();
2761*PrintS("new iscom: ");
2762*for (j=0;j<cmax;j++) Print("%d ",iscom[j]);
2763*PrintLn();
2764*Print("new set %d, order %d, ord %d, diff %d\n",pGetComp(p),order,ord,diff[pGetComp(p)]);
2765*/
2766      }
2767      else
2768      {
2769/*
2770*PrintS("new diff: ");
2771*for (j=0;j<cmax;j++) Print("%d ",diff[j]);
2772*PrintLn();
2773*Print("order %d, ord %d, diff %d\n",order,ord,diff[pGetComp(p)]);
2774*/
2775        if (order != ord+diff[pGetComp(p)])
2776        {
2777          Free((ADDRESS) iscom,cmax*sizeof(int));
2778          Free((ADDRESS) diff,cmax*sizeof(int));
2779          Free((ADDRESS) F,length*sizeof(poly));
2780          delete *w;*w=NULL;
2781          return FALSE;
2782        }
2783      }
2784      pIter(p);
2785    }
2786  }
2787  Free((ADDRESS) iscom,cmax*sizeof(int));
2788  Free((ADDRESS) F,length*sizeof(poly));
2789  for (i=1;i<cmax;i++) (**w)[i-1]=diff[i];
2790  for (i=1;i<cmax;i++)
2791  {
2792    if (diff[i]<diffmin) diffmin=diff[i];
2793  }
2794  for (i=1;i<cmax;i++)
2795  {
2796    (**w)[i-1]=diff[i]-diffmin;
2797  }
2798  Free((ADDRESS) diff,cmax*sizeof(int));
2799  return TRUE;
2800}
2801
2802ideal idJet(ideal i,int d)
2803{
2804  ideal r=idInit(IDELEMS(i),i->rank);
2805  int k;
2806  for(k=0; k<IDELEMS(i); k++)
2807  {
2808    r->m[k]=pJet(i->m[k],d);
2809  }
2810  return r;
2811}
2812
2813ideal idJetW(ideal i,int d, intvec * iv)
2814{
2815  ideal r=idInit(IDELEMS(i),i->rank);
2816  if (ecartWeights!=NULL)
2817  {
2818    WerrorS("cannot compute weighted jets now");
2819  }
2820  else
2821  {
2822    short *w=iv2array(iv);
2823    int k;
2824    for(k=0; k<IDELEMS(i); k++)
2825    {
2826      r->m[k]=pJetW(i->m[k],d,w);
2827    }
2828    Free((ADDRESS)w,(pVariables+1)*sizeof(short));
2829  }
2830  return r;
2831}
2832
2833matrix idDiff(matrix i, int k)
2834{
2835  int e=MATCOLS(i)*MATROWS(i);
2836  matrix r=mpNew(MATROWS(i),MATCOLS(i));
2837  int j;
2838  for(j=0; j<e; j++)
2839  {
2840    r->m[j]=pDiff(i->m[j],k);
2841  }
2842  return r;
2843}
2844
2845matrix idDiffOp(ideal I, ideal J,BOOLEAN multiply)
2846{
2847  matrix r=mpNew(IDELEMS(I),IDELEMS(J));
2848  int i,j;
2849  for(i=0; i<IDELEMS(I); i++)
2850  {
2851    for(j=0; j<IDELEMS(J); j++)
2852    {
2853      MATELEM(r,i+1,j+1)=pDiffOp(I->m[i],J->m[j],multiply);
2854    }
2855  }
2856  return r;
2857}
2858
2859/*2
2860* represents (h1+h2)/h2=h1/(h1 intersect h2)
2861*/
2862ideal idModulo (ideal h2,ideal h1)
2863{
2864  ideal temp,temp1;
2865  int i,j,k,rk,flength=0,slength,length;
2866  intvec * w;
2867  poly p,q;
2868
2869  if (idIs0(h2))
2870    return idFreeModule(max(1,h2->ncols));
2871  if (!idIs0(h1))
2872    flength = idRankFreeModule(h1);
2873  slength = idRankFreeModule(h2);
2874  length  = max(flength,slength);
2875  if (length==0)
2876  {
2877    length = 1;
2878  }
2879  temp = idInit(IDELEMS(h2),1);
2880  for (i=0;i<IDELEMS(h2);i++)
2881  {
2882    temp->m[i] = pCopy(h2->m[i]);
2883    q = pOne();
2884    pSetComp(q,i+1+length);
2885    if(temp->m[i]!=NULL)
2886    {
2887      if (slength==0) pShift(&(temp->m[i]),1);
2888      p = temp->m[i];
2889      while (pNext(p)!=NULL) pIter(p);
2890      pNext(p) = q;
2891    }
2892    else
2893      temp->m[i]=q;
2894  }
2895  rk = k = IDELEMS(h2);
2896  if (!idIs0(h1))
2897  {
2898    pEnlargeSet(&(temp->m),IDELEMS(temp),IDELEMS(h1));
2899    IDELEMS(temp) += IDELEMS(h1);
2900    for (i=0;i<IDELEMS(h1);i++)
2901    {
2902      if (h1->m[i]!=NULL)
2903      {
2904        temp->m[k] = pCopy(h1->m[i]);
2905        if (flength==0) pShift(&(temp->m[k]),1);
2906        k++;
2907      }
2908    }
2909  }
2910  pSetSyzComp(length);
2911  temp1 = std(temp,currQuotient,testHomog,&w,NULL,length);
2912  pSetSyzComp(0);
2913  idDelete(&temp);
2914  if (w!=NULL) delete w;
2915  for (i=0;i<IDELEMS(temp1);i++)
2916  {
2917    if ((temp1->m[i]!=NULL)
2918    && (pGetComp(temp1->m[i])<=length))
2919    {
2920      pDelete(&(temp1->m[i]));
2921    }
2922    else
2923    {
2924      pShift(&(temp1->m[i]),-length);
2925    }
2926  }
2927  idSkipZeroes(temp1);
2928  temp1->rank = rk;
2929  return temp1;
2930}
2931
2932int idElem(ideal F)
2933{
2934  int i=0,j=0;
2935
2936  while(j<IDELEMS(F))
2937  {
2938   if ((F->m)[j]!=NULL) i++;
2939   j++;
2940  }
2941  return i;
2942}
2943
2944/*
2945*computes module-weights for liftings of homogeneous modules
2946*/
2947intvec * idMWLift(ideal mod,intvec * weights)
2948{
2949  if (idIs0(mod)) return new intvec(2);
2950  int i=IDELEMS(mod);
2951  while ((i>0) && (mod->m[i-1]==NULL)) i--;
2952  intvec *result = new intvec(i+1);
2953  while (i>0)
2954  {
2955    (*result)[i]=pFDeg(mod->m[i])+(*weights)[pGetComp(mod->m[i])];
2956  }
2957  return result;
2958}
2959
2960/*2
2961*sorts the kbase for idCoef* in a special way (lexicographically
2962*with x_max,...,x_1)
2963*/
2964ideal idCreateSpecialKbase(ideal kBase,intvec ** convert)
2965{
2966  int i;
2967  ideal result;
2968
2969  if (idIs0(kBase)) return NULL;
2970  result = idInit(IDELEMS(kBase),kBase->rank);
2971  *convert = idSort(kBase,FALSE);
2972  for (i=0;i<(*convert)->length();i++)
2973  {
2974    result->m[i] = pCopy(kBase->m[(**convert)[i]-1]);
2975  }
2976  return result;
2977}
2978
2979/*2
2980*returns the index of a given monom in the list of the special kbase
2981*/
2982int idIndexOfKBase(poly monom, ideal kbase)
2983{
2984  int j=IDELEMS(kbase);
2985
2986  while ((j>0) && (kbase->m[j-1]==NULL)) j--;
2987  if (j==0) return -1;
2988  int i=pVariables;
2989  while (i>=0)
2990  {
2991    while ((j>0) && (pGetExp(monom,i)<pGetExp(kbase->m[j-1],i))) j--;
2992    if ((j==0) || (pGetExp(monom,i)>pGetExp(kbase->m[j-1],i))) return -1;
2993    if (i==0)
2994      return j-1;
2995    else
2996      i--;
2997  }
2998  return -1;
2999}
3000
3001/*2
3002*decomposes the monom in a part of coefficients described by the
3003*complement of how and a monom in variables occuring in how, the
3004*index of which in kbase is returned as integer pos (-1 if it don't
3005*exists)
3006*/
3007poly idDecompose(poly monom, poly how, ideal kbase, int * pos)
3008{
3009  int i;
3010  poly coeff=pOne(), base=pOne();
3011
3012  for (i=1;i<=pVariables;i++)
3013  {
3014    if (pGetExp(how,i)>0)
3015    {
3016      pSetExp(base,i,pGetExp(monom,i));
3017    }
3018    else
3019    {
3020      pSetExp(coeff,i,pGetExp(monom,i));
3021    }
3022  }
3023  pSetComp(base,pGetComp(monom));
3024  pSetm(base);
3025  pSetCoeff(coeff,nCopy(pGetCoeff(monom)));
3026  pSetm(coeff);
3027  *pos = idIndexOfKBase(base,kbase);
3028  if (*pos<0)
3029    pDelete(&coeff);
3030  pDelete(&base);
3031  return coeff;
3032}
3033
3034/*2
3035*returns a matrix A of coefficients with kbase*A=arg
3036*if all monomials in variables of how occur in kbase
3037*the other are deleted
3038*/
3039matrix idCoeffOfKBase(ideal arg, ideal kbase, poly how)
3040{
3041  matrix result;
3042  ideal tempKbase;
3043  poly p,q;
3044  intvec * convert;
3045  int i=IDELEMS(kbase),j=IDELEMS(arg),k,pos;
3046
3047  while ((i>0) && (kbase->m[i-1]==NULL)) i--;
3048  if (idIs0(arg))
3049    return mpNew(i,1);
3050  while ((j>0) && (arg->m[j-1]==NULL)) j--;
3051  result = mpNew(i,j);
3052  tempKbase = idCreateSpecialKbase(kbase,&convert);
3053  for (k=0;k<j;k++)
3054  {
3055    p = arg->m[k];
3056    while (p!=NULL)
3057    {
3058      q = idDecompose(p,how,tempKbase,&pos);
3059      if (pos>=0)
3060      {
3061        MATELEM(result,(*convert)[pos],k+1) =
3062            pAdd(MATELEM(result,(*convert)[pos],k+1),q);
3063      }
3064      else
3065        pDelete(&q);
3066      p = pIter(p);
3067    }
3068  }
3069  idDelete(&tempKbase);
3070  return result;
3071}
3072
3073intvec * idQHomWeights(ideal id)
3074{
3075  intvec * imat=new intvec(2*pVariables,pVariables,0);
3076  poly actHead=NULL,wPoint=NULL;
3077  int actIndex,i=-1,j=1,k;
3078  BOOLEAN notReady=TRUE;
3079
3080  while (notReady)
3081  {
3082    if (wPoint==NULL)
3083    {
3084      i++;
3085      while ((i<IDELEMS(id))
3086      && ((id->m[i]==NULL) || (pNext(id->m[i])==NULL)))
3087        i++;
3088      if (i<IDELEMS(id))
3089      {
3090        actHead = id->m[i];
3091        wPoint = pNext(actHead);
3092      }
3093    }
3094    while ((wPoint!=NULL) && (j<=2*pVariables))
3095    {
3096      for (k=1;k<=pVariables;k++)
3097        IMATELEM(*imat,j,k) += pGetExp(actHead,k)-pGetExp(wPoint,k);
3098      pIter(wPoint);
3099      j++;
3100    }
3101    if ((i>=IDELEMS(id)) || (j>2*pVariables))
3102    {
3103      ivTriangMat(imat,1,1);
3104      j = ivFirstEmptyRow(imat);
3105      if ((i>=IDELEMS(id)) || (j>pVariables)) notReady=FALSE;
3106    }
3107  }
3108  intvec *result=NULL;
3109  if (j<=pVariables)
3110  {
3111    result=ivSolveIntMat(imat);
3112  }
3113  //else
3114  //{
3115  //  WerrorS("not homogeneous");
3116  //}
3117  delete imat;
3118  return result;
3119}
3120
3121/*2
3122* returns the presentation of an isomorphic, minimally
3123* embedded  module
3124*/
3125ideal idMinEmbedding(ideal arg)
3126{
3127  if (idIs0(arg)) return idInit(1,arg->rank);
3128
3129  int i,j,k,pC;
3130  poly p,q;
3131  int rg=arg->rank;
3132  ideal res = idCopy(arg);
3133  intvec *indexMap=new intvec(rg+1);
3134  intvec *toKill=new intvec(rg+1);
3135
3136  loop
3137  {
3138    k = 0;
3139    for (i=indexMap->length()-1;i>0;i--)
3140    {
3141      (*indexMap)[i] = i;
3142      (*toKill)[i] = 0;
3143    }
3144    for (j=IDELEMS(res)-1;j>=0;j--)
3145    {
3146      if ((res->m[j]!=NULL) && (pIsConstantComp(res->m[j])) &&
3147           (pNext(res->m[j])==NULL))
3148      {
3149        pC = pGetComp(res->m[j]);
3150        if ((*toKill)[pC]==0)
3151        {
3152          rg--;
3153          (*toKill)[pC] = 1;
3154          for (i=indexMap->length()-1;i>=pC;i--)
3155            (*indexMap)[i]--;
3156        }
3157        pDelete(&(res->m[j]));
3158        k++;
3159      }
3160    }
3161    idSkipZeroes(res);
3162    if (k==0) break;
3163    if (rg>0)
3164    {
3165      res->rank=rg;
3166      for (j=IDELEMS(res)-1;j>=0;j--)
3167      {
3168        while ((res->m[j]!=NULL) && ((*toKill)[pGetComp(res->m[j])]==1))
3169          pDelete1(&res->m[j]);
3170        p = res->m[j];
3171        while ((p!=NULL) && (pNext(p)!=NULL))
3172        {
3173          pSetComp(p,(*indexMap)[pGetComp(p)]);
3174          while ((pNext(p)!=NULL) && ((*toKill)[pGetComp(pNext(p))]==1))
3175            pDelete1(&pNext(p));
3176          pIter(p);
3177        }
3178        if (p!=NULL) pSetComp(p,(*indexMap)[pGetComp(p)]);
3179      }
3180      idSkipZeroes(res);
3181    }
3182    else
3183    {
3184      idDelete(&res);
3185      res=idFreeModule(1);
3186      break;
3187    }
3188  }
3189  delete toKill;
3190  delete indexMap;
3191  return res;
3192}
Note: See TracBrowser for help on using the repository browser.