source: git/kernel/ideals.cc @ 0277c5

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