source: git/Singular/LIB/resolve.lib

spielwiese
Last change on this file was 3f7e01a, checked in by Hans Schoenemann <hannes@…>, 9 months ago
remnemae: sat -> sat, sat_with_exp
  • Property mode set to 100644
File size: 135.6 KB
Line 
1////////////////////////////////////////////////////////////////////////////
2version="version resolve.lib 4.3.1.3 Feb_2023 "; // $Id$
3category="Algebraic Geometry";
4info="
5LIBRARY:  resolve.lib      Resolution of singularities (Desingularization)
6                           Algorithm of Villamayor
7AUTHORS:  A. Fruehbis-Krueger,  anne@mathematik.uni-kl.de,
8@*        G. Pfister,           pfister@mathematik.uni-kl.de
9
10REFERENCES:
11[1] J.Kollar: Lectures on Resolution of Singularities, Princeton University Press (2007)@*
12  (contains large overview over various known methods for curves and surfaces as well as@*
13   a detailed description of the approach in the general case)@*
14[2] A.Bravo, S.Encinas, O.Villamayor: A Simplified Proof of Desingularisation and@*
15  Applications, Rev. Math. Iberoamericana 21 (2005), 349-458@*
16  (description of the algorithmic proof of desingularization in characteristic zero
17    which underlies this implementation)@*
18[3] A.Fruehbis-Krueger: Computational Aspects of Singularities, in J.-P. Brasselet,
19  J.Damon et al.: Singularities in Geometry and Topology, World Scientific
20  Publishing, 253--327 (2007)@*
21  (chapter 4 contains a detailed discussion on algorithmic desingularization and
22  efficiency aspects thereof)
23
24PROCEDURES:
25 blowUp(J,C[,W,E]) computes the blowing up of the variety V(J) (considered
26                   as embedded in V(W)) in the (smooth) center V(C),
27 blowUp2(J,C)      computes the blowing up of the variety V(J) in the
28                   (possibly singular) center V(C)
29 Center(J[,W,E])   computes 'Villamayor'-center for blow up
30 resolve(J)        computes the desingularization of the variety V(J)
31
32 showBO(BO)      prints the content of a BO in more human readable form
33 presentTree(L)  prints the final charts in more human readable form
34 showDataTypes() prints help text for output data types
35
36 blowUpBO(BO,C)  computes the blowing up of the variety V(BO[1]) in the
37                 center V(C). BO is a list (basic object), C is an ideal
38 createBO(J,W,E) creates basic object from input data
39 CenterBO(BO)    computes the center for the next blow-up of the
40                 given basic object
41 Delta(BO)       apply the Delta-operator of [Bravo,Encinas,Villamayor]
42 DeltaList(BO)   list of results of Delta^0 to Delta^bmax
43";
44LIB "elim.lib";
45LIB "primdec.lib";
46LIB "presolve.lib";
47LIB "linalg.lib";
48LIB "sing.lib";
49///////////////////////////////////////////////////////////////////////////////
50//                      Tasks:
51//                     1) optimization of the local case
52//                     2) optimization in Coeff
53//                     3) change invariant to represent coeff=1 case
54///////////////////////////////////////////////////////////////////////////////
55
56proc showDataTypes()
57"USAGE:  showDataTypes();
58RETURN:  nothing, only pretty printing of extended version of help text
59EXAMPLE: none
60"
61{
62"                               ";
63"//////////////// Short description of data type BO ///////////////////";
64"BO[1] an ideal, say Wi, defining the ambient space of the i-th chart";
65"      of the blowing up";
66"BO[2] an ideal defining the strict transform";
67"BO[3] intvec, the first integer b such that in the original object";
68"      (Delta^b(BO[2]))==1";
69"      the subsequent integers have the same property for Coeff-Objects";
70"      of BO[2] used when determining the center";
71"BO[4] the list of exceptional divisors";
72"BO[5] an ideal defining the map K[W] ----> K[Wi]";
73"BO[6] an intvec BO[6][j]=1 indicates that <BO[4][j],BO[2]>=1, i.e. the";
74"      strict transform does not meet the j-th exceptional divisor";
75"BO[7] intvec,";
76"      the index of the first blown-up object in the resolution process";
77"      leading to this object for which the value of b was BO[3]";
78"      the subsequent ones are the indices for the Coeff-Objects";
79"      of BO[2] used when determining the center";
80"BO[i], i>7: internal data";
81"                      ";
82pause();
83"              ";
84"///////////// Short description of data in a chart ///////////////////";
85"All chart data is stored in an object of type ring, the following ";
86"variables are always present in such a ring:";
87"BO:      list of type basic object containing the variety, ambient space,";
88"         exceptional divisors and further data (see previous page)";
89"cent:    ideal, describing the upcoming center determined by the algorithm";
90"path:    module (autoconverted to matrix)";
91"         path[1][i]= (i-1)st chart in resolution history of this chart";
92"         path[2][i]= index of chart of the blow up leading to i-th chart";
93"                     in resolution history";
94"lastMap: ideal, describing the preceding blow up leading to this chart";
95"                      ";
96pause();
97"                  ";
98"///////////// Short description of type resolution data //////////////";
99"list L containing two lists:";
100"L[1]: list of rings, containing the final charts";
101"L[2]: list of rings, containing all charts created in the resolution";
102"      process";
103"The most convenient way to view these data is the procedure presentTree()";
104"from this library. Alternatively, it can be digested using tools from";
105"the libraries reszeta.lib and resgraph.lib";
106"//////////////////////////////////////////////////////////////////////";
107}
108///////////////////////////////////////////////////////////////////////////////
109proc createBO(ideal J,list #)
110"USAGE:  createBO(J[,W][,E]);
111@*       J,W = ideals
112@*       E     = list
113ASSUME:  J  = ideal containing W ( W = 0 if not specified)
114@*       E  = list of smooth hypersurfaces (e.g. exceptional divisors)
115RETURN:  list BO representing a basic object :
116         BO[1] ideal W, if W has been specified; ideal(0) otherwise
117         BO[2] ideal J
118         BO[3] intvec
119         BO[4] the list E of exceptional divisors if specified;
120               empty list otherwise
121         BO[5] an ideal defining the identity map
122         BO[6] an intvec
123         BO[7] intvec
124         BO[8] a matrix
125         entries 3,5,6,7,8 are initialized appropriately for use of CenterBO
126         and blowUpBO
127EXAMPLE: example createBO;  shows an example
128"
129{
130  ideal W;
131  list E;
132  ideal abb=maxideal(1);
133  intvec v;
134  intvec bvec;
135  intvec w=-1;
136  matrix intE;
137  if(size(#)>0)
138  {
139    if(typeof(#[1])=="ideal")
140    {
141      W=#[1];
142    }
143    if(typeof(#[1])=="list")
144    {
145      E=#[1];
146    }
147    if(size(#)>1)
148    {
149      if((typeof(#[2])=="list") && (size(E)==0))
150      {
151        E=#[2];
152      }
153      if((typeof(#[2])=="ideal") && (size(W)==0))
154      {
155        W=#[2];
156      }
157    }
158  }
159  list BO=W,J,bvec,E,abb,v,w,intE;
160  return(BO);
161}
162example
163{"EXAMPLE:";
164   echo = 2;
165   ring R=0,(x,y,z),dp;
166   ideal J=x2-y3;
167   createBO(J,ideal(z));
168}
169///////////////////////////////////////////////////////////////////////////////
170
171proc blowUp(ideal J,ideal C,list #)
172"USAGE:  blowUp(J,C[,W][,E]);
173         W,J,C = ideals,
174         E     = list
175ASSUME:  J  = ideal containing W ( W = 0 if not specified)
176@*       C  = ideal containing J
177@*       E  = list of smooth hypersurfaces (e.g. exceptional divisors)
178NOTE:    W the ideal of the ambient space, C the ideal of the center of
179         the blowup and J the ideal of the variety
180         Important difference to blowUp2:
181         - the ambient space V(W) is blown up and V(J) transformed in it
182@*         - V(C) is assumed to be non-singular
183COMPUTE: the blowing up of W in C, the exceptional locus, the strict
184         transform of J and the blowup map
185RETURN:  list, say l, of size at most size(C),
186
187         l[i] is the affine ring corresponding to the i-th chart
188         each l[i] contains the ideals
189         - aS, ideal of the blownup ambient space
190         - sT, ideal of the strict transform
191         - eD, ideal of the exceptional divisor
192         - bM, ideal corresponding to the blowup map
193
194         l[i] also contains a list BO, which can best be viewed with showBO(BO)
195         detailed information on the data type BO can be viewed via the
196         command showDataTypes();
197EXAMPLE: example blowUp;  shows an example
198"
199{
200  def S=basering;
201  ideal W;
202  list E;
203  ideal abb=maxideal(1);
204  intvec v;
205  intvec bvec;
206  intvec w=-1;
207  matrix intE;
208  if(size(#)>0)
209  {
210    if(typeof(#[1])=="ideal")
211    {
212      W=#[1];
213    }
214    if(typeof(#[1])=="list")
215    {
216      E=#[1];
217    }
218    if(size(#)>1)
219    {
220      if((typeof(#[2])=="list") && (size(E)==0))
221      {
222        E=#[2];
223      }
224      if((typeof(#[2])=="ideal") && (size(W)==0))
225      {
226        W=#[2];
227      }
228    }
229  }
230  list BO=W,J,bvec,E,abb,v,w,intE;
231  int locaT;
232  export locaT;
233  list blow=blowUpBO(BO,C,0);
234  kill locaT;
235  int i;
236  for(i=1;i<=size(blow);i++)
237  {
238     def Q=blow[i];
239     setring Q;
240     ideal aS=BO[1];
241     ideal sT=BO[2];
242     ideal eD=BO[4][size(BO[4])];
243     ideal bM=BO[5];
244     kill lastMap;
245     kill thisChart;
246     export(aS);
247     export(sT);
248     export(eD);
249     export(bM);
250     blow[i]=Q;
251     setring S;
252     kill Q;
253  }
254  return(blow);
255}
256example
257{"EXAMPLE:";
258   echo = 2;
259   ring R=0,(x,y),dp;
260   ideal J=x2-y3;
261   ideal C=x,y;
262   list blow=blowUp(J,C);
263   def Q=blow[1];
264   setring Q;
265   aS;
266   sT;
267   eD;
268   bM;
269}
270///////////////////////////////////////////////////////////////////////////////
271
272proc blowUp2(ideal J,ideal C)
273"USAGE:  blowUp2(J,C);
274         J,C = ideals,
275ASSUME:  C  = ideal containing J
276NOTE:    C the ideal of the center of the blowup and J the ideal
277         of the variety
278         Important differences to blowUp:
279         - V(J) itself is blown up, not the ambient space
280         - C is not assumed to be non-singular
281COMPUTE: the blowing up of J in C, the exceptional locus and the blow-up
282         map
283RETURN:  list, say l, of size at most size(C),
284
285         l[i] is the affine ring corresponding to the i-th chart
286         each l[i] contains the ideals
287         - Jnew, ideal of the blownup J
288         - eD, ideal of the new exceptional divisor
289         - bM, ideal corresponding to the blowup map
290
291EXAMPLE: example blowUp2;  shows an example
292"
293{
294//----------------------------------------------------------------------------
295// Initialization and basic sanity checks of the input data
296//----------------------------------------------------------------------------
297  int i,j;
298  def S=basering;
299  def laM=maxideal(1);
300//--- number of generators of C should be as small as possible
301  def mstdC=mstd(C);
302  if(ncols(mstdC[1])<ncols(mstdC[2]))
303  {
304     C=mstdC[1];
305  }
306  else
307  {
308     C=mstdC[2];
309  }
310  C=simplify(interred(C),2);
311//--- the empty set is not a good center ;-)
312  if(deg(lead(C[1]))==0)
313  {
314     ERROR("Your chosen center was the empty set. Exiting.");
315  }
316//--- V(C) should be a subset of V(J)
317  if(size(reduce(J,std(C),5))>0)
318  {
319     ERROR("V(J) does not contain V(C). Exiting.");
320  }
321//---------------------------------------------------------------------------
322// To compute the blowing up, we need to consider
323//       (K[x_1,\dots,x_n]/J)[t*C[1],...,t*C[m]]
324// which we want to represent as a quotient of K[x_1,...,x_n,y_1,..,y_m]
325// by an ideal obtained by elimination of the extra variable t.
326// (in the comments n=nvars(S) and m=ncols(C))
327//---------------------------------------------------------------------------
328//--- set up rings for the elimination
329  int ii;
330  list l5;
331  for (ii = 1; ii<= nvars(S); ii++)
332  {
333   l5[ii] = "x("+string(ii)+")";
334  }
335  for (ii = 1; ii<= ncols(C); ii++)
336  {
337   l5[nvars(S)+ii] = "y("+string(ii)+")";
338  }
339  ring R = create_ring(ring_list(basering)[1], l5, "dp", "no_minpoly");     // ring for describing the transforms
340  def C=fetch(S,C);
341  list l6;
342  for (ii = 1; ii<= nvars(S); ii++)
343  {
344   l6[ii] = "x("+string(ii)+")";
345  }
346  for (ii = 1; ii<= ncols(C); ii++)
347  {
348   l6[nvars(S)+ii] = "y("+string(ii)+")";
349  }
350  l6[size(l6)+1] = "t";
351  ring Rt = create_ring(ring_list(basering)[1], l6, "(dp("+string(ncols(C)+nvars(S))+"),dp(1))", "no_minpoly");
352  def J=fetch(S,J);
353  def C=fetch(S,C);
354//--- we need to eliminate t from J,y(1)-t*C[1],...y(m)-t*C[m]
355  ideal elId=J;
356  for(i=1;i<=ncols(C);i++)
357  {
358     elId=elId,y(i)-t*C[i];
359  }
360  elId=eliminate(elId,t);   // ideal describing the transform of J
361  setring R;                // get rid of t
362  def elId=fetch(Rt,elId);
363  def E=fetch(S,C);         // determine exceptional divisor
364  E=E+elId;
365  def laM0=fetch(S,laM);    // the blowup map
366//-----------------------------------------------------------------------------
367// The result is now represented in an A^n \times P^{m-1}, hence
368// involving n+m variables. For further computations we would like
369// to pass to charts to keep the total number of variables as low as
370// possible
371//----------------------------------------------------------------------------
372  list resList;
373  ideal Jsub;
374  ideal Esub;
375  ideal laM;
376  ideal testId;
377  map phi;
378  list templist;
379  for(i=1;i<=nvars(R)-nvars(S);i++)
380  {
381//--- first pass elId and E on to the i-th chart
382      Jsub=std(subst(elId,y(i),1));
383      if(deg(Jsub[1])==0)
384      {
385//--- transform does not meet this chart ==> ignore it
386         i++;
387         continue;
388      }
389      Esub=std(subst(E,y(i),1));
390//--- now get rid of unnecessary variables
391//--- first by appropriate coordinate changes
392      templist=elimpart(Jsub);
393      if(size(templist[2])>0)
394      {
395         phi=R,templist[5];
396         Jsub=phi(Jsub);
397         Jsub=simplify(interred(Jsub),2);
398         Esub=phi(Esub);
399         Esub=simplify(interred(Esub),2);
400         laM=phi(laM0);
401      }
402      else
403      {
404         laM=laM0;
405      }
406//--- then by dropping non-occuring variables
407      testId=Jsub,Esub,laM;
408      templist=findvars(testId);
409      if(size(templist[1])<nvars(R))
410      {
411         for(j=1;j<=size(templist[4]);j++)
412         {
413            laM=subst(laM,var(templist[4][j]),0);
414         }
415         ring Rnew = create_ring(ring_list(basering)[1], "("+string(templist[1])+")", "dp", "no_minpoly");
416         ideal Jnew=imap(R,Jsub);
417         ideal eD=imap(R,Esub);
418         ideal bM=imap(R,laM);
419      }
420      else
421      {
422         def Rnew=basering;
423         ideal Jnew=Jsub;
424         ideal eD=Esub;
425         ideal bM=laM;
426      }
427//--- export the relevant data of this ring and add the ring to the list
428      export Jnew;
429      export eD;
430      export bM;
431      resList[size(resList)+1]=Rnew;
432      setring R;
433      kill Rnew;
434  }
435  setring S;
436  return(resList);
437}
438example
439{  "EXAMPLE:";
440   echo = 2;
441   ring r=0,(x,y,z),dp;
442   ideal I=z2-x^3*y^2;
443   ideal C=z,xy;
444   list li=blowUp2(I,C);
445   size(li);                  // number of charts
446   def S1=li[1];
447   setring S1;                // chart 1
448   basering;
449   Jnew;
450   eD;
451   bM;
452   def S2=li[2];
453   setring S2;                // chart 2
454   basering;
455   Jnew;
456   eD;
457   bM;
458}
459///////////////////////////////////////////////////////////////////////////////
460
461proc Center(ideal J,list #)
462"USAGE:  Center(J[,W][,E])
463@*       J,W = ideals
464@*       E   = list
465ASSUME:  J  = ideal containing W ( W = 0 if not specified)
466@*       E  = list of smooth hypersurfaces (e.g. exceptional divisors)
467COMPUTE: the center of the blow-up of J for the resolution algorithm
468         of [Bravo,Encinas,Villamayor]
469RETURN:  ideal, describing the center
470EXAMPLE: example Center;  shows an example
471"
472{
473  ideal W;
474  list E;
475  ideal abb=maxideal(1);
476  intvec v;
477  intvec bvec;
478  intvec w=-1;
479  matrix intE;
480  if(size(#)>0)
481  {
482    if(typeof(#[1])=="ideal")
483    {
484      W=#[1];
485    }
486    if(typeof(#[1])=="list")
487    {
488      E=#[1];
489    }
490    if(size(#)>1)
491    {
492      if((typeof(#[2])=="list") && (size(E)==0))
493      {
494        E=#[2];
495      }
496      if((typeof(#[2])=="ideal") && (size(W)==0))
497      {
498        W=#[2];
499      }
500      if(size(#)==3){bvec=#[3];}
501    }
502  }
503
504  list BO=W,J,bvec,E,abb,v,w,intE,intvec(0);
505  if(defined(invSat)){kill invSat;}
506  list invSat=ideal(0),intvec(0);
507  export(invSat);
508
509  list re=CenterBO(BO);
510  ideal cent=re[1];
511  return(cent);
512}
513example
514{  "EXAMPLE:";
515   echo = 2;
516   ring R=0,(x,y),dp;
517   ideal J=x2-y3;
518   Center(J);
519}
520///////////////////////////////////////////////////////////////////////////////
521
522proc blowUpBO(list BO, ideal C,int e)
523"USAGE:  blowUpBO (BO,C,e);
524@*       BO = basic object, a list: ideal W,
525@*                                  ideal J,
526@*                                  intvec b,
527@*                                  list Ex,
528@*                                  ideal ab,
529@*                                  intvec v,
530@*                                  intvec w,
531@*                                  matrix M
532@*       C  = ideal
533@*       e  = integer (0 usual blowing up, 1 deleting extra charts, 2 deleting
534@*            no charts )
535ASSUME:  R  = basering, a polynomial ring, W an ideal of R,
536@*       J  = ideal containing W,
537@*       C  = ideal containing J
538COMPUTE: the blowing up of BO[1] in C, the exceptional locus, the strict
539         transform of BO[2]
540NOTE:    blowUpBO may be applied to basic objects in the sense of
541@*       [Bravo, Encinas, Villamayor] in the following referred to as BO and
542@*       to presentations in the sense of [Bierstone, Milman] in the following
543@*       referred to as BM.
544RETURN:  a list l of length at most size(C),
545         l[i] is a ring containing an object BO resp. BM:
546@*         BO[1]=BM[1] an ideal, say Wi, defining the ambient space of the
547               i-th chart of the blowing up
548@*         BO[2]=BM[2] an ideal defining the strict transform
549@*         BO[3] intvec, the first integer b such that in the original object
550               (Delta^b(BO[2]))==1
551               the subsequent integers have the same property for Coeff-Objects
552               of BO[2] used when determining the center
553@*         BM[3] intvec, BM[3][i] is the assigned multiplicity of BM[2][i]
554@*         BO[4]=BM[4] the list of exceptional divisors
555@*         BO[5]=BM[5] an ideal defining the map K[W] ----> K[Wi]
556@*         BO[6]=BM[6] an intvec BO[6][j]=1 indicates that <BO[4][j],BO[2]>=1,
557               i.e. the strict transform does not meet the j-th exceptional
558               divisor
559@*         BO[7] intvec,
560               the index of the first blown-up object in the resolution process
561               leading to this object for which the value of b was BO[3]
562               the subsequent ones are the indices for the Coeff-Objects
563               of BO[2] used when determining the center
564@*         BM[7] intvec, BM[7][i] is the index at which the (2i-1)st entry
565               of the invariant first reached its current maximal value
566@*         BO[8]=BM[8] a matrix indicating that BO[4][i] meets BO[4][j] by
567               BO[8][i,j]=1 for i < j
568@*         BO[9] empty
569@*         BM[9] the invariant
570
571EXAMPLE: example blowUpBO;  shows an example
572"
573{
574//---------------------------------------------------------------------------
575// Initialization  and sanity checks
576//---------------------------------------------------------------------------
577   def R0=basering;
578   if(!defined(locaT)){int locaT;}
579   if(locaT){poly pp=@p;}
580   intvec v;
581   int shortC=defined(shortcut);
582   int invS=defined(invSat);
583   int eq,hy,ii;
584   int extra,noDel,keepDiv;
585   if(e==1){extra=1;}
586//---keeps all charts
587   if(e==2){noDel=1;}
588//---this is only for curves and surfaces
589//---keeps all charts with relevant information on the exceptional divisors
590   if(e==3){keepDiv=1;}
591   if( typeof(attrib(BO[2],"isEqui"))=="int" )
592   {
593      eq=attrib(BO[2],"isEqui");
594   }
595   if( typeof(attrib(BO[2],"isHy"))=="int" )
596   {
597      hy=attrib(BO[2],"isHy");
598   }
599   string newvar;
600   int n=nvars(R0);
601   int i,j,l,m,x,jj,ll,haveCenters,co;
602//---the center should neither be the whole space nor empty
603   if((size(C)==0)||(deg(C[1])==0))
604   {
605      list result=R0;
606      return(result);
607   }
608   if(!defined(debugBlowUp))
609   {
610     int debugBlowUp=0;
611   }
612//---------------------------------------------------------------------------
613// Drop unnecessary variables
614//---------------------------------------------------------------------------
615//---step 1: substitution
616   if(!((keepDiv)||(noDel)))
617   {
618//!!! in case keepDiv and noDel:
619//!!! maybe simplify the situation by an appropriate coordinate change
620//!!! of this kind -- without dropping variables?
621      list L=elimpart(BO[1]);
622      if(size(L[2])!=0)
623      {
624         map psi=R0,L[5];
625         C=psi(C);
626         BO=psi(BO);
627      }
628
629      if(size(BO[1])==0)
630      {
631         ideal LL;
632         for(j=1;j<=size(BO[4]);j++)
633         {
634            LL=LL,BO[4][j];
635         }
636         LL=variables(LL);
637         L=elimpart(BO[2]);
638         if((size(L[2])!=0)&&(size(std(LL+L[2]))==size(L[2])+size(LL)))
639         {
640            map chi=R0,L[5];
641            C=chi(C);
642            BO=chi(BO);
643         }
644      }
645//---step 2: dropping non-occurring variables
646      int s=size(C);
647      ideal K=BO[1],BO[2],C;
648      for(j=1;j<=size(BO[4]);j++)
649      {
650        K=K,BO[4][j];
651      }
652      list N=findvars(K);
653      if(size(N[1])<n)
654      {
655         newvar=string(N[1]);
656         v=N[4];
657         for(j=1;j<=size(v);j++){BO[5]=subst(BO[5],var(v[j]),0);}
658         ring R1 = create_ring(ring_list(R0)[1], "("+newvar+")", "dp", "no_minpoly");
659         list BO=imap(R0,BO);
660         ideal C=imap(R0,C);
661         n=nvars(R1);
662      }
663      else
664      {
665         def R1=basering;
666      }
667   }
668   else
669   {
670     int s=size(C);
671     def R1=basering;
672   }
673   if(debugBlowUp)
674   {
675     "---> In BlowUp: After dropping unnecessary variables";
676     "BO:";
677     BO;
678     "C:";
679     C;
680   }
681//---------------------------------------------------------------------------
682// Do the actual blow-up
683//---------------------------------------------------------------------------
684//--- control the names of the variables
685   list l2;
686   for (ii = 1; ii <= n; ii++)
687   {
688    l2[ii] = "x("+string(ii)+")";
689   }
690   ring R = create_ring(ring_list(R0)[1], l2, "dp", "no_minpoly");
691   ideal R_maxid=maxideal(1);
692   list BO=fetch(R1,BO);
693   ideal C=fetch(R1,C);
694   list Cmstd=mstd(C);
695   C=Cmstd[2];
696   if(size(Cmstd[1])<=size(Cmstd[2]))
697   {
698      C=Cmstd[1];
699   }
700   else
701   {
702      C=interred(C);
703   }
704   list result;
705//--- the blow-up process
706   ideal W  =BO[1];
707   ideal J  =BO[2];
708   intvec bvec  =BO[3];
709   list Ex  =BO[4];
710   ideal abb=BO[5];
711   intvec wvec=BO[7];
712   ideal laM=maxideal(1);
713   if((typeof(BO[9])=="intmat")||(typeof(BO[9])=="intvec"))
714   {
715      def @invmat=BO[9];
716   }
717   if(size(BO)>9)
718   {
719//--- check whether a previous center had been split into connected components
720      if(size(BO[10])>0)
721      {
722         list knownCenters=BO[10];
723         haveCenters=1;
724       }
725   }
726
727   matrix intE=BO[8];
728   Ex[size(Ex)+1]=var(1);
729         //to have the list depending on R in case BO[4] is empty
730
731   list l3 = ringlist(R)[2];
732   for (ii = 0; ii <= s-1; ii++)
733   {
734    l3[size(l3)+1] = "y("+string(ii)+")";
735   }
736   ring S = create_ring(ring_list(R)[1], l3, "dp", "no_minpoly");
737   list resu;
738   list B;
739   list l4 = ringlist(R)[2];
740   for (ii = 0; ii <= s-1; ii++)
741   {
742    l4[size(l4)+1] = "y("+string(ii)+")";
743   }
744   l4[size(l4)+1] = "t";
745   ring T = create_ring(ring_list(R)[1], l4, "dp", "no_minpoly");
746   ideal C=imap(R,C);
747   ideal W=imap(R,W);
748   ideal R_im=imap(R,R_maxid);
749   R_im=R_im,t*C;
750   map phi=S,R_im;
751   setring S;
752
753//--- the ideal describing the blow-up map
754   ideal abb=imap(R,abb);
755   ideal laM0=imap(R,laM);
756//--- the ideal of the blowing up of the ambient space
757   ideal W=preimage(T,phi,W);
758//--- the ideal of the exceptional locus
759   ideal E=imap(R,C);
760
761   list E1=imap(R,Ex);
762   E1[size(E1)]=E;
763   ideal J=imap(R,J)+W;
764
765   if(haveCenters){list kN=imap(R,knownCenters);}
766
767//---  the strict transform of the exceptional divisors
768   for(j=1;j<size(E1);j++){E1[j]=sat(E1[j]+W,E);}
769//---  the intersection matrix of the exceptional divisors
770   matrix intEold=imap(R,intE);
771   matrix intE[size(E1)][size(E1)];
772   ideal U,Jsub,sLstd;
773
774   for(j=1;j<size(E1);j++)
775   {
776       for(l=j+1;l<=size(E1);l++)
777       {
778          if(deg(E1[j][1])==0)
779          {
780             if(l<size(E1)){intE[j,l]=intEold[j,l];}
781             else             {intE[j,l]=0;}
782          }
783          else
784          {
785             if(deg(E1[l][1])==0)
786             {
787                if(l<size(E1)){intE[j,l]=intEold[j,l];}
788             }
789             else
790             {
791                U= std(E1[l]+E1[j]);
792                if(dim(U)>0){intE[j,l]=1;}
793                else        {intE[j,l]=0;}
794             }
795          }
796       }
797   }
798   if(debugBlowUp)
799   {
800     "----> In BlowUp: After Blowing-up, before Clean-Up";
801     "W:";
802     W;
803     "J:";
804     J;
805   }
806//----------------------------------------------------------------------------
807// generating and cleaning up the different charts
808//----------------------------------------------------------------------------
809   list M;
810   map psi;
811   list E2;
812   ideal K,JJ,laM,LL,MM;
813   n=nvars(S);
814   list N;
815   list Bstd;
816   intvec delCharts,extraCharts;
817   delCharts[s]=0;
818   extraCharts[s]=0;
819   ideal MA=y(0..s-1);
820   list ZRes,ZlaM,ZsLstd;
821   for(i=0;i<=s-1;i++)
822   {
823     if(haveCenters)
824     {
825        B[10]=kN;
826        for(j=1;j<=size(kN);j++)
827        {
828           B[10][j][1]=subst(B[10][j][1],y(i),1);
829        }
830     }
831     B[8]=intE;
832     B[1]=std(subst(W,y(i),1));
833     if(deg(B[1][1])==0)
834     {
835//--- subsets of the empty set are not really interesting!
836       delCharts[i+1]=1;
837       ZRes[i+1]=B;
838       ZlaM[i+1]=laM;
839       i++;
840       continue;
841     }
842     Jsub=subst(J,y(i),1);
843     attrib(Jsub,"isEqui",eq);
844     attrib(Jsub,"isHy",hy);
845     B[2]=Jsub;
846     B[3]=bvec;
847     for(j=1;j<size(E1);j++){E2[j]=subst(E1[j],y(i),1);}
848     E2[size(E1)]=E+B[1];
849     B[4]=E2;
850     M=elimpart(B[1]);
851     B[5]=abb;
852     laM=laM0;
853     psi=S,maxideal(1);
854     if(size(M[2])!=0)
855     {
856        psi=S,M[5];
857        B=psi(B);
858        laM=psi(laM);
859     }
860     Jsub=B[2];
861     B[2]=sat(Jsub,std(psi(E)));
862     if(!defined(MAtmp)){ideal MAtmp=MA;}
863     MAtmp[i+1]=0;
864     JJ=std(B[2]+MAtmp);
865     if(deg(JJ[1])==0)
866     {
867        delCharts[i+1]=1;
868//--- the i-th chart will be marked for deleting because all information
869//--- are already contained in the union of the remaining charts
870     }
871     else
872     {
873        if((eq)&&(dim(JJ)<dim(std(B[2]))))
874        {
875           extraCharts[i+1]=1;
876//---  compute the singular locus
877           if((B[3][1]<=1)&&(hy))
878//--- B[2] is a smooth hypersurface
879           {
880              sLstd=ideal(1);
881           }
882           else
883           {
884              Bstd=mstd(B[2]);
885              if(n-dim(Bstd[1])>4)
886              {
887//--- in this case the singular locus is too complicated
888                 sLstd=ideal(0);
889              }
890              JJ=Bstd[2];
891              attrib(JJ,"isEqui",eq);
892              B[2]=JJ;
893              sLstd=slocusE(B[2]);
894           }
895           m=0;
896           if(deg(std(sLstd+MAtmp)[1])==0)
897           {
898//--- the singular locus of B[2] is in the union of the remaining charts
899              m=1;
900              for(l=1;l<=size(B[4]);l++)
901              {
902                 if(deg(std(B[2]+B[4][l]+MAtmp)[1])!=0)
903                 {
904//--- the exceptional divisor meets B[2] at the locus of MAtmp
905//--- we continue only if the option extra=1 and we have transversal
906//--- intersection
907                    m=0;
908                    break;
909                  }
910              }
911           }
912           if(m)
913           {
914//--- the i-th chart will be marked for deleting because all information
915//--- are already contained in the union of the remaining charts
916              delCharts[i+1]=1;
917           }
918        }
919     }
920     if(delCharts[i+1]==0)
921     {
922        MAtmp[i+1]=MA[i+1];
923        ZsLstd[i+1]=sLstd;
924     }
925     ZRes[i+1]=B;
926     ZlaM[i+1]=laM;
927   }
928//---------------------------------------------------------------------------
929// extra = ignore uninteresting charts even if there is a normal
930//         crosssing intersection in it
931//---------------------------------------------------------------------------
932   if(extra)
933   {
934      for(i=0;i<=s-1;i++)
935      {
936         if((delCharts[i+1]==0)&&(extraCharts[i+1]))
937         {
938           MAtmp[i+1]=0;
939           B=ZRes[i+1];
940           sLstd=ZsLstd[i+1];
941           m=0;
942           if(deg(std(sLstd+MAtmp)[1])==0)
943           {
944//--- the singular locus of B[2] is in the union of the remaining charts
945              m=1;
946              for(l=1;l<=size(B[4]);l++)
947              {
948                 if(deg(std(B[2]+B[4][l]+MAtmp)[1])!=0)
949                 {
950//--- the exceptional divisor meets B[2] at the locus of MAtmp
951//--- we continue only if the option extra=1 and we have transversal
952//--- intersection
953                    m=2;
954                    if(!transversalTB(B[2],list(B[4][l]),MAtmp))
955                    {
956                       m=0;break;
957                    }
958                  }
959              }
960           }
961           if(m)
962           {
963              if(m==1)
964              {
965//--- the i-th chart will be marked for deleting because all information
966//--- are already contained in the union of the remaining charts
967                 delCharts[i+1]=1;
968              }
969              else
970              {
971//--- the option extra=1 and we have transversal intersection
972//--- we delete the chart in case of normal crossings
973                 if(normalCrossB(B[2],B[4],MAtmp))
974                 {
975//--- in case of the option extra
976//--- the i-th chart will be marked for deleting because all information
977//--- are already contained in the union of the remaining charts
978
979                   delCharts[i+1]=1;
980                 }
981              }
982           }
983           if(delCharts[i+1]==0)
984           {
985              MAtmp[i+1]=MA[i+1];
986           }
987         }
988      }
989      for(i=0;i<=s-1;i++)
990      {
991         if(!delCharts[i+1]){break;}
992      }
993      if(i==s){delCharts[s]=0;}
994   }
995   for(i=0;i<=s-1;i++)
996   {
997     B=ZRes[i+1];
998     laM=ZlaM[i+1];
999     if(noDel){delCharts[i+1]=0;}
1000//---keeps chart if the exceptional divisor is not in any other chart
1001     if((delCharts[i+1])&&(keepDiv))
1002     {
1003         for(j=1;j<=size(B[4]);j++)
1004         {
1005            if(deg(std(B[4][j])[1])>0)
1006            {
1007               x=0;
1008               for(l=0;l<=s-1;l++)
1009               {
1010                  if((l!=i)&&(!delCharts[l+1])&&(deg(std(ZRes[l+1][4][j])[1])>0))
1011                  {
1012                     x=1;
1013                     break;
1014                  }
1015               }
1016               if(!x)
1017               {
1018                  delCharts[i+1]=0;
1019//!!!evtl. diese Karten markieren und nicht weiter aufblasen???
1020                  break;
1021               }
1022            }
1023         }
1024     }
1025//---keeps charts if the intersection of 2 divisors is not in any other chart
1026     if((delCharts[i+1])&&(keepDiv))
1027     {
1028         for(j=1;j<=size(B[4])-1;j++)
1029         {
1030            for(l=j+1;l<=size(B[4]);l++)
1031            {
1032               if(deg(std(B[4][j]+B[4][l])[1])>0)
1033               {
1034                  x=0;
1035                  for(ll=0;ll<=s-1;ll++)
1036                  {
1037                     if((ll!=i)&&(!delCharts[ll+1]))
1038                     {
1039                        if(deg(std(ZRes[ll+1][4][j]+ZRes[ll+1][4][l])[1])>0)
1040                        {
1041                           x=1;
1042                           break;
1043                        }
1044                     }
1045                  }
1046                  if(!x)
1047                  {
1048                     delCharts[i+1]=0;
1049                     break;
1050                  }
1051               }
1052            }
1053            if(!delCharts[i+1]){break;}
1054         }
1055     }
1056//---keeps charts if the intersection of 3 divisors is not in any other chart
1057     if((delCharts[i+1])&&(keepDiv))
1058     {
1059         for(j=1;j<=size(B[4])-2;j++)
1060         {
1061            for(l=j+1;l<=size(B[4])-1;l++)
1062            {
1063               for(ll=l+1;ll<=size(B[4]);ll++)
1064               {
1065                  if(deg(std(B[4][j]+B[4][l]+B[4][ll])[1])>0)
1066                  {
1067                     x=0;
1068                     for(jj=0;jj<=s-1;jj++)
1069                     {
1070                        if((jj!=i)&&(!delCharts[jj+1]))
1071                        {
1072                           if(deg(std(ZRes[jj+1][4][j]
1073                              +ZRes[jj+1][4][l]+ZRes[jj+1][4][ll])[1])>0)
1074                           {
1075                              x=1;
1076                              break;
1077                           }
1078                        }
1079                     }
1080                     if(!x)
1081                     {
1082                       delCharts[i+1]=0;
1083                       break;
1084                     }
1085                  }
1086               }
1087               if(!delCharts[i+1]){break;}
1088            }
1089            if(!delCharts[i+1]){break;}
1090        }
1091     }
1092     if(delCharts[i+1]==0)
1093     {
1094//--- try to decrease the number of variables by substitution
1095        if((!keepDiv)&&(!noDel))
1096        {
1097           list WW=elimpart(B[1]);
1098           map phiW=basering,WW[5];
1099           B=phiW(B);
1100           laM=phiW(laM);
1101           kill WW;
1102           kill phiW;
1103           if(size(B[1])==0)
1104           {
1105              LL=0;
1106              for(j=1;j<=size(B[4]);j++)
1107              {
1108                 MM=std(B[4][j]);
1109                 if(deg(MM[1])>0){LL=LL,MM;}
1110              }
1111              LL=variables(LL);
1112              M=elimpart(B[2]);
1113              if((size(M[2])!=0)&&(size(std(LL+M[2]))==size(M[2])+size(LL)))
1114              {
1115                psi=S,M[5];
1116                B=psi(B);
1117                laM=psi(laM);
1118              }
1119           }
1120         }
1121//---- interreduce B[1],B[2] and all B[4][j]
1122        B[1]=interred(B[1]);
1123        B[2]=interred(B[2]);
1124        E2=B[4];
1125        for(j=1;j<=size(E2);j++){E2[j]=interred(E2[j]);}
1126        B[4]=E2;
1127        v=0;v[size(E2)]=0;
1128//--- mark those j for which B[4] does not meet B[2]
1129        for(j=1;j<=size(E2);j++)
1130        {
1131            K=E2[j],B[2];
1132            K=std(K);
1133            if(deg(K[1])==0)
1134            {
1135              v[j]=1;
1136            }
1137        }
1138        B[6]=v;
1139        B[7]=wvec;
1140//--- throw away variables which do not occur
1141        K=B[1],B[2],B[5];          //Aenderung!!!
1142        for(j=1;j<=size(B[4]);j++){K=K,B[4][j];}
1143        N=findvars(K);
1144        if(size(N[1])<n)
1145        {
1146           newvar=string(N[1]);
1147           v=N[4];
1148           for(j=1;j<=size(v);j++)
1149           {
1150              B[5]=subst(B[5],var(v[j]),0);
1151              laM=subst(laM,var(v[j]),0);
1152           }
1153           ring R2 = create_ring(ring_list(S)[1], "("+newvar+")", "dp", "no_minpoly");
1154           list BO=imap(S,B);
1155           ideal laM=imap(S,laM);
1156        }
1157        else
1158        {
1159           def R2=basering;
1160           list BO=B;
1161        }
1162        ideal JJ=BO[2];
1163        attrib(JJ,"isEqui",eq);
1164        attrib(JJ,"isHy",hy);
1165        BO[2]=JJ;
1166//--- strict transforms of the known centers
1167        if(haveCenters)
1168        {
1169           ideal tt;
1170           list tList;
1171           for(j=1;j<=size(BO[10]);j++)
1172           {
1173              tt=std(BO[10][j][1]);
1174              if(deg(tt[1])>0)
1175              {
1176                tt=sat(tt,BO[4][size(BO[4])]);
1177              }
1178              if((deg(tt[1])>0)&&(deg(std(tt+BO[2]+BO[1])[1])>0))
1179              {
1180                 tList[size(tList)+1]=
1181                            list(tt,BO[10][j][2],BO[10][j][3],BO[10][j][4]);
1182              }
1183           }
1184           BO[10]=tList;
1185           kill tList;
1186        }
1187//--- marking  variables which do not occur in BO[1] and BO[2]
1188//--- and occur in exactly one BO[4][j], which is the hyperplane given by
1189//--- this variable
1190//!!!! not necessarily in exactly one BO[4][j]
1191        list N=findvars(BO[1]+BO[2]);
1192        if(size(N[1])<nvars(basering))
1193        {
1194           v=N[4];
1195           if(defined(H)){kill H;}
1196           if(defined(EE)){kill EE;}
1197           if(defined(vv)){kill vv;}
1198           list EE;
1199           intvec vv;
1200           ideal H=maxideal(1);
1201           for(j=1;j<=size(v);j++)
1202           {
1203             H[v[j]]=0;
1204           }
1205           H=std(H);
1206           for(l=1;l<=size(BO[4]);l++)
1207           {
1208              if(BO[6][l]==1){l++;continue;}
1209              if(size(ideal(matrix(reduce(BO[4][l],H))-BO[4][l]))==0)
1210              {
1211//!!! need further cleanup:
1212//!!! this part of the code is no longer used since it did not glue properly
1213//                 BO[6][l]=2;
1214                 EE[size(EE)+1]=BO[4][l];
1215                 vv[size(vv)+1]=l;
1216              }
1217           }
1218           if((size(vv)>dim(std(BO[2])))&&(deg(BO[2][1])>0))
1219           {
1220              list BOtemp3=BO;
1221              BOtemp3[4]=EE;
1222              intvec ivtemp3;
1223              ivtemp3[size(BOtemp3[4])]=0;
1224              BOtemp3[6]=ivtemp3;
1225              BOtemp3[7][1]=-1;
1226              list iEtemp3=inters_E(BOtemp3);
1227              if(iEtemp3[2]>=dim(std(BOtemp3[2])))
1228              {
1229                 for(l=2;l<=size(vv);l++)
1230                 {
1231                    BO[6][vv[l]]=0;
1232                 }
1233              }
1234              kill BOtemp3,ivtemp3,iEtemp3;
1235           }
1236        }
1237        list thisChart=ideal(0),i;
1238        export thisChart;
1239
1240//----------------------------------------------------------------------------
1241// export the basic object and append the ring to the list of rings
1242//----------------------------------------------------------------------------
1243        if(debugBlowUp)
1244        {
1245           "----> In BlowUp: Adding a single chart";
1246           "BO:";
1247           BO;
1248        }
1249        if(locaT)
1250        {
1251           map locaPhi=R0,laM;
1252           poly @p=locaPhi(pp);
1253           export(@p);
1254        }
1255        ideal lastMap=laM;
1256        export lastMap;
1257        if(invS){list invSat=imap(R0,invSat);export invSat;}
1258        if(defined(@invmat)){BO[9]=@invmat;}
1259        if(shortC){list shortcut=imap(R0,shortcut);export(shortcut);}
1260        export BO;
1261        result[size(result)+1]=R2;
1262        setring S;
1263        kill R2;
1264     }
1265   }
1266   setring R0;
1267   return(result);
1268}
1269example
1270{"EXAMPLE:";
1271   echo = 2;
1272   ring R=0,(x,y),dp;
1273
1274   ideal W;
1275   ideal J=x2-y3;
1276   intvec b=1;
1277   list E;
1278   ideal abb=maxideal(1);
1279   intvec v;
1280   intvec w=-1;
1281   matrix M;
1282   intvec ma;
1283   list BO=W,J,b,E,abb,v,w,M,ma;
1284
1285   ideal C=CenterBO(BO)[1];
1286
1287   list blow=blowUpBO(BO,C,0);
1288   def Q=blow[1];
1289   setring Q;
1290   BO;
1291}
1292//////////////////////////////////////////////////////////////////////////////
1293static proc slocusE(ideal i)
1294"Internal procedure - no help and no example available
1295"
1296{
1297//--- do slocus in equidimensional case directly -- speed up
1298  if(size(i)==0){return(ideal(1));}
1299  if( typeof(attrib(i,"isEqui"))=="int" )
1300  {
1301     if(attrib(i,"isEqui")==1)
1302     {
1303        ideal j=std(i);
1304        if(deg(j[1])==0){return(j);}
1305        int cod  = nvars(basering)-dim(j);
1306        i        = i+minor(jacob(i),cod);
1307        return(i);
1308     }
1309  }
1310  return(slocus(i));
1311}
1312///////////////////////////////////////////////////////////////////////////////
1313static proc inters_E(list BO)
1314"USAGE:  inters_E(BO);
1315@*       BO = basic object, a list: ideal W,
1316@*                                  ideal J,
1317@*                                  intvec b,
1318@*                                  list Ex,
1319@*                                  ideal ab,
1320@*                                  intvec v,
1321@*                                  intvec w,
1322@*                                  matrix M
1323ASSUME:  R  = basering, a polynomial ring, W an ideal of R,
1324@*       J  = ideal containing W,
1325@*       BO in the setting of case 2 of [Bravo,Encinas,Villamayor]
1326@*             BO[4]=E, BO[4][1..count]=E^-
1327@*             BO[7][1]=count
1328COMPUTE: (W,(P,1),E^+) in the notation of [Bravo,Encinas,Villamayor]
1329RETURN:  a list l ,
1330         l[1]: P = product of ideals I(H_i1)+..+I(H_in) over all
1331                   n-tuples of indices i1..in from 1..count
1332         l[2]: n = maximal number of H_i from E^- meeting J simultaneously
1333         l[3]: maximal number of H_i from E meeting J simultaneously
1334EXAMPLE: internal procedure - no example available
1335"
1336{
1337//---------------------------------------------------------------------
1338// Initialization
1339//---------------------------------------------------------------------
1340  int kk,jj,ii,updated,n,count2,kkdiff;
1341  def rb=basering;
1342  def W=BO[1];
1343  ideal J=BO[1],BO[2];
1344  int nonnormal;
1345  int maxkk=dim(std(J));
1346  int dimJ=maxkk;
1347  ideal test2;
1348  list merklist1,merklist2;
1349  if(size(BO[4])==0)
1350  {
1351    list retlist=BO[2],n;
1352    return(retlist);
1353  }
1354  def E=BO[4];
1355  intvec stoplist=BO[6];
1356//--- fill in all known information about exceptional divisors not meeting
1357//--- current chart
1358  for(ii=1;ii<=size(E);ii++)
1359  {
1360    if(deg(std(E[ii])[1])==0)
1361    {
1362      stoplist[ii]=1;
1363    }
1364  }
1365
1366  int count=BO[7][1];
1367  if(!defined(debug_Inters_E))
1368  {
1369    int debug_Inters_E=0;
1370  }
1371//---------------------------------------------------------------------
1372// we only want to look at E^-, not at all of E
1373//---------------------------------------------------------------------
1374  if (count>-1)
1375  {
1376    if (count>0)
1377    {
1378      list E_new=E[1..count];
1379      count2=size(E);
1380    }
1381    else
1382    {
1383      list E_new;
1384      count2=size(E);
1385    }
1386  }
1387  else
1388  {
1389    list E_new=E;
1390    count=size(E_new);
1391    count2=count;
1392  }
1393//---------------------------------------------------------------------
1394// combinatorics is expensive in an interpreted language,
1395// we leave it to the kernel by translating it into monomial
1396// ideals in a new ring with variables t(i)
1397//---------------------------------------------------------------------
1398  list l7;
1399  for (int zz = 1; zz<= size(E); zz++)
1400  {
1401   l7[zz] = "t("+string(zz)+")";
1402  }
1403  ring rcomb = create_ring(0, l7, "dp");
1404  ideal potid,potid2;
1405  list monlist,comblist,merkmon;
1406  for(kk=1;kk<=count;kk++)
1407  {
1408    if(stoplist[kk]==0)
1409    {
1410//**************************************************************************/
1411// it does not make sense to intersect twice by the same E_i
1412// ===> reduce by t(i)^2
1413//**************************************************************************/
1414      potid=potid,t(kk)^2;
1415    }
1416    else
1417    {
1418//**************************************************************************/
1419// it does not make sense to consider E_i with v[i]==1 ===> reduce by t(i)
1420//**************************************************************************/
1421      potid=potid,t(kk);
1422//**************************************************************************/
1423// if stoplist[kk]==2 then J and all E_i automatically intersect E_kk
1424// hence we need not test it, but we have to lower maxkk by one
1425//**************************************************************************/
1426      if(stoplist[kk]==2)
1427      {
1428        maxkk=maxkk-1;
1429        kkdiff++;             // count these for dimension check later on
1430
1431      }
1432    }
1433  }
1434
1435  potid2=std(potid);
1436  if(count2>count)
1437  {
1438    potid=potid,t((count+1)..count2);
1439    for(kk=max(1,count);kk<=count2;kk++)
1440    {
1441      potid2=potid2,t(kk)^2;
1442    }
1443  }
1444  potid=std(potid);
1445  if(!attrib(potid2,"isSB")) { potid2=std(potid2); }
1446  for(kk=1;(((kk<=count)||(kk<=maxkk+1))&&(kk<=count2));kk++)
1447  {
1448//-------------------------------------------------------------------------
1449// monlist[kk]=lists of kk entries of E_new, not containing an E_i twice,
1450// not containing an E_i where v[i]==1
1451//-------------------------------------------------------------------------
1452    monlist[kk]=redMax(kk,potid);
1453//*************************************************************************/
1454// in the case of n<=maxkk we also need to know whether n would still be
1455// below this bound if we considered all of E instead of E_new
1456// ===> merkmon contains previously ignored tuples E_i1,..,E_im
1457//*************************************************************************/
1458    if(kk<=maxkk+1)
1459    {
1460      merkmon[kk]=redMax(kk,potid2);
1461      merkmon[kk]=simplify(reduce(merkmon[kk],std(monlist[kk])),2);
1462    }
1463  }
1464  if(debug_Inters_E)
1465  {
1466    "----> In Inters_E: the tuples";
1467    "tuples of E^-:";
1468    monlist;
1469    "the remaining tuples:";
1470    merkmon;
1471  }
1472//-------------------------------------------------------------------------
1473// check whether there is a kk-tuple of E_i intersecting J,
1474// kk running from 1 to count
1475//-------------------------------------------------------------------------
1476  for(kk=1;kk<=count;kk++)
1477  {
1478    if(size(monlist[kk])==0) break;
1479    kill comblist;
1480    list comblist;
1481//--- transscribe the tuples from monomial notation to intvec notation
1482    for(jj=1;jj<=ncols(monlist[kk]);jj++)
1483    {
1484      comblist[jj]=leadexp(monlist[kk][jj]);
1485    }
1486    setring rb;
1487    updated=0;
1488//------------------------------------------------------------------------
1489// Do the intersections
1490//------------------------------------------------------------------------
1491    for(jj=1;jj<=size(comblist);jj++)
1492    {
1493//--- jj-th tuple from list of tuples of kk E_i
1494      test2=J;
1495      for(ii=1;ii<=count;ii++)
1496      {
1497        if(comblist[jj][ii]==1)
1498        {
1499          test2=test2,E_new[ii];
1500        }
1501      }
1502      test2=std(test2);
1503//--- check whether this intersection is non-empty and store it accordingly
1504      if(deg(test2[1])!=0)
1505      {
1506//--- it is non-empty
1507        if(updated!=0)
1508        {
1509          merklist1[size(merklist1)+1]=comblist[jj];
1510        }
1511        else
1512        {
1513          kill merklist1;
1514          list merklist1;
1515          merklist1[1]=comblist[jj];
1516          updated=1;
1517          n=kk;
1518        }
1519        if(dim(test2)!=maxkk-kk+kkdiff)
1520        {
1521          nonnormal=1;
1522        }
1523      }
1524      else
1525      {
1526//--- it is empty
1527        merklist2[size(merklist2)+1]=jj;
1528      }
1529    }
1530    setring rcomb;
1531    ideal redid;
1532//---------------------------------------------------------------------
1533// update monlist and merkmon by the knowledge what intersections are
1534// empty in the kk-th step
1535//---------------------------------------------------------------------
1536    for(jj=1;jj<=size(merklist2);jj++)
1537    {
1538      redid=redid,monlist[kk][merklist2[jj]];
1539    }
1540    for(jj=kk+1;jj<=count;jj++)
1541    {
1542      monlist[jj]=simplify(reduce(monlist[jj],std(redid)),2);
1543      if(jj<=maxkk+1)
1544      {
1545        merkmon[jj]=simplify(reduce(merkmon[jj],std(redid)),2);
1546      }
1547    }
1548    kill redid;
1549    kill merklist2;
1550    list merklist2;
1551  }
1552  if(debug_Inters_E)
1553  {
1554    "----> In Inters_E: intersections found:";
1555    merklist1;
1556  }
1557//---------------------------------------------------------------------
1558// form the union of the intersections of the appropriate E_i
1559//---------------------------------------------------------------------
1560  setring rb;
1561  ideal center,dummy;
1562  list centlist;
1563  for(kk=1;kk<=size(merklist1);kk++)
1564  {
1565    for(jj=1;jj<=size(merklist1[kk]);jj++)
1566    {
1567      if(merklist1[kk][jj]==1)
1568      {
1569        dummy=dummy,E_new[jj];
1570      }
1571    }
1572    if(size(center)==0)
1573    {
1574      center=dummy;
1575      centlist[1]=dummy;
1576    }
1577    else
1578    {
1579      center=intersect(center,dummy);
1580      centlist[size(centlist)+1]=dummy;
1581    }
1582    dummy=0;
1583  }
1584  if(debug_Inters_E)
1585  {
1586    "----> In Inters_E: intersection of E_i";
1587    "maximal number of E_i encountered in:";
1588    center;
1589    "the components of this locus:";
1590    centlist;
1591    "maximal number of E_i from E^- intersecting simultaneously:",n;
1592    if(nonnormal)
1593    {
1594      "flag nonnormal is set";
1595    }
1596  }
1597  list retlist=center,n;
1598//-------------------------------------------------------------------------
1599// If n<=maxkk, then test if this is the case for all of E not just E_new
1600// using the pairs indicated by merkmon
1601//-------------------------------------------------------------------------
1602  int ntotal=n;
1603  if((n<=maxkk)&&(n<count2)&&(!nonnormal))
1604  {
1605//--- check kk-tuples
1606    for(kk=n+1;kk<=maxkk+1;kk++)
1607    {
1608      setring rcomb;
1609//--- check if there are combinations to be checked
1610      if(kk>size(merkmon))
1611      {
1612        setring rb;
1613        break;
1614      }
1615      if(size(merkmon[kk])!=0)
1616      {
1617        kill comblist;
1618        list comblist;
1619//--- transscribe tuples from  monomial notation to intvec notation
1620        for(jj=1;jj<=size(merkmon[kk]);jj++)
1621        {
1622          comblist[jj]=leadexp(merkmon[kk][jj]);
1623        }
1624        setring rb;
1625//--- check jj-th tuple from the list of kk-tuples
1626        for(jj=1;jj<=size(comblist);jj++)
1627        {
1628          test2=J;
1629          for(ii=1;ii<=nvars(rcomb);ii++)
1630          {
1631            if(comblist[jj][ii]==1)
1632            {
1633              test2=test2,E[ii];
1634            }
1635          }
1636          test2=std(test2);
1637//--- as soon as we found one we can proceed to the subsequent kk
1638          if(deg(test2[1])!=0)
1639          {
1640            ntotal=kk;
1641            if(dim(test2)-kkdiff!=maxkk-kk)
1642            {
1643              nonnormal=2;
1644              break;
1645            }
1646          }
1647        }
1648//--- if we already know that too many E_i intersect simultaneously,
1649//--- we need not proceed any further
1650        if(nonnormal)
1651        {
1652          break;
1653        }
1654      }
1655      else
1656      {
1657        setring rb;
1658        break;
1659      }
1660    }
1661  }
1662//-------------------------------------------------------------------------
1663// update the result accordingly and return it
1664//-------------------------------------------------------------------------
1665  if(maxkk<dimJ)
1666  {
1667    n=n+dimJ-maxkk;
1668    ntotal=ntotal+dimJ-maxkk;
1669  }
1670  retlist[2]=n;
1671  retlist[3]=ntotal;
1672  if(n<=dimJ)
1673  {
1674    retlist[4]=centlist;
1675    retlist[5]=merklist1;
1676    if(nonnormal)
1677    {
1678      retlist[6]=nonnormal;
1679    }
1680  }
1681  return(retlist);
1682}
1683///////////////////////////////////////////////////////////////////////////
1684
1685proc Delta(list BO)
1686"USAGE:  Delta (BO);
1687@*       BO = basic object, a list: ideal W,
1688@*                                  ideal J,
1689@*                                  intvec b,
1690@*                                  list Ex,
1691@*                                  ideal ab,
1692@*                                  intvec v,
1693@*                                  intvec w,
1694@*                                  matrix M
1695ASSUME:  R  = basering, a polynomial ring, W an ideal of R,
1696@*       J  = ideal containing W
1697COMPUTE: Delta-operator applied to J in the notation of
1698         [Bravo,Encinas,Villamayor]
1699RETURN:  ideal
1700EXAMPLE: example Delta;  shows an example
1701"
1702{
1703//---------------------------------------------------------------------------
1704// Initialization  and sanity checks
1705//---------------------------------------------------------------------------
1706   ideal W=BO[1];
1707   ideal J=BO[2];
1708   ideal C=simplify(reduce(J,std(W)),2);
1709   list LC;
1710   int n=nvars(basering);
1711//---------------------------------------------------------------------------
1712// Simple case: W is the empty set
1713//---------------------------------------------------------------------------
1714   if(size(W)==0)
1715   {
1716      C=C,jacob(J);
1717      C=std(C);
1718      return(C);
1719   }
1720//---------------------------------------------------------------------------
1721// General case: W is non-empty
1722// Step 1: Find a minor of the Jacobian of W which is not identically zero
1723//         and look at the complement of the zero-set given by this minor;
1724//         this leads to the system of local parameters
1725// Step 2: Form the derivatives w.r.t. this system of parameters
1726//---------------------------------------------------------------------------
1727//--- Step 1
1728   list re=findMinor(W);
1729   list L;
1730   int ii,i,j,l,k;
1731   J=C;
1732   ideal D=ideal(1);
1733   intvec v,w;
1734   ideal V;
1735   poly m;
1736
1737   for(ii=1;ii<=size(re);ii++)
1738   {
1739      C=J;
1740      L=re[ii];
1741      matrix A=L[1];  //(1/m)*A is the inverse matrix of the Jacobian of W
1742                      //corresponding to m
1743      m=L[2];  //a k- minor of jacob(W), not identically zero
1744                      //k=n-dim(W)
1745      V=L[3];  //the elements of W corresponding to m
1746      v=L[4];  //the indices of variables corresponding to m
1747      w=L[5];  //the indices of variables not corresponding to m
1748
1749//--- Step 2
1750//--- first some initialization depending on results of step 1
1751      k=size(V);
1752      matrix dg[1][k];
1753      matrix df[k][1];
1754//--- derivatives of the generators of J w.r.t. system of parameters
1755      for(i=1;i<=size(J);i++)
1756      {
1757         for(j=1;j<=n-k;j++)
1758         {
1759            for(l=1;l<=k;l++)
1760            {
1761               dg[1,l]=diff(V[l],var(w[j]));
1762               df[l,1]=diff(J[i],var(v[l]));
1763             }
1764             C=C,m*diff(J[i],var(w[j]))-dg*A*df;
1765         }
1766      }
1767//--- everything should live in W, not just in the intersection of
1768//--- D(m) with W
1769      C=C+W;
1770      C=sat(C,m);
1771//--- intersect ideal with previously computed ones to make sure that no
1772//--- components are lost
1773      D=intersect(D,C);
1774      kill dg,df,A;
1775   }
1776//--- return minimal set of generators of the result
1777   list li=mstd(D);
1778   D=li[2];
1779   if(size(li[1])<=size(D)){D=li[1];}
1780   return(D);
1781}
1782example
1783{ "EXAMPLE:";
1784   echo = 2;
1785   ring R=0,(x,y,z),dp;
1786
1787   ideal W=z^2-x;
1788   ideal J=x*y^2+x^3;
1789   intvec b=1;
1790   list E;
1791   ideal abb=maxideal(1);
1792   intvec v;
1793   intvec w=-1;
1794   matrix M;
1795
1796   list BO=W,J,b,E,abb,v,w,M;
1797
1798   Delta(BO);
1799}
1800
1801//////////////////////////////////////////////////////////////////////////////
1802static proc redMax(int k,ideal J)
1803"Internal procedure - no help and no example available
1804"
1805{
1806//--- reduce maxideal(k) by J, more efficient approach
1807    int i;
1808    ideal K=simplify(reduce(maxideal(1),J),2);
1809    for(i=2;i<=k;i++)
1810    {
1811       K=simplify(reduce(K*maxideal(1),J),2);
1812    }
1813    return(K);
1814}
1815
1816//////////////////////////////////////////////////////////////////////////////
1817static proc findMinor(ideal W)
1818"Internal procedure - no help and no example available
1819"
1820{
1821//---------------------------------------------------------------------------
1822// Initialization and sanity checks
1823//---------------------------------------------------------------------------
1824   list L;
1825   intvec v,w;
1826   ideal Wstd=std(W);
1827   int n=nvars(basering);   // total number of columns of Jacobian
1828   int k=n-dim(Wstd);       // size of minors of Jacobian
1829   int a=size(W);           // total number of rows of Jacobian
1830   matrix A[k][k];
1831   list LW=indexSet(a,k);   // set of tuples of k rows
1832   list LV=indexSet(n,k);   // set of tuples of k columns
1833   ideal IW,IV;
1834   int i,j,l,e;
1835   list re;
1836//---------------------------------------------------------------------------
1837// We need to know which minor corresponds to which variable and to which
1838// generator of W - therefore we cannot use the function minor()!
1839//---------------------------------------------------------------------------
1840//--- choose the generators which we want to differentiate
1841   for(i=1;i<=size(LW);i++)
1842   {
1843      IW=0;
1844      for(l=1;l<=a;l++)
1845      {
1846         if(LW[i][l]!=0){IW[size(IW)+1]=W[l];}
1847      }
1848//--- choose the variables by which to differentiate and apply diff
1849      for(j=1;j<=size(LV);j++)
1850      {
1851          IV=0;v=0;w=0;
1852          for(l=1;l<=n;l++)
1853          {
1854             if(LV[j][l]!=0)
1855             {
1856                v[size(v)+1]=l;
1857                IV[size(IV)+1]=var(l);
1858             }
1859             else
1860             {
1861                w[size(w)+1]=l;
1862
1863             }
1864          }
1865          A=diff(IV,IW);      // appropriate submatrix of Jacobian
1866//--- if the minor is non-zero, then it might be the one we need
1867//--- ==> put it in the list of candidates
1868          if(det(A)!=0)
1869          {
1870            v=v[2..size(v)];  // first entry is zero for technical reasons
1871            w=w[2..size(w)];  // first entry is zero for technical reasons
1872            L=inverse_L(A);
1873            L[3]=IW;
1874            L[4]=v;
1875            L[5]=w;
1876            re[size(re)+1]=L;
1877          }
1878      }
1879   }
1880//---------------------------------------------------------------------------
1881// return the result
1882//---------------------------------------------------------------------------
1883   return(re);
1884}
1885
1886/////////////////////////////////////////////////////////////////////////////
1887static proc indexSet(int a, int b)
1888"Internal procedure - no help and no example available
1889"
1890{
1891//---------------------------------------------------------------------------
1892// Find all tuples of size b containing pairwise distict elements from a
1893// list of a elements
1894//---------------------------------------------------------------------------
1895//**************************************************************************/
1896// Combinatorics is expensive in an interpreted language
1897// ==> shift it into the kernel
1898//**************************************************************************/
1899   def R=basering;
1900   list L;
1901   ring S=2,x(1..a),dp;
1902   ideal I=maxideal(b);
1903   int i;
1904   ideal J=x(1)^2;
1905   for(i=2;i<=a;i++){J=J,x(i)^2;}
1906   attrib(J,"isSB",1);
1907   I=reduce(I,J);
1908   I=simplify(I,2);
1909   for(i=1;i<=size(I);i++){L[i]=leadexp(I[i]);}
1910   setring R;
1911   return(L);
1912}
1913
1914/////////////////////////////////////////////////////////////////////////////
1915
1916proc DeltaList(list BO)
1917"USAGE:  DeltaList (BO);
1918@*       BO = basic object, a list: ideal W,
1919@*                                  ideal J,
1920@*                                  intvec b,
1921@*                                  list Ex,
1922@*                                  ideal ab,
1923@*                                  intvec v,
1924@*                                  intvec w,
1925@*                                  matrix M
1926ASSUME:  R  = basering, a polynomial ring, W an ideal of R,
1927@*       J  = ideal containing W
1928COMPUTE: Delta-operator iteratively applied to J in the notation of
1929         [Bravo,Encinas,Villamayor]
1930RETURN:  list l of length ((max w-ord) * b),
1931         l[i+1]=Delta^i(J)
1932EXAMPLE: example DeltaList;  shows an example
1933"
1934{
1935//----------------------------------------------------------------------------
1936// Iteratively apply proc Delta
1937//----------------------------------------------------------------------------
1938   int i;
1939   list L;
1940   ideal C=BO[2];
1941   while(deg(C[1])!=0)
1942   {
1943      L[size(L)+1]=C;
1944      C=Delta(BO);
1945      BO[2]=C;
1946   }
1947   return(L);
1948}
1949example
1950{
1951   "EXAMPLE:";
1952   echo = 2;
1953   ring R=0,(x,y,z),dp;
1954
1955   ideal W=z^2-x;
1956   ideal J=x*y^2+x^3;
1957   intvec b=1;
1958   list E;
1959   ideal abb=maxideal(1);
1960   intvec v;
1961   intvec w=-1;
1962   matrix M;
1963
1964   list BO=W,J,b,E,abb,v,w,M;
1965
1966   DeltaList(BO);
1967}
1968/////////////////////////////////////////////////////////////////////////////
1969proc CenterBM(list BM)
1970"USAGE:  CenterBM(BM);
1971@*       BM = object related to a presentation,
1972                            a list: ideal W,
1973@*                                  ideal J,
1974@*                                  intvec b,
1975@*                                  list Ex,
1976@*                                  ideal ab,
1977@*                                  intvec v,
1978@*                                  intvec w,
1979@*                                  matrix M
1980ASSUME:  R  = basering, a polynomial ring, W an ideal of R,
1981@*       J  = ideal containing W
1982COMPUTE: the center of the next blow-up of BM in the resolution algorithm
1983         of [Bierstone, Milman]
1984RETURN:  list l,
1985         l[1]: ideal describing the center
1986         l[2]: intvec w obtained in the process of determining l[1]
1987         l[3]: intvec b obtained in the process of determining l[1]
1988         l[4]: intmat invmat obtained in the process of determining l[1]
1989EXAMPLE: example CenterBM;  shows an example
1990"
1991{
1992//!!! NOCH NICHT IN BETRIEB
1993ERROR("Not implemented yet");
1994   int i,j;
1995   intmat tmat[2][1]=0,-1;
1996//--- re=center,E^- indices, b vector, n vector
1997   list re=ideal(1),BM[7],BM[3],tmat;
1998   ideal J=BM[2];
1999   if(size(J)==0)
2000   {
2001     re[1]=ideal(0);
2002     return(re);
2003   }
2004//--- find Delta^(b-1)(J)
2005   if(size(reduce(J,std(BM[1]),5))!=0)
2006   {
2007     list L=DeltaList(BM);
2008   }
2009   else
2010   {
2011     list L;
2012     L[1]=J;
2013   }
2014   if(!defined(debugCenter))
2015   {
2016     int debugCenter;
2017   }
2018   if(debugCenter)
2019   {
2020     "----> In Center: after DeltaList";
2021     "W";
2022     BM[1];
2023     "J";
2024     BM[2];
2025     "The Delta List:";
2026     L;
2027   }
2028   int b=size(L);
2029   if(b==0)
2030   {
2031//--- if J=W, we do not need to do anything
2032//--- returning center=1 marks this chart as completed
2033     return(re);
2034   }
2035//---------------------------------------------------------------------------
2036// check whether max ord is constant
2037//---------------------------------------------------------------------------
2038   if((BM[9][2,1]<0)||(BM[9][1,1]>b))
2039   {
2040//--- we are either at the beginning or the invariant has dropped
2041     intvec tempvec=size(BM[4]);
2042     BM[7]=tempvec;
2043//!!!! nur fuer hyperflaechen!!!!!!!!
2044     tempvec=b;
2045     BM[3]=tempvec;
2046//!!!! Ende !!!!!!!!!!!!
2047     kill tempvec;
2048     BM[9][1,1]=b;
2049     BM[9][2,1]=1;
2050   }
2051//---------------------------------------------------------------------------
2052// prepare for intersection with E_i
2053//---------------------------------------------------------------------------
2054   ideal C=L[b];
2055   re[2]=BM[7];
2056   re[3]=BM[3];
2057   BM[2]=C;
2058      if(debugCenter)
2059   {
2060     "----> In Center: before intersection with E_i:";
2061     "bmax:",b;
2062     "Sing(J,bmax):";
2063      C;
2064     "E:";
2065      BO[4];
2066     "list marking a priori known intersection properties:",BO[6];
2067     "index of last element of E^- in E:",BO[7][1];
2068   }
2069   list E=inters_E(BM);
2070// !!!!!!!!! Drop Redundant fehlt noch!!!!!!!!
2071//---------------------------------------------------------------------------
2072// Check whether it is a single point
2073//---------------------------------------------------------------------------
2074   ideal C1=std(ideal(L[b])+E[1]);
2075   if(dim(C1)==0)
2076   {
2077     if(size(E[4])==1)
2078     {
2079        tmat[1,1]=BM[9][1,1];
2080        tmat[2,1]=BM[9][2,1];
2081        re[4]=tmat;
2082        re[1]=radical(C1);
2083        return(re);
2084     }
2085   }
2086   if(size(BM[9])>2)
2087   {
2088      BM[9][1,2]=E[2];
2089      BM[9][2,2]=1;
2090   }
2091   else
2092   {
2093      intmat tempInt[2][1]=E[2],1;
2094      BM[9]=concatInt(BM[9],tempInt);
2095      kill tempInt;
2096   }
2097   BM[2]=J;
2098   list BM1=dropDim(BM);
2099   list BMlist,hilfList;
2100   ideal hilf;
2101   intvec tempvec;
2102
2103   if(!attrib(BM1[1],"isSB")){BM1[1]=std(BM1[1]);}
2104   for(i=1;i<=size(BM1[4]);i++)
2105   {
2106      hilf=simplify(reduce(BM1[4][i],BM1[1]),2);
2107      if(size(hilf)>1){"Problem with BM1[4]in CenterBM";~;}
2108      hilfList[i]=hilf[1];
2109   }
2110   for(i=1;i<=size(E[4]);i++)
2111   {
2112      BMlist[i]=BM1;
2113      for(j=size(E[5][i]);j>=1;j--)
2114      {
2115         if(E[5][i][j]!=0)
2116         {
2117            BMlist[i][2][size(BMlist[i][2])+1]=hilfList[j];
2118            BMlist[i][3][size(BMlist[i][3])+1]=1;
2119         }
2120         BMlist[i][4]=delete(BMlist[i][4],j);
2121         BMlist[i][6]=deleteInt(BMlist[i][6],j,0);
2122      }
2123      BMlist[i][7]=deleteInt(BMlist[i][7],1,-1);
2124      if(size(BMlist[i][9])>4)
2125      {
2126         intmat tempInt[2][ncols(BMlist[i][9])]=BMlist[i][9];
2127         intmat tempInt2[2][ncols(BMlist[i][9])-2]=
2128                 tempInt[1..2,3..ncols(BMlist[i][9])];
2129         BMlist[i][9]=tempInt2;
2130         kill tempInt,tempInt2;
2131      }
2132      else
2133      {
2134         BMlist[i][9]=tmat;
2135      }
2136   }
2137   kill hilfList;list hilfList;
2138   hilfList[1]=CenterTail(BMlist[1],C);
2139   intmat maxmat=hilfList[1][9];
2140   intvec maxiv=E[4][1];
2141   int pos=1;
2142   for(i=2;i<=size(E[4]);i++)
2143   {
2144      hilfList[i]=CenterTail(BMlist[i],C);
2145      if(invGreater(hilfList[i][4]),maxmat,E[4][i],maxiv)
2146      {
2147         maxmat=hilfList[i][4];
2148         maxiv=E[4][i];
2149         pos=i;
2150      }
2151   }
2152   re[1]=hilfList[pos][1];
2153   intmat tempint=BM[9];
2154   intmat tempint1[2][2]=tempint[1..2,1..2];
2155   re[4]=concatInt(tempint1,maxmat);
2156   re[2]=re[2][1],hilfList[pos][2];
2157   re[3]=b;
2158~;
2159   return(re);
2160}
2161example
2162{  "EXAMPLE:";
2163   echo = 2;
2164   ring R=0,(x,y),dp;
2165
2166   ideal W;
2167   ideal J=x2-y3;
2168   intvec b=1;
2169   list E;
2170   ideal abb=maxideal(1);
2171   intvec v;
2172   intvec w=-1;
2173   matrix M;
2174   intmat invmat[2][1]=0,-1;
2175
2176   list BM=W,J,b,E,abb,v,w,M,invmat;
2177
2178   CenterBM(BM);
2179}
2180
2181/////////////////////////////////////////////////////////////////////////////
2182static proc invGreater(intmat M1, intmat M2, intvec iv1, intvec iv2)
2183{
2184// Auxiliary procedure, BM-algorithm
2185   int i;
2186   for(i=1;i<=min(ncols(M1),ncols(M2));i++)
2187   {
2188      if(M1[2,i]==-1)
2189      {
2190         if(M1[1,i]==0){ERROR("Invariant not set");}
2191         if(M2[2,i]!=-1){return(1);}
2192         if(M2[1,i]==0){ERROR("Invariant not set");}
2193         break;
2194      }
2195      else
2196      {
2197         if(M2[2,i]==-1)
2198         {
2199            if(M2[1,i]==0){ERROR("Invariant not set");}
2200            return(0);
2201         }
2202         if(M1[1,i]*M2[2,i]!= M2[1,i]*M1[2,i])
2203         {
2204            return(M1[1,i]*M2[2,i]> M2[1,i]*M1[2,i]);
2205         }
2206      }
2207   }
2208   return(iv1>iv2);
2209}
2210/////////////////////////////////////////////////////////////////////////////
2211proc CenterTail(list BM, ideal C)
2212{
2213//!!! Auxiliary procedure, BM-algorithm
2214//!!!!!!!!Rueckgabe im Zentrumsformat
2215  int i,j,bmin;
2216  int alpha=lcm(BM[3]);
2217  vector w;
2218  list re;
2219  if(size(BM[2])==0)
2220  {
2221    re[1]=C+BM[1];
2222    intvec tvec;
2223    re[3]=tvec;
2224    intmat tmat[2][1]=-1,-1;
2225    re[4]=tmat;
2226    tvec=size(BM[4]);
2227    re[2]=tvec;
2228    return(re);
2229  }
2230  for(i=1;i<=size(BM[3]);i++)
2231  {
2232     if(BM[2][i]!=0)
2233     {
2234       w[size(w)+1]=BM[2][i]^(alpha/BM[3][i]);
2235     }
2236  }
2237  module M=w;
2238  intvec satex;
2239  list satList;
2240  for(i=1;i<=size(BM[4]);i++)
2241  {
2242     satList=sat_with_exp(M,BM[4][i]);
2243     satex[i]=satList[2];
2244     M=satList[1];
2245  }
2246//!!!!Hilfsobjekt G bilden!!!!!!!!!!!!!!!!
2247//!!!!Hilfsobjekt H,codim -1 bilden!!!!!!!!!!!!!!!!
2248//!!!! ???? an welcher stelle?????????
2249  list deltaL;
2250  list BMtemp=BM;
2251  for(i=1;i<=nrows(M[1]);i++)
2252  {
2253     BMtemp[2]=ideal(M[1][i])+BMtemp[1];
2254     deltaL[i]=DeltaList(BMtemp);
2255     if(i==1)
2256     {
2257        bmin=size(deltaL[i]);
2258     }
2259     else
2260     {
2261        bmin=min(size(deltaL[i]),bmin);
2262     }
2263  }
2264  if(bmin==0)
2265  {
2266     re[1]=C+BM[1];
2267     intvec tvec;
2268     re[3]=tvec;
2269     if((BM[9][2,1]==-1)||(BM[9][1,1]!=0))
2270     {
2271        tvec=size(BM[4]);
2272        re[2]=tvec;
2273        intmat tmat[2][1]=0,1;
2274        re[4]=tmat;
2275     }
2276     else
2277     {
2278        re[2]=BM[7];
2279        re[4]=BM[9];
2280     }
2281     return(re);
2282  }
2283  ideal Ctemp=ideal(1);
2284  while(deg(Ctemp[1])==0)
2285  {
2286    Ctemp=C;
2287    for(i=1;i<=nrows(M[1]);i++)
2288    {
2289       Ctemp=Ctemp,deltaL[i][bmin];
2290    }
2291    Ctemp=std(Ctemp);
2292    bmin--;
2293    if(bmin==0){ERROR("empty set");}
2294  }
2295  //!!!!!!!!!!!!!Invariante ist bmin/alpha
2296  // naechster Eintrag s_i wie in CenterBM
2297  // dann dropDim  ....
2298}
2299
2300/////////////////////////////////////////////////////////////////////////////
2301static proc deleteInt(intvec v,int i,int ini)
2302{
2303//!!! Should be in kernel of Singular
2304//--- delete i-th entry in intvec v,
2305//--- if necessary reinitializing v with value ini
2306   int s=size(v);
2307   intvec w;
2308   if((i<s)&&(i>1)){w=v[1..i-1],v[i+1..s];}
2309   if(s==1){w=ini;return(w);}
2310   if(i==1){w=v[2..s];}
2311   if(i==s){w=v[1..s-1];}
2312   return(w);
2313}
2314/////////////////////////////////////////////////////////////////////////////
2315static proc concatInt(intmat A, intmat B)
2316{
2317//!!! Should be in kernel of Singular
2318//--- concatenate two intmats
2319  if(nrows(A)!=nrows(B)){ERROR("could not concat, wrong number of rows");}
2320  intmat tempmat[nrows(A)][ncols(A)+ncols(B)];
2321  tempmat[1..nrows(A),1..ncols(A)]=A[1..nrows(A),1..ncols(A)];
2322  tempmat[1..nrows(A),ncols(A)+1..ncols(tempmat)]=B[1..nrows(A),1..ncols(B)];
2323  return(tempmat);
2324}
2325/////////////////////////////////////////////////////////////////////////////
2326proc dropDim(list BM)
2327{
2328ERROR("Not implemented yet");
2329}
2330/////////////////////////////////////////////////////////////////////////////
2331proc CenterBO(list BO,list #)
2332"USAGE:  CenterBO(BO);
2333@*       BO = basic object, a list: ideal W,
2334@*                                  ideal J,
2335@*                                  intvec b,
2336@*                                  list Ex,
2337@*                                  ideal ab,
2338@*                                  intvec v,
2339@*                                  intvec w,
2340@*                                  matrix M
2341ASSUME:  R  = basering, a polynomial ring, W an ideal of R,
2342@*       J  = ideal containing W
2343COMPUTE: the center of the next blow-up of BO in the resolution algorithm
2344         of [Bravo,Encinas,Villamayor]
2345RETURN:  list l,
2346         l[1]: ideal describing the center@*
2347         l[2]: intvec w obtained in the process of determining l[1]@*
2348         l[3]: intvec b obtained in the process of determining l[1]@*
2349         l[4]: intvec inv obtained in the process of determining l[1]
2350EXAMPLE: example CenterBO;  shows an example
2351"
2352{
2353//---------------------------------------------------------------------------
2354// Initialization  and sanity checks
2355//---------------------------------------------------------------------------
2356   int i,bo7save;
2357   intvec tvec;
2358//--- re=center,E^- indices, b vector, n vector
2359   list re=ideal(1),BO[7],BO[3],tvec;
2360   ideal J=BO[2];
2361   if(size(J)==0)
2362   {
2363     re[1]=ideal(0);
2364     return(re);
2365   }
2366//--- find Delta^(b-1)(J)
2367   if(size(reduce(J,std(BO[1])))!=0)
2368   {
2369     list L=DeltaList(BO);
2370   }
2371   else
2372   {
2373     list L;
2374     L[1]=J;
2375   }
2376   if(!defined(debugCenter))
2377   {
2378     int debugCenter;
2379   }
2380   if(debugCenter)
2381   {
2382     "----> In Center: after DeltaList";
2383     "W";
2384     BO[1];
2385     "J";
2386     BO[2];
2387     "The Delta List:";
2388     L;
2389   }
2390   int b=size(L);
2391   if(b==0)
2392   {
2393//--- if J=W, we do not need to do anything
2394//--- returning center=1 marks this chart as completed
2395     return(re);
2396   }
2397//---------------------------------------------------------------------------
2398// check whether max w-ord is constant
2399//---------------------------------------------------------------------------
2400   if(b==BO[3][1])
2401   {
2402//--- max w-ord is constant
2403     if(BO[7][1]==-1)
2404     {
2405//--- first got its value in the previous step ==> initialize BO[7]
2406       tvec[1]=size(BO[4])-1;
2407       for(i=2;i<=size(BO[7]);i++)
2408       {
2409         tvec[i]=BO[7][i];
2410       }
2411       re[2]=tvec;
2412       BO[7]=tvec;
2413     }
2414   }
2415   else
2416   {
2417//--- max w-ord changed ==> reset BO[7], correct BO[3]
2418     tvec[1]=-1;
2419     re[2]=tvec;
2420     BO[7]=tvec;
2421     tvec[1]=b;
2422     BO[3]=tvec;
2423     if(defined(invSat))
2424     {
2425        invSat[2]=intvec(0);
2426     }
2427   }
2428   re[3]=BO[3];
2429//---------------------------------------------------------------------------
2430// reduce from case 2 to case 1 of [Bravo, Encinas, Villamayor]
2431//---------------------------------------------------------------------------
2432   ideal C=L[b];
2433   BO[2]=C;
2434   if(debugCenter)
2435   {
2436     "----> In Center: before intersection with E_i:";
2437     "bmax:",b;
2438     "Sing(J,bmax):";
2439      C;
2440     "E:";
2441      BO[4];
2442     "list marking a priori known intersection properties:",BO[6];
2443     "index of last element of E^- in E:",BO[7][1];
2444   }
2445//--- is intermediate result in iteration already good?
2446//--- return it to calling proc CenterBO
2447   if(size(#)>0)
2448   {
2449     if(#[1]==2)
2450     {
2451       re[1]=C;
2452       kill tvec;
2453       intvec tvec=re[2][1];
2454       re[2]=tvec;
2455       kill tvec;
2456       intvec tvec=re[3][1];
2457       re[3]=tvec;
2458       kill tvec;
2459       intvec tvec;
2460       re[4]=tvec;
2461       return(re);
2462     }
2463   }
2464//--- do the reduction to case 1
2465   list E=inters_E(BO);
2466//--- if J is smooth and not too many E_i intersect simultaneously, let us
2467//--- try to drop redundant components of the candidate for the center
2468   if((b==1)&&(size(E)>3))
2469   {
2470//--- if J is not smooth we do not want to drop any information
2471     if((size(E[4])>0) && (dim(std(slocusE(BO[2])))<0))
2472     {
2473//--- BO[2]==J because b==1
2474//--- DropRedundant is the counterpart to DropCoeff
2475//--- do not leave out one of them separately!!!
2476      E=DropRedundant(BO,E);
2477      if(size(E)==1)
2478       {
2479         kill tvec;
2480         intvec tvec=re[2][1];
2481         re[2]=tvec;
2482         tvec[1]=re[3][1];
2483         re[3]=tvec;
2484         tvec[1]=re[4][1];
2485         re[4]=tvec;
2486         re[1]=E[1];
2487         return(re);
2488       }
2489     }
2490   }
2491//--- set n correctly
2492   if(E[2]<BO[9][1])
2493   {
2494//--- if n dropped, the subsequent Coeff-object will not be the same
2495//--- ===> set BO[3][2] to zero to make sure that no previous data is used
2496      if(defined(tvec)) {kill tvec;}
2497      intvec tvec=BO[7][1],-1;
2498      BO[7]=tvec;
2499      tvec=BO[3][1],0;
2500      BO[3]=tvec;
2501      if(defined(invSat))
2502      {
2503         invSat[2]=intvec(0);
2504      }
2505   }
2506   re[4][1]=E[2];
2507   C=E[1]^b+J;
2508   C=mstd(C)[2];
2509   ideal C1=std(ideal(L[b])+E[1]);
2510   if(debugCenter)
2511   {
2512     "----> In Center: reduction of case 2 to case 1";
2513     "Output of inters_E, after dropping redundant components:";
2514      E;
2515     "result of intersection with E^-, i.e.(E^-)^b+J:";
2516     C;
2517     "candidate for center:";
2518     C1;
2519   }
2520//---------------------------------------------------------------------------
2521// Check whether we have a hypersurface component
2522//---------------------------------------------------------------------------
2523   if(dim(C1)==dim(std(BO[1]))-1)
2524   {
2525     if((size(reduce(J,C1,5))==0)&&(size(reduce(C1,std(J),5))==0))
2526     {
2527//--- C1 equals J and is of codimension 1 in W
2528        re[1]=C1;
2529     }
2530     else
2531     {
2532//--- C1 has a codimension 1 (in W) component
2533        re[1]=std(equiRadical(C1));
2534     }
2535     kill tvec;
2536     intvec tvec=re[2][1];
2537     re[2]=tvec;
2538     tvec[1]=re[3][1];
2539     re[3]=tvec;
2540     tvec[1]=re[4][1];
2541     re[4]=tvec;
2542//--- is the codimension 1 component a good choice or do we need to reset
2543//--- the information from the previous steps
2544     if(transversalT(re[1],BO[4]))
2545     {
2546        if(size(E)>2)
2547        {
2548          if(E[3]>E[2])
2549          {
2550            if(defined(shortcut)){kill shortcut;}
2551            list shortcut=ideal(0),size(BO[4]),BO[7];
2552            export(shortcut);
2553          }
2554        }
2555        return(re);
2556     }
2557
2558     ERROR("reset in Center, please send the example to the authors.");
2559   }
2560//---------------------------------------------------------------------------
2561// Check whether it is a single point
2562//---------------------------------------------------------------------------
2563   if(dim(C1)==0)
2564   {
2565      C1=std(radical(C1));
2566      if(vdim(C1)==1)
2567      {
2568//--- C1 is one point
2569        re[1]=C1;
2570        kill tvec;
2571        intvec tvec=re[2][1];
2572        re[2]=tvec;
2573        kill tvec;
2574        intvec tvec=re[3][1];
2575        re[3]=tvec;
2576        return(re);
2577      }
2578    }
2579//---------------------------------------------------------------------------
2580// Prepare input for forming the Coeff-Ideal
2581//---------------------------------------------------------------------------
2582   BO[2]=C;
2583   if(size(BO[2])>5)
2584   {
2585      BO[2]=mstd(BO[2])[2];
2586   }
2587//--- drop leading entry of BO[3]
2588   tvec=BO[3];
2589   if(size(tvec)>1)
2590   {
2591     tvec=tvec[2..size(tvec)];
2592     BO[3]=tvec;
2593   }
2594   else
2595   {
2596     BO[3][1]=0;
2597   }
2598   tvec=BO[9];
2599   if(size(tvec)>1)
2600   {
2601     tvec=tvec[2..size(tvec)];
2602     BO[9]=tvec;
2603   }
2604   else
2605   {
2606     BO[9][1]=0;
2607   }
2608   bo7save=BO[7][1];          // original value needed for result
2609   if(defined(shortcut))
2610   {
2611     if((bo7save!=shortcut[3][1])&&(size(shortcut[3])!=1))
2612     {
2613       kill shortcut;
2614     }
2615     else
2616     {
2617       shortcut[2]=shortcut[2]-bo7save;
2618       tvec=shortcut[3];
2619       if(size(tvec)>1)
2620       {
2621         tvec=tvec[2..size(tvec)];
2622         shortcut[3]=tvec;
2623       }
2624       else
2625       {
2626         shortcut[3]=intvec(shortcut[2]);
2627       }
2628     }
2629   }
2630   if(BO[7][1]>-1)
2631   {
2632//--- drop E^- and the corresponding information from BO[6]
2633     for(i=1;i<=BO[7][1];i++)
2634     {
2635       BO[4]=delete(BO[4],1);
2636       intvec bla1=BO[6];
2637       BO[6]=intvec(bla1[2..size(bla1)]);
2638       kill bla1;
2639     }
2640//--- drop leading entry of BO[7]
2641     tvec=BO[7];
2642     if(size(tvec)>1)
2643     {
2644       tvec=tvec[2..size(tvec)];
2645       BO[7]=tvec;
2646     }
2647     else
2648     {
2649       BO[7][1]=-1;
2650     }
2651   }
2652   else
2653   {
2654     if(BO[7][1]==-1)
2655     {
2656       list tplist;
2657       BO[4]=tplist;
2658       kill tplist;
2659     }
2660   }
2661   if(debugCenter)
2662   {
2663     "----> In Center: Input to Coeff";
2664     "b:",b;
2665     "BO:";
2666     BO;
2667   }
2668//--- prepare the third entry of the invariant tuple
2669   int invSatSave=invSat[2][1];
2670   tvec=invSat[2];
2671   if(size(tvec)>1)
2672   {
2673     tvec=tvec[2..size(tvec)];
2674     invSat[2]=tvec;
2675   }
2676   else
2677   {
2678     invSat[2][1]=0;
2679   }
2680//---------------------------------------------------------------------------
2681// Form the Coeff-ideal, if possible and useful; otherwise use the previous
2682// candidate for the center
2683//---------------------------------------------------------------------------
2684   list BO1=Coeff(BO,b);
2685   if(debugCenter)
2686   {
2687     "----> In Center: Output of Coeff";
2688     BO1;
2689   }
2690//--- Coeff returns int if something went wrong
2691   if(typeof(BO1[1])=="int")
2692   {
2693      if(BO1[1]==0)
2694      {
2695//--- Coeff ideal was already resolved
2696        re[1]=C1;
2697        return(re);
2698      }
2699      else
2700      {
2701//--- no global hypersurface found
2702        re=CoverCenter(BO,b,BO1[2]);
2703        kill tvec;
2704        intvec tvec=invSatSave;
2705        for(i=1;i<=size(invSat[2]);i++)
2706        {
2707           tvec[i+1]=invSat[2][i];
2708        }
2709        invSat[2]=tvec;
2710        return(re);
2711      }
2712   }
2713   int coeff_invar;
2714   ideal Idropped=1;
2715//--- if b=1 drop redundant components of the Coeff-ideal
2716   if(b==1)
2717   {
2718//--- Counterpart to DropRedundant -- do not leave out one of them separately
2719     Idropped=DropCoeff(BO1);         // blow-up in these components
2720                                      // is unnecessary
2721   }
2722//--- to switch off DropCoeff, set Idropped=1;
2723   BO1[2]=sat(BO1[2],Idropped);
2724   if(deg(BO1[2][1])==0)
2725   {
2726//--- Coeff ideal is trivial
2727     C1=radical(C1);
2728     ideal C2=sat(C1,Idropped);
2729     if(deg(std(C2)[1])!=0)
2730     {
2731        C1=C2;
2732     }
2733//Aenderung: Strategie: nur im Notfall ganze except. Divisoren
2734     if(deg(std(BO1[2])[1])==0)
2735     {
2736       list BOtemp=BO;
2737       int bo17save=BO1[7][1];
2738       BOtemp[7]=0;
2739       BO1=Coeff(BOtemp,b,int(0));
2740       BO1[2]=sat(BO1[2],Idropped);
2741       if(deg(std(BO1[2])[1])==0)
2742       {
2743//--- there is really nothing left to do for the Coeff ideal
2744//--- the whole original BO1[2], i.e. Idropped, is the upcoming center
2745          re[1]=Idropped;
2746          re[2]=intvec(bo7save);
2747          re[3]=intvec(b);
2748          re[4]=intvec(E[2]);
2749          return(re);
2750       }
2751       if(deg(std(slocus(radical(BO1[2])))[1])==0)
2752       {
2753          re[1]=BO1[2];
2754//          re[2]=intvec(bo7save,BO1[7][1]);
2755          re[2]=intvec(bo7save,bo17save);
2756          re[3]=intvec(b,1);
2757          re[4]=intvec(E[2],1);
2758          invSat[2]=intvec(1,0);
2759          return(re);
2760       }
2761//!!! effizienter machen???
2762       list pr=primdecGTZ(BO1[2]);
2763       ideal Itemp1=1;
2764       int aa,bb;
2765       for(aa=1;aa<=size(pr);aa++)
2766       {
2767          if(dim(std(pr[aa][2])) < (dim(std(BO1[1]))-1))
2768          {
2769//--- drop components which are themselves exceptional diviosrs
2770             Itemp1=intersect(Itemp1,pr[aa][1]);
2771          }
2772       }
2773       if(deg(std(Itemp1)[1])!=0)
2774       {
2775//--- treat the remaining components of the weak Coeff ideal
2776          BO1[2]=Itemp1;
2777       }
2778       BO1[7]=BO[7];
2779       for(aa=1;aa<=size(BO1[4]);aa++)
2780       {
2781         if(deg(std(BO1[4][aa])[1])==0){aa++;continue;}
2782         if(defined(satlist)){kill satlist;}
2783         list satlist=sat_with_exp(BO1[2],BO1[4][aa]+BO1[1]);
2784         if(deg(std(satlist[1])[1])==0)
2785         {
2786            coeff_invar++;
2787            if(satlist[2]!=0)
2788            {
2789              for(bb=1;bb<=satlist[2]-1;bb++)
2790              {
2791                 BO1[2]=quotient(BO1[2],BO1[4][aa]+BO1[1]);
2792              }
2793            }
2794            else
2795            {
2796              ERROR("J of temporary object had unexpected value;
2797                     please send this example to the authors.");
2798            }
2799         }
2800         else
2801         {
2802            BO1[2]=satlist[1];
2803         }
2804       }
2805       if(deg(std(Itemp1)[1])==0)
2806       {
2807          re[1]=BO1[2];
2808          re[2]=intvec(bo7save,BO1[7][1]);
2809          re[3]=intvec(b,1);
2810          re[4]=intvec(E[2],1);
2811          invSat[2]=intvec(1,0);
2812          return(re);
2813       }
2814       kill aa,bb;
2815     }
2816   }
2817   if(invSatSave<coeff_invar)
2818   {
2819     invSatSave=coeff_invar;
2820   }
2821//---------------------------------------------------------------------------
2822// Determine Center of Coeff-ideal and use it as the new center
2823//---------------------------------------------------------------------------
2824   if(!defined(templist))
2825   {
2826     if(size(BO1[2])>5)
2827     {
2828        BO1[2]=mstd(BO1[2])[2];
2829     }
2830     list templist=CenterBO(BO1,2);
2831//--- only a sophisticated guess of a good center computed by
2832//--- leaving center before intersection with the E_i.
2833//--- whether the guess was good, is stored in 'good'.
2834//--- (this variant saves charts in cases like the Whitney umbrella)
2835     list E0,E1;
2836
2837     ideal Cstd=std(radical(templist[1]));
2838     int good=((deg(std(slocusE(Cstd))[1])==0)&&(dim(std(BO1[2]))<=2));
2839//if(defined(satlist)){good=0;}
2840     if(good)
2841     {
2842        for(i=1;i<=size(BO[4]);i++)
2843        {
2844           if((deg(BO[4][i][1])>0)&&(size(reduce(BO[4][i],Cstd,5))!=0))
2845           {
2846              E0[size(E0)+1]=BO[4][i]+Cstd;
2847              E1[size(E1)+1]=BO[4][i];
2848           }
2849        }
2850        good=transversalT(Cstd,E1);
2851        if(good)
2852        {
2853           good=normalCross(E0);
2854        }
2855     }
2856     if(good)
2857     {
2858        list templist2=CenterBO(BO1,1);
2859        if(dim(std(templist2[1]))!=dim(Cstd))
2860        {
2861           templist[1]=Cstd;
2862           if(defined(shortcut)){kill shortcut;}
2863           list shortcut=ideal(0),size(BO1[4]),templist[2];
2864           export(shortcut);
2865        }
2866        else
2867        {
2868           templist=templist2;
2869        }
2870        kill templist2;
2871     }
2872     else
2873     {
2874//--- sophisticated guess was wrong, follow Villamayor's approach
2875        kill templist;
2876        list templist=CenterBO(BO1,1);
2877     }
2878   }
2879   if((dim(std(templist[1]))==dim(std(BO1[1]))-1)
2880       &&(size(templist[4])==1))
2881   {
2882     if(templist[4][1]==0)
2883     {
2884        for(i=1;i<=size(BO1[4]);i++)
2885        {
2886           if(size(reduce(templist[1],std(BO1[4][i]),5))==0)
2887           {
2888              templist[4][1]=1;
2889              break;
2890           }
2891        }
2892     }
2893   }
2894//!!! subsequent line should be deleted
2895//if(defined(satlist)){templist[3][1]=BO[3][1];}
2896   if(debugCenter)
2897   {
2898     "----> In Center: Iterated Center returned:";
2899     templist;
2900   }
2901//--------------------------------------------------------------------------
2902// set up the result and return it
2903//--------------------------------------------------------------------------
2904   re[1]=templist[1];
2905   kill tvec;
2906   intvec tvec;
2907   tvec[1]=bo7save;
2908   for(i=1;i<=size(templist[2]);i++)
2909   {
2910     tvec[i+1]=templist[2][i];
2911   }
2912   re[2]=tvec;
2913   if(defined(shortcut))
2914   {
2915      shortcut[2]=shortcut[2]+bo7save;
2916      shortcut[3]=tvec;
2917   }
2918   kill tvec;
2919   intvec tvec;
2920   tvec[1]=invSatSave;
2921   for(i=1;i<=size(invSat[2]);i++)
2922   {
2923      tvec[i+1]=invSat[2][i];
2924   }
2925   invSat[2]=tvec;
2926   kill tvec;
2927   intvec tvec;
2928   tvec[1]=b;
2929   for(i=1;i<=size(templist[3]);i++)
2930   {
2931     tvec[i+1]=templist[3][i];
2932   }
2933   re[3]=tvec;
2934   kill tvec;
2935   intvec tvec;
2936   tvec[1]=E[2];
2937   for(i=1;i<=size(templist[4]);i++)
2938   {
2939     tvec[i+1]=templist[4][i];
2940   }
2941   re[4]=tvec;
2942
2943   return(re);
2944}
2945example
2946{  "EXAMPLE:";
2947   echo = 2;
2948   ring R=0,(x,y),dp;
2949
2950   ideal W;
2951   ideal J=x2-y3;
2952   intvec b=1;
2953   list E;
2954   ideal abb=maxideal(1);
2955   intvec v;
2956   intvec w=-1;
2957   matrix M;
2958
2959   list BO=W,J,b,E,abb,v,w,M,v;
2960
2961   CenterBO(BO);
2962}
2963//////////////////////////////////////////////////////////////////////////////
2964static proc CoverCenter(list BO,int b, ideal Jb)
2965{
2966//----------------------------------------------------------------------------
2967// Initialization
2968//----------------------------------------------------------------------------
2969   def R=basering;
2970   int i,j,k;
2971   intvec merk,merk2,maxv,fvec;
2972   list L,ceList,re;
2973   ceList[1]=ideal(0);
2974   poly @p,@f;
2975   ideal K,dummy;
2976   if(!attrib(BO[2],"isSB"))
2977   {
2978     BO[2]=std(BO[2]);
2979   }
2980   for(i=1;i<=size(Jb);i++)
2981   {
2982      list tempmstd=mstd(slocus(Jb[i]));
2983      if(size(tempmstd[1])>size(tempmstd[2]))
2984      {
2985         dummy=tempmstd[2];
2986      }
2987      else
2988      {
2989         dummy=tempmstd[1];
2990      }
2991      kill tempmstd;
2992      L[i]=dummy;
2993      K=K,dummy;
2994   }
2995   K=simplify(K,2);
2996//---------------------------------------------------------------------------
2997// The intersection of the singular loci of the L[i] is empty.
2998// Find a suitable open covering of the affine chart, such that a global
2999// hypersurface can be found in each open set.
3000//---------------------------------------------------------------------------
3001   matrix M=lift(K,ideal(1));
3002   j=1;
3003   for(i=1;i<=nrows(M);i++)
3004   {
3005      if(M[i,1]!=0)
3006      {
3007         merk[size(merk)+1]=i;
3008         fvec[size(merk)]=j;
3009      }
3010      if((i-k)==size(L[j]))
3011      {
3012        k=i;
3013        j++;
3014      }
3015   }
3016//--------------------------------------------------------------------------
3017// Find a candidate for the center in each open set
3018//--------------------------------------------------------------------------
3019//--- first entry of merk is 0 by construction of merk
3020   for(i=2;i<=size(merk);i++)
3021   {
3022//--- open set is D(@p)
3023       @p=K[merk[i]];
3024//--- hypersurface is V(@f)
3025       @f=Jb[fvec[i]];
3026       ring R1 = create_ring(ring_list(R)[1], "(@y,"+varstr(R)+")", "dp", "no_minpoly");
3027       poly p=imap(R,@p);
3028       poly f=imap(R,@f);
3029       list @ce;
3030       list BO=imap(R,BO);
3031       BO[1]=BO[1]+ideal(@y*p-1);
3032       BO[2]=BO[2]+ideal(@y*p-1);
3033       for(j=1;j<=size(BO[4]);j++)
3034       {
3035          BO[4][j]=BO[4][j]+ideal(@y*p-1);
3036       }
3037//--- like usual Coeff, but hypersurface is already known
3038       list BO1=SpecialCoeff(BO,b,f);
3039//--- special situation in SpecialCoeff are marked by an error code of
3040//--- type int
3041       if(typeof(BO1[1])=="int")
3042       {
3043         if(BO1[1]==0)
3044         {
3045//--- Coeff ideal was already resolved
3046           @ce[1]=BO[2];
3047           @ce[2]=BO[7];
3048           @ce[3]=BO[3];
3049         }
3050         else
3051         {
3052           if(BO[3]!=0)
3053           {
3054//--- intersections with E do not meet conditions ==> reset
3055              ERROR("reset in Coeff, please send the example to the authors");
3056           }
3057         }
3058       }
3059       else
3060       {
3061//--- now do the recursion as usual
3062         @ce=CenterBO(BO1);
3063       }
3064//---------------------------------------------------------------------------
3065// Go back to the whole affine chart and form a suitable union of the
3066// candidates
3067//---------------------------------------------------------------------------
3068//--- pass from open set to the whole affine chart by taking the closure
3069       @ce[1]=eliminate(@ce[1],@y);
3070       setring R;
3071       ceList[i]=imap(R1,@ce);
3072//--- set up invariant vector and determine maximum value of it
3073       if(size(ceList[i][3])==size(ceList[i][4]))
3074       {
3075          kill merk2,maxv;
3076          intvec merk2,maxv;
3077          for(j=1;j<=size(ceList[i][3]);j++)
3078          {
3079            merk2[2*j-1]=ceList[i][3][j];
3080            merk2[2*j]=ceList[i][4][j];
3081            ceList[i][5]=merk2;
3082            if(maxv<merk2)
3083            {
3084               maxv=merk2;
3085            }
3086          }
3087       }
3088       else
3089       {
3090          ERROR("This situation should not occur, please send the example
3091                 to the authors.");
3092       }
3093       kill R1;
3094   }
3095   kill merk2;
3096   intvec merk2=-2;
3097//--- form the union of the components of the center with maximum invariant
3098   for(i=1;i<=size(ceList);i++)
3099   {
3100     if(size(reduce(ceList[i][1],BO[2],5))==0)
3101     {
3102//--- already resolved ==> ignore
3103       i++;
3104       continue;
3105     }
3106     if(ceList[i][5]==maxv)
3107     {
3108        if(merk2!=ceList[i][2])
3109        {
3110//--- E^- not of the same size as before resp. initialization
3111          if(merk2[1]==-2)
3112          {
3113//--- initialization: save size of E^-
3114            merk2=ceList[i][2];
3115            re[1]=ceList[i][1];
3116            re[2]=ceList[i][2];
3117            re[3]=ceList[i][3];
3118            re[4]=ceList[i][4];
3119          }
3120          else
3121          {
3122//--- otherwise ignore
3123            i++;
3124            continue;
3125          }
3126        }
3127        else
3128        {
3129          re[1]=intersect(re[1],ceList[i][1]);
3130        }
3131     }
3132   }
3133//--------------------------------------------------------------------------
3134// Perform last checks and return the result
3135//--------------------------------------------------------------------------
3136   if(size(re)!=4)
3137   {
3138//--- oops: already resolved in all open sets
3139     re[1]=BO[2];
3140     re[2]=-1;
3141     re[3]=0;
3142     re[4]=intvec(0);
3143   }
3144   return(re);
3145}
3146//////////////////////////////////////////////////////////////////////////////
3147static proc SpecialCoeff(list BO,int b,poly f)
3148{
3149//----------------------------------------------------------------------------
3150// Coeff with given hypersurface -- no checks of the hypersurface performed
3151//----------------------------------------------------------------------------
3152   int i,ch;
3153   int e=int(factorial(b));
3154   ideal C;
3155   list L=DeltaList(BO);
3156   int d=size(L);
3157//--- set up ideal
3158   for(i=0;i<b;i++)
3159   {
3160      C=C+L[i+1]^(e/(b-i));
3161   }
3162//--- move to hypersurface V(Z)
3163   ideal Z=f;
3164   C=C,Z;
3165   BO[1]=BO[1]+Z;
3166   BO[2]=C;
3167   for(i=1;i<=size(BO[4]);i++)
3168   {
3169      BO[6][i]=0;             // reset intersection indicator
3170      BO[4][i]=BO[4][i]+Z;    // intersect the E_i
3171      BO[2]=sat(BO[2],BO[4][i]+BO[1]);
3172                              // "strict transform" of J w.r.t E, not "total"
3173   }
3174   return(BO);
3175}
3176
3177//////////////////////////////////////////////////////////////////////////////
3178static proc DropCoeff(list BO)
3179"Internal procedure - no help and no example available
3180"
3181{
3182//--- Initialization
3183  int i,j;
3184  list pr=minAssGTZ(BO[2]);
3185  ideal I=BO[2];
3186  ideal Itemp;
3187  ideal Idropped=1;
3188//--- Tests
3189  for(i=1;i<=size(pr);i++)
3190  {
3191     if(i>size(pr))
3192     {
3193//--- the continue statement does not test the loop condition *sigh*
3194        break;
3195     }
3196     if(deg(std(slocus(pr[i]))[1])!=0)
3197     {
3198//--- this component is singular ===> we still need it
3199        i++;
3200        continue;
3201     }
3202     Itemp=sat(I,pr[i]);
3203     if(deg(std(Itemp+pr[i])[1])!=0)
3204     {
3205//--- this component is not disjoint from the other ones ===> we still need it
3206        i++;
3207        continue;
3208     }
3209     if(!transversalT(pr[i],BO[4]))
3210     {
3211//--- this component does not meet one of the remaining E_i transversally
3212//--- ===> we still need it
3213        i++;
3214        continue;
3215     }
3216     if(!normalCross(BO[4],pr[i]))
3217     {
3218//--- this component is not normal crossing with the remaining E_i
3219//--- ===> we still need it
3220        i++;
3221        continue;
3222     }
3223     if(defined(EE)){kill EE;}
3224     list EE;
3225     for(j=1;j<=size(BO[4]);j++)
3226     {
3227        EE[j]=BO[4][j]+pr[i];
3228     }
3229     if(!normalCross(EE))
3230     {
3231//--- we do not have a normal crossing situation for this component after all
3232//--- ===> we still need it
3233        i++;
3234        continue;
3235     }
3236     Idropped=intersect(Idropped,pr[i]);
3237     I=Itemp;
3238  }
3239  return(Idropped);
3240}
3241
3242//////////////////////////////////////////////////////////////////////////////
3243static proc DropRedundant(list BO,list E)
3244"Internal procedure - no help and no example available
3245"
3246{
3247//---------------------------------------------------------------------------
3248// Initialization and sanity checks
3249//---------------------------------------------------------------------------
3250  int ii,jj,kkdiff,nonnormal,ok;
3251  ideal testid,dummy;
3252  ideal center;
3253  intvec transverse,dontdrop,zerovec;
3254  transverse[size(BO[4])]=0;
3255  dontdrop[size(E[4])]=0;
3256  zerovec[size(E[4])]=0;
3257  ideal J=BO[2];
3258  int dimJ=dim(std(BO[2]));
3259  list templist;
3260  if(size(E)<5)
3261  {
3262//--- should not occur
3263    return(E);
3264  }
3265  for(ii=1;ii<=BO[7][1];ii++)
3266  {
3267     if(BO[6][ii]==2)
3268     {
3269       kkdiff++;
3270     }
3271  }
3272  int expDim=dimJ-E[2]+kkdiff;
3273  if(size(E)==6)
3274  {
3275    nonnormal=E[6];
3276  }
3277//---------------------------------------------------------------------------
3278// if dimJ were smaller than E[2], we would not have more than 3 entries in
3279//    in the list E
3280// if dimJ is also at least E[3] and nonnormal is 0, we only need to test that
3281// * the intersection is of the expected dimension
3282// * the intersections of the BO[4][i] and J are normal crossing
3283// * the elements of E^+ have no influence (is done below)
3284//---------------------------------------------------------------------------
3285  if((E[3]<=dimJ)&&(!nonnormal))
3286  {
3287    ideal bla=E[1]+BO[2]+BO[1];
3288    bla=radical(bla);
3289    bla=mstd(bla)[2];
3290
3291    if(dim(std(slocusE(bla)))<0)
3292    {
3293      if(transversalT(J,BO[4]))
3294      {
3295        ok=1;
3296        if(E[2]==E[3])
3297        {
3298//--- no further intersection with elements from E^+
3299          for(ii=1;ii<=size(E[4]);ii++)
3300          {
3301            if(dim_slocus(BO[2]+E[4][ii])!=-1)
3302            {
3303              dontdrop[ii]=1;
3304            }
3305          }
3306          if(dontdrop==zerovec)
3307          {
3308            list relist;
3309            relist[1]=std(J);
3310            return(relist);
3311          }
3312        }
3313      }
3314    }
3315  }
3316//---------------------------------------------------------------------------
3317// now check whether the E_i actually occurring in the intersections meet
3318// J transversally (one by one) and mark those elements of E[4] where it is
3319// not the case
3320//---------------------------------------------------------------------------
3321 if(!ok)
3322 {
3323     for(ii=1;ii<=size(E[5]);ii++)
3324     {
3325//--- test the ii-th tuple of E[4] resp. its indices E[5]
3326       for(jj=1;jj<=size(E[5][ii]);jj++)
3327       {
3328//--- if E[5][ii][jj]==1, E_jj is involved in E[4][ii]
3329        if(E[5][ii][jj]==1)
3330         {
3331//--- transversality not yet determined
3332           if(transverse[jj]==0)
3333           {
3334             templist[1]=BO[4][jj];
3335             if(transversalT(BO[2],templist))
3336             {
3337               transverse[jj]=1;
3338             }
3339             else
3340             {
3341               transverse[jj]=-1;
3342               dontdrop[ii]=1;
3343             }
3344           }
3345           else
3346           {
3347//--- already computed transversality
3348             if(transverse[jj]<0)
3349             {
3350               dontdrop[ii]=1;
3351             }
3352           }
3353         }
3354       }
3355     }
3356   }
3357//---------------------------------------------------------------------------
3358// if one of the non-marked tuples from E^- in E[4] has an intersection
3359// of the expected dimension and does not meet any E_i from E^+
3360// - except the ones which are met trivially - , it should be
3361// dropped from the list.
3362// it can also be dropped if an intersection occurs and normal crossing has
3363// been checked.
3364//---------------------------------------------------------------------------
3365  for(ii=1;ii<=size(E[4]);ii++)
3366  {
3367//--- if E[4][ii] does not have transversal intersections, we cannot drop it
3368    if(dontdrop[ii]==1)
3369    {
3370      ii++;
3371      continue;
3372    }
3373//--- testing ii-th tuple from E[4]
3374    testid=BO[1]+BO[2]+E[4][ii];
3375    if(dim(std(testid))!=expDim)
3376    {
3377//--- not expected dimension
3378      dontdrop[ii]=1;
3379      ii++;
3380      continue;
3381    }
3382    testid=mstd(testid)[2];
3383
3384    if(dim(std(slocusE(testid)))>=0)
3385    {
3386//--- not smooth, i.e. more than one component which intersect
3387      dontdrop[ii]=1;
3388      ii++;
3389      continue;
3390    }
3391//--- if E^+ is empty, we are done; otherwise check intersections with E^+
3392    if(BO[7][1]!=-1)
3393    {
3394      if(defined(pluslist)){kill pluslist;}
3395      list pluslist;
3396      for(jj=BO[7][1]+1;jj<=size(BO[4]);jj++)
3397      {
3398        dummy=BO[4][jj]+testid;
3399        dummy=std(dummy);
3400        if(expDim==dim(dummy))
3401        {
3402//--- intersection has wrong dimension
3403          dontdrop[ii]=1;
3404          break;
3405        }
3406        pluslist[jj-BO[7][1]]=BO[4][jj]+testid;
3407      }
3408      if(dontdrop[ii]==1)
3409      {
3410        ii++;
3411        continue;
3412      }
3413      if(!normalCross(pluslist))
3414      {
3415//--- unfortunately, it is not normal crossing
3416        dontdrop[ii]=1;
3417      }
3418    }
3419  }
3420//---------------------------------------------------------------------------
3421// The returned list should look like the truncated output of inters_E
3422//---------------------------------------------------------------------------
3423  list retlist;
3424  for(ii=1;ii<=size(E[4]);ii++)
3425  {
3426    if(dontdrop[ii]==1)
3427    {
3428      if(size(center)>0)
3429      {
3430        center=intersect(center,E[4][ii]);
3431      }
3432      else
3433      {
3434        center=E[4][ii];
3435      }
3436    }
3437  }
3438  retlist[1]=center;
3439  retlist[2]=E[2];
3440  retlist[3]=E[3];
3441  return(retlist);
3442}
3443//////////////////////////////////////////////////////////////////////////////
3444static proc transversalT(ideal J, list E,list #)
3445"Internal procedure - no help and no example available
3446"
3447{
3448//----------------------------------------------------------------------------
3449// check whether J and each element of the list E meet transversally
3450//----------------------------------------------------------------------------
3451   def R=basering;
3452   if(size(#)>0)
3453   {
3454     ideal pp=#[1];
3455   }
3456   int i;
3457   ideal T,M;
3458   ideal Jstd=std(J);
3459   ideal Tstd;
3460   int d=nvars(basering)-dim(Jstd)+1;   // d=n-dim(V(J) \cap hypersurface)
3461   for(i=1;i<=size(E);i++)
3462   {
3463      if(size(reduce(E[i],Jstd,5))==0)
3464      {
3465//--- V(J) is contained in E[i]
3466        return(0);
3467      }
3468      T=J,E[i];
3469      Tstd=std(T);
3470      d=nvars(basering)-dim(Tstd);
3471      if(deg(Tstd[1])!=0)
3472      {
3473//--- intersection is non-empty
3474//!!! abgeklemmt, da es doch in der Praxis vorkommt und korrekt sein kann!!!
3475//!!! wenn ueberhaupt dann -1 zurueckgeben!!!
3476//         if((d>=4)&&(size(T)>=10)){return(0);}
3477         M=minor(jacob(T),d,Tstd)+T;
3478         M=std(M);
3479         if(deg(M[1])>0)
3480         {
3481//--- intersection is not transversal
3482           if(size(#)==0)
3483           {
3484              return(0);
3485           }
3486           M=std(radical(M));
3487           if(size(reduce(pp,M,5))>0){return(0);}
3488         }
3489      }
3490   }
3491//--- passed all tests
3492   return(1);
3493}
3494///////////////////////////////////////////////////////////////////////////////
3495static proc transversalTB(ideal J, list E,ideal V)
3496"Internal procedure - no help and no example available
3497"
3498{
3499//----------------------------------------------------------------------------
3500// check whether J and each element of the list E meet transversally
3501//----------------------------------------------------------------------------
3502   def R=basering;
3503
3504   int i;
3505   ideal T,M;
3506   ideal Jstd=std(J);
3507   ideal Tstd;
3508   int d=nvars(basering)-dim(Jstd)+1;   // d=n-dim(V(J) \cap hypersurface)
3509   for(i=1;i<=size(E);i++)
3510   {
3511      if(size(reduce(E[i],Jstd,5))==0)
3512      {
3513//--- V(J) is contained in E[i]
3514        return(0);
3515      }
3516      T=J,E[i];
3517      Tstd=std(T);
3518      d=nvars(basering)-dim(Tstd);
3519      if(deg(Tstd[1])!=0)
3520      {
3521//--- intersection is non-empty
3522         if((d>=4)&&(size(T)>=10)){return(0);}
3523         M=minor(jacob(T),d,Tstd)+T;
3524         M=std(M+V);
3525         if(deg(M[1])>0)
3526         {
3527            return(0);
3528         }
3529      }
3530   }
3531//--- passed all tests
3532   return(1);
3533}
3534///////////////////////////////////////////////////////////////////////////////
3535static proc powerI(ideal I,int n,int m)
3536{
3537//--- compute (n!/m)-th power of I, more efficient variant
3538   int i;
3539   int mon=1;
3540   for(i=1;i<=size(I);i++)
3541   {
3542     if(size(I[i])>1){mon=0;break;}
3543   }
3544   if(mon)
3545   {
3546      if(size(reduce(I,std(radical(I[1])),5))<size(I)-1){mon=0;}
3547   }
3548   if((mon)&&(size(I)>3))
3549   {
3550      int e=int(factorial(n))/m;
3551      ideal J=1;
3552      poly p=I[1];
3553      I=I[2..size(I)];
3554      ideal K=p^e;
3555      for(i=1;i<=e;i++)
3556      {
3557         J=interred(J*I);
3558         K=K,(p^(e-i))*J;
3559      }
3560      return(K);
3561   }
3562   for(i=n;i>1;i--)
3563   {
3564      if(i!=m)
3565      {
3566         I=I^i;
3567      }
3568   }
3569   return(I);
3570}
3571
3572///////////////////////////////////////////////////////////////////////////////
3573static proc Coeff(list BO, int b, list #)
3574"USAGE:  Coeff (BO);
3575@*       BO = basic object, a list: ideal W,
3576@*                                  ideal J,
3577@*                                  intvec b (already truncated for Coeff),
3578@*                                  list Ex  (already truncated for Coeff),
3579@*                                  ideal ab,
3580@*                                  intvec v,
3581@*                                  intvec w (already truncated for Coeff),
3582@*                                  matrix M
3583@*       b  = integer indication bmax(BO)
3584ASSUME:  R  = basering, a polynomial ring, W an ideal of R,
3585@*       J  = ideal containing W
3586COMPUTE: Coeff-Ideal of BO as defined in [Bravo,Encinas,Villamayor]
3587RETURN:  basic object of the Coeff-Ideal
3588EXAMPLE: example Coeff;    shows an example
3589"
3590{
3591//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3592//!!! TASK: lower dimension by more than one in a single step if possible !!!
3593//!!!       (improve bookkeeping of invariants in Coeff and Center)       !!!
3594//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
3595//---------------------------------------------------------------------------
3596// Initialization  and sanity checks
3597//---------------------------------------------------------------------------
3598   int i,k,dummy,errtype;
3599   int ma=size(BO[4]);
3600   intvec merk;
3601   if(!defined(debugCoeff))
3602   {
3603     int debugCoeff;
3604   }
3605   ideal C;
3606   list L;
3607   if(size(#)!=0)
3608   {
3609      if(typeof(#[1])=="ideal")
3610      {
3611        L=#;
3612      }
3613      else
3614      {
3615        ma=#[1];
3616        L=DeltaList(BO);
3617      }
3618   }
3619   else
3620   {
3621      L=DeltaList(BO);
3622   }
3623
3624   if(debugCoeff)
3625   {
3626     "----> In Coeff: result of DeltaList:";
3627     L;
3628   }
3629   int d=size(L);                   // bmax of BO
3630   if((debugCoeff)&&(d!=b))
3631   {
3632      "!!!!!! Length of DeltaList does not equal second argument !!!!!!";
3633      "!!!!!! BO might not have been ord ~ 1 or wrong b          !!!!!!";
3634   }
3635   if(b>=6){return(0);}              // b is too big
3636   int e=int(factorial(b));          // b of Coeff-Ideal
3637   if(e==0)
3638   {
3639     ERROR( "// integer size too small for forming b! .");
3640   }
3641   if(b==0)
3642   {
3643     ERROR( "// second argument to Coeff should never be zero."  );
3644   }
3645//----------------------------------------------------------------------------
3646// Form the Coeff-Ideal
3647// Step 1: choose hypersurface
3648// Step 2: sum over correct powers of Delta^i(BO[2])
3649// Step 3: do the intersection
3650//----------------------------------------------------------------------------
3651//--- Step 1
3652   ideal Z;
3653   poly p;
3654   for(i=1;i<=ncols(L[d]);i++)
3655   {
3656//--- Look for smooth hypersurface in generators of Delta^(bmax-1)(BO[2])
3657     dummy=goodChoice(BO,L[d][i]);
3658     if(!dummy)
3659     {
3660       Z= L[d][i];
3661       break;
3662     }
3663     else
3664     {
3665       if(dummy>1)
3666       {
3667          merk[size(merk)+1]=i;
3668       }
3669       if(dummy>errtype)
3670       {
3671         errtype=dummy;
3672       }
3673     }
3674   }
3675   if(size(Z)==0)
3676   {
3677//--- no suitable element in generators of Delta^(bmax-1)(BO[2])
3678//--- try random linear combination
3679      for(k=1;k<=10;k++)
3680      {
3681         for(i=2;i<=size(merk);i++)
3682         {
3683            p=p+random(-100,100)*L[d][merk[i]];
3684         }
3685         dummy=goodChoice(BO,p);
3686         if(!dummy)
3687         {
3688            Z=p;
3689            break;
3690         }
3691         else
3692         {
3693            p=0;
3694         }
3695      }
3696      if(dummy)
3697      {
3698        for(i=1;i<=size(L[d]);i++)
3699        {
3700           p=p+random(-100,100)*L[d][i];
3701        }
3702        dummy=goodChoice(BO,p);
3703        if(!dummy)
3704        {
3705//--- found a suitable one
3706           Z=p;
3707        }
3708      }
3709      if(dummy)
3710      {
3711//--- did not find a suitable random linear combination either
3712         if(dummy>errtype)
3713         {
3714           errtype=dummy;
3715         }
3716         list retlist=errtype,L[d];
3717         return(retlist);
3718      }
3719   }
3720   if(debugCoeff)
3721   {
3722     "----> In Coeff: Chosen hypersurface";
3723     Z;
3724   }
3725//--- Step 2
3726   C=Z;
3727   for(i=0;i<b;i++)
3728   {
3729      C=C,powerI(simplify(reduce(L[i+1],std(Z)),2),b,b-i);
3730   }
3731   C=interred(C);
3732
3733   if(debugCoeff)
3734   {
3735     "----> In Coeff: J before saturation";
3736     C;
3737   }
3738
3739//--- Step 3
3740   BO[1]=BO[1]+Z;
3741   BO[2]=C;
3742   for(i=1;i<=size(BO[4]);i++)
3743   {
3744      BO[6][i]=0;             // reset intersection indicator
3745      BO[4][i]=BO[4][i]+Z;    // intersect the E_i
3746      if(i<=ma)
3747      {
3748        BO[2]=sat(BO[2],BO[4][i]+BO[1]);
3749                       // "strict transform" of J w.r.t E, not "total"
3750      }
3751   }
3752   if(debugCoeff)
3753   {
3754     "----> In Coeff:";
3755     " J after saturation:";
3756     BO[2];
3757   }
3758   return(BO);
3759}
3760example
3761{"EXAMPLE:";
3762   echo = 2;
3763   ring R=0,(x,y,z),dp;
3764
3765   ideal W;
3766   ideal J=z^2+x^2*y^2;
3767   intvec b=0;
3768   list E;
3769   ideal abb=maxideal(1);
3770   intvec v;
3771   intvec w=-1;
3772   matrix M;
3773
3774   list BO=W,J,b,E,abb,v,w,M;
3775
3776   Coeff(BO,2);
3777}
3778//////////////////////////////////////////////////////////////////////////////
3779static proc goodChoice(list BO, poly p)
3780"Internal procedure - no help and no example available
3781"
3782{
3783//---------------------------------------------------------------------------
3784// test whether new W is smooth
3785//---------------------------------------------------------------------------
3786   ideal W=BO[1]+ideal(p);
3787   if(size(reduce(p,std(BO[1]),5))==0)
3788   {
3789//--- p is already in BO[1], i.e. does not define a hypersurface in W
3790     return(1);
3791   }
3792   if(dim(std(slocusE(W)))>=0)
3793//   if(dim(timeStd(slocusE(W),20))>=0)
3794   {
3795//--- new W would not be smooth
3796     return(1);
3797   }
3798   if(size(BO[4])==0)
3799   {
3800//--- E is empty, no further tests necessary
3801     return(0);
3802   }
3803//--------------------------------------------------------------------------
3804// test whether the hypersurface meets the E_i transversally
3805//--------------------------------------------------------------------------
3806   list E=BO[4];
3807   int i,d;
3808   ideal T=W;
3809   ideal Tstd=std(T);
3810   d=nvars(basering)-dim(Tstd)+1;
3811   ideal M;
3812   for(i=1;i<=size(E);i++)
3813   {
3814      T=W,E[i];
3815      M=minor(jacob(T),d,Tstd)+T;
3816      M=std(M);
3817      if(deg(M[1])>0)
3818      {
3819//--- intersection not transversal
3820        return(2);
3821      }
3822   }
3823//--------------------------------------------------------------------------
3824// test whether the new E_i have normal crossings
3825//--------------------------------------------------------------------------
3826   for(i=1;i<=size(E);i++)
3827   {
3828      E[i]=E[i],p;
3829   }
3830   if(normalCross(E))
3831   {
3832     return(0);
3833   }
3834   else
3835   {
3836     return(2);
3837   }
3838}
3839//////////////////////////////////////////////////////////////////////////////
3840
3841proc presentTree(list L)
3842"USAGE:  presentTree(L);
3843         L=list, output of resolve
3844RETURN:  nothing, only pretty printing of the output data of resolve()
3845EXAMPLE: none
3846"
3847{
3848  def r=basering;
3849  int i,j,k;
3850  if(size(L[2])==1)
3851  {
3852     "The object was already resolved or the list L does not";
3853     "have required input format. There is just one chart in";
3854     "the tree.";
3855     return();
3856  }
3857  for(i=1;i<=size(L[1]);i++)
3858  {
3859    "                        ";
3860    "/////////////////////////// Final Chart",i,"/////////////////////////";
3861    def s=L[1][i];
3862    setring s;
3863    "======================== History of this chart ======================";
3864    for(j=2;j<=ncols(path);j++)
3865    {
3866      "                  ";
3867      "Blow Up",j-1,":";
3868      "     Center determined in L[2]["+string(path[1,j])+"],";
3869      "     Passing to chart ",path[2,j]," in resulting blow up.";
3870    }
3871    "                 ";
3872    "======================== Data of this chart ========================";
3873    showBO(BO);
3874    setring r;
3875    kill s;
3876    pause();
3877  }
3878  "////////////////////////////////////////////////////////////////////";
3879  "For identification of exceptional divisors please use the tools";
3880  "provided by reszeta.lib, e.g. collectDiv.";
3881  "For viewing an illustration of the tree of charts please use the";
3882  "procedure ResTree from resgraph.lib.";
3883  "////////////////////////////////////////////////////////////////////";
3884  return();
3885}
3886//////////////////////////////////////////////////////////////////////////////
3887
3888proc showBO(list BO)
3889"USAGE:  showBO(BO);
3890@*        BO=basic object, a list: ideal W,
3891@*                                  ideal J,
3892@*                                  intvec b (already truncated for Coeff),
3893@*                                  list Ex  (already truncated for Coeff),
3894@*                                  ideal ab,
3895@*                                  intvec v,
3896@*                                  intvec w (already truncated for Coeff),
3897@*                                  matrix M
3898RETURN:   nothing, only pretty printing
3899EXAMPLE:  none
3900"
3901{
3902  "                       ";
3903  "==== Ambient Space: ";BO[1];"      ";
3904  "==== Ideal of Variety: ";BO[2];"      ";
3905  int i;
3906  list M;
3907  for(i=1;i<=size(BO[4]);i++)
3908  {
3909    M[i]=ideal(BO[4][i]);
3910  }
3911  "==== Exceptional Divisors: ";print(M);"   ";
3912  "==== Images of variables of original ring:";BO[5];"   ";
3913}
3914//////////////////////////////////////////////////////////////////////////////
3915////////////////////////    main procedure    ////////////////////////////////
3916//////////////////////////////////////////////////////////////////////////////
3917proc resolve(ideal J, list #)
3918"USAGE:  resolve (J); or resolve (J,i[,k]);
3919@*       J ideal
3920@*       i,k int
3921COMPUTE: a resolution of J,
3922@*       if i > 0 debugging is turned on according to the following switches:
3923@*       j1: value 0 or 1; turn off or on correctness checks in all steps
3924@*       j2: value 0 or 2; turn off or on debugCenter
3925@*       j3: value 0 or 4; turn off or on debugBlowUp
3926@*       j4: value 0 or 8; turn off or on debugCoeff
3927@*       j5: value 0 or 16:turn off or on debugging of Intersection with E^-
3928@*       j6: value 0 or 32:turn off or on stop after pass through the loop
3929@*       i=j1+j2+j3+j4+j5+j6
3930RETURN:  a list l of 2 lists of rings
3931         l[1][i] is a ring containing a basic object BO, the result of the
3932         resolution.
3933         l[2] contains all rings which occurred during the resolution process
3934NOTE:    result may be viewed in a human readable form using presentTree()
3935EXAMPLE: example resolve;  shows an example
3936"
3937{
3938//----------------------------------------------------------------------------
3939// Initialization and sanity checks
3940//----------------------------------------------------------------------------
3941   def R=basering;
3942   list allRings;
3943   allRings[1]=R;
3944   list endRings;
3945   module path=[0,-1];
3946   ideal W;
3947   list E;
3948   ideal abb=maxideal(1);
3949   intvec v;
3950   intvec bvec;
3951   intvec w=-1;
3952   matrix intE;
3953   int extra,bm;
3954   if(defined(BO)){kill BO;}
3955   if(defined(cent)){kill cent;}
3956
3957   ideal Jrad=equiRadical(J);
3958   if(size(reduce(Jrad,std(J),5))!=0)
3959   {
3960      "WARNING! The input is not reduced or not equidimensional!";
3961      "We will continue with the reduced top-dimensional part of input";
3962      J=Jrad;
3963   }
3964
3965   int i,j,debu,loca,locaT,ftemp,debugResolve,smooth;
3966//--- switches for local and for debugging may occur in any order
3967   i=size(#);
3968   extra=3;
3969   for(j=1;j<=i;j++)
3970   {
3971     if(typeof(#[j])=="int")
3972     {
3973       debugResolve=#[j];
3974//--- debu: debug switch for resolve, smallest bit in debugResolve
3975       debu=debugResolve mod 2;
3976     }
3977     else
3978     {
3979        if(#[j]=="M")
3980        {
3981           bm=1;
3982           ERROR("Not implemented yet");
3983        }
3984        if(#[j]=="E"){extra=0;}
3985        if(#[j]=="A"){extra=2;}
3986        if(#[j]=="K"){extra=3;}
3987        if(#[j]=="L"){loca=1;}
3988     }
3989   }
3990   if(loca)
3991   {
3992      list qs=minAssGTZ(J);
3993      ideal K=ideal(1);
3994      for(j=1;j<=size(qs);j++)
3995      {
3996         if(size(reduce(qs[j],maxideal(1),5))==0)
3997         {
3998            K=intersect(K,qs[j]);
3999         }
4000      }
4001      J=K;
4002      list qr=minAssGTZ(slocus(J));
4003      K=ideal(1);
4004      for(j=1;j<=size(qr);j++)
4005      {
4006         if(size(reduce(qr[j],maxideal(1),5))!=0)
4007         {
4008            K=intersect(K,qr[j]);
4009            smooth++;
4010         }
4011         else
4012         {
4013            if(dim(std(qr[j]))>0){loca=0;}
4014//---- test for isolated singularity at 0
4015         }
4016      }
4017      K=std(K);
4018//---- if deg(K[1])==0 the point 0 is on all components of the singular
4019//---- locus and we can work globally
4020      if(smooth==size(qr)){smooth=-1;}
4021//---- the point 0 is not on the singular locus
4022      if((deg(K[1])>0)&&(smooth>=0)&&(!loca))
4023      {
4024         locaT=1;
4025         poly @p;
4026         for(j=1;j<=size(K);j++)
4027         {
4028            if(jet(K[j],0)!=0)
4029            {
4030               @p=K[j];
4031               break;
4032            }
4033         }
4034         export(@p);
4035      }
4036      if((loca)&&(!smooth)){loca=0;}
4037//---- the case that 0 is isolated singularity and the only singular point
4038   }
4039   export(locaT);
4040//---In case of option "L" the following holds
4041//---loca=0 and locaT=0  we perform the global case
4042//---loca !=0: 0 is isolated singular point, but there are other singularities
4043//---locaT!=0: O is singular point, but not isolated, and there is a componente//---          of the singular locus not containing 0
4044
4045//--- if necessary, set the corresponding debugFlags
4046   if(defined(debugResolve))
4047   {
4048//--- 2nd bit from the right
4049     int debugCenter=(debugResolve div 2) mod 2;
4050     export debugCenter;
4051//--- 3rd bit from the right
4052     int debugBlowUp=(debugResolve div 4) mod 2;
4053     export debugBlowUp;
4054//--- 4th bit from the right
4055     int debugCoeff=(debugResolve div 8) mod 2;
4056     export debugCoeff;
4057//--- 5th bit from the right
4058     int debug_Inters_E=(debugResolve div 16) mod 2;
4059     export debug_Inters_E;
4060//--- 6th bit from the right
4061     int praes_stop=(debugResolve div 32) mod 2;
4062   }
4063//--- set the correct attributes to J for speed ups
4064   if( typeof(attrib(J,"isEqui"))!="int" )
4065   {
4066      if(size(J)==1)
4067      {
4068         attrib(J,"isEqui",1);
4069      }
4070      else
4071      {
4072         attrib(J,"isEqui",0);
4073      }
4074   }
4075   if(size(J)==1)
4076   {
4077      attrib(J,"isHy",1);
4078   }
4079   else
4080   {
4081      attrib(J,"isHy",0);
4082   }
4083//--- create the BO
4084   list BO=W,J,bvec,E,abb,v,w,intE;
4085   if(defined(invSat)){kill invSat;}
4086   list invSat=ideal(0),intvec(0);
4087   export(invSat);
4088   if(bm)
4089   {
4090     intmat invmat[2][1]=0,-1;
4091     BO[9]=invmat;
4092   }
4093   else
4094   {
4095     BO[9]=intvec(0);
4096   }
4097   export BO;
4098   list tmpList;
4099   int blo;
4100   int k,Ecount,tmpPtr;
4101   i=0;
4102   if(smooth==-1)
4103   {
4104      endRings[1]=R;
4105      list result=endRings,allRings;
4106      if(debu)
4107      {
4108         "============= result will be tested ==========";
4109         "                                              ";
4110         "the number of charts obtained:",size(endRings);
4111         "=============     result is o.k.    ==========";
4112      }
4113      kill debugCenter,debugBlowUp,debugCoeff,debug_Inters_E;
4114      return(result);
4115   }
4116//-----------------------------------------------------------------------------
4117// While there are rings to be considered, determine center and blow up
4118//-----------------------------------------------------------------------------
4119   while(i<size(allRings))
4120   {
4121      i++;
4122      def S=allRings[i];
4123      setring S;
4124      list pr;
4125      ideal Jstd=std(BO[2]);
4126//-----------------------------------------------------------------------------
4127// Determine Center
4128//-----------------------------------------------------------------------------
4129      if(i==1)
4130      {
4131         list deltaL=DeltaList(BO);
4132         ideal sL=radical(deltaL[size(deltaL)]);
4133         if((deg(std(slocus(sL))[1])==0)&&(size(minAssGTZ(sL))==1))
4134         {
4135            list @ce=sL,intvec(-1),intvec(0),intvec(0);
4136            ideal cent=@ce[1];
4137         }
4138      }
4139//--- before computing a center, check whether we have a stored one
4140      if(size(BO)>9)
4141      {
4142         while(size(BO[10])>0)
4143         {
4144            list @ce=BO[10][1];
4145//--- check of the center
4146           // @ce=correctC(BO,@ce,bm);
4147//--- use stored center
4148            BO[10]=delete(BO[10],1);
4149            if(size(@ce[1])==0)
4150            {
4151//--- stored center was not ok
4152              continue;
4153            }
4154            tmpPtr=0;
4155            for(Ecount=1;Ecount <= size(@ce[2]); Ecount++)
4156            {
4157              if(@ce[2][Ecount]>-1)
4158              {
4159                tmpPtr=tmpPtr+@ce[2][Ecount];
4160              }
4161              else
4162              {
4163                @ce[2][Ecount]=size(BO[4])-tmpPtr-1;
4164                for(int cnthlp=1;cnthlp<=size(BO[10]);cnthlp++)
4165                {
4166                   BO[10][cnthlp][2][Ecount]=@ce[2][Ecount];
4167                }
4168                kill cnthlp;
4169                break;
4170              }
4171            }
4172            if(Ecount<size(@ce[2]))
4173            {
4174              for(tmpPtr=Ecount+1;tmpPtr<=size(@ce[2]);tmpPtr++)
4175              {
4176                @ce[2][tmpPtr]=0;
4177                for(int cnthlp=1;cnthlp<=size(BO[10]);cnthlp++)
4178                {
4179                   BO[10][cnthlp][2][tmpPtr]=@ce[2][tmpPtr];
4180                }
4181                kill cnthlp;
4182              }
4183            }
4184            break;
4185         }
4186         if(defined(@ce))
4187         {
4188           if(size(@ce[1])==0)
4189           {
4190              kill @ce;
4191           }
4192           else
4193           {
4194              ideal cent=@ce[1];
4195           }
4196         }
4197         if(size(BO[10])==0)
4198         {
4199//--- previously had stored centers, all have been used; we need to clean up
4200            BO=delete(BO,10);
4201         }
4202      }
4203      if((loca)&&(i==1))
4204      {
4205//--- local case: initial step is blow-up in origin
4206         if(defined(@ce)){kill @ce;}
4207         if(defined(cent)){kill cent;}
4208         if(size(reduce(slocusE(BO[2]),maxideal(1),5))==0)
4209         {
4210            list @ce=maxideal(1),intvec(-1),intvec(0),intvec(0);
4211         }
4212         else
4213         {
4214            list @ce=BO[2],intvec(-1),intvec(1),intvec(0);
4215         }
4216         ideal cent=@ce[1];
4217      }
4218      if(((loca)||(locaT))&&(i!=1))
4219      {
4220         int JmeetsE;
4221         for(j=1;j<=size(BO[4]);j++)
4222         {
4223            if(deg(std(BO[2]+BO[4][j])[1])!=0)
4224            {
4225               JmeetsE=1;
4226               break;
4227            }
4228         }
4229         if(!JmeetsE)
4230         {
4231            list @ce=BO[2],intvec(-1),intvec(1),intvec(0);
4232            ideal cent=@ce[1];
4233         }
4234         kill JmeetsE;
4235      }
4236      if((locaT)&&(!defined(@ce)))
4237      {
4238          if(@p!=1)
4239          {
4240             list tr=minAssGTZ(slocusE(BO[2]));
4241             ideal L=ideal(1);
4242             for(j=1;j<=size(tr);j++)
4243             {
4244                if(size(reduce(ideal(@p),std(tr[j]),5))==0)
4245                {
4246                   L=intersect(L,tr[j]);
4247                }
4248             }
4249             L=std(L);
4250             if(deg(L[1])==0)
4251             {
4252                @p=1;
4253             }
4254             else
4255             {
4256               ideal fac=factorize(@p,1);
4257               if(size(fac)==1)
4258               {
4259                 @p=fac[1];
4260               }
4261               else
4262               {
4263                  for(j=1;j<=size(fac);j++)
4264                  {
4265                     if(reduce(fac[j],L)==0)
4266                     {
4267                        @p=fac[j];
4268                        break;
4269                     }
4270                  }
4271               }
4272             }
4273             kill tr,L;
4274          }
4275          ring R1 = create_ring(ring_list(S)[1], "(@z,"+varstr(S)+")", "dp", "no_minpoly");
4276          poly p=imap(S,@p);
4277          list BO=imap(S,BO);
4278          list invSat=imap(S,invSat);
4279          export(invSat);
4280          ideal te=std(BO[2]);
4281          BO[1]=BO[1]+ideal(@z*p-1);
4282          BO[2]=BO[2]+ideal(@z*p-1);
4283          for(j=1;j<=size(BO[4]);j++)
4284          {
4285             BO[4][j]=BO[4][j]+ideal(@z*p-1);
4286          }
4287//--- for computation of center: drop components not meeting the Ei
4288          def BO2=BO;
4289          list qs=minAssGTZ(BO2[2]);
4290          ideal K=ideal(1);
4291          for(j=1;j<=size(qs);j++)
4292          {
4293             if(CompMeetsE(qs[j],BO2[4]))
4294             {
4295                K=intersect(K,qs[j]);
4296             }
4297          }
4298          BO2[2]=K;
4299//--- check whether we are done
4300          if(deg(std(BO2[2])[1])==0)
4301          {
4302             list @ce=BO[2],intvec(-1),intvec(1),intvec(0);
4303          }
4304          if(!defined(@ce))
4305          {
4306             if(bm)
4307             {
4308                list @ce=CenterBM(BO2);
4309             }
4310             else
4311             {
4312                list @ce=CenterBO(BO2);
4313             }
4314          }
4315//--- if computation of center returned BO2[2], we are done
4316//--- ==> set @ce to BO[2], because later checks work with BO instead of BO2
4317          if((size(reduce(@ce[1],std(BO2[2]),5))==0)&&
4318             (size(reduce(BO2[2],std(@ce[1]),5))==0))
4319          {
4320             @ce[1]=BO[2];
4321          }
4322          if(size(specialReduce(@ce[1],te,p))==0)
4323          {
4324             BO=imap(S,BO);
4325             @ce[1]=BO[2];
4326          }
4327          else
4328          {
4329             //@ce=correctC(BO,@ce,bm);
4330             @ce[1]=eliminate(@ce[1],@z);
4331          }
4332          setring S;
4333          list @ce=imap(R1,@ce);
4334          kill R1;
4335
4336         if((size(reduce(BO[2],std(@ce[1]),5))==0)
4337             &&(size(reduce(@ce[1],Jstd,5))==0))
4338         {
4339//--- J and center coincide
4340            pr[1]=@ce[1];
4341            ideal cent=@ce[1];
4342         }
4343         else
4344         {
4345//--- decompose center and use first component
4346            pr=minAssGTZ(@ce[1]);
4347               if(size(reduce(@p,std(pr[1]),5))==0){"Achtung";~;}
4348               if(deg(std(slocus(pr[1]))[1])>0){"singulaer";~;}
4349            ideal cent=pr[1];
4350         }
4351         if(size(pr)>1)
4352         {
4353//--- store the other components
4354            for(k=2;k<=size(pr);k++)
4355            {
4356               if(size(reduce(@p,std(pr[k]),5))==0){"Achtung";~;}
4357               if(deg(std(slocus(pr[k]))[1])>0){"singulaer";~;}
4358               if(size(reduce(@p,std(pr[k]),5))!=0)
4359               {
4360                  tmpList[size(tmpList)+1]=list(pr[k],@ce[2],@ce[3],@ce[4]);
4361               }
4362            }
4363            BO[10]=tmpList;
4364            kill tmpList;
4365            list tmpList;
4366         }
4367      }
4368      if(!defined(@ce))
4369      {
4370//--- no previously determined center, we need to compute one
4371         if(loca)
4372         {
4373//--- local case: center should be inside exceptional locus
4374            ideal Ex=ideal(1);
4375            k=0;
4376            for(j=1;j<=size(BO[4]);j++)
4377            {
4378               if(deg(BO[4][j][1])!=0)
4379               {
4380                 Ex=Ex*BO[4][j];   //----!!!!hier evtl. Durchschnitt???
4381                 k++;
4382               }
4383            }
4384//--- for computation of center: drop components not meeting the Ei
4385            list BOloc=BO;
4386            list qs=minAssGTZ(BOloc[2]);
4387            ideal K=ideal(1);
4388            for(j=1;j<=size(qs);j++)
4389            {
4390              if(CompMeetsE(qs[j],BOloc[4]))
4391              {
4392                 K=intersect(K,qs[j]);
4393              }
4394            }
4395            BOloc[2]=K;
4396//--- check whether we are done
4397            if(deg(std(BOloc[2])[1])==0)
4398            {
4399               list @ce=BO[2],intvec(-1),intvec(1),intvec(0);
4400            }
4401            if(!defined(@ce))
4402            {
4403              if(BO[3][1]!=0)
4404              {
4405                 BOloc[2]=BO[2]+Ex^((BO[3][1] div k)+1);//!!!!Vereinfachen???
4406              }
4407              else
4408              {
4409                 BOloc[2]=BO[2]+Ex^((size(DeltaList(BO)) div k)+1);
4410              }
4411              if(bm)
4412              {
4413                 list @ce=CenterBM(BOloc);
4414              }
4415              else
4416              {
4417                 list @ce=CenterBO(BOloc);
4418              }
4419              if(size(reduce(Ex,std(@ce[1]),5))!=0)
4420              {
4421                 list tempPr=minAssGTZ(@ce[1]);
4422                 for(k=size(tempPr);k>=1;k--)
4423                 {
4424                    if(size(reduce(Ex,std(tempPr[k]),5))!=0)
4425                    {
4426                      tempPr=delete(tempPr,k);
4427                    }
4428                 }
4429                 @ce[1]=1;
4430                 for(k=1;k<=size(tempPr);k++)
4431                 {
4432                    @ce[1]=intersect(@ce[1],tempPr[k]);
4433                 }
4434                 if(deg(std(@ce[1])[1])==0)
4435                 {
4436                    @ce[1]=BO[2];
4437                 }
4438              }
4439            }
4440//--- test whether we are done
4441            if(size(reduce(slocusE(BO[2]),std(@ce[1]),5))!=0)
4442            {
4443               if(transversalT(BO[2],BO[4]))
4444               {
4445                  if(defined(E)){kill E;}
4446                  list E=BO[4];
4447                  for(j=1;j<=size(E);j++){if(deg(E[j][1])>0){E[j]=E[j]+BO[2];}}
4448                  if(normalCross(E))
4449                  {
4450                     @ce[1]=BO[2];
4451                  }
4452                  kill E;
4453               }
4454            }
4455         }
4456         else
4457         {
4458//--- non-local
4459            if(bm)
4460            {
4461               list @ce=CenterBM(BO);
4462            }
4463            else
4464            {
4465               list @ce=CenterBO(BO);
4466            }
4467//--- check of the center
4468            //@ce=correctC(BO,@ce,bm);
4469            if((size(@ce[1])==0)&&(size(@ce[4])<(size(@ce[3])-1)))
4470            {
4471               intvec xxx=@ce[3];
4472               xxx=xxx[1..size(@ce[4])];
4473               @ce[3]=xxx;
4474               xxx=@ce[2];
4475               xxx=xxx[1..size(@ce[4])];
4476               @ce[2]=xxx;
4477               kill xxx;
4478            }
4479         }
4480         if((size(reduce(BO[2],std(@ce[1]),5))==0)
4481             &&(size(reduce(@ce[1],Jstd,5))==0))
4482         {
4483//--- J and center coincide
4484            pr[1]=@ce[1];
4485            ideal cent=@ce[1];
4486         }
4487         else
4488         {
4489//--- decompose center and use first component
4490            pr=minAssGTZ(@ce[1]);
4491            ideal cent=pr[1];
4492         }
4493         if(size(pr)>1)
4494         {
4495//--- store the other components
4496            for(k=2;k<=size(pr);k++)
4497            {
4498               tmpList[k-1]=list(pr[k],@ce[2],@ce[3],@ce[4]);
4499            }
4500            BO[10]=tmpList;
4501            kill tmpList;
4502            list tmpList;
4503         }
4504      }
4505//--- do not forget to update BO[7] and BO[3]
4506      export cent;
4507      BO[7]=@ce[2];
4508      BO[3]=@ce[3];
4509      if((loca||locaT)&&(size(@ce)<4)){@ce[4]=0;} //Provisorium !!!
4510      if((size(@ce[4])<size(@ce[2])-1)||(size(@ce[4])<size(@ce[3])-1))
4511      {
4512        if((deg(std(@ce[1])[1])==0)&&(deg(std(BO[2])[1])==0))
4513        {
4514           intvec nullvec;
4515           nullvec[size(@ce[2])-1]=0;
4516           @ce[4]=nullvec;
4517           kill nullvec;
4518        }
4519        else
4520        {
4521           "ERROR:@ce[4] hat falsche Laenge - nicht-trivialer Fall";
4522           ~;
4523        }
4524      }
4525      if((typeof(@ce[4])=="intvec") || (typeof(@ce[4])=="intmat"))
4526      {
4527        BO[9]=@ce[4];
4528      }
4529//---------------------------------------------------------------------------
4530// various checks and debug output
4531//---------------------------------------------------------------------------
4532      if((debu) || (praes_stop))
4533      {
4534//--- Show BO of this step
4535         "++++++++++++++ Overview of Current Chart +++++++++++++++++++++++";
4536         "Current number of final charts:",size(endRings);
4537         "Total number of charts currently in chart-tree:",size(allRings);
4538         "Index of the current chart in chart-tree:",i;
4539         "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
4540         showBO(BO);
4541         "-------------------------- Upcoming Center ---------------------";
4542         interred(cent);
4543         "----------------------------------------------------------------";
4544      }
4545      if(praes_stop)
4546      {
4547         ~;
4548      }
4549      if(debu)
4550      {
4551//--- various checks, see output for comments
4552         if(size(BO[1])>0)
4553         {
4554            if(deg(BO[1][1])==0)
4555            {
4556               "!!!  W is empty  !!!";
4557               path;
4558               setring R;
4559               kill S;
4560               list result=endRings,allRings;
4561               return(result);
4562            }
4563            if(deg(std(slocusE(BO[1]))[1])>0)
4564            {
4565               "!!!  W not smooth  !!!";
4566               path;
4567               setring R;
4568               kill S;
4569               list result=endRings,allRings;
4570               return(result);
4571            }
4572         }
4573         if((!loca)&&(!locaT))
4574         {
4575            if(deg(std(slocusE(cent+BO[1]))[1])>0)
4576            {
4577               "!!!  Center not smooth  !!!";
4578               path;
4579               std(cent+BO[1]);
4580               ~;
4581               setring R;
4582               kill S;
4583               list result=endRings,allRings;
4584               return(result);
4585            }
4586         }
4587         for(j=1;j<=size(BO[4]);j++)
4588         {
4589            if(deg(BO[4][j][1])>0)
4590            {
4591               if(deg(std(slocusE(BO[4][j]+BO[1]))[1])>0)
4592               {
4593                  "!!!  exceptional divisor is not smooth  !!!";
4594                  path;
4595                  setring R;
4596                  kill S;
4597                  list result=endRings,allRings;
4598                  return(result);
4599               }
4600            }
4601         }
4602         if((!loca)&&(!locaT))
4603         {
4604            if((norC(BO,cent))&&(size(reduce(cent,Jstd,5))!=0))
4605            {
4606               "!!!  this chart is already finished  !!!";
4607               cent=BO[2];
4608               ~;
4609            }
4610         }
4611      }
4612//----------------------------------------------------------------------------
4613// Do the blow up
4614//----------------------------------------------------------------------------
4615//!!!! Change this as soon as there is time!!!
4616//!!!! quick and dirty bug fix for old shortcut which has not yet been killed
4617if((dim(std(cent))==0)&&defined(shortcut)) {kill shortcut;}
4618//!!! end of bugfix
4619      if(size(reduce(cent,Jstd,5))!=0)
4620      {
4621//--- center does not equal J
4622         tmpList=blowUpBO(BO,cent,extra);
4623         if((debu)&&(!loca)&&(!locaT))
4624         {
4625//--- test it, if debu is set
4626            if(!testBlowUp(BO,cent,tmpList,i,extra))
4627            {
4628               "non-redundant chart has been killed!";
4629               ~;
4630            }
4631         }
4632//--- extend the list of all rings
4633         allRings[size(allRings)+1..size(allRings)+size(tmpList)]=
4634                         tmpList[1..size(tmpList)];
4635         for(j=1;j<=size(tmpList);j++)
4636         {
4637            def Q=allRings[size(allRings)-j+1];
4638            setring Q;
4639            def path=imap(S,path);
4640            path=path,[i,size(tmpList)-j+1];
4641            export path;
4642            setring S;
4643            kill Q;
4644         }
4645         kill tmpList;
4646         list tmpList;
4647      }
4648      else
4649      {
4650//--- center equals J
4651           k=0;
4652           for(j=1;j<=size(BO[6]);j++)
4653           {
4654              if(BO[6][j]!=1)
4655              {
4656//--- there is an E_i which meets J in this chart
4657                k=1;
4658                break;
4659              }
4660           }
4661           if((k)||(extra==2))
4662           {
4663//--- chart finished, non-redundant
4664              endRings[size(endRings)+1]=S;
4665           }
4666      }
4667      kill pr;
4668      setring R;
4669      kill S;
4670   }
4671//---------------------------------------------------------------------------
4672// set up the result, test it (if debu is set) and return it
4673//---------------------------------------------------------------------------
4674   list result=endRings,allRings;
4675   if(debu)
4676   {
4677      "============= result will be tested ==========";
4678      "                                              ";
4679      "the number of charts obtained:",size(endRings);
4680      if(locaT){loca=2;}
4681      int tes=testRes(J,endRings,loca);
4682      if(tes)
4683      {
4684         "=============     result is o.k.    ==========";
4685      }
4686      else
4687      {
4688         "============     result is wrong    =========="; ~;
4689      }
4690   }
4691   kill debugCenter,debugBlowUp,debugCoeff,debug_Inters_E;
4692   if(locaT){kill @p;}
4693   kill locaT;
4694   return(result);
4695}
4696example
4697{"EXAMPLE:";
4698   echo = 2;
4699   ring R=0,(x,y,z),dp;
4700   ideal J=x3+y5+yz2+xy4;
4701   list L=resolve(J,0);
4702   def Q=L[1][7];
4703   setring Q;
4704   showBO(BO);
4705}
4706//////////////////////////////////////////////////////////////////////////
4707//static
4708proc CompMeetsE(ideal J, list E)
4709"Internal procedure - no help and no example available
4710"
4711{
4712   int i;
4713   for(i=1;i<=size(E);i++)
4714   {
4715      if(deg(std(E[i])[1])!=0)
4716      {
4717         if(deg(std(J+E[i])[1])!=0)
4718         {
4719            return(1);
4720         }
4721      }
4722   }
4723   return(0);
4724}
4725
4726//========================================================================
4727//--------------  procedures for testing the result ----------------------
4728//                (not yet commented)
4729//========================================================================
4730
4731//////////////////////////////////////////////////////////////////////////
4732static proc testRes(ideal J,list L,int loca)
4733"Internal procedure - no help and no example available
4734"
4735{
4736   int loc;
4737   if(defined(locaT)){loc=locaT;}
4738   if(loc){loca=0;}
4739   def R=basering;
4740   ideal M=maxideal(1);
4741   int i,j,tr;
4742   for(i=1;i<=size(L);i++)
4743   {
4744      def Q=L[i];
4745      setring Q;
4746      ideal J=BO[2];
4747      list E=BO[4];
4748      map phi=R,BO[5];
4749      ideal K=phi(J)+BO[1];
4750      ideal stTK=std(K);
4751
4752      if(loca)
4753      {
4754         ideal M=phi(M)+BO[1];
4755         ideal stTM=std(M);
4756      }
4757      for(j=1;j<=size(E);j++)
4758      {
4759         if(deg(E[j][1])>0)
4760         {
4761            stTK=sat(stTK,E[j]);
4762         }
4763         if(loca)
4764         {
4765            stTM=sat(stTM,E[j]);
4766         }
4767      }
4768      ideal sL=slocusE(J);
4769      if(loca){sL=sL+stTM;}
4770      ideal sLstd=std(sL);
4771      if(deg(sLstd[1])>0)
4772      {
4773         if(!loc)
4774         {
4775            "J is not smooth";i;
4776            setring R;
4777            return(0);
4778         }
4779         if(size(reduce(@p,std(radical(sLstd)),5))>0)
4780         {
4781            "J is not smooth";i;
4782            setring R;
4783            return(0);
4784         }
4785      }
4786      if(!((size(reduce(J,std(stTK),5))==0)
4787           &&(size(reduce(stTK,std(J),5))==0)))
4788      {
4789         "map is wrong";i;
4790         setring R;
4791         return(0);
4792      }
4793      if(loc){tr=transversalT(J,E,@p);}
4794      else{tr=transversalT(J,E);}
4795      if(!tr)
4796      {
4797         "E not transversal with J";i;
4798         setring R;
4799         return(0);
4800      }
4801      if(!normalCross(E))
4802      {
4803         "E not normal crossings";i;
4804         setring R;
4805         return(0);
4806      }
4807      for(j=1;j<=size(E);j++)
4808      {
4809         if(deg(E[j][1])>0){E[j]=E[j]+J;}
4810      }
4811      if(!normalCross(E))
4812      {
4813         "E not normal crossings with J";i;
4814         setring R;
4815         return(0);
4816      }
4817      kill J,E,phi,K,stTK;
4818      if(loca){kill M,stTM;}
4819      setring R;
4820      kill Q;
4821   }
4822   return(1);
4823}
4824//////////////////////////////////////////////////////////////////////////////
4825static proc testBlowUp(list BO,ideal cent,list tmpList, int j, int extra)
4826{
4827   def R=basering;
4828   int n=nvars(basering);
4829   int i;
4830   if((extra!=3)&&(extra!=2))
4831   {
4832      ideal K=BO[1],BO[2],cent;
4833      for(i=1;i<=size(BO[4]);i++)
4834      {
4835        K=K,BO[4][i];
4836      }
4837      list N=findvars(K);
4838      //list N=findvars(BO[2]);
4839      if(size(N[1])<n)
4840      {
4841         string newvar=string(N[1]);
4842         ring R1 = create_ring(ring_list(R)[1], "("+newvar+")", "dp", "no_minpoly");
4843         list BO=imap(R,BO);
4844         ideal cent=imap(R,cent);
4845         n=nvars(R1);
4846      }
4847      else
4848      {
4849         def R1=basering;
4850      }
4851   }
4852   else
4853   {
4854      def R1=basering;
4855   }
4856
4857   i=0;
4858   ideal T=cent;
4859   ideal TW;
4860   for(i=1;i<=size(tmpList);i++)
4861   {
4862      def Q=tmpList[i];
4863      setring Q;
4864      map phi=R1,lastMap;
4865      ideal TE=radical(slocusE(BO[2]));
4866      setring R1;
4867      TW=preimage(Q,phi,TE);
4868      T=intersect(T,TW);
4869      kill Q;
4870   }
4871   ideal sL=intersect(slocusE(BO[2]),cent);
4872   if(size(reduce(sL,std(radical(T)),5))>0){setring R;return(0);}
4873   if(size(reduce(T,std(radical(sL)),5))>0){setring R;return(0);}
4874   setring R;
4875   return(1);
4876}
4877//////////////////////////////////////////////////////////////////////////////
4878static proc normalCross(list E,list #)
4879"Internal procedure - no help and no example available
4880"
4881{
4882   int loc;
4883   if((defined(locaT))&&(defined(@p)))
4884   {
4885      loc=1;
4886      ideal pp=@p;
4887   }
4888   int i,d,j;
4889   int n=nvars(basering);
4890   list E1,E2;
4891   ideal K,M,Estd,cent;
4892   intvec v,w;
4893   if(size(#)>0){cent=#[1];}
4894
4895   for(i=1;i<=size(E);i++)
4896   {
4897      Estd=std(E[i]);
4898      if(deg(Estd[1])>0)
4899      {
4900         E1[size(E1)+1]=Estd;
4901      }
4902   }
4903   E=E1;
4904   for(i=1;i<=size(E);i++)
4905   {
4906      v=i;
4907      E1[i]=list(E[i],v);
4908   }
4909   list ll;
4910   int re=1;
4911   int ok;
4912   while(size(E1)>0)
4913   {
4914      K=E1[1][1];
4915      v=E1[1][2];
4916      attrib(K,"isSB",1);
4917      E1=delete(E1,1);
4918      d=n-dim(K);
4919      M=minor(jacob(K),d)+K;
4920      if(deg(std(M)[1])>0)
4921      {
4922         if(size(#)>0)
4923         {
4924            if(size(reduce(M,std(cent),5))>0)
4925            {
4926               ll[size(ll)+1]=std(M);
4927            }
4928            else
4929            {
4930               ok=1;
4931            }
4932         }
4933         if(!loc)
4934         {
4935            re=0;
4936         }
4937         else
4938         {
4939            if(size(reduce(pp,std(radical(M)),5))>0){re=0;}
4940         }
4941      }
4942      for(i=1;i<=size(E);i++)
4943      {
4944         for(j=1;j<=size(v);j++){if(v[j]==i){break;}}
4945         if(j<=size(v)){if(v[j]==i){i++;continue;}}
4946         Estd=std(K+E[i]);
4947         w=v;
4948         if(deg(Estd[1])==0){i++;continue;}
4949         if(d==n-dim(Estd))
4950         {
4951            if(size(#)>0)
4952            {
4953               if(size(reduce(Estd,std(cent),5))>0)
4954               {
4955                  ll[size(ll)+1]=Estd;
4956               }
4957               else
4958               {
4959                  ok=1;
4960               }
4961            }
4962            if(!loc)
4963            {
4964               re=0;
4965            }
4966            else
4967            {
4968               if(size(reduce(pp,std(radical(M)),5))>0){re=0;}
4969            }
4970         }
4971         w[size(w)+1]=i;
4972         E2[size(E2)+1]=list(Estd,w);
4973      }
4974      if(size(E2)>0)
4975      {
4976         if(size(E1)>0)
4977         {
4978            E1[size(E1)+1..size(E1)+size(E2)]=E2[1..size(E2)];
4979         }
4980         else
4981         {
4982            E1=E2;
4983         }
4984      }
4985      kill E2;
4986      list E2;
4987   }
4988/*
4989   if((!ok)&&(!re)&&(size(#)==1))
4990   {
4991
4992      "the center is wrong";
4993      "it could be one of the following list";
4994      ll;
4995       ~;
4996   }
4997*/
4998   if((!ok)&&(!re)&&(size(#)==2))
4999   {
5000      return(2);   //for Center correction
5001   }
5002   return(re);
5003}
5004//////////////////////////////////////////////////////////////////////////////
5005static proc normalCrossB(ideal J,list E,ideal V)
5006"Internal procedure - no help and no example available
5007"
5008{
5009   int i,d,j;
5010   int n=nvars(basering);
5011   list E1,E2;
5012   ideal K,M,Estd;
5013   intvec v,w;
5014
5015   for(i=1;i<=size(E);i++)
5016   {
5017      Estd=std(E[i]+J);
5018      if(deg(Estd[1])>0)
5019      {
5020         E1[size(E1)+1]=Estd;
5021      }
5022   }
5023   E=E1;
5024   for(i=1;i<=size(E);i++)
5025   {
5026      v=i;
5027      E1[i]=list(E[i],v);
5028   }
5029   list ll;
5030   int re=1;
5031
5032   while((size(E1)>0)&&(re==1))
5033   {
5034      K=E1[1][1];
5035      v=E1[1][2];
5036      attrib(K,"isSB",1);
5037      E1=delete(E1,1);
5038      d=n-dim(K);
5039      M=minor(jacob(K),d)+K;
5040      if(deg(std(M+V)[1])>0)
5041      {
5042         re=0;
5043         break;
5044      }
5045      for(i=1;i<=size(E);i++)
5046      {
5047         for(j=1;j<=size(v);j++){if(v[j]==i){break;}}
5048         if(j<=size(v)){if(v[j]==i){i++;continue;}}
5049         Estd=std(K+E[i]);
5050         w=v;
5051         if(deg(Estd[1])==0){i++;continue;}
5052         if(d==n-dim(Estd))
5053         {
5054            if(deg(std(Estd+V)[1])>0)
5055            {
5056               re=0;
5057               break;
5058            }
5059         }
5060         w[size(w)+1]=i;
5061         E2[size(E2)+1]=list(Estd,w);
5062      }
5063      if(size(E2)>0)
5064      {
5065         if(size(E1)>0)
5066         {
5067            E1[size(E1)+1..size(E1)+size(E2)]=E2[1..size(E2)];
5068         }
5069         else
5070         {
5071            E1=E2;
5072         }
5073      }
5074      kill E2;
5075      list E2;
5076   }
5077   return(re);
5078}
5079//////////////////////////////////////////////////////////////////////////////
5080static proc norC(list BO,ideal cent)
5081"Internal procedure - no help and no example available
5082"
5083{
5084   int j;
5085   list  E=BO[4];
5086   ideal N=BO[2];
5087   if(BO[3][1]>1){return(0);}
5088   if(deg(std(slocusE(BO[2]))[1])>0){return(0);}
5089   if(!transversalT(N,E)){return(0);}
5090   for(j=1;j<=size(E);j++){if(deg(E[j][1])>0){E[j]=E[j]+N;}}
5091   if(!normalCross(E,cent)){return(0);}
5092   return(1);
5093}
5094//////////////////////////////////////////////////////////////////////////////
5095static proc specialReduce(ideal I,ideal J,poly p)
5096{
5097   matrix M;
5098   int i,j;
5099   for(i=1;i<=ncols(I);i++)
5100   {
5101      M=coeffs(I[i],@z);
5102      I[i]=0;
5103      for(j=1;j<=nrows(M);j++)
5104      {
5105         I[i]=I[i]+M[j,1]*p^(nrows(M)-j);
5106      }
5107      I[i]=reduce(I[i],J);
5108   }
5109   return(I);
5110}
Note: See TracBrowser for help on using the repository browser.