source: git/kernel/ideals.cc @ 341943

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