source: git/Singular/LIB/modnormal.lib @ 1b2216

spielwiese
Last change on this file since 1b2216 was b0732eb, checked in by Hans Schoenemann <hannes@…>, 12 years ago
add: new libs from master
  • Property mode set to 100644
File size: 19.0 KB
Line 
1////////////////////////////////////////////////////////////////////////////////
2version="$Id$";
3category = "Commutative Algebra";
4info="
5LIBRARY:  modnormal.lib    Normalization of affine domains using modular methods
6
7AUTHORS:  J. Boehm        boehm@mathematik.uni-kl.de
8          W. Decker       decker@mathematik.uni-kl.de
9          S. Laplagne     slaplagn@dm.uba.ar
10          G. Pfister      pfister@mathematik.uni-kl.de
11          A. Steenpass    steenpass@mathematik.uni-kl.de
12          S. Steidel      steidel@mathematik.uni-kl.de
13@*
14
15OVERVIEW:
16Suppose A is an affine domain over a perfect field.@*
17This library implements a modular strategy for finding the normalization of A.
18Following [1], the idea is to apply the normalization algorithm given in [2]
19over finite fields and lift the results via Chinese remaindering and rational
20reconstruction as described in [3]. This approch is inherently parallel.@*
21The strategy is available both as a randomized and as a verified algorithm.
22
23REFERENCES:
24
25[1] Janko Boehm, Wolfram Decker, Santiago Laplagne, Gerhard Pfister, Stefan Steidel,
26Andreas Steenpass: Parallel algorithms for normalization, preprint, 2011.
27
28[2] Gert-Martin Greuel, Santiago Laplagne, Frank Seelisch: Normalization of Rings,
29Journal of Symbolic Computation 9 (2010), p. 887-901
30
31[3] Janko Boehm, Wolfram Decker, Claus Fieker, Gerhard Pfister:
32The use of Bad Primes in Rational Reconstruction, preprint, 2012.
33
34KEYWORDS:
35normalization; modular methods
36
37SEE ALSO: normal_lib, locnormal_lib
38
39PROCEDURES:
40modNormal(I);        normalization of R/I using modular methods
41
42";
43
44LIB "poly.lib";
45LIB "ring.lib";
46LIB "normal.lib";
47LIB "modstd.lib";
48LIB "parallel.lib";
49
50////////////////////////////////////////////////////////////////////////////////
51// Verify the char 0 result L of normalization of I modulo a prime p
52
53static proc pTestNormal(ideal I, list L, int p, ideal normalIP)
54{
55   // We change the characteristic of the ring to p.
56  def R0 = basering;
57  ideal U = L[1];
58  poly condu=L[2];
59  list rl = ringlist(R0);
60  rl[1] = p;
61  def @r = ring(rl);
62  setring @r;
63  ideal IP = fetch(R0,I);
64  ideal UP = fetch(R0,U);
65  poly conduP = fetch(R0, condu);
66  ideal outP = fetch(R0,normalIP);
67  poly denOutP = outP[1];
68
69  // Check if the universal denominator is valid
70  ideal cOut = conduP*outP;
71  ideal dI = ideal(denOutP) + IP;
72  int inc = size(reduce(cOut, groebner(dI)));
73  if(inc > 0)
74  {
75    "Inclusion is not satisfied. Unlucky prime?";
76    return(ideal(0));
77  }
78  return(outComp(UP, outP, conduP, denOutP, IP))
79  }
80
81////////////////////////////////////////////////////////////////////////////////
82
83
84// Computes the normalization of I in characterisitic p.
85// Returns an ideal Out such that the normalization mod p is the
86// module 1/condu * Out
87static proc modpNormal(ideal I, int p, poly condu,printTimings,list #)
88{
89  int tt = timer;
90  int liftRelations;
91  // We change the characteristic of the ring to p.
92  def R0 = basering;
93  list rl = ringlist(R0);
94  rl[1] = p;
95  def @r = ring(rl);
96  int loc;
97  int i;
98  for ( i=1; i <= size(#); i++ )
99  {
100    if ( typeof(#[i]) == "string" )
101    {
102      if (#[i]=="inputJ") { loc = 1;ideal J=#[i][2];}
103    }
104  }
105  setring @r;
106  if (loc==1) {ideal JP = fetch(R0,J)};
107  //int t=timer;
108  ideal IP = groebner(fetch(R0,I));
109  //"Time for groebner mod p "+string(timer -t);
110  poly conduP = fetch(R0, condu);
111
112  option(redSB);
113
114  int t = timer;
115  // We compute the normalization mod p
116  if (loc==0)
117  {
118    //global
119    list l = normal(IP);
120  } else {
121    //local
122    list l = normal(IP,list(list("inputJ", JP)));
123  }
124  if (printTimings==1) {"Time for modular normal: "+string(timer - t);}
125
126  t = timer;
127
128  // Currently, the algorithm only works if no splitting occurs during the
129  // normalization process. (For example, if I is prime.)
130  if(size(l[2]) > 1){
131    ERRROR("Original ideal is not prime (Not implemented.) or unlucky prime");
132  }
133
134  ideal outP = l[2][1];
135  poly denOutP = outP[size(outP)];
136
137  // Check if the universal denominator is valid
138  ideal cOut = conduP*outP;
139  ideal dI = ideal(denOutP) + IP;
140  int inc = size(reduce(cOut, groebner(dI)));
141  if(inc > 0)
142  {
143    ERROR("Inclusion is not satisfied. Unlucky prime?");
144  }
145
146  // We change the denominator to the universal denominator
147  outP = changeDenominator(outP, denOutP, conduP, IP);
148  if(size(outP) > 1)
149  {
150    ideal JP = conduP, outP[1..size(outP)-1];
151  } else
152  {
153    ERROR("Normal ring - Special case not fully implemented.");
154    ideal JP = conduP;
155    ideal norid = 0;
156    export norid;
157    def RP = @r;
158  }
159
160  setring R0;
161  ideal out = fetch(@r, JP);
162
163  if (printTimings==1) {"Prime: "+string(p);}
164  tt = timer-tt;
165  return(list(out, p, tt));
166}
167
168// Computes the normalization using modular methods.
169// Basic algorithm based on modstd.
170proc modNormal(ideal I, int nPrimes, list #)
171"USAGE:  modNormal(I, n [,options]); I = prime ideal, n = positive integer, options = list of options. @*
172         Optional parameters in list options (can be entered in any order):@*
173         noVerificication: do not verify the result.@*
174         printTimings: print timings.@*
175         int ncores: number of cores to be used (default = 1).
176ASSUME:  I is a prime ideal (the algorithm will also work for radical ideals as long as the
177         normal command does not detect that the ideal under consideration is not prime).
178RETURN:  a list of an ideal U and a universal denominator d such that U/d is the normalization.
179REMARKS: We use the algorithm given in [1] to compute the normalization of A = R/I where R is the
180         basering. We apply the algorithm for n primes at a time until the result lifted to the
181         rationals is correct modulo one additional prime. Depending on whether the option
182         noVerificication is used or not, the result is returned as a probabilistic result
183         or verified over the rationals.@*
184         The normalization of A is represented as an R-module by returning a list of U and d,
185         where U is an ideal of A and d is an element of A such that U/d is the normalization of A.
186         In fact, U and d are returned as an ideal and a polynomial of the base ring R.
187KEYWORDS: normalization; modular techniques.
188SEE ALSO: normal_lib, locnormal_lib.
189EXAMPLE: example modNormal; shows an example
190"
191{
192
193  int i,noVerif,printTimings;
194  int liftRelations;
195  int ncores = 1;
196  for ( i=1; i <= size(#); i++ )
197  {
198    if ( typeof(#[i]) == "string" )
199    {
200      if (#[i]=="noVerification") { noVerif = 1;}
201      if (#[i]=="printTimings") { printTimings = 1;}
202    }
203    if ( typeof(#[i]) == "int" )
204    {
205      ncores = #[i];
206    }
207  }
208
209
210  int totalTime = timer;
211
212  intvec LTimer;
213  int t;
214
215  def R = basering;
216  int j;
217
218//--------------------  Initialize the list of primes  -------------------------
219  int n2 = nPrimes;
220
221
222
223//---Computation of the jacobian ideal and the universal denominator
224
225  list IM = mstd(I);
226  I = IM[1];
227  int d = dim(I);
228  ideal IMin = IM[2];
229  qring Q = I;   // We work in the quotient by the groebner base of the ideal I
230  option("redSB");
231  option("returnSB");
232  ideal I = fetch(R, I);
233  attrib(I, "isSB", 1);
234  ideal IMin = fetch(R, IMin);
235  dbprint(dbg, "Computing the jacobian ideal...");
236  ideal J = minor(jacob(IMin), nvars(basering) - d, I);
237  t=timer;
238  J = modStd(J);
239  if (printTimings==1) {"Time for modStd Jacobian "+string(timer-t);}
240
241  setring R;
242  ideal J = fetch(Q, J);
243
244  //------------------ We check if the singular locus is empty -------------
245  if(J[1] == 1)
246  {
247    // The original ring R/I was normal. Nothing to do.
248    return(ideal(1));
249  }
250
251//--- Universal denominator---
252  poly condu = getSmallest(J);   // Choses the polynomial of smallest degree
253                                 // of J as universal denominator.
254  if (printTimings==1) {"conductor: ", condu;}
255
256//--------------  Main standard basis computations in positive  ----------------
257//----------------------  characteristic start here  ---------------------------
258  list resultNormal,currentPrimes;
259  list resultNormalX,currentPrimesX;
260  list LL;
261
262  ideal ChremLift;
263  ideal Out;
264  list OutCondu;
265
266  int ptn;
267  int k = 1;
268  int sh;
269  int p;
270  int h;
271
272  intvec L;
273  bigint N;
274
275  int totalModularTime;
276  int maxModularTime;
277  int sumMaxModularTime;
278  int sumTotalModularTime;
279
280  ideal normalIP;
281
282  I = groebner(I);
283  // Largest prime:     2147483647
284  // Max prime for gcd:  536870909
285
286  // loop increasing the number of primes by n2 until pTest is true
287  list modarguments;
288  list modresults;
289  int lastPrime;
290  while (ptn==0)
291  {
292    L = primeList(I,k*n2+1,intvec(536870627),1);
293    maxModularTime=0;
294    totalModularTime = timer;
295    if (k==1) {sh=0;} else {sh=1;}
296    if (ncores == 1)
297    {
298      for(j = (k-1)*n2+1+sh; j <= k*n2+1; j++)
299      {
300        t = timer;
301        normalIP = modpNormal(I, L[j], condu,printTimings,#)[1];
302        if(timer - t > maxModularTime) { maxModularTime = timer - t; }
303        LTimer[j] = timer - t;
304        setring R;
305        resultNormalX[j] = normalIP;
306        currentPrimesX[j] = bigint(L[j]);
307      }
308      lastPrime = L[k*n2+1];
309    }
310    else
311    {
312      for(j = (k-1)*n2+1+sh; j <= k*n2+1; j++)
313      {
314        modarguments[j-(k-1)*n2-sh] = list(I, L[j], condu, printTimings, #);
315      }
316      modresults = parallelWaitAll("modpNormal", modarguments,
317        list(list(list(ncores))));
318      for(j = (k-1)*n2+1+sh; j <= k*n2+1; j++)
319      {
320        resultNormalX[j] = modresults[j-(k-1)*n2-sh][1];
321        currentPrimesX[j] = bigint(modresults[j-(k-1)*n2-sh][2]);
322        LTimer[j] = modresults[j-(k-1)*n2-sh][3];
323        if(LTimer[j] > maxModularTime) { maxModularTime = LTimer[j]; }
324      }
325      normalIP = resultNormalX[k*n2+1];
326      lastPrime = modresults[n2-sh+1][2];
327    }
328
329    if (printTimings==1) {"List of times for all modular computations so far: "+string(LTimer);}
330    if (printTimings==1) {"Maximal modular time of current step: "+string(maxModularTime);}
331    sumMaxModularTime=sumMaxModularTime+maxModularTime;
332    totalModularTime = timer - totalModularTime;
333    sumTotalModularTime=sumTotalModularTime+totalModularTime;
334    if (printTimings==1) {"Total modular time of current step: "+string(totalModularTime);}
335    resultNormal=delete(resultNormalX,size(resultNormalX));
336    currentPrimes=delete(currentPrimesX,size(currentPrimesX));
337    //------------------------  Delete unlucky primes  -----------------------------
338    //-------------  unlucky if and only if the leading ideal is wrong  ------------
339    // Polynomials are not homogeneous: h = 0
340    LL = deleteUnluckyPrimes(resultNormal,currentPrimes,h);
341    resultNormal = LL[1];
342    currentPrimes = LL[2];
343    if (printTimings==1) {"Number of lucky primes: ", size(currentPrimes);}
344
345    //-------------------  Now all leading ideals are the same  --------------------
346    //-------------------  Lift results to basering via farey  ---------------------
347    N = currentPrimes[1];
348    for(i = 2; i <= size(currentPrimes); i++)
349    {
350      N = N*currentPrimes[i];
351    }
352    // Chinese remainder
353    ChremLift = chinrem(resultNormal,currentPrimes);
354    // Farey lifting
355    Out = farey(ChremLift,N);
356
357    OutCondu=Out,condu;
358    // pTest
359    if (pTestNormal(I,OutCondu,lastPrime,normalIP)==0)
360    {
361      if (printTimings==1) {"pTestNormal has failed, increasing the number of primes by "+string(n2);}
362      k=k+1;
363    } else
364    {
365       ptn=1;
366    }
367  }
368  if (printTimings==1)
369  {
370      "Time for all modular computations: "+string(sumTotalModularTime);
371      "Parallel time for all modular computations: "+string(sumMaxModularTime);
372      "Time for randomized normal: "+string(timer - totalTime);
373      "Simulated parallel time for randomized normal: "+string(timer - totalTime + sumMaxModularTime - sumTotalModularTime);
374  }
375  // return the result if no verification
376  if (noVerif==1) {
377      Out[size(Out) + 1] = Out[1];
378      Out = Out[2..size(Out)];
379      OutCondu=modStd(Out),condu;
380      return(OutCondu);
381   };
382
383//------------------- Optional tests to ensure correctness --------------------
384  // Check for finiteness. We do this by checking if the reconstruction of
385  // the ring structure is still valid
386
387  t = timer;
388  int tVerif=timer;
389  if (printTimings==1) {"Verification:";}
390  setring R;
391
392  int isNormal = normalCheck(Out, I,printTimings);
393
394
395  if(isNormal == 0)
396  {
397    ERROR("Not normal!");
398  } else {
399    if (printTimings==1) {"Normal!";}
400  }
401
402
403  if (printTimings==1)
404  {
405     "Time for verifying normal: "+string(timer - t);
406     "Time for all verification tests: "+string(timer - tVerif);
407     "Simulated parallel time including verfications: "+string(timer - totalTime + sumMaxModularTime - sumTotalModularTime);
408     "Total time: "+string(timer - totalTime);
409  }
410  // We put the denominator at the end
411  // however we return condu anyway
412  Out[size(Out) + 1] = Out[1];
413  Out = Out[2..size(Out)];
414  OutCondu=modStd(Out),condu;
415  return(OutCondu);
416}
417
418example
419{ "EXAMPLE:";
420ring R = 0,(x,y,z),dp;
421int k = 4;
422poly f = (x^(k+1)+y^(k+1)+z^(k+1))^2-4*(x^(k+1)*y^(k+1)+y^(k+1)*z^(k+1)+z^(k+1)*x^(k+1));
423f = subst(f,z,3x-2y+1);
424ring S = 0,(x,y),dp;
425poly f = imap(R,f);
426ideal i = f;
427list L = modNormal(i,1,"noVerification");
428}
429
430
431// Computes the Jacobian ideal
432// I is assumed to be a groebner base
433static proc jacobIdOne(ideal I,int printTimings)
434{
435  def R = basering;
436
437  int d = dim(I);
438
439  if (printTimings==1) {"Computing the ideal of minors...";}
440  ideal J = minor(jacob(I), nvars(basering) - d, I);
441  if (printTimings==1) {"Computing the modstd of the ideal of minors...";}
442  J = modStd(J);
443  if (printTimings==1)
444  {
445       "Groebner base computed.";
446       "ideal of minors: "; J;
447  }
448  return(J);
449}
450
451// Procedure for comparing timings and outputs between the modular approach
452// and the classical approach. Remove static to be used.
453static proc norComp(ideal I, int nPrimes)
454{
455  // nPrimes is the number of primes to use.
456
457  int t = timer;
458  list Out2 = modNormal(I, nPrimes,"noVerification");
459  "Time modNormal: ", timer - t;
460  t = timer;
461  ideal Out1 = normal(I)[2][1];
462  "Time normal: ", timer - t;
463  "Same output?";
464  outComp(Out1, Out2[1], Out1[size(Out1)], Out2[2], I);
465}
466
467static proc outComp(ideal Out1, ideal Out2, poly den1, poly den2, ideal I)
468{
469  I = groebner(I);
470  Out1 = changeDenominator(Out1, den1, den1, I);
471  Out2 = changeDenominator(Out2, den2, den1, I);
472  Out1 = groebner(I+Out1);
473  Out2 = groebner(I+Out2);
474  return((size(reduce(Out1, Out2)) == 0) * (size(reduce(Out2, Out1)) == 0));
475}
476
477
478// Make p homogeneous of degree d taking h as the aux variable of deg 1.
479static proc polyHomogenize(poly p, int d, intvec degs, poly h)
480{
481  int i;
482  poly q;
483  for(i = 1; i <= size(p); i++)
484  {
485    q = q + p[i]*h^(d-deg(p[i], degs));
486  }
487  return(q);
488}
489
490
491// verification procedure
492static proc normalCheck(ideal U, ideal I,int printTimings)
493// U / U[1] = output of the normalization
494{
495  if (printTimings==1) {"normalCheck: computes the new ring structure and checks if the ring is normal";}
496
497  def R = basering;
498  poly D = U[1];  // universal denominator
499
500  if (printTimings==1) {"Computing the new ring structure";}
501  list ele = Normal::computeRing(U, I, "noRed");
502
503  def origEre = ele[1];
504  setring origEre;
505  if (printTimings==1) {"Number of variables: ", nvars(basering);}
506
507  if (printTimings==1) {"Computing the groebner base of the relations...";}
508  norid = modStd(norid);
509
510  if (printTimings==1) {"Computing the jacobian ideal...";}
511  ideal J = jacobIdOne(norid,printTimings);
512  ideal JI = J + norid;
513  if (printTimings==1) {"Computing the radical...";}
514  ideal JR = radical(JI);
515  poly testP = getSmallest(JR);   // Choses the polynomial of smallest degree
516
517  qring Q = norid;
518  ideal J = fetch(origEre, JR);
519  poly D = fetch(origEre, testP);
520  if (printTimings==1) {"Computing the quotient (DJ : J)...";}
521  ideal oldU = 1;
522  ideal U = quotient(D*J, J);
523  U = groebner(U);
524
525  // ----------------- Grauer-Remmert criterion check -----------------------
526  // We check if the equality in Grauert - Remmert criterion is satisfied.
527  int isNormal = Normal::checkInclusions(D*oldU, U);
528  setring R;
529  return(isNormal);
530}
531
532///////////////////////////////////////////////////////////////////////////
533//
534//                            EXAMPLES
535//
536///////////////////////////////////////////////////////////////////////////
537/*
538// plane curves
539
540ring r24 = 0,(x,y,z),dp;
541int k = 2;
542poly f = (x^(k+1)+y^(k+1)+z^(k+1))^2-4*(x^(k+1)*y^(k+1)+y^(k+1)*z^(k+1)+z^(k+1)*x^(k+1));
543f = subst(f,z,2x-y+1);
544ring s24 = 0,(x,y),dp;
545poly f = imap(r24,f);
546ideal i = f;
547
548//locNormal(i);
549modNormal(i,1);
550
551
552ring r24 = 0,(x,y,z),dp;
553int k = 3;
554poly f = (x^(k+1)+y^(k+1)+z^(k+1))^2-4*(x^(k+1)*y^(k+1)+y^(k+1)*z^(k+1)+z^(k+1)*x^(k+1));
555f = subst(f,z,2x-y+1);
556ring s24 = 0,(x,y),dp;
557poly f = imap(r24,f);
558ideal i = f;
559
560//locNormal(i);
561modNormal(i,1,"noVerification");
562
563
564ring r24 = 0,(x,y,z),dp;
565int k = 4;
566poly f = (x^(k+1)+y^(k+1)+z^(k+1))^2-4*(x^(k+1)*y^(k+1)+y^(k+1)*z^(k+1)+z^(k+1)*x^(k+1));
567f = subst(f,z,2x-y+1);
568ring s24 = 0,(x,y),dp;
569poly f = imap(r24,f);
570ideal i = f;
571
572//locNormal(i);
573modNormal(i,1,"noVerification");
574
575
576ring r24 = 0,(x,y,z),dp;
577int k = 5;
578poly f = (x^(k+1)+y^(k+1)+z^(k+1))^2-4*(x^(k+1)*y^(k+1)+y^(k+1)*z^(k+1)+z^(k+1)*x^(k+1));
579f = subst(f,z,2x-y+1);
580ring s24 = 0,(x,y),dp;
581poly f = imap(r24,f);
582ideal i = f;
583
584//locNormal(i);
585modNormal(i,1);
586
587
588ring s24 = 0,(x,y),dp;
589int a=7;
590ideal i = ((x-1)^a-y^3)*((x+1)^a-y^3)*((x)^a-y^3)*((x-2)^a-y^3)*((x+2)^a-y^3)+y^15;
591
592//locNormal(i);
593modNormal(i,1);
594
595
596ring s24 = 0,(x,y),dp;
597int a=8;
598ideal i = ((x-1)^a-y^3)*((x+1)^a-y^3)*((x)^a-y^3)*((x-2)^a-y^3)*((x+2)^a-y^3)+y^15;
599
600//locNormal(i);
601modNormal(i,1);
602
603ring s24 = 0,(x,y),dp;
604int a=9;
605ideal i = ((x-1)^a-y^3)*((x+1)^a-y^3)*((x)^a-y^3)*((x-2)^a-y^3)*((x+2)^a-y^3)+y^15;
606
607//locNormal(i);
608modNormal(i,1,"noVerification");
609
610
611
612
613ring r=0,(x,y),dp;
614ideal i=9127158539954x10+3212722859346x8y2+228715574724x6y4-34263110700x4y6
615-5431439286x2y8-201803238y10-134266087241x8-15052058268x6y2+12024807786x4y4
616+506101284x2y6-202172841y8+761328152x6-128361096x4y2+47970216x2y4-6697080y6
617-2042158x4+660492x2y2-84366y4+2494x2-474y2-1;
618
619//locNormal(i);
620modNormal(i,1);
621
622
623// surfaces in A3
624
625
626ring r7 = 0,(x,y,t),dp;
627int a=11;
628ideal i = x*y*(x-y)*(x+y)*(y-1)*t+(x^a-y^2)*(x^10-(y-1)^2);
629//locNormal(i);
630modNormal(i,1,"noVerification");
631
632ring r7 = 0,(x,y,t),dp;
633int a=12;
634ideal i = x*y*(x-y)*(x+y)*(y-1)*t+(x^a-y^2)*(x^10-(y-1)^2);
635//locNormal(i);
636modNormal(i,1,"noVerification");
637
638
639ring r7 = 0,(x,y,t),dp;
640int a=13;
641ideal i = x*y*(x-y)*(x+y)*(y-1)*t+(x^a-y^2)*(x^10-(y-1)^2);
642
643//locNormal(i);
644modNormal(i,1,"noVerification");
645
646
647ring r22 = 0,(x,y,z),dp;
648ideal i = z2-(y2-1234x3)^2*(15791x2-y3)*(1231y2-x2*(x+158))*(1357y5-3x11);
649
650//locNormal(i);
651modNormal(i,1,"noVerification");
652
653
654ring r22 = 0,(x,y,z),dp;
655ideal i = z2-(y2-1234x3)^3*(15791x2-y3)*(1231y2-x2*(x+158))*(1357y5-3x11);
656
657//locNormal(i);
658modNormal(i,1,"noVerification");
659
660
661ring r23 = 0,(x,y,z),dp;
662ideal i = z5-((13x-17y)*(5x2-7y3)*(3x3-2y2)*(19y2-23x2*(x+29)))^2;
663
664//locNormal(i);
665modNormal(i,1,"noVerification");
666
667
668// curve in A3
669
670ring r23 = 0,(x,y,z),dp;
671ideal i = z3-(19y2-23x2*(x+29))^2,x3-(11y2-13z2*(z+1));
672
673//locNormal(i);
674modNormal(i,1,"noVerification");
675
676
677ring r23 = 0,(x,y,z),dp;
678ideal i = z3-(19y2-23x2*(x+29))^2,x3-(11y2-13z2*(z+1))^2;
679
680//locNormal(i);
681modNormal(i,1,"noVerification");
682
683// surface in A4
684
685ring r23 = 0,(x,y,z,w),dp;
686ideal i = z2-(y3-123456w2)*(15791x2-y3)^2, w*z-(1231y2-x*(111x+158));
687
688
689//locNormal(i);
690modNormal(i,1,"noVerification");
691
692*/
693
694
Note: See TracBrowser for help on using the repository browser.