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

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