source: git/Singular/LIB/classify.lib

spielwiese
Last change on this file was 9bfa4d, checked in by Hans Schoenemann <hannes@…>, 5 months ago
bigntvec - intvec use (stdhilb, eliminate)
  • Property mode set to 100644
File size: 92.6 KB
Line 
1///////////////////////////////////////////////////////////////////////////////
2version="version classify.lib 4.4.0.0 Nov_2023 "; // $Id$
3category="Singularities";
4info="
5LIBRARY:  classify.lib  Arnold Classifier of Singularities
6AUTHOR:   Kai Krueger, krueger@mathematik.uni-kl.de
7
8OVERVIEW:
9   A library for classifying isolated hypersurface singularities w.r.t. right
10   equivalence, based on the determinator of singularities by V.I. Arnold.
11
12SEE ALSO:  realclassify_lib
13
14PROCEDURES:
15 basicinvariants(f); computes Milnor number, determinacy-bound and corank of
16 classify(f);        normal form of polynomial f determined with Arnold's method
17 corank(f);          computes the corank of f (i.e. of the Hessian of f)
18 Hcode(v);           coding of intvec v according to the number repetitions
19 init_debug([n]);    print trace and debugging information depending on int n
20 internalfunctions();display names of internal procedures of this library
21 milnorcode(f[,e]);  Hilbert polynomial of [e-th] Milnor algebra coded with Hcode
22 morsesplit(f);      residual part of f after applying the splitting lemma
23 quickclass(f)       normal form of f determined by invariants (milnorcode)
24 singularity(s,[]);  normal form of singularity given by its name s and index
25 A_L(s/f);           shortcut for quickclass(f) or normalform(s)
26 normalform(s);      normal form of singularity given by its name s
27 debug_log(lev,[]);  print trace and debugging information w.r.t level>@DeBug
28 swap(a,b);          swaps the arguments
29 modality(f);        modality of the singularity
30 complexSingType(f); complex type of the singularity as a string
31 prepRealclassify(f);
32                     the modality and the complex type of the singularity at
33                     once
34           (parameters in square brackets [] are optional)
35";
36
37LIB "inout.lib";
38LIB "elim.lib";
39LIB "sing.lib";
40LIB "makedbm.lib";
41
42///////////////////////////////////////////////////////////////////////////////
43proc classify_init
44{
45  string s;
46  link l="DBM:r NFlist";
47  s = read(l,"VERSION");
48  if (s == "" )
49  {
50    if (printlevel > 0)
51    {
52      "(classify.lib): Need to create database...";
53    }
54    create_sing_dbm();
55  }
56  close(l);
57  l="DBM:r NFlist";
58  s = read(l,"VERSION");
59  //"(classify.lib): Creation done. Current version:", s;
60}
61///////////////////////////////////////////////////////////////////////////////
62
63proc classify (poly f_in)
64"USAGE:    classify(f);  f=poly
65COMPUTE:  normal form and singularity type of f with respect to right
66          equivalence, as given in the book \"Singularities of differentiable
67          maps, Volume I\" by V.I. Arnold, S.M. Gusein-Zade, A.N. Varchenko
68RETURN:   normal form of f, of type poly
69REMARK:   This version of classify is only beta. Please send bugs and
70          comments to: \"Kai Krueger\" <krueger@mathematik.uni-kl.de> @*
71          Be sure to have at least Singular version 1.0.1.
72NOTE:     type init_debug(n); (0 <= n <= 10) in order to get intermediate
73          information, higher values of n give more information.
74          The proc creates several global objects with names all starting
75          with @, hence there should be no name conflicts.
76EXAMPLE:  example classify; shows an example"
77{
78//---------------------------- initialisation ---------------------------------
79  poly   f_out;
80  int    n, i, corank, show_nf;
81  string s2;
82  list   v;
83  def ring_ext = basering;
84
85  // Namespaces:
86  if(defined(A_Z)==0) { proc A_Z = General::A_Z; export A_Z; }
87  init_debug();                    // initialize trace/debug mode
88  if(checkring()) { return(f_in); }
89  n = nvars(basering);
90  show_nf  = 1;                // return normal form if set to '1'
91
92  // define new ring
93  ring ring_top=char(basering),(x(1..n)),(c,ds);
94
95  map conv_ext2top=ring_ext,maxideal(1);
96
97  if(defined(@ringdisplay)!=0) { kill @ringdisplay; }
98  string @ringdisplay = "ring_ext";
99  export @ringdisplay;
100
101  v = Klassifiziere(conv_ext2top(f_in));
102  if(typeof(v[1])=="poly")
103  {
104     poly f_out = v[1];
105     s2 = v[2];          // s2: Typ des Polynoms f z.b: E[18]
106     corank = v[3];
107  }
108  else
109  {
110     s2="NoClass";
111  }
112
113//---------------- collect results and create return-value --------------------
114  if( s2=="error!" || s2=="NoClass")
115  {
116      setring ring_ext;
117      return(f_in);
118  }
119
120  if(show_nf==1)
121  {
122    poly f_nf = normalform(s2);
123    for(i=corank+1;i<=n;i=i+1) { f_nf = f_nf + x(i)^2; }
124    debug_log(2, "Normal form NF(f)=", f_nf);
125  }
126  if(corank>1) { for(i=corank+1;i<=n;i=i+1) { f_out = f_out + x(i)^2; } }
127  setring ring_ext;
128  map conv_top2ext=ring_top,maxideal(1);
129
130  if(show_nf == 1) { return(conv_top2ext(f_nf)); }
131  else { return(conv_top2ext(f_out)); }
132}
133example
134{"EXAMPLE"; echo=2;
135   ring r=0,(x,y,z),ds;
136   poly f=(x2+3y-2z)^2+xyz-(x-y3+x2*z3)^3;
137   classify(f);
138   init_debug(3);
139   classify(f);
140}
141
142///////////////////////////////////////////////////////////////////////////////
143static proc Klassifiziere (poly f)
144{
145//--------------------------- initialisation ----------------------------------
146  string s1;
147  int    n, cnt, corank_f, K, Mu;
148  list   v, cstn;
149  map    PhiG;
150  def ring_top = basering;
151
152  n = nvars(basering);    // Zahl der Variablen des aktuellen Rings.
153  PhiG = ring_top, maxideal(1);
154  cstn[4] = PhiG;
155  if( defined(@ringdisplay) == 0)
156  {
157    string @ringdisplay;               // Define always 'ringdisplay' to be
158    export @ringdisplay;               // able to run 'Show(f)'
159  }
160  @ringdisplay = "setring RingB;";
161  if(defined(RingB)!=0) { kill RingB; }
162  ring RingB = create_ring(ring_list(basering)[1], "("+A_Z("x", n)+")", "(c,ds)", "no_minpoly");
163  export RingB;
164  setring ring_top;
165
166//---------------------- compute basciinvariants ------------------------------
167  if(jet(f,0) != 0 )
168  {
169    cstn[1] = corank(f); cstn[2]=-1; cstn[3]=1;
170    return(printresult(1, f, "a unit", cstn, -1));
171  }
172
173  debug_log(1, "Computing Basicinvariants of f ...");
174  K, Mu, corank_f = basicinvariants(f);
175  debug_log(0, "About the singularity :");
176  debug_log(0, "          Milnor number(f)   = "+string(Mu));
177  debug_log(0, "          Corank(f)          = "+string(corank_f));
178  debug_log(0, "          Determinacy       <= "+string(K));
179  cstn[1] = corank_f;
180  cstn[2] = Mu;
181  cstn[3] = K;
182
183  if( Mu == 0)
184  {
185    cstn[1]=1; cstn[3]=1;
186    return(printresult(1, f, "A[0]", cstn, 0));
187  }
188
189  if(Mu<0)
190  {
191    debug_log(0, "The Milnor number of the function is infinite.");
192    debug_log(0, "The singularity is not in Arnolds list.");
193    return(printresult(1, 1, "error!", cstn, -1));
194  }
195
196  f = jet(f, K);
197  v = HKclass(milnorcode(f));
198  if(v[2]>0) { debug_log(0, "Guessing type via Milnorcode: ", v[1]);}
199  else
200  {
201    debug_log(0, "Hilbert polynomial not recognised. Milnor code = ",
202              milnorcode(f));
203  }
204  debug_log(0, "");
205  debug_log(0, "Computing normal form ...");
206
207//------------ step 1, classification according to corank(f) ------------------
208  if(corank_f == 0)
209  {
210    return(printresult(2, f, "A["+string(Mu)+"]", cstn, 0));
211  }
212  if(corank_f == 1)
213  {
214    return(printresult(2, f, "A["+string(Mu)+"]", cstn, 0));
215  }
216  cstn[4] = 0;
217  if(corank_f == 2) { return(Funktion1bis(f, cstn)); }
218  if(corank_f == 3) { return(Funktion1bis(f, cstn)); }
219  return(printresult(105, f, "NoClass", cstn, -1));
220}
221
222///////////////////////////////////////////////////////////////////////////////
223static proc Funktion1bis (poly f, list cstn)
224{
225//---------------------------- initialisation ---------------------------------
226   def ring_top=basering;
227   poly   g;
228   int    n, corank, K;
229   map    conv, PhiG;
230   string s1;
231   list   v_res, v_class, v, iv;
232
233   corank = cstn[1];
234   K = cstn[3];
235   n = nvars(basering);
236
237//-------------------- apply morsesplit if n>corank ---------------------------
238   if( n > corank)
239   {
240     debug_log(0,
241      "I have to apply the splitting lemma. This will take some time....:-)");
242     v_res = Morse(f, K, corank, 0);
243     g = v_res[1];
244     PhiG = v_res[2];
245
246     conv = ReOrder(g);
247     g = conv(g);
248     PhiG = conv(PhiG);
249
250     if(defined(RingB) != 0 ) { kill RingB; }
251     ring ring_rest=char(basering),(x(1..corank)),(c,ds);
252
253     map MapReduce=ring_top,maxideal(1);
254     poly G = MapReduce(g);
255     map PhiG=ring_top,maxideal(1);// Konstruiere Id auf r
256     PhiG = MapReduce(PhiG);
257
258     ring RingB = create_ring(ring_list(basering)[1], "("+A_Z("x",corank)+")", "(c,ds)", "no_minpoly");
259     export RingB;
260     setring ring_rest;
261   }
262   else
263   {
264     ring ring_rest=char(basering),(x(1..corank)),(c,ds);
265     map  PhiG=ring_top,maxideal(1);
266     poly G = PhiG(f);
267   }
268
269//--------------------- step 1 of Arnold now finished -------------------------
270    map phi = ring_rest,maxideal(1);
271    cstn[4] = phi;
272    if(corank == 2) { v_class = Funktion3(G, cstn); }
273    else
274    {
275      if(corank == 3) { v_class = Funktion50(G, cstn); }
276      else { v_class = printresult(1, f, "error!", cstn, -1); }
277    }
278//-------------------------- classification done ------------------------------
279    if(typeof(v_class[1])!="poly") { return(v); }
280    poly f_result = v_class[1];
281    v[2] = v_class[2];
282    v[3] = v_class[3];
283    map Phi = v_class[4];
284    PhiG = Phi(PhiG);
285    setring ring_top;
286    if(defined(conv)!=0) { kill conv; }
287    map conv=ring_rest,maxideal(1);
288    v[1] = conv(f_result);
289    return(v);
290}
291
292///////////////////////////////////////////////////////////////////////////////
293static proc Funktion3 (poly f, list cstn)
294{
295//---------------------------- initialisation ---------------------------------
296    poly f3 = jet(f, 3);
297    ideal Jf;
298    int Dim, Mult, Mu;
299    debug_log(1, "Step 3");
300
301    if( f3 == 0 ) { return(Funktion13(f, cstn)); }
302
303    // f3 ~ x3 , x2y+y3 , x2y
304    Jf = std(jacob(f3));
305    Dim = dim(Jf);
306    if(Dim == 0) { return(printresult(4, f, "D[4]", cstn, 0)); }
307
308    Mult = mult(Jf);
309    Mu = cstn[2];
310    if(Dim == 1)
311    {
312      if( Mult == 1) { return(printresult(5,f,"D["+string(Mu)+"]", cstn, 0)); }
313      if( Mult == 2) { return(Funktion6(f, cstn));}         // series E,J
314      debug_log(0, "dimension 1 und deg != 1, 2 => error, ",
315                        "this should never occur");
316      return(printresult(3, f, "error!", cstn, -1));
317      // Should never reach this line
318    }
319    // Should never reach this line
320    return(printresult(3, f, "error!", cstn, -1));
321}
322
323///////////////////////////////////////////////////////////////////////////////
324static proc Funktion6 (poly f, list cstn)
325{ // Arnold's steps 6-12
326//---------------------------- initialisation ---------------------------------
327    poly   f3, fk;
328    ideal  JetId, Jf;
329    int    k, Dim, Mult, n, Mu;
330    map    PhiG, Phi;
331    intvec RFlg;
332    list   v;
333
334    def ring_top=basering;
335    f3   = jet(f, 3);            // 3-Jet von f
336    n    = nvars(basering);
337    Mu   = cstn[2];
338    PhiG = cstn[4];
339    k    = 1;
340    debug_log(1, "   Step 6");
341
342    RFlg = GetRf(f, n);
343    v    = Faktorisiere(f, f3, 3, 1, RFlg);
344    f    = v[1];
345    Phi  = v[2];
346    PhiG = Phi(PhiG);
347    cstn[4] = PhiG;
348
349//---------------------------- begin of loop ----------------------------------
350    while( (6*k) <= Mu )
351    {
352      JetId = x(1)^3+x(2)^(3*k);
353      fk    = jet(f, 3*k, weight(JetId));
354      //--------------------------- step 6(k) ---------------------------------
355      if( fk == Coeff(fk,x(1), x(1)^3)*x(1)^3 )
356      {
357        JetId = x(1)^3+x(2)^(3*k+1);           // check jet x3,y3k+1  : E[6k]
358        fk    = jet(f, 3*(3*k+1), weight(JetId));
359        if( Coeff(fk,x(2),x(2)^(3*k+1)) != 0 )
360        {
361          return(printresult(7, f, "E["+string(6*k)+"]", cstn, k-1));
362        }
363
364        JetId = x(1)^3+x(1)*x(2)^(2*k+1);      // check jet x3,xy2k+1 : E[6k+1]
365        fk    = jet(f, 3*(2*k+1), weight(JetId));
366        if( Coeff(fk, x(1)*x(2), x(1)*x(2)^(2*k+1)) != 0 )
367        {
368          return(printresult(8, f,"E["+string(6*k+1)+"]", cstn, k-1));
369        }
370
371        JetId = x(1)^3+x(2)^(3*k+2);           // check jet x3,y3k+1  : E[6k+2]
372        fk    = jet(f, 3*(3*k+2), weight(JetId));
373        if( Coeff(fk,x(2),x(2)^(3*k+2)) != 0 )
374        {
375          return(printresult(9, f,"E["+string(6*k+2)+"]", cstn, k-1));
376        }
377
378        //------------------------- step 10(k) --------------------------------
379        k++;
380        JetId = x(1)^3+x(2)^(3*k);
381        fk    = jet(f, 3*k, weight(JetId));
382        Jf    = std(jacob(fk));
383        Dim   = dim(Jf);
384
385        if(Dim==0) { return(printresult(11,f,"J["+string(k)+",0]",cstn,k-1)); }
386        Mult = mult(Jf);
387        if( Dim ==1  && Mult==1)
388        {
389          return(printresult(12,f,"J["+string(k)+","+string(Mu - 6*k +2)+"]",
390                 cstn, k-1));
391        }
392        if( Dim == 1  && Mult == 2)
393        {
394          if(Coeff(fk, x(2), x(2)^(3*k)) != 0)
395          {
396            v    = Faktorisiere(f, fk, 3, k, RFlg);
397            f    = v[1];
398            Phi  = v[2];
399            PhiG = Phi(PhiG);
400            cstn[4] = PhiG;
401          }
402        }
403      }
404    }
405    // Should never reach this line
406    return(printresult(6, f, "error!", cstn, -1));
407}
408
409///////////////////////////////////////////////////////////////////////////////
410static proc Funktion13 (poly f, list cstn)
411{
412//---------------------------- initialisation ---------------------------------
413    poly f4;
414    ideal Jf;
415    int Dim, Mult, Mu;
416
417    debug_log(1, "   Step 13");
418    Mu = cstn[2];
419    f4 = jet(f, 4);
420    if( f4 == 0 ) { return(Funktion47(f, cstn)); }
421
422    // f4 ~ x4+ax2y2+y4, x4+x2y2, x2y2, x3y, x4
423    Jf  = std(jacob(f4));
424    Dim = dim(Jf);
425
426    if(Dim==0) { return(printresult(14,f,"X[9] = X[1,0] = T[2,4,4]",cstn,1)); }
427    Mult = mult(Jf);
428    if( Dim == 1)
429    {
430      if( Mult == 1 )
431      {
432        return(printresult(15, f,
433              "X[1,"+string(Mu-9)+"] = T[2,4,"+string(Mu-5)+"]", cstn, 1));
434      }
435      if( Mult == 2 )
436      {
437        Jf = Jf, jacob(Jf);
438        Jf = std(Jf);
439        Dim = dim(Jf);
440        if(Dim==0){return(printresult(16,f,"Y[1,p,q] = T[2,4+p,4+q]",cstn,1));}
441        if( Dim == 1 ) { return(Funktion17(f, cstn)); }
442      }
443      if( Mult == 3 ) { return(Funktion25(f, cstn)); }
444    }
445    // Should never reach this line
446    return(printresult(13, f, "error!", cstn, -1));
447}
448
449///////////////////////////////////////////////////////////////////////////////
450static proc Funktion17 (poly f, list cstn)
451{ // Analog zu Fumktion 6, Kombination 17-24
452//---------------------------- initialisation ---------------------------------
453    poly  fk, ft;
454    ideal JetId, Jf;
455    int   p, Dim, Mult, Mu;
456    list  v;
457    map   PhiG, Phi;
458
459    def ring_top=basering;
460    debug_log(1, "      Step 17");
461    Mu   = cstn[2];
462    PhiG = cstn[4];
463    fk   = jet(f, 4);
464    p    = 1;
465
466//---------------------------- begin of loop ----------------------------------
467    while( 3*p<= Mu)
468    {
469      debug_log(1, "         Step 18("+string(p)+")");
470      v   = Isomorphie_s17(f, fk, p, 1);
471      f, Phi  = v[1..2];
472      PhiG    = Phi(PhiG);
473      cstn[4] = PhiG;
474
475      if ( p>1)
476      {
477        JetId = x(1)^3*x(2) + x(2)^(3*p);
478        fk = jet(f, 3*p, weight(JetId));
479      }
480      //--------------------------- step 18(p) --------------------------------
481      JetId = x(1)^3*x(2) + x(2)^(3*p+2);     // check jet x3y,y3k+2  : Z[6p+5]
482      fk = jet(f, 3*(3*p+2), weight(JetId));
483      if( Coeff(fk, x(2), x(2)^(3*p+2)) != 0)
484      {
485        return(printresult(19,f, "Z["+string(6*p+5)+"]", cstn, p));
486      }
487
488      JetId = x(1)^3*x(2)+x(1)*x(2)^(2*p+2);  // check jet x3y,xy2k+2 : Z[6p+6]
489      fk = jet(f, 2*(3*p+2)+1, weight(JetId));
490      if( Coeff(fk, x(1)*x(2), x(1)*x(2)^(2*p+2)) != 0)
491      {
492        return(printresult(20, f, "Z["+string(6*p+6)+"]", cstn, p));
493      }
494
495      JetId = x(1)^3*x(2) + x(2)^(3*p+3);     // check jet x3y,y3k+3  : Z[6p+7]
496      fk = jet(f, 3*(3*p+3), weight(JetId));
497      if( Coeff(fk, x(2), x(2)^(3*p+3)) != 0)
498      {
499        return(printresult(21, f, "Z["+string(6*p+7)+"]", cstn, p));
500      }
501
502      //---------------------------- step 22 ----------------------------------
503      p = p+1;
504      JetId = x(1)^3*x(2) + x(2)^(3*p+1);
505      fk   = jet(f, 3*p+1, weight(JetId));
506      ft   = Teile(fk, x(2));
507      Jf   = std(jacob(ft));
508      Dim  = dim(Jf);
509      Mult = mult(Jf);
510      if(Dim==0) { return(printresult(23,f,"Z["+string(p-1)+",0]", cstn, p)); }
511      if( Mult == 1 )
512      {
513         return(printresult(24, f, "Z["+string(p-1)+","+string(Mu-3-6*p)+"]",
514                cstn, p));
515      }
516    }
517    // Should never reach this line
518    return(printresult(17, f, "error!", cstn, -1));
519}
520
521///////////////////////////////////////////////////////////////////////////////
522static proc Funktion25 (poly f, list cstn)
523{ // Analog zu Fumktion 6, Kombination 25-46
524//---------------------------- initialisation ---------------------------------
525    poly   fk, ft;
526    ideal  JetId, Jf;
527    int    k, Dim, Mult, Mu;
528    map    PhiG, Phi;
529    intvec RFlg;
530    list   v;
531    def ring_top=basering;
532
533    debug_log(1, "      Step 25");
534    Mu   = cstn[2];
535    PhiG = cstn[4];
536    fk   = jet(f, 4);
537    k    = 1;
538    RFlg = GetRf(f, 2);
539
540//---------------------------- begin of loop ----------------------------------
541    while (k<Mu)
542    {
543      v    =  Faktorisiere(f, fk, 4 , k, RFlg);
544      f, Phi  = v[1..2];
545      PhiG    = Phi(PhiG);
546      cstn[4] = PhiG;
547
548      //--------------------------- step 26(k) --------------------------------
549      JetId = x(1)^4 + x(2)^(4*k+1);          // check jet x4,y4k+1  : W[12k]
550      fk    = jet(f, 4*(4*k+1), weight(JetId));
551      if( Coeff(fk, x(2), x(2)^(4*k+1)) != 0)
552      {
553        return(printresult(27, f, "W["+string(12*k)+"]", cstn, 3*k-2));
554      }
555
556      JetId = x(1)^4 + x(1)*x(2)^(3*k+1);     // check jet x4,xy3k+1 : W[12k+1]
557      fk    = jet(f, 4*(3*k+1), weight(JetId));
558      if( Coeff(fk, x(1)*x(2), x(1)*x(2)^(3*k+1)) != 0)
559      {
560        return(printresult(28, f, "W["+string(12*k+1)+"]", cstn, 3*k-2));
561      }
562
563      //--------------------------- step 29(k) --------------------------------
564      JetId = x(1)^4 + x(2)^(4*k+2);
565      fk    = jet(f, 2*(4*k+2), weight(JetId));
566      if( Coeff(fk, x(2), x(2)^(4*k+2)) != 0)
567      {
568        Jf  = std(jacob(fk));
569        Dim = dim(Jf);
570        if(Dim==0) {return(printresult(30,f,"W["+string(k)+",0]",cstn,3*k-1));}
571        if(Dim==1)
572        {
573           return(printresult(32, f,
574                  "W#["+string(k)+","+string(Mu-12*k-3)+"]", cstn, 3*k-1));
575        }
576        return(printresult(29, f, "error!", cstn, -1));
577      }
578      else
579      {
580        // x^4 oder x^2(x^2+x(2)^2k+1)
581        ft  = Teile(fk, x(1)^2);
582        Jf  = std(jacob(ft));
583        Dim = dim(Jf);
584        if( Dim == 0 )
585        {
586           return(printresult(31, f, "W["+string(k)+","+string(Mu-12*k-3)+"]",
587                  cstn, 3*k-1));
588        }
589        if( Dim != 1 ) { return(printresult(29, f, "error!", cstn, -1)); }
590
591        //-------------------------- step 33(k) -------------------------------
592        JetId = x(1)^4 + x(1)*x(2)^(3*k+2);   // check jet x4,xy3k+2 : W[12k+5]
593        fk    = jet(f, 4*(3*k+2), weight(JetId));
594        if( Coeff(fk, x(1)*x(2), x(1)*x(2)^(3*k+2)) != 0)
595        {
596          return(printresult(34, f,"W["+string(12*k+5)+"]", cstn, 3*k-1));
597        }
598
599        JetId = x(1)^4 + x(2)^(4*k+3);        // check jet x4,y4k+3  : W[12k+6]
600        fk    = jet(f, 4*(4*k+3), weight(JetId));
601        if( Coeff(fk, x(2), x(2)^(4*k+3)) != 0)
602        {
603          return(printresult(35, f,"W["+string(12*k+6)+"]", cstn, 3*k-1));
604        }
605
606        //-------------------------- step 36(k) -------------------------------
607        k = k+1;
608        JetId = x(1)^4 + x(2)^(4*k);
609        fk    = jet(f, (4*k), weight(JetId));
610        Jf    = std(jacob(fk));
611        Dim   = dim(Jf);
612        Mult  = mult(Jf);
613        if(Dim==0) {return(printresult(37,f,"X["+string(k)+",0]",cstn,3*k-1));}
614        if(Dim==1)
615        {
616          if(Mult==1)
617          {
618             return(printresult(38, f,"X["+string(k)+","+string(Mu-12*k+3)+"]",
619                    cstn, 3*k-1));
620          }
621          if(Mult==2)
622          {
623            ft  = Teile(fk, x(1)^2);
624            Jf  = std(jacob(ft));
625            Dim = dim(Jf);
626            if( Dim == 0) { return(Funktion40(f, cstn, k)); }
627            if( Dim == 1)
628            {
629               return(printresult(39, f, "Y["+string(k)+",r,s]", cstn,3*k-1));
630            }
631          }
632          if(Mult!=3)
633          {
634            return(printresult(36, f, "error!", cstn, -1)); }
635        }
636        else { return(printresult(36, f, "error!", cstn, -1)); }
637      }
638    }  // Ende der While-Schleife
639    // Should never reach this line
640    return(printresult(25, f, "error!", cstn, -1));
641}
642
643///////////////////////////////////////////////////////////////////////////////
644static proc Funktion40 (poly f, list cstn, int k)
645{
646//---------------------------- initialisation ---------------------------------
647    int    r, kr, rr, sr, oldDebug;
648    poly   fk, f2, a, b, c;
649    ideal  JetId, Jfsyz;
650    string Typ, RestRing, s1;
651    list   v1, v2;
652    def ring_top=basering;
653
654    debug_log(1, "         Step 40" );
655
656//------------------------------ compute f2 -----------------------------------
657    JetId = x(1)^4 + x(2)^(4*k);
658    fk  = jet(f, (4*k), weight(JetId));
659    f2  = -fk / x(1)^3;
660    Jfsyz = f - fk, x(1)^3, f2;
661    matrix Mat = matrix(syz(Jfsyz));
662    a = Mat[2,1] / Mat[1,1] - Mat[2,2];
663    b = - Mat[3,1] / Mat[1,1] + Mat[3,2];
664    ring tmp_ring=char(basering), (x(1),x(2)),(c,ds);
665    map map_top2tmp=ring_top,maxideal(1);
666    oldDebug = @DeBug;
667    init_debug(-1);
668//------------------------------ classify f2 ----------------------------------
669    v1=Klassifiziere(map_top2tmp(b));
670    init_debug(oldDebug);
671    Typ = v1[2];
672    v2 = DecodeNormalFormString(Typ);
673    Typ, kr, rr, sr = v2[1..4];
674    r   = kr-k;
675    setring ring_top;
676    if( Typ == "E[6k]" )
677    {
678       return(printresult(42, f, "Z["+string(k)+","+string(12*k+6*r-1)+"]",
679              cstn, 3*k+r-2));
680    }
681    if( Typ == "E[6k+1]" )
682    {
683       return(printresult(43, f, "Z["+string(k)+","+string(12*k+6*r)+"]",
684              cstn, 3*k+r-2));
685    }
686    if( Typ == "E[6k+2]" )
687    {
688       return(printresult(44, f, "Z["+string(k)+","+string(12*k+6*r+1)+"]",
689              cstn, 3*k+r-2));
690    }
691    if( Typ == "J[k,0]" )
692    {
693       return(printresult(45, f, "Z["+string(k)+","+string(r)+",0]",
694              cstn, 3*k+r-2));
695    }
696    if( Typ == "J[k,r]" )
697    {
698       return(printresult(46,f,"Z["+string(k)+","+string(r)+","+string(rr)+"]",
699              cstn, 3*k+r-2));
700    }
701    // Should never reach this line
702    return(printresult(40, f, "error!", cstn, -1));
703}
704
705///////////////////////////////////////////////////////////////////////////////
706static proc Funktion50 (poly f, list cstn)
707{
708//---------------------------- initialisation ---------------------------------
709    poly  f3;
710    ideal Jf, Jf1, Jf2;
711    int   Dim, Mult, Mu;
712    debug_log(1, "Step 50");
713
714    f3 = jet(f, 3);
715    if( f3 == 0 ) { return(printresult(104, f, "NoClass", cstn, -1)); }
716
717    // f3 ~
718    Jf1  = jacob(f3);
719    Jf   = std(Jf1);
720    Dim  = dim(Jf);
721    Mult = mult(Jf);
722    Mu   = cstn[2];
723
724    if(Dim == 0)
725    {
726       return(printresult(51, f, "P[8] = T[3,3,3]", cstn, 1));
727    } // x3 + y3 + z3 + axyz
728    if(Dim == 1)
729    {
730      if (Mult == 1)
731      {
732        return(printresult(52, f,"P["+string(Mu)+"] = T[3,3,"+string(Mu-5)+"]",
733               cstn, 1));
734      } // x3 + y3 + xyz
735      if(Mult == 2)
736      {
737        Jf2 = wedge(jacob(Jf1),3-Dim), Jf1;
738        Jf2 = std(Jf2);
739        Dim = dim(Jf2);
740        if (Dim==0) { return(printresult(54,f,"R[p,q] = T[3,p,q]", cstn, 1)); }
741        if (Dim==1) { return(Funktion58(f, cstn)); }  // x3 + yz2
742      }
743      if(Mult == 3)
744      {
745        Jf2 = wedge(jacob(Jf1),3-Dim), Jf1;
746        Jf2 = std(Jf2);
747        Dim = dim(Jf2);
748        if(Dim == 0) { return(printresult(56, f, "T[p,q,r]", cstn, 1)); }
749        if(Dim == 1) { return(Funktion66(f, cstn)); }   // x2z + yz2
750      }
751      if(Mult == 4) { return(Funktion82(f, cstn)); }    // x3 + xz2
752    }
753    if(Dim == 2)
754    {
755      if(Mult == 1) { return(Funktion97(f, cstn)); }    // x2y
756      if(Mult == 2) { return(printresult(103,f,"NoClass", cstn, -1));}
757    }
758
759    // Should never reach this line
760    return(printresult(50, f, "error!", cstn, -1));
761}
762
763///////////////////////////////////////////////////////////////////////////////
764static proc Funktion58 (poly fin, list cstn)
765{
766//---------------------------- initialisation ---------------------------------
767    poly  f, f3, a, b, phi, b1, b2, b3, fa, fb, fc;
768    ideal B, Jf3, J1, J2, S, Jfsyz;
769    int   kx, ky, kz;
770    string tp;
771    matrix M[2][3];
772    matrix C[2][3], D;
773    list v;
774    map  PhiG, VERT;
775    def ring_top=basering;
776    debug_log(1, "   Step 58");
777
778    f    = fin;
779    f3   = jet(f, 3);
780    PhiG = cstn[4];
781    tp   = "Nix";
782    kx   = 1;     // Koordinate x
783    ky   = 2;     // Koordinate y
784    kz   = 3;     // Koordinate z
785    B    = maxideal(1);     // ideal fuer Abbildungen
786    Jf3  = jacob(f3);
787    S    = sat(Jf3, maxideal(1));
788    J1   = diff(S[1], x(kx)), diff(S[1], x(ky)), diff(S[1], x(kz)),
789           diff(S[2], x(kx)), diff(S[2], x(ky)), diff(S[2], x(kz));
790    M    = J1;
791    J2   = minor(M, 2), S;
792
793    //------------------ determine coordinate named 'x' -----------------------
794    S  = sat(J2, maxideal(1));
795    J1 = Coeff(S[1], x(1), x(1)), Coeff(S[1], x(2), x(2)),
796          Coeff(S[1], x(3), x(3)), Coeff(S[2], x(1), x(1)),
797          Coeff(S[2], x(2), x(2)), Coeff(S[2], x(3), x(3));
798    C  = J1;
799    D  = syz(C);
800    kill C;
801
802    b1 = D[1,1];
803    b2 = D[2,1];
804    b3 = D[3,1];
805
806    debug_log(6, "f3,s1=", Show(f3));
807    if( b1 != 0)
808    {
809      VERT=ring_top,-1*b1*x(1), -1*b2*x(1)+x(2), -1*b3*x(1) + x(3);
810      kx=1; ky=2; kz=3;
811    }
812    else
813    {
814      if( b2 != 0)
815      {
816        VERT=ring_top, x(1) + -1*b1*x(2), -1*b2*x(2), -1*b3*x(2) + x(3);
817        kx=2; ky=1; kz=3;
818      }
819      else
820      {
821        if( b3 != 0)
822        {
823          VERT=ring_top,x(1) + -1*b1*x(3), x(2) + -1*b2*x(3), -1*b3*x(3);
824          kx=3; ky=1; kz=2;
825        }
826      }
827    }
828    f       = VERT(f);
829    PhiG    = VERT(PhiG);
830    cstn[4] = PhiG;
831    debug_log(6, VERT);
832    f3 = jet(f,3);
833    debug_log(6, "f3,s2=", Show(f3));
834
835    //---------------- compute f_2 such that j3f = xf_2+f_3 -------------------
836    debug_log(6, "1) x=", kx, "  y=", ky, "  z=", kz );
837    matrix C = Coeffs(f3, x(kx));
838    fb=C[2,1];  // Coeff von x^1
839    fc=C[1,1];  // Coeff von x^0
840    if(diff(fb, x(ky)) != 0)
841    {
842      Jfsyz = fb, diff(fb, x(ky));
843      matrix Mat = matrix(syz(Jfsyz));
844      B = maxideal(1);     // setze Abbildungs-ideal
845      if( nrows(Mat) == 2)
846      {
847        poly Relation = -2 * Mat[2,1] / Mat[1,1];
848        b = Coeff(Relation, x(kz), x(kz));
849        B[rvar(x(ky))] = x(ky)-b*x(kz);
850      }
851      else
852      {
853        Jfsyz = fb, diff(fb, x(kz));
854        Mat = matrix(syz(Jfsyz));
855        poly Relation = -2 * Mat[2,1];
856        a = Coeff(Relation, x(ky), x(ky));
857        B[rvar(x(kz))] = x(kz)-a*x(kz);
858        ky, kz = swap(ky, kz);
859      }
860      VERT = ring_top, B;
861      f    = VERT(f);
862      PhiG = VERT(PhiG);
863      cstn[4] = PhiG;
864      f3 = jet(f,3);
865      kill Mat;
866    }
867    else { ky,kz = swap(ky,kz); }
868
869    //------- compute tschirnhaus for 'z' and get f3=f_1(x,y,z)y^2+z^3 --------
870    C    = Coeffs(f3, x(kx));
871    fb   = C[2,1];  // Coeff von x^1
872    fc   = C[1,1];  // Coeff von x^0
873    v    = tschirnhaus(fc, x(kz));
874    fc, VERT = v[1..2];
875    f    = VERT(f);
876    PhiG = VERT(PhiG);
877    cstn[4] = PhiG;
878    f3 = jet(f,3);
879
880    //------------------- compute f_1 and get f3=xy^2+z^3 ---------------------
881    fb = (f3 - 1*(Coeffs(f3, x(kz))[4,1])*x(kz)^3)/(x(ky)^2);
882    fc=(x(kx)-1*(Coeffs(fb,x(ky))[2,1])*x(ky)-1*(Coeffs(fb,x(kz))[2,1])*x(kz));
883    fa = Coeffs(fb, x(kx))[2,1];
884    if ( fa != 0 )
885    {
886      B = maxideal(1);
887      B[rvar(x(kx))] = fc / fa;
888      VERT = ring_top, B;
889      f    = VERT(f);
890      PhiG = VERT(PhiG);
891      cstn[4] = PhiG;
892      f3   = jet(f,3);
893    }
894
895    //--------------------- permutation of x,y,z  -----------------------------
896    if(Coeffs(f3, x(1))[4,1]!=0)
897    {
898      kx=1;
899      if(Coeffs(f3, x(2))[3,1]==0) { ky=2; kz=3; }
900      else { ky=3; kz=2; }
901    }
902    else
903    {
904      if(Coeffs(f3, x(2))[4,1]!=0)
905      {
906        kx=2;
907        if(Coeffs(f3, x(3))[3,1]==0) { ky=3; kz=1; }
908        else { ky=1; kz=3; }
909      }
910      else
911      {
912        kx=3;
913        if(Coeffs(f3, x(1))[3,1]==0) { ky=1; kz=2; }
914        else { ky=2; kz=1; }
915      }
916    }
917    VERT = ring_top, x(kx), x(ky), x(kz);
918    f    = VERT(f);
919    PhiG = VERT(PhiG);
920    cstn[4] = PhiG;
921    f3   = jet(f,3);
922    return(Funktion59(f, cstn));
923}
924
925///////////////////////////////////////////////////////////////////////////////
926static proc Funktion59 (poly f, list cstn)
927{
928//---------------------------- initialisation ---------------------------------
929    poly   phi, fr, fk, alpha, beta, f_tmp;
930    ideal JetId;
931    int    p, Dim, Mult, Mu;
932    string tp;
933    list   v;
934    map    PhiG, Phi;
935    intvec w, RFlg;
936    def ring_top=basering;
937    debug_log(1, "      Step 59");
938
939    Mu   = cstn[2];
940    PhiG = cstn[4];
941    tp   = "Nix";
942    p    = 1;
943    phi  = jet(f,3);
944    fr   = f - phi;
945    RFlg = 1,2,3;
946    alpha = coeffs(fr, x(1))[1,1];
947    beta = (fr - alpha) / x(1);
948    debug_log(3, "f    = ", Show(f));
949    debug_log(3, "fr   = ", Show(fr));
950    debug_log(3, "alpha= ", Show(alpha));
951    debug_log(3, "beta = ", Show(beta));
952
953//---------------------------- begin of loop ----------------------------------
954    while(6*p<Mu)
955    {
956      JetId = x(2)^(3*p+1);
957      JetId = phi + x(2)^(3*p+1);
958      //--------------------------- step 59(k) --------------------------------
959      w     = weight(JetId);
960      fk    = jet(fr, 3*w[1], w);
961      if(fk!=0) { return(printresult(60,f, "Q["+string(6*p+4)+"]", cstn, p)); }
962
963      JetId = phi + x(1)*x(2)^(2*p+1);
964      w     = weight(JetId);
965      fk    = jet(fr, 3*w[1], w);
966      if(fk!=0) { return(printresult(61,f, "Q["+string(6*p+5)+"]", cstn, p)); }
967
968      JetId = phi + x(2)^(3*p+2);
969      w     = weight(JetId);
970      fk    = jet(fr, 3*w[1], w);
971      if(fk!=0) { return(printresult(62,f, "Q["+string(6*p+6)+"]", cstn, p)); }
972
973      //--------------------------- step 63(k) --------------------------------
974      p++;
975      JetId = phi + x(2)^(3*p);
976      w     = weight(JetId);
977      fk    = jet(f, 3*w[1], w);
978      JetId = std(jacob(fk));
979      Dim   = dim(JetId);
980      Mult  = mult(JetId);
981      if(Dim==0) { return(printresult(64, f, "Q["+string(p)+",0]", cstn, p)); }
982      if(Dim==1)
983      {
984        if(Mult == 1)
985        {
986           return(printresult(65, f, "Q["+string(p)+","+string(Mu-(6*p+2))+"]",
987                  cstn, p));
988        }
989        if(Mult == 2)
990        {
991          fk    = jet(fr, 3*w[1], w);
992          f_tmp = Coeffs(phi, x(1))[4,1] *x(1)^3+fk;
993          v    = Faktorisiere(f, f_tmp, 3 , p, RFlg);
994          f    = v[1];
995          Phi  = v[2];
996          PhiG = Phi(PhiG);
997          cstn[4] = PhiG;
998          fr = f - phi;
999        }
1000      }
1001    }
1002    // Should never reach this line
1003    return(printresult(59, f, "error!", cstn, -1));
1004}
1005
1006///////////////////////////////////////////////////////////////////////////////
1007static proc Funktion66 (poly f, list cstn)
1008{
1009//---------------------------- initialisation ---------------------------------
1010    int kx = 1; // Koordinate x
1011    int ky = 2; // Koordinate y
1012    int kz = 3; // Koordinate z
1013    poly f3 = jet(f, 3);
1014    ideal JetId;
1015
1016    debug_log(1, "   Step 66");
1017    debug_log(2, "F3=", Show(f3));
1018    poly fx = diff(f3, x(kx));
1019    JetId = jacob(fx);
1020    JetId = std(JetId);
1021    "nach x:",Show(fx), "  Id=", JetId, "  Dim=", dim(JetId);
1022
1023    poly fy = diff(f3, x(ky));
1024    JetId = jacob(fx);
1025    JetId = std(JetId);
1026    "nach y:",Show(fy), "  Id=", JetId, "  Dim=", dim(JetId);
1027
1028    poly fz = diff(f3, x(kz));
1029    JetId = jacob(fx);
1030    JetId = std(JetId);
1031    "nach z:",Show(fz), "  Id=", JetId, "  Dim=", dim(JetId);
1032    return(printresult(1, 66, "error!", cstn, -1));
1033}
1034
1035///////////////////////////////////////////////////////////////////////////////
1036static proc Funktion82 (poly f, list cstn)
1037{
1038//---------------------------- initialisation ---------------------------------
1039    poly   f3, b1, b2, b3;
1040    int    i, kx, ky, kz, Fall;
1041    ideal  Jfsyz, B;
1042    intvec kv = 1,2,3;
1043    matrix Mat;
1044    map    PhiG, VERT;
1045    list   v;
1046    def ring_top=basering;
1047    debug_log(1, "   Step 82");
1048
1049    f3 = jet(f,3);
1050    kx = 1;     // Koordinate x
1051    ky = 2;     // Koordinate y
1052    kz = 3;     // Koordinate z
1053    B  = maxideal(1);
1054    Jfsyz = jacob(f3);
1055    PhiG  = cstn[4];
1056    Fall  = 2;
1057
1058//------------------ find coordinatechange that f3 ~ g(x,z) -------------------
1059    if (diff(f3, x(1)) == 0) { kx, ky = swap(kx, ky); }
1060    if (diff(f3, x(2)) == 0) {  }
1061    if (diff(f3, x(3)) == 0) { kz, ky = swap(kz, ky); }
1062    if ( (diff(f3, x(1)) != 0) && (diff(f3, x(2)) != 0) &&
1063          (diff(f3, x(3)) != 0) )
1064    {
1065      Mat = matrix(syz(Jfsyz));
1066      b1  = Mat[1,1];
1067      b2  = Mat[2,1];
1068      b3  = Mat[3,1];
1069
1070      if( b1 != 0)
1071      {
1072        VERT = ring_top,b1*x(kx), b2*x(kx)+x(ky), b3*x(kx) + x(kz);
1073        kx, ky = swap(kx, ky);
1074      }
1075      else
1076      {
1077        if(b2!=0) { VERT = ring_top,x(kx)+b1*x(ky),b2*x(ky),b3*x(ky)+x(kz); }
1078        else
1079        {
1080          if(b3!=0) { VERT = ring_top,x(kx)+b1*x(kz),x(ky)+b2*x(kz),b3*x(kz); }
1081          else { VERT = ring_top,B; }
1082        }
1083      }
1084      f    = VERT(f);
1085      PhiG = VERT(PhiG);
1086      cstn[4] = PhiG;
1087    }
1088    VERT = ring_top,x(kx),x(ky),x(kz);
1089    f    = VERT(f);
1090    PhiG = VERT(PhiG);
1091    cstn[4] = PhiG;
1092    f3   = jet(f,3);
1093
1094    if( (f3-subst(f3, x(kx), 0)) == 0) { kx, ky = swap(kx, ky); }
1095    if( (f3-subst(f3, x(kz), 0)) == 0) { kz, ky = swap(kz, ky); }
1096
1097//------------ find coordinatechange for f3 ~ x3+xz2, if possible  ------------
1098    matrix C = coeffs(f3, x(kx));
1099    if(size(C) == 3) { C = coeffs(f3, x(kz)); kx,kz=swap(kx, kz); }
1100    if(C[1,1] == 0 && C[3,1] == 0) { Fall = 1; }
1101    if(C[1,1] != 0 && C[3,1] != 0 ) { Fall = 3; }
1102    if(C[1,1] == 0 && C[3,1] != 0 ) { Fall = 2; }
1103    if(C[1,1] != 0 && C[3,1] == 0 ) { Fall = 2; kx,kz=swap(kx, kz); }
1104
1105    if(Fall == 1)
1106    {
1107      VERT=ring_top,x(kx),x(ky),x(kz);
1108    }
1109    if(Fall == 2)
1110    {
1111       v = tschirnhaus(f3/x(kz), x(kx));
1112       b1, VERT = v[1..2];
1113    }
1114    if(Fall == 3)
1115    {
1116      v = tschirnhaus(f3/x(kx), x(kx));
1117      b1, VERT = [1..2];
1118      debug_log(2, "B1=", Show(jet(VERT(f),3)));
1119      v = tschirnhaus(f3/x(kz), x(kz));
1120      b2, VERT = [1..2];
1121      debug_log(2, "B2=", Show(jet(VERT(f),3)));
1122    }
1123    f    = VERT(f);
1124    PhiG = VERT(PhiG);
1125    cstn[4] = PhiG;
1126    f3   = jet(f,3);
1127
1128//------------- if f3 ~ x3+xz2 then continue with classification  -------------
1129    C = coeffs(f3, x(1));
1130    if( C[1,1] == 0 && C[2,1] != 0 && C[3,1] == 0 && C[4,1] != 0 )
1131    {
1132      return(Funktion83(f, cstn));
1133    }
1134    return(printresult(82, f, "error!", cstn, -1));
1135}
1136
1137///////////////////////////////////////////////////////////////////////////////
1138static proc Isomorphie_s82_z (poly f, poly fk, int p)
1139{
1140//---------------------------- initialisation ---------------------------------
1141    poly   Relation, a, b;
1142    ideal  Jfsyz, B;
1143    matrix Mat;
1144    map    VERT;
1145    list   v;
1146    def ring_top=basering;
1147
1148    debug_log(1, "      Isomorphie 82/90 z");
1149    debug_log(2, "tt=", Show(fk));
1150    Jfsyz = fk, diff(fk, x(3));
1151    Mat   = matrix(syz(Jfsyz));
1152    Relation = -2 * Mat[2,1] / Mat[1,1];
1153    a = Coeff(Relation, x(3), x(3));
1154    b = Coeff(Relation, x(2), x(2)^p);
1155    B = maxideal(1);
1156    B[rvar(x(3))] = x(3)-b*x(2)^p;
1157    VERT = ring_top,B;
1158    v    = VERT(f), VERT;
1159    debug_log(2, VERT);
1160    debug_log(2, "      z res=", Show(VERT(fk)));
1161    return(v);
1162}
1163
1164///////////////////////////////////////////////////////////////////////////////
1165static proc Isomorphie_s82_x (poly f, poly fk, int p)
1166{
1167//---------------------------- initialisation ---------------------------------
1168    matrix Mat;
1169    poly   Relation, a, b;
1170    ideal  Jfsyz, B;
1171    map    VERT;
1172    list   v;
1173    def ring_top=basering;
1174
1175    debug_log(1, "      Isomorphie 82/90 x");
1176    debug_log(2, "tt=", Show(fk));
1177    Jfsyz = fk, diff(fk, x(1));
1178    Mat   = matrix(syz(Jfsyz));
1179    Relation = -3 * Mat[2,1] / Mat[1,1];
1180    a = Coeff(Relation, x(1), x(1));
1181    b = Coeff(Relation, x(2), x(2)^p);
1182    B = maxideal(1);
1183    B[rvar(x(1))] = x(1)-b*x(2)^p;
1184    VERT = ring_top,B;
1185    v    = VERT(f), VERT;
1186    debug_log(2, VERT);
1187    debug_log(2, "      x res=", Show(VERT(fk)));
1188
1189    return(v);
1190}
1191
1192///////////////////////////////////////////////////////////////////////////////
1193static proc Funktion83 (poly f, list cstn)
1194{
1195//---------------------------- initialisation ---------------------------------
1196    poly   fk, phi, a, b;
1197    ideal  JetId, Jf, B;
1198    int    k, Dim, Mult;
1199    intvec w;
1200    map    PhiG, Phi;
1201    list   v;
1202    matrix Mat;
1203    def ring_top=basering;
1204    debug_log(1, "      Step 83");
1205
1206    k    = 1;
1207    PhiG = cstn[4];
1208//---------------------------- begin of loop ----------------------------------
1209    while(k<10)
1210    {
1211      phi   = jet(f, 3);
1212      //--------------------------- step 83(k) --------------------------------
1213      JetId = x(1)^3 + x(3)^3 + x(2)^(3*k+1);
1214      fk    = jet(f- phi, 3*w[1], weight(JetId)) ;
1215      if(fk!=0) { return(printresult(84,f,"U["+string(12*k)+"]",cstn,4*k-3)); }
1216
1217      JetId = x(1)^3 + x(3)^3 + x(1)*x(2)^(2*k+1);
1218      fk    = jet(f, 3*w[1], weight(JetId)) ;
1219      //--------------------------- step 85(k) --------------------------------
1220      if ( fk != phi )
1221      {
1222        Jf   = std(jacob(fk));
1223        Dim  = dim(Jf);
1224        if(Dim==0) {return(printresult(86,f,"U["+string(k)+",0]",cstn,4*k-2));}
1225        if(Dim==1) {return(printresult(87,f,"U["+string(k)+",p]",cstn,4*k-2));}
1226      }
1227
1228      //--------------------------- step 88(k) --------------------------------
1229      JetId = x(1)^3 + x(3)^3 + x(2)^(3*k+2);
1230      fk    = jet(f- phi, 3*w[1], weight(JetId)) ;
1231      if(fk!=0) {return(printresult(89,f,"U["+string(12*k+4)+"]",cstn,4*k-2));}
1232
1233      //--------------------------- step 90(k) --------------------------------
1234      k++;
1235      JetId = x(1)^3 + x(3)^3 + x(2)^(3*k);
1236      fk    = jet(f, 3*w[1], weight(JetId)) ;
1237      Jf    = std(jacob(fk));
1238      Dim   = dim(Jf);
1239      Mult  = mult(Jf);
1240      if ( Dim == 0 ) { return(printresult(83, f, "NoClass", cstn, -1)); }
1241      if ( Dim == 1 )
1242      {
1243        if ( Mult == 4 )
1244        {
1245          if( fk - phi != 0)
1246          { // b!=0  und/oder b'!=0
1247            if( Coeff(fk,x(1)*x(2), x(1)^2*x(2)^k) == 0 )
1248            { // b=0 und b'!=0
1249              a    = (fk - Coeff(fk, x(1), x(1)^3)*x(1)^3) / x(1);
1250              v    = Isomorphie_s82_z(f, a, k);
1251            }
1252            else
1253            {
1254              if( Coeff(fk,x(1)*x(2)*x(3), x(1)*x(2)^k*x(3)) == 0 )
1255              {
1256                        // b!=0 und b'=0
1257                a    = subst(fk, x(3), 0);
1258                v    = Isomorphie_s82_x(f, a, k);
1259              }
1260              else
1261              {
1262                a = Coeff(fk,x(1)*x(2)*x(3), x(1)*x(2)^k*x(3));
1263                b = Coeff(fk,x(2)*x(3), x(2)^(2*k)*x(3));
1264                B = maxideal(1);
1265                B[rvar(x(1))] = x(1)-b/a*x(2)^k;
1266                Phi  = ring_top,B;
1267                f    = Phi(f);
1268                PhiG = Phi(PhiG);
1269                cstn[4] = PhiG;
1270                fk   = jet(f, 3*w[1], w) ;
1271                a    = (fk - Coeff(fk, x(1), x(1)^3)*x(1)^3) / x(1);
1272                v    = Isomorphie_s82_z(f, a, k);
1273              } // ende else b!=0 und b'=0
1274            } // ende else b=0 und b'!=0
1275            f, Phi  = v[1..2];
1276            PhiG    = Phi(PhiG);
1277            cstn[4] = PhiG;
1278          } //ende fk-phi!=0
1279        } // ende mult=4
1280        else { return(printresult(83, f, "NoClass", cstn, -1)); }
1281      } // ende dim=1
1282      else { return(printresult(83, f, "NoClass", cstn, -1)); }
1283    } // ENDE While
1284    return(printresult(83, f, "error!", cstn, -1));
1285}
1286
1287///////////////////////////////////////////////////////////////////////////////
1288static proc Funktion97 (poly f, list cstn)
1289{
1290//---------------------------- initialisation ---------------------------------
1291    poly   f3, l1, l2, a, b, c, prod;
1292    ideal  Jfsyz, Jf, B;
1293    int    k, i, pt, kx, ky, kz, Dim, Mult, Mu;
1294    matrix Mat;
1295    map    PhiG, VERT;
1296    def ring_top=basering;
1297    debug_log(1, "   Step 97");
1298
1299    Mu   = cstn[2];
1300    PhiG = cstn[4];
1301    kx   = 1;   // Koordinate x
1302    ky   = 2;   // Koordinate y
1303    kz   = 3;   // Koordinate z
1304    B    = maxideal(1); // Abbildungs-ideal
1305    pt   = 2;
1306    f3   = jet(f, 3);
1307    k    = 1;
1308
1309//--------------------------- compute f3 ~ x2y --------------------------------
1310    // vertausche 2 Koordinaten sodass d2f/dx2 <>0 ist.
1311    for(i=1;i<4;i=i+1)
1312    {
1313      if(diff(diff(f3, x(i)), x(i)) != 0) { kx = i; i=4; }
1314    }
1315    if(kx == 2) { ky = 1; kz = 3; }
1316    if(kx == 3) { ky = 2; kz = 1; }
1317    //-------------------------- compute -l1*l2 -------------------------------
1318    f3    = jet(f, 3);
1319    Jfsyz = f3, diff(f3, x(kx));
1320    Mat   = matrix(syz(Jfsyz));
1321    if(deg(Mat[2,1])>1)
1322    {
1323      Jfsyz = f3, Mat[2,1];
1324      Mat   = matrix(syz(Jfsyz));
1325
1326      // berechen Abb. sodass f=x2*l2
1327      l1 = Mat[2,1];
1328      a  = Coeff(l1, x(kx), x(kx));
1329      l1 =  l1 / number(a);
1330      b  = Coeff(l1, x(ky), x(ky));
1331      c  = Coeff(l1, x(kz), x(kz));
1332      B[rvar(x(kx))] = x(kx) - b * x(ky) - c * x(kz);
1333      VERT = ring_top, B;
1334      f    = VERT(f);
1335      PhiG = VERT(PhiG);
1336      cstn[4] = PhiG;
1337
1338      f3 = jet(f, 3);
1339      l2 = f3 / x(kx)^2;
1340
1341      // sorge dafuer, dass b<>0 ist.
1342      b = Coeff(l2, x(ky), x(ky));
1343      if( b== 0) { ky, kz = swap(ky, kz); }
1344
1345      // Koordinaten-Transf. s.d. f=x2y
1346      b  = Coeff(l2, x(ky), x(ky));
1347      l2 =  l2 / number(b);
1348      a  = Coeff(l2, x(kx), x(kx));
1349      c  = Coeff(l2, x(kz), x(kz));
1350      B  = maxideal(1);
1351      B[rvar(x(ky))] = -a * x(kx) + x(ky) - c * x(kz);
1352      VERT = ring_top, B;
1353      f    = VERT(f);
1354      PhiG = VERT(PhiG);
1355      cstn[4] = PhiG;
1356    }
1357
1358//------------------------------- step 98 ---------------------------------
1359    Jfsyz = x(kx)^2*x(ky) + x(ky)^4 + x(kz)^4;
1360    a     = jet(f, 8, weight(Jfsyz));
1361    Jf    = std(jacob(a));
1362    Dim   = dim(Jf);
1363    Mult  = mult(Jf);
1364    if( Dim == 0) { return(printresult(99, f, "V[1,0]", cstn, 3)); }
1365    if( Dim == 1)
1366    {
1367      if(Mult==1) {return(printresult(100,f,"V[1,"+string(Mu-15)+"]",cstn,3));}
1368      if(Mult==2){return(printresult(101,f,"V#[1,"+string(Mu-15)+"]",cstn,3));}
1369    }
1370    " Dim=",Dim," Mult=",Mult;
1371    return(printresult(102, f, "NoClass", cstn, -1));
1372}
1373
1374///////////////////////////////////////////////////////////////////////////////
1375proc tschirnhaus (poly f, poly x)
1376"USAGE:    tschirnhaus();"
1377{
1378//---------------------------- initialisation ---------------------------------
1379    poly   b;
1380    ideal  B;
1381    int    n, j, hc;
1382    matrix cf;
1383    intvec z;
1384    string s;
1385    list   v;
1386    map    Phi, EH;
1387    def ring_top=basering;
1388
1389    n    = nvars(basering);
1390    cf   = coeffs(f, x);
1391    hc   = nrows(cf) - 1; // hoechster exponent von x_i
1392    b    = cf[hc+1,1];    // koeffizient von x_i^hc
1393    B    = maxideal(1);
1394    z[n] = 0;
1395    EH   = ring_top, z;
1396    Phi  = ring_top, B;
1397    v[1] = f;
1398    if ( EH(b) != 0)    // pruefe ob der Koeff von x_i^hc
1399    { B[rvar(x)] = x -1*(cf[hc,1]/(hc*b));
1400      v[1] = Phi(f);
1401    }
1402    v[2] = Phi;
1403    return(v);
1404}
1405
1406///////////////////////////////////////////////////////////////////////////////
1407static proc Isomorphie_s17 (poly f, poly fk, int k, int ct, list #)
1408{
1409//---------------------------- initialisation ---------------------------------
1410    ideal  Jfsyz, JetId, bb;
1411    poly   a, b, c, d, Relation, an, bn;
1412    int    B,C, alpha, beta, gamma, g;
1413    matrix Matx, Maty;
1414    map    PhiG, VERT;
1415    list   v;
1416    def ring_top=basering;
1417
1418    if(size(#)==1) { PhiG = #[1]; }
1419    else { PhiG = ring_top,maxideal(1); }
1420    bb = maxideal(1);
1421
1422    // Ziel: bestimme a,b,c,d sodass  fk = (ax+by^k)^3(cx+dy) gilt.
1423    debug_log(2, "Isomorphie_s17:");
1424    debug_log(2, "Faktor: f=",Show(f)," Jet=",Show(fk)," k=",k, "cnt=", ct);
1425
1426    if( k == 1)
1427    {
1428      Jfsyz = fk, diff(fk, x(1));
1429      Matx  = matrix(syz(Jfsyz));
1430      Jfsyz = fk, diff(fk, x(2));
1431      Maty  = matrix(syz(Jfsyz));
1432
1433      a = Coeff(fk, x(1), x(1)^4);
1434      b = Coeff(fk, x(2), x(2)^4);
1435      c = Coeff(fk, x(1)*x(2), x(1)^3*x(2));
1436      d = Coeff(fk, x(1)*x(2), x(1)*x(2)^3);
1437
1438      if( (a != 0) && (b != 0) )
1439      {
1440        B = -int(Coeff(Matx[1,1], x(2), x(2)));
1441        C = -int(Coeff(Maty[1,1], x(1), x(1)));
1442        alpha = int(Coeff(Matx[2,1], x(1), x(1)^2));
1443        beta  = int(Coeff(Matx[2,1], x(1)*x(2), x(1)*x(2)));
1444        gamma = int(Coeff(Matx[2,1], x(2), x(2)^2));
1445
1446        bb[rvar(x(1))] = x(1) - (2*number(gamma) / (B - beta))*x(2);
1447        bb[rvar(x(2))] = x(2) - ((C - number(beta)) / (2*gamma))*x(1);
1448        VERT     = ring_top,bb;
1449        Relation = VERT(f);
1450        fk       = jet(Relation, 4);
1451
1452        an = Coeff(fk, x(1), x(1)^4);
1453        bn = Coeff(fk, x(2), x(2)^4);
1454        if( (an != 0) & (bn != 0) ) { VERT=ring_top,x(1),(x(2) + a*x(1))/ b; }
1455        f    = VERT(f);
1456        fk   = jet(f, 4);
1457        PhiG = VERT(PhiG);
1458
1459        a = Coeff(fk, x(1), x(1)^4);
1460        b = Coeff(fk, x(2), x(2)^4);
1461        c = Coeff(fk, x(1)*x(2), x(1)^3*x(2));
1462        d = Coeff(fk, x(1)*x(2), x(1)*x(2)^3);
1463        Jfsyz = fk, diff(fk, x(1));
1464        Matx  = matrix(syz(Jfsyz));
1465        Jfsyz = fk, diff(fk, x(2));
1466        Maty  = matrix(syz(Jfsyz));
1467      }
1468
1469      if( (a == 0) || (b == 0) )
1470      {
1471        if( a == 0)
1472        {
1473          if( c == 0)
1474          { // y3(ax+by)
1475            Relation = - Matx[2,1] / Matx[1,1];
1476            a = Coeff(Relation, x(1), x(1));
1477            b = Coeff(Relation, x(2), x(2));
1478            VERT=ring_top,a*x(2)^k - b*x(1), x(1);
1479          }
1480          else
1481          { // (ax+by)^3y
1482            Relation = - 3*Matx[2,1] / Matx[1,1];
1483            a = Coeff(Relation, x(1), x(1));
1484            b = Coeff(Relation, x(2), x(2));
1485            VERT=ring_top,a*x(1) - b*x(2), x(2);
1486          }
1487        }
1488        else
1489        {
1490          if( d == 0)
1491          { // x3(ax+by)
1492            Relation = - Maty[2,1] / Maty[1,1];
1493            a = Coeff(Relation, x(1), x(1));
1494            b = Coeff(Relation, x(2), x(2));
1495            VERT=ring_top,x(1), b*x(2)^k - a*x(1);
1496          }
1497          else
1498          { // x(ax+by)^3
1499            Relation = - 3*Maty[2,1] / Maty[1,1];
1500            a = Coeff(Relation, x(1), x(1));
1501            b = Coeff(Relation, x(2), x(2));
1502            VERT=ring_top,x(2), b*x(1) - a*x(2);
1503          }
1504        }
1505        f    = VERT(f);
1506        PhiG = VERT(PhiG);
1507      }
1508      else
1509      {  //      "Weder b noch a sind 0";
1510        if(ct > 5) { v[1]=f; v[2]=PhiG; return(v); }
1511        fk = jet(f, 4);
1512        return(Isomorphie_s17(f, fk, k, ct+1, PhiG));
1513      }
1514    }
1515    else
1516    {  // k >1
1517      a     = fk/x(2);
1518      Jfsyz = a, diff(a, x(1));
1519      Matx  = matrix(syz(Jfsyz));
1520      Relation = -3 * Matx[2,1] / Matx[1,1];
1521      a    = Coeff(Relation, x(1), x(1));
1522      b    = Coeff(Relation, x(2), x(2)^k);
1523      VERT = basering,x(1)-b*x(2)^k,x(2);
1524      f    = VERT(f);
1525      PhiG = VERT(PhiG);
1526      JetId = x(1)^3*x(2) + x(2)^(3*k+1);
1527      fk = jet(f, 3*k+1, weight(JetId));
1528    }
1529    v = f, PhiG;
1530    debug_log(2, "Isomorphie_s17: done");
1531    debug_log(2, "Faktor: f=",Show(f)," Jet=",Show(fk)," k=",k);
1532
1533    return(v);
1534}
1535
1536///////////////////////////////////////////////////////////////////////////////
1537static proc printresult (int step, poly f, string typ, list cstn, int m)
1538{
1539  if(defined(onlyreturninvariants))
1540  {
1541    if(onlyreturninvariants == 1)
1542    {
1543      Modality = m;
1544      Type = typ;
1545    }
1546  }
1547//---------------------------- initialisation ---------------------------------
1548  int corank, Mu, K;
1549  list v;
1550
1551  corank, Mu, K = cstn[1..3];
1552  debug_log(0,"   Arnold step number "+string(step));
1553  if( @DeBug >= 0 )
1554  {
1555    "The singularity";
1556    "   "+Show(jet(f, K))+"";
1557    if( typ != "error!" && typ != "NoClass" )
1558    {
1559      "is R-equivalent to "+typ+".";
1560    }
1561    if ( typ == "NoClass" )
1562    {
1563      "is not in Arnolds list.";
1564    }
1565//    if(K>=0)  { "  det = "+string(K); }
1566    if(Mu>=0) { "   Milnor number = "+string(Mu); }
1567    if(m>=0)  { "   modality      = "+string(m); }
1568  }
1569  v = f, typ, corank, cstn[4];
1570  return(v);
1571}
1572
1573///////////////////////////////////////////////////////////////////////////////
1574static proc Funktion47 (poly f, list cstn)
1575{
1576  int corank = cstn[1];
1577  int Mu = cstn[2];
1578  int K  = cstn[3];
1579  string s = "The Singularity "+Show(jet(f, K));
1580  string tp="";
1581//  return(printresult(47, f, tp, cstn, -1));
1582
1583  s = s +" has 4-jet equal to zero. (F47), mu="+string(Mu);
1584
1585  s; // +"  ("+SG_Typ+")";
1586  s = "No further classification available.";
1587  s;
1588  return(Show(f), tp, corank);
1589}
1590
1591///////////////////////////////////////////////////////////////////////////////
1592static proc Funktion91 (poly f, list cstn, int k)
1593{
1594  string tp  = "U*[k,0]";
1595  return(printresult(91, f, tp, cstn, -1));
1596}
1597
1598///////////////////////////////////////////////////////////////////////////////
1599static proc Funktion92 (poly f, list cstn, int k)
1600{
1601  string tp  = "UP[k]";
1602  return(printresult(92, f, tp, cstn, -1));
1603}
1604
1605///////////////////////////////////////////////////////////////////////////////
1606static proc Funktion93 (poly f, list cstn, int k)
1607{
1608  string tp  = "UQ[k]";
1609  return(printresult(93, f, tp, cstn, -1));
1610}
1611
1612///////////////////////////////////////////////////////////////////////////////
1613static proc Funktion94 (poly f, list cstn, int k)
1614{
1615  string tp  = "UR[k]";
1616  return(printresult(94, f, tp, cstn, -1));
1617}
1618
1619///////////////////////////////////////////////////////////////////////////////
1620static proc Funktion95 (poly f, list cstn, int k)
1621{
1622  string tp  = "US[k]";
1623  return(printresult(95, f, tp, cstn, -1));
1624}
1625
1626///////////////////////////////////////////////////////////////////////////////
1627static proc Funktion96 (poly f, list cstn, int k)
1628{
1629  string tp  = "UT[k]";
1630  return(printresult(96, f, tp, cstn, -1));
1631}
1632
1633///////////////////////////////////////////////////////////////////////////////
1634proc morsesplit(poly f)
1635"
1636USAGE:    morsesplit(f);        f=poly
1637RETURN:   Normal form of f in M^3 after application of the splitting lemma
1638COMPUTE:  apply the splitting lemma (generalized Morse lemma) to f
1639EXAMPLE:  example morsesplit; shows an example"
1640{
1641//---------------------------- initialisation ---------------------------------
1642  poly f_out;
1643  int  n, K, Mu, corank;
1644  list v;
1645
1646  if(defined(@ringdisplay) != 0 ) { kill @ringdisplay; }
1647  string @ringdisplay = "setring "+nameof(basering);
1648  export @ringdisplay;
1649
1650  def ring_ext=basering;
1651
1652  n = nvars(basering);
1653
1654  // if trace/debug mode not set, do it!
1655  init_debug();
1656  K, Mu, corank = basicinvariants(f);
1657  ring ring_top=char(basering),(x(1..n)),(c,ds);
1658
1659  map Conv=ring_ext,maxideal(1);
1660  setring ring_top;
1661  v = Morse(jet(Conv(f),K), K, corank, 0);
1662  poly f_out = v[1];
1663  setring ring_ext;
1664  map ConvUp = ring_top, maxideal(1);
1665  return(ConvUp(f_out));
1666}
1667example
1668{ "EXAMPLE"; echo=2;
1669   ring r=0,(x,y,z),ds;
1670   export r;
1671   init_debug(1);
1672   poly f=(x2+3y-2z)^2+xyz-(x-y3+x2*z3)^3;
1673   poly g=morsesplit(f);
1674   g;
1675}
1676
1677///////////////////////////////////////////////////////////////////////////////
1678static proc Coeffs (list #)
1679{
1680  matrix m=matrix(coeffs(#[1],#[2]), deg(#[1])+1, 1);
1681  return(m);
1682}
1683
1684///////////////////////////////////////////////////////////////////////////////
1685static proc Morse(poly f, int K, int corank, int ShowPhi)
1686{
1687//---------------------------- initialisation ---------------------------------
1688  poly   fc, f2, a, P, Beta, fi;
1689  ideal  Jfx, B;
1690  int    n, i, j, k, Rang, Done;
1691  matrix Mat;
1692  map    Id, Psi, Phi, PhiG;
1693  intvec Abb, RFlg;
1694  list   v;
1695
1696  fi = f;
1697  n = nvars(basering);
1698  init_debug();
1699
1700  def ring_top=basering;
1701
1702  debug_log(3, "Split the polynomial below using determinacy: ", string(K));
1703  debug_log(3, Show(fi));
1704
1705  for( j=1; j<=n ; j++) { Abb[j] = 0; }
1706
1707  RFlg = GetRf(fi, n);
1708  debug_log(2, "Permutations:", RFlg );
1709  PhiG=ring_top,maxideal(1);
1710
1711//----------------- find quadratic term, if there is only one -----------------
1712  B = maxideal(1);
1713  if(corank == (n-1))
1714  {
1715    Done = 0;
1716    f2   = jet(fi, 2);
1717    j    = 1;
1718    Jfx  = f2, diff(f2, x(j));
1719    while(j<=n && (diff(f2, x(j))==0))
1720    {
1721      j++;
1722      Jfx = f2, diff(f2, x(j));
1723    }
1724    Mat  = matrix(syz(Jfx));
1725    Beta = 2*Mat[2,1]/Mat[1,1];
1726    for( j=1; j<=n ; j++)
1727    {
1728      f2 = Coeff(Beta, x(RFlg[j]), x(RFlg[j]));
1729      if(f2!=0)
1730      {
1731        k = RFlg[j];
1732        break;
1733      }
1734    }
1735    for( j=1; j<=n ; j=j+1)
1736    {
1737      f2 = Coeff(Beta, x(j), x(j));
1738      if(j == k) { B[rvar(x(j))] = (2*f2*x(j)-Beta) / number(f2); }
1739    }
1740    Phi  =ring_top,B;
1741    fi   = Phi(fi);
1742    PhiG = Phi(PhiG);
1743  }
1744  if( ShowPhi > 1) { PhiG; }
1745
1746//------------------------ compute splitting lemma -----------------------------
1747  fc = fi;
1748  i  = 1;              // Index fuer Variablen wird bearbeitet
1749  while( i <= n)
1750  {
1751    Phi=ring_top,maxideal(1);
1752    debug_log(6, "Pruefe Variable x(" +string(RFlg[i]) + ")");
1753    debug_log(6, "--------------------");
1754    j  = i + 1;        // setze j fuer evtle Verschiebung
1755    f2 = jet(fc,2);
1756    debug_log(6, "Rechne 2-Jet =" , string(f2));
1757    if( (f2 - subst(f2, x(RFlg[i]), 0)) == 0 ) { Abb[RFlg[i]] = 1; }
1758    if( (f2 - subst(f2, x(RFlg[i]), 0)) != 0 )
1759    {
1760      while( (j<=n) || (i==n) )
1761      {
1762        debug_log(6, "Pruefe 2-Jet mit Wert : " + string(jet(fc,2)));
1763        a = Coeff(jet(fc,2), x(RFlg[i]), x(RFlg[i])^2);
1764        debug_log(6,"Koeffizient von x(" + string(RFlg[i]) + ")^2 ist:", a);
1765        if( (a != 0) || (i==n) )
1766        {
1767          debug_log(6, "BREAK!!!!!!!!!!!!!!");
1768          break;
1769        }
1770        debug_log(6,"Verschiebe evtl Variable x(",string(RFlg[j]),") um x(",
1771                     string(RFlg[i]), ")");
1772        B = maxideal(1);
1773        for( k=1; k<=n ; k=k+1)
1774        {
1775          if(k==RFlg[j]) { B[rvar(x(k))] = x(k) + x(RFlg[i]); }
1776        }
1777        Phi = ring_top,B;
1778        fc  = Phi(fi);
1779        j++;
1780      }               // Ende while( (j<=n) || (i==n) )
1781
1782      debug_log(6, "Moegliche Verschiebung fertig!");
1783      PhiG = Phi(PhiG);
1784      if( ShowPhi > 1) { "NachVersch.:"; Phi; }
1785
1786      if( (j<=n) || (i==n))
1787      {
1788        P = Coeff(fc, x(RFlg[i]), x(RFlg[i]));
1789        debug_log(6, "Koeffizient von x("+string(RFlg[i])+") ist: ",
1790                      string(P));
1791        if(P != 0)
1792        {
1793          debug_log(6, "1 Koeffizient von x("+string(RFlg[i])+") ist: ",
1794                       string(P));
1795          debug_log(6, "a=" + string(a));
1796          P = P / number (2 * a);
1797          debug_log(6, "2 Koeffizient von x("+string(RFlg[i])+") ist: ",
1798                       string(P));
1799          B = maxideal(1);
1800          for( k=1; k<=n ; k=k+1) {if(k==RFlg[i]) {B[rvar(x(k))]=x(k)-P;}}
1801          Phi =ring_top,B;
1802          debug_log(6, "Quadratische-Ergaenzung durch:", Phi);
1803          fi   = Phi(fc);
1804          PhiG = Phi(PhiG);
1805          fc   = jet(fi,K);
1806          P    = Coeff(fc, x(RFlg[i]), x(RFlg[i]));
1807          if( P != 0)
1808          {
1809            fi = fc;
1810            continue;
1811          }
1812        }     // Ende if(P != 0)
1813              // Fertig mit Quadratischer-Ergaenzung
1814      }               // Ende if( (j<=n) || (i==n))
1815    }                 // Ende if( (f2 - subst(f2, x(RFlg[i]), 0)) != 0 )
1816
1817    fi = fc;
1818    i++;
1819    debug_log(6, "++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
1820  }
1821  debug_log(6, "Ende  ---------------------------------------------------");
1822
1823//--------------------------- collect results ---------------------------------
1824  if( ShowPhi > 0 )
1825  {
1826    "Abbildung innerhalb des Morse-Lemmas:";
1827    PhiG;
1828    "Vergleich:";
1829    "PhiG(f)= " + Show(jet(PhiG(f), K));
1830    "fi     = " + Show(fi);
1831  }
1832
1833  Rang = 0;
1834  B    = maxideal(1);
1835  for( i=1; i<=n ; i++) { if(Abb[i] != 1) { Rang ++; B[rvar(x(i))] = 0; } }
1836  Phi  = ring_top,B;
1837  PhiG = Phi(PhiG);
1838  fi   = Phi(fi);
1839  v    = fi, PhiG;
1840  debug_log(2, "rank determined with Morse rg=", Rang);
1841  debug_log(1, "Residual singularity f=",Show(fi));
1842  return(v);
1843}
1844
1845///////////////////////////////////////////////////////////////////////////////
1846static proc Coeff(poly f, list #)
1847{
1848//---------------------------- initialisation ---------------------------------
1849  poly   a, term;
1850  int    n, i;
1851  matrix K;
1852
1853  n     = nvars(basering);
1854  i     = 1;
1855  term  = #[2];
1856  K     = coef(f, #[1]);
1857
1858  while( (i<=ncols(K)) && (K[1,i] != term) )
1859  { i++;
1860    if(i>ncols(K)) break;
1861  }
1862  if(i<=ncols(K)) { a = K[2,i]; }
1863  if(i>ncols(K)) { a = 0; }
1864
1865  return(a);
1866}
1867
1868///////////////////////////////////////////////////////////////////////////////
1869static proc ReOrder(poly f)
1870{
1871//---------------------------- initialisation ---------------------------------
1872  poly  result;
1873  ideal B = maxideal(1);
1874  int   i, n, Ctn, Ctv;
1875  map   conv;
1876
1877  n = nvars(basering);
1878  Ctv = 1;              // Zahl der Vorhandenen Variablen
1879  Ctn = n;              // Zahl der Nicht-Vorhandenen Variablen
1880  def ring_top=basering;
1881
1882  for( i=1; i<=n; i=i+1)
1883  { result = subst(f,x(i), 0) - f;
1884    if( result != 0 ) { B[rvar(x(i))] = x(Ctv); Ctv++; }
1885    else { B[rvar(x(i))] = x(Ctn); Ctn--; }
1886  }
1887
1888  conv = ring_top,B;
1889  return(conv);
1890}
1891
1892///////////////////////////////////////////////////////////////////////////////
1893proc quickclass(poly f)
1894"
1895USAGE:    quickclass(f);         f=poly
1896RETURN:   Normal form of f in Arnold's list
1897REMARK:   try to determine the normal form of f by invariants, mainly by
1898          computing the Hilbert function of the Milnor algebra,
1899          no coordinate change is needed (see also proc 'milnorcode').
1900EXAMPLE:  example quickclass; shows an example"
1901{
1902//---------------------------- initialisation ---------------------------------
1903  string Typ;
1904  int    cnt, K, Mu, corank;
1905  list   v;
1906  def ring_top=basering;
1907  // check basic condition on the basering.
1908  if(checkring()) { return(f); }
1909  if( f==0 )
1910  {
1911    "Normal form : 0";
1912    return(f);
1913  }
1914  if( jet(f,0)!=0 )
1915  {
1916    "Normal form : 1";
1917    return(f);
1918  }
1919  K, Mu, corank = basicinvariants(f);
1920  if(Mu<0)
1921  {
1922    debug_log(0, "The Milnor number of the function is infinite.");
1923    return(f);
1924  }
1925
1926  // Do the classification of f
1927  // typ: list of types matching the milnorcode
1928  // cnt: number of matches found
1929  v = HKclass(milnorcode(f));
1930  Typ, cnt = v[1..2];
1931  "Singularity R-equivalent to :",Typ;
1932  if(cnt==0)
1933  {
1934    "Hilbert polynomial not recognised. Milnor code = ", milnorcode(f);
1935    return();
1936  }
1937  if(cnt==1)
1938  {
1939    debug_log(1,"Getting normal form from database.");
1940    "normal form :",A_L(Typ);
1941    return(A_L(Typ));
1942  }
1943  // Hier nun der Fall cnt>1
1944  "Hilbert-Code of Jf^2";
1945  "We have ", cnt, "cases to test";
1946  Cubic(f);
1947  return(v);
1948}
1949example
1950{ "EXAMPLE:"; echo=2;
1951   ring r=0,(x,y,z),ds;
1952   poly f=(x2+3y-2z)^2+xyz-(x-y3+x2*z3)^3;
1953   quickclass(f);
1954}
1955
1956///////////////////////////////////////////////////////////////////////////////
1957proc milnorcode (poly f, list #)
1958"USAGE:    milnorcode(f[,e]); f=poly, e=int
1959RETURN:   intvec, coding the Hilbert function of the e-th Milnor algebra
1960          of f, i.e. of basering/(jacob(f)^e) (default e=1), according
1961          to proc Hcode
1962EXAMPLE:  example milnorcode; shows an example"
1963{
1964  int  e=1;
1965  if(size(#)==1) { e=#[1]; }
1966  ideal jf=std(jacob(f)^e);
1967  intvec v=intvec(hilb(jf,2));
1968
1969  return(Hcode(v));
1970}
1971example
1972{ "EXAMPLE:"; echo=2;
1973  ring r=0,(x,y,z),ds;
1974  poly f=x2y+y3+z2;
1975  milnorcode(f);
1976  milnorcode(f,2);  // a big second argument may result in memory overflow
1977}
1978
1979///////////////////////////////////////////////////////////////////////////////
1980proc Hcode (intvec v)
1981"USAGE:    Hcode(v); v=intvec
1982RETURN:   intvec, coding v according to the number of successive
1983          repetitions of an entry
1984EXAMPLE:  example Hcode; shows an example."
1985{
1986  int    col, len, i, cur, cnt, maxcoef, nlen;
1987  intvec hil1, hil2;
1988
1989  col      = 1;
1990  len      = size(v);
1991  v[len+1] = 0;
1992
1993  init_debug();
1994  debug_log(1, "Hcode:", v );
1995
1996  for(i=1; i<=len; i++) { if( v[i] > maxcoef) { maxcoef = v[i]; } }
1997
1998  nlen       = 2*maxcoef - 1;
1999  hil1[nlen] = 0;
2000  hil2[nlen] = 0;
2001
2002  for(i=1; i<=nlen; i++)
2003  { if( i > maxcoef) { hil2[i] = 2*maxcoef-i; }
2004    else { hil2[i] = i; }
2005  }
2006
2007  for(i=1; i<=nlen; i++)
2008  { cnt=0;
2009    while( (col<=len) && (v[col] == hil2[i]) )
2010    { cnt++; col++; }
2011    hil1[i] = cnt;
2012  }
2013  return(hil1);
2014}
2015example
2016{ "EXAMPLE:"; echo=2;
2017  intvec v1 = 1,3,5,5,2;
2018  Hcode(v1);
2019  intvec v2 = 1,2,3,4,4,4,4,4,4,4,3,2,1;
2020  Hcode(v2);
2021}
2022
2023///////////////////////////////////////////////////////////////////////////////
2024static proc Cubic (poly f)
2025{
2026//---------------------------- initialisation ---------------------------------
2027  poly  f3;
2028  ideal Jf, Jf1, Jf2;
2029  int   Dim, Mult;
2030
2031  f3 = jet(f, 3);
2032  if( jet(f,2) != 0) { return("2-jet non zero"); }
2033  if( f3 == 0 ) { return("null form"); }
2034
2035  Jf1  = jacob(f3);
2036  Jf   = std(Jf1);
2037  Dim  = dim(Jf);
2038  Mult = mult(Jf);
2039
2040  if(Dim == 0) { return("P[8]:smooth cubic"); } // x3 + y3 + z3 + axyz
2041  if(Dim == 1)
2042  {
2043    if(Mult == 2)
2044    {
2045      Jf2  = wedge(jacob(Jf1),3-Dim), Jf1;
2046      Jf2  = std(Jf2);
2047      Dim  = dim(Jf2);
2048      if (Dim == 0) { return("R:conic + line"); }       // x3 + xyz
2049      if (Dim == 1) { return("Q:cuspidal cubic"); }  // x3 + yz2
2050    }
2051    if(Mult == 3)
2052    {
2053      Jf2 = wedge(jacob(Jf1),3-Dim), Jf1;
2054      Jf2 = std(Jf2);
2055      Dim = dim(Jf2);
2056      if(Dim == 0) { return("T:three lines"); } // xyz
2057      if(Dim == 1) { return("S:conic + tangent"); }     // x2z + yz2
2058    }
2059    if(Mult == 4) { return("U:three concurrent lines"); }       // x3 + xz2
2060  }
2061  if(Dim == 2)
2062  {
2063    if(Mult == 1) { return("V:doubleline + line"); }    // x2y
2064    if(Mult == 2) { return("V': triple line"); }       // x3
2065  }
2066  if(Dim == 3) { return("P[9]:nodal cubic"); }  // x3 + y3 + xyz
2067
2068  return("");
2069}
2070
2071///////////////////////////////////////////////////////////////////////////////
2072static proc parity  (int e)
2073"USAGE:    parity()"
2074{
2075  int r = e div 2;
2076  if( 2*r == e ) { return(0); }
2077  return(1);
2078}
2079
2080///////////////////////////////////////////////////////////////////////////////
2081static proc HKclass (intvec sg)
2082{
2083//---------------------------- initialisation ---------------------------------
2084  int    cnt = 0;
2085  string SG_Typ = "";
2086  list   v;
2087
2088  // if trace/debug mode not set, do it!
2089  init_debug();
2090  debug_log(1, "Milnor code : ", sg );
2091  if(size(sg) == 1) { v ="A["+string(sg[1])+"]", 1; return(v); }
2092  if(size(sg) == 3) { return(HKclass3(sg, SG_Typ, cnt)); }
2093  if(size(sg) == 5) { return(HKclass5(sg, SG_Typ, cnt)); }
2094  if(size(sg) == 7) { return(HKclass7(sg, SG_Typ, cnt)); }
2095  debug_log(1, "No solution found." );
2096  v = "", 0;
2097  return(v);
2098}
2099
2100///////////////////////////////////////////////////////////////////////////////
2101static proc HKclass3 (intvec sg, string SG_Typ, int cnt)
2102{
2103  list v;
2104
2105  if(sg[1] == 1) { v = HKclass3_teil_1(sg, SG_Typ, cnt); }
2106  debug_log(6, "HKclass3: ", v[1], " cnt=", v[2]);
2107  return(v);
2108}
2109
2110///////////////////////////////////////////////////////////////////////////////
2111static proc HKclass3_teil_1 (intvec sg, string SG_Typ, int cnt)
2112{
2113  int  k, r, s;
2114  list v;
2115
2116  debug_log(2, "entering HKclass3_teil_1", sg);
2117  if(sg[2]==1) { SG_Typ=SG_Typ+" D[k]=D["+string(sg[3]+3)+"]";cnt++;} // D[k]
2118  if(sg[2]>=1)
2119  {
2120    if( parity(sg[2]))
2121    { // sg[2] ist ungerade
2122      if(sg[2]<=sg[3])
2123      {
2124        k = (sg[2]+1) div 2;
2125        if(k>1)
2126        {
2127          cnt++;
2128          SG_Typ=SG_Typ+" J[k,r]=J["+string(k)+","+string(sg[3]+1-2*k)+"]";
2129        }// J[k,r]
2130      }
2131      if(sg[2]==sg[3]+2)
2132      {                              // E[6k+2]
2133        k = (sg[2]-1) div 2;
2134        if(k>0) {cnt++; SG_Typ=SG_Typ+" E[6k+2]=E[" + string(6*k+2) + "]"; }
2135      }
2136    }
2137    else
2138    {              // sg[2] ist gerade
2139      if( sg[2] == sg[3]+1)
2140      {                           // E[6k]
2141        k = sg[2] div 2; cnt++; SG_Typ=SG_Typ + " E[6k]=E[" + string(6*k) + "]";
2142      }
2143      if( sg[2] == sg[3])
2144      {                             // E[6k+1]
2145        k=sg[2] div 2; cnt++; SG_Typ=SG_Typ+" E[6k+1]=E["+string(6*k+1)+"]"; }
2146    }
2147  }
2148
2149  debug_log(2, "finishing HKclass3_teil_1");
2150  debug_log(6, "HKclass3: ", SG_Typ, " cnt=", cnt);
2151  v = SG_Typ, cnt;
2152  return(v);
2153}
2154
2155///////////////////////////////////////////////////////////////////////////////
2156static proc HKclass5 (intvec sg, string SG_Typ, int cnt)
2157{
2158  list v;
2159
2160  if(sg[1] == 1 && sg[2] == 1) { v = HKclass5_teil_1(sg, SG_Typ,cnt); }
2161  if(sg[1] == 1 && sg[2] == 0) { v = HKclass5_teil_2(sg, SG_Typ,cnt); }
2162  debug_log(6, "HKclass5: ", v[1], " cnt=", v[2]);
2163  return(v);
2164}
2165
2166///////////////////////////////////////////////////////////////////////////////
2167static proc HKclass5_teil_1 (intvec sg, string SG_Typ, int cnt)
2168{
2169  int  k, r, s;
2170  list v;
2171
2172  debug_log(2, "entering HKclass5_teil_1", sg);
2173  if(parity(sg[3]))
2174  {  // Dritte Stelle soll ungerade sein
2175    k = (sg[3]+1) div 2;
2176    if(sg[3] > sg[4])
2177    {
2178      k--;
2179      if( (sg[4]==sg[5]) && (sg[3] == sg[4]+1) && k>0 )
2180      { // W[12k+6]
2181        SG_Typ = SG_Typ + " W[12k+6]=W["+string(12*k+6)+"]"; cnt++;
2182      }
2183      if( (sg[3]==sg[5]) && (sg[3] == sg[4]+2) && k>0 )
2184      { // W[12k+5]
2185        SG_Typ = SG_Typ + " W[12k+5]=W["+string(12*k+5)+"]"; cnt++;
2186      }
2187    }
2188    else
2189    {  // sg[3] <= sg[4]
2190      if( (sg[3]==sg[4]) && (sg[5] >= sg[3]) )
2191      {
2192        r = sg[5] - sg[4];
2193        SG_Typ=SG_Typ +" X[k,r]=X["+string(k)+","+string(r)+"]"; cnt++;
2194      }
2195      if( (sg[3]==1) && (sg[4]==3) && (sg[5]>=sg[4]))
2196      {    // Z[1,r]
2197        r = sg[5] - sg[4];
2198        SG_Typ = SG_Typ + " Z[1,r]=Z[1,"+string(r)+"]"; cnt++;
2199      }
2200
2201      if( sg[4] == sg[5])
2202      {
2203        if(parity(sg[4]))
2204        {                                  // Z[k,r,0]
2205          r = (sg[4] - sg[3]) div 2;
2206          if( r>0 )
2207          { cnt++;
2208            SG_Typ = SG_Typ + " Z[k,r,0]=Z["+string(k)+","+string(r)+",0]";
2209          }
2210        }
2211        else
2212        {                                                // Z[k,12k+6r]
2213          r = (sg[4] - 2*k) div 2; cnt++;
2214          SG_Typ = SG_Typ+" Z[k,12k+6r]=Z["+string(k)+","+string(12*k+6*r)+"]";
2215        }
2216      }
2217
2218      if( parity(sg[4]) )
2219      {  // 4. Stelle ist ungerade
2220        if(sg[4] == sg[5]+2)
2221        {                              // Z[k,12k+6r+1]
2222          r = (sg[4]-2*k-1) div 2; cnt++;
2223          SG_Typ=SG_Typ+" Z[k,12k+6r+1]=Z["+string(k)+",";
2224          SG_Typ=SG_Typ+string(12*k+6*r+1)+"]";
2225       }
2226       if( (sg[5]>sg[4]) && (sg[4]>sg[3]) )
2227       {           // Z[k,r,s]
2228          r = (sg[4] - sg[3]) div 2; cnt++;
2229          s = sg[5] - sg[4];
2230          SG_Typ = SG_Typ + " Z[k,r,s]=";
2231          SG_Typ = SG_Typ + "Z["+string(k)+","+string(r)+","+string(s)+"]";
2232        }
2233      }
2234      else
2235      {  // 4. Stelle ist gerade
2236        if( sg[4] == sg[5]+1)
2237        {                             // Z[k,12k+6r-1]
2238          r = (sg[4] - 2*k) div 2; cnt++;
2239          SG_Typ=SG_Typ+" Z[k,12k+6r-1]=Z["+string(k)+",";
2240          SG_Typ=SG_Typ+string(12*k+6*r-1)+"]";
2241        }
2242      }
2243
2244      if(sg[4]>sg[3])
2245      {                                     // Y[k,r,s]
2246        r = sg[4] - sg[3];
2247        s = sg[5] - sg[3] + r;
2248        if( s<0 ) { s = -s; }
2249        SG_Typ = SG_Typ + " Y[k,r,s]="; cnt++;
2250        SG_Typ = SG_Typ + "Y["+string(k)+","+string(r)+","+string(s)+"]";
2251      }
2252    }
2253  }
2254  else
2255  {  // Dritte Stelle soll gerade sein
2256    k = sg[3] div 2;
2257    // sortiere verschiedene W's
2258    if(k>0)
2259    {
2260      if( (sg[4]==2*k-1) && (sg[4]==sg[5]) )
2261      {  // W[12k]
2262        SG_Typ = SG_Typ + " W[12k]=W["+string(12*k)+"]"; cnt++;
2263      }
2264      if( (sg[4]==2*k-1) && (sg[3]==sg[5]) )
2265      {  // W[12k+1]
2266        SG_Typ = SG_Typ + " W[12k+1]=W["+string(12*k+1)+"]"; cnt++;
2267      }
2268      if( (sg[4]==2*k) && (sg[5]>=sg[4]) )
2269      {    // W[k,r]
2270        r = sg[5] - sg[4];
2271        SG_Typ=SG_Typ+" W[k,r]=W["+string(k)+","+string(r)+"]"; cnt++;
2272      }
2273      if( (sg[5]==2*k-1) && (sg[4]>sg[3]) )
2274      {  // W#[k,2r-1]
2275        r = sg[4] - sg[3]; cnt++;
2276        SG_Typ = SG_Typ + " W#[k,2r-1]=W["+string(k)+","+string(2*r-1)+"]";
2277      }
2278      if( (sg[5]==2*k) && (sg[4]>sg[3]) )
2279      {  // W#[k,2r]
2280        r = sg[4] - sg[3]; cnt++;
2281        SG_Typ = SG_Typ + " W#[k,2r]=W["+string(k)+","+string(2*r)+"]";
2282      }
2283    }   // ENDIF k>0
2284  }
2285  debug_log(2, "finishing HKclass5_teil_1");
2286  debug_log(6, "HKclass5_teil_1: ", SG_Typ, " cnt=", cnt);
2287  v = SG_Typ, cnt;
2288  return(v);
2289}
2290
2291///////////////////////////////////////////////////////////////////////////////
2292static proc HKclass5_teil_2 (intvec sg, string SG_Typ, int cnt)
2293{
2294  int k, r, s;
2295  list v;
2296
2297  debug_log(2, "entering HKclass5_teil_2", sg);
2298  // finde T[p,q,r]
2299  k = sg[3] + 1;
2300  r = sg[4] + k;
2301  s = sg[5] + r - 1;
2302  if(k>2 && r>2 && s>2)
2303  {                               // T[k,r,s]
2304    cnt++;
2305    SG_Typ = SG_Typ + " T[k,r,s]=T["+string(k)+","+string(r)+","+string(s)+"]";
2306  }
2307
2308  // finde weitere Moeglicjkeiten.
2309  if(sg[3]==2)
2310  {  // Q[...]
2311    if(parity(sg[4]))
2312    { // 4. Stelle ist ungerade.
2313      if(sg[4]==sg[5])
2314      {                                // Q[6k+4]
2315        k=(sg[4]+1) div 2; cnt++; SG_Typ=SG_Typ+" Q[6k+4]=Q["+string(6*k+4)+"]";
2316      }
2317      if(sg[4]+1==sg[5])
2318      {                      // Q[6k+5]
2319        k=sg[5] div 2; cnt++; SG_Typ=SG_Typ+" Q[6k+5]=Q["+string(6*k+5)+"]";
2320      }
2321    }
2322    else
2323    { // 4. Stelle ist gerade.
2324      if(sg[4]==sg[5]+1)
2325      {                      // Q[6k+6]
2326        k=sg[4] div 2; cnt++; SG_Typ=SG_Typ+" Q[6k+6]=Q["+string(6*k+6)+"]";
2327      }
2328      if(sg[4]<sg[5])
2329      {                 // Q[k,r]
2330        k = (sg[4]+2) div 2;
2331        if(k>=2)
2332        {
2333          r=sg[5]+1-2*k; cnt++;
2334          SG_Typ=SG_Typ+" Q[k,r]=Q["+string(k)+","+string(r)+"]";
2335        }
2336      }
2337    }
2338  }
2339  else
2340  {           // S[...]
2341    if(parity(sg[3]))
2342    {  // 3. Stelle ist ungerade.
2343      k = (sg[3]-1) div 2;
2344      if(sg[3]==sg[4]+3 && sg[3]==sg[5]+2)
2345      {    // S[12k-1]
2346        cnt++; SG_Typ = SG_Typ + " S[12k-1]=S["+string(12*k-1)+"]";
2347      }
2348      if(sg[3]==sg[4]+3 && sg[3]==sg[5]+1)
2349      {    // s[12k]
2350        cnt++; SG_Typ = SG_Typ + " S[12k]=S["+string(12*k)+"]";
2351      }
2352      if(sg[3]==sg[4]+2 && sg[5]>=sg[4]+1)
2353      {    // S[k,r]
2354        r = sg[5] - 2*k; cnt++;
2355        SG_Typ = SG_Typ + " S[k,r]=S["+string(k)+","+string(r)+"]";
2356      }
2357      if(sg[3]==sg[5]+2 && sg[4]>=sg[5])
2358      {              // S#[k,2r-1]
2359        r = sg[4] - 2*k + 1; cnt++;
2360        SG_Typ = SG_Typ + " S#[k,2r-1]=S#["+string(k)+","+string(2*r-1)+"]";
2361      }
2362      if(sg[3]==sg[5]+1 && sg[4]>=sg[5])
2363      {              // S#[k,2r]
2364        r = sg[4] - 2*k + 1; cnt++;
2365        SG_Typ = SG_Typ + " S#[k,2r]=S#["+string(k)+","+string(2*r)+"]";
2366      }
2367    }
2368    else
2369    { // 3. Stelle ist gerade.
2370      if(sg[3]==sg[5]+1 && sg[5]==sg[4]+3)
2371      {    // S[12k+4]
2372        k = (sg[3]-2) div 2; cnt++;
2373        SG_Typ = SG_Typ + " S[12k+4]=S["+string(12*k+4)+"]";
2374      }
2375      if(sg[3]==sg[5]+2 && sg[5]==sg[4]+1)
2376      {    // S[12k+5]
2377        k = (sg[3]-2) div 2; cnt++;
2378        SG_Typ = SG_Typ + " S[12k+5]=S["+string(12*k+5)+"]";
2379      }
2380    }
2381  }
2382  debug_log(2, "finishing HKclass5_teil_2");
2383  debug_log(6, "HKclass5_teil_2: ", SG_Typ, " cnt=", cnt);
2384  v = SG_Typ, cnt;
2385  return(v);
2386}
2387
2388///////////////////////////////////////////////////////////////////////////////
2389static proc HKclass7 (intvec sg, string SG_Typ, int cnt)
2390{
2391  list v;
2392
2393  if(sg[1]==1 && sg[2]==0 && sg[3]==1)
2394  {
2395      v=HKclass7_teil_1(sg, SG_Typ, cnt);
2396  }
2397  else
2398  {
2399      v[1]="not in list";
2400      v[2]=0;
2401  }
2402  debug_log(6, "HKclass7: ", v[1], " cnt=", v[2]);
2403  return(v);
2404}
2405
2406///////////////////////////////////////////////////////////////////////////////
2407static proc HKclass7_teil_1 (intvec sg, string SG_Typ, int cnt)
2408{
2409  int k, r, s;
2410  list v;
2411
2412  debug_log(2, "entering HKclass7_teil_1", sg);
2413  if(sg[4] == 2)
2414  {                                      // V[...]
2415    if(sg[5] == 0 && sg[6] == 1 && sg[7]>0)
2416    {   // V[1,r]
2417      r = sg[7] - 1; cnt++; SG_Typ = SG_Typ + " V[1,r]=V[1,"+string(r)+"]";
2418    }
2419    if(sg[5] == 1 && sg[7] == 1)
2420    {                      // V#[1,2r-1]
2421      r=sg[6]+1; cnt++; SG_Typ=SG_Typ+" V#[1,2r-1]=V#[1,"+string(2*r-1)+"]";
2422    }
2423    if(sg[5] == 1 && sg[7] == 2)
2424    {                      // V#[1,2r]
2425      r=sg[6]+1; cnt++; SG_Typ=SG_Typ+" V#[1,2r]=V#[1,"+string(2*r)+"]";
2426    }
2427  }
2428  //            Moegliche U[...]'s
2429  k = sg[4];
2430  if(sg[5]==2*k-1 && sg[6]==0 && sg[7]==sg[5])
2431  {        // U[12k]
2432    cnt++;SG_Typ = SG_Typ + " U[12k]=U["+string(12*k)+"]";
2433  }
2434  if(sg[5]==2*k && sg[6]==0 && sg[7]==sg[5])
2435  {  // U[12k+4]
2436    cnt++;SG_Typ = SG_Typ + " U[12k+4]=U["+string(12*k+4)+"]";
2437  }
2438  if(sg[5]==2*k-1 && sg[6]>0 && sg[7]==sg[5])
2439  { // U[k,2r-1]
2440    r=sg[6]-1; cnt++;
2441    SG_Typ=SG_Typ+" U[k,2r-1]=U["+string(k)+","+string(2*r-1)+"]";
2442  }
2443  if(sg[5]==2*k-1 && sg[6]>0 && sg[7]==2*k)
2444  {   // U[k,2r]
2445    r = sg[6]; cnt++;
2446    SG_Typ = SG_Typ + " U[k,2r]=U["+string(k)+","+string(2*r)+"]";
2447  }
2448  debug_log(2, "finishing HKclass7_teil_1");
2449  debug_log(6, "HKclass7_teil_1: ", SG_Typ, " cnt=", cnt);
2450  v = SG_Typ, cnt;
2451  return(v);
2452}
2453
2454///////////////////////////////////////////////////////////////////////////////
2455proc singularity(string typ, list #)
2456"USAGE:    singularity(t, l); t=string (name of singularity),
2457          l=list of integers/polynomials (indices/parameters of singularity)
2458COMPUTE:  get the singularity named by type t from the database.
2459          list l is as follows: @*
2460          l= k [,r [,s [,a [,b [,c [,d]..]: k,r,s=int   a,b,c,d=poly. @*
2461          The name of the dbm-databasefile is: NFlist.[dir,pag].
2462          The file is found in the current directory. If it does not
2463          exist, please run the script MakeDBM first.
2464RETURN:   Normal form and corank of the singularity named by type t and its
2465          index (indices) l.
2466EXAMPLE:  example singularity; shows an example"
2467{
2468  poly a1, a2, a3, a4, f;
2469  int k, r, s;
2470  int len = size(#);
2471  list v, ret;
2472
2473  classify_init();
2474  ret = 0, 0;
2475  k = #[1];
2476  if(len>=2) { r = #[2]; }
2477  else { r = 0; }
2478  if(len>=3) { s = #[3]; }
2479  else { s = 0; }
2480  if( k<0 || r<0 || s<0)
2481  {
2482    "Initial condition failed: k>=0; r>=0; s>=0";
2483    "k="+string(k)+" r="+string(r)+"   s="+string(s);
2484    return(ret);
2485  }
2486  int crk;
2487
2488  init_debug();
2489  def ring_top=basering;
2490
2491  if(len>=4) { a1 = #[4]; }
2492  else { a1=1; }
2493  if(len>=5) { a2 = #[5]; }
2494  else { a2=1; }
2495  if(len>=6) { a3 = #[6]; }
2496  else { a3=1; }
2497  if(len>=7) { a4 = #[7]; }
2498  else { a4=1; }
2499
2500  debug_log(4, "Values: len=", string(len), " k=", string(k), " r=",
2501        string(r));
2502  if(defined(RingNF) != 0 ) { kill RingNF; }
2503  ring RingNF=char(basering),(x,y,z),(c,ds);
2504  poly f;
2505  map Conv=ring_top,maxideal(1);
2506  v = Singularitaet(typ, k, r, s, Conv(a1), Conv(a2), Conv(a4), Conv(a4));
2507  f, crk = v[1..2];
2508  debug_log(2, "Info=", f );
2509  setring ring_top;
2510  if(defined(Phi) != 0 ) { kill Phi; }
2511  map Phi=RingNF,maxideal(1);
2512
2513  ret = Phi(f), crk;
2514  return(ret);
2515}
2516example
2517{ "EXAMPLE"; echo=2;
2518  ring r=0,(x,y,z),(c,ds);
2519  init_debug(0);
2520  singularity("E[6k]",6);
2521  singularity("T[k,r,s]", 3, 7, 5);
2522  poly f=y;
2523  singularity("J[k,r]", 4, 0, 0, f);
2524}
2525
2526///////////////////////////////////////////////////////////////////////////////
2527static proc Singularitaet (string typ,int k,int r,int s,poly a,poly b,poly c,poly d)
2528{
2529  list   v;
2530  string DBMPATH=system("getenv","DBMPATH");
2531  string DatabasePath, Database, S, Text, Tp;
2532  poly   f, f1;
2533  int    crk, Mu, ret;
2534  intvec MlnCd;
2535
2536  if( DBMPATH != "" ) { DatabasePath = DBMPATH+"/NFlist"; }
2537  else { DatabasePath = "NFlist"; }
2538  Database="DBM: ",DatabasePath;
2539
2540  link dbmLink=Database;
2541  debug_log(2, "Opening Singalarity-database: ", newline, Database);
2542  Tp = read(dbmLink, typ);
2543  debug_log(2,"DBMread(", typ, ")=", Tp, ".");
2544  if( Tp != "(null)" && Tp !="" )
2545  {
2546    string Key = "I_", typ;
2547    S = "f = ", Tp, ";";
2548    debug_log(2,"S=", S, " Tp=", Tp, "Key=", Key);
2549    execute(S);
2550    execute(read(dbmLink, Key)+";");
2551    debug_log(1, "Polynom f=", f,  "  crk=", crk, "  Mu=", Mu,
2552                " MlnCd=", MlnCd);
2553    v = f, crk, Mu, MlnCd;
2554  }
2555  else
2556  {
2557    v = 0, 0, 0, 0;
2558  }
2559  close(dbmLink);
2560  return(v);
2561}
2562
2563///////////////////////////////////////////////////////////////////////////////
2564proc RandomPolyK (int M, string Typ)
2565"USAGE:    RandomPolyK(M, Typ)"
2566{
2567//---------------------------- initialisation ---------------------------------
2568  int    n, b, i, k, r, s, crk;
2569  ideal  B;
2570  map    Phi;
2571  string txt, Tp;
2572  list   v;
2573
2574  def ring_ext=basering;
2575  n=4;
2576  if(M<5) { M = 5; }
2577
2578  k = random(1, M);
2579  r = random(-5, 2*M);
2580  s = random(-5, 2*M);
2581  if(r<0) { r = 0; }
2582  if(s<0) { s = 0; }
2583
2584  ring RgAnf=char(basering),(x,y,z,t),(c,ds);
2585  poly f;
2586
2587  v = singularity(Typ, k, r, s);
2588  f, crk = v[1..2];
2589//  f = f +t2;
2590  if(crk==1) { f = f + y2 + z2; }
2591  if(crk==2) { f = f + z2; }
2592  txt="RandomPoly-Series: gewaehlt fall "+Typ+" mit";
2593  txt=txt+" f="+string(f);
2594  txt;
2595  setring ring_ext;
2596  B = maxideal(1);
2597
2598  r=1;
2599  for(i=n; i>0; i--,r++)
2600  {
2601//  for(i=1; i<=n; i=i+1)
2602    B[rvar(x(r))] = x(i);
2603    if(i>2 && random(1,10)<3) { B[rvar(x(r))] = B[rvar(x(r))] + x(i-1); }
2604//    if(i==1 && random(1,10)<4) { B[rvar(x(r))] = B[rvar(x(r))]- x(n); }
2605    if(i>0)
2606    {
2607      for(b=3; b<5; b=b+1)
2608      {
2609        // B[rvar(x(r))] = B[rvar(x(r))] + random(0,9) * x(i)^(b+2);
2610        if(random(1,20)<3)
2611        {
2612          B[rvar(x(r))] = B[rvar(x(r))] - random(-2,2)*x(b)^2;
2613        }
2614      }
2615    }
2616  }
2617  Phi=RgAnf, B;
2618  Phi;
2619  poly fr=Phi(f);
2620  fr = fr+(x(1)+x(2))^2;
2621//  return(Phi(f));
2622  return(fr);
2623}
2624
2625///////////////////////////////////////////////////////////////////////////////
2626proc debug_log (int level, list #)
2627"USAGE:    debug_log(level,li); level=int, li=comma separated \"message\" list
2628COMPUTE:  print \"messages\" if level>=@DeBug.
2629          useful for user-defined trace messages.
2630EXAMPLE:  example debug_log; shows an example
2631SEE ALSO: init_debug
2632"
2633{
2634   int len = size(#);
2635//   int printresult = printlevel - level +1;
2636//   if(level>1)
2637//   {
2638//     dbprint(printresult, "Debug:("+ string(level)+ "): ", #[2..len]);
2639//   }
2640//   else { dbprint(printresult, #[1..len]); }
2641   if( defined(@DeBug) == 0 ) { init_debug(); }
2642   if(@DeBug>=level)
2643   {
2644      if(level>1) { "Debug:("+ string(level)+ "): ", #[1..len]; }
2645      else { #[1..len]; }
2646   }
2647}
2648example
2649{ "EXAMPLE:"; echo=2;
2650  example init_debug;
2651}
2652
2653///////////////////////////////////////////////////////////////////////////////
2654proc init_debug(list #)
2655"USAGE:    init_debug([level]);  level=int
2656COMPUTE:  Set the global variable @DeBug to level. The variable @DeBug is
2657          used by the function debug_log(level, list of strings) to know
2658          when to print the list of strings. init_debug() reports only
2659          changes of @DeBug.
2660NOTE:     The procedure init_debug(n); is useful as trace-mode. n may
2661          range from 0 to 10, higher values of n give more information.
2662EXAMPLE:  example init_debug; shows an example"
2663{
2664  int newDebug=0;
2665  if( defined(@DeBug) != 0 ) { newDebug = @DeBug; }
2666
2667  if( size(#) > 0 )
2668  {
2669    newDebug=#[1];
2670  }
2671  else
2672  {
2673    string s=system("getenv", "SG_DEBUG");
2674    if( s != "" && defined(@DeBug)==0)
2675    {
2676      s="newDebug="+s;
2677      execute(s);
2678    }
2679  }
2680  if( defined(@DeBug) == 0)
2681  {
2682    int @DeBug = newDebug;
2683    export @DeBug;
2684    if(@DeBug>0) { "Debugging level is set to ", @DeBug; }
2685  }
2686  else
2687  {
2688    if( (size(#) == 0) && (newDebug < @DeBug) ) { return(); }
2689    if( @DeBug != newDebug)
2690    {
2691      int oldDebug = @DeBug;
2692      @DeBug = newDebug;
2693      if(@DeBug>0) { "Debugging level change from ", oldDebug, " to ",@DeBug; }
2694      else
2695      {
2696        if( @DeBug==0 && oldDebug>0 ) { "Debugging switched off."; }
2697      }
2698    }
2699  }
2700  printlevel = @DeBug;
2701}
2702example
2703{ "EXAMPLE:"; echo=2;
2704  init_debug();
2705  debug_log(1,"no trace information printed");
2706  init_debug(1);
2707  debug_log(1,"some trace information");
2708  init_debug(2);
2709  debug_log(2,"nice for debugging scripts");
2710  init_debug(0);
2711}
2712
2713///////////////////////////////////////////////////////////////////////////////
2714proc basicinvariants(poly f)
2715"USAGE:    basicinvariants(f);   f = poly
2716COMPUTE:  Compute basic invariants of f: an upper bound d for the
2717          determinacy, the milnor number mu and the corank c of f
2718RETURN:   intvec: d, mu, c
2719EXAMPLE:  example basicinvariants; shows an example"
2720{
2721  intvec v;
2722  ideal Jfs = std(jacob(f));
2723  v[1] = system("HC")+1;
2724  v[2] = vdim(Jfs);
2725  v[3] = corank(f);
2726  if( v[2]<v[1] ) { v[1] = v[2]+1; }
2727  return(v);
2728}
2729example
2730{ "EXAMPLE:"; echo=2;
2731   ring r=0,(x,y,z),ds;
2732   basicinvariants((x2+3y-2z)^2+xyz-(x-y3+x2*z3)^3);
2733}
2734
2735///////////////////////////////////////////////////////////////////////////////
2736proc corank(poly f)
2737"USAGE:    corank(f);   f=poly
2738RETURN:   the corank of the Hessian matrix of f, of type int
2739REMARK:   corank(f) is the number of variables occurring in the residual
2740          singularity after applying 'morsesplit' to f
2741EXAMPLE:  example corank; shows an example"
2742{
2743  matrix M = jacob(jacob(jet(f,2)));
2744  list lba = bareiss(M);
2745  int cr = nvars(basering) - size(module(lba[1]));
2746  return(cr);
2747}
2748example
2749{ "EXAMPLE:"; echo=2;
2750  ring r=0,(x,y,z),ds;
2751  poly f=(x2+3y-2z)^2+xyz-(x-y3+x2*z3)^3;
2752  corank(f);
2753}
2754///////////////////////////////////////////////////////////////////////////////
2755static proc Faktorisiere(poly f, poly fk, int pt, int k, intvec RFlg)
2756{
2757//---------------------------- initialisation ---------------------------------
2758  poly   a, b, Relation;
2759  ideal  B, Jfsyz;
2760  map    PhiG, VERT;
2761  matrix Mat;
2762  list   v;
2763  def    ring_top=basering;
2764
2765  // Ziel: bestimme a,b sodass  fk = (ax+by^k)^pt gilt.
2766  B    = maxideal(1);
2767  PhiG = ring_top,B;
2768  debug_log(2, "Faktor: f=",Show(f)," Jet=",Show(fk)," k=",k," exp=",pt);
2769
2770//----------------------- compute role of x and y -----------------------------
2771  Jfsyz = fk, diff(fk, x(1));
2772  Mat   = matrix(syz(Jfsyz));
2773  if( (fk-subst(fk,x(1),0)) != 0  &&  (fk-subst(fk,x(2),0)) != 0 )
2774  {
2775    // Wenn k>0 ist die Wahl fuer x & y bereits getroffen
2776    // sonst bestimmen x und y
2777    Jfsyz    = fk, diff(fk, x(1));
2778    Mat      = matrix(syz(Jfsyz));
2779    Relation = -pt * Mat[2,1] / Mat[1,1];
2780    a = Coeff(Relation, x(1), x(1));
2781    b = Coeff(Relation, x(2), x(2)^k);
2782    B = maxideal(1);
2783    if( (RFlg[1]==1 && k==1) || k>1) { B[rvar(x(1))] = x(1)-b*x(2)^k; }
2784    else { B[rvar(x(2))] = x(2)-b*x(1)^k; }
2785    VERT = basering,B;
2786    f    = VERT(f);
2787    PhiG = VERT(PhiG);
2788  }
2789
2790//------------------- permutation of x and y, if needed -----------------------
2791  if( k==1 )
2792  {
2793    debug_log(2, "Fak-7:",Show(f)," jet=",Show(fk));
2794    if(Coeff(jet(f, pt), x(1), x(1)^pt) == 0)
2795    {
2796      VERT = basering,x(2),x(1);
2797      f    = VERT(f);
2798      PhiG = VERT(PhiG);
2799    }
2800  }
2801  debug_log(2, "Fak-8:",Show(f)," jet=",Show(fk));
2802  debug_log(6, "Faktorisiere liefert: f=", Show(f));
2803  v[1] = f;
2804  v[2] = PhiG;
2805  return(v);
2806}
2807
2808///////////////////////////////////////////////////////////////////////////////
2809static proc Teile(poly f, poly fk)
2810{
2811  ideal  Jfsyz = f, fk;
2812  poly   Relation;
2813  matrix Mat = matrix(syz(Jfsyz));
2814  Relation   = -1 * Mat[2,1]/Mat[1,1];
2815  return(Relation);
2816}
2817
2818///////////////////////////////////////////////////////////////////////////////
2819static proc GetRf (poly fi, int n)
2820"USAGE:    GetRf();"
2821{
2822//---------------------------- initialisation ---------------------------------
2823  int    j, k, l1, l1w;
2824  matrix Koef;
2825  intvec RFlg;
2826
2827  RFlg[n] = 0;
2828  intvec Haeufigkeit = RFlg;
2829
2830  for( j=1; j<=n ; j=j+1)
2831  {
2832    Koef = coef(fi, x(j));
2833    Haeufigkeit[j] = ncols(Koef);
2834    if(Coeff(fi, x(j),0) == 0) { Haeufigkeit[j] = Haeufigkeit[j] + 1;}
2835  }
2836  for( j=n; j>0 ; j=j-1)
2837  {
2838    l1  = 0;
2839    l1w = 0;
2840    for(k=1;k<=n;k=k+1) { if(Haeufigkeit[k]>l1w) { l1=k; l1w=Haeufigkeit[k];}}
2841    RFlg[j]        = l1;
2842    Haeufigkeit[l1] = 0;
2843  }
2844  debug_log(2, "Permutations:", RFlg);
2845  return(RFlg);
2846}
2847
2848///////////////////////////////////////////////////////////////////////////////
2849static proc Show(poly g)
2850{
2851  string s;
2852  def ring_save=basering;
2853
2854  execute(@ringdisplay);
2855  map showpoly=ring_save,maxideal(1);
2856  s = string(showpoly(g));
2857  setring ring_save;
2858  return (s);
2859}
2860
2861///////////////////////////////////////////////////////////////////////////////
2862static proc checkring
2863{
2864  int CH = char(basering);
2865  if(CH >= 2 && CH<=13)
2866  {
2867    "Ring has characteristic ",CH;
2868    "Characteristic other than 0 or 0<char<13 is not yet implemented";
2869    return(1);
2870  }
2871  return(0);  // characteristic of ring is OK, return (0)
2872}
2873
2874///////////////////////////////////////////////////////////////////////////////
2875static proc DecodeNormalFormString (string S_in)
2876"USAGE:    DecodeNormalFormString"
2877{
2878//---------------------------- initialisation ---------------------------------
2879  int    C_eq, a, b, i, t, k, r, s;
2880  string s1, s2, s3, s4, s_in, Typ;
2881  list v = "Error", 0, 0, 0;
2882
2883  C_eq = find(S_in, "=")+1;
2884  s_in = S_in[C_eq,30];
2885  debug_log(2, "Decode:");
2886
2887  debug_log(2, "S_in=", S_in,"  s_in=",s_in );
2888  a = find(s_in, "[")+1;
2889  b = find(s_in, "]")-1;
2890  t = 1;
2891  k = 0;
2892  r = 0;
2893  s = 0;
2894
2895  if(a<0 || b<0) { return(v); }
2896  Typ = s_in[1..a-1];
2897  s1  = s_in[a..b];
2898  debug_log(6, "Suche Type:", Typ);
2899  //---------------------- decode between brackets ----------------------------
2900  if( find(s1, ",") == 0)
2901  {
2902    debug_log(8, "  Number of columns: 0");
2903    s2 = "k = "+s1+";";
2904    execute(s2);
2905    if( (Typ=="A[") || (Typ=="D[") ) { s3 = "k"; }
2906    if( Typ == "E[") { t = 6; }
2907    if( Typ == "W[") { t = 12; }
2908    if( Typ == "Q[") { t = 6; }
2909    if( Typ == "Z[") { t = 6; }
2910    if( Typ == "U[") { t = 12; }
2911    if( t > 1 )
2912    {
2913      i = k;
2914      k = k div t;
2915      b = i - t*k;
2916      if( (s1 == "Q[") && (b==0) ) { k=k-1; b=6; }
2917      if(Typ == "Z[")
2918      {
2919        if(b==0) { k=k-1; b=6; }
2920        if(b==1) { k=k-1; b=7; }
2921      }
2922      if( b == 0 ) { s3 = string(t)+"k"; }
2923      else { s3 = string(t)+"k+"+string(b); }
2924    }
2925    if( Typ == "S[")
2926    {
2927      i = k+1;
2928      k = i/12;
2929      b = i - 12*k;
2930      if( b == 1 ) { s3 = "k"; }
2931      else
2932      {
2933        if(b==0) { s3 = "12k"+string(b-1); }
2934        else { s3 = "12k+"+string(b-1); }
2935      }
2936    }
2937    s2 = Typ + s3 +"]";
2938  }  // es kommt mindestens ein komma vor...
2939  //----------------------- more than 1 parameter -----------------------------
2940  else
2941  {
2942    b  = find(s1, ",");
2943    s2 = "k = ",s1[1..b-1],";";
2944    execute(s2);
2945    s1 = s1[b+1..size(s1)];
2946    if(find(s1, ",") == 0)
2947    {
2948      debug_log(8, "  Number of columns 1");
2949      s2 = "r = "+s1+";";
2950      execute(s2);
2951      s4 = "r";
2952      s3 = "k";
2953      if(r==0) { s4 = string(0); }
2954      if(k==0 && Typ=="Z[") { s3 = string(1); }
2955      if(Typ[2] == "#")
2956      {
2957        i = r+1;
2958        r = i div 2;
2959        b = i - 2*r;
2960        if( b == 1 ) { s4 = "2r"; }
2961        else { s4 = "2r-1"; }
2962      }
2963      s2 = Typ + s3 + "," + s4 +"]";
2964    }  // es kommt mindestens zwei komma vor...
2965    //----------------------- get third parameter -----------------------------
2966    else
2967    {
2968      debug_log(8, "  Number of columns >=2");
2969      debug_log(2, "Y[k,r,s] / Z[k,r,s] / T[k,r,s]");
2970      b  = find(s1, ",");
2971      s2 = "r = ",s1[1..b-1],";";
2972      if ((s2[5]>"0") && (s2[5]<="9")) { execute(s2); }
2973      s2 = "s = ",s1[b+1..size(s1)],";";
2974      if ((s2[5]>"0") && (s2[5]<="9")) { execute(s2); }
2975      if(Typ=="Y[") { s2 = "Y[k,r,s]"; }
2976      if(Typ=="Z[") { s2 = "Z[k,r,s]"; }
2977      if(Typ=="T[") { s2 = "T[k,r,s]"; }
2978    }
2979  }
2980  debug_log(2, "Looking for Normalform of ",s2,"with (k,r,s) = (",
2981        k,",",r,",", s, ")" );
2982  v = s2, k, r, s;
2983  return(v);
2984}
2985
2986///////////////////////////////////////////////////////////////////////////////
2987proc A_L
2988"USAGE:    A_L(f);  f poly
2989          A_L(s);  s string, the name of the singularity
2990COMPUTE:  the normal form of f in Arnold's list of singularities in case 1,
2991          in case 2 nothing has to be computed.
2992RETURN:   A_L(f): compute via 'milnorcode' the class of f and return the normal
2993          form of f found in the database.
2994          A_L(\"name\"): get the normal form from the database for the
2995          singularity given by its name.
2996EXAMPLE:  example A_L; shows an example"
2997{
2998  // if trace/debug mode not set, do it!
2999  init_debug();
3000
3001  if( typeof(#[1]) == "string" )
3002  {
3003    if(checkring()) { return(#[1]); }
3004    return(normalform(#[1]));
3005  }
3006  if( typeof(#[1]) == "poly" )
3007  {
3008    if(checkring()) { return(#[1]); }
3009    return(quickclass(#[1]));
3010  }
3011
3012}
3013example
3014{ "EXAMPLE:"; echo=2;
3015  ring r=0,(a,b,c),ds;
3016  poly f=A_L("E[13]");
3017  f;
3018  A_L(f);
3019}
3020
3021///////////////////////////////////////////////////////////////////////////////
3022proc normalform(string s_in)
3023"USAGE:    normalform(s);  s=string
3024RETURN:   Arnold's normal form of singularity with name s
3025EXAMPLE:  example normalform; shows an example."
3026{
3027  string Typ;
3028  int    k, r, s, crk;
3029  int    n, i;
3030  poly   f;
3031  list   v;
3032  def ring_ext = basering;
3033  n = nvars(basering);
3034  ring ring_top=char(basering),(x(1..n)),(c,ds);
3035
3036  if(checkring()) { return(s_in); }
3037  if(nvars(basering)<=1)
3038  {
3039    "We need at least 2 variables in basering, you have",nvars(basering),".";
3040    return();
3041  }
3042  // if trace/debug mode not set, do it!
3043  init_debug();
3044
3045  v = DecodeNormalFormString(s_in);
3046  Typ, k, r, s = v[1..4];
3047  if(Typ=="Error") { return(0); }
3048  v = singularity(Typ, k, r, s);
3049  poly f_out;
3050  f_out, crk = v[1..2];
3051  if(crk>1) { for(i=crk+1;i<=n;i=i+1) { f_out = f_out + x(i)^2; } }
3052  setring ring_ext;
3053  map conv_top2ext=ring_top,maxideal(1);
3054  f = conv_top2ext(f_out);
3055//  f, crk = v[1..2];
3056  return(f);
3057}
3058example
3059{ "EXAMPLE:"; echo=2;
3060  ring r=0,(a,b,c),ds;
3061  normalform("E[13]");
3062}
3063
3064///////////////////////////////////////////////////////////////////////////////
3065proc swap
3066"USAGE:    swap(a,b);
3067RETURN:   b,a if a,b is the input (any type)"
3068{
3069  return(#[2],#[1]);
3070}
3071example
3072{ "EXAMPLE:"; echo=2;
3073  swap("variable1","variable2");
3074}
3075
3076///////////////////////////////////////////////////////////////////////////////
3077proc Setring(int c, string name)
3078"USAGE:    "
3079{
3080  string s="ring "+name+"=0,(x(1.."+ string(c) +")),(c,ds);";
3081  return(s);
3082}
3083
3084///////////////////////////////////////////////////////////////////////////////
3085proc internalfunctions()
3086"USAGE:   internalfunctions();
3087RETURN:  nothing, display names of internal procedures of classify.lib
3088EXAMPLE: no example"
3089{ "   Internal functions for the classification using Arnold's method,";
3090 "   the function numbers correspond to numbers in Arnold's classifier:";
3091 "Klassifiziere(poly f);      //determine the type of the singularity f
3092  Funktion1bis (poly f, list cstn)
3093  Funktion3 (poly f, list cstn)
3094  Funktion6 (poly f, list cstn)
3095  Funktion13 (poly f, list cstn)
3096  Funktion17 (poly f, list cstn)
3097  Funktion25 (poly f, list cstn)
3098  Funktion40 (poly f, list cstn, int k)
3099  Funktion47 (poly f, list cstn)
3100  Funktion50 (poly f, list cstn)
3101  Funktion58 (poly fin, list cstn)
3102  Funktion59 (poly f, list cstn)
3103  Funktion66 (poly f, list cstn)
3104  Funktion82 (poly f, list cstn)
3105  Funktion83 (poly f, list cstn)
3106  Funktion91 (poly f, list cstn, int k)
3107  Funktion92 (poly f, list cstn, int k)
3108  Funktion93 (poly f, list cstn, int k)
3109  Funktion94 (poly f, list cstn, int k)
3110  Funktion95 (poly f, list cstn, int k)
3111  Funktion96 (poly f, list cstn, int k)
3112  Funktion97 (poly f, list cstn)
3113  Isomorphie_s82_x (poly f, poly fk, int k)
3114  Isomorphie_s82_z (poly f, poly fk, int k)
3115  Isomorphie_s17 (poly f, poly fk, int k, int ct)
3116  printresult (string f,string typ,int Mu,int m,int corank,int K)
3117  ";
3118  "   Internal functions for the classifcation by invariants:
3119  Cubic (poly f)
3120  parity (int e)             //return the parity of e
3121  HKclass (intvec i)
3122  HKclass3( intvec i, string SG_Typ, int cnt)
3123  HKclass3_teil_1 (intvec i, string SG_Typ, int cnt)
3124  HKclass5 (intvec i, string SG_Typ, int cnt)
3125  HKclass5_teil_1 (intvec i, string SG_Typ, int cnt)
3126  HKclass5_teil_2 (intvec i, string SG_Typ, int cnt)
3127  HKclass7 (intvec i, string SG_Typ, int cnt)
3128  HKclass7_teil_1 (intvec i, string SG_Typ, int cnt)
3129  ";
3130  "   Internal functions for the Morse-splitting lemma:
3131  Morse(poly fi, int K, int corank)  //splitting lemma itself
3132  Coeffs (list #)
3133  Coeff
3134  ";
3135  "   Internal functions providing tools:
3136  ReOrder(poly f)
3137  Singularitaet(string typ,int k,int r,int s,poly a,poly b,poly c,poly d)
3138  RandomPolyK
3139  Faktorisiere(poly f, poly g, int p, int k)   compute g = (ax+by^k)^p
3140  Teile(poly f, poly g);             //divides f by g
3141  GetRf(poly f, int n);
3142  Show(poly f);
3143  checkring();
3144  DecodeNormalFormString(string s);
3145  Setring(int n, string ringname);
3146  ";
3147}
3148example
3149{
3150  "EXAMPLE"; echo=2;
3151  internalfunctions();
3152}
3153
3154///////////////////////////////////////////////////////////////////////////////
3155proc prepRealclassify(poly f)
3156"
3157USAGE:    prepRealclassify(f); f poly
3158RETURN:   a list, containing the modality of the singularity and the type of
3159          the singularity as a string
3160          @* This procedure is needed in realclassify.lib in order to avoid
3161          classify() being called more than once.
3162EXAMPLE:  example prepRealclassify; shows an example"
3163{
3164  exportinvariants(f);
3165  return(list(Modality, Type));
3166}
3167example
3168{
3169  "EXAMPLE"; echo = 2;
3170  ring r = 0, (x,y,z), ds;
3171  poly f = (x2+3y-2z)^2+xyz-(x-y3+x2z3)^3;
3172  prepRealclassify(f);
3173}
3174
3175///////////////////////////////////////////////////////////////////////////////
3176proc modality(poly f)
3177"
3178USAGE:    modality(f); f poly
3179RETURN:   the modality of the singularity
3180EXAMPLE:  example modality; shows an example"
3181{
3182  exportinvariants(f);
3183  return(Modality);
3184}
3185example
3186{
3187  "EXAMPLE"; echo = 2;
3188  ring r = 0, (x,y,z), ds;
3189  poly f = (x2+3y-2z)^2+xyz-(x-y3+x2z3)^3;
3190  modality(f);
3191}
3192
3193///////////////////////////////////////////////////////////////////////////////
3194proc complexSingType(poly f)
3195"
3196USAGE:    complexSingType(f); f poly
3197RETURN:   the type of the singularity as a string
3198EXAMPLE:  example complexSingType; shows an example"
3199{
3200  exportinvariants(f);
3201  return(Type);
3202}
3203example
3204{
3205  "EXAMPLE"; echo = 2;
3206  ring r = 0, (x,y,z), ds;
3207  poly f = (x2+3y-2z)^2+xyz-(x-y3+x2z3)^3;
3208  complexSingType(f);
3209}
3210
3211///////////////////////////////////////////////////////////////////////////////
3212/* some of the invariants will be exported during the computation of
3213 * classify(f) such that they are accessible at for all procs in the library
3214 */
3215static proc exportinvariants(poly f)
3216{
3217  init_debug(-1);
3218  if(!defined(onlyreturninvariants))
3219  {
3220    int onlyreturninvariants;
3221    export(onlyreturninvariants);
3222  }
3223  onlyreturninvariants = 1;
3224  if(!defined(Modality))
3225  {
3226    int Modality;
3227    export(Modality);
3228  }
3229  if(!defined(Type))
3230  {
3231    string Type;
3232    export(Type);
3233  }
3234  f = classify(f);
3235}
3236
3237///////////////////////////////////////////////////////////////////////////////
3238// E n d   O f   F i l e
3239
Note: See TracBrowser for help on using the repository browser.