source: git/Singular/LIB/classify.lib @ 3d276d

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