source: git/kernel/ideals.cc @ eb6798

fieker-DuValspielwiese
Last change on this file since eb6798 was eb6798, checked in by Hans Schoenemann <hannes@…>, 7 years ago
chg: move option handling in idQuot
  • Property mode set to 100644
File size: 70.2 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5* ABSTRACT - all basic methods to manipulate ideals
6*/
7
8/* includes */
9
10#include "kernel/mod2.h"
11
12#include "omalloc/omalloc.h"
13
14#include "misc/options.h"
15#include "misc/intvec.h"
16
17#include "coeffs/coeffs.h"
18#include "coeffs/numbers.h"
19// #include "coeffs/longrat.h"
20
21
22#include "polys/monomials/ring.h"
23#include "polys/matpol.h"
24#include "polys/weight.h"
25#include "polys/sparsmat.h"
26#include "polys/prCopy.h"
27#include "polys/nc/nc.h"
28
29
30#include "kernel/ideals.h"
31
32#include "kernel/polys.h"
33
34#include "kernel/GBEngine/kstd1.h"
35#include "kernel/GBEngine/kutil.h"
36#include "kernel/GBEngine/tgb.h"
37#include "kernel/GBEngine/syz.h"
38#include "Singular/ipshell.h" // iiCallLibProc1
39#include "Singular/ipid.h" // ggetid
40
41
42/* #define WITH_OLD_MINOR */
43
44/*0 implementation*/
45
46/*2
47*returns a minimized set of generators of h1
48*/
49ideal idMinBase (ideal h1)
50{
51  ideal h2, h3,h4,e;
52  int j,k;
53  int i,l,ll;
54  intvec * wth;
55  BOOLEAN homog;
56  if(rField_is_Ring(currRing))
57  {
58      WarnS("minbase applies only to the local or homogeneous case over coefficient fields");
59      e=idCopy(h1);
60      return e;
61  }
62  homog = idHomModule(h1,currRing->qideal,&wth);
63  if (rHasGlobalOrdering(currRing))
64  {
65    if(!homog)
66    {
67      WarnS("minbase applies only to the local or homogeneous case over coefficient fields");
68      e=idCopy(h1);
69      return e;
70    }
71    else
72    {
73      ideal re=kMin_std(h1,currRing->qideal,(tHomog)homog,&wth,h2,NULL,0,3);
74      idDelete(&re);
75      return h2;
76    }
77  }
78  e=idInit(1,h1->rank);
79  if (idIs0(h1))
80  {
81    return e;
82  }
83  pEnlargeSet(&(e->m),IDELEMS(e),15);
84  IDELEMS(e) = 16;
85  h2 = kStd(h1,currRing->qideal,isNotHomog,NULL);
86  h3 = idMaxIdeal(1);
87  h4=idMult(h2,h3);
88  idDelete(&h3);
89  h3=kStd(h4,currRing->qideal,isNotHomog,NULL);
90  k = IDELEMS(h3);
91  while ((k > 0) && (h3->m[k-1] == NULL)) k--;
92  j = -1;
93  l = IDELEMS(h2);
94  while ((l > 0) && (h2->m[l-1] == NULL)) l--;
95  for (i=l-1; i>=0; i--)
96  {
97    if (h2->m[i] != NULL)
98    {
99      ll = 0;
100      while ((ll < k) && ((h3->m[ll] == NULL)
101      || !pDivisibleBy(h3->m[ll],h2->m[i])))
102        ll++;
103      if (ll >= k)
104      {
105        j++;
106        if (j > IDELEMS(e)-1)
107        {
108          pEnlargeSet(&(e->m),IDELEMS(e),16);
109          IDELEMS(e) += 16;
110        }
111        e->m[j] = pCopy(h2->m[i]);
112      }
113    }
114  }
115  idDelete(&h2);
116  idDelete(&h3);
117  idDelete(&h4);
118  if (currRing->qideal!=NULL)
119  {
120    h3=idInit(1,e->rank);
121    h2=kNF(h3,currRing->qideal,e);
122    idDelete(&h3);
123    idDelete(&e);
124    e=h2;
125  }
126  idSkipZeroes(e);
127  return e;
128}
129
130
131/*2
132*initialized a field with r numbers between beg and end for the
133*procedure idNextChoise
134*/
135ideal idSectWithElim (ideal h1,ideal h2)
136// does not destroy h1,h2
137{
138  if (TEST_OPT_PROT) PrintS("intersect by elimination method\n");
139  assume(!idIs0(h1));
140  assume(!idIs0(h2));
141  assume(IDELEMS(h1)<=IDELEMS(h2));
142  assume(id_RankFreeModule(h1,currRing)==0);
143  assume(id_RankFreeModule(h2,currRing)==0);
144  // add a new variable:
145  int j;
146  ring origRing=currRing;
147  ring r=rCopy0(origRing);
148  r->N++;
149  r->block0[0]=1;
150  r->block1[0]= r->N;
151  omFree(r->order);
152  r->order=(rRingOrder_t*)omAlloc0(3*sizeof(rRingOrder_t));
153  r->order[0]=ringorder_dp;
154  r->order[1]=ringorder_C;
155  char **names=(char**)omAlloc0(rVar(r) * sizeof(char_ptr));
156  for (j=0;j<r->N-1;j++) names[j]=r->names[j];
157  names[r->N-1]=omStrDup("@");
158  omFree(r->names);
159  r->names=names;
160  rComplete(r,TRUE);
161  // fetch h1, h2
162  ideal h;
163  h1=idrCopyR(h1,origRing,r);
164  h2=idrCopyR(h2,origRing,r);
165  // switch to temp. ring r
166  rChangeCurrRing(r);
167  // create 1-t, t
168  poly omt=p_One(currRing);
169  p_SetExp(omt,r->N,1,currRing);
170  poly t=p_Copy(omt,currRing);
171  p_Setm(omt,currRing);
172  omt=p_Neg(omt,currRing);
173  omt=p_Add_q(omt,pOne(),currRing);
174  // compute (1-t)*h1
175  h1=(ideal)mp_MultP((matrix)h1,omt,currRing);
176  // compute t*h2
177  h2=(ideal)mp_MultP((matrix)h2,pCopy(t),currRing);
178  // (1-t)h1 + t*h2
179  h=idInit(IDELEMS(h1)+IDELEMS(h2),1);
180  int l;
181  for (l=IDELEMS(h1)-1; l>=0; l--)
182  {
183    h->m[l] = h1->m[l];  h1->m[l]=NULL;
184  }
185  j=IDELEMS(h1);
186  for (l=IDELEMS(h2)-1; l>=0; l--)
187  {
188    h->m[l+j] = h2->m[l];  h2->m[l]=NULL;
189  }
190  idDelete(&h1);
191  idDelete(&h2);
192  // eliminate t:
193
194  ideal res=idElimination(h,t);
195  // cleanup
196  idDelete(&h);
197  if (res!=NULL) res=idrMoveR(res,r,origRing);
198  rChangeCurrRing(origRing);
199  rDelete(r);
200  return res;
201}
202/*2
203* h3 := h1 intersect h2
204*/
205ideal idSect (ideal h1,ideal h2, GbVariant alg)
206{
207  int i,j,k;
208  unsigned length;
209  int flength = id_RankFreeModule(h1,currRing);
210  int slength = id_RankFreeModule(h2,currRing);
211  int rank=si_max(h1->rank,h2->rank);
212  if ((idIs0(h1)) || (idIs0(h2)))  return idInit(1,rank);
213
214  ideal first,second,temp,temp1,result;
215  poly p,q;
216
217  if (IDELEMS(h1)<IDELEMS(h2))
218  {
219    first = h1;
220    second = h2;
221  }
222  else
223  {
224    first = h2;
225    second = h1;
226    int t=flength; flength=slength; slength=t;
227  }
228  length  = si_max(flength,slength);
229  if (length==0)
230  {
231    if ((currRing->qideal==NULL)
232    && (currRing->OrdSgn==1)
233    && (!rIsPluralRing(currRing))
234    && ((TEST_V_INTERSECT_ELIM) || (!TEST_V_INTERSECT_SYZ)))
235      return idSectWithElim(first,second);
236    else length = 1;
237  }
238  if (TEST_OPT_PROT) PrintS("intersect by syzygy methods\n");
239  j = IDELEMS(first);
240
241  ring orig_ring=currRing;
242  ring syz_ring=rAssure_SyzOrder(orig_ring,TRUE);
243  rSetSyzComp(length,syz_ring);
244  rChangeCurrRing(syz_ring);
245
246  while ((j>0) && (first->m[j-1]==NULL)) j--;
247  temp = idInit(j /*IDELEMS(first)*/+IDELEMS(second),length+j);
248  k = 0;
249  for (i=0;i<j;i++)
250  {
251    if (first->m[i]!=NULL)
252    {
253      if (syz_ring==orig_ring)
254        temp->m[k] = pCopy(first->m[i]);
255      else
256        temp->m[k] = prCopyR(first->m[i], orig_ring, syz_ring);
257      q = pOne();
258      pSetComp(q,i+1+length);
259      pSetmComp(q);
260      if (flength==0) p_Shift(&(temp->m[k]),1,currRing);
261      p = temp->m[k];
262      while (pNext(p)!=NULL) pIter(p);
263      pNext(p) = q;
264      k++;
265    }
266  }
267  for (i=0;i<IDELEMS(second);i++)
268  {
269    if (second->m[i]!=NULL)
270    {
271      if (syz_ring==orig_ring)
272        temp->m[k] = pCopy(second->m[i]);
273      else
274        temp->m[k] = prCopyR(second->m[i], orig_ring,currRing);
275      if (slength==0) p_Shift(&(temp->m[k]),1,currRing);
276      k++;
277    }
278  }
279  intvec *w=NULL;
280  if (alg==GbDefault) alg=GbStd;
281  if (alg==GbStd)
282  {
283    if (TEST_OPT_PROT) { PrintS("std:"); mflush(); }
284    temp1 = kStd(temp,currRing->qideal,testHomog,&w,NULL,length);
285    if (w!=NULL) delete w;
286    idDelete(&temp);
287  }
288  else if (alg==GbSlimgb)
289  {
290    if (TEST_OPT_PROT) { PrintS("slimgb:"); mflush(); }
291    temp1 = t_rep_gb(currRing, temp, temp->rank);
292    idDelete(&temp);
293  }
294  else if (alg==GbGroebner)
295  {
296    if (TEST_OPT_PROT) { PrintS("groebner:"); mflush(); }
297    BOOLEAN err;
298    temp1=(ideal)iiCallLibProc1("groebner",temp,MODUL_CMD,err);
299    if (err)
300    {
301      Werror("error %d in >>groebner<<",err);
302      temp1=idInit(1,1);
303    }
304  }
305  else if (alg==GbModstd)
306  {
307    if (TEST_OPT_PROT) { PrintS("modStd:"); mflush(); }
308    BOOLEAN err;
309    void *args[]={temp,(void*)1,NULL};
310    int arg_t[]={MODUL_CMD,INT_CMD,0};
311    temp1=(ideal)iiCallLibProcM("modStd",args,arg_t,err);
312    if (err)
313    {
314      Werror("error %d in >>modStd<<",err);
315      temp1=idInit(1,1);
316    }
317  }
318  else if (alg==GbStdSat)
319  {
320    if (TEST_OPT_PROT) { PrintS("std:sat:"); mflush(); }
321    BOOLEAN err;
322    // search for 2nd block of vars
323    int i=0;
324    int block=-1;
325    loop
326    {
327      if ((currRing->order[i]!=ringorder_c)
328      && (currRing->order[i]!=ringorder_C)
329      && (currRing->order[i]!=ringorder_s))
330      {
331        if (currRing->order[i]==0) { err=TRUE;break;}
332        block++;
333        if (block==1) { block=i; break;}
334      }
335      i++;
336    }
337    if (block>0)
338    {
339      if (TEST_OPT_PROT)
340      {
341        Print("sat(%d..%d)\n",currRing->block0[block],currRing->block1[block]);
342        mflush();
343      }
344      ideal v=idInit(currRing->block1[block]-currRing->block0[block]+1,1);
345      for(i=currRing->block0[block];i<=currRing->block1[block];i++)
346      {
347        v->m[i-currRing->block0[block]]=pOne();
348        pSetExp(v->m[i-currRing->block0[block]],i,1);
349        pSetm(v->m[i-currRing->block0[block]]);
350      }
351      void *args[]={temp,v,NULL};
352      int arg_t[]={MODUL_CMD,IDEAL_CMD,0};
353      temp1=(ideal)iiCallLibProcM("satstd",args,arg_t,err);
354    }
355    if (err)
356    {
357      Werror("error %d in >>satstd<<",err);
358      temp1=idInit(1,1);
359    }
360  }
361
362  if(syz_ring!=orig_ring)
363    rChangeCurrRing(orig_ring);
364
365  result = idInit(IDELEMS(temp1),rank);
366  j = 0;
367  for (i=0;i<IDELEMS(temp1);i++)
368  {
369    if ((temp1->m[i]!=NULL)
370    && (__p_GetComp(temp1->m[i],syz_ring)>length))
371    {
372      if(syz_ring==orig_ring)
373      {
374        p = temp1->m[i];
375      }
376      else
377      {
378        p = prMoveR(temp1->m[i], syz_ring,orig_ring);
379      }
380      temp1->m[i]=NULL;
381      while (p!=NULL)
382      {
383        q = pNext(p);
384        pNext(p) = NULL;
385        k = pGetComp(p)-1-length;
386        pSetComp(p,0);
387        pSetmComp(p);
388        /* Warning! multiply only from the left! it's very important for Plural */
389        result->m[j] = pAdd(result->m[j],pMult(p,pCopy(first->m[k])));
390        p = q;
391      }
392      j++;
393    }
394  }
395  if(syz_ring!=orig_ring)
396  {
397    rChangeCurrRing(syz_ring);
398    idDelete(&temp1);
399    rChangeCurrRing(orig_ring);
400    rDelete(syz_ring);
401  }
402  else
403  {
404    idDelete(&temp1);
405  }
406
407  idSkipZeroes(result);
408  if (TEST_OPT_RETURN_SB)
409  {
410     w=NULL;
411     temp1=kStd(result,currRing->qideal,testHomog,&w);
412     if (w!=NULL) delete w;
413     idDelete(&result);
414     idSkipZeroes(temp1);
415     return temp1;
416  }
417  else //temp1=kInterRed(result,currRing->qideal);
418    return result;
419}
420
421/*2
422* ideal/module intersection for a list of objects
423* given as 'resolvente'
424*/
425ideal idMultSect(resolvente arg, int length, GbVariant alg)
426{
427  int i,j=0,k=0,l,maxrk=-1,realrki;
428  unsigned syzComp;
429  ideal bigmat,tempstd,result;
430  poly p;
431  int isIdeal=0;
432  intvec * w=NULL;
433
434  /* find 0-ideals and max rank -----------------------------------*/
435  for (i=0;i<length;i++)
436  {
437    if (!idIs0(arg[i]))
438    {
439      realrki=id_RankFreeModule(arg[i],currRing);
440      k++;
441      j += IDELEMS(arg[i]);
442      if (realrki>maxrk) maxrk = realrki;
443    }
444    else
445    {
446      if (arg[i]!=NULL)
447      {
448        return idInit(1,arg[i]->rank);
449      }
450    }
451  }
452  if (maxrk == 0)
453  {
454    isIdeal = 1;
455    maxrk = 1;
456  }
457  /* init -----------------------------------------------------------*/
458  j += maxrk;
459  syzComp = k*maxrk;
460
461  ring orig_ring=currRing;
462  ring syz_ring=rAssure_SyzOrder(orig_ring,TRUE);
463  rSetSyzComp(syzComp,syz_ring);
464  rChangeCurrRing(syz_ring);
465
466  bigmat = idInit(j,(k+1)*maxrk);
467  /* create unit matrices ------------------------------------------*/
468  for (i=0;i<maxrk;i++)
469  {
470    for (j=0;j<=k;j++)
471    {
472      p = pOne();
473      pSetComp(p,i+1+j*maxrk);
474      pSetmComp(p);
475      bigmat->m[i] = pAdd(bigmat->m[i],p);
476    }
477  }
478  /* enter given ideals ------------------------------------------*/
479  i = maxrk;
480  k = 0;
481  for (j=0;j<length;j++)
482  {
483    if (arg[j]!=NULL)
484    {
485      for (l=0;l<IDELEMS(arg[j]);l++)
486      {
487        if (arg[j]->m[l]!=NULL)
488        {
489          if (syz_ring==orig_ring)
490            bigmat->m[i] = pCopy(arg[j]->m[l]);
491          else
492            bigmat->m[i] = prCopyR(arg[j]->m[l], orig_ring,currRing);
493          p_Shift(&(bigmat->m[i]),k*maxrk+isIdeal,currRing);
494          i++;
495        }
496      }
497      k++;
498    }
499  }
500  /* std computation --------------------------------------------*/
501  if (alg==GbDefault) alg=GbStd;
502  if (alg==GbStd)
503  {
504    if (TEST_OPT_PROT) { PrintS("std:"); mflush(); }
505    tempstd = kStd(bigmat,currRing->qideal,testHomog,&w,NULL,syzComp);
506    if (w!=NULL) delete w;
507    idDelete(&bigmat);
508  }
509  else if (alg==GbSlimgb)
510  {
511    if (TEST_OPT_PROT) { PrintS("slimgb:"); mflush(); }
512    tempstd = t_rep_gb(currRing, bigmat, syzComp);
513    idDelete(&bigmat);
514  }
515  else if (alg==GbGroebner)
516  {
517    if (TEST_OPT_PROT) { PrintS("groebner:"); mflush(); }
518    BOOLEAN err;
519    tempstd=(ideal)iiCallLibProc1("groebner",bigmat,MODUL_CMD,err);
520    if (err)
521    {
522      Werror("error %d in >>groebner<<",err);
523      tempstd=idInit(1,1);
524    }
525  }
526//  else if (alg==GbModstd): requires ideal, not module
527//  {
528//    if (TEST_OPT_PROT) { PrintS("modstd:"); mflush(); }
529//    BOOLEAN err;
530//    tempstd=(ideal)iiCallLibProc1("modStd",bigmat,MODUL_CMD,err);
531//    if (err)
532//    {
533//      Werror("error %d in >>modStd<<",err);
534//      tempstd=idInit(1,1);
535//    }
536//  }
537  //else if (alg==GbSba): requires order C,...
538  //{
539  //  if (TEST_OPT_PROT) { PrintS("sba:"); mflush(); }
540  //  tempstd = kSba(bigmat,currRing->qideal,hom,w,1,0,NULL,syzComp);
541  //  idDelete(&bigmat);
542  //}
543  else
544  {
545    tempstd=idInit(1,1);
546    Werror("wrong algorith %d for SB",(int)alg);
547  }
548
549  if(syz_ring!=orig_ring)
550    rChangeCurrRing(orig_ring);
551
552  /* interprete result ----------------------------------------*/
553  result = idInit(IDELEMS(tempstd),maxrk);
554  k = 0;
555  for (j=0;j<IDELEMS(tempstd);j++)
556  {
557    if ((tempstd->m[j]!=NULL) && (__p_GetComp(tempstd->m[j],syz_ring)>syzComp))
558    {
559      if (syz_ring==orig_ring)
560        p = pCopy(tempstd->m[j]);
561      else
562        p = prCopyR(tempstd->m[j], syz_ring,currRing);
563      p_Shift(&p,-syzComp-isIdeal,currRing);
564      result->m[k] = p;
565      k++;
566    }
567  }
568  /* clean up ----------------------------------------------------*/
569  if(syz_ring!=orig_ring)
570    rChangeCurrRing(syz_ring);
571  idDelete(&tempstd);
572  if(syz_ring!=orig_ring)
573  {
574    rChangeCurrRing(orig_ring);
575    rDelete(syz_ring);
576  }
577  idSkipZeroes(result);
578  return result;
579}
580
581/*2
582*computes syzygies of h1,
583*if quot != NULL it computes in the quotient ring modulo "quot"
584*works always in a ring with ringorder_s
585*/
586static ideal idPrepare (ideal  h1, tHomog hom, int syzcomp, intvec **w, GbVariant alg)
587{
588  ideal   h2, h3;
589  int     j,k;
590  poly    p,q;
591
592  if (idIs0(h1)) return NULL;
593  k = id_RankFreeModule(h1,currRing);
594  h2=idCopy(h1);
595  int i = IDELEMS(h2);
596  if (k == 0)
597  {
598    id_Shift(h2,1,currRing);
599    k = 1;
600  }
601  if (syzcomp<k)
602  {
603    Warn("syzcomp too low, should be %d instead of %d",k,syzcomp);
604    syzcomp = k;
605    rSetSyzComp(k,currRing);
606  }
607  h2->rank = syzcomp+i;
608
609  //if (hom==testHomog)
610  //{
611  //  if(idHomIdeal(h1,currRing->qideal))
612  //  {
613  //    hom=TRUE;
614  //  }
615  //}
616
617  for (j=0; j<i; j++)
618  {
619    p = h2->m[j];
620    q = pOne();
621    pSetComp(q,syzcomp+1+j);
622    pSetmComp(q);
623    if (p!=NULL)
624    {
625      while (pNext(p)) pIter(p);
626      p->next = q;
627    }
628    else
629      h2->m[j]=q;
630  }
631
632  idTest(h2);
633
634  if (alg==GbDefault) alg=GbStd;
635  if (alg==GbStd)
636  {
637    if (TEST_OPT_PROT) { PrintS("std:"); mflush(); }
638    h3 = kStd(h2,currRing->qideal,hom,w,NULL,syzcomp);
639  }
640  else if (alg==GbSlimgb)
641  {
642    if (TEST_OPT_PROT) { PrintS("slimgb:"); mflush(); }
643    h3 = t_rep_gb(currRing, h2, syzcomp);
644  }
645  else if (alg==GbGroebner)
646  {
647    if (TEST_OPT_PROT) { PrintS("groebner:"); mflush(); }
648    BOOLEAN err;
649    h3=(ideal)iiCallLibProc1("groebner",idCopy(h2),MODUL_CMD,err);
650    if (err)
651    {
652      Werror("error %d in >>groebner<<",err);
653      h3=idInit(1,1);
654    }
655  }
656  else if (alg==GbModstd)
657  {
658    if (TEST_OPT_PROT) { PrintS("modstd:"); mflush(); }
659    BOOLEAN err;
660    void *args[]={idCopy(h2),(void*)1,NULL};
661    int arg_t[]={MODUL_CMD,INT_CMD,0};
662    h3=(ideal)iiCallLibProcM("modStd",args,arg_t,err);
663    if (err)
664    {
665      Werror("error %d in >>modStd<<",err);
666      h3=idInit(1,1);
667    }
668  }
669  else if (alg==GbStdSat)
670  {
671    if (TEST_OPT_PROT) { PrintS("std:sat:"); mflush(); }
672    BOOLEAN err;
673    // search for 2nd block of vars
674    int i=0;
675    int block=-1;
676    loop
677    {
678      if ((currRing->order[i]!=ringorder_c)
679      && (currRing->order[i]!=ringorder_C)
680      && (currRing->order[i]!=ringorder_s))
681      {
682        if (currRing->order[i]==0) { err=TRUE;break;}
683        block++;
684        if (block==1) { block=i; break;}
685      }
686      i++;
687    }
688    if (block>0)
689    {
690      if (TEST_OPT_PROT)
691      {
692        Print("sat(%d..%d)\n",currRing->block0[block],currRing->block1[block]);
693        mflush();
694      }
695      ideal v=idInit(currRing->block1[block]-currRing->block0[block]+1,1);
696      for(i=currRing->block0[block];i<=currRing->block1[block];i++)
697      {
698        v->m[i-currRing->block0[block]]=pOne();
699        pSetExp(v->m[i-currRing->block0[block]],i,1);
700        pSetm(v->m[i-currRing->block0[block]]);
701      }
702      void *args[]={idCopy(h2),v,NULL};
703      int arg_t[]={MODUL_CMD,IDEAL_CMD,0};
704      h3=(ideal)iiCallLibProcM("satstd",args,arg_t,err);
705    }
706    if (err)
707    {
708      Werror("error %d in >>satstd<<",err);
709      h3=idInit(1,1);
710    }
711  }
712  //else if (alg==GbSba): requires order C,...
713  //{
714  //  if (TEST_OPT_PROT) { PrintS("sba:"); mflush(); }
715  //  h3 = kSba(h2,currRing->qideal,hom,w,1,0,NULL,syzcomp);
716  //}
717  else
718  {
719    h3=idInit(1,1);
720    Werror("wrong algorith %d for SB",(int)alg);
721  }
722
723  idDelete(&h2);
724  return h3;
725}
726
727/*2
728* compute the syzygies of h1 in R/quot,
729* weights of components are in w
730* if setRegularity, return the regularity in deg
731* do not change h1,  w
732*/
733ideal idSyzygies (ideal  h1, tHomog h,intvec **w, BOOLEAN setSyzComp,
734                  BOOLEAN setRegularity, int *deg, GbVariant alg)
735{
736  ideal s_h1;
737  int   j, k, length=0,reg;
738  BOOLEAN isMonomial=TRUE;
739  int ii, idElemens_h1;
740
741  assume(h1 != NULL);
742
743  idElemens_h1=IDELEMS(h1);
744#ifdef PDEBUG
745  for(ii=0;ii<idElemens_h1 /*IDELEMS(h1)*/;ii++) pTest(h1->m[ii]);
746#endif
747  if (idIs0(h1))
748  {
749    ideal result=idFreeModule(idElemens_h1/*IDELEMS(h1)*/);
750    return result;
751  }
752  int slength=(int)id_RankFreeModule(h1,currRing);
753  k=si_max(1,slength /*id_RankFreeModule(h1)*/);
754
755  assume(currRing != NULL);
756  ring orig_ring=currRing;
757  ring syz_ring=rAssure_SyzComp(orig_ring,TRUE);
758  if (setSyzComp) rSetSyzComp(k,syz_ring);
759
760  if (orig_ring != syz_ring)
761  {
762    rChangeCurrRing(syz_ring);
763    s_h1=idrCopyR_NoSort(h1,orig_ring,syz_ring);
764  }
765  else
766  {
767    s_h1 = h1;
768  }
769
770  idTest(s_h1);
771
772  ideal s_h3=idPrepare(s_h1,h,k,w,alg); // main (syz) GB computation
773
774  if (s_h3==NULL)
775  {
776    if (orig_ring != syz_ring)
777    {
778      rChangeCurrRing(orig_ring);
779      rDelete(syz_ring);
780    }
781    return idFreeModule( idElemens_h1 /*IDELEMS(h1)*/);
782  }
783
784  if (orig_ring != syz_ring)
785  {
786    idDelete(&s_h1);
787    for (j=0; j<IDELEMS(s_h3); j++)
788    {
789      if (s_h3->m[j] != NULL)
790      {
791        if (p_MinComp(s_h3->m[j],syz_ring) > k)
792          p_Shift(&s_h3->m[j], -k,syz_ring);
793        else
794          p_Delete(&s_h3->m[j],syz_ring);
795      }
796    }
797    idSkipZeroes(s_h3);
798    s_h3->rank -= k;
799    rChangeCurrRing(orig_ring);
800    s_h3 = idrMoveR_NoSort(s_h3, syz_ring, orig_ring);
801    rDelete(syz_ring);
802    #ifdef HAVE_PLURAL
803    if (rIsPluralRing(orig_ring))
804    {
805      id_DelMultiples(s_h3,orig_ring);
806      idSkipZeroes(s_h3);
807    }
808    #endif
809    idTest(s_h3);
810    return s_h3;
811  }
812
813  ideal e = idInit(IDELEMS(s_h3), s_h3->rank);
814
815  for (j=IDELEMS(s_h3)-1; j>=0; j--)
816  {
817    if (s_h3->m[j] != NULL)
818    {
819      if (p_MinComp(s_h3->m[j],syz_ring) <= k)
820      {
821        e->m[j] = s_h3->m[j];
822        isMonomial=isMonomial && (pNext(s_h3->m[j])==NULL);
823        p_Delete(&pNext(s_h3->m[j]),syz_ring);
824        s_h3->m[j] = NULL;
825      }
826    }
827  }
828
829  idSkipZeroes(s_h3);
830  idSkipZeroes(e);
831
832  if ((deg != NULL)
833  && (!isMonomial)
834  && (!TEST_OPT_NOTREGULARITY)
835  && (setRegularity)
836  && (h==isHomog)
837  && (!rIsPluralRing(currRing))
838  && (!rField_is_Ring(currRing))
839  )
840  {
841    assume(orig_ring==syz_ring);
842    ring dp_C_ring = rAssure_dp_C(syz_ring); // will do rChangeCurrRing later
843    if (dp_C_ring != syz_ring)
844    {
845      rChangeCurrRing(dp_C_ring);
846      e = idrMoveR_NoSort(e, syz_ring, dp_C_ring);
847    }
848    resolvente res = sySchreyerResolvente(e,-1,&length,TRUE, TRUE);
849    intvec * dummy = syBetti(res,length,&reg, *w);
850    *deg = reg+2;
851    delete dummy;
852    for (j=0;j<length;j++)
853    {
854      if (res[j]!=NULL) idDelete(&(res[j]));
855    }
856    omFreeSize((ADDRESS)res,length*sizeof(ideal));
857    idDelete(&e);
858    if (dp_C_ring != orig_ring)
859    {
860      rChangeCurrRing(orig_ring);
861      rDelete(dp_C_ring);
862    }
863  }
864  else
865  {
866    idDelete(&e);
867  }
868  assume(orig_ring==currRing);
869  idTest(s_h3);
870  if (currRing->qideal != NULL)
871  {
872    ideal ts_h3=kStd(s_h3,currRing->qideal,h,w);
873    idDelete(&s_h3);
874    s_h3 = ts_h3;
875  }
876  return s_h3;
877}
878
879/*2
880*/
881ideal idXXX (ideal  h1, int k)
882{
883  ideal s_h1;
884  intvec *w=NULL;
885
886  assume(currRing != NULL);
887  ring orig_ring=currRing;
888  ring syz_ring=rAssure_SyzComp(orig_ring,TRUE);
889  rSetSyzComp(k,syz_ring);
890  rChangeCurrRing(syz_ring);
891
892  if (orig_ring != syz_ring)
893  {
894    s_h1=idrCopyR_NoSort(h1,orig_ring, syz_ring);
895  }
896  else
897  {
898    s_h1 = h1;
899  }
900
901  ideal s_h3=kStd(s_h1,NULL,testHomog,&w,NULL,k);
902
903  if (s_h3==NULL)
904  {
905    return idFreeModule(IDELEMS(h1));
906  }
907
908  if (orig_ring != syz_ring)
909  {
910    idDelete(&s_h1);
911    idSkipZeroes(s_h3);
912    rChangeCurrRing(orig_ring);
913    s_h3 = idrMoveR_NoSort(s_h3, syz_ring, orig_ring);
914    rDelete(syz_ring);
915    idTest(s_h3);
916    return s_h3;
917  }
918
919  idSkipZeroes(s_h3);
920  idTest(s_h3);
921  return s_h3;
922}
923
924/*
925*computes a standard basis for h1 and stores the transformation matrix
926* in ma
927*/
928ideal idLiftStd (ideal  h1, matrix* ma, tHomog hi, ideal * syz, GbVariant alg)
929{
930  int  i, j, t, inputIsIdeal=id_RankFreeModule(h1,currRing);
931  long k;
932  poly  p=NULL, q;
933  intvec *w=NULL;
934
935  idDelete((ideal*)ma);
936  BOOLEAN lift3=FALSE;
937  if (syz!=NULL) { lift3=TRUE; idDelete(syz); }
938  if (idIs0(h1))
939  {
940    *ma=mpNew(1,0);
941    if (lift3)
942    {
943      *syz=idFreeModule(IDELEMS(h1));
944    }
945    return idInit(1,h1->rank);
946  }
947
948  BITSET save2;
949  SI_SAVE_OPT2(save2);
950
951  k=si_max(1L,id_RankFreeModule(h1,currRing));
952
953  if ((k==1) && (!lift3)) si_opt_2 |=Sy_bit(V_IDLIFT);
954
955  ring orig_ring = currRing;
956  ring syz_ring = rAssure_SyzOrder(orig_ring,TRUE);
957  rSetSyzComp(k,syz_ring);
958  rChangeCurrRing(syz_ring);
959
960  ideal s_h1=h1;
961
962  if (orig_ring != syz_ring)
963    s_h1 = idrCopyR_NoSort(h1,orig_ring,syz_ring);
964  else
965    s_h1 = h1;
966
967  ideal s_h3=idPrepare(s_h1,hi,k,&w,alg); // main (syz) GB computation
968
969  ideal s_h2 = idInit(IDELEMS(s_h3), s_h3->rank);
970
971  if (lift3) (*syz)=idInit(IDELEMS(s_h3),IDELEMS(h1));
972
973  if (w!=NULL) delete w;
974  i = 0;
975
976  // now sort the result, SB : leave in s_h3
977  //                      T:  put in s_h2
978  //                      syz: put in *syz
979  for (j=0; j<IDELEMS(s_h3); j++)
980  {
981    if (s_h3->m[j] != NULL)
982    {
983      //if (p_MinComp(s_h3->m[j],syz_ring) <= k)
984      if (pGetComp(s_h3->m[j]) <= k) // syz_ring == currRing
985      {
986        i++;
987        q = s_h3->m[j];
988        while (pNext(q) != NULL)
989        {
990          if (pGetComp(pNext(q)) > k)
991          {
992            s_h2->m[j] = pNext(q);
993            pNext(q) = NULL;
994          }
995          else
996          {
997            pIter(q);
998          }
999        }
1000        if (!inputIsIdeal) p_Shift(&(s_h3->m[j]), -1,currRing);
1001      }
1002      else
1003      {
1004        // we a syzygy here:
1005        if (lift3)
1006        {
1007          p_Shift(&s_h3->m[j], -k,currRing);
1008          (*syz)->m[j]=s_h3->m[j];
1009          s_h3->m[j]=NULL;
1010        }
1011        else
1012          p_Delete(&(s_h3->m[j]),currRing);
1013      }
1014    }
1015  }
1016  idSkipZeroes(s_h3);
1017  //extern char * iiStringMatrix(matrix im, int dim,char ch);
1018  //PrintS("SB: ----------------------------------------\n");
1019  //PrintS(iiStringMatrix((matrix)s_h3,k,'\n'));
1020  //PrintLn();
1021  //PrintS("T: ----------------------------------------\n");
1022  //PrintS(iiStringMatrix((matrix)s_h2,h1->rank,'\n'));
1023  //PrintLn();
1024
1025  if (lift3) idSkipZeroes(*syz);
1026
1027  j = IDELEMS(s_h1);
1028
1029
1030  if (syz_ring!=orig_ring)
1031  {
1032    idDelete(&s_h1);
1033    rChangeCurrRing(orig_ring);
1034  }
1035
1036  *ma = mpNew(j,i);
1037
1038  i = 1;
1039  for (j=0; j<IDELEMS(s_h2); j++)
1040  {
1041    if (s_h2->m[j] != NULL)
1042    {
1043      q = prMoveR( s_h2->m[j], syz_ring,orig_ring);
1044      s_h2->m[j] = NULL;
1045
1046      if (q!=NULL)
1047      {
1048        q=pReverse(q);
1049        while (q != NULL)
1050        {
1051          p = q;
1052          pIter(q);
1053          pNext(p) = NULL;
1054          t=pGetComp(p);
1055          pSetComp(p,0);
1056          pSetmComp(p);
1057          MATELEM(*ma,t-k,i) = pAdd(MATELEM(*ma,t-k,i),p);
1058        }
1059      }
1060      i++;
1061    }
1062  }
1063  idDelete(&s_h2);
1064
1065  for (i=0; i<IDELEMS(s_h3); i++)
1066  {
1067    s_h3->m[i] = prMoveR_NoSort(s_h3->m[i], syz_ring,orig_ring);
1068  }
1069  if (lift3)
1070  {
1071    for (i=0; i<IDELEMS(*syz); i++)
1072    {
1073      (*syz)->m[i] = prMoveR_NoSort((*syz)->m[i], syz_ring,orig_ring);
1074    }
1075  }
1076
1077  if (syz_ring!=orig_ring) rDelete(syz_ring);
1078  SI_RESTORE_OPT2(save2);
1079  return s_h3;
1080}
1081
1082static void idPrepareStd(ideal s_temp, int k)
1083{
1084  int j,rk=id_RankFreeModule(s_temp,currRing);
1085  poly p,q;
1086
1087  if (rk == 0)
1088  {
1089    for (j=0; j<IDELEMS(s_temp); j++)
1090    {
1091      if (s_temp->m[j]!=NULL) pSetCompP(s_temp->m[j],1);
1092    }
1093    k = si_max(k,1);
1094  }
1095  for (j=0; j<IDELEMS(s_temp); j++)
1096  {
1097    if (s_temp->m[j]!=NULL)
1098    {
1099      p = s_temp->m[j];
1100      q = pOne();
1101      //pGetCoeff(q)=nInpNeg(pGetCoeff(q));   //set q to -1
1102      pSetComp(q,k+1+j);
1103      pSetmComp(q);
1104      while (pNext(p)) pIter(p);
1105      pNext(p) = q;
1106    }
1107  }
1108  s_temp->rank = k+IDELEMS(s_temp);
1109}
1110
1111/*2
1112*computes a representation of the generators of submod with respect to those
1113* of mod
1114*/
1115
1116ideal idLift(ideal mod, ideal submod,ideal *rest, BOOLEAN goodShape,
1117             BOOLEAN isSB, BOOLEAN divide, matrix *unit, GbVariant alg)
1118{
1119  int lsmod =id_RankFreeModule(submod,currRing), j, k;
1120  int comps_to_add=0;
1121  poly p;
1122
1123  if (idIs0(submod))
1124  {
1125    if (unit!=NULL)
1126    {
1127      *unit=mpNew(1,1);
1128      MATELEM(*unit,1,1)=pOne();
1129    }
1130    if (rest!=NULL)
1131    {
1132      *rest=idInit(1,mod->rank);
1133    }
1134    return idInit(1,mod->rank);
1135  }
1136  if (idIs0(mod)) /* and not idIs0(submod) */
1137  {
1138    WerrorS("2nd module does not lie in the first");
1139    return NULL;
1140  }
1141  if (unit!=NULL)
1142  {
1143    comps_to_add = IDELEMS(submod);
1144    while ((comps_to_add>0) && (submod->m[comps_to_add-1]==NULL))
1145      comps_to_add--;
1146  }
1147  k=si_max(id_RankFreeModule(mod,currRing),id_RankFreeModule(submod,currRing));
1148  if  ((k!=0) && (lsmod==0)) lsmod=1;
1149  k=si_max(k,(int)mod->rank);
1150  if (k<submod->rank) { WarnS("rk(submod) > rk(mod) ?");k=submod->rank; }
1151
1152  ring orig_ring=currRing;
1153  ring syz_ring=rAssure_SyzOrder(orig_ring,TRUE);
1154  rSetSyzComp(k,syz_ring);
1155  rChangeCurrRing(syz_ring);
1156
1157  ideal s_mod, s_temp;
1158  if (orig_ring != syz_ring)
1159  {
1160    s_mod = idrCopyR_NoSort(mod,orig_ring,syz_ring);
1161    s_temp = idrCopyR_NoSort(submod,orig_ring,syz_ring);
1162  }
1163  else
1164  {
1165    s_mod = mod;
1166    s_temp = idCopy(submod);
1167  }
1168  ideal s_h3;
1169  if (isSB)
1170  {
1171    s_h3 = idCopy(s_mod);
1172    idPrepareStd(s_h3, k+comps_to_add);
1173  }
1174  else
1175  {
1176    s_h3 = idPrepare(s_mod,(tHomog)FALSE,k+comps_to_add,NULL,alg);
1177  }
1178  if (!goodShape)
1179  {
1180    for (j=0;j<IDELEMS(s_h3);j++)
1181    {
1182      if ((s_h3->m[j] != NULL) && (pMinComp(s_h3->m[j]) > k))
1183        p_Delete(&(s_h3->m[j]),currRing);
1184    }
1185  }
1186  idSkipZeroes(s_h3);
1187  if (lsmod==0)
1188  {
1189    id_Shift(s_temp,1,currRing);
1190  }
1191  if (unit!=NULL)
1192  {
1193    for(j = 0;j<comps_to_add;j++)
1194    {
1195      p = s_temp->m[j];
1196      if (p!=NULL)
1197      {
1198        while (pNext(p)!=NULL) pIter(p);
1199        pNext(p) = pOne();
1200        pIter(p);
1201        pSetComp(p,1+j+k);
1202        pSetmComp(p);
1203        p = pNeg(p);
1204      }
1205    }
1206    s_temp->rank += (k+comps_to_add);
1207  }
1208  ideal s_result = kNF(s_h3,currRing->qideal,s_temp,k);
1209  s_result->rank = s_h3->rank;
1210  ideal s_rest = idInit(IDELEMS(s_result),k);
1211  idDelete(&s_h3);
1212  idDelete(&s_temp);
1213
1214  for (j=0;j<IDELEMS(s_result);j++)
1215  {
1216    if (s_result->m[j]!=NULL)
1217    {
1218      if (pGetComp(s_result->m[j])<=k)
1219      {
1220        if (!divide)
1221        {
1222          if (isSB)
1223          {
1224            WarnS("first module not a standardbasis\n"
1225              "// ** or second not a proper submodule");
1226          }
1227          else
1228            WerrorS("2nd module does not lie in the first");
1229          idDelete(&s_result);
1230          idDelete(&s_rest);
1231          s_result=idInit(IDELEMS(submod),submod->rank);
1232          break;
1233        }
1234        else
1235        {
1236          p = s_rest->m[j] = s_result->m[j];
1237          while ((pNext(p)!=NULL) && (pGetComp(pNext(p))<=k)) pIter(p);
1238          s_result->m[j] = pNext(p);
1239          pNext(p) = NULL;
1240        }
1241      }
1242      p_Shift(&(s_result->m[j]),-k,currRing);
1243      pNeg(s_result->m[j]);
1244    }
1245  }
1246  if ((lsmod==0) && (s_rest!=NULL))
1247  {
1248    for (j=IDELEMS(s_rest);j>0;j--)
1249    {
1250      if (s_rest->m[j-1]!=NULL)
1251      {
1252        p_Shift(&(s_rest->m[j-1]),-1,currRing);
1253        s_rest->m[j-1] = s_rest->m[j-1];
1254      }
1255    }
1256  }
1257  if(syz_ring!=orig_ring)
1258  {
1259    idDelete(&s_mod);
1260    rChangeCurrRing(orig_ring);
1261    s_result = idrMoveR_NoSort(s_result, syz_ring, orig_ring);
1262    s_rest = idrMoveR_NoSort(s_rest, syz_ring, orig_ring);
1263    rDelete(syz_ring);
1264  }
1265  if (rest!=NULL)
1266    *rest = s_rest;
1267  else
1268    idDelete(&s_rest);
1269//idPrint(s_result);
1270  if (unit!=NULL)
1271  {
1272    *unit=mpNew(comps_to_add,comps_to_add);
1273    int i;
1274    for(i=0;i<IDELEMS(s_result);i++)
1275    {
1276      poly p=s_result->m[i];
1277      poly q=NULL;
1278      while(p!=NULL)
1279      {
1280        if(pGetComp(p)<=comps_to_add)
1281        {
1282          pSetComp(p,0);
1283          if (q!=NULL)
1284          {
1285            pNext(q)=pNext(p);
1286          }
1287          else
1288          {
1289            pIter(s_result->m[i]);
1290          }
1291          pNext(p)=NULL;
1292          MATELEM(*unit,i+1,i+1)=pAdd(MATELEM(*unit,i+1,i+1),p);
1293          if(q!=NULL)   p=pNext(q);
1294          else          p=s_result->m[i];
1295        }
1296        else
1297        {
1298          q=p;
1299          pIter(p);
1300        }
1301      }
1302      p_Shift(&s_result->m[i],-comps_to_add,currRing);
1303    }
1304  }
1305  return s_result;
1306}
1307
1308/*2
1309*computes division of P by Q with remainder up to (w-weighted) degree n
1310*P, Q, and w are not changed
1311*/
1312void idLiftW(ideal P,ideal Q,int n,matrix &T, ideal &R,short *w)
1313{
1314  long N=0;
1315  int i;
1316  for(i=IDELEMS(Q)-1;i>=0;i--)
1317    if(w==NULL)
1318      N=si_max(N,p_Deg(Q->m[i],currRing));
1319    else
1320      N=si_max(N,p_DegW(Q->m[i],w,currRing));
1321  N+=n;
1322
1323  T=mpNew(IDELEMS(Q),IDELEMS(P));
1324  R=idInit(IDELEMS(P),P->rank);
1325
1326  for(i=IDELEMS(P)-1;i>=0;i--)
1327  {
1328    poly p;
1329    if(w==NULL)
1330      p=ppJet(P->m[i],N);
1331    else
1332      p=ppJetW(P->m[i],N,w);
1333
1334    int j=IDELEMS(Q)-1;
1335    while(p!=NULL)
1336    {
1337      if(pDivisibleBy(Q->m[j],p))
1338      {
1339        poly p0=p_DivideM(pHead(p),pHead(Q->m[j]),currRing);
1340        if(w==NULL)
1341          p=pJet(pSub(p,ppMult_mm(Q->m[j],p0)),N);
1342        else
1343          p=pJetW(pSub(p,ppMult_mm(Q->m[j],p0)),N,w);
1344        pNormalize(p);
1345        if(((w==NULL)&&(p_Deg(p0,currRing)>n))||((w!=NULL)&&(p_DegW(p0,w,currRing)>n)))
1346          p_Delete(&p0,currRing);
1347        else
1348          MATELEM(T,j+1,i+1)=pAdd(MATELEM(T,j+1,i+1),p0);
1349        j=IDELEMS(Q)-1;
1350      }
1351      else
1352      {
1353        if(j==0)
1354        {
1355          poly p0=p;
1356          pIter(p);
1357          pNext(p0)=NULL;
1358          if(((w==NULL)&&(p_Deg(p0,currRing)>n))
1359          ||((w!=NULL)&&(p_DegW(p0,w,currRing)>n)))
1360            p_Delete(&p0,currRing);
1361          else
1362            R->m[i]=pAdd(R->m[i],p0);
1363          j=IDELEMS(Q)-1;
1364        }
1365        else
1366          j--;
1367      }
1368    }
1369  }
1370}
1371
1372/*2
1373*computes the quotient of h1,h2 : internal routine for idQuot
1374*BEWARE: the returned ideals may contain incorrectly ordered polys !
1375*
1376*/
1377static ideal idInitializeQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb, BOOLEAN *addOnlyOne, int *kkmax)
1378{
1379  idTest(h1);
1380  idTest(h2);
1381
1382  ideal temph1;
1383  poly     p,q = NULL;
1384  int i,l,ll,k,kkk,kmax;
1385  int j = 0;
1386  int k1 = id_RankFreeModule(h1,currRing);
1387  int k2 = id_RankFreeModule(h2,currRing);
1388  tHomog   hom=isNotHomog;
1389  k=si_max(k1,k2);
1390  if (k==0)
1391    k = 1;
1392  if ((k2==0) && (k>1)) *addOnlyOne = FALSE;
1393  intvec * weights;
1394  hom = (tHomog)idHomModule(h1,currRing->qideal,&weights);
1395  if /**addOnlyOne &&*/ (/*(*/ !h1IsStb /*)*/)
1396    temph1 = kStd(h1,currRing->qideal,hom,&weights,NULL);
1397  else
1398    temph1 = idCopy(h1);
1399  if (weights!=NULL) delete weights;
1400  idTest(temph1);
1401/*--- making a single vector from h2 ---------------------*/
1402  for (i=0; i<IDELEMS(h2); i++)
1403  {
1404    if (h2->m[i] != NULL)
1405    {
1406      p = pCopy(h2->m[i]);
1407      if (k2 == 0)
1408        p_Shift(&p,j*k+1,currRing);
1409      else
1410        p_Shift(&p,j*k,currRing);
1411      q = pAdd(q,p);
1412      j++;
1413    }
1414  }
1415  *kkmax = kmax = j*k+1;
1416/*--- adding a monomial for the result (syzygy) ----------*/
1417  p = q;
1418  while (pNext(p)!=NULL) pIter(p);
1419  pNext(p) = pOne();
1420  pIter(p);
1421  pSetComp(p,kmax);
1422  pSetmComp(p);
1423/*--- constructing the big matrix ------------------------*/
1424  ideal h4 = idInit(k,kmax+k-1);
1425  h4->m[0] = q;
1426  if (k2 == 0)
1427  {
1428    for (i=1; i<k; i++)
1429    {
1430      if (h4->m[i-1]!=NULL)
1431      {
1432        p = p_Copy_noCheck(h4->m[i-1], currRing);
1433        p_Shift(&p,1,currRing);
1434        h4->m[i] = p;
1435      }
1436      else break;
1437    }
1438  }
1439  idSkipZeroes(h4);
1440  kkk = IDELEMS(h4);
1441  i = IDELEMS(temph1);
1442  for (l=0; l<i; l++)
1443  {
1444    if(temph1->m[l]!=NULL)
1445    {
1446      for (ll=0; ll<j; ll++)
1447      {
1448        p = pCopy(temph1->m[l]);
1449        if (k1 == 0)
1450          p_Shift(&p,ll*k+1,currRing);
1451        else
1452          p_Shift(&p,ll*k,currRing);
1453        if (kkk >= IDELEMS(h4))
1454        {
1455          pEnlargeSet(&(h4->m),IDELEMS(h4),16);
1456          IDELEMS(h4) += 16;
1457        }
1458        h4->m[kkk] = p;
1459        kkk++;
1460      }
1461    }
1462  }
1463/*--- if h2 goes in as single vector - the h1-part is just SB ---*/
1464  if (*addOnlyOne)
1465  {
1466    idSkipZeroes(h4);
1467    p = h4->m[0];
1468    for (i=0;i<IDELEMS(h4)-1;i++)
1469    {
1470      h4->m[i] = h4->m[i+1];
1471    }
1472    h4->m[IDELEMS(h4)-1] = p;
1473  }
1474  idDelete(&temph1);
1475  //idTest(h4);//see remark at the beginning
1476  return h4;
1477}
1478
1479/*2
1480*computes the quotient of h1,h2
1481*/
1482ideal idQuot (ideal  h1, ideal h2, BOOLEAN h1IsStb, BOOLEAN resultIsIdeal)
1483{
1484  // first check for special case h1:(0)
1485  if (idIs0(h2))
1486  {
1487    ideal res;
1488    if (resultIsIdeal)
1489    {
1490      res = idInit(1,1);
1491      res->m[0] = pOne();
1492    }
1493    else
1494      res = idFreeModule(h1->rank);
1495    return res;
1496  }
1497  int i, kmax;
1498  BOOLEAN  addOnlyOne=TRUE;
1499  tHomog   hom=isNotHomog;
1500  intvec * weights1;
1501
1502  ideal s_h4 = idInitializeQuot (h1,h2,h1IsStb,&addOnlyOne,&kmax);
1503
1504  hom = (tHomog)idHomModule(s_h4,currRing->qideal,&weights1);
1505
1506  ring orig_ring=currRing;
1507  ring syz_ring=rAssure_SyzOrder(orig_ring,TRUE);
1508  rSetSyzComp(kmax-1,syz_ring);
1509  rChangeCurrRing(syz_ring);
1510  if (orig_ring!=syz_ring)
1511  //  s_h4 = idrMoveR_NoSort(s_h4,orig_ring, syz_ring);
1512    s_h4 = idrMoveR(s_h4,orig_ring, syz_ring);
1513  idTest(s_h4);
1514  #if 0
1515  void ipPrint_MA0(matrix m, const char *name);
1516  matrix m=idModule2Matrix(idCopy(s_h4));
1517  PrintS("start:\n");
1518  ipPrint_MA0(m,"Q");
1519  idDelete((ideal *)&m);
1520  PrintS("last elem:");wrp(s_h4->m[IDELEMS(s_h4)-1]);PrintLn();
1521  #endif
1522  ideal s_h3;
1523  if (addOnlyOne)
1524  {
1525    BITSET old_test1;
1526    SI_SAVE_OPT1(old_test1);
1527    if(!rField_is_Ring(currRing)) si_opt_1 |= Sy_bit(OPT_SB_1);
1528    s_h3 = kStd(s_h4,currRing->qideal,hom,&weights1,NULL,0/*kmax-1*/,IDELEMS(s_h4)-1);
1529    SI_RESTORE_OPT1(old_test1);
1530  }
1531  else
1532  {
1533    s_h3 = kStd(s_h4,currRing->qideal,hom,&weights1,NULL,kmax-1);
1534  }
1535  #if 0
1536  // only together with the above debug stuff
1537  idSkipZeroes(s_h3);
1538  m=idModule2Matrix(idCopy(s_h3));
1539  Print("result, kmax=%d:\n",kmax);
1540  ipPrint_MA0(m,"S");
1541  idDelete((ideal *)&m);
1542  #endif
1543  idTest(s_h3);
1544  if (weights1!=NULL) delete weights1;
1545  idDelete(&s_h4);
1546
1547  for (i=0;i<IDELEMS(s_h3);i++)
1548  {
1549    if ((s_h3->m[i]!=NULL) && (pGetComp(s_h3->m[i])>=kmax))
1550    {
1551      if (resultIsIdeal)
1552        p_Shift(&s_h3->m[i],-kmax,currRing);
1553      else
1554        p_Shift(&s_h3->m[i],-kmax+1,currRing);
1555    }
1556    else
1557      p_Delete(&s_h3->m[i],currRing);
1558  }
1559  if (resultIsIdeal)
1560    s_h3->rank = 1;
1561  else
1562    s_h3->rank = h1->rank;
1563  if(syz_ring!=orig_ring)
1564  {
1565    rChangeCurrRing(orig_ring);
1566    s_h3 = idrMoveR_NoSort(s_h3, syz_ring, orig_ring);
1567    rDelete(syz_ring);
1568  }
1569  idSkipZeroes(s_h3);
1570  idTest(s_h3);
1571  return s_h3;
1572}
1573
1574/*2
1575* eliminate delVar (product of vars) in h1
1576*/
1577ideal idElimination (ideal h1,poly delVar,intvec *hilb)
1578{
1579  int    i,j=0,k,l;
1580  ideal  h,hh, h3;
1581  rRingOrder_t    *ord;
1582  int    *block0,*block1;
1583  int    ordersize=2;
1584  int    **wv;
1585  tHomog hom;
1586  intvec * w;
1587  ring tmpR;
1588  ring origR = currRing;
1589
1590  if (delVar==NULL)
1591  {
1592    return idCopy(h1);
1593  }
1594  if ((currRing->qideal!=NULL) && rIsPluralRing(origR))
1595  {
1596    WerrorS("cannot eliminate in a qring");
1597    return NULL;
1598  }
1599  if (idIs0(h1)) return idInit(1,h1->rank);
1600#ifdef HAVE_PLURAL
1601  if (rIsPluralRing(origR))
1602    /* in the NC case, we have to check the admissibility of */
1603    /* the subalgebra to be intersected with */
1604  {
1605    if ((ncRingType(origR) != nc_skew) && (ncRingType(origR) != nc_exterior)) /* in (quasi)-commutative algebras every subalgebra is admissible */
1606    {
1607      if (nc_CheckSubalgebra(delVar,origR))
1608      {
1609        WerrorS("no elimination is possible: subalgebra is not admissible");
1610        return NULL;
1611      }
1612    }
1613  }
1614#endif
1615  hom=(tHomog)idHomModule(h1,NULL,&w); //sets w to weight vector or NULL
1616  h3=idInit(16,h1->rank);
1617  for (k=0;; k++)
1618  {
1619    if (origR->order[k]!=0) ordersize++;
1620    else break;
1621  }
1622#if 0
1623  if (rIsPluralRing(origR)) // we have too keep the odering: it may be needed
1624                            // for G-algebra
1625  {
1626    for (k=0;k<ordersize-1; k++)
1627    {
1628      block0[k+1] = origR->block0[k];
1629      block1[k+1] = origR->block1[k];
1630      ord[k+1] = origR->order[k];
1631      if (origR->wvhdl[k]!=NULL) wv[k+1] = (int*) omMemDup(origR->wvhdl[k]);
1632    }
1633  }
1634  else
1635  {
1636    block0[1] = 1;
1637    block1[1] = (currRing->N);
1638    if (origR->OrdSgn==1) ord[1] = ringorder_wp;
1639    else                  ord[1] = ringorder_ws;
1640    wv[1]=(int*)omAlloc0((currRing->N)*sizeof(int));
1641    double wNsqr = (double)2.0 / (double)(currRing->N);
1642    wFunctional = wFunctionalBuch;
1643    int  *x= (int * )omAlloc(2 * ((currRing->N) + 1) * sizeof(int));
1644    int sl=IDELEMS(h1) - 1;
1645    wCall(h1->m, sl, x, wNsqr);
1646    for (sl = (currRing->N); sl!=0; sl--)
1647      wv[1][sl-1] = x[sl + (currRing->N) + 1];
1648    omFreeSize((ADDRESS)x, 2 * ((currRing->N) + 1) * sizeof(int));
1649
1650    ord[2]=ringorder_C;
1651    ord[3]=0;
1652  }
1653#else
1654#endif
1655  if ((hom==TRUE) && (origR->OrdSgn==1) && (!rIsPluralRing(origR)))
1656  {
1657    #if 1
1658    // we change to an ordering:
1659    // aa(1,1,1,...,0,0,0),wp(...),C
1660    // this seems to be better than version 2 below,
1661    // according to Tst/../elimiate_[3568].tat (- 17 %)
1662    ord=(rRingOrder_t*)omAlloc0(4*sizeof(rRingOrder_t));
1663    block0=(int*)omAlloc0(4*sizeof(int));
1664    block1=(int*)omAlloc0(4*sizeof(int));
1665    wv=(int**) omAlloc0(4*sizeof(int**));
1666    block0[0] = block0[1] = 1;
1667    block1[0] = block1[1] = rVar(origR);
1668    wv[0]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
1669    // use this special ordering: like ringorder_a, except that pFDeg, pWeights
1670    // ignore it
1671    ord[0] = ringorder_aa;
1672    for (j=0;j<rVar(origR);j++)
1673      if (pGetExp(delVar,j+1)!=0) wv[0][j]=1;
1674    BOOLEAN wp=FALSE;
1675    for (j=0;j<rVar(origR);j++)
1676      if (p_Weight(j+1,origR)!=1) { wp=TRUE;break; }
1677    if (wp)
1678    {
1679      wv[1]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
1680      for (j=0;j<rVar(origR);j++)
1681        wv[1][j]=p_Weight(j+1,origR);
1682      ord[1] = ringorder_wp;
1683    }
1684    else
1685      ord[1] = ringorder_dp;
1686    #else
1687    // we change to an ordering:
1688    // a(w1,...wn),wp(1,...0.....),C
1689    ord=(int*)omAlloc0(4*sizeof(int));
1690    block0=(int*)omAlloc0(4*sizeof(int));
1691    block1=(int*)omAlloc0(4*sizeof(int));
1692    wv=(int**) omAlloc0(4*sizeof(int**));
1693    block0[0] = block0[1] = 1;
1694    block1[0] = block1[1] = rVar(origR);
1695    wv[0]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
1696    wv[1]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
1697    ord[0] = ringorder_a;
1698    for (j=0;j<rVar(origR);j++)
1699      wv[0][j]=pWeight(j+1,origR);
1700    ord[1] = ringorder_wp;
1701    for (j=0;j<rVar(origR);j++)
1702      if (pGetExp(delVar,j+1)!=0) wv[1][j]=1;
1703    #endif
1704    ord[2] = ringorder_C;
1705    ord[3] = (rRingOrder_t)0;
1706  }
1707  else
1708  {
1709    // we change to an ordering:
1710    // aa(....),orig_ordering
1711    ord=(rRingOrder_t*)omAlloc0(ordersize*sizeof(rRingOrder_t));
1712    block0=(int*)omAlloc0(ordersize*sizeof(int));
1713    block1=(int*)omAlloc0(ordersize*sizeof(int));
1714    wv=(int**) omAlloc0(ordersize*sizeof(int**));
1715    for (k=0;k<ordersize-1; k++)
1716    {
1717      block0[k+1] = origR->block0[k];
1718      block1[k+1] = origR->block1[k];
1719      ord[k+1] = origR->order[k];
1720      if (origR->wvhdl[k]!=NULL) wv[k+1] = (int*) omMemDup(origR->wvhdl[k]);
1721    }
1722    block0[0] = 1;
1723    block1[0] = rVar(origR);
1724    wv[0]=(int*)omAlloc0((rVar(origR) + 1)*sizeof(int));
1725    for (j=0;j<rVar(origR);j++)
1726      if (pGetExp(delVar,j+1)!=0) wv[0][j]=1;
1727    // use this special ordering: like ringorder_a, except that pFDeg, pWeights
1728    // ignore it
1729    ord[0] = ringorder_aa;
1730  }
1731  // fill in tmp ring to get back the data later on
1732  tmpR  = rCopy0(origR,FALSE,FALSE); // qring==NULL
1733  //rUnComplete(tmpR);
1734  tmpR->p_Procs=NULL;
1735  tmpR->order = ord;
1736  tmpR->block0 = block0;
1737  tmpR->block1 = block1;
1738  tmpR->wvhdl = wv;
1739  rComplete(tmpR, 1);
1740
1741#ifdef HAVE_PLURAL
1742  /* update nc structure on tmpR */
1743  if (rIsPluralRing(origR))
1744  {
1745    if ( nc_rComplete(origR, tmpR, false) ) // no quotient ideal!
1746    {
1747      WerrorS("no elimination is possible: ordering condition is violated");
1748      // cleanup
1749      rDelete(tmpR);
1750      if (w!=NULL)
1751        delete w;
1752      return NULL;
1753    }
1754  }
1755#endif
1756  // change into the new ring
1757  //pChangeRing((currRing->N),currRing->OrdSgn,ord,block0,block1,wv);
1758  rChangeCurrRing(tmpR);
1759
1760  //h = idInit(IDELEMS(h1),h1->rank);
1761  // fetch data from the old ring
1762  //for (k=0;k<IDELEMS(h1);k++) h->m[k] = prCopyR( h1->m[k], origR);
1763  h=idrCopyR(h1,origR,currRing);
1764  if (origR->qideal!=NULL)
1765  {
1766    WarnS("eliminate in q-ring: experimental");
1767    ideal q=idrCopyR(origR->qideal,origR,currRing);
1768    ideal s=idSimpleAdd(h,q);
1769    idDelete(&h);
1770    idDelete(&q);
1771    h=s;
1772  }
1773  // compute kStd
1774#if 1
1775  //rWrite(tmpR);PrintLn();
1776  //BITSET save1;
1777  //SI_SAVE_OPT1(save1);
1778  //si_opt_1 |=1;
1779  //Print("h: %d gen, rk=%d\n",IDELEMS(h),h->rank);
1780  //extern char * showOption();
1781  //Print("%s\n",showOption());
1782  hh = kStd(h,NULL,hom,&w,hilb);
1783  //SI_RESTORE_OPT1(save1);
1784  idDelete(&h);
1785#else
1786  extern ideal kGroebner(ideal F, ideal Q);
1787  hh=kGroebner(h,NULL);
1788#endif
1789  // go back to the original ring
1790  rChangeCurrRing(origR);
1791  i = IDELEMS(hh)-1;
1792  while ((i >= 0) && (hh->m[i] == NULL)) i--;
1793  j = -1;
1794  // fetch data from temp ring
1795  for (k=0; k<=i; k++)
1796  {
1797    l=(currRing->N);
1798    while ((l>0) && (p_GetExp( hh->m[k],l,tmpR)*pGetExp(delVar,l)==0)) l--;
1799    if (l==0)
1800    {
1801      j++;
1802      if (j >= IDELEMS(h3))
1803      {
1804        pEnlargeSet(&(h3->m),IDELEMS(h3),16);
1805        IDELEMS(h3) += 16;
1806      }
1807      h3->m[j] = prMoveR( hh->m[k], tmpR,origR);
1808      hh->m[k] = NULL;
1809    }
1810  }
1811  id_Delete(&hh, tmpR);
1812  idSkipZeroes(h3);
1813  rDelete(tmpR);
1814  if (w!=NULL)
1815    delete w;
1816  return h3;
1817}
1818
1819#ifdef WITH_OLD_MINOR
1820/*2
1821* compute the which-th ar-minor of the matrix a
1822*/
1823poly idMinor(matrix a, int ar, unsigned long which, ideal R)
1824{
1825  int     i,j/*,k,size*/;
1826  unsigned long curr;
1827  int *rowchoise,*colchoise;
1828  BOOLEAN rowch,colch;
1829  // ideal result;
1830  matrix tmp;
1831  poly p,q;
1832
1833  i = binom(a->rows(),ar);
1834  j = binom(a->cols(),ar);
1835
1836  rowchoise=(int *)omAlloc(ar*sizeof(int));
1837  colchoise=(int *)omAlloc(ar*sizeof(int));
1838  // if ((i>512) || (j>512) || (i*j >512)) size=512;
1839  // else size=i*j;
1840  // result=idInit(size,1);
1841  tmp=mpNew(ar,ar);
1842  // k = 0; /* the index in result*/
1843  curr = 0; /* index of current minor */
1844  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
1845  while (!rowch)
1846  {
1847    idInitChoise(ar,1,a->cols(),&colch,colchoise);
1848    while (!colch)
1849    {
1850      if (curr == which)
1851      {
1852        for (i=1; i<=ar; i++)
1853        {
1854          for (j=1; j<=ar; j++)
1855          {
1856            MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
1857          }
1858        }
1859        p = mp_DetBareiss(tmp,currRing);
1860        if (p!=NULL)
1861        {
1862          if (R!=NULL)
1863          {
1864            q = p;
1865            p = kNF(R,currRing->qideal,q);
1866            p_Delete(&q,currRing);
1867          }
1868          /*delete the matrix tmp*/
1869          for (i=1; i<=ar; i++)
1870          {
1871            for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
1872          }
1873          idDelete((ideal*)&tmp);
1874          omFreeSize((ADDRESS)rowchoise,ar*sizeof(int));
1875          omFreeSize((ADDRESS)colchoise,ar*sizeof(int));
1876          return (p);
1877        }
1878      }
1879      curr++;
1880      idGetNextChoise(ar,a->cols(),&colch,colchoise);
1881    }
1882    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
1883  }
1884  return (poly) 1;
1885}
1886
1887/*2
1888* compute all ar-minors of the matrix a
1889*/
1890ideal idMinors(matrix a, int ar, ideal R)
1891{
1892  int     i,j,/*k,*/size;
1893  int *rowchoise,*colchoise;
1894  BOOLEAN rowch,colch;
1895  ideal result;
1896  matrix tmp;
1897  poly p,q;
1898
1899  i = binom(a->rows(),ar);
1900  j = binom(a->cols(),ar);
1901
1902  rowchoise=(int *)omAlloc(ar*sizeof(int));
1903  colchoise=(int *)omAlloc(ar*sizeof(int));
1904  if ((i>512) || (j>512) || (i*j >512)) size=512;
1905  else size=i*j;
1906  result=idInit(size,1);
1907  tmp=mpNew(ar,ar);
1908  // k = 0; /* the index in result*/
1909  idInitChoise(ar,1,a->rows(),&rowch,rowchoise);
1910  while (!rowch)
1911  {
1912    idInitChoise(ar,1,a->cols(),&colch,colchoise);
1913    while (!colch)
1914    {
1915      for (i=1; i<=ar; i++)
1916      {
1917        for (j=1; j<=ar; j++)
1918        {
1919          MATELEM(tmp,i,j) = MATELEM(a,rowchoise[i-1],colchoise[j-1]);
1920        }
1921      }
1922      p = mp_DetBareiss(tmp,currRing);
1923      if (p!=NULL)
1924      {
1925        if (R!=NULL)
1926        {
1927          q = p;
1928          p = kNF(R,currRing->qideal,q);
1929          p_Delete(&q,currRing);
1930        }
1931        if (p!=NULL)
1932        {
1933          if (k>=size)
1934          {
1935            pEnlargeSet(&result->m,size,32);
1936            size += 32;
1937          }
1938          result->m[k] = p;
1939          k++;
1940        }
1941      }
1942      idGetNextChoise(ar,a->cols(),&colch,colchoise);
1943    }
1944    idGetNextChoise(ar,a->rows(),&rowch,rowchoise);
1945  }
1946  /*delete the matrix tmp*/
1947  for (i=1; i<=ar; i++)
1948  {
1949    for (j=1; j<=ar; j++) MATELEM(tmp,i,j) = NULL;
1950  }
1951  idDelete((ideal*)&tmp);
1952  if (k==0)
1953  {
1954    k=1;
1955    result->m[0]=NULL;
1956  }
1957  omFreeSize((ADDRESS)rowchoise,ar*sizeof(int));
1958  omFreeSize((ADDRESS)colchoise,ar*sizeof(int));
1959  pEnlargeSet(&result->m,size,k-size);
1960  IDELEMS(result) = k;
1961  return (result);
1962}
1963#else
1964
1965
1966/// compute all ar-minors of the matrix a
1967/// the caller of mpRecMin
1968/// the elements of the result are not in R (if R!=NULL)
1969ideal idMinors(matrix a, int ar, ideal R)
1970{
1971
1972  const ring origR=currRing;
1973  id_Test((ideal)a, origR);
1974
1975  const int r = a->nrows;
1976  const int c = a->ncols;
1977
1978  if((ar<=0) || (ar>r) || (ar>c))
1979  {
1980    Werror("%d-th minor, matrix is %dx%d",ar,r,c);
1981    return NULL;
1982  }
1983
1984  ideal h = id_Matrix2Module(mp_Copy(a,origR),origR);
1985  long bound = sm_ExpBound(h,c,r,ar,origR);
1986  id_Delete(&h, origR);
1987
1988  ring tmpR = sm_RingChange(origR,bound);
1989
1990  matrix b = mpNew(r,c);
1991
1992  for (int i=r*c-1;i>=0;i--)
1993    if (a->m[i] != NULL)
1994      b->m[i] = prCopyR(a->m[i],origR,tmpR);
1995
1996  id_Test( (ideal)b, tmpR);
1997
1998  if (R!=NULL)
1999  {
2000    R = idrCopyR(R,origR,tmpR); // TODO: overwrites R? memory leak?
2001    //if (ar>1) // otherwise done in mpMinorToResult
2002    //{
2003    //  matrix bb=(matrix)kNF(R,currRing->qideal,(ideal)b);
2004    //  bb->rank=b->rank; bb->nrows=b->nrows; bb->ncols=b->ncols;
2005    //  idDelete((ideal*)&b); b=bb;
2006    //}
2007    id_Test( R, tmpR);
2008  }
2009
2010
2011  ideal result = idInit(32,1);
2012
2013  int elems = 0;
2014
2015  if(ar>1)
2016    mp_RecMin(ar-1,result,elems,b,r,c,NULL,R,tmpR);
2017  else
2018    mp_MinorToResult(result,elems,b,r,c,R,tmpR);
2019
2020  id_Test( (ideal)b, tmpR);
2021
2022  id_Delete((ideal *)&b, tmpR);
2023
2024  if (R!=NULL) id_Delete(&R,tmpR);
2025
2026  idSkipZeroes(result);
2027  rChangeCurrRing(origR);
2028  result = idrMoveR(result,tmpR,origR);
2029  sm_KillModifiedRing(tmpR);
2030  idTest(result);
2031  return result;
2032}
2033#endif
2034
2035/*2
2036*returns TRUE if id1 is a submodule of id2
2037*/
2038BOOLEAN idIsSubModule(ideal id1,ideal id2)
2039{
2040  int i;
2041  poly p;
2042
2043  if (idIs0(id1)) return TRUE;
2044  for (i=0;i<IDELEMS(id1);i++)
2045  {
2046    if (id1->m[i] != NULL)
2047    {
2048      p = kNF(id2,currRing->qideal,id1->m[i]);
2049      if (p != NULL)
2050      {
2051        p_Delete(&p,currRing);
2052        return FALSE;
2053      }
2054    }
2055  }
2056  return TRUE;
2057}
2058
2059BOOLEAN idTestHomModule(ideal m, ideal Q, intvec *w)
2060{
2061  if ((Q!=NULL) && (!idHomIdeal(Q,NULL)))  { PrintS(" Q not hom\n"); return FALSE;}
2062  if (idIs0(m)) return TRUE;
2063
2064  int cmax=-1;
2065  int i;
2066  poly p=NULL;
2067  int length=IDELEMS(m);
2068  polyset P=m->m;
2069  for (i=length-1;i>=0;i--)
2070  {
2071    p=P[i];
2072    if (p!=NULL) cmax=si_max(cmax,(int)pMaxComp(p)+1);
2073  }
2074  if (w != NULL)
2075  if (w->length()+1 < cmax)
2076  {
2077    // Print("length: %d - %d \n", w->length(),cmax);
2078    return FALSE;
2079  }
2080
2081  if(w!=NULL)
2082    p_SetModDeg(w, currRing);
2083
2084  for (i=length-1;i>=0;i--)
2085  {
2086    p=P[i];
2087    if (p!=NULL)
2088    {
2089      int d=currRing->pFDeg(p,currRing);
2090      loop
2091      {
2092        pIter(p);
2093        if (p==NULL) break;
2094        if (d!=currRing->pFDeg(p,currRing))
2095        {
2096          //pWrite(q); wrp(p); Print(" -> %d - %d\n",d,pFDeg(p,currRing));
2097          if(w!=NULL)
2098            p_SetModDeg(NULL, currRing);
2099          return FALSE;
2100        }
2101      }
2102    }
2103  }
2104
2105  if(w!=NULL)
2106    p_SetModDeg(NULL, currRing);
2107
2108  return TRUE;
2109}
2110
2111ideal idSeries(int n,ideal M,matrix U,intvec *w)
2112{
2113  for(int i=IDELEMS(M)-1;i>=0;i--)
2114  {
2115    if(U==NULL)
2116      M->m[i]=pSeries(n,M->m[i],NULL,w);
2117    else
2118    {
2119      M->m[i]=pSeries(n,M->m[i],MATELEM(U,i+1,i+1),w);
2120      MATELEM(U,i+1,i+1)=NULL;
2121    }
2122  }
2123  if(U!=NULL)
2124    idDelete((ideal*)&U);
2125  return M;
2126}
2127
2128matrix idDiff(matrix i, int k)
2129{
2130  int e=MATCOLS(i)*MATROWS(i);
2131  matrix r=mpNew(MATROWS(i),MATCOLS(i));
2132  r->rank=i->rank;
2133  int j;
2134  for(j=0; j<e; j++)
2135  {
2136    r->m[j]=pDiff(i->m[j],k);
2137  }
2138  return r;
2139}
2140
2141matrix idDiffOp(ideal I, ideal J,BOOLEAN multiply)
2142{
2143  matrix r=mpNew(IDELEMS(I),IDELEMS(J));
2144  int i,j;
2145  for(i=0; i<IDELEMS(I); i++)
2146  {
2147    for(j=0; j<IDELEMS(J); j++)
2148    {
2149      MATELEM(r,i+1,j+1)=pDiffOp(I->m[i],J->m[j],multiply);
2150    }
2151  }
2152  return r;
2153}
2154
2155/*3
2156*handles for some ideal operations the ring/syzcomp managment
2157*returns all syzygies (componentwise-)shifted by -syzcomp
2158*or -syzcomp-1 (in case of ideals as input)
2159static ideal idHandleIdealOp(ideal arg,int syzcomp,int isIdeal=FALSE)
2160{
2161  ring orig_ring=currRing;
2162  ring syz_ring=rAssure_SyzOrder(orig_ring, TRUE); rChangeCurrRing(syz_ring);
2163  rSetSyzComp(length, syz_ring);
2164
2165  ideal s_temp;
2166  if (orig_ring!=syz_ring)
2167    s_temp=idrMoveR_NoSort(arg,orig_ring, syz_ring);
2168  else
2169    s_temp=arg;
2170
2171  ideal s_temp1 = kStd(s_temp,currRing->qideal,testHomog,&w,NULL,length);
2172  if (w!=NULL) delete w;
2173
2174  if (syz_ring!=orig_ring)
2175  {
2176    idDelete(&s_temp);
2177    rChangeCurrRing(orig_ring);
2178  }
2179
2180  idDelete(&temp);
2181  ideal temp1=idRingCopy(s_temp1,syz_ring);
2182
2183  if (syz_ring!=orig_ring)
2184  {
2185    rChangeCurrRing(syz_ring);
2186    idDelete(&s_temp1);
2187    rChangeCurrRing(orig_ring);
2188    rDelete(syz_ring);
2189  }
2190
2191  for (i=0;i<IDELEMS(temp1);i++)
2192  {
2193    if ((temp1->m[i]!=NULL)
2194    && (pGetComp(temp1->m[i])<=length))
2195    {
2196      pDelete(&(temp1->m[i]));
2197    }
2198    else
2199    {
2200      p_Shift(&(temp1->m[i]),-length,currRing);
2201    }
2202  }
2203  temp1->rank = rk;
2204  idSkipZeroes(temp1);
2205
2206  return temp1;
2207}
2208*/
2209/*2
2210* represents (h1+h2)/h2=h1/(h1 intersect h2)
2211*/
2212//ideal idModulo (ideal h2,ideal h1)
2213ideal idModulo (ideal h2,ideal h1, tHomog hom, intvec ** w)
2214{
2215  intvec *wtmp=NULL;
2216
2217  int i,k,rk,flength=0,slength,length;
2218  poly p,q;
2219
2220  if (idIs0(h2))
2221    return idFreeModule(si_max(1,h2->ncols));
2222  if (!idIs0(h1))
2223    flength = id_RankFreeModule(h1,currRing);
2224  slength = id_RankFreeModule(h2,currRing);
2225  length  = si_max(flength,slength);
2226  if (length==0)
2227  {
2228    length = 1;
2229  }
2230  ideal temp = idInit(IDELEMS(h2),length+IDELEMS(h2));
2231  if ((w!=NULL)&&((*w)!=NULL))
2232  {
2233    //Print("input weights:");(*w)->show(1);PrintLn();
2234    int d;
2235    int k;
2236    wtmp=new intvec(length+IDELEMS(h2));
2237    for (i=0;i<length;i++)
2238      ((*wtmp)[i])=(**w)[i];
2239    for (i=0;i<IDELEMS(h2);i++)
2240    {
2241      poly p=h2->m[i];
2242      if (p!=NULL)
2243      {
2244        d = p_Deg(p,currRing);
2245        k= pGetComp(p);
2246        if (slength>0) k--;
2247        d +=((**w)[k]);
2248        ((*wtmp)[i+length]) = d;
2249      }
2250    }
2251    //Print("weights:");wtmp->show(1);PrintLn();
2252  }
2253  for (i=0;i<IDELEMS(h2);i++)
2254  {
2255    temp->m[i] = pCopy(h2->m[i]);
2256    q = pOne();
2257    pSetComp(q,i+1+length);
2258    pSetmComp(q);
2259    if(temp->m[i]!=NULL)
2260    {
2261      if (slength==0) p_Shift(&(temp->m[i]),1,currRing);
2262      p = temp->m[i];
2263      while (pNext(p)!=NULL) pIter(p);
2264      pNext(p) = q; // will be sorted later correctly
2265    }
2266    else
2267      temp->m[i]=q;
2268  }
2269  rk = k = IDELEMS(h2);
2270  if (!idIs0(h1))
2271  {
2272    pEnlargeSet(&(temp->m),IDELEMS(temp),IDELEMS(h1));
2273    IDELEMS(temp) += IDELEMS(h1);
2274    for (i=0;i<IDELEMS(h1);i++)
2275    {
2276      if (h1->m[i]!=NULL)
2277      {
2278        temp->m[k] = pCopy(h1->m[i]);
2279        if (flength==0) p_Shift(&(temp->m[k]),1,currRing);
2280        k++;
2281      }
2282    }
2283  }
2284
2285  ring orig_ring=currRing;
2286  ring syz_ring=rAssure_SyzOrder(orig_ring, TRUE);
2287  rSetSyzComp(length,syz_ring);
2288  rChangeCurrRing(syz_ring);
2289  // we can use OPT_RETURN_SB only, if syz_ring==orig_ring,
2290  // therefore we disable OPT_RETURN_SB for modulo:
2291  // (see tr. #701)
2292  //if (TEST_OPT_RETURN_SB)
2293  //  rSetSyzComp(IDELEMS(h2)+length, syz_ring);
2294  //else
2295  //  rSetSyzComp(length, syz_ring);
2296  ideal s_temp;
2297
2298  if (syz_ring != orig_ring)
2299  {
2300    s_temp = idrMoveR_NoSort(temp, orig_ring, syz_ring);
2301  }
2302  else
2303  {
2304    s_temp = temp;
2305  }
2306
2307  idTest(s_temp);
2308  ideal s_temp1 = kStd(s_temp,currRing->qideal,hom,&wtmp,NULL,length);
2309
2310  //if (wtmp!=NULL)  Print("output weights:");wtmp->show(1);PrintLn();
2311  if ((w!=NULL) && (*w !=NULL) && (wtmp!=NULL))
2312  {
2313    delete *w;
2314    *w=new intvec(IDELEMS(h2));
2315    for (i=0;i<IDELEMS(h2);i++)
2316      ((**w)[i])=(*wtmp)[i+length];
2317  }
2318  if (wtmp!=NULL) delete wtmp;
2319
2320  for (i=0;i<IDELEMS(s_temp1);i++)
2321  {
2322    if ((s_temp1->m[i]!=NULL)
2323    && (((int)pGetComp(s_temp1->m[i]))<=length))
2324    {
2325      p_Delete(&(s_temp1->m[i]),currRing);
2326    }
2327    else
2328    {
2329      p_Shift(&(s_temp1->m[i]),-length,currRing);
2330    }
2331  }
2332  s_temp1->rank = rk;
2333  idSkipZeroes(s_temp1);
2334
2335  if (syz_ring!=orig_ring)
2336  {
2337    rChangeCurrRing(orig_ring);
2338    s_temp1 = idrMoveR_NoSort(s_temp1, syz_ring, orig_ring);
2339    rDelete(syz_ring);
2340    // Hmm ... here seems to be a memory leak
2341    // However, simply deleting it causes memory trouble
2342    // idDelete(&s_temp);
2343  }
2344  else
2345  {
2346    idDelete(&temp);
2347  }
2348  idTest(s_temp1);
2349  return s_temp1;
2350}
2351
2352/*
2353*computes module-weights for liftings of homogeneous modules
2354*/
2355intvec * idMWLift(ideal mod,intvec * weights)
2356{
2357  if (idIs0(mod)) return new intvec(2);
2358  int i=IDELEMS(mod);
2359  while ((i>0) && (mod->m[i-1]==NULL)) i--;
2360  intvec *result = new intvec(i+1);
2361  while (i>0)
2362  {
2363    (*result)[i]=currRing->pFDeg(mod->m[i],currRing)+(*weights)[pGetComp(mod->m[i])];
2364  }
2365  return result;
2366}
2367
2368/*2
2369*sorts the kbase for idCoef* in a special way (lexicographically
2370*with x_max,...,x_1)
2371*/
2372ideal idCreateSpecialKbase(ideal kBase,intvec ** convert)
2373{
2374  int i;
2375  ideal result;
2376
2377  if (idIs0(kBase)) return NULL;
2378  result = idInit(IDELEMS(kBase),kBase->rank);
2379  *convert = idSort(kBase,FALSE);
2380  for (i=0;i<(*convert)->length();i++)
2381  {
2382    result->m[i] = pCopy(kBase->m[(**convert)[i]-1]);
2383  }
2384  return result;
2385}
2386
2387/*2
2388*returns the index of a given monom in the list of the special kbase
2389*/
2390int idIndexOfKBase(poly monom, ideal kbase)
2391{
2392  int j=IDELEMS(kbase);
2393
2394  while ((j>0) && (kbase->m[j-1]==NULL)) j--;
2395  if (j==0) return -1;
2396  int i=(currRing->N);
2397  while (i>0)
2398  {
2399    loop
2400    {
2401      if (pGetExp(monom,i)>pGetExp(kbase->m[j-1],i)) return -1;
2402      if (pGetExp(monom,i)==pGetExp(kbase->m[j-1],i)) break;
2403      j--;
2404      if (j==0) return -1;
2405    }
2406    if (i==1)
2407    {
2408      while(j>0)
2409      {
2410        if (pGetComp(monom)==pGetComp(kbase->m[j-1])) return j-1;
2411        if (pGetComp(monom)>pGetComp(kbase->m[j-1])) return -1;
2412        j--;
2413      }
2414    }
2415    i--;
2416  }
2417  return -1;
2418}
2419
2420/*2
2421*decomposes the monom in a part of coefficients described by the
2422*complement of how and a monom in variables occuring in how, the
2423*index of which in kbase is returned as integer pos (-1 if it don't
2424*exists)
2425*/
2426poly idDecompose(poly monom, poly how, ideal kbase, int * pos)
2427{
2428  int i;
2429  poly coeff=pOne(), base=pOne();
2430
2431  for (i=1;i<=(currRing->N);i++)
2432  {
2433    if (pGetExp(how,i)>0)
2434    {
2435      pSetExp(base,i,pGetExp(monom,i));
2436    }
2437    else
2438    {
2439      pSetExp(coeff,i,pGetExp(monom,i));
2440    }
2441  }
2442  pSetComp(base,pGetComp(monom));
2443  pSetm(base);
2444  pSetCoeff(coeff,nCopy(pGetCoeff(monom)));
2445  pSetm(coeff);
2446  *pos = idIndexOfKBase(base,kbase);
2447  if (*pos<0)
2448    p_Delete(&coeff,currRing);
2449  p_Delete(&base,currRing);
2450  return coeff;
2451}
2452
2453/*2
2454*returns a matrix A of coefficients with kbase*A=arg
2455*if all monomials in variables of how occur in kbase
2456*the other are deleted
2457*/
2458matrix idCoeffOfKBase(ideal arg, ideal kbase, poly how)
2459{
2460  matrix result;
2461  ideal tempKbase;
2462  poly p,q;
2463  intvec * convert;
2464  int i=IDELEMS(kbase),j=IDELEMS(arg),k,pos;
2465#if 0
2466  while ((i>0) && (kbase->m[i-1]==NULL)) i--;
2467  if (idIs0(arg))
2468    return mpNew(i,1);
2469  while ((j>0) && (arg->m[j-1]==NULL)) j--;
2470  result = mpNew(i,j);
2471#else
2472  result = mpNew(i, j);
2473  while ((j>0) && (arg->m[j-1]==NULL)) j--;
2474#endif
2475
2476  tempKbase = idCreateSpecialKbase(kbase,&convert);
2477  for (k=0;k<j;k++)
2478  {
2479    p = arg->m[k];
2480    while (p!=NULL)
2481    {
2482      q = idDecompose(p,how,tempKbase,&pos);
2483      if (pos>=0)
2484      {
2485        MATELEM(result,(*convert)[pos],k+1) =
2486            pAdd(MATELEM(result,(*convert)[pos],k+1),q);
2487      }
2488      else
2489        p_Delete(&q,currRing);
2490      pIter(p);
2491    }
2492  }
2493  idDelete(&tempKbase);
2494  return result;
2495}
2496
2497static void idDeleteComps(ideal arg,int* red_comp,int del)
2498// red_comp is an array [0..args->rank]
2499{
2500  int i,j;
2501  poly p;
2502
2503  for (i=IDELEMS(arg)-1;i>=0;i--)
2504  {
2505    p = arg->m[i];
2506    while (p!=NULL)
2507    {
2508      j = pGetComp(p);
2509      if (red_comp[j]!=j)
2510      {
2511        pSetComp(p,red_comp[j]);
2512        pSetmComp(p);
2513      }
2514      pIter(p);
2515    }
2516  }
2517  (arg->rank) -= del;
2518}
2519
2520/*2
2521* returns the presentation of an isomorphic, minimally
2522* embedded  module (arg represents the quotient!)
2523*/
2524ideal idMinEmbedding(ideal arg,BOOLEAN inPlace, intvec **w)
2525{
2526  if (idIs0(arg)) return idInit(1,arg->rank);
2527  int i,next_gen,next_comp;
2528  ideal res=arg;
2529  if (!inPlace) res = idCopy(arg);
2530  res->rank=si_max(res->rank,id_RankFreeModule(res,currRing));
2531  int *red_comp=(int*)omAlloc((res->rank+1)*sizeof(int));
2532  for (i=res->rank;i>=0;i--) red_comp[i]=i;
2533
2534  int del=0;
2535  loop
2536  {
2537    next_gen = id_ReadOutPivot(res, &next_comp, currRing);
2538    if (next_gen<0) break;
2539    del++;
2540    syGaussForOne(res,next_gen,next_comp,0,IDELEMS(res));
2541    for(i=next_comp+1;i<=arg->rank;i++) red_comp[i]--;
2542    if ((w !=NULL)&&(*w!=NULL))
2543    {
2544      for(i=next_comp;i<(*w)->length();i++) (**w)[i-1]=(**w)[i];
2545    }
2546  }
2547
2548  idDeleteComps(res,red_comp,del);
2549  idSkipZeroes(res);
2550  omFree(red_comp);
2551
2552  if ((w !=NULL)&&(*w!=NULL) &&(del>0))
2553  {
2554    int nl=si_max((*w)->length()-del,1);
2555    intvec *wtmp=new intvec(nl);
2556    for(i=0;i<res->rank;i++) (*wtmp)[i]=(**w)[i];
2557    delete *w;
2558    *w=wtmp;
2559  }
2560  return res;
2561}
2562
2563#include "polys/clapsing.h"
2564
2565#if 0
2566poly id_GCD(poly f, poly g, const ring r)
2567{
2568  ring save_r=currRing;
2569  rChangeCurrRing(r);
2570  ideal I=idInit(2,1); I->m[0]=f; I->m[1]=g;
2571  intvec *w = NULL;
2572  ideal S=idSyzygies(I,testHomog,&w);
2573  if (w!=NULL) delete w;
2574  poly gg=pTakeOutComp(&(S->m[0]),2);
2575  idDelete(&S);
2576  poly gcd_p=singclap_pdivide(f,gg,r);
2577  p_Delete(&gg,r);
2578  rChangeCurrRing(save_r);
2579  return gcd_p;
2580}
2581#else
2582poly id_GCD(poly f, poly g, const ring r)
2583{
2584  ideal I=idInit(2,1); I->m[0]=f; I->m[1]=g;
2585  intvec *w = NULL;
2586
2587  ring save_r = currRing;
2588  rChangeCurrRing(r);
2589  ideal S=idSyzygies(I,testHomog,&w);
2590  rChangeCurrRing(save_r);
2591
2592  if (w!=NULL) delete w;
2593  poly gg=p_TakeOutComp(&(S->m[0]), 2, r);
2594  id_Delete(&S, r);
2595  poly gcd_p=singclap_pdivide(f,gg, r);
2596  p_Delete(&gg, r);
2597
2598  return gcd_p;
2599}
2600#endif
2601
2602#if 0
2603/*2
2604* xx,q: arrays of length 0..rl-1
2605* xx[i]: SB mod q[i]
2606* assume: char=0
2607* assume: q[i]!=0
2608* destroys xx
2609*/
2610ideal id_ChineseRemainder(ideal *xx, number *q, int rl, const ring R)
2611{
2612  int cnt=IDELEMS(xx[0])*xx[0]->nrows;
2613  ideal result=idInit(cnt,xx[0]->rank);
2614  result->nrows=xx[0]->nrows; // for lifting matrices
2615  result->ncols=xx[0]->ncols; // for lifting matrices
2616  int i,j;
2617  poly r,h,hh,res_p;
2618  number *x=(number *)omAlloc(rl*sizeof(number));
2619  for(i=cnt-1;i>=0;i--)
2620  {
2621    res_p=NULL;
2622    loop
2623    {
2624      r=NULL;
2625      for(j=rl-1;j>=0;j--)
2626      {
2627        h=xx[j]->m[i];
2628        if ((h!=NULL)
2629        &&((r==NULL)||(p_LmCmp(r,h,R)==-1)))
2630          r=h;
2631      }
2632      if (r==NULL) break;
2633      h=p_Head(r, R);
2634      for(j=rl-1;j>=0;j--)
2635      {
2636        hh=xx[j]->m[i];
2637        if ((hh!=NULL) && (p_LmCmp(r,hh, R)==0))
2638        {
2639          x[j]=p_GetCoeff(hh, R);
2640          hh=p_LmFreeAndNext(hh, R);
2641          xx[j]->m[i]=hh;
2642        }
2643        else
2644          x[j]=n_Init(0, R->cf); // is R->cf really n_Q???, yes!
2645      }
2646
2647      number n=n_ChineseRemainder(x,q,rl, R->cf);
2648
2649      for(j=rl-1;j>=0;j--)
2650      {
2651        x[j]=NULL; // nlInit(0...) takes no memory
2652      }
2653      if (n_IsZero(n, R->cf)) p_Delete(&h, R);
2654      else
2655      {
2656        p_SetCoeff(h,n, R);
2657        //Print("new mon:");pWrite(h);
2658        res_p=p_Add_q(res_p, h, R);
2659      }
2660    }
2661    result->m[i]=res_p;
2662  }
2663  omFree(x);
2664  for(i=rl-1;i>=0;i--) id_Delete(&(xx[i]), R);
2665  omFree(xx);
2666  return result;
2667}
2668#endif
2669/* currently unsed:
2670ideal idChineseRemainder(ideal *xx, intvec *iv)
2671{
2672  int rl=iv->length();
2673  number *q=(number *)omAlloc(rl*sizeof(number));
2674  int i;
2675  for(i=0; i<rl; i++)
2676  {
2677    q[i]=nInit((*iv)[i]);
2678  }
2679  return idChineseRemainder(xx,q,rl);
2680}
2681*/
2682/*
2683 * lift ideal with coeffs over Z (mod N) to Q via Farey
2684 */
2685ideal id_Farey(ideal x, number N, const ring r)
2686{
2687  int cnt=IDELEMS(x)*x->nrows;
2688  ideal result=idInit(cnt,x->rank);
2689  result->nrows=x->nrows; // for lifting matrices
2690  result->ncols=x->ncols; // for lifting matrices
2691
2692  int i;
2693  for(i=cnt-1;i>=0;i--)
2694  {
2695    result->m[i]=p_Farey(x->m[i],N,r);
2696  }
2697  return result;
2698}
2699
2700
2701
2702
2703// uses glabl vars via pSetModDeg
2704/*
2705BOOLEAN idTestHomModule(ideal m, ideal Q, intvec *w)
2706{
2707  if ((Q!=NULL) && (!idHomIdeal(Q,NULL)))  { PrintS(" Q not hom\n"); return FALSE;}
2708  if (idIs0(m)) return TRUE;
2709
2710  int cmax=-1;
2711  int i;
2712  poly p=NULL;
2713  int length=IDELEMS(m);
2714  poly* P=m->m;
2715  for (i=length-1;i>=0;i--)
2716  {
2717    p=P[i];
2718    if (p!=NULL) cmax=si_max(cmax,(int)pMaxComp(p)+1);
2719  }
2720  if (w != NULL)
2721  if (w->length()+1 < cmax)
2722  {
2723    // Print("length: %d - %d \n", w->length(),cmax);
2724    return FALSE;
2725  }
2726
2727  if(w!=NULL)
2728    p_SetModDeg(w, currRing);
2729
2730  for (i=length-1;i>=0;i--)
2731  {
2732    p=P[i];
2733    poly q=p;
2734    if (p!=NULL)
2735    {
2736      int d=p_FDeg(p,currRing);
2737      loop
2738      {
2739        pIter(p);
2740        if (p==NULL) break;
2741        if (d!=p_FDeg(p,currRing))
2742        {
2743          //pWrite(q); wrp(p); Print(" -> %d - %d\n",d,pFDeg(p,currRing));
2744          if(w!=NULL)
2745            p_SetModDeg(NULL, currRing);
2746          return FALSE;
2747        }
2748      }
2749    }
2750  }
2751
2752  if(w!=NULL)
2753    p_SetModDeg(NULL, currRing);
2754
2755  return TRUE;
2756}
2757*/
2758
2759/// keeps the first k (>= 1) entries of the given ideal
2760/// (Note that the kept polynomials may be zero.)
2761void idKeepFirstK(ideal id, const int k)
2762{
2763   for (int i = IDELEMS(id)-1; i >= k; i--)
2764   {
2765      if (id->m[i] != NULL) pDelete(&id->m[i]);
2766   }
2767   int kk=k;
2768   if (k==0) kk=1; /* ideals must have at least one element(0)*/
2769   pEnlargeSet(&(id->m), IDELEMS(id), kk-IDELEMS(id));
2770   IDELEMS(id) = kk;
2771}
2772
2773typedef struct
2774{
2775  poly p;
2776  int index;
2777} poly_sort;
2778
2779int pCompare_qsort(const void *a, const void *b)
2780{
2781  return (p_Compare(((poly_sort *)a)->p, ((poly_sort *)b)->p,currRing));
2782}
2783
2784void idSort_qsort(poly_sort *id_sort, int idsize)
2785{
2786  qsort(id_sort, idsize, sizeof(poly_sort), pCompare_qsort);
2787}
2788
2789/*2
2790* ideal id = (id[i])
2791* if id[i] = id[j] then id[j] is deleted for j > i
2792*/
2793void idDelEquals(ideal id)
2794{
2795  int idsize = IDELEMS(id);
2796  poly_sort *id_sort = (poly_sort *)omAlloc0(idsize*sizeof(poly_sort));
2797  for (int i = 0; i < idsize; i++)
2798  {
2799    id_sort[i].p = id->m[i];
2800    id_sort[i].index = i;
2801  }
2802  idSort_qsort(id_sort, idsize);
2803  int index, index_i, index_j;
2804  int i = 0;
2805  for (int j = 1; j < idsize; j++)
2806  {
2807    if (id_sort[i].p != NULL && pEqualPolys(id_sort[i].p, id_sort[j].p))
2808    {
2809      index_i = id_sort[i].index;
2810      index_j = id_sort[j].index;
2811      if (index_j > index_i)
2812      {
2813        index = index_j;
2814      }
2815      else
2816      {
2817        index = index_i;
2818        i = j;
2819      }
2820      pDelete(&id->m[index]);
2821    }
2822    else
2823    {
2824      i = j;
2825    }
2826  }
2827  omFreeSize((ADDRESS)(id_sort), idsize*sizeof(poly_sort));
2828}
2829
2830static int * id_satstdSaturatingVariables=NULL;
2831
2832static BOOLEAN id_sat_vars_sp(kStrategy strat)
2833{
2834  BOOLEAN b = FALSE; // set b to TRUE, if spoly was changed,
2835                     // let it remain FALSE otherwise
2836  if (strat->P.t_p==NULL)
2837  {
2838    poly p=strat->P.p;
2839
2840    // iterate over all terms of p and
2841    // compute the minimum mm of all exponent vectors
2842    int *mm=(int*)omAlloc((1+rVar(currRing))*sizeof(int));
2843    int *m0=(int*)omAlloc0((1+rVar(currRing))*sizeof(int));
2844    p_GetExpV(p,mm,currRing);
2845    bool nonTrivialSaturationToBeDone=true;
2846    for (p=pNext(p); p!=NULL; pIter(p))
2847    {
2848      nonTrivialSaturationToBeDone=false;
2849      p_GetExpV(p,m0,currRing);
2850      for (int i=rVar(currRing); i>0; i--)
2851      {
2852        if (id_satstdSaturatingVariables[i]!=0)
2853        {
2854          mm[i]=si_min(mm[i],m0[i]);
2855          if (mm[i]>0) nonTrivialSaturationToBeDone=true;
2856        }
2857        else mm[i]=0;
2858      }
2859      // abort if the minimum is zero in each component
2860      if (!nonTrivialSaturationToBeDone) break;
2861    }
2862    if (nonTrivialSaturationToBeDone)
2863    {
2864      // std::cout << "simplifying!" << std::endl;
2865      if (TEST_OPT_PROT) { PrintS("S"); mflush(); }
2866      p=p_Copy(strat->P.p,currRing);
2867      //pWrite(p);
2868      //  for (int i=rVar(currRing); i>0; i--)
2869      //    if (mm[i]!=0) Print("x_%d:%d ",i,mm[i]);
2870      //PrintLn();
2871      memset(&strat->P,0,sizeof(strat->P));
2872      strat->P.tailRing = strat->tailRing;
2873      strat->P.p=p;
2874      while(p!=NULL)
2875      {
2876        for (int i=rVar(currRing); i>0; i--)
2877        {
2878          p_SubExp(p,i,mm[i],currRing);
2879        }
2880        p_Setm(p,currRing);
2881        pIter(p);
2882      }
2883      b = TRUE;
2884    }
2885    omFree(mm);
2886    omFree(m0);
2887  }
2888  else
2889  {
2890    poly p=strat->P.t_p;
2891
2892    // iterate over all terms of p and
2893    // compute the minimum mm of all exponent vectors
2894    int *mm=(int*)omAlloc((1+rVar(currRing))*sizeof(int));
2895    int *m0=(int*)omAlloc0((1+rVar(currRing))*sizeof(int));
2896    p_GetExpV(p,mm,strat->tailRing);
2897    bool nonTrivialSaturationToBeDone=true;
2898    for (p = pNext(p); p!=NULL; pIter(p))
2899    {
2900      nonTrivialSaturationToBeDone=false;
2901      p_GetExpV(p,m0,strat->tailRing);
2902      for(int i=rVar(currRing); i>0; i--)
2903      {
2904        if(id_satstdSaturatingVariables[i]!=0)
2905        {
2906          mm[i]=si_min(mm[i],m0[i]);
2907          if (mm[i]>0) nonTrivialSaturationToBeDone = true;
2908        }
2909        else mm[i]=0;
2910      }
2911      // abort if the minimum is zero in each component
2912      if (!nonTrivialSaturationToBeDone) break;
2913    }
2914    if (nonTrivialSaturationToBeDone)
2915    {
2916      if (TEST_OPT_PROT) { PrintS("S"); mflush(); }
2917      p=p_Copy(strat->P.t_p,strat->tailRing);
2918      //p_Write(p,strat->tailRing);
2919      //  for (int i=rVar(currRing); i>0; i--)
2920      //    if (mm[i]!=0) Print("x_%d:%d ",i,mm[i]);
2921      //PrintLn();
2922      memset(&strat->P,0,sizeof(strat->P));
2923      strat->P.tailRing = strat->tailRing;
2924      strat->P.t_p=p;
2925      while(p!=NULL)
2926      {
2927        for(int i=rVar(currRing); i>0; i--)
2928        {
2929          p_SubExp(p,i,mm[i],strat->tailRing);
2930        }
2931        p_Setm(p,strat->tailRing);
2932        pIter(p);
2933      }
2934      strat->P.GetP();
2935      b = TRUE;
2936    }
2937    omFree(mm);
2938    omFree(m0);
2939  }
2940  return b; // return TRUE if sp was changed, FALSE if not
2941}
2942
2943ideal id_Satstd(const ideal I, ideal J, const ring r)
2944{
2945  ring save=currRing;
2946  if (currRing!=r) rChangeCurrRing(r);
2947  idSkipZeroes(J);
2948  id_satstdSaturatingVariables=(int*)omAlloc0((1+rVar(currRing))*sizeof(int));
2949  int k=IDELEMS(J);
2950  if (k>1)
2951  {
2952    for (int i=0; i<k; i++)
2953    {
2954      poly x = J->m[i];
2955      int li = p_Var(x,r);
2956      if (li>0)
2957        id_satstdSaturatingVariables[li]=1;
2958      else
2959      {
2960        if (currRing!=save) rChangeCurrRing(save);
2961        WerrorS("ideal generators must be variables");
2962        return NULL;
2963      }
2964    }
2965  }
2966  else
2967  {
2968    poly x = J->m[0];
2969    for (int i=1; i<=r->N; i++)
2970    {
2971      int li = p_GetExp(x,i,r);
2972      if (li==1)
2973        id_satstdSaturatingVariables[i]=1;
2974      else if (li>1)
2975      {
2976        if (currRing!=save) rChangeCurrRing(save);
2977        Werror("exponent(x(%d)^%d) must be 0 or 1",i,li);
2978        return NULL;
2979      }
2980    }
2981  }
2982  ideal res=kStd(I,r->qideal,testHomog,NULL,NULL,0,0,NULL,id_sat_vars_sp);
2983  omFreeSize(id_satstdSaturatingVariables,(1+rVar(currRing))*sizeof(int));
2984  id_satstdSaturatingVariables=NULL;
2985  if (currRing!=save) rChangeCurrRing(save);
2986  return res;
2987}
2988
2989GbVariant syGetAlgorithm(char *n, const ring r, const ideal /*M*/)
2990{
2991  GbVariant alg=GbDefault;
2992  if (strcmp(n,"slimgb")==0) alg=GbSlimgb;
2993  else if (strcmp(n,"std")==0) alg=GbStd;
2994  else if (strcmp(n,"sba")==0) alg=GbSba;
2995  else if (strcmp(n,"singmatic")==0) alg=GbSingmatic;
2996  else if (strcmp(n,"groebner")==0) alg=GbGroebner;
2997  else if (strcmp(n,"modstd")==0) alg=GbModstd;
2998  else if (strcmp(n,"ffmod")==0) alg=GbFfmod;
2999  else if (strcmp(n,"nfmod")==0) alg=GbNfmod;
3000  else if (strcmp(n,"std:sat")==0) alg=GbStdSat;
3001  else Warn(">>%s<< is an unknown algorithm",n);
3002
3003  if (alg==GbSlimgb) // test conditions for slimgb
3004  {
3005    if(rHasGlobalOrdering(r)
3006    &&(!rIsPluralRing(r))
3007    &&(r->qideal==NULL)
3008    &&(!rField_is_Ring(r)))
3009    {
3010       return GbSlimgb;
3011    }
3012    if (TEST_OPT_PROT)
3013      WarnS("requires: coef:field, commutative, global ordering, not qring");
3014  }
3015  else if (alg==GbSba) // cond. for sba
3016  {
3017    if(rField_is_Domain(r)
3018    &&(!rIsPluralRing(r))
3019    &&(rHasGlobalOrdering(r)))
3020    {
3021      return GbSba;
3022    }
3023    if (TEST_OPT_PROT)
3024      WarnS("requires: coef:domain, commutative, global ordering");
3025  }
3026  else if (alg==GbGroebner) // cond. for groebner
3027  {
3028    return GbGroebner;
3029  }
3030  else if(alg==GbModstd)  // cond for modstd: Q or Q(a)
3031  {
3032    if(ggetid("modStd")==NULL)
3033    {
3034      WarnS(">>modStd<< not found");
3035    }
3036    else if(rField_is_Q(r)
3037    &&(!rIsPluralRing(r))
3038    &&(rHasGlobalOrdering(r)))
3039    {
3040      return GbModstd;
3041    }
3042    if (TEST_OPT_PROT)
3043      WarnS("requires: coef:QQ, commutative, global ordering");
3044  }
3045  else if(alg==GbStdSat)  // cond for std:sat: 2 blocks of variables
3046  {
3047    if(ggetid("satstd")==NULL)
3048    {
3049      WarnS(">>satstd<< not found");
3050    }
3051    else
3052    {
3053      return GbStdSat;
3054    }
3055  }
3056
3057  return GbStd; // no conditions for std
3058}
3059//----------------------------------------------------------------------------
3060// GB-algorithms and their pre-conditions
3061// std   slimgb  sba singmatic modstd ffmod nfmod groebner
3062// +     +       +   -         +      -     -     + coeffs: QQ
3063// +     +       +   +         -      -     -     + coeffs: ZZ/p
3064// +     +       +   -         ?      -     +     + coeffs: K[a]/f
3065// +     +       +   -         ?      +     -     + coeffs: K(a)
3066// +     -       +   -         -      -     -     + coeffs: domain, not field
3067// +     -       -   -         -      -     -     + coeffs: zero-divisors
3068// +     +       +   +         -      ?     ?     + also for modules: C
3069// +     +       -   +         -      ?     ?     + also for modules: all orderings
3070// +     +       -   -         -      -     -     + exterior algebra
3071// +     +       -   -         -      -     -     + G-algebra
3072// +     +       +   +         +      +     +     + degree ordering
3073// +     -       +   +         +      +     +     + non-degree ordering
3074// -     -       -   +         +      +     +     + parallel
Note: See TracBrowser for help on using the repository browser.