source: git/Singular/LIB/grobcov.lib @ 380a17b

spielwiese
Last change on this file since 380a17b was 380a17b, checked in by Hans Schoenemann <hannes@…>, 11 years ago
fix: new version numbers for libs
  • Property mode set to 100644
File size: 110.6 KB
Line 
1/////////////////////////////////////////////////////////////////////////////
2version="version grobcov.lib 4.0.0.0 Jun_2013 ";
3category="General purpose";
4info="
5LIBRARY:  grobcov.lib   Groebner Cover for parametric ideals.
6PURPOSE:  Comprehensive Groebner Systems, Groebner Cover, Canonical Forms,
7          Parametric Polynomial Systems.
8          The library contains Montes-Wibmer's algorithms to compute the
9          canonical Groebner cover of a parametric ideal as described in
10          the paper:
11
12          Montes A., Wibmer M.,
13          \"Groebner Bases for Polynomial Systems with parameters\".
14          Journal of Symbolic Computation 45 (2010) 1391-1425.
15          The locus algorithm and definitions will be
16          published in a forthcoming paper by Abanades, Botana, Montes, Recio:
17          \''Geometrical locus of points using the Groebner cover\''.
18
19
20          The central routine is grobcov. Given a parametric
21          ideal, grobcov outputs its Canonical Groebner Cover, consisting
22          of a set of pairs of (basis, segment). The basis (after
23          normalization) is the reduced Groebner basis for each point
24          of the segment. The segments are disjoint, locally closed
25          and correspond to constant lpp (leading power product)
26          of the basis, and are represented in canonical prime
27          representation. The segments are disjoint and cover the
28          whole parameter space. The output is canonical, it only
29          depends on the given parametric ideal and the monomial order.
30          This is much more than a simple Comprehensive Groebner System.
31          The algorithm grobcov allows options to solve partially the
32          problem when the whole automatic algorithm does not finish
33          in reasonable time.
34
35          grobcov uses a first algorithm cgsdr that outputs a disjoint
36          reduced Comprehensive Groebner System with constant lpp.
37          For this purpose, in this library, the implemented algorithm is
38          Kapur-Sun-Wang algorithm, because it is the most efficient
39          algorithm known for this purpose.
40
41          D. Kapur, Y. Sun, and D.K. Wang.
42          \"A New Algorithm for Computing Comprehensive Groebner Systems\".
43          Proceedings of ISSAC'2010, ACM Press, (2010), 29-36.
44
45          cgsdr can be called directly if only a disjoint reduced
46          Comprehensive Groebner System (CGS) is required.
47
48AUTHORS:  Antonio Montes , Hans Schoenemann.
49OVERVIEW: see \"Groebner Bases for Polynomial Systems with parameters\"
50          Montes A., Wibmer M.,
51          Journal of Symbolic Computation 45 (2010) 1391-1425.
52          (http://www-ma2.upc.edu/~montes/).
53
54NOTATIONS: All given and determined polynomials and ideals are in the
55@*         basering Q[a][x]; (a=parameters, x=variables)
56@*         After defining the ring, the main routines
57@*         grobcov, cgsdr,
58@*         generate the global rings
59@*         @R   (Q[a][x]),
60@*         @P   (Q[a]),
61@*         @RP  (Q[x,a])
62@*         that are used inside and killed before the output.
63@*         If you want to use some internal routine you must
64@*         create before the above rings by calling setglobalrings();
65@*         because most of the internal routines use these rings.
66@*         The call to the basic routines grobcov, cgsdr will
67@*         kill these rings.
68
69PROCEDURES:
70
71grobcov(F);        Is the basic routine giving the canonical
72                   Groebner cover of the parametric ideal F.
73                   This routine accepts many options, that
74                   allow to obtain results even when the canonical
75                   computation does not finish in reasonable time.
76
77cgsdr(F);          Is the procedure for obtaining a first disjoint,
78                   reduced Comprehensive Groebner System that
79                   is used in grobcov, but that can be used
80                   independently if only the CGS is required.
81                   It is a more efficient routine than buildtree
82                   (the own routine that is no more used). It uses
83                   now KSW algorithm.
84
85setglobalrings();  Generates the global rings @R, @P and @PR that are
86                   respectively the rings Q[a][x], Q[a], Q[x,a].
87                   It is called inside each of the fundamental routines
88                   of the library: grobcov, cgsdr and killed before
89                   the output.
90                   If the user want to use some other internal routine,
91                   then setglobalrings() is to be called before, as
92                   the rings @R, @P and @RP are needed in most of them.
93                   globally, and more internal routines can be used, but
94                   these rings are killed by the call to any of the
95                   basic routines.
96
97pdivi(f,F);     Performs a pseudodivision of a parametric polynomial
98                   by a parametric ideal.
99
100pnormalf(f,E,N);   Reduces a parametric polynomial f over V(E) \ V(N)
101                   E is the null ideal and N the non-null ideal
102                   over the parameters.
103
104extend(GC); When the grobcov of an ideal has been computed
105                   with the default option ('ext',0) and the explicit
106                   option ('rep',2) (which is not the default), then
107                   one can call extend (GC) (and options) to obtain the
108                   full representation of the bases. With the default
109                   option ('ext',0) only the generic representation of
110                   the bases are computed, and one can obtain the full
111                   representation using extend.
112
113locus(G):   Special routine for determining the locus of points
114                   of  objects. Given a parametric ideal J with
115                   parameters (a_1,..a_m) and variables (x_1,..,xn),
116                   representing the system determining
117                   the locus of points (a_1,..,a_m)) who verify certain
118                   properties, computing the grobcov G of
119                   J and applying to it locus, determines the different
120                   classes of locus components. They can be
121                   Normal, Special, Accumulation point, Degenerate.
122                   The output are the components given in P-canonical form
123                   of two constructible sets: Normal, and Non-Normal
124                   The Normal Set has Normal and Special components
125                   The Non-Normal set has Accumulation and Degenerate components.
126                   The description of the algorithm and definitions will be
127                   given in a forthcoming paper by Abanades, Botana, Montes, Recio:
128                   ''Geometrical locus of points using the Groebner cover''
129
130locusdg(G):  Is a special routine for computing the locus in dinamical geometry.
131                    It detects automatically a possible point that is to be avoided by the mover,
132                    whose coordinates must be the last two coordinates in the definition of the ring.
133                    If such a point is detected, then it eliminates the segments of the grobcov
134                    depending on the point that is to be avoided.
135                    Then it calls locus.
136
137locusto(L):  Transforms the output of locus to a string that
138                  can be reed from different computational systems.
139
140SEE ALSO: compregb_lib
141";
142
143LIB "primdec.lib";
144LIB "qhmoduli.lib";
145
146// ************ Begin of the grobcov library *********************
147
148// Library grobcov.lib
149// (Groebner cover):
150// Release 1: (public)
151// Initial data: 21-1-2008
152// Final data: 3-7-2008
153// Release 2: (private)
154// Initial data: 6-9-2009
155// Final data: 25-10-2011
156// Release 3: (this release, public)
157// Initial data: 1-7-2012
158// Final data: 4-9-2012
159// basering Q[a][x];
160
161// ************ Begin of buildtree ******************************
162
163proc setglobalrings()
164"USAGE:   setglobalrings();
165          No arguments
166RETURN:   After its call the rings @R=Q[a][x], @P=Q[a], @RP=Q[x,a] are
167          defined as global variables.
168NOTE:     It is called internally by the fundamental routines of the
169          library grobcov, cgsdr, extend, pdivi, pnormalf, locus, locusto,
170          and killed before the output.
171          The user does not need to call it, except when it is interested
172          in using some internal routine of the library that
173          uses these rings.
174          The basering R, must be of the form Q[a][x], a=parameters,
175          x=variables, and should be defined previously.
176KEYWORDS: ring, rings
177EXAMPLE:  setglobalrings; shows an example"
178{
179  if (defined(@P))
180  {
181    kill @P; kill @R; kill @RP;
182  }
183  def RR=basering;
184  def @R=basering;  // must be of the form K[a][x], a=parameters, x=variables
185  def Rx=ringlist(RR);
186  def @P=ring(Rx[1]);
187  list Lx;
188  Lx[1]=0;
189  Lx[2]=Rx[2]+Rx[1][2];
190  Lx[3]=Rx[1][3];
191  Lx[4]=Rx[1][4];
192  Rx[1]=0;
193  def D=ring(Rx);
194  def @RP=D+@P;
195  exportto(Top,@R);      // global ring K[a][x]
196  exportto(Top,@P);      // global ring K[a]
197  exportto(Top,@RP);     // global ring K[x,a] with product order
198  setring(RR);
199};
200example
201{ "EXAMPLE:"; echo = 2;
202  ring R=(0,a,b),(x,y,z),dp;
203  setglobalrings();
204  @R;
205  @P;
206  @RP;
207ringlist(@R);
208ringlist(@P);
209ringlist(@RP);
210}
211
212//*************Auxilliary routines**************
213
214// cld : clears denominators of an ideal and normalizes to content 1
215//       can be used in @R or @P or @RP
216// input:
217//    ideal J (J can be also poly), but the output is an ideal;
218// output:
219//    ideal Jc (the new form of ideal J without denominators and
220//       normalized to content 1)
221proc cld(ideal J)
222{
223  if (size(J)==0){return(ideal(0));}
224  def RR=basering;
225  setring(@RP);
226  def Ja=imap(RR,J);
227  ideal Jb;
228  if (size(Ja)==0){setring(RR); return(ideal(0));}
229  int i;
230  def j=0;
231  for (i=1;i<=ncols(Ja);i++){if (size(Ja[i])!=0){j++; Jb[j]=cleardenom(Ja[i]);}}
232  setring(RR);
233  def Jc=imap(@RP,Jb);
234  return(Jc);
235};
236
237proc memberpos(f,J)
238//"USAGE:  memberpos(f,J);
239//         (f,J) expected (polynomial,ideal)
240//               or       (int,list(int))
241//               or       (int,intvec)
242//               or       (intvec,list(intvec))
243//               or       (list(int),list(list(int)))
244//               or       (ideal,list(ideal))
245//               or       (list(intvec),  list(list(intvec))).
246//         The ring can be @R or @P or @RP or any other.
247//RETURN:  The list (t,pos) t int; pos int;
248//         t is 1 if f belongs to J and 0 if not.
249//         pos gives the position in J (or 0 if f does not belong).
250//EXAMPLE: memberpos; shows an example"
251{
252  int pos=0;
253  int i=1;
254  int j;
255  int t=0;
256  int nt;
257  if (typeof(J)=="ideal"){nt=ncols(J);}
258  else{nt=size(J);}
259  if ((typeof(f)=="poly") or (typeof(f)=="int"))
260  { // (poly,ideal)  or
261    // (poly,list(poly))
262    // (int,list(int)) or
263    // (int,intvec)
264    i=1;
265    while(i<=nt)
266    {
267      if (f==J[i]){return(list(1,i));}
268      i++;
269    }
270    return(list(0,0));
271  }
272  else
273  {
274    if ((typeof(f)=="intvec") or ((typeof(f)=="list") and (typeof(f[1])=="int")))
275    { // (intvec,list(intvec)) or
276      // (list(int),list(list(int)))
277      i=1;
278      t=0;
279      pos=0;
280      while((i<=nt) and (t==0))
281      {
282        t=1;
283        j=1;
284        if (size(f)!=size(J[i])){t=0;}
285        else
286        {
287          while ((j<=size(f)) and t)
288          {
289            if (f[j]!=J[i][j]){t=0;}
290            j++;
291          }
292        }
293        if (t){pos=i;}
294        i++;
295      }
296      if (t){return(list(1,pos));}
297      else{return(list(0,0));}
298    }
299    else
300    {
301      if (typeof(f)=="ideal")
302      { // (ideal,list(ideal))
303        i=1;
304        t=0;
305        pos=0;
306        while((i<=nt) and (t==0))
307        {
308          t=1;
309          j=1;
310          if (ncols(f)!=ncols(J[i])){t=0;}
311          else
312          {
313            while ((j<=ncols(f)) and t)
314            {
315              if (f[j]!=J[i][j]){t=0;}
316              j++;
317            }
318          }
319          if (t){pos=i;}
320          i++;
321        }
322        if (t){return(list(1,pos));}
323        else{return(list(0,0));}
324      }
325      else
326      {
327        if ((typeof(f)=="list") and (typeof(f[1])=="intvec"))
328        { // (list(intvec),list(list(intvec)))
329          i=1;
330          t=0;
331          pos=0;
332          while((i<=nt) and (t==0))
333          {
334            t=1;
335            j=1;
336            if (size(f)!=size(J[i])){t=0;}
337            else
338            {
339              while ((j<=size(f)) and t)
340              {
341                if (f[j]!=J[i][j]){t=0;}
342                j++;
343              }
344            }
345            if (t){pos=i;}
346            i++;
347          }
348          if (t){return(list(1,pos));}
349          else{return(list(0,0));}
350        }
351      }
352    }
353  }
354}
355//example
356//{ "EXAMPLE:"; echo = 2;
357//  list L=(7,4,5,1,1,4,9);
358//  memberpos(1,L);
359//}
360
361proc subset(J,K)
362//"USAGE:   subset(J,K);
363//          (J,K)  expected (ideal,ideal)
364//                   or     (list, list)
365//RETURN:   1 if all the elements of J are in K, 0 if not.
366//EXAMPLE:  subset; shows an example;"
367{
368  int i=1;
369  int nt;
370  if (typeof(J)=="ideal"){nt=ncols(J);}
371  else{nt=size(J);}
372  if (size(J)==0){return(1);}
373  while(i<=nt)
374  {
375    if (memberpos(J[i],K)[1]){i++;}
376    else {return(0);}
377  }
378  return(1);
379}
380//example
381//{ "EXAMPLE:"; echo = 2;
382//  list J=list(7,3,2);
383//  list K=list(1,2,3,5,7,8);
384//  subset(J,K);
385//}
386
387// elimintfromideal: elimine the constant numbers from an ideal
388//        (designed for W, nonnull conditions)
389// input: ideal J
390// output:ideal K with the elements of J that are non constants, in the
391//        ring @P
392proc elimintfromideal(ideal J)
393{
394  int i;
395  int j=0;
396  ideal K;
397  if (size(J)==0){return(ideal(0));}
398  for (i=1;i<=ncols(J);i++){if (size(variables(J[i])) !=0){j++; K[j]=J[i];}}
399  return(K);
400}
401
402// simpqcoeffs : simplifies a quotient of two polynomials
403// input: two coeficients (or terms), that are considered as a quotient
404// output: the two coeficients reduced without common factors
405proc simpqcoeffs(poly n,poly m)
406{
407  def nc=content(n);
408  def mc=content(m);
409  def gc=gcd(nc,mc);
410  ideal s=n/gc,m/gc;
411  return (s);
412}
413
414// pdivi : pseudodivision of a poly f by a parametric ideal F in Q[a][x].
415// input:
416//   poly  f (in the parametric ring @R)
417//   ideal F (in the parametric ring @R)
418// output:
419//   list (poly r, ideal q, poly mu)
420proc pdivi(poly f,ideal F)
421"USAGE:   pdivi(f,F);
422          poly f: the polynomial to be divided
423          ideal F: the divisor ideal
424RETURN:   A list (poly r, ideal q, poly m). r is the remainder of the
425          pseudodivision, q is the set of quotients, and m is the
426          coefficient factor by which f is to be multiplied.
427NOTE:     pseudodivision of a poly f by an ideal F in @R. Returns a
428          list (r,q,m) such that m*f=r+sum(q.G), and no lpp of a divisor
429          divides a pp of r.
430KEYWORDS: division, reduce
431EXAMPLE:  pdivi; shows an example"
432{
433  int te=0;
434  if (defined(@P)==1){te=1;}
435  else{setglobalrings();}
436  def R=basering;
437  int i;
438  int j;
439  poly r=0;
440  poly mu=1;
441  def p=f;
442  ideal q;
443  for (i=1; i<=size(F); i++){q[i]=0;};
444  ideal lpf;
445  ideal lcf;
446  for (i=1;i<=size(F);i++){lpf[i]=leadmonom(F[i]);}
447  for (i=1;i<=size(F);i++){lcf[i]=leadcoef(F[i]);}
448  poly lpp;
449  poly lcp;
450  poly qlm;
451  poly nu;
452  poly rho;
453  int divoc=0;
454  ideal qlc;
455  while (p!=0)
456  {
457    i=1;
458    divoc=0;
459    lpp=leadmonom(p);
460    lcp=leadcoef(p);
461    while (divoc==0 and i<=size(F))
462    {
463      qlm=lpp/lpf[i];
464      if (qlm!=0)
465      {
466        qlc=simpqcoeffs(lcp,lcf[i]);
467        nu=qlc[2];
468        mu=mu*nu;
469        rho=qlc[1]*qlm;
470        p=nu*p-rho*F[i];
471        r=nu*r;
472        for (j=1;j<=size(F);j++){q[j]=nu*q[j];}
473        q[i]=q[i]+rho;
474        divoc=1;
475      }
476      else {i++;}
477    }
478    if (divoc==0)
479    {
480      r=r+lcp*lpp;
481      p=p-lcp*lpp;
482    }
483  }
484  list res=r,q,mu;
485  if(te==0){kill @P; kill @R; kill @RP;}
486  return(res);
487}
488example
489{ "EXAMPLE:"; echo = 2;
490  ring R=(0,a,b,c),(x,y),dp;
491  "Divisor=";
492  poly f=(ab-ac)*xy+(ab)*x+(5c);
493  "Dividends=";
494  ideal F=ax+b,cy+a;
495  "(Remainder, quotients, factor)=";
496  def r=pdivi(f,F);
497  r;
498  "Verifying the division: r[3]*f-(r[2][1]*F[1]+r[2][2]*F[2])-r[1] =";
499  r[3]*f-(r[2][1]*F[1]+r[2][2]*F[2])-r[1];
500}
501
502// pspol : S-poly of two polynomials in @R
503// @R
504// input:
505//   poly f (given in the ring @R)
506//   poly g (given in the ring @R)
507// output:
508//   list (S, red):  S is the S-poly(f,g) and red is a Boolean variable
509//                if red then S reduces by Buchberger 1st criterion
510//                (not used)
511proc pspol(poly f,poly g)
512{
513  def lcf=leadcoef(f);
514  def lcg=leadcoef(g);
515  def lpf=leadmonom(f);
516  def lpg=leadmonom(g);
517  def v=gcd(lpf,lpg);
518  def s=simpqcoeffs(lcf,lcg);
519  def vf=lpf/v;
520  def vg=lpg/v;
521  poly S=s[2]*vg*f-s[1]*vf*g;
522  return(S);
523}
524
525// facvar: Returns all the free-square factors of the elements
526//         of ideal J (non repeated). Integer factors are ignored,
527//         even 0 is ignored. It can be called from ideal @R, but
528//         the given ideal J must only contain poynomials in the
529//         parameters.
530//         Operates in the ring @P, but can be called from ring @R,
531//         and the ideal @P must be defined calling first setglobalrings();
532// input:  ideal J
533// output: ideal Jc: Returns all the free-square factors of the elements
534//         of ideal J (non repeated). Integer factors are ignored,
535//         even 0 is ignored. It can be called from ideal @R.
536proc facvar(ideal J)
537//"USAGE:   facvar(J);
538//          J: an ideal in the parameters
539//RETURN:   all the free-square factors of the elements
540//          of ideal J (non repeated). Integer factors are ignored,
541//          even 0 is ignored. It can be called from ideal @R, but
542//          the given ideal J must only contain poynomials in the
543//          parameters.
544//NOTE:     Operates in the ring @P, and the ideal J must contain only
545//          polynomials in the parameters, but can be called from ring @R.
546//KEYWORDS: factor
547//EXAMPLE:  facvar; shows an example"
548{
549  int i;
550  def RR=basering;
551  setring(@P);
552  def Ja=imap(RR,J);
553  if(size(Ja)==0){setring(RR); return(ideal(0));}
554  Ja=elimintfromideal(Ja); // also in ideal @P
555  ideal Jb;
556  if (size(Ja)==0){Jb=ideal(0);}
557  else
558  {
559    for (i=1;i<=ncols(Ja);i++){if(size(Ja[i])!=0){Jb=Jb,factorize(Ja[i],1);}}
560    Jb=simplify(Jb,2+4+8);
561    Jb=cld(Jb);
562    Jb=elimintfromideal(Jb); // also in ideal @P
563  }
564  setring(RR);
565  def Jc=imap(@P,Jb);
566  return(Jc);
567}
568//example
569//{ "EXAMPLE:"; echo = 2;
570//  ring R=(0,a,b,c),(x,y,z),dp;
571//  setglobalrings();
572//  ideal J=a2-b2,a2-2ab+b2,abc-bc;
573//  facvar(J);
574//}
575
576// Ered: eliminates the factors in the polynom f that are non-null.
577//       In ring @R
578// input:
579//   poly f:
580//   ideal E  of null-conditions
581//   ideal N  of non-null conditions
582//        (E,N) represents V(E)\V(N),
583//        Ered eliminates the non-null factors of f in V(E)\V(N)
584// output:
585//   poly f2  where the non-null conditions have been dropped from f
586proc Ered(poly f,ideal E, ideal N)
587{
588  def RR=basering;
589  setring(@R);
590  poly ff=imap(RR,f);
591  ideal EE=imap(RR,E);
592  ideal NN=imap(RR,N);
593  if((ff==0) or (equalideals(NN,ideal(1)))){setring(RR); return(f);}
594  def v=variables(ff);
595  int i;
596  poly X=1;
597  for(i=1;i<=size(v);i++){X=X*v[i];}
598  matrix M=coef(ff,X);
599  setring(@P);
600  def RPE=imap(@R,EE);
601  def RPN=imap(@R,NN);
602  matrix Mp=imap(@R,M);
603  poly g=Mp[2,1];
604  if (size(Mp)!=2)
605  {
606    for(i=2;i<=size(Mp) div 2;i++)
607    {
608      g=gcd(g,Mp[2,i]);
609    }
610  }
611  if (g==1){setring(RR); return(f);}
612  else
613  {
614    def wg=factorize(g,2);
615    if (wg[1][1]==1){setring(RR); return(f);}
616    else
617    {
618      poly simp=1;
619      int te;
620      for(i=1;i<=size(wg[1]);i++)
621      {
622        te=inconsistent(RPE+wg[1][i],RPN);
623        if(te)
624        {
625          simp=simp*(wg[1][i])^(wg[2][i]);
626        }
627      }
628    }
629    if (simp==1){setring(RR); return(f);}
630    else
631    {
632      setring(RR);
633      def simp0=imap(@P,simp);
634      def f2=f/simp0;
635      return(f2);
636    }
637  }
638}
639
640// pnormalf: reduces a polynomial f wrt a V(E)\V(N)
641//           dividing by E and eliminating factors in N.
642//           called in the ring @R,
643//           operates in the ring @RP.
644// input:
645//         poly  f
646//         ideal E  (depends only on the parameters)
647//         ideal N  (depends only on the parameters)
648//                  (E,N) represents V(E)\V(N)
649//         optional:
650// output: poly f2 reduced wrt to V(E)\V(N)
651proc pnormalf(poly f, ideal E, ideal N)
652"USAGE:   pnormalf(f,E,N);
653          f: the polynomial to be reduced modulo V(E)\V(N)
654          of a segment in the parameters.
655          E: the null conditions ideal
656          N: the non-null conditions
657RETURN:   a reduced polynomial g of f, whose coefficients are reduced
658          modulo E and having no factor in N.
659NOTE: Should be called from ring Q[a][x].
660          Ideals E and N must be given by polynomials
661          in the parameters.
662KEYWORDS: division, pdivi, reduce
663EXAMPLE:  pnormalf; shows an example"
664{
665    def RR=basering;
666    int te=0;
667    if (defined(@P)){te=1;}
668    else{setglobalrings();}
669    setring(@RP);
670    def fa=imap(RR,f);
671    def Ea=imap(RR,E);
672    def Na=imap(RR,N);
673    option(redSB);
674    Ea=std(Ea);
675    def r=cld(reduce(fa,Ea));
676    poly f1=r[1];
677    f1=Ered(r[1],Ea,Na);
678    setring(RR);
679    def f2=imap(@RP,f1);
680    if(te==0){kill @R; kill @RP; kill @P;}
681    return(f2)
682};
683example
684{ "EXAMPLE:"; echo = 2;
685  ring R=(0,a,b,c),(x,y),dp;
686  poly f=(b^2-1)*x^3*y+(c^2-1)*x*y^2+(c^2*b-b)*x+(a-bc)*y;
687  ideal E=(c-1);
688  ideal N=a-b;
689  pnormalf(f,E,N);
690}
691
692// idint: ideal intersection
693//        in the ring @P.
694//        it works in an extended ring
695// input: two ideals in the ring @P
696// output the intersection of both (is not a GB)
697proc idint(ideal I, ideal J)
698{
699  def RR=basering;
700  ring T=0,t,lp;
701  def K=T+RR;
702  setring(K);
703  def Ia=imap(RR,I);
704  def Ja=imap(RR,J);
705  ideal IJ;
706  int i;
707  for(i=1;i<=size(Ia);i++){IJ[i]=t*Ia[i];}
708  for(i=1;i<=size(Ja);i++){IJ[size(Ia)+i]=(1-t)*Ja[i];}
709  ideal eIJ=eliminate(IJ,t);
710  setring(RR);
711  return(imap(K,eIJ));
712}
713
714// lesspol: compare two polynomials by its leading power products
715// input:  two polynomials f,g in the ring @R
716// output: 0 if f<g,  1 if f>=g
717proc lesspol(poly f, poly g)
718{
719  if (leadmonom(f)<leadmonom(g)){return(1);}
720  else
721  {
722    if (leadmonom(g)<leadmonom(f)){return(0);}
723    else
724    {
725      if (leadcoef(f)<leadcoef(g)){return(1);}
726      else {return(0);}
727    }
728  }
729};
730
731// delfromideal: deletes the i-th polynomial from the ideal F
732proc delfromideal(ideal F, int i)
733{
734  int j;
735  ideal G;
736  if (size(F)<i){ERROR("delfromideal was called incorrect arguments");}
737  if (size(F)<=1){return(ideal(0));}
738  if (i==0){return(F)};
739  for (j=1;j<=size(F);j++)
740  {
741    if (j!=i){G[size(G)+1]=F[j];}
742  }
743  return(G);
744}
745
746// delidfromid: deletes the polynomials in J that are in I
747// input: ideals I,J
748// output: the ideal J without the polynomials in I
749proc delidfromid(ideal I, ideal J)
750{
751  int i; list r;
752  ideal JJ=J;
753  for (i=1;i<=size(I);i++)
754  {
755    r=memberpos(I[i],JJ);
756    if (r[1])
757    {
758      JJ=delfromideal(JJ,r[2]);
759    }
760  }
761  return(JJ);
762}
763
764// sortideal: sorts the polynomials in an ideal by lm in ascending order
765proc sortideal(ideal Fi)
766{
767  def RR=basering;
768  setring(@RP);
769  def F=imap(RR,Fi);
770  def H=F;
771  ideal G;
772  int i;
773  int j;
774  poly p;
775  while (size(H)!=0)
776  {
777    j=1;
778    p=H[1];
779    for (i=1;i<=size(H);i++)
780    {
781      if(lesspol(H[i],p)){j=i;p=H[j];}
782    }
783    G[size(G)+1]=p;
784    H=delfromideal(H,j);
785  }
786  setring(RR);
787  def GG=imap(@RP,G);
788  return(GG);
789}
790
791// mingb: given a basis (gb reducing) it
792// order the polynomials is ascending order and
793// eliminates the polynomials whose lpp are divisible by some
794// smaller one
795proc mingb(ideal F)
796{
797  int t; int i; int j;
798  def H=sortideal(F);
799  ideal G;
800  if (ncols(H)<=1){return(H);}
801  G=H[1];
802  for (i=2; i<=ncols(H); i++)
803  {
804    t=1;
805    j=1;
806    while (t and (j<i))
807    {
808      if((leadmonom(H[i])/leadmonom(H[j]))!=0) {t=0;}
809      j++;
810    }
811    if (t) {G[size(G)+1]=H[i];}
812  }
813  return(G);
814}
815
816// redgbn: given a minimal basis (gb reducing) it
817// reduces each polynomial wrt to V(E) \ V(N)
818proc redgbn(ideal F, ideal E, ideal N)
819{
820  int te=0;
821  if (defined(@P)==1){te=1;}
822  ideal G=F;
823  ideal H;
824  int i;
825  if (size(G)==0){return(ideal(0));}
826  for (i=1;i<=size(G);i++)
827  {
828    H=delfromideal(G,i);
829    G[i]=pnormalf(pdivi(G[i],H)[1],E,N);
830    G[i]=primepartZ(G[i]);
831  }
832  if(te==1){setglobalrings();}
833  return(G);
834};
835
836// eliminates repeated elements form an ideal or matrix or module or intmat or bigintmat
837proc elimrepeated(F)
838{
839  int i;
840  def FF=F;
841  FF=F[1];
842  for (i=2;i<=ncols(F);i++)
843  {
844    if (not(memberpos(F[i],FF)[1]))
845    {
846      FF[size(FF)+1]=F[i];
847    }
848  }
849  return(FF);
850}
851
852proc elimrepeatedvl(F)
853{
854  int i;
855  def FF=F;
856  FF=F[1];
857  for (i=2;i<=size(F);i++)
858  {
859    if (not(memberpos(F[i],FF)[1]))
860    {
861      FF[size(FF)+1]=F[i];
862    }
863  }
864  return(FF);
865}
866
867
868// equalideals
869// input: 2 ideals F and G;
870// output: 1 if they are identical (the same polynomials in the same order)
871//         0 else
872proc equalideals(ideal F, ideal G)
873{
874  int i=1; int t=1;
875  if (size(F)!=size(G)){return(0);}
876  while ((i<=size(F)) and (t))
877  {
878    if (F[i]!=G[i]){t=0;}
879    i++;
880  }
881  return(t);
882}
883
884// delintvec
885// input: intvec V
886//        int i
887// output:
888//        intvec W (equal to V but the coordinate i is deleted
889proc delintvec(intvec V, int i)
890{
891  int j;
892  intvec W;
893  for (j=1;j<i;j++){W[j]=V[j];}
894  for (j=i+1;j<=size(V);j++){W[j-1]=V[j];}
895  return(W);
896}
897
898//**************Begin homogenizing************************
899
900// ishomog:
901// Purpose: test if a polynomial is homogeneous in the variables or not
902// input:  poly f
903// output  1 if f is homogeneous, 0 if not
904proc ishomog(f)
905{
906  int i; poly r; int d; int dr;
907  if (f==0){return(1);}
908  d=deg(f); dr=d; r=f;
909  while ((d==dr) and (r!=0))
910  {
911    r=r-lead(r);
912    dr=deg(r);
913  }
914  if (r==0){return(1);}
915  else{return(0);}
916}
917
918// postredgb: given a minimal basis (gb reducing) it
919// reduces each polynomial wrt to the others
920proc postredgb(ideal F)
921{
922  int te=0;
923  if(defined(@P)==1){te=1;}
924  ideal G;
925  ideal H;
926  int i;
927  if (size(F)==0){return(ideal(0));}
928  for (i=1;i<=size(F);i++)
929  {
930    H=delfromideal(F,i);
931    G[i]=pdivi(F[i],H)[1];
932  }
933  if(te==1){setglobalrings();}
934  return(G);
935}
936
937//purpose ideal intersection called in @R and computed in @P
938proc idintR(ideal N, ideal M)
939{
940  def RR=basering;
941  setring(@P);
942  def Np=imap(RR,N);
943  def Mp=imap(RR,M);
944  def Jp=idint(Np,Mp);
945  setring(RR);
946  return(imap(@P,Jp));
947}
948
949//purpose reduced Groebner basis called in @R and computed in @P
950proc gbR(ideal N)
951{
952  def RR=basering;
953  setring(@P);
954  def Np=imap(RR,N);
955  option(redSB);
956  Np=std(Np);
957  setring(RR);
958  return(imap(@P,Np));
959}
960
961//**************End homogenizing************************
962
963//**************Begin of Groebner Cover*****************
964
965// incquotient
966// incremental quotient
967// Input: ideal N: a Groebner basis of an ideal
968//        poly f:
969// Output: Na = N:<f>
970proc incquotient(ideal N, poly f)
971{
972  poly g; int i;
973  ideal Nb; ideal Na=N;
974
975  // begins incquotient
976  if (size(Na)==1)
977  {
978    g=gcd(Na[1],f);
979    if (g!=1)
980    {
981      Na[1]=Na[1]/g;
982    }
983    attrib(Na,"IsSB",1);
984    return(Na);
985  }
986  def P=basering;
987  poly @t;
988  ring H=0,@t,lp;
989  def HP=H+P;
990  setring(HP);
991  def fh=imap(P,f);
992  def Nh=imap(P,N);
993  ideal Nht;
994  for (i=1;i<=size(Nh);i++)
995  {
996    Nht[i]=Nh[i]*@t;
997  }
998  attrib(Nht,"isSB",1);
999  def fht=(1-@t)*fh;
1000  option(redSB);
1001  Nht=std(Nht,fht);
1002  ideal Nc; ideal v;
1003  for (i=1;i<=size(Nht);i++)
1004  {
1005    v=variables(Nht[i]);
1006    if(memberpos(@t,v)[1]==0)
1007    {
1008      Nc[size(Nc)+1]=Nht[i]/fh;
1009    }
1010  }
1011  setring(P);
1012  ideal HH;
1013  def Nd=imap(HP,Nc); Nb=Nd;
1014  option(redSB);
1015  Nb=std(Nd);
1016  return(Nb);
1017}
1018
1019// eliminates the ith element from a list or an intvec
1020proc elimfromlist(l, int i)
1021{
1022  if(typeof(l)=="list"){list L;}
1023  if (typeof(l)=="intvec"){intvec L;}
1024  if (typeof(l)=="ideal"){ideal L;}
1025  int j;
1026  if((size(l)==0) or (size(l)==1 and i!=1)){return(l);}
1027  if (size(l)==1 and i==1){return(L);}
1028  // L=l[1];
1029  if(i==1)
1030  {
1031    for(j=2;j<=size(l);j++)
1032    {
1033      L[j-1]=l[j];
1034    }
1035  }
1036  else
1037  {
1038    for(j=1;j<=i-1;j++)
1039    {
1040      L[j]=l[j];
1041    }
1042    for(j=i+1;j<=size(l);j++)
1043    {
1044      L[j-1]=l[j];
1045    }
1046  }
1047  return(L);
1048}
1049
1050proc idbefid(ideal a, ideal b)
1051{
1052  poly fa; poly fb; poly la; poly lb;
1053  int te=1; int i; int j;
1054  int na=size(a);
1055  int nb=size(b);
1056  int nm;
1057  if (na<=nb){nm=na;} else{nm=nb;}
1058  for (i=1;i<=nm; i++)
1059  {
1060    fa=a[i]; fb=b[i];
1061    while((fa!=0) or (fb!=0))
1062    {
1063      la=lead(fa);
1064      lb=lead(fb);
1065      fa=fa-la;
1066      fb=fb-lb;
1067      la=leadmonom(la);
1068      lb=leadmonom(lb);
1069      if(leadmonom(la+lb)!=la){return(1);}
1070      else{if(leadmonom(la+lb)!=lb){return(2);}}
1071    }
1072  }
1073  if(na<nb){return(1);}
1074  else
1075  {
1076    if(na>nb){return(2);}
1077    else{return(0);}
1078  }
1079}
1080
1081proc sortlistideals(list L)
1082{
1083  int i; int j; int n;
1084  ideal a; ideal b;
1085  list LL=L;
1086  list NL;
1087  int k; int te;
1088  i=1;
1089  while(size(LL)>0)
1090  {
1091    k=1;
1092    for(j=2;j<=size(LL);j++)
1093    {
1094      te=idbefid(LL[k],LL[j]);
1095      if (te==2){k=j;}
1096    }
1097    NL[size(NL)+1]=LL[k];
1098    n=size(LL);
1099    if (n>1){LL=elimfromlist(LL,k);} else{LL=list();}
1100  }
1101  return(NL);
1102}
1103
1104// returns 1 if the two lists of ideals are equal and 0 if not
1105proc equallistideals(list L, list M)
1106{
1107  int t; int i;
1108  if (size(L)!=size(M)){return(0);}
1109  else
1110  {
1111    t=1;
1112    if (size(L)>0)
1113    {
1114      i=1;
1115      while ((t) and (i<=size(L)))
1116      {
1117        if (equalideals(L[i],M[i])==0){t=0;}
1118        i++;
1119      }
1120    }
1121    return(t);
1122  }
1123}
1124
1125// Prep
1126// Computes the P-representation of V(N) \ V(M).
1127// input:
1128//    ideal N (null ideal) (not necessarily radical nor maximal)
1129//    ideal M (hole ideal) (not necessarily containing N)
1130// output:
1131//    the ((p_1,(p_11,p_1k_1)),..,(p_r,(p_r1,p_rk_r)));
1132//    the Prep of V(N)\V(M)
1133// Assumed to work in the ring @P of the parameters
1134proc Prep(ideal N, ideal M)
1135{
1136  if (N[1]==1)
1137  {
1138    return(list(list(ideal(1),list(ideal(1)))));
1139  }
1140  def RR=basering;
1141  setring(@P);
1142  ideal Np=imap(RR,N);
1143  ideal Mp=imap(RR,M);
1144  int i; int j; list L0;
1145
1146  list Ni=minGTZ(Np);
1147  list prep;
1148  for(j=1;j<=size(Ni);j++)
1149  {
1150    option(redSB);
1151    Ni[j]=std(Ni[j]);
1152  }
1153  list Mij;
1154  for (i=1;i<=size(Ni);i++)
1155  {
1156    Mij=minGTZ(Ni[i]+Mp);
1157    for(j=1;j<=size(Mij);j++)
1158    {
1159      option(redSB);
1160      Mij[j]=std(Mij[j]);
1161    }
1162    if ((size(Mij)==1) and (equalideals(Ni[i],Mij[1])==1)){;}
1163    else
1164    {
1165        prep[size(prep)+1]=list(Ni[i],Mij);
1166    }
1167  }
1168  if (size(prep)==0){prep=list(list(ideal(1),list(ideal(1))));}
1169  setring(RR);
1170  return(imap(@P,prep));
1171}
1172
1173// PtoCrep
1174// Computes the C-representation from the P-representation.
1175// input:
1176//    list ((p_1,(p_11,p_1k_1)),..,(p_r,(p_r1,p_rk_r)));
1177//         the P-representation of V(N)\V(M)
1178// output:
1179//    list (ideal ida, ideal idb)
1180//    the C-representaion of V(N)\V(M) = V(ida)\V(idb)
1181// Assumed to work in the ring @P of the parameters
1182proc PtoCrep(list L)
1183{
1184  def RR=basering;
1185  setring(@P);
1186  def Lp=imap(RR,L);
1187  int i; int j;
1188  ideal ida=ideal(1); ideal idb=ideal(1); list Lb; ideal N;
1189  for (i=1;i<=size(Lp);i++)
1190  {
1191    option(returnSB);
1192    N=Lp[i][1];
1193    ida=intersect(ida,N);
1194    Lb=Lp[i][2];
1195    for(j=1;j<=size(Lb);j++)
1196    {
1197      idb=intersect(idb,Lb[j]);
1198    }
1199  }
1200  def La=list(ida,idb);
1201  setring(RR);
1202  return(imap(@P,La));
1203}
1204
1205// input: F a parametric ideal in Q[a][x]
1206// output: a rComprehensive Groebner System disjoint and reduced.
1207//      It uses Kapur-Sun-Wang algorithm, and with the options
1208//      can compute the homogenization before  (('can',0) or ( 'can',1))
1209//      and dehomogenize the result.
1210proc cgsdr(ideal F, list #)
1211"USAGE: cgsdr(F); To compute a disjoint, reduced CGS.
1212          cgsdr is the starting point of the fundamental routine grobcov.
1213          Inside grobcov it is used only with options 'can' set to 0,1 and
1214          not with options ('can',2).
1215          It is to be used if only a disjoint reduced CGS is required.
1216          F: ideal in Q[a][x] (parameters and variables) to be discussed.
1217
1218          Options: To modify the default options, pairs of arguments
1219          -option name, value- of valid options must be added to the call.
1220
1221          Options:
1222            \"can\",0-1-2: The default value is \"can\",2. In this case no
1223                homogenization is done. With option (\"can\",0) the given
1224                basis is homogenized, and with option (\"can\",1) the
1225                whole given ideal is homogenized before computing the
1226                cgs and dehomogenized after.
1227                with option (\"can\",0) the homogenized basis is used
1228                with option (\"can\",1) the homogenized ideal is used
1229                with option (\"can\",2) the given basis is used
1230            \"null\",ideal E: The default is (\"null\",ideal(0)).
1231            \"nonnull\",ideal N: The default (\"nonnull\",ideal(1)).
1232                When options 'null' and/or 'nonnull' are given, then
1233                the parameter space is restricted to V(E)\V(N).
1234            \"comment\",0-1: The default is (\"comment\",0). Setting (\"comment\",1)
1235                will provide information about the development of the
1236                computation.
1237            \"out\",0-1: 1 (default) the output segments are given as
1238                as difference of varieties.
1239                0: the output segments are given in P-representation
1240                and the segments grouped by lpp
1241                With options (\"can\",0) and (\"can\",1) the option (\"out\",1)
1242                is set to (out,0) because it is not compatible.
1243          One can give none or whatever of these options.
1244          With the default options (\"can\",2,\"out\",1), only the
1245          Kapur-Sun-Wang algorithm is computed. This is very effectif
1246          but is only the starting point for the computation.
1247          When grobcov is computed, the call to cgsdr inside uses
1248          specific options that are more expensive ("can",0-1,"out",0).
1249RETURN:   Returns a list T describing a reduced and disjoint
1250          Comprehensive Groebner System (CGS),
1251          With option (\"out\",0)
1252           the segments are grouped by
1253           leading power products (lpp) of the reduced Groebner
1254           basis and given in P-representation.
1255           The returned list is of the form:
1256           (
1257             (lpp, (num,basis,segment),...,(num,basis,segment),lpp),
1258             ..,,
1259             (lpp, (num,basis,segment),...,(num,basis,segment),lpp)
1260           )
1261           The bases are the reduced Groebner bases (after normalization)
1262           for each point of the corresponding segment.
1263
1264           The third element of each lpp segment is the lpp of the
1265           used ideal in the CGS as a string:
1266            with option (\"can\",0) the homogenized basis is used
1267            with option (\"can\",1) the homogenized ideal is used
1268            with option (\"can\",2) the given basis is used
1269
1270          With option (\"out\",1) (default)
1271           only KSW is applied and segments are given as
1272           difference of varieties and are not grouped
1273           The returned list is of the form:
1274           (
1275             (E,N,B),..(E,N,B)
1276           )
1277           E is the null variety
1278           N is the nonnull variety
1279           segment = V(E)\V(N)
1280           B is the reduced Groebner basis
1281
1282NOTE:     The basering R, must be of the form Q[a][x], a=parameters,
1283          x=variables, and should be defined previously, and the ideal
1284          defined on R.
1285KEYWORDS: CGS, disjoint, reduced, Comprehensive Groebner System
1286EXAMPLE:  cgsdr; shows an example"
1287{
1288  def RR=basering;
1289  setglobalrings();
1290  // INITIALIZING OPTIONS
1291  int i; int j;
1292  int can=2;
1293  int out=1;
1294  poly f;
1295  ideal B;
1296  def E=ideal(0);
1297  def N=ideal(1);
1298  int comment=0;
1299  int start=timer;
1300  list L=#;
1301  for(i=1;i<=size(L) div 2;i++)
1302  {
1303    if(L[2*i-1]=="null"){E=L[2*i];}
1304    else
1305    {
1306      if(L[2*i-1]=="nonnull"){N=L[2*i];}
1307      else
1308      {
1309        if(L[2*i-1]=="comment"){comment=L[2*i];}
1310        else
1311        {
1312          if(L[2*i-1]=="can"){can=L[2*i];}
1313          else
1314          {
1315            if(L[2*i-1]=="out"){out=L[2*i];}
1316          }
1317        }
1318      }
1319    }
1320  }
1321  //if(can==2){out=1;}
1322  B=F;
1323  if ((printlevel) and (comment==0)){comment=printlevel;}
1324  if((can<2) and (out>0)){"Option out,1 is not compatible with can,0,1"; out=0;}
1325  // DEFINING OPTIONS
1326  list LL;
1327  LL[1]="can";     LL[2]=can;
1328  LL[3]="comment"; LL[4]=comment;
1329  LL[5]="out";     LL[6]=out;
1330  LL[7]="null";    LL[8]=E;
1331  LL[9]="nonnull"; LL[10]=N;
1332  if(comment>=1)
1333  {
1334    string("Begin cgsdr with options: ",LL);
1335  }
1336  int ish;
1337  for (i=1;i<=size(B);i++){ish=ishomog(B[i]); if(ish==0){break;};}
1338  if (ish)
1339  {
1340    if(comment>0){string("The given system is homogneous");}
1341    def GS=KSW(B,LL);
1342    //can=0;
1343  }
1344  else
1345  {
1346  // ACTING DEPENDING ON OPTIONS
1347  if(can==2)
1348  {
1349    // WITHOUT HOMOHGENIZING
1350    if(comment>0){string("Option of cgsdr: do not homogenize");}
1351    def GS=KSW(B,LL);
1352    setglobalrings();
1353  }
1354  else
1355  {
1356    if(can==1)
1357    {
1358      // COMPUTING THE HOMOGOENIZED IDEAL
1359      if(comment>0){string("Homogenizing the whole ideal: option can=1");}
1360      list RRL=ringlist(RR);
1361      RRL[3][1][1]="dp";
1362      def Pa=ring(RRL[1]);
1363      list Lx;
1364      Lx[1]=0;
1365      Lx[2]=RRL[2]+RRL[1][2];
1366      Lx[3]=RRL[1][3];
1367      Lx[4]=RRL[1][4];
1368      RRL[1]=0;
1369      def D=ring(RRL);
1370      def RP=D+Pa;
1371      setring(RP);
1372      def B1=imap(RR,B);
1373      option(redSB);
1374      B1=std(B1);
1375      setring(RR);
1376      def B2=imap(RP,B1);
1377    }
1378    else
1379    { // (can=0)
1380       if(comment>0){string("Homogenizing the basis: option can=0");}
1381      def B2=B;
1382    }
1383    // COMPUTING HOMOGENIZED CGS
1384    poly @t;
1385    ring H=0,@t,dp;
1386    def RH=RR+H;
1387    setring(RH);
1388    setglobalrings();
1389    def BH=imap(RR,B2);
1390    def LH=imap(RR,LL);
1391    for (i=1;i<=size(BH);i++)
1392    {
1393      BH[i]=homog(BH[i],@t);
1394    }
1395    if (comment>=1){string("Homogenized system = "); BH;}
1396    def GSH=KSW(BH,LH);
1397    setglobalrings();
1398    // DEHOMOGENIZING THE RESULT
1399    if(out==0)
1400    {
1401      for (i=1;i<=size(GSH);i++)
1402      {
1403        GSH[i][1]=subst(GSH[i][1],@t,1);
1404        for(j=1;j<=size(GSH[i][2]);j++)
1405        {
1406          GSH[i][2][j][2]=subst(GSH[i][2][j][2],@t,1);
1407        }
1408      }
1409    }
1410    else
1411    {
1412      for (i=1;i<=size(GSH);i++)
1413      {
1414        GSH[i][3]=subst(GSH[i][3],@t,1);
1415        GSH[i][7]=subst(GSH[i][7],@t,1);
1416      }
1417    }
1418    setring(RR);
1419    def GS=imap(RH,GSH);
1420    }
1421
1422
1423    setglobalrings();
1424    if(out==0)
1425    {
1426      for (i=1;i<=size(GS);i++)
1427      {
1428        GS[i][1]=postredgb(mingb(GS[i][1]));
1429        for(j=1;j<=size(GS[i][2]);j++)
1430        {
1431          GS[i][2][j][2]=postredgb(mingb(GS[i][2][j][2]));
1432        }
1433      }
1434    }
1435    else
1436    {
1437      for (i=1;i<=size(GS);i++)
1438      {
1439        if(GS[i][2]==1)
1440        {
1441          GS[i][3]=postredgb(mingb(GS[i][3]));
1442          GS[i][7]=postredgb(mingb(GS[i][7]));
1443        }
1444      }
1445    }
1446  }
1447  if(defined(@P)){kill @P; kill @R; kill @RP;}
1448  return(GS);
1449}
1450example
1451{ "EXAMPLE:"; echo = 2;
1452  "Casas conjecture for degree 4";
1453  ring R=(0,a0,a1,a2,a3,a4),(x1,x2,x3),dp;
1454  ideal F=x1^4+(4*a3)*x1^3+(6*a2)*x1^2+(4*a1)*x1+(a0),
1455          x1^3+(3*a3)*x1^2+(3*a2)*x1+(a1),
1456          x2^4+(4*a3)*x2^3+(6*a2)*x2^2+(4*a1)*x2+(a0),
1457          x2^2+(2*a3)*x2+(a2),
1458          x3^4+(4*a3)*x3^3+(6*a2)*x3^2+(4*a1)*x3+(a0),
1459          x3+(a3);
1460  cgsdr(F);
1461}
1462
1463// input:  internal routine called by cgsdr at the end to group the
1464//         lpp segments and improve the output
1465// output: grouped segments by lpp obtained in cgsdr
1466proc grsegments(list T)
1467{
1468  int i;
1469  list L;
1470  list lpp;
1471  list lp;
1472  list ls;
1473  int n=size(T);
1474  lpp[1]=T[n][1];
1475  L[1]=list(lpp[1],list(list(T[n][2],T[n][3],T[n][4])));
1476  if (n>1)
1477  {
1478    for (i=1;i<=size(T)-1;i++)
1479    {
1480      lp=memberpos(T[n-i][1],lpp);
1481      if(lp[1]==1)
1482      {
1483        ls=L[lp[2]][2];
1484        ls[size(ls)+1]=list(T[n-i][2],T[n-i][3],T[n-i][4]);
1485        L[lp[2]][2]=ls;
1486      }
1487      else
1488      {
1489        lpp[size(lpp)+1]=T[n-i][1];
1490        L[size(L)+1]=list(T[n-i][1],list(list(T[n-i][2],T[n-i][3],T[n-i][4])));
1491      }
1492    }
1493  }
1494  return(L);
1495}
1496
1497// idcontains
1498// input: ideal p, ideal q
1499// output: 1 if p contains q,  0 otherwise
1500proc idcontains(ideal p, ideal q)
1501{
1502  int t; int i;
1503  t=1; i=1;
1504  def RR=basering;
1505  setring(@P);
1506  def P=imap(RR,p);
1507  def Q=imap(RR,q);
1508  attrib(P,"isSB",1);
1509  poly r;
1510  while ((t) and (i<=size(Q)))
1511  {
1512    r=reduce(Q[i],P);
1513    if (r!=0){t=0;}
1514    i++;
1515  }
1516  setring(RR);
1517  return(t);
1518}
1519
1520// selectminindeals
1521//   given a list of ideals returns the list of integers corresponding
1522//   to the minimal ideals in the list
1523// input: L (list of ideals)
1524// output: the list of integers corresponding to the minimal ideals in L
1525proc selectminideals(list L)
1526{
1527  if (size(L)==0){return(L)};
1528  def RR=basering;
1529  setring(@P);
1530  def Lp=imap(RR,L);
1531  int i; int j; int t; intvec notsel;
1532  list P;
1533  for (i=1;i<=size(Lp);i++)
1534  {
1535    if(memberpos(i,notsel)[1])
1536    {
1537      i++;
1538      if(i>size(Lp)){break;}
1539    }
1540    t=1;
1541    j=1;
1542    while ((t) and (j<=size(Lp)))
1543    {
1544      if (i==j){j++;}
1545      if ((j<=size(Lp)) and (memberpos(j,notsel)[1]==0))
1546      {
1547
1548        if (idcontains(Lp[i],Lp[j]))
1549        {
1550          notsel[size(notsel)+1]=i;
1551          t=0;
1552        }
1553      }
1554      j++;
1555    }
1556    if (t){P[size(P)+1]=i;}
1557  }
1558  setring(RR);
1559  return(P);
1560}
1561
1562// LCUnion
1563// Given a list of the P-representations of locally closed segments
1564// for which we know that the union is also locally closed
1565// it returns the P-representation of its union
1566// input:  L list of segments in P-representation
1567//      ((p_j^i,(p_j1^i,...,p_jk_j^i | j=1..t_i)) | i=1..s )
1568//      where i represents a segment
1569// output: P-representation of the union
1570//       ((P_j,(P_j1,...,P_jk_j | j=1..t)))
1571proc LCUnion(list LL)
1572{
1573  def RR=basering;
1574  setring(@P);
1575  def L=imap(RR,LL);
1576  int i; int j; int k; list H; list C; list T;
1577  list L0; list P0; list P; list Q0; list Q;
1578  for (i=1;i<=size(L);i++)
1579  {
1580    for (j=1;j<=size(L[i]);j++)
1581    {
1582      P0[size(P0)+1]=L[i][j][1];
1583      L0[size(L0)+1]=intvec(i,j);
1584    }
1585  }
1586  Q0=selectminideals(P0);
1587  for (i=1;i<=size(Q0);i++)
1588  {
1589    Q[i]=L0[Q0[i]];
1590    P[i]=L[Q[i][1]][Q[i][2]];
1591  }
1592  // P is the list of the maximal components of the union
1593  //   with the corresponding initial holes.
1594  // Q is the list of intvec positions in L of the first element of the P's
1595  //   Its elements give (num of segment, num of max component (=min ideal))
1596  for (k=1;k<=size(Q);k++)
1597  {
1598    H=P[k][2]; // holes of P[k][1]
1599    for (i=1;i<=size(L);i++)
1600    {
1601      if (i!=Q[k][1])
1602      {
1603        for (j=1;j<=size(L[i]);j++)
1604        {
1605          C[size(C)+1]=L[i][j];
1606        }
1607      }
1608    }
1609    T[size(T)+1]=list(Q[k],P[k][1],addpart(H,C));
1610  }
1611  setring(RR);
1612  def TT=imap(@P,T);
1613  return(TT);
1614}
1615
1616// Called by LCUnion to modify the holes of a primepart of the union
1617// by the addition of the segments that do not correspond to that part
1618// Works on @P ring.
1619// Input:
1620//   H=(p_i1,..,p_is) the holes of a component to be transformed by the addition of
1621//        the segments C that do not correspond to that component
1622//   C=((q_1,(q_11,..,q_1l_1)),..,(q_k,(q_k1,..,q_kl_k)))
1623//        the list of segments to be added to the holes
1624proc addpart(list H, list C)
1625{
1626  list Q; int i; int j; int k; int l; int t; int t1;
1627  Q=H; intvec notQ; list QQ; list addq;
1628  ideal q;
1629  i=1;
1630  while (i<=size(Q))
1631  {
1632    if (memberpos(i,notQ)[1]==0)
1633    {
1634      q=Q[i];
1635      t=1; j=1;
1636      while ((t) and (j<=size(C)))
1637      {
1638        if (equalideals(q,C[j][1]))
1639        {
1640          t=0;
1641          for (k=1;k<=size(C[j][2]);k++)
1642          {
1643            t1=1;
1644            //kill addq;
1645            //list addq;
1646            l=1;
1647            while((t1) and (l<=size(Q)))
1648            {
1649              if ((l!=i) and (memberpos(l,notQ)[1]==0))
1650              {
1651                if (idcontains(C[j][2][k],Q[l]))
1652                {
1653                  t1=0;
1654                }
1655              }
1656              l++;
1657            }
1658            if (t1)
1659            {
1660              addq[size(addq)+1]=C[j][2][k];
1661            }
1662          }
1663          if((size(notQ)==1) and (notQ[1]==0)){notQ[1]=i;}
1664          else {notQ[size(notQ)+1]=i;}
1665        }
1666        j++;
1667      }
1668      if (size(addq)>0)
1669      {
1670        for (k=1;k<=size(addq);k++)
1671        {
1672          Q[size(Q)+1]=addq[k];
1673        }
1674        kill addq;
1675        list addq;
1676      }
1677      //print("Q="); Q; print("notQ="); notQ;
1678    }
1679    i++;
1680  }
1681  for (i=1;i<=size(Q);i++)
1682  {
1683    if(memberpos(i,notQ)[1]==0)
1684    {
1685      QQ[size(QQ)+1]=Q[i];
1686    }
1687  }
1688  if (size(QQ)==0){QQ[1]=ideal(1);}
1689  return(addpartfine(QQ,C));
1690}
1691
1692// Called by addpart to finish the modification of the holes of a primepart
1693// of the union by the addition of the segments that do not correspond to
1694// that part.
1695// Works on @P ring.
1696proc addpartfine(list H, list C0)
1697{
1698  int i; int j; int k; int te; intvec notQ; int l; list sel; int used;
1699  intvec jtesC;
1700  if ((size(H)==1) and (equalideals(H[1],ideal(1)))){return(H);}
1701  if (size(C0)==0){return(H);}
1702  def RR=basering;
1703  setring(@P);
1704  list newQ; list nQ; list Q; list nQ1; list Q0;
1705  def Q1=imap(RR,H);
1706  //Q1=sortlistideals(Q1);
1707  def C=imap(RR,C0);
1708  while(equallistideals(Q0,Q1)==0)
1709  {
1710    Q0=Q1;
1711    i=0;
1712    Q=Q1;
1713    kill notQ; intvec notQ;
1714    while(i<size(Q))
1715    {
1716      i++;
1717      for(j=1;j<=size(C);j++)
1718      {
1719        te=idcontains(Q[i],C[j][1]);
1720        if(te)
1721        {
1722          for(k=1;k<=size(C[j][2]);k++)
1723          {
1724            if(idcontains(Q[i],C[j][2][k]))
1725            {
1726              te=0; break;
1727            }
1728          }
1729          if (te)
1730          {
1731            used++;
1732            if ((size(notQ)==1) and (notQ[1]==0)){notQ[1]=i;}
1733            else{notQ[size(notQ)+1]=i;}
1734            kill newQ; list newQ;
1735            for(k=1;k<=size(C[j][2]);k++)
1736            {
1737              nQ=minGTZ(Q[i]+C[j][2][k]);
1738              for(l=1;l<=size(nQ);l++)
1739              {
1740                option(redSB);
1741                nQ[l]=std(nQ[l]);
1742                newQ[size(newQ)+1]=nQ[l];
1743              }
1744            }
1745            sel=selectminideals(newQ);
1746            kill nQ1; list nQ1;
1747            for(l=1;l<=size(sel);l++)
1748            {
1749              nQ1[l]=newQ[sel[l]];
1750            }
1751            newQ=nQ1;
1752            for(l=1;l<=size(newQ);l++)
1753            {
1754              Q[size(Q)+1]=newQ[l];
1755            }
1756            break;
1757          }
1758        }
1759      }
1760    }
1761    kill Q1; list Q1;
1762    for(i=1;i<=size(Q);i++)
1763    {
1764      if(memberpos(i,notQ)[1]==0)
1765      {
1766        Q1[size(Q1)+1]=Q[i];
1767      }
1768    }
1769    sel=selectminideals(Q1);
1770    kill nQ1; list nQ1;
1771    for(l=1;l<=size(sel);l++)
1772    {
1773      nQ1[l]=Q1[sel[l]];
1774    }
1775    Q1=nQ1;
1776  }
1777  setring(RR);
1778  //if(used>0){string("addpartfine was ", used, " times used");}
1779  return(imap(@P,Q1));
1780}
1781
1782// specswellCrep
1783// input:
1784//   given two corresponding polynomials g1 and g2 with the same lpp
1785//   g1 belonging to the basis in the segment ida1,idb1
1786//   g2 belonging to the basis in the segment ida2,idb2
1787// output:
1788//   1 if g1 spezializes well to g2 on the whole (ida2,idb2) segment
1789//   0 if not
1790proc specswellCrep(poly g1, poly g2, ideal ida2)
1791{
1792  poly S;
1793  S=leadcoef(g2)*g1-leadcoef(g1)*g2;
1794  def RR=basering;
1795  setring(@RPt);
1796  def SR=imap(RR,S);
1797  def ida2R=imap(RR,ida2);
1798  attrib(ida2R,"isSB",1);
1799  poly S2R=reduce(SR,ida2R);
1800  setring(RR);
1801  def S2=imap(@RPt,S2R);
1802  if (S2==0){return(1);}   // and (nonnullCrep(leadcoef(g1),ida2,idb2))
1803  else {return(0);}
1804}
1805
1806// gcover
1807// input: ideal F: a generating set of a homogeneous ideal in Q[a][x]
1808//    list #: optional
1809// output: the list
1810//   S=((lpp, generic basis, Prep, Crep),..,(lpp, generic basis, Prep, Crep))
1811//      where a Prep is ( (p1,(p11,..,p1k_1)),..,(pj,(pj1,..,p1k_j)) )
1812//            a Crep is ( ida, idb )
1813proc gcover(ideal F,list #)
1814{
1815  int i; int j; int k; ideal lpp; list GPi2; list pairspP; ideal B; int ti;
1816  int i1; int tes; int j1; int selind; int i2; int m;
1817  list prep; list crep; list LCU; poly p; poly lcp; ideal FF;
1818  list lpi;
1819  string lpph;
1820  list L=#;
1821  int canop=1;
1822  int extop=1;
1823  int repop=0;
1824  ideal E=ideal(0);;
1825  ideal N=ideal(1);;
1826  int comment;
1827  for(i=1;i<=size(L) div 2;i++)
1828  {
1829    if(L[2*i-1]=="can"){canop=L[2*i];}
1830    else
1831    {
1832      if(L[2*i-1]=="ext"){extop=L[2*i];}
1833      else
1834      {
1835        if(L[2*i-1]=="rep"){repop=L[2*i];}
1836        else
1837        {
1838          if(L[2*i-1]=="null"){E=L[2*i];}
1839          else
1840          {
1841            if(L[2*i-1]=="nonnull"){N=L[2*i];}
1842            else
1843            {
1844              if (L[2*i-1]=="comment"){comment=L[2*i];}
1845            }
1846          }
1847        }
1848      }
1849    }
1850  }
1851  list GS; list GP;
1852  def RR=basering;
1853  GS=cgsdr(F,L); // "null",NW[1],"nonnull",NW[2],"cgs",CGS,"comment",comment);
1854  setglobalrings();
1855  int start=timer;
1856  GP=GS;
1857  ideal lppr;
1858  list LL;
1859  list S;
1860  poly sp;
1861  ideal BB;
1862  for (i=1;i<=size(GP);i++)
1863  {
1864    kill LL;
1865    list LL;
1866    lpp=GP[i][1];
1867    GPi2=GP[i][2];
1868    lpph=GP[i][3];
1869    kill pairspP; list pairspP;
1870    for(j=1;j<=size(GPi2);j++)
1871    {
1872      pairspP[size(pairspP)+1]=GPi2[j][3];
1873    }
1874    LCU=LCUnion(pairspP);
1875    kill prep; list prep;
1876    for(k=1;k<=size(LCU);k++)
1877    {
1878      prep[k]=list(LCU[k][2],LCU[k][3]);
1879      B=GPi2[LCU[k][1][1]][2]; // ATENTION last 1 has been changed to [2]
1880      LCU[k][1]=B;
1881    }
1882    //"Deciding if combine is needed";
1883    kill BB;
1884    ideal BB;
1885    tes=1; m=1;
1886    while((tes) and (m<=size(LCU[1][1])))
1887    {
1888      j=1;
1889      while((tes) and (j<=size(LCU)))
1890      {
1891        k=1;
1892        while((tes) and (k<=size(LCU)))
1893        {
1894          if(j!=k)
1895          {
1896            sp=pnormalf(pspol(LCU[j][1][m],LCU[k][1][m]),LCU[k][2],N);
1897            if(sp!=0){tes=0;}
1898          }
1899          k++;
1900        }        //setglobalrings();
1901        if(tes)
1902        {
1903          BB[m]=LCU[j][1][m];
1904        }
1905        j++;
1906      }
1907      if(tes==0){break;}
1908      m++;
1909    }
1910    crep=PtoCrep(prep);
1911    if(tes==0)
1912    {
1913      // combine is needed
1914      kill B; ideal B;
1915      for (j=1;j<=size(LCU);j++)
1916      {
1917        LL[j]=LCU[j][2];
1918      }
1919      if (size(LCU)>1)
1920      {
1921        FF=precombint(LL);
1922      }
1923      for (k=1;k<=size(lpp);k++)
1924      {
1925        kill L; list L;
1926        for (j=1;j<=size(LCU);j++)
1927        {
1928          L[j]=list(LCU[j][2],LCU[j][1][k]);
1929        }
1930        if (size(LCU)>1)
1931        {
1932          B[k]=combine(L,FF);
1933        }
1934        else{B[k]=L[1][2];}
1935      }
1936    }
1937    else{B=BB;}
1938    for(j=1;j<=size(B);j++)
1939    {
1940      B[j]=pnormalf(B[j],crep[1],N);
1941    }
1942    S[i]=list(lpp,B,prep,crep,lpph);
1943    if(comment>=1)
1944    {
1945      lpi[size(lpi)+1]=string("[",i,"]");
1946      lpi[size(lpi)+1]=S[i][1];
1947    }
1948  }
1949  if(comment>=1)
1950  {
1951    string("Time in LCUnion + combine = ",timer-start);
1952    if(comment>=2){string("lpp=",lpi)};
1953  }
1954  if(defined(@P)==1){kill @P; kill @RP; kill @R;}
1955  return(S);
1956}
1957
1958// grobcov
1959// input:
1960//    ideal F: a parametric ideal in Q[a][x], where a are the parameters
1961//             and x the variables
1962//    list #: (options) list("null",N,"nonnull",W,"can",0-1,ext",0-1, "rep",0-1-2)
1963//            where
1964//            N is the null conditions ideal (if desired)
1965//            W is the ideal of non-null conditions (if desired)
1966//            The value of \"can\"i s 1 by default and can be set to 0 if we do not
1967//            need to obtain the canonical GC, but only a GC.
1968//            The value of \"ext\" is 0 by default and so the generic representation
1969//             of the bases is given. It can be set to 1, and then the full
1970//             representation of the bases is given.
1971//            The value of \"rep\" is 0 by default, and then the segments
1972//            are given in canonical P-representation. It can be set to 1
1973//            and then they are given in canonical C-representation.
1974//            If it is set to 2, then both representations are given.
1975// output:
1976//    list S: ((lpp,basis,(idp_1,(idp_11,..,idp_1s_1))), ..
1977//             (lpp,basis,(idp_r,(idp_r1,..,idp_rs_r))) ) where
1978//            each element of S corresponds to a lpp-segment
1979//            given by the lpp, the basis, and the P-representation of the segment
1980proc grobcov(ideal F,list #)
1981"USAGE:   grobcov(F); This is the fundamental routine of the
1982          library. It computes the Groebner cover of a parametric ideal
1983          (see (*) Montes A., Wibmer M., Groebner Bases for Polynomial
1984          Systems with parameters. JSC 45 (2010) 1391-1425.)
1985          The Groebner cover of a parametric ideal consist of a set of
1986          pairs(S_i,B_i), where the S_i are disjoint locally closed
1987          segments of the parameter space, and the B_i are the reduced
1988          Groebner bases of the ideal on every point of S_i.
1989
1990          The ideal F must be defined on a parametric ring Q[a][x].
1991          Options: To modify the default options, pair of arguments
1992          -option name, value- of valid options must be added to the call.
1993
1994          Options:
1995            \"null\",ideal E: The default is (\"null\",ideal(0)).
1996            \"nonnull\",ideal N: The default (\"nonnull\",ideal(1)).
1997                When options \"null\" and/or \"nonnull\" are given, then
1998                the parameter space is restricted to V(E)\V(N).
1999            \"can\",0-1: The default is (\"can\",1). With the default option
2000                the homogenized ideal is computed before obtaining the
2001                Groebner cover, so that the result is the canonical
2002                Groebner cover. Setting (\"can\",0) only homogenizes the
2003                basis so the result is not exactly canonical, but the
2004                computation is shorter.
2005            \"ext\",0-1: The default is (\"ext\",0). With the default
2006                (\"ext\",0), only the generic representation is computed
2007                (single polynomials, but not specializing to non-zero at
2008                each point of the segment. With option (\"ext\",1) the
2009                full representation of the bases is computed (possible
2010                shaves) and sometimes a simpler result is obtained.
2011            \"rep\",0-1-2: The default is (\"rep\",0) and then the segments
2012                are given in canonical P-representation. Option (\"rep\",1)
2013                represents the segments in canonical C-representation,
2014                and option (\"rep\",2) gives both representations.
2015            \"comment\",0-3: The default is (\"comment\",0). Setting
2016                \"comment\" higher will provide information about the
2017                development of the computation.
2018          One can give none or whatever of these options.
2019RETURN:   The list
2020          (
2021           (lpp_1,basis_1,segment_1,lpph_1),
2022           ...
2023           (lpp_s,basis_s,segment_s,lpph_s)
2024          )
2025
2026          The lpp are constant over a segment and correspond to the
2027          set of lpp of the reduced Groebner basis for each point
2028          of the segment.
2029          The lpph corresponds to the lpp of the homogenized ideal
2030          and is different for each segment. It is given as a string.
2031
2032          Basis: to each element of lpp corresponds an I-regular function given
2033          in full representation (by option (\"ext\",1)) or in
2034          generic representation (default option (\"ext\",0)). The
2035          I-regular function is the corresponding element of the reduced
2036          Groebner basis for each point of the segment with the given lpp.
2037          For each point in the segment, the polynomial or the set of
2038          polynomials representing it, if they do not specialize to 0,
2039          then after normalization, specializes to the corresponding
2040          element of the reduced Groebner basis. In the full representation
2041          at least one of the polynomials representing the I-regular
2042          function specializes to non-zero.
2043
2044          With the default option (\"rep\",0) the representation of the
2045          segment is the P-representation.
2046          With option (\"rep\",1) the representation of the segment is
2047          the C-representation.
2048          With option (\"rep\",2) both representations of the segment are
2049          given.
2050
2051          The P-representation of a segment is of the form
2052          ((p_1,(p_11,..,p_1k1)),..,(p_r,(p_r1,..,p_rkr))
2053          representing the segment U_i (V(p_i) \ U_j (V(p_ij))),
2054          where the p's are prime ideals.
2055
2056          The C-representation of a segment is of the form
2057          (E,N) representing V(E)\V(N), and the ideals E and N are
2058          radical and N contains E.
2059
2060NOTE: The basering R, must be of the form Q[a][x], a=parameters,
2061          x=variables, and should be defined previously. The ideal must
2062          be defined on R.
2063KEYWORDS: Groebner cover, parametric ideal, canonical, discussion of
2064          parametric ideal.
2065EXAMPLE:  grobcov; shows an example"
2066{
2067  list S; int i; int ish=1; list GBR; list BR; int j; int k;
2068  ideal idp; ideal idq; int s; ideal ext; list SS;
2069  ideal E; ideal N; int canop;  int extop; int repop;
2070  int comment=0; int m;
2071  def RR=basering;
2072  setglobalrings();
2073  list L0=#;
2074  int out=0;
2075  L0[size(L0)+1]="res"; L0[size(L0)+1]=ideal(1);
2076  // default options
2077  int start=timer;
2078  E=ideal(0);
2079  N=ideal(1);
2080  canop=1; // canop=0 for homogenizing the basis but not the ideal (not canonical)
2081           // canop=1 for working with the homogenized ideal
2082  repop=0; // repop=0 for representing the segments in Prep
2083           // repop=1 for representing the segments in Crep
2084           // repop=2 for representing the segments in Prep and Crep
2085  extop=0; // extop=0 if only generic representation of the bases are to be computed
2086           // extop=1 if the full representation of the bases are to be computed
2087  for(i=1;i<=size(L0) div 2;i++)
2088  {
2089    if(L0[2*i-1]=="can"){canop=L0[2*i];}
2090    else
2091    {
2092      if(L0[2*i-1]=="ext"){extop=L0[2*i];}
2093      else
2094      {
2095        if(L0[2*i-1]=="rep"){repop=L0[2*i];}
2096        else
2097        {
2098          if(L0[2*i-1]=="null"){E=L0[2*i];}
2099          else
2100          {
2101            if(L0[2*i-1]=="nonnull"){N=L0[2*i];}
2102            else
2103            {
2104              if (L0[2*i-1]=="comment"){comment=L0[2*i];}
2105            }
2106          }
2107        }
2108      }
2109    }
2110  }
2111  if(not((canop==0) or (canop==1)))
2112  {
2113    string("Option can = ",canop," is not supported. It is changed to can = 1");
2114    canop=1;
2115  }
2116  for(i=1;i<=size(L0) div 2;i++)
2117  {
2118    if(L0[2*i-1]=="can"){L0[2*i]=canop;}
2119  }
2120  if ((printlevel) and (comment==0)){comment=printlevel;}
2121  list LL;
2122  LL[1]="can";     LL[2]=canop;
2123  LL[3]="comment"; LL[4]=comment;
2124  LL[5]="out";     LL[6]=0;
2125  LL[7]="null";    LL[8]=E;
2126  LL[9]="nonnull"; LL[10]=N;
2127  LL[11]="ext";    LL[12]=extop;
2128  LL[13]="rep";    LL[14]=repop;
2129  if (comment>=1)
2130  {
2131    string("Begin grobcov with options: ",LL);
2132  }
2133  kill S;
2134  def S=gcover(F,LL);
2135  // NOW extend
2136  if(extop)
2137  {
2138    S=extend(S,LL);
2139  }
2140  else
2141  {
2142    // NOW representation of the segments by option repop
2143    list Si; list nS;
2144    if(repop==0)
2145    {
2146      for(i=1;i<=size(S);i++)
2147      {
2148        Si=list(S[i][1],S[i][2],S[i][3],S[i][5]);
2149        nS[size(nS)+1]=Si;
2150      }
2151      kill S;
2152      def S=nS;
2153    }
2154    else
2155    {
2156      if(repop==1)
2157      {
2158        for(i=1;i<=size(S);i++)
2159        {
2160          Si=list(S[i][1],S[i][2],S[i][4],S[i][5]);
2161          nS[size(nS)+1]=Si;
2162        }
2163        kill S;
2164        def S=nS;
2165      }
2166      else
2167      {
2168        for(i=1;i<=size(S);i++)
2169        {
2170          Si=list(S[i][1],S[i][2],S[i][3],S[i][4],S[i][5]);
2171          nS[size(nS)+1]=Si;
2172        }
2173        kill S;
2174        def S=nS;
2175      }
2176    }
2177  }
2178  if (comment>=1)
2179  {
2180    string("Time in grobcov = ", timer-start);
2181    string("Number of segments of grobcov = ", size(S));
2182  }
2183  if(defined(@P)==1){kill @R; kill @P; kill @RP;}
2184  return(S);
2185}
2186example
2187{ "EXAMPLE:"; echo = 2;
2188  "Casas conjecture for degree 4";
2189  ring R=(0,a0,a1,a2,a3,a4),(x1,x2,x3),dp;
2190  ideal F=x1^4+(4*a3)*x1^3+(6*a2)*x1^2+(4*a1)*x1+(a0),
2191          x1^3+(3*a3)*x1^2+(3*a2)*x1+(a1),
2192          x2^4+(4*a3)*x2^3+(6*a2)*x2^2+(4*a1)*x2+(a0),
2193          x2^2+(2*a3)*x2+(a2),
2194          x3^4+(4*a3)*x3^3+(6*a2)*x3^2+(4*a1)*x3+(a0),
2195          x3+(a3);
2196  grobcov(F);
2197}
2198
2199// input. GC the grobcov of an ideal in generic representation of the
2200//        bases computed with option option ("rep",2).
2201// output The grobcov in full representation.
2202// option ("comment",1) shows the time.
2203proc extend(list GC, list #);
2204"USAGE:   extend(GC); When the grobcov of an ideal has been computed
2205          with the default option (\"ext\",0) and the explicit option
2206          (\"rep\",2) (which is not the default), then one can call
2207          extend (GC) (and options) to obtain the full representation
2208          of the bases. With the default option (\"ext\",0) only the
2209          generic representation of the bases are computed, and one can
2210          obtain the full representation using extend.
2211            \"rep\",0-1-2: The default is (\"rep\",0) and then the segments
2212                are given in canonical P-representation. Option (\"rep\",1)
2213                represents the segments in canonical C-representation,
2214                and option (\"rep\",2) gives both representations.
2215            \"comment\",0-1: The default is (\"comment\",0). Setting
2216                \"comment\" higher will provide information about the
2217                time used in the computation.
2218          One can give none or whatever of these options.
2219RETURN:   The list
2220          (
2221           (lpp_1,basis_1,segment_1,lpph_1),
2222           ...
2223           (lpp_s,basis_s,segment_s,lpph_s)
2224          )
2225
2226          The lpp are constant over a segment and correspond to the
2227          set of lpp of the reduced Groebner basis for each point
2228          of the segment.
2229          The lpph corresponds to the lpp of the homogenized ideal
2230          and is different for each segment. It is given as a string.
2231
2232          Basis: to each element of lpp corresponds an I-regular function given
2233          in full representation. The
2234          I-regular function is the corresponding element of the reduced
2235          Groebner basis for each point of the segment with the given lpp.
2236          For each point in the segment, the polynomial or the set of
2237          polynomials representing it, if they do not specialize to 0,
2238          then after normalization, specializes to the corresponding
2239          element of the reduced Groebner basis. In the full representation
2240          at least one of the polynomials representing the I-regular
2241          function specializes to non-zero.
2242
2243          With the default option (\"rep\",0) the segments are given
2244          in P-representation.
2245          With option (\"rep\",1) the segments are given
2246          in C-representation.
2247          With option (\"rep\",2) both representations of the segments are
2248          given.
2249
2250          The P-representation of a segment is of the form
2251          ((p_1,(p_11,..,p_1k1)),..,(p_r,(p_r1,..,p_rkr))
2252          representing the segment U_i (V(p_i) \ U_j (V(p_ij))),
2253          where the p's are prime ideals.
2254
2255          The C-representation of a segment is of the form
2256          (E,N) representing V(E)\V(N), and the ideals E and N are
2257          radical and N contains E.
2258
2259NOTE: The basering R, must be of the form Q[a][x], a=parameters,
2260          x=variables, and should be defined previously. The ideal must
2261          be defined on R.
2262KEYWORDS: Groebner cover, parametric ideal, canonical, discussion of
2263          parametric ideal, full representation.
2264EXAMPLE:  extend; shows an example"
2265{
2266  list L=#;
2267  list S=GC;
2268  ideal idp;
2269  ideal idq;
2270  int i; int j; int m; int s;
2271  m=0; i=1;
2272  while((i<=size(S)) and (m==0))
2273  {
2274    if(typeof(S[i][2])=="list"){m=1;}
2275    i++;
2276  }
2277  if(m==1){"Warning! grobcov has already extended bases"; return(S);}
2278  if(size(GC[1])!=5){"Warning! extend make sense only when grobcov has been called with options 'rep',2,'ext',0"; " "; return();}
2279  int repop=0;
2280  int start3=timer;
2281  int comment;
2282  for(i=1;i<=size(L) div 2;i++)
2283  {
2284    if(L[2*i-1]=="comment"){comment=L[2*i];}
2285    else
2286    {
2287      if(L[2*i-1]=="rep"){repop=L[2*i];}
2288    }
2289  }
2290  poly leadc;
2291  poly ext;
2292  int te=0;
2293  list SS;
2294  def R=basering;
2295  if (defined(@R)){te=1;}
2296  else{setglobalrings();}
2297  // Now extend
2298  for (i=1;i<=size(S);i++)
2299  {
2300    m=size(S[i][2]);
2301     for (j=1;j<=m;j++)
2302    {
2303      idp=S[i][4][1];
2304      idq=S[i][4][2];
2305      if (size(idp)>0)
2306      {
2307        leadc=leadcoef(S[i][2][j]);
2308        kill ext;
2309        def ext=extend0(S[i][2][j],idp,idq);
2310        if (typeof(ext)=="poly")
2311        {
2312          S[i][2][j]=pnormalf(ext,idp,idq);
2313        }
2314        else
2315        {
2316          if(size(ext)==1)
2317          {
2318            S[i][2][j]=ext[1];
2319          }
2320          else
2321          {
2322            kill SS; list SS;
2323            for(s=1;s<=size(ext);s++)
2324            {
2325              ext[s]=pnormalf(ext[s],idp,idq);
2326            }
2327            for(s=1;s<=size(S[i][2]);s++)
2328            {
2329              if(s!=j){SS[s]=S[i][2][s];}
2330              else{SS[s]=ext;}
2331            }
2332            S[i][2]=SS;
2333          }
2334        }
2335      }
2336    }
2337  }
2338  // NOW representation of the segments by option repop
2339  list Si; list nS;
2340  if (repop==0)
2341  {
2342    for(i=1;i<=size(S);i++)
2343    {
2344      Si=list(S[i][1],S[i][2],S[i][3],S[i][5]);
2345      nS[size(nS)+1]=Si;
2346    }
2347    S=nS;
2348  }
2349  else
2350  {
2351    if (repop==1)
2352    {
2353      for(i=1;i<=size(S);i++)
2354      {
2355        Si=list(S[i][1],S[i][2],S[i][4],S[i][5]);
2356        nS[size(nS)+1]=Si;
2357      }
2358      S=nS;
2359    }
2360    else
2361    {
2362      for(i=1;i<=size(S);i++)
2363      {
2364        Si=list(S[i][1],S[i][2],S[i][3],S[i][4],S[i][5]);
2365        nS[size(nS)+1]=Si;
2366      }
2367
2368    }
2369  }
2370  if(comment>=1){string("Time in extend = ",timer-start3);}
2371  if(te==0){kill @R; kill @RP; kill @P;}
2372  return(S);
2373}
2374example
2375{
2376  ring R=(0,a0,b0,c0,a1,b1,c1,a2,b2,c2),(x), dp;
2377  short=0;
2378  ideal S=a0*x^2+b0*x+c0,
2379          a1*x^2+b1*x+c1,
2380          a2*x^2+b2*x+c2;
2381  "System S="; S;
2382
2383  def GCS=grobcov(S,"rep",2,"comment",1);
2384  "grobcov(S,'rep',2,'comment',1)="; GCS;
2385  def FGC=extend(GCS,"rep",0,"comment",1);
2386  "Full representation="; FGC;
2387}
2388
2389
2390// nonzerodivisor
2391// input:
2392//    poly g in K[a],
2393//    list P=(p_1,..p_r) representing a minimal prime decomposition
2394// output
2395//    poly f such that f notin p_i for all i and
2396//           g-f in p_i for all i such that g notin p_i
2397proc nonzerodivisor(poly gr, list Pr)
2398{
2399  def RR=basering;
2400  setring(@P);
2401  def g=imap(RR,gr);
2402  def P=imap(RR,Pr);
2403  int i; int k;  list J; ideal F;
2404  def f=g;
2405  ideal Pi;
2406  for (i=1;i<=size(P);i++)
2407  {
2408    option(redSB);
2409    Pi=std(P[i]);
2410    //attrib(Pi,"isSB",1);
2411    if (reduce(g,Pi,1)==0){J[size(J)+1]=i;}
2412  }
2413  for (i=1;i<=size(J);i++)
2414  {
2415    F=ideal(1);
2416    for (k=1;k<=size(P);k++)
2417    {
2418      if (k!=J[i])
2419      {
2420        F=idint(F,P[k]);
2421      }
2422    }
2423    f=f+F[1];
2424  }
2425  setring(RR);
2426  def fr=imap(@P,f);
2427  return(fr);
2428}
2429
2430// deltai
2431// input:
2432//   int i:
2433//   list LPr: (p1,..,pr) of prime components of an ideal in K[a]
2434// output:
2435//   list (fr,fnr) of two polynomials that are equal on V(pi)
2436//       and fr=0 on V(P) \ V(pi), and fnr is nonzero on V(pj) for all j.
2437proc deltai(int i, list LPr)
2438{
2439  def RR=basering;
2440  setring(@P);
2441  def LP=imap(RR,LPr);
2442  int j; poly p;
2443  def F=ideal(1);
2444  poly f;
2445  poly fn;
2446  ideal LPi;
2447  for (j=1;j<=size(LP);j++)
2448  {
2449    if (j!=i)
2450    {
2451      F=idint(F,LP[j]);
2452    }
2453  }
2454  p=0; j=1;
2455  while ((p==0) and (j<=size(F)))
2456  {
2457    LPi=LP[i];
2458    attrib(LPi,"isSB",1);
2459    p=reduce(F[j],LPi);
2460    j++;
2461  }
2462  f=F[j-1];
2463  fn=nonzerodivisor(f,LP);
2464  setring(RR);
2465  def fr=imap(@P,f);
2466  def fnr=imap(@P,fn);
2467  return(list(fr,fnr));
2468}
2469
2470// combine
2471// input: a list of pairs ((p1,P1),..,(pr,Pr)) where
2472//    ideal pi is a prime component
2473//    poly Pi is the polynomial in Q[a][x] on V(pi)\ V(Mi)
2474//    (p1,..,pr) are the prime decomposition of the lpp-segment
2475//    list crep =(ideal ida,ideal idb): the Crep of the segment.
2476//    list Pci of the intersecctions of all pj except the ith one
2477// output:
2478//    poly P on an open and dense set of V(p_1 int ... p_r)
2479proc combine(list L, ideal F)
2480{
2481  // ATTENTION REVISE AND USE Pci and F
2482  int i; poly f;
2483  f=0;
2484  for(i=1;i<=size(L);i++)
2485  {
2486    f=f+F[i]*L[i][2];
2487  }
2488//   f=elimconstfac(f);
2489  f=primepartZ(f);
2490  return(f);
2491}
2492
2493// elimconstfac: eliminate the factors in the polynom f that are in K[a]
2494// input:
2495//   poly f:
2496//   list L: of components of the segment
2497// output:
2498//   poly f2  where the factors of f in K[a] that are non-null on any component
2499//   have been dropped from f
2500proc elimconstfac(poly f)
2501{
2502  int cond; int i; int j; int t;
2503  if (f==0){return(f);}
2504  def RR=basering;
2505  setring(@R);
2506  def ff=imap(RR,f);
2507  def l=factorize(ff,0);
2508  poly f1=1;
2509  for(i=2;i<=size(l[1]);i++)
2510  {
2511      f1=f1*(l[1][i])^(l[2][i]);
2512  }
2513  setring(RR);
2514  def f2=imap(@R,f1);
2515  return(f2);
2516};
2517
2518// nullin
2519// input:
2520//   poly f:  a polynomial in Q[a]
2521//   ideal P: an ideal in Q[a]
2522//   called from ring @R
2523// output:
2524//   t:  with value 1 if f reduces modulo P, 0 if not.
2525proc nullin(poly f,ideal P)
2526{
2527  int t;
2528  def RR=basering;
2529  setring(@P);
2530  def f0=imap(RR,f);
2531  def P0=imap(RR,P);
2532  attrib(P0,"isSB",1);
2533  if (reduce(f0,P0,1)==0){t=1;}
2534  else{t=0;}
2535  setring(RR);
2536  return(t);
2537}
2538
2539// monoms
2540proc monoms(poly f)
2541{
2542  list L;
2543  poly lm; poly lc; poly lp; poly Q; poly mQ;
2544  def p=f;
2545  int i=1;
2546  while (p!=0)
2547  {
2548    lm=lead(p);
2549    p=p-lm;
2550    lc=leadcoef(lm);
2551    lp=leadmonom(lm);
2552    L[size(L)+1]=list(lc,lp);
2553    i++;
2554  }
2555  return(L);
2556}
2557
2558// extend0
2559// input:
2560//   poly f: a generic polynomial in the basis
2561//   ideal idp: such that ideal(S)=idp
2562//   ideal idq: such that S=V(idp)\V(idq)
2563////   NW the list of ((N1,W1),..,(Ns,Ws)) of red-rep of the grouped
2564////      segments in the lpp-segment  NO MORE USED
2565// output:
2566proc extend0(poly f, ideal idp, ideal idq)
2567{
2568  matrix CC; poly Q; list NewMonoms;
2569  int i;  int j;  poly fout; ideal idout;
2570  list L=monoms(f);
2571  int nummonoms=size(L)-1;
2572  Q=L[1][1];
2573  if (nummonoms==0){return(f);}
2574  for (i=2;i<=size(L);i++)
2575  {
2576    CC=matrix(extendcoef(L[i][1],Q,idp,idq));
2577    NewMonoms[i-1]=list(CC,L[i][2]);
2578  }
2579  if (nummonoms==1)
2580  {
2581    for(j=1;j<=ncols(NewMonoms[1][1]);j++)
2582    {
2583      fout=NewMonoms[1][1][2,j]*L[1][2]+NewMonoms[1][1][1,j]*NewMonoms[1][2];
2584      //fout=pnormalf(fout,idp,W);
2585      if(ncols(NewMonoms[1][1])>1){idout[j]=fout;}
2586    }
2587    if(ncols(NewMonoms[1][1])==1){return(fout);} else{return(idout);}
2588  }
2589  else
2590  {
2591    list cfi;
2592    list coefs;
2593    for (i=1;i<=nummonoms;i++)
2594    {
2595      kill cfi; list cfi;
2596      for(j=1;j<=ncols(NewMonoms[i][1]);j++)
2597      {
2598        cfi[size(cfi)+1]=NewMonoms[i][1][2,j];
2599      }
2600      coefs[i]=cfi;
2601    }
2602    def indexpolys=findindexpolys(coefs);
2603    for(i=1;i<=size(indexpolys);i++)
2604    {
2605      fout=L[1][2];
2606      for(j=1;j<=nummonoms;j++)
2607      {
2608        fout=fout+(NewMonoms[j][1][1,indexpolys[i][j]])/(NewMonoms[j][1][2,indexpolys[i][j]])*NewMonoms[j][2];
2609      }
2610      fout=cleardenom(fout);
2611      if(size(indexpolys)>1){idout[i]=fout;}
2612    }
2613    if (size(indexpolys)==1){return(fout);} else{return(idout);}
2614  }
2615}
2616
2617// findindexpolys
2618// input:
2619//   list coefs=( (q11,..,q1r_1),..,(qs1,..,qsr_1) )
2620//               of denominators of the monoms
2621// output:
2622//   list ind=(v_1,..,v_t) of intvec
2623//        each intvec v=(i_1,..,is) corresponds to a polynomial in the sheaf
2624//        that will be built from it in extend procedure.
2625proc findindexpolys(list coefs)
2626{
2627  int i; int j; intvec numdens;
2628  for(i=1;i<=size(coefs);i++)
2629  {
2630    numdens[i]=size(coefs[i]);
2631  }
2632  def RR=basering;
2633  setring(@P);
2634  def coefsp=imap(RR,coefs);
2635  ideal cof; list combpolys; intvec v; int te; list mp;
2636  for(i=1;i<=size(coefsp);i++)
2637  {
2638    cof=ideal(0);
2639    for(j=1;j<=size(coefsp[i]);j++)
2640    {
2641      cof[j]=factorize(coefsp[i][j],3);
2642    }
2643    coefsp[i]=cof;
2644  }
2645  for(j=1;j<=size(coefsp[1]);j++)
2646  {
2647    v[1]=j;
2648    te=1;
2649    for (i=2;i<=size(coefsp);i++)
2650    {
2651      mp=memberpos(coefsp[1][j],coefsp[i]);
2652      if(mp[1])
2653      {
2654        v[i]=mp[2];
2655      }
2656      else{v[i]=0;}
2657    }
2658    combpolys[j]=v;
2659  }
2660  combpolys=reform(combpolys,numdens);
2661  setring(RR);
2662  return(combpolys);
2663}
2664
2665// extendcoef: given Q,P in K[a] where P/Q specializes on an open and dense subset
2666//      of the whole V(p1 int...int pr), it returns a basis of the module
2667//      of all syzygies equivalent to P/Q,
2668proc extendcoef(poly P, poly Q, ideal idp, ideal idq)
2669{
2670  def RR=basering;
2671  setring(@P);
2672  def PL=ringlist(@P);
2673  PL[3][1][1]="dp";
2674  def P1=ring(PL);
2675  setring(P1);
2676  ideal idp0=imap(RR,idp);
2677  option(redSB);
2678  qring q=std(idp0);
2679  poly P0=imap(RR,P);
2680  poly Q0=imap(RR,Q);
2681  ideal PQ=Q0,-P0;
2682  module C=syz(PQ);
2683  setring(@P);
2684  def idp1=imap(RR,idp);
2685  def idq1=imap(RR,idq);
2686  def C1=matrix(imap(q,C));
2687  def redC=selectregularfun(C1,idp1,idq1);
2688  setring(RR);
2689  def CC=imap(@P,redC);
2690  return(CC);
2691}
2692
2693// selectregularfun
2694// input:
2695//   list L of the polynomials matrix CC
2696//      (we assume that one of them is non-null on V(N)\V(M))
2697//   ideal N, ideal M: ideals representing the locally closed set V(N)\V(M)
2698// assume to work in @P
2699proc selectregularfun(matrix CC, ideal NN, ideal MM)
2700{
2701  int numcombused;
2702  def RR=basering;
2703  setring(@P);
2704  def C=imap(RR,CC);
2705  def N=imap(RR,NN);
2706  def M=imap(RR,MM);
2707  if (ncols(C)==1){return(C);}
2708
2709  int i; int j; int k; list c; intvec ci; intvec c0; intvec c1;
2710  list T; list T0; list T1; list LL; ideal N1;ideal M1; int te=0;
2711  for(i=1;i<=ncols(C);i++)
2712  {
2713    if((C[1,i]!=0) and (C[2,i]!=0))
2714    {
2715      if(c0==intvec(0)){c0[1]=i;}
2716      else{c0[size(c0)+1]=i;}
2717    }
2718  }
2719  def C1=submat(C,1..2,c0);
2720  for (i=1;i<=ncols(C1);i++)
2721  {
2722    c=comb(ncols(C1),i);
2723    for(j=1;j<=size(c);j++)
2724    {
2725      ci=c[j];
2726      numcombused++;
2727      if(i==1){N1=N+C1[2,j]; M1=M;}
2728      if(i>1)
2729      {
2730        kill c0; intvec c0 ; kill c1; intvec c1;
2731        c1=ci[size(ci)];
2732        for(k=1;k<size(ci);k++){c0[k]=ci[k];}
2733        T0=searchinlist(c0,LL);
2734        T1=searchinlist(c1,LL);
2735        N1=T0[1]+T1[1];
2736        M1=intersect(T0[2],T1[2]);
2737      }
2738      T=list(ci,PtoCrep(Prep(N1,M1)));
2739      LL[size(LL)+1]=T;
2740      if(equalideals(T[2][1],ideal(1))){te=1; break;}
2741    }
2742    if(te){break;}
2743  }
2744  ci=T[1];
2745  def Cs=submat(C1,1..2,ci);
2746  setring(RR);
2747  return(imap(@P,Cs));
2748}
2749
2750// searchinlist
2751// input:
2752//   intvec c:
2753//   list L=( (c1,T1),..(ck,Tk) )
2754//      where the c's are assumed to be intvects
2755// output:
2756//   object T with index c
2757proc searchinlist(intvec c,list L)
2758{
2759  int i; list T;
2760  for(i=1;i<=size(L);i++)
2761  {
2762    if (L[i][1]==c)
2763    {
2764      T=L[i][2];
2765      break;
2766    }
2767  }
2768  return(T);
2769}
2770
2771// comb: the list of combinations of elements (1,..n) of order p
2772proc comb(int n, int p)
2773{
2774  list L; list L0;
2775  intvec c; intvec d;
2776  int i; int j; int last;
2777  if ((n<0) or (n<p))
2778  {
2779    return(L);
2780  }
2781  if (p==1)
2782  {
2783    for (i=1;i<=n;i++)
2784    {
2785      c=i;
2786      L[size(L)+1]=c;
2787    }
2788    return(L);
2789  }
2790  else
2791  {
2792    L0=comb(n,p-1);
2793    for (i=1;i<=size(L0);i++)
2794    {
2795      c=L0[i]; d=c;
2796      last=c[size(c)];
2797      for (j=last+1;j<=n;j++)
2798      {
2799        d[size(c)+1]=j;
2800        L[size(L)+1]=d;
2801      }
2802    }
2803    return(L);
2804  }
2805}
2806
2807// selectminsheaves
2808// Input: L=((v_11,..,v_1k_1),..,(v_s1,..,v_sk_s))
2809//    where:
2810//    The s lists correspond to the s coefficients of the polynomial f
2811//    (v_i1,..,v_ik_i) correspond to the k_i intvec v_ij of the
2812//    spezializations of the jth rekpresentant (Q,P) of the ith coefficient
2813//    v_ij is an intvec of size equal to the number of little segments
2814//    forming the lpp-segment of 0,1, where 1 represents that it specializes
2815//    to non-zedro an the whole little segment and 0 if not.
2816// Output: S=(w_1,..,w_j)
2817//    where the w_l=(n_l1,..,n_ls) are intvec of length size(L), where
2818//    n_lt fixes which element of (v_t1,..,v_tk_t) is to be
2819//    choosen to form the tth (Q,P) for the lth element of the sheaf
2820//    representing the I-regular function.
2821// The selection is done to obtian the minimal number of elements
2822//    of the sheaf that specializes to non-null everywhere.
2823proc selectminsheaves(list L)
2824{
2825  list C=allsheaves(L);
2826  return(smsheaves(C[1],C[2]));
2827}
2828
2829// smsheaves
2830// Input:
2831//   list C of all the combrep
2832//   list L of the intvec that correesponds to each element of C
2833// Output:
2834//   list LL of the subsets of C that cover all the subsegments
2835//   (the union of the corresponding L(C) has all 1).
2836proc smsheaves(list C, list L)
2837{
2838  int i; int i0; intvec W;
2839  int nor; int norn;
2840  intvec p;
2841  int sp=size(L[1]); int j0=1;
2842  for (i=1;i<=sp;i++){p[i]=1;}
2843  while (p!=0)
2844  {
2845    i0=0; nor=0;
2846    for (i=1; i<=size(L); i++)
2847    {
2848      norn=numones(L[i],pos(p));
2849      if (nor<norn){nor=norn; i0=i;}
2850    }
2851    W[j0]=i0;
2852    j0++;
2853    p=actualize(p,L[i0]);
2854  }
2855  list LL;
2856  for (i=1;i<=size(W);i++)
2857  {
2858    LL[size(LL)+1]=C[W[i]];
2859  }
2860  return(LL);
2861}
2862
2863// allsheaves
2864// Input: L=((v_11,..,v_1k_1),..,(v_s1,..,v_sk_s))
2865//    where:
2866//    The s lists correspond to the s coefficients of the polynomial f
2867//    (v_i1,..,v_ik_i) correspond to the k_i intvec v_ij of the
2868//    spezializations of the jth rekpresentant (Q,P) of the ith coefficient
2869//    v_ij is an intvec of size equal to the number of little segments
2870//    forming the lpp-segment of 0,1, where 1 represents that it specializes
2871//    to non-zero on the whole little segment and 1 if not.
2872// Output:
2873//    (list LL, list LLS)  where
2874//    LL is the list of all combrep
2875//    LLS is the list of intvec of the corresponding elements of LL
2876proc allsheaves(list L)
2877{
2878  intvec V; list LL; intvec W; int r; intvec U;
2879  int i; int j; int k;
2880  int s=size(L[1][1]); // s = number of little segments of the lpp-segment
2881  list LLS;
2882  for (i=1;i<=size(L);i++)
2883  {
2884    V[i]=size(L[i]);
2885  }
2886  LL=combrep(V);
2887  for (i=1;i<=size(LL);i++)
2888  {
2889    W=LL[i];   // size(W)= number of coefficients of the polynomial
2890    kill U; intvec U;
2891    for (j=1;j<=s;j++)
2892    {
2893      k=1; r=1; U[j]=1;
2894      while((r==1) and (k<=size(W)))
2895      {
2896        if(L[k][W[k]][j]==0){r=0; U[j]=0;}
2897        k++;
2898      }
2899    }
2900    LLS[i]=U;
2901  }
2902  return(list(LL,LLS));
2903}
2904
2905// numones
2906// Input:
2907//   intvec v of (0,1) in each position
2908//   intvec pos: the positions to test
2909// Output:
2910//   int nor: the nuber of 1 of v in the positions given by pos.
2911proc numones(intvec v, intvec pos)
2912{
2913  int i; int n;
2914  for (i=1;i<=size(pos);i++)
2915  {
2916    if (v[pos[i]]==1){n++;}
2917  }
2918  return(n);
2919}
2920
2921// pos
2922// Input:  intvec p of zeros and ones
2923// Output: intvec W of the positions where p has ones.
2924proc pos(intvec p)
2925{
2926  int i;
2927  intvec W; int j=1;
2928  for (i=1; i<=size(p); i++)
2929  {
2930    if (p[i]==1){W[j]=i; j++;}
2931  }
2932  return(W);
2933}
2934
2935// actualize: actualizes zeroes of p
2936// Input:
2937//   intvec p: of zeroes and ones
2938//   intvec c: of zeroes and ones (of the same length)
2939// Output;
2940//   intvec pp: of zeroes and ones, where a 0 stays in pp[i] if either
2941//   already p[i]==0 or c[i]==1.
2942proc actualize(intvec p, intvec c)
2943{
2944  int i; intvec pp=p;
2945  for (i=1;i<=size(p);i++)
2946  {
2947    if ((pp[i]==1) and (c[i]==1)){pp[i]=0;}
2948  }
2949  return(pp);
2950}
2951
2952// combrep
2953// Input: V=(n_1,..,n_i)
2954// Output: L=(v_1,..,v_p) where p=prod_j=1^i (n_j)
2955//    is the list of all intvec v_j=(v_j1,..,v_ji) where 1<=v_jk<=n_i
2956proc combrep(intvec V)
2957{
2958  list L; list LL;
2959  int i; int j; int k;  intvec W;
2960  if (size(V)==1)
2961  {
2962    for (i=1;i<=V[1];i++)
2963    {
2964      L[i]=intvec(i);
2965    }
2966    return(L);
2967  }
2968  for (i=1;i<size(V);i++)
2969  {
2970    W[i]=V[i];
2971  }
2972  LL=combrep(W);
2973  for (i=1;i<=size(LL);i++)
2974  {
2975    W=LL[i];
2976    for (j=1;j<=V[size(V)];j++)
2977    {
2978      W[size(V)]=j;
2979      L[size(L)+1]=W;
2980    }
2981  }
2982  return(L);
2983}
2984
2985proc reducemodN(poly f,ideal E)
2986{
2987  def RR=basering;
2988  setring(@RPt);
2989  def fa=imap(RR,f);
2990  def Ea=imap(RR,E);
2991  attrib(Ea,"isSB",1);
2992  // option(redSB);
2993  // Ea=std(Ea);
2994  fa=reduce(fa,Ea);
2995  setring(RR);
2996  def f1=imap(@RPt,fa);
2997  return(f1);
2998}
2999
3000// intersp: computes the intersection of the ideals in S in @P
3001proc intersp(list S)
3002{
3003  def RR=basering;
3004  setring(@P);
3005  def SP=imap(RR,S);
3006  option(returnSB);
3007  def NP=intersect(SP[1..size(SP)]);
3008  setring(RR);
3009  return(imap(@P,NP));
3010}
3011
3012// radicalmember
3013proc radicalmember(poly f,ideal ida)
3014{
3015  int te;
3016  def RR=basering;
3017  setring(@P);
3018  def fp=imap(RR,f);
3019  def idap=imap(RR,ida);
3020  poly @t;
3021  ring H=0,@t,dp;
3022  def PH=@P+H;
3023  setring(PH);
3024  def fH=imap(@P,fp);
3025  def idaH=imap(@P,idap);
3026  idaH[size(idaH)+1]=1-@t*fH;
3027  option(redSB);
3028  def G=std(idaH);
3029  if (G==1){te=1;} else {te=0;}
3030  setring(RR);
3031  return(te);
3032}
3033
3034// NonNull: returns 1 if the poly f is nonnull on V(E)\V(N), 0 otherwise.
3035proc NonNull(poly f, ideal E, ideal N)
3036{
3037  int te=1; int i;
3038  def RR=basering;
3039  setring(@P);
3040  def fp=imap(RR,f);
3041  def Ep=imap(RR,E);
3042  def Np=imap(RR,N);
3043  ideal H;
3044  ideal Ef=Ep+fp;
3045  for (i=1;i<=size(Np);i++)
3046  {
3047    te=radicalmember(Np[i],Ef);
3048    if (te==0){break;}
3049  }
3050  setring(RR);
3051  return(te);
3052}
3053
3054// selectextendcoef
3055// input:
3056//    matrix CC: CC=(p_a1 .. p_ar_a)
3057//                  (q_a1 .. q_ar_a)
3058//            the matrix of elements of a coefficient in oo[a].
3059//    (ideal ida, ideal idb): the canonical representation of the segment S.
3060// output:
3061//    list caout
3062//            the minimum set of elements of CC needed such that at least one
3063//            of the q's is non-null on S, as well as the C-rep of of the
3064//            points where the q's are null on S.
3065//            The elements of caout are of the form (p,q,prep);
3066proc selectextendcoef(matrix CC, ideal ida, ideal idb)
3067{
3068  def RR=basering;
3069  setring(@P);
3070  def ca=imap(RR,CC);
3071  def E0=imap(RR,ida);
3072  ideal E;
3073  def N=imap(RR,idb);
3074  int r=ncols(ca);
3075  int i; int te=1; list com; int j; int k; intvec c; list prep;
3076  list cs; list caout;
3077  i=1;
3078  while ((i<=r) and (te))
3079  {
3080    com=comb(r,i);
3081    j=1;
3082    while((j<=size(com)) and (te))
3083    {
3084      E=E0;
3085      c=com[j];
3086      for (k=1;k<=i;k++)
3087      {
3088        E=E+ca[2,c[k]];
3089      }
3090      prep=Prep(E,N);
3091      if (i==1)
3092      {
3093        cs[j]=list(ca[1,j],ca[2,j],prep);
3094      }
3095      if ((size(prep)==1) and (equalideals(prep[1][1],ideal(1))))
3096      {
3097        te=0;
3098        for(k=1;k<=size(c);k++)
3099        {
3100          caout[k]=cs[c[k]];
3101        }
3102      }
3103      j++;
3104    }
3105    i++;
3106  }
3107  if (te){"error: extendcoef does not extend to the whole S";}
3108  setring(RR);
3109  return(imap(@P,caout));
3110}
3111
3112// input:
3113//   ideal E1: in some basering (depends only on the parameters)
3114//   ideal E2: in some basering (depends only on the parameters)
3115// output:
3116//   ideal Ep=E1+E2; computed in P
3117proc plusP(ideal E1,ideal E2)
3118{
3119  def RR=basering;
3120  setring(@P);
3121  def E1p=imap(RR,E1);
3122  def E2p=imap(RR,E2);
3123  def Ep=E1p+E2p;
3124  setring(RR);
3125  return(imap(@P,Ep));
3126}
3127
3128// reform
3129// input:
3130//   list combpolys: (v1,..,vs)
3131//      where vi are intvec.
3132//   output outcomb: (w1,..,wt)
3133//      whre wi are intvec.
3134//      All the vi without zeroes are in outcomb, and those with zeroes are
3135//         combined to form new intvec with the rest
3136proc reform(list combpolys, intvec numdens)
3137{
3138  list combp0; list combp1; int i; int j; int k; int l; list rest; intvec notfree;
3139  list free; intvec free1; int te; intvec v;  intvec w;
3140  int nummonoms=size(combpolys[1]);
3141  for(i=1;i<=size(combpolys);i++)
3142  {
3143    if(memberpos(0,combpolys[i])[1])
3144    {
3145      combp0[size(combp0)+1]=combpolys[i];
3146    }
3147    else {combp1[size(combp1)+1]=combpolys[i];}
3148  }
3149  for(i=1;i<=nummonoms;i++)
3150  {
3151    kill notfree; intvec notfree;
3152    for(j=1;j<=size(combpolys);j++)
3153    {
3154      if(combpolys[j][i]<>0)
3155      {
3156        if(notfree[1]==0){notfree[1]=combpolys[j][i];}
3157        else{notfree[size(notfree)+1]=combpolys[j][i];}
3158      }
3159    }
3160    kill free1; intvec free1;
3161    for(j=1;j<=numdens[i];j++)
3162    {
3163      if(memberpos(j,notfree)[1]==0)
3164      {
3165        if(free1[1]==0){free1[1]=j;}
3166        else{free1[size(free1)+1]=j;}
3167      }
3168      free[i]=free1;
3169    }
3170  }
3171  list amplcombp; list aux;
3172  for(i=1;i<=size(combp0);i++)
3173  {
3174    v=combp0[i];
3175    kill amplcombp; list amplcombp;
3176    amplcombp[1]=intvec(v[1]);
3177    for(j=2;j<=size(v);j++)
3178    {
3179      if(v[j]!=0)
3180      {
3181        for(k=1;k<=size(amplcombp);k++)
3182        {
3183          w=amplcombp[k];
3184          w[size(w)+1]=v[j];
3185          amplcombp[k]=w;
3186        }
3187      }
3188      else
3189      {
3190        kill aux; list aux;
3191        for(k=1;k<=size(amplcombp);k++)
3192        {
3193          for(l=1;l<=size(free[j]);l++)
3194          {
3195            w=amplcombp[k];
3196            w[size(w)+1]=free[j][l];
3197            aux[size(aux)+1]=w;
3198          }
3199        }
3200        amplcombp=aux;
3201      }
3202    }
3203    for(j=1;j<=size(amplcombp);j++)
3204    {
3205      combp1[size(combp1)+1]=amplcombp[j];
3206    }
3207  }
3208  return(combp1);
3209}
3210
3211// nonnullCrep
3212proc nonnullCrep(poly f0,ideal ida0,ideal idb0)
3213{
3214  int i;
3215  def RR=basering;
3216  setring(@P);
3217  def f=imap(RR,f0);
3218  def ida=imap(RR,ida0);
3219  def idb=imap(RR,idb0);
3220  def idaf=ida+f;
3221  int te=1;
3222  for(i=1;i<=size(idb);i++)
3223  {
3224    if(radicalmember(idb[i],idaf)==0)
3225    {
3226      te=0; break;
3227    }
3228  }
3229  setring(RR);
3230  return(te);
3231}
3232
3233// precombint
3234// input:  L: list of ideals (works in @P)
3235// output: F0: ideal of polys. F0[i] is a poly in the intersection of
3236//             all ideals in L except in the ith one, where it is not.
3237//             L=(p1,..,ps);  F0=(f1,..,fs);
3238//             F0[i] \in intersect_{j#i} p_i
3239proc precombint(list L)
3240{
3241  int i; int j; int tes;
3242  def RR=basering;
3243  setring(@P);
3244  list L0; list L1; list L2; list L3; ideal F;
3245  L0=imap(RR,L);
3246  L1[1]=L0[1]; L2[1]=L0[size(L0)];
3247  for (i=2;i<=size(L0)-1;i++)
3248  {
3249    L1[i]=intersect(L1[i-1],L0[i]);
3250    L2[i]=intersect(L2[i-1],L0[size(L0)-i+1]);
3251  }
3252  L3[1]=L2[size(L2)];
3253  for (i=2;i<=size(L0)-1;i++)
3254  {
3255    L3[i]=intersect(L1[i-1],L2[size(L0)-i]);
3256  }
3257  L3[size(L0)]=L1[size(L1)];
3258  for (i=1;i<=size(L3);i++)
3259  {
3260    option(redSB); L3[i]=std(L3[i]);
3261  }
3262  for (i=1;i<=size(L3);i++)
3263  {
3264    tes=1; j=0;
3265    while((tes) and (j<size(L3[i])))
3266    {
3267      j++;
3268      option(redSB);
3269      L0[i]=std(L0[i]);
3270      if(reduce(L3[i][j],L0[i])!=0){tes=0; F[i]=L3[i][j];}
3271    }
3272    if (tes){"ERROR a polynomial in all p_j except p_i was not found";}
3273  }
3274  setring(RR);
3275  def F0=imap(@P,F);
3276  return(F0);
3277}
3278
3279// precombinediscussion
3280// not used, can be deleted
3281// input:  list L: the LCU segment with bases for each pi component
3282// output: intvec vv:  vv[1]=(1 if the generic polynomial of the vv[2]
3283//                     component already specializes well,
3284//                     0 if combine is to be used)
3285//                     vv[2]=selind, the index for which the generic basis
3286//                     already specializes well if combine is not to be used (vv[1]=1).
3287proc precombinediscussion(L,crep)
3288{
3289  int tes=1; int selind; int i1; int j1; poly p; poly lcp; intvec vv;
3290  if (size(L)==1){vv=1,1; return(vv);}
3291  for (i1=1;i1<=size(L);i1++)
3292  {
3293    tes=1;
3294    p=L[i1][2];
3295    lcp=leadcoef(p);
3296
3297
3298    if(nonnullCrep(lcp,crep[1],crep[2]))
3299    {
3300      for(j1=1;j1<=size(L);j1++)
3301      {
3302        if(i1!=j1)
3303        {
3304          if(specswellCrep(p,L[j1][2],L[j1][1])==0){tes=0; break;}
3305        }
3306      }
3307    }
3308    else{tes=0;}
3309    if(tes){selind=i1; break;}
3310  }
3311  vv=tes,selind;
3312  return(vv);
3313}
3314
3315// minAssGTZ eliminating denominators
3316proc minGTZ(ideal N);
3317{
3318  int i; int j;
3319  def L=minAssGTZ(N);
3320  for(i=1;i<=size(L);i++)
3321  {
3322    for(j=1;j<=size(L[i]);j++)
3323    {
3324      L[i][j]=cleardenom(L[i][j]);
3325    }
3326  }
3327  return(L);
3328}
3329
3330//********************* Begin KapurSunWang *************************
3331
3332// inconsistent
3333// Input:
3334//   ideal E: of null conditions
3335//   ideal N: of non-null conditions representing V(E)\V(N)
3336// Output:
3337//   1 if V(E) \V(N) = empty
3338//   0 if not
3339proc inconsistent(ideal E, ideal N)
3340{
3341  int j;
3342  int te=1;
3343  def R=basering;
3344  setring(@P);
3345  def EP=imap(R,E);
3346  def NP=imap(R,N);
3347  poly @t;
3348  ring H=0,@t,dp;
3349  def RH=@P+H;
3350  setring(RH);
3351  def EH=imap(@P,EP);
3352  def NH=imap(@P,NP);
3353  ideal G;
3354  j=1;
3355  while((te==1) and j<=size(NH))
3356  {
3357    G=EH+(1-@t*NH[j]);
3358    option(redSB);
3359    G=std(G);
3360    if (G[1]!=1){te=0;}
3361    j++;
3362  }
3363  setring(R);
3364  return(te);
3365}
3366
3367// MDBasis: Minimal Dickson Basis
3368proc MDBasis(ideal G)
3369{
3370  int i; int j; int te=1;
3371  G=sortideal(G);
3372  ideal MD=G[1];
3373  poly lm;
3374  for (i=2;i<=size(G);i++)
3375  {
3376    te=1;
3377    lm=leadmonom(G[i]);
3378    j=1;
3379    while ((te==1) and (j<=size(MD)))
3380    {
3381      if (lm/leadmonom(MD[j])!=0){te=0;}
3382      j++;
3383    }
3384    if (te==1)
3385    {
3386      MD[size(MD)+1]=(G[i]);
3387    }
3388  }
3389  return(MD);
3390}
3391
3392// primepartZ
3393proc primepartZ(poly f);
3394{
3395  def R=basering;
3396  def cp=content(f);
3397  def fp=f/cp;
3398  return(fp);
3399}
3400
3401// LCMLC
3402proc LCMLC(ideal H)
3403{
3404  int i;
3405  def R=basering;
3406  setring(@RP);
3407  def HH=imap(R,H);
3408  poly h=1;
3409  for (i=1;i<=size(HH);i++)
3410  {
3411    h=lcm(h,HH[i]);
3412  }
3413  setring(R);
3414  def hh=imap(@RP,h);
3415  return(hh);
3416}
3417
3418// KSW: Kapur-Sun-Wang algorithm for computing a CGS
3419// Input:
3420//   F:   parametric ideal to be discussed
3421//   Options:
3422//     \"out\",0 Transforms the description of the segments into
3423//     canonical P-representation form.
3424//     \"out\",1 Original KSW routine describing the segments as
3425//     difference of varieties
3426//   The ideal must be defined on C[parameters][variables]
3427// Output:
3428//   With option \"out\",0 :
3429//     ((lpp,
3430//       (1,B,((p_1,(p_11,..,p_1k_1)),..,(p_s,(p_s1,..,p_sk_s)))),
3431//       string(lpp)
3432//      )
3433//      ,..,
3434//      (lpp,
3435//       (k,B,((p_1,(p_11,..,p_1k_1)),..,(p_s,(p_s1,..,p_sk_s)))),
3436//       string(lpp))
3437//      )
3438//     )
3439//   With option \"out\",1 ((default, original KSW) (shorter to be computed,
3440//                    but without canonical description of the segments.
3441//     ((B,E,N),..,(B,E,N))
3442proc KSW(ideal F, list #)
3443{
3444  setglobalrings();
3445  int start=timer;
3446  ideal E=ideal(0);
3447  ideal N=ideal(1);
3448  int comment=0;
3449  int out=1;
3450  int i;
3451  def L=#;
3452  if (size(L)>0)
3453  {
3454    for (i=1;i<=size(L) div 2;i++)
3455    {
3456      if (L[2*i-1]=="null"){E=L[2*i];}
3457      else
3458      {
3459        if (L[2*i-1]=="nonnull"){N=L[2*i];}
3460        else
3461        {
3462          if (L[2*i-1]=="comment"){comment=L[2*i];}
3463          else
3464          {
3465            if (L[2*i-1]=="out"){out=L[2*i];}
3466          }
3467        }
3468      }
3469    }
3470  }
3471  if (comment>0){string("Begin KSW with null = ",E," nonnull = ",N);}
3472  def CG=KSW0(F,E,N,comment);
3473  if (comment>0)
3474  {
3475    string("Number of segments in KSW (total) = ",size(CG));
3476    string("Time in KSW = ",timer-start);
3477  }
3478  if(out==0)
3479  {
3480    CG=KSWtocgsdr(CG);
3481    CG=groupKSWsegments(CG);
3482    if (comment>0)
3483    {
3484      string("Number of lpp segments = ",size(CG));
3485      string("Time in KSW + group + Prep = ",timer-start);
3486    }
3487  }
3488  if(defined(@P)){kill @P; kill @R; kill @RP;}
3489  return(CG);
3490}
3491
3492// sqf
3493// This is for releases of Singular before 3-5-1
3494// proc sqf(poly f)
3495// {
3496//  def RR=basering;
3497//  setring(@P);
3498//  def ff=imap(RR,f);
3499//  def G=sqrfree(ff);
3500//  poly fff=1;
3501//  int i;
3502//  for (i=1;i<=size(G);i++)
3503//  {
3504//    fff=fff*G[i];
3505//  }
3506//  setring(RR);
3507//   def ffff=imap(@P,fff);
3508//   return(ffff);
3509// }
3510
3511// sqf
3512proc sqf(poly f)
3513{
3514  def RR=basering;
3515  setring(@P);
3516  def ff=imap(RR,f);
3517  poly fff=sqrfree(ff,3);
3518  setring(RR);
3519  def ffff=imap(@P,fff);
3520  return(ffff);
3521}
3522
3523
3524// KSW0: Kapur-Sun-Wang algorithm for computing a CGS, called by KSW
3525// Input:
3526//   F:   parametric ideal to be discussed
3527//   Options:
3528//   The ideal must be defined on C[parameters][variables]
3529// Output:
3530proc KSW0(ideal F, ideal E, ideal N, int comment)
3531{
3532  def R=basering;
3533  int i; int j; list emp;
3534  list CGS;
3535  ideal N0;
3536  for (i=1;i<=size(N);i++)
3537  {
3538    N0[i]=sqf(N[i]);
3539  }
3540  ideal E0;
3541  for (i=1;i<=size(E);i++)
3542  {
3543    E0[i]=sqf(leadcoef(E[i]));
3544  }
3545  setring(@P);
3546  ideal E1=imap(R,E0);
3547  E1=std(E1);
3548  ideal N1=imap(R,N0);
3549  N1=std(N1);
3550  setring(R);
3551  E0=imap(@P,E1);
3552  N0=imap(@P,N1);
3553//   E0=elimrepeated(E0);
3554//   N0=elimrepeated(N0);
3555  if (inconsistent(E0,N0)==1)
3556  {
3557    return(emp);
3558  }
3559  setring(@RP);
3560  def FRP=imap(R,F);
3561  def ERP=imap(R,E);
3562  FRP=FRP+ERP;
3563  option(redSB);
3564  def GRP=std(FRP);
3565  setring(R);
3566  def G=imap(@RP,GRP);
3567  if (memberpos(1,G)[1]==1)
3568  {
3569    if(comment>1){"Basis 1 is found"; E; N;}
3570    return(E0,N0,ideal(1));
3571  }
3572  ideal Gr; ideal Gm; ideal GM;
3573  for (i=1;i<=size(G);i++)
3574  {
3575    if (variables(G[i])[1]==0){Gr[size(Gr)+1]=G[i];}
3576    else{Gm[size(Gm)+1]=G[i];}
3577  }
3578  ideal Gr0;
3579  for (i=1;i<=size(Gr);i++)
3580  {
3581    Gr0[i]=sqf(Gr[i]);
3582  }
3583
3584
3585  Gr=elimrepeated(Gr0);
3586  ideal GrN;
3587  for (i=1;i<=size(Gr);i++)
3588   {
3589    for (j=1;j<=size(N0);j++)
3590    {
3591      GrN[size(GrN)+1]=sqf(Gr[i]*N0[j]);
3592    }
3593  }
3594  if (inconsistent(E,GrN)){;}
3595  else
3596  {
3597    if(comment>1){"Basis 1 is found in a branch with arguments"; E; GrN;}
3598    CGS[size(CGS)+1]=list(E,GrN,ideal(1));
3599  }
3600  if (inconsistent(Gr,N0)){return(CGS);}
3601  GM=Gm;
3602  Gm=MDBasis(Gm);
3603  ideal H;
3604  for (i=1;i<=size(Gm);i++)
3605  {
3606    H[i]=sqf(leadcoef(Gm[i]));
3607  }
3608  H=facvar(H);
3609  poly h=sqf(LCMLC(H));
3610  if(comment>1){"H = "; H; "h = "; h;}
3611  ideal Nh=N0;
3612  if(size(N0)==0){Nh=h;}
3613  else
3614  {
3615    for (i=1;i<=size(N0);i++)
3616    {
3617      Nh[i]=sqf(N0[i]*h);
3618    }
3619  }
3620  if (inconsistent(Gr,Nh)){;}
3621  else
3622  {
3623    CGS[size(CGS)+1]=list(Gr,Nh,Gm);
3624  }
3625  poly hc=1;
3626  list KS;
3627  ideal GrHi;
3628  for (i=1;i<=size(H);i++)
3629  {
3630    kill GrHi;
3631    ideal GrHi;
3632    Nh=N0;
3633    if (i>1){hc=sqf(hc*H[i-1]);}
3634    for (j=1;j<=size(N0);j++){Nh[j]=sqf(N0[j]*hc);}
3635    if (equalideals(Gr,ideal(0))==1){GrHi=H[i];}
3636    else {GrHi=Gr,H[i];}
3637//     else {for (j=1;j<=size(Gr);j++){GrHi[size(GrHi)+1]=Gr[j]*H[i];}}
3638    if(comment>1){"Call to KSW with arguments "; GM; GrHi;  Nh;}
3639    KS=KSW0(GM,GrHi,Nh,comment);
3640    for (j=1;j<=size(KS);j++)
3641    {
3642      CGS[size(CGS)+1]=KS[j];
3643    }
3644    if(comment>1){"CGS after KSW = "; CGS;}
3645  }
3646  return(CGS);
3647}
3648
3649// KSWtocgsdr
3650proc KSWtocgsdr(list L)
3651{
3652  int i; list CG; ideal B; ideal lpp; int j; list NKrep;
3653  for(i=1;i<=size(L);i++)
3654  {
3655    B=redgbn(L[i][3],L[i][1],L[i][2]);
3656    lpp=ideal(0);
3657    for(j=1;j<=size(B);j++)
3658    {
3659      lpp[j]=leadmonom(B[j]);
3660    }
3661    NKrep=KtoPrep(L[i][1],L[i][2]);
3662    CG[i]=list(lpp,B,NKrep);
3663  }
3664  return(CG);
3665}
3666
3667// KtoPrep
3668// Computes the P-representaion of a K-representation (N,W) of a set
3669// input:
3670//    ideal E (null conditions)
3671//    ideal N (non-null conditions ideal)
3672// output:
3673//    the ((p_1,(p_11,..,p_1k_1)),..,(p_r,(p_r1,..,p_rk_r)));
3674//    the Prep of V(N) \ V(W)
3675proc KtoPrep(ideal N, ideal W)
3676{
3677  int i; int j;
3678  if (N[1]==1)
3679  {
3680    L0[1]=list(ideal(1),list(ideal(1)));
3681    return(L0);
3682  }
3683  def RR=basering;
3684  setring(@P);
3685  ideal B; int te; poly f;
3686  ideal Np=imap(RR,N);
3687  ideal Wp=imap(RR,W);
3688  list L;
3689  list L0; list T0;
3690  L0=minGTZ(Np);
3691  for(j=1;j<=size(L0);j++)
3692  {
3693    option(redSB);
3694    L0[j]=std(L0[j]);
3695  }
3696  for(i=1;i<=size(L0);i++)
3697  {
3698    if(inconsistent(L0[i],Wp)==0)
3699    {
3700      B=L0[i]+Wp;
3701      T0=minGTZ(B);
3702      option(redSB);
3703      for(j=1;j<=size(T0);j++)
3704      {
3705        T0[j]=std(T0[j]);
3706      }
3707      L[size(L)+1]=list(L0[i],T0);
3708    }
3709  }
3710  setring(RR);
3711  def LL=imap(@P,L);
3712  return(LL);
3713}
3714
3715// groupKSWsegments
3716// input:  the list of vertices of KSW
3717// output: the same terminal vertices grouped by lpp
3718proc groupKSWsegments(list T)
3719{
3720  int i; int j;
3721  list L;
3722  list lpp; list lppor;
3723  list kk;
3724  lpp[1]=T[1][1]; j=1;
3725  lppor[1]=intvec(1);
3726  for(i=2;i<=size(T);i++)
3727  {
3728    kk=memberpos(T[i][1],lpp);
3729    if(kk[1]==0){j++; lpp[j]=T[i][1]; lppor[j]=intvec(i);}
3730    else{lppor[kk[2]][size(lppor[kk[2]])+1]=i;}
3731  }
3732  list ll;
3733  for (j=1;j<=size(lpp);j++)
3734  {
3735    kill ll; list ll;
3736    for(i=1;i<=size(lppor[j]);i++)
3737    {
3738      ll[size(ll)+1]=list(i,T[lppor[j][i]][2],T[lppor[j][i]][3]);
3739    }
3740    L[j]=list(lpp[j],ll,string(lpp[j]));
3741  }
3742  return(L);
3743}
3744
3745//********************* End KapurSunWang *************************
3746
3747//******************** Begin locus ******************************
3748
3749
3750// indepparameters
3751// Auxiliary routine to detect "Special" components of the locus
3752// Input: ideal B
3753// Output:
3754//   1 if the solutions of the ideal do not depend on the parameters
3755//   0 if they depend
3756proc indepparameters(ideal B)
3757{
3758  def R=basering;
3759  ideal v=variables(B);
3760  setring @RP;
3761  def BP=imap(R,B);
3762  def vp=imap(R,v);
3763  ideal varpar=variables(BP);
3764  int te;
3765  te=equalideals(vp,varpar);
3766  setring(R);
3767  if(te){return(1);}
3768  else{return(0);}
3769}
3770
3771
3772// dimP0: Auxiliar routine
3773// if the dimension in @P of an ideal in the parameters has dimension 0 then it returns 0
3774// else it retuns 1
3775proc dimP0(ideal N)
3776{
3777  def R=basering;
3778  setring(@P);
3779  int te=1;
3780  def NP=imap(R,N);
3781  attrib(NP,"IsSB",1);
3782  int d=dim(std(NP));
3783  if(d==0){te=0;}
3784  setring(R);
3785  return(te);
3786}
3787
3788// Auxiliar routine.
3789// input:    ideals E and F (assumed in ring @P
3790// returns: 1 if ideal E is contained in ideal F (assumed F is std basis)
3791//              0 if not
3792proc containedideal(ideal E, ideal F)
3793{
3794  int i; int t; poly f;
3795  if(equalideals(F,ideal(0)))
3796  {
3797    if(equalideals(E,ideal(0))==0){return(0);}
3798    else(return(1));
3799  }
3800  t=1; i=1;
3801  while((t==1) and (i<=size(E)))
3802  {
3803    attrib(F,"isSB",1);
3804    f=reduce(E[i],F);
3805    if(f!=0){t=0;}
3806    i++;
3807  }
3808  return(t);
3809}
3810
3811// AddCons: given a set of locally closed components of a selection of
3812//       segments of the Grobner cover, it builds the canonical P-representation
3813//       of the corresponding constructible set, including levels it they are
3814// input: a list L of a selection of segments of the Groebner cover
3815//       given a a set of components of the form
3816//       ( (p_1,(p_11,..,p_1k_1).. (p_s,(p_s1,..,p_sk_s))
3817// output: The canonical P-representation of adding the given components.
3818proc AddCons(list L)
3819{
3820  // First step: Selecting the top varieties
3821  list L1; list L2; list LL; int i; int j; int t;
3822  list Lend;
3823  for(i=1;i<=size(L);i++)
3824  {
3825    t=1;
3826    for(j=1;j<=size(L);j++)
3827    {
3828      if(i!=j)
3829      {
3830        if(containedideal(L[j][1],L[i][1])==1)
3831        {t=0;
3832         // "the ideal "; L[j][1]; "is contained in ideal "; L[i][1];
3833          j=size(L);
3834        }
3835      }
3836    }
3837    if(t==1){L1[size(L1)+1]=L[i];}
3838    else{L2[size(L2)+1]=L[i];}
3839  }
3840  // Second step: Adding segments to obtain a locally closed sets for each level
3841  int lev=1;
3842  if(size(L2)==0)
3843  {
3844     for(i=1;i<=size(L1);i++)
3845     {
3846       if(size(L1[i])>=3)
3847       {L1[i][3]=string(string(L1[i][3]),",",lev);}
3848       else{L1[i][3]=string(lev);}
3849     }
3850   return(L1);
3851  }
3852   while(size(L2)>0)
3853   {
3854     LL=addtolocalclosed(L1,L2);
3855     for(i=1;i<=size(LL[1]);i++)
3856     {
3857       if(size(LL[1][i])>=3)
3858       {LL[1][i][3]=string(string(LL[1][i][3]),",",lev);}
3859       else{LL[1][i][3]=string(lev);}
3860       Lend[size(Lend)+1]=LL[1][i];
3861     }
3862     L2=LL[2];
3863     lev++;
3864   }
3865   return(Lend);
3866}
3867
3868// input: Two lists of P-components to be added.
3869//           L1 contains the top components, and L2 the remaining components
3870//           each of the form ( (p_1,(p_11,..,p_1k_1).. (p_s,(p_s1,..,p_sk_s))
3871// output: A list of two lists:
3872//           The first one contains the P-representation of the top components added
3873//           The second contains the components that have not yet been added when
3874//           the total subset is not locally closed. If so addtolocalclosed is to be called
3875//           at new after separating the new top and remaining components in order
3876//           to compute the next level of the constructible set.
3877//           The input and the output must be in the ring @P of parameters.
3878proc  addtolocalclosed(list L1,list L2)
3879{
3880   // Second step: Adding segments to obtain a locally closed set
3881   // L1 contains the top components (ideals and descendants)
3882   // L2 contains the nontop components (ideals and descendants)
3883   list LL; int i; int j; int t; intvec Added; int mesvoltes=1; intvec alreadyadded; list LN;
3884   int k; int l; int m; ideal top; ideal hole; ideal nhole; intvec nottoadd; int t0; list h;
3885   LL=L1;
3886   LN=L2;
3887   while(mesvoltes)
3888   {
3889     //"volta";
3890     for(i=1;i<=size(L1);i++)
3891     {
3892        Added=Added,alreadyadded;
3893        Added=sort(elimrepeatedvl(Added))[1];
3894        kill alreadyadded; intvec alreadyadded;
3895        top=LL[i][1][1];
3896        j=1;
3897        while(j<=size(LL[i][2]))
3898        {
3899           kill nottoadd; intvec nottoadd;
3900           hole=LL[i][2][j];
3901           t0=1;
3902           k=1;
3903           while(t0 and k<=size(LN))
3904           {
3905              if (equalideals(hole,LN[k][1])==1)
3906              {
3907                 t0=0;
3908                  if(alreadyadded==intvec(0)){alreadyadded[1]=k;}
3909                 else{alreadyadded[size(alreadyadded)+1]=k;}
3910                 LL[i][2]=elimfromlist(LL[i][2],j);
3911                 j=j-1;
3912                 for(l=1;l<=size(LN[k][2]);l++)
3913                 {
3914                   nhole=LN[k][2][l],LL[i][1];
3915                   nhole=std(nhole);
3916                   t=1; m=1;
3917                    while(t and m<=size(LL[i][2]))
3918                    {
3919                       if(containedideal(LL[i][2][m],nhole)==1)
3920                       {
3921                         t=0;
3922                       }
3923                       m++;
3924                    }
3925                    if(t==0){nottoadd[size(nottoadd)+1]=l;}
3926                  }
3927                 for(m=1;m<=size(LN[k][2]);m++)
3928                 {
3929                     if(memberpos(m,nottoadd)[1]==0)
3930                    {
3931                       LL[i][2][size(LL[i][2])+1]=LN[k][2][m];
3932                    }
3933                 }
3934              }
3935              k++;
3936
3937           }
3938           j++;
3939        }
3940        if(size(LL[i][2])==0 and size(LL[i][1])>0){LL[i][2][1]=ideal(1);}
3941     }
3942     h=1,1;
3943     while((h[1]==1) and (alreadyadded!=intvec(0)))
3944     {
3945       h=memberpos(0,alreadyadded);
3946       if(h[1]==1){alreadyadded=elimfromlist(alreadyadded,h[2]);}
3947     }
3948     if(alreadyadded!=intvec(0))
3949     {alreadyadded=sort(elimrepeatedvl(alreadyadded))[1];}
3950     if(Added==intvec(0)){Added=alreadyadded;}
3951     else{
3952       Added=Added,alreadyadded;
3953       Added=sort(elimrepeatedvl(Added))[1];
3954     }
3955     h=1,1;
3956     while((h[1]==1) and (Added!=intvec(0)))
3957     {
3958       h=memberpos(0,Added);
3959       if(h[1]==1){Added=elimfromlist(Added,h[2]);}
3960     }
3961     if (alreadyadded==intvec(0))
3962     {
3963       mesvoltes=0;
3964     }
3965  }
3966  if(Added!=intvec(0)){Added=sort(elimrepeatedvl(Added))[1]; }
3967  if(Added!=intvec(0))
3968  {
3969    for(i=1;i<=size(Added);i++)
3970    {
3971      if(size(LN)>0){LN=elimfromlist(LN,Added[size(Added)+1-i]);}
3972    }
3973  }
3974  for (i=1;i<=size(LL);i++)
3975  {
3976    for(j=1;j<=size(LL[i][2]);j++)
3977    {
3978      hole=LL[i][2][j];
3979      for (k=1;k<=size(LL);k++)
3980      {
3981        if(k!=i)
3982        {
3983          if(containedideal(LL[k][1],hole))
3984          {
3985            LL[i][2]=elimfromlist(LL[i][2],j);
3986            for(l=1;l<=size(LL[k][2]);l++)
3987            {
3988              nhole=hole,LL[k][2][l];
3989              nhole=std(nhole);
3990              if(equalideals(nhole,ideal(1))==0)
3991              {
3992                m=1; t=1;
3993                while(t and m<size(LL[i][2]))
3994                {
3995                  if(containedideal(LL[i][2][m],nhole)){t=0;}
3996                  m++;
3997                }
3998                if(t==1){LL[i][2][size(LL[i][2])+1]=nhole;}
3999              }
4000            }
4001          }
4002        }
4003      }
4004    }
4005  }
4006  LL[1]=LL; LL[2]=LN;
4007  return(LL);
4008}
4009
4010// locus(G):  Special routine for determining the locus of points
4011//                of  objects. Given a parametric ideal J with
4012//                parameters (a_1,..a_m) and variables (x_1,..,xn),
4013//                representing the system determining
4014//                the locus of points (a_1,..,a_m)) who verify certain
4015//                properties, computing the grobcov G of
4016//                J and applying to it locus, determines the different
4017//                classes of locus components. They can be
4018//                Normal, Special, Accumulation point, Degenerate.
4019//                The output are the components given in P-canonical form
4020//                of at most 4 constructible sets: Normal, Special, Accumulation,
4021//                Degenerate.
4022//                The description of the algorithm and definitions will be
4023//                given in a forthcoming paper by Abanades, Botana, Montes Recio.
4024
4025// input:      The output G of the grobcov (in generic representation, which is the default)
4026// output:
4027//         list, the canonical P-representation of the Normal and Non-Normal locus:
4028//              The Normal locus has two kind of components: Normal and Special.
4029//              The Non-normal locus has two kind of components: Accumulation and Degenerate.
4030//              Normal components: for each point in the component,
4031//              the number of solutions in the variables is finite, and
4032//              the solutions depend on the point in the component if the component is not 0-dimensional.
4033//              Special components:  for each point in the component,
4034//              the number of solutions in the variables is finite,
4035//              the component is not 0-dimensional, but the solutions do not depend on the
4036//              values of the parameters in the component.
4037//              Accumlation points: are 0-dimensional components for which it exist
4038//              an infinite number of solutions.
4039//              Degenerate components: are components of dimension greater than 0 for which
4040//              for every point in the component there exist infinite solutions.
4041//         The output components are given as
4042//              ((p1,(p11,..p1s_1),type_1,level_1),..,(pk,(pk1,..pks_k),type_k,level_k)
4043//         The components are given in canonical P-representation of the subset.
4044//              If all levels of a class of locus are 1, then the set is locally closed. Otherwise the level
4045//              gives the depth of the component.
4046proc locus(list GG)
4047"USAGE:   locus(G);
4048               The input must be the grobcov  of a parametrical ideal
4049RETURN:  The  locus.
4050               The output are the components of two constructible subsets of the locus
4051               of the parametrical system.: Normal and Non-normal.
4052               These components are
4053               given as a list of  (pi,(pi1,..pis_i),type_i,level_i) varying i,
4054               where the p's are prime ideals, the type can be: Normal, Special,
4055               Accumulation, Degenerate.
4056NOTE:      It can only be called after computing the grobcov of the
4057               parametrical ideal in generic representation ('ext',0),
4058               which is the default.
4059               The basering R, must be of the form Q[a_1,..,a_m][x_1,..,x_n].
4060KEYWORDS: geometrical locus, locus, loci.
4061EXAMPLE:  locus; shows an example"
4062{
4063  int t1=1; int t2=1;
4064  def R=basering;
4065  setglobalrings();
4066  list G1; list G2;
4067  def G=GG;
4068  int i; int d; int j; int k;
4069  t1=1;
4070  for(i=1;i<=size(G);i++)
4071  {
4072    attrib(G[i][1],"IsSB",1);
4073    d=dim(std(G[i][1]));
4074    if(d==0){G1[size(G1)+1]=G[i];}
4075    else
4076    {
4077      if(d>0){G2[size(G2)+1]=G[i];}
4078    }
4079  }
4080  if(size(G1)==0){t1=0;}
4081  if(size(G2)==0){t2=0;}
4082  setring(@RP);
4083  if(t1)
4084  {
4085    list G1RP=imap(R,G1);
4086  }
4087  else {list G1RP;}
4088  list P1RP;
4089  ideal B;
4090  for(i=1;i<=size(G1RP);i++)
4091  {
4092     kill B;
4093     ideal B;
4094     for(k=1;k<=size(G1RP[i][3]);k++)
4095     {
4096       attrib(G1RP[i][3][k][1],"IsSB",1);
4097       G1RP[i][3][k][1]=std(G1RP[i][3][k][1]);
4098       for(j=1;j<=size(G1RP[i][2]);j++)
4099       {
4100         B[j]=reduce(G1RP[i][2][j],G1RP[i][3][k][1]);
4101       }
4102       P1RP[size(P1RP)+1]=list(G1RP[i][3][k][1],G1RP[i][3][k][2],B);
4103     }
4104  }
4105  setring(R);
4106  ideal h;
4107  if(t1)
4108  {
4109    def P1=imap(@RP,P1RP);
4110    for(i=1;i<=size(P1);i++)
4111    {
4112      for(j=1;j<=size(P1[i][3]);j++)
4113      {
4114        h=factorize(P1[i][3][j],1);
4115        P1[i][3][j]=h[1];
4116        for(k=2;k<=size(h);k++)
4117        {
4118          P1[i][3][j]=P1[i][3][j]*h[k];
4119        }
4120        //P1[i][3][j]=normalize(P1[i][3][j]);
4121      }
4122    }
4123  }
4124  else{list P1;}
4125  for(i=1;i<=size(P1);i++)
4126  {
4127    if (indepparameters(P1[i][3])==1){P1[i][3]="Special";}
4128    else{P1[i][3]="Normal";}
4129  }
4130  list P2;
4131  for(i=1;i<=size(G2);i++)
4132  {
4133    for(k=1;k<=size(G2[i][3]);k++)
4134    {
4135      P2[size(P2)+1]=list(G2[i][3][k][1],G2[i][3][k][2]);
4136    }
4137  }
4138  setring @P;
4139  // CANVIAR
4140  if(t1==1)
4141  {
4142    def C1=imap(R,P1);
4143    def L1=AddCons(C1);
4144   }
4145  else{list C1; list L1; kill P1; list P1;}
4146  if(t2==1)
4147  {
4148    def C2=imap(R,P2);
4149    def L2=AddCons(C2);
4150  }
4151  else{list L2; list C2; kill P2; list P2;}
4152    for(i=1;i<=size(L2);i++)
4153    {
4154      d=dim(std(L2[i][1]));
4155      if(d==0)
4156      {
4157        L2[i][3]=string("Accumulation,",L2[i][3]);
4158      }
4159      else{L2[i][3]=string("Degenerate,",L2[i][3]);}
4160    }
4161  list LN;
4162  if(t1==1)
4163  {
4164    for(i=1;i<=size(L1);i++){LN[size(LN)+1]=L1[i];}
4165  }
4166  if(t2==1)
4167  {
4168    for(i=1;i<=size(L2);i++){LN[size(LN)+1]=L2[i];}
4169  }
4170  setring(R);
4171  def L=imap(@P,LN);
4172  for(i=1;i<=size(L);i++){if(size(L[i][2])==0){L[i][2]=ideal(1);}}
4173  kill @R; kill @RP; kill @P;
4174  return(L);
4175}
4176example
4177{"EXAMPLE:"; echo = 2;
4178  ring R=(0,a,b),(x,y),dp;
4179  short=0;
4180  "Concoid";
4181  ideal S96=x^2+y^2-4,(b-2)*x-a*y+2*a,(a-x)^2+(b-y)^2-1;
4182  "System="; S96; " ";
4183  locus(grobcov(S96));
4184}
4185
4186
4187// locusto: Transforms the output of locus to a string that
4188//      can be read by different computational systems.
4189// input:
4190//     list L: The output of locus
4191// output:
4192//     string s: The output of locus converted to a string readable by other programs
4193proc locusto(list L)
4194"USAGE:   locusto(G);
4195          The argument must be the output of locus of a parametrical ideal
4196          It transforms the output into a string in standard form
4197          readable in many languages (Geogebra).
4198
4199RETURN: The locus in string standard form
4200NOTE:     It can only be called after computing the locus(grobcov(F)) of the
4201              parametrical ideal.
4202              The basering R, must be of the form Q[a,b,..][x,y,..].
4203KEYWORDS: geometrical locus, locus, loci.
4204EXAMPLE:  locusto; shows an example"
4205{
4206  int i; int j; int k;
4207  string s;
4208  s="[";
4209  ideal p;
4210  ideal q;
4211  for(i=1;i<=size(L);i++)
4212  {
4213    s=string(s,"[[");
4214    for (j=1;j<=size(L[i][1]);j++)
4215    {
4216      s=string(s,L[i][1][j],",");
4217    }
4218    s[size(s)]="]";
4219    s=string(s,",[");
4220    for(j=1;j<=size(L[i][2]);j++)
4221    {
4222      s=string(s,"[");
4223      for(k=1;k<=size(L[i][2][j]);k++)
4224      {
4225        s=string(s,L[i][2][j][k],",");
4226      }
4227      s[size(s)]="]";
4228      s=string(s,",");
4229    }
4230    s[size(s)]="]";
4231    s=string(s,"]");
4232    if(size(L[i])>=3)
4233    {
4234      s[size(s)]=",";
4235      s=string(s,string(L[i][3]),"]");
4236    }
4237    if(size(L[i])>=4)
4238    {
4239      s[size(s)]=",";
4240      s=string(s,string(L[i][4]),"],");
4241    }
4242    s[size(s)]="]";
4243    s=string(s,",");
4244  }
4245  s[size(s)]="]";
4246  return(s);
4247}
4248example
4249{"EXAMPLE:"; echo = 2;
4250  ring R=(0,a,b),(x,y),dp;
4251  short=0;
4252  ideal S96=x^2+y^2-4,(b-2)*x-a*y+2*a,(a-x)^2+(b-y)^2-1;
4253  "System="; S96; " ";
4254  locusto(locus(grobcov(S96)));
4255}
4256
4257// locusdg is the routine for computing the locus in dinamical geometry.
4258//    It detects automatically a possible point that is to be avoided by the mover,
4259//    whose coordinates must be the last two coordinates in the definition of the ring.
4260//    If such a point is detected, then it eliminates the segments of the grobcov that
4261//    have this point as solution.
4262//    Then it calls locus.
4263proc locusdg(list GG)
4264"USAGE:  locusdg(GG) ;
4265          The argument must be the output of grobcov
4266RETURN:  The  components of the locus of points in dinamical geometry
4267NOTE:  The basering R, must be of the form Q[a][x], a=parameters,
4268          x=variables, and the mover coordinates must be the two last variables in the
4269          definition of the ring.
4270KEYWORDS: ring, locus, grobcov
4271EXAMPLE:  locusdg(GG); shows an example"
4272{
4273  def R=basering;
4274  int i; int j; int k;
4275  def B0=GG[1][2];
4276  if (equalideals(B0,ideal(1)))
4277  {
4278    return(locus(GG));
4279  }
4280  else
4281  {
4282    int n=nvars(R);
4283    ideal vmov=var(n-1),var(n);
4284    ideal N;
4285    intvec xw; intvec yw;
4286    for(i=1;i<=n-1;i++){xw[i]=0;}
4287    xw[n]=1;
4288    for(i=1;i<=n;i++){yw[i]=0;}
4289    yw[n-1]=1;
4290    poly px; poly py;
4291    int te=1;
4292    i=1;
4293    while( te and i<=size(B0))
4294    {
4295      if((deg(B0[i],xw)==1) and (deg(B0[i])==1)){px=B0[i]; te=0;}
4296      i++;
4297    }
4298    i=1; te=1;
4299    while( te and i<=size(B0))
4300    {
4301      if((deg(B0[i],yw)==1) and (deg(B0[i])==1)){py=B0[i]; te=0;}
4302      i++;
4303    }
4304    N=px,py;
4305    setglobalrings();
4306    te=indepparameters(N);
4307    if(te)
4308    {
4309      //"T_N="; N;
4310      // eliminate segments of GG where N is contained in the basis
4311      list nGP;
4312      def GP=GG;
4313      ideal BP;
4314      for(j=1;j<=size(GP);j++)
4315      {
4316        te=1; k=1;
4317        BP=GP[j][2];
4318        while((te==1) and (k<=size(N)))
4319        {
4320          if(pdivi(N[k],BP)[1]!=0){te=0;}
4321          k++;
4322        }
4323        if(te==0){nGP[size(nGP)+1]=GP[j];}
4324      }
4325      //"T_nGP="; nGP;
4326      // Now eliminate components for which the basis has dim>0, and all elements non reducing to 0
4327      // modulo N do not contain the mover coordinates
4328      list nnGP; poly r;
4329      for(j=1; j<=size(nGP);j++)
4330      {
4331        if(not(indepparameters(nGP[j][2])))
4332        {
4333          if(dim(std(nGP[j][1]))==0){nnGP[size(nnGP)+1]=nGP[j];}
4334          else
4335          {
4336            te=1; k=1;
4337            while(te and k<=size(nGP[2]))
4338            {
4339              r=pdivi(nGP[j][2][k],N)[1];
4340              if(r==0){k++;}
4341              else
4342              {
4343                if(not(subset(variables(nGP[j][2][k]),vmov )))
4344                {
4345                  te=0;
4346                }
4347                else{k++;}
4348              }
4349            }
4350            if(te==1){nnGP[size(nnGP)+1]=nGP[j];}
4351          }
4352        }
4353      }
4354    }
4355    kill @RP; kill @P; kill @R;
4356    return(locus(nnGP));
4357  }
4358}
4359example
4360{"EXAMPLE:"; echo = 2;
4361  ring R=(0,a,b),(x4,x3,x2,x1),dp;
4362  ideal S=(x1-3)^2+(x2-1)^2-9,
4363             (4-x2)*(x3-3)+(x1-3)*(x4-1),
4364             (3-x1)*(x3-x1)+(4-x2)*(x4-x2),
4365             (4-x4)*a+(x3-3)*b+3*x4-4*x3,
4366             (a-x1)^2+(b-x2)^2-(x1-x3)^2-(x2-x4)^2;
4367  short=0;
4368  locusdg(grobcov(S));
4369}
4370
4371
4372//********************* End locus ****************************
4373;
Note: See TracBrowser for help on using the repository browser.