source: git/Singular/LIB/classify.lib @ a42239

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