source: git/Singular/ideals.cc @ 94fcf4

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