source: git/Singular/LIB/modnormal.lib @ 4f3359

spielwiese
Last change on this file since 4f3359 was 4f3359, checked in by Hans Schoenemann <hannes@…>, 10 years ago
add data types to procedures, p2
  • Property mode set to 100644
File size: 19.0 KB
Line 
1//////////////////////////////////////////////////////////////////////////////
2version="version modnormal.lib 4.0.0.0 Dec_2013 "; // $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,int 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, 0, ncores);
317      for(j = (k-1)*n2+1+sh; j <= k*n2+1; j++)
318      {
319        resultNormalX[j] = modresults[j-(k-1)*n2-sh][1];
320        currentPrimesX[j] = bigint(modresults[j-(k-1)*n2-sh][2]);
321        LTimer[j] = modresults[j-(k-1)*n2-sh][3];
322        if(LTimer[j] > maxModularTime) { maxModularTime = LTimer[j]; }
323      }
324      normalIP = resultNormalX[k*n2+1];
325      lastPrime = modresults[n2-sh+1][2];
326    }
327
328    if (printTimings==1) {"List of times for all modular computations so far: "+string(LTimer);}
329    if (printTimings==1) {"Maximal modular time of current step: "+string(maxModularTime);}
330    sumMaxModularTime=sumMaxModularTime+maxModularTime;
331    totalModularTime = timer - totalModularTime;
332    sumTotalModularTime=sumTotalModularTime+totalModularTime;
333    if (printTimings==1) {"Total modular time of current step: "+string(totalModularTime);}
334    resultNormal=delete(resultNormalX,size(resultNormalX));
335    currentPrimes=delete(currentPrimesX,size(currentPrimesX));
336    //------------------------  Delete unlucky primes  -----------------------------
337    //-------------  unlucky if and only if the leading ideal is wrong  ------------
338    // Polynomials are not homogeneous: h = 0
339    LL = deleteUnluckyPrimes(resultNormal,currentPrimes,h);
340    resultNormal = LL[1];
341    currentPrimes = LL[2];
342    if (printTimings==1) {"Number of lucky primes: ", size(currentPrimes);}
343
344    //-------------------  Now all leading ideals are the same  --------------------
345    //-------------------  Lift results to basering via farey  ---------------------
346    N = currentPrimes[1];
347    for(i = 2; i <= size(currentPrimes); i++)
348    {
349      N = N*currentPrimes[i];
350    }
351    // Chinese remainder
352    ChremLift = chinrem(resultNormal,currentPrimes);
353    // Farey lifting
354    Out = farey(ChremLift,N);
355
356    OutCondu=Out,condu;
357    // pTest
358    if (pTestNormal(I,OutCondu,lastPrime,normalIP)==0)
359    {
360      if (printTimings==1) {"pTestNormal has failed, increasing the number of primes by "+string(n2);}
361      k=k+1;
362    } else
363    {
364       ptn=1;
365    }
366  }
367  if (printTimings==1)
368  {
369      "Time for all modular computations: "+string(sumTotalModularTime);
370      "Parallel time for all modular computations: "+string(sumMaxModularTime);
371      "Time for randomized normal: "+string(timer - totalTime);
372      "Simulated parallel time for randomized normal: "+string(timer - totalTime + sumMaxModularTime - sumTotalModularTime);
373  }
374  // return the result if no verification
375  if (noVerif==1) {
376      Out[size(Out) + 1] = Out[1];
377      Out = Out[2..size(Out)];
378      OutCondu=modStd(Out),condu;
379      return(OutCondu);
380   };
381
382//------------------- Optional tests to ensure correctness --------------------
383  // Check for finiteness. We do this by checking if the reconstruction of
384  // the ring structure is still valid
385
386  t = timer;
387  int tVerif=timer;
388  if (printTimings==1) {"Verification:";}
389  setring R;
390
391  int isNormal = normalCheck(Out, I,printTimings);
392
393
394  if(isNormal == 0)
395  {
396    ERROR("Not normal!");
397  } else {
398    if (printTimings==1) {"Normal!";}
399  }
400
401
402  if (printTimings==1)
403  {
404     "Time for verifying normal: "+string(timer - t);
405     "Time for all verification tests: "+string(timer - tVerif);
406     "Simulated parallel time including verfications: "+string(timer - totalTime + sumMaxModularTime - sumTotalModularTime);
407     "Total time: "+string(timer - totalTime);
408  }
409  // We put the denominator at the end
410  // however we return condu anyway
411  Out[size(Out) + 1] = Out[1];
412  Out = Out[2..size(Out)];
413  OutCondu=modStd(Out),condu;
414  return(OutCondu);
415}
416
417example
418{ "EXAMPLE:";
419ring R = 0,(x,y,z),dp;
420int k = 4;
421poly 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));
422f = subst(f,z,3x-2y+1);
423ring S = 0,(x,y),dp;
424poly f = imap(R,f);
425ideal i = f;
426list L = modNormal(i,1,"noVerification");
427}
428
429
430// Computes the Jacobian ideal
431// I is assumed to be a groebner base
432static proc jacobIdOne(ideal I,int printTimings)
433{
434  def R = basering;
435
436  int d = dim(I);
437
438  if (printTimings==1) {"Computing the ideal of minors...";}
439  ideal J = minor(jacob(I), nvars(basering) - d, I);
440  if (printTimings==1) {"Computing the modstd of the ideal of minors...";}
441  J = modStd(J);
442  if (printTimings==1)
443  {
444       "Groebner base computed.";
445       "ideal of minors: "; J;
446  }
447  return(J);
448}
449
450// Procedure for comparing timings and outputs between the modular approach
451// and the classical approach. Remove static to be used.
452static proc norComp(ideal I, int nPrimes)
453{
454  // nPrimes is the number of primes to use.
455
456  int t = timer;
457  list Out2 = modNormal(I, nPrimes,"noVerification");
458  "Time modNormal: ", timer - t;
459  t = timer;
460  ideal Out1 = normal(I)[2][1];
461  "Time normal: ", timer - t;
462  "Same output?";
463  outComp(Out1, Out2[1], Out1[size(Out1)], Out2[2], I);
464}
465
466static proc outComp(ideal Out1, ideal Out2, poly den1, poly den2, ideal I)
467{
468  I = groebner(I);
469  Out1 = changeDenominator(Out1, den1, den1, I);
470  Out2 = changeDenominator(Out2, den2, den1, I);
471  Out1 = groebner(I+Out1);
472  Out2 = groebner(I+Out2);
473  return((size(reduce(Out1, Out2)) == 0) * (size(reduce(Out2, Out1)) == 0));
474}
475
476
477// Make p homogeneous of degree d taking h as the aux variable of deg 1.
478static proc polyHomogenize(poly p, int d, intvec degs, poly h)
479{
480  int i;
481  poly q;
482  for(i = 1; i <= size(p); i++)
483  {
484    q = q + p[i]*h^(d-deg(p[i], degs));
485  }
486  return(q);
487}
488
489
490// verification procedure
491static proc normalCheck(ideal U, ideal I,int printTimings)
492// U / U[1] = output of the normalization
493{
494  if (printTimings==1) {"normalCheck: computes the new ring structure and checks if the ring is normal";}
495
496  def R = basering;
497  poly D = U[1];  // universal denominator
498
499  if (printTimings==1) {"Computing the new ring structure";}
500  list ele = Normal::computeRing(U, I, "noRed");
501
502  def origEre = ele[1];
503  setring origEre;
504  if (printTimings==1) {"Number of variables: ", nvars(basering);}
505
506  if (printTimings==1) {"Computing the groebner base of the relations...";}
507  norid = modStd(norid);
508
509  if (printTimings==1) {"Computing the jacobian ideal...";}
510  ideal J = jacobIdOne(norid,printTimings);
511  ideal JI = J + norid;
512  if (printTimings==1) {"Computing the radical...";}
513  ideal JR = radical(JI);
514  poly testP = getSmallest(JR);   // Choses the polynomial of smallest degree
515
516  qring Q = norid;
517  ideal J = fetch(origEre, JR);
518  poly D = fetch(origEre, testP);
519  if (printTimings==1) {"Computing the quotient (DJ : J)...";}
520  ideal oldU = 1;
521  ideal U = quotient(D*J, J);
522  U = groebner(U);
523
524  // ----------------- Grauer-Remmert criterion check -----------------------
525  // We check if the equality in Grauert - Remmert criterion is satisfied.
526  int isNormal = Normal::checkInclusions(D*oldU, U);
527  setring R;
528  return(isNormal);
529}
530
531///////////////////////////////////////////////////////////////////////////
532//
533//                            EXAMPLES
534//
535///////////////////////////////////////////////////////////////////////////
536/*
537// plane curves
538
539ring r24 = 0,(x,y,z),dp;
540int k = 2;
541poly 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));
542f = subst(f,z,2x-y+1);
543ring s24 = 0,(x,y),dp;
544poly f = imap(r24,f);
545ideal i = f;
546
547//locNormal(i);
548modNormal(i,1);
549
550
551ring r24 = 0,(x,y,z),dp;
552int k = 3;
553poly 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));
554f = subst(f,z,2x-y+1);
555ring s24 = 0,(x,y),dp;
556poly f = imap(r24,f);
557ideal i = f;
558
559//locNormal(i);
560modNormal(i,1,"noVerification");
561
562
563ring r24 = 0,(x,y,z),dp;
564int k = 4;
565poly 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));
566f = subst(f,z,2x-y+1);
567ring s24 = 0,(x,y),dp;
568poly f = imap(r24,f);
569ideal i = f;
570
571//locNormal(i);
572modNormal(i,1,"noVerification");
573
574
575ring r24 = 0,(x,y,z),dp;
576int k = 5;
577poly 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));
578f = subst(f,z,2x-y+1);
579ring s24 = 0,(x,y),dp;
580poly f = imap(r24,f);
581ideal i = f;
582
583//locNormal(i);
584modNormal(i,1);
585
586
587ring s24 = 0,(x,y),dp;
588int a=7;
589ideal 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;
590
591//locNormal(i);
592modNormal(i,1);
593
594
595ring s24 = 0,(x,y),dp;
596int a=8;
597ideal 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;
598
599//locNormal(i);
600modNormal(i,1);
601
602ring s24 = 0,(x,y),dp;
603int a=9;
604ideal 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;
605
606//locNormal(i);
607modNormal(i,1,"noVerification");
608
609
610
611
612ring r=0,(x,y),dp;
613ideal i=9127158539954x10+3212722859346x8y2+228715574724x6y4-34263110700x4y6
614-5431439286x2y8-201803238y10-134266087241x8-15052058268x6y2+12024807786x4y4
615+506101284x2y6-202172841y8+761328152x6-128361096x4y2+47970216x2y4-6697080y6
616-2042158x4+660492x2y2-84366y4+2494x2-474y2-1;
617
618//locNormal(i);
619modNormal(i,1);
620
621
622// surfaces in A3
623
624
625ring r7 = 0,(x,y,t),dp;
626int a=11;
627ideal i = x*y*(x-y)*(x+y)*(y-1)*t+(x^a-y^2)*(x^10-(y-1)^2);
628//locNormal(i);
629modNormal(i,1,"noVerification");
630
631ring r7 = 0,(x,y,t),dp;
632int a=12;
633ideal i = x*y*(x-y)*(x+y)*(y-1)*t+(x^a-y^2)*(x^10-(y-1)^2);
634//locNormal(i);
635modNormal(i,1,"noVerification");
636
637
638ring r7 = 0,(x,y,t),dp;
639int a=13;
640ideal i = x*y*(x-y)*(x+y)*(y-1)*t+(x^a-y^2)*(x^10-(y-1)^2);
641
642//locNormal(i);
643modNormal(i,1,"noVerification");
644
645
646ring r22 = 0,(x,y,z),dp;
647ideal i = z2-(y2-1234x3)^2*(15791x2-y3)*(1231y2-x2*(x+158))*(1357y5-3x11);
648
649//locNormal(i);
650modNormal(i,1,"noVerification");
651
652
653ring r22 = 0,(x,y,z),dp;
654ideal i = z2-(y2-1234x3)^3*(15791x2-y3)*(1231y2-x2*(x+158))*(1357y5-3x11);
655
656//locNormal(i);
657modNormal(i,1,"noVerification");
658
659
660ring r23 = 0,(x,y,z),dp;
661ideal i = z5-((13x-17y)*(5x2-7y3)*(3x3-2y2)*(19y2-23x2*(x+29)))^2;
662
663//locNormal(i);
664modNormal(i,1,"noVerification");
665
666
667// curve in A3
668
669ring r23 = 0,(x,y,z),dp;
670ideal i = z3-(19y2-23x2*(x+29))^2,x3-(11y2-13z2*(z+1));
671
672//locNormal(i);
673modNormal(i,1,"noVerification");
674
675
676ring r23 = 0,(x,y,z),dp;
677ideal i = z3-(19y2-23x2*(x+29))^2,x3-(11y2-13z2*(z+1))^2;
678
679//locNormal(i);
680modNormal(i,1,"noVerification");
681
682// surface in A4
683
684ring r23 = 0,(x,y,z,w),dp;
685ideal i = z2-(y3-123456w2)*(15791x2-y3)^2, w*z-(1231y2-x*(111x+158));
686
687
688//locNormal(i);
689modNormal(i,1,"noVerification");
690
691*/
692
693
Note: See TracBrowser for help on using the repository browser.