source: git/Singular/LIB/classify.lib @ 29a9d13

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