source: git/Singular/LIB/classify.lib @ 0b59f5

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