source: git/Singular/LIB/classify.lib @ 876fc4

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