source: git/Singular/LIB/classify.lib @ 1288ef

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