source: git/Singular/longalg.cc @ 470c7c

spielwiese
Last change on this file since 470c7c was 470c7c, checked in by Olaf Bachmann <obachman@…>, 23 years ago
bug fix git-svn-id: file:///usr/local/Singular/svn/trunk@4747 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 46.8 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: longalg.cc,v 1.49 2000-11-20 17:29:45 obachman Exp $ */
5/*
6* ABSTRACT:   algebraic numbers
7*/
8
9#include <stdio.h>
10#include <string.h>
11#include "mod2.h"
12#include "structs.h"
13#include "tok.h"
14#include "omalloc.h"
15#include "febase.h"
16#include "longrat.h"
17#include "modulop.h"
18#include "numbers.h"
19#include "polys.h"
20#include "ideals.h"
21#include "ipid.h"
22#include "ring.h"
23#ifdef HAVE_FACTORY
24#include "clapsing.h"
25#endif
26#include "longalg.h"
27
28#define  FEHLER1 1
29#define  FEHLER2 1
30#define  FEHLER3 1
31
32naIdeal naI=NULL;
33
34//#define RECA_SIZE (sizeof(alg)+sizeof(number))
35alg naMinimalPoly;
36int naNumbOfPar;
37int napMonomSize;
38char **naParNames;
39static int naIsChar0;
40static int naPrimeM;
41
42#ifdef LDEBUG
43#define naTest(a) naDBTest(a,__FILE__,__LINE__)
44BOOLEAN naDBTest(number a, char *f,int l);
45#else
46#define naTest(a)
47#endif
48
49number (*naMap)(number from);
50/* procedure variables */
51static numberfunc
52                nacMult, nacSub, nacAdd, nacDiv, nacIntDiv, nacGcd, nacLcm;
53#ifdef LDEBUG
54static void     (*nacDBDelete)(number *a,char *f,int l);
55#define         nacDelete(A) nacDBDelete(A,__FILE__,__LINE__)
56#else
57static void     (*nacDelete)(number *a);
58#endif
59       number   (*nacInit)(int i);
60static int      (*nacInt)(number &n);
61       void     (*nacNormalize)(number &a);
62static number   (*nacNeg)(number a);
63static void     (*nacWrite)(number &a);
64       number   (*nacCopy)(number a);
65static number   (*nacInvers)(number a);
66       BOOLEAN  (*nacIsZero)(number a);
67static BOOLEAN  (*nacIsOne)(number a);
68static BOOLEAN  (*nacIsMOne)(number a);
69static BOOLEAN  (*nacGreaterZero)(number a);
70static char   * (*nacRead) (char *s, number *a);
71extern void     napDelete(alg *p);
72static alg napRedp(alg q);
73static alg napTailred(alg q);
74static BOOLEAN napDivPoly(alg p, alg q);
75static int napExpi(int i, alg a, alg b);
76
77static number nadGcd( number a, number b) { return nacInit(1); }
78/*2
79*  sets the appropriate operators
80*/
81void naSetChar(int i, BOOLEAN complete, ring r)
82{
83  if (naI!=NULL)
84  {
85    int j;
86    for (j=naI->anz-1; j>=0; j--)
87       napDelete (&naI->liste[j]);
88    omFreeSize((ADDRESS)naI->liste,naI->anz*sizeof(alg));
89    omFreeBin((ADDRESS)naI, snaIdeal_bin);
90    naI=NULL;
91  }
92  naMap = naCopy;
93  naMinimalPoly = NULL;
94  naParNames=r->parameter;
95  naNumbOfPar=rPar(r);
96  napMonomSize = RECA_SIZE + naNumbOfPar*SIZEOF_PARAMETER;
97  if (i == 1)
98  {
99    naIsChar0 = 1;
100#ifdef LDEBUG
101    nacDBDelete      = nlDBDelete;
102#else
103    nacDelete      = nlDelete;
104#endif
105    if (complete)
106    {
107      nacInit        = nlInit;
108      nacInt         = nlInt;
109      nacCopy        = nlCopy;
110      nacAdd         = nlAdd;
111      nacSub         = nlSub;
112      nacMult        = nlMult;
113      nacDiv         = nlDiv;
114      nacIntDiv      = nlIntDiv;
115      nacInvers      = nlInvers;
116      nacNormalize   = nlNormalize;
117      nacNeg         = nlNeg;
118      nacIsZero      = nlIsZero;
119      nacRead        = nlRead;
120      nacWrite       = nlWrite;
121      nacGreaterZero = nlGreaterZero;
122      nacIsOne       = nlIsOne;
123      nacIsMOne      = nlIsMOne;
124      nacGcd         = nlGcd;
125      nacLcm         = nlLcm;
126    }
127  }
128  else if (i < 0)
129  {
130    naIsChar0 = 0;
131#ifdef LDEBUG
132    nacDBDelete    = nDBDummy1;
133#else
134    nacDelete      = nDummy1;
135#endif
136    if (complete)
137    {
138      npSetChar(-i, r->algring); // to be changes HS
139      nacInit        = npInit;
140      nacInt         = npInt;
141      nacCopy        = ndCopy;
142      nacAdd         = npAdd;
143      nacSub         = npSub;
144      nacMult        = npMult;
145      nacDiv         = npDiv;
146      nacIntDiv      = npDiv;
147      nacInvers      = npInvers;
148      nacNormalize   = nDummy2;
149      nacNeg         = npNeg;
150      nacIsZero      = npIsZero;
151      nacRead        = npRead;
152      nacWrite       = npWrite;
153      nacGreaterZero = npGreaterZero;
154      nacIsOne       = npIsOne;
155      nacIsMOne      = npIsMOne;
156      nacGcd         = nadGcd;
157      nacLcm         = nadGcd;
158    }
159  }
160#ifdef TEST
161  else
162  {
163    Print("naSetChar:c=%d compl=%d param=%d\n",i,complete,rPar(r));
164  }
165#endif
166}
167
168/*============= procedure for polynomials: napXXXX =======================*/
169
170#define napSetCoeff(p,n) {nacDelete(&((p)->ko));(p)->ko=n;}
171#define napIter(A) A=(A)->ne
172
173
174#ifdef LDEBUG
175static void napTest(alg p)
176{
177  while (p != NULL)
178  {
179    if (naIsChar0)
180      nlDBTest(p->ko, "", 0);
181    omCheckAddrSize(p, napMonomSize);
182    p = p->ne;
183  }
184}
185#else
186#define napTest(p) ((void) 0)
187#endif
188
189/*3
190* creates  an alg poly
191*/
192static alg napInit(int i)
193{
194  alg a = (alg)omAlloc0(napMonomSize);
195
196  a->ko = nacInit(i);
197  if (!nacIsZero(a->ko))
198  {
199    return a;
200  }
201  else
202  {
203    omFreeSize((ADDRESS)a, napMonomSize);
204    return NULL;
205  }
206}
207
208/*3
209* creates  an alg poly
210*/
211alg napInitz(number z)
212{
213  alg a = (alg)omAlloc0(napMonomSize);
214
215  a->ko = z;
216  return a;
217}
218
219/*3
220*  deletes head of  an alg poly
221*/
222static void napDelete1(alg *p)
223{
224  alg h = *p;
225
226  if (h!=NULL)
227  {
228    *p = h->ne;
229    nacDelete(&(h->ko));
230    omFreeSize((ADDRESS)h, napMonomSize);
231  }
232}
233
234/*3
235*  delete an alg poly
236*/
237void napDelete(alg *p)
238{
239  alg w, h = *p;
240
241  while (h!=NULL)
242  {
243    w = h;
244    h = h->ne;
245    nacDelete(&(w->ko));
246    omFreeSize((ADDRESS)w, napMonomSize);
247  }
248  *p = NULL;
249}
250
251
252/*3
253* copy a alg. poly
254*/
255static alg napCopy(alg p)
256{
257  if (p==NULL) return NULL;
258
259  alg w, a;
260
261  omCheckAddrSize(p,napMonomSize);
262  a = w = (alg)omAlloc(napMonomSize);
263  memcpy(w->e, p->e, naNumbOfPar * SIZEOF_PARAMETER);
264  w->ko = nacCopy(p->ko);
265  loop
266  {
267    p=p->ne;
268    if (p==NULL) break;
269    omCheckAddrSize(p,napMonomSize);
270    a->ne = (alg)omAlloc(napMonomSize);
271    a = a->ne;
272    memcpy(a->e, p->e, naNumbOfPar * SIZEOF_PARAMETER);
273    a->ko = nacCopy(p->ko);
274  }
275  a->ne = NULL;
276  return w;
277}
278
279/*3
280* copy a alg. poly
281*/
282static alg napCopyNeg(alg p)
283{
284  alg w, a;
285
286  if (p==NULL) return NULL;
287  omCheckAddrSize(p,napMonomSize);
288  a = w = (alg)omAlloc(napMonomSize);
289  memcpy(w->e, p->e, naNumbOfPar * SIZEOF_PARAMETER);
290  w->ko = nacNeg(nacCopy(p->ko));
291  loop
292  {
293    p=p->ne;
294    if (p==NULL) break;
295    omCheckAddrSize(p,napMonomSize);
296    a->ne = (alg)omAlloc(napMonomSize);
297    a = a->ne;
298    memcpy(a->e, p->e, naNumbOfPar * SIZEOF_PARAMETER);
299    a->ko = nacNeg(nacCopy(p->ko));
300  }
301  a->ne = NULL;
302  return w;
303}
304
305/*3
306* Compare exponents of p and q
307*/
308static int  napComp(alg p, alg q)
309{
310  int  i = 0;
311
312  omCheckAddrSize(p,napMonomSize);
313  omCheckAddrSize(q,napMonomSize);
314  while (p->e[i] == q->e[i])
315  {
316    i++;
317    if (i >= naNumbOfPar)
318      return 0;
319  }
320  if (p->e[i]  >  q->e[i])
321    return 1;
322  else
323    return - 1;
324}
325
326/*3
327*  addition of alg. polys
328*/
329alg napAdd(alg p1, alg p2)
330{
331  alg a1, p, a2, a;
332  int  c;  number t;
333
334  if (p1==NULL) return p2;
335  if (p2==NULL) return p1;
336  omCheckAddrSize(p1,napMonomSize);
337  omCheckAddrSize(p2,napMonomSize);
338  a1 = p1;
339  a2 = p2;
340  a = p  = (alg)omAlloc(napMonomSize);
341  loop
342  {
343    c = napComp(a1, a2);
344    if (c == 1)
345    {
346      a = a->ne = a1;
347      a1 = a1->ne;
348      if (a1==NULL)
349      {
350        a->ne= a2;
351        break;
352      }
353      omCheckAddrSize(a1,napMonomSize);
354    }
355    else if (c == -1)
356    {
357      a = a->ne = a2;
358      a2 = a2->ne;
359      if (a2==NULL)
360      {
361        a->ne = a1;
362        break;
363      }
364      omCheckAddrSize(a2,napMonomSize);
365    }
366    else
367    {
368      t = nacAdd(a1->ko, a2->ko);
369      napDelete1(&a2);
370      if (nacIsZero(t))
371      {
372        nacDelete(&t);
373        napDelete1(&a1);
374      }
375      else
376      {
377        nacDelete(&(a1->ko));
378        a1->ko = t;
379        a = a->ne = a1;
380        a1 = a1->ne;
381      }
382      if (a1==NULL)
383      {
384        a->ne = a2;
385        break;
386      }
387      else if (a2==NULL)
388      {
389        a->ne = a1;
390        break;
391      }
392      omCheckAddrSize(a1,napMonomSize);
393      omCheckAddrSize(a2,napMonomSize);
394    }
395  }
396  a = p->ne;
397  omFreeSize((ADDRESS)p, napMonomSize);
398  return a;
399}
400
401
402/*3
403* multiply a alg. poly by -1
404*/
405static alg napNeg(alg a)
406{
407  alg p = a;
408
409  while (p!=NULL)
410  {
411    omCheckAddrSize(p,napMonomSize);
412    p->ko = nacNeg(p->ko);
413    p = p->ne;
414  }
415  return a;
416}
417
418/*3
419* returns ph * z
420*/
421static void napMultN(alg p, number z)
422{
423  number t;
424
425  while (p!=NULL)
426  {
427    omCheckAddrSize(p,napMonomSize);
428    t = nacMult(p->ko, z);
429    nacNormalize(t);
430    nacDelete(&p->ko);
431    p->ko = t;
432    p = p->ne;
433  }
434}
435
436/*3
437* update the polynomial a by multipying it by
438* the (number) coefficient
439* and the exponent vector (of) exp (a well initialized polynomial)
440*/
441static void napMultT(alg a, alg exp)
442{
443  int  i;
444  number t, h;
445  if (a==NULL)
446    return;
447  h = exp->ko;
448  if (nacIsOne(h))
449  {
450    do
451    {
452      for (i = naNumbOfPar - 1; i >= 0; i--)
453        a->e[i] += exp->e[i];
454      a = a->ne;
455    }
456    while (a!=NULL);
457  }
458  else
459  {
460    h = nacNeg(h);
461    if (nacIsOne(h))
462    {
463      h = nacNeg(h);
464      do
465      {
466        a->ko = nacNeg(a->ko);
467        for (i = naNumbOfPar - 1; i >= 0; i--)
468          a->e[i] += exp->e[i];
469        a = a->ne;
470      }
471      while (a!=NULL);
472    }
473    else
474    {
475      h = nacNeg(h);
476      do
477      {
478        t = nacMult(a->ko, h);
479        nacDelete(&(a->ko));
480        a->ko = t;
481        for (i = naNumbOfPar - 1; i >= 0; i--)
482          a->e[i] += exp->e[i];
483        a = a->ne;
484      }
485      while (a!=NULL);
486    }
487    // need to do this, since nacNeg might have changed h
488    exp->ko = h;
489  }
490}
491
492/*3
493* multiplication of alg. polys
494* multiply p1 with p2, p1 and p2 are destroyed
495*/
496static alg napMult(alg p1, alg p2)
497{
498  alg a1, a2, b, h;
499  if (p1==NULL)
500  {
501    napDelete(&p2);
502    return NULL;
503  }
504  if (p2==NULL)
505  {
506    napDelete(&p1);
507    return NULL;
508  }
509  b = NULL;
510  a1 = p1;
511  a2 = p2;
512  if (a2->ne!=NULL)
513  {
514    if (a1->ne!=NULL)
515    {
516      do
517      {
518        a1 = a1->ne;
519        a2 = a2->ne;
520      }
521      while ((a1!=NULL) && (a2!=NULL));
522      if (a1!=NULL)
523      {
524        a1 = p1;
525        a2 = p2;
526      }
527      else
528      {
529        a1 = p2;
530        a2 = p1;
531      }
532      do
533      {
534        if (a2->ne!=NULL)
535          h = napCopy(a1);
536        else
537          h = a1;
538        napMultT(h, a2);
539        b = napAdd(h, b);
540        napDelete1(&a2);
541      }
542      while (a2!=NULL);
543    }
544    else
545    {
546      napMultT(a2, a1);
547      b = napAdd(a2, b);
548      napDelete1(&a1);
549    }
550  }
551  else
552  {
553    napMultT(a1, a2);
554    b = napAdd(a1, b);
555    napDelete1(&a2);
556  }
557  return b;
558}
559
560/*3
561*  division with rest; f = g*q + r, returns r and destroy f
562*/
563static alg napRemainder(alg f, const alg  g)
564{
565  alg a, h, qq;
566
567  qq = (alg)omAlloc(napMonomSize);
568  qq->ne = NULL;
569  a = f;
570  do
571  {
572    omCheckAddrSize(a,napMonomSize);
573    omCheckAddrSize(g,napMonomSize);
574    qq->e[0] = a->e[0] - g->e[0];
575    qq->ko = nacDiv(a->ko, g->ko);
576    qq->ko = nacNeg(qq->ko);
577    h = napCopy(g);
578    napMultT(h, qq);
579    nacDelete(&(qq->ko));
580    a = napAdd(a, h);
581  }
582  while ((a!=NULL) && (a->e[0] >= g->e[0]));
583  omFreeSize((ADDRESS)qq, napMonomSize);
584  return a;
585}
586
587/*3
588*  division with rest; f = g*q + r,  destroy f
589*/
590static void napDivMod(alg f, alg  g, alg *q, alg *r)
591{
592  alg a, h, b, qq;
593
594  qq = (alg)omAlloc(napMonomSize);
595  qq->ne = b = NULL;
596  a = f;
597  do
598  {
599    omCheckAddrSize(a,napMonomSize);
600    omCheckAddrSize(g,napMonomSize);
601    qq->e[0] = a->e[0] - g->e[0];
602    qq->ko = nacDiv(a->ko, g->ko);
603    b = napAdd(b, napCopy(qq));
604    qq->ko = nacNeg(qq->ko);
605    h = napCopy(g);
606    napMultT(h, qq);
607    nacDelete(&(qq->ko));
608    a = napAdd(a, h);
609  }
610  while ((a!=NULL) && (a->e[0] >= g->e[0]));
611  omFreeSize((ADDRESS)qq, napMonomSize);
612  *q = b;
613  *r = a;
614}
615
616/*3
617*  returns z with z*x mod c = 1
618*/
619static alg napInvers(alg x, const alg c)
620{
621  alg y, r, qa, qn, q;
622  number t, h;
623
624  if (x->e[0] >= c->e[0])
625    x = napRemainder(x, c);
626  if (x==NULL)
627  {
628    goto zero_divisor;
629  }
630  if (x->e[0]==0)
631  {
632    if (!nacIsOne(x->ko))
633    {
634      h = nacInit(1);
635      t = nacDiv(h, x->ko);
636      nacDelete(&(x->ko));
637      nacDelete(&h);
638      x->ko = t;
639    }
640    return x;
641  }
642  y = napCopy(c);
643  napDivMod(y, x, &qa, &r);
644  if (r==NULL)
645  {
646    goto zero_divisor;
647  }
648  if (r->e[0]==0)
649  {
650    h = nacInit(-1);
651    t = nacDiv(h, r->ko);
652    nacNormalize(t);
653    napMultN(qa, t);
654    nacDelete(&h);
655    nacDelete(&t);
656    napDelete(&x);
657    napDelete(&r);
658    return qa;
659  }
660  y = x;
661  x = r;
662  napDivMod(y, x, &q, &r);
663  if (r==NULL)
664  {
665    goto zero_divisor;
666  }
667  if (r->e[0]==0)
668  {
669    q = napMult(q, qa);
670    q = napAdd(q, napInit(1));
671    h = nacInit(1);
672    t = nacDiv(h, r->ko);
673    napMultN(q, t);
674    nacDelete(&h);
675    nacDelete(&t);
676    napDelete(&x);
677    napDelete(&r);
678    if (q->e[0] >= c->e[0])
679      q = napRemainder(q, c);
680    return q;
681  }
682  q = napMult(q, napCopy(qa));
683  q = napAdd(q, napInit(1));
684  qa = napNeg(qa);
685  loop
686  {
687    y = x;
688    x = r;
689    napDivMod(y, x, &qn, &r);
690    if (r==NULL)
691    {
692      break;
693    }
694    if (r->e[0]==0)
695    {
696      q = napMult(q, qn);
697      q = napNeg(q);
698      q = napAdd(q, qa);
699      h = nacInit(1);
700      t = nacDiv(h, r->ko);
701      napMultN(q, t);
702      nacDelete(&h);
703      nacDelete(&t);
704      napDelete(&x);
705      napDelete(&r);
706      if (q->e[0] >= c->e[0])
707        q = napRemainder(q, c);
708      return q;
709    }
710    y = q;
711    q = napMult(napCopy(q), qn);
712    q = napNeg(q);
713    q = napAdd(q, qa);
714    qa = y;
715  }
716// zero divisor found:
717zero_divisor:
718  Werror("zero divisor found - your minpoly is not irreducible");
719  return x;
720}
721
722/*3
723* the degree of an alg poly (used for test of "constant" et al.)
724*/
725static int  napDeg(alg p)
726{
727  int  d = 0, i;
728
729  omCheckAddrSize(p,napMonomSize);
730  for (i = naNumbOfPar-1; i>=0; i--)
731    d += p->e[i];
732  return d;
733}
734
735/*3
736* the max degree of an alg poly (used for test of "simple" et al.)
737*/
738static int  napMaxDeg(alg p)
739{
740  int  d = 0;
741  while(p!=NULL)
742  {
743    omCheckAddrSize(p,napMonomSize);
744    d=max(d,napDeg(p));
745    p=p->ne;
746  }
747  return d;
748}
749
750/*3
751* the max degree of an alg poly (used for test of "simple" et al.)
752*/
753static int  napMaxDegLen(alg p, int &l)
754{
755  int  d = 0;
756  int ll=0;
757  while(p!=NULL)
758  {
759    omCheckAddrSize(p,napMonomSize);
760    d=max(d,napDeg(p));
761    p=p->ne;
762    ll++;
763  }
764  l=ll;
765  return d;
766}
767
768
769/*3
770*writes a polynomial number
771*/
772void napWrite(alg p)
773{
774  if (p==NULL)
775    StringAppendS("0");
776  else if (napDeg(p)==0)
777  {
778    //StringAppendS("-1");
779    nacWrite(p->ko);
780  }
781  else
782  {
783    StringAppendS("(");
784    loop
785    {
786      BOOLEAN wroteCoeff=FALSE;
787      omCheckAddrSize(p,napMonomSize);
788      if ((napDeg(p)==0)
789      || ((!nacIsOne(p->ko))
790        && (!nacIsMOne(p->ko))))
791      {
792        nacWrite(p->ko);
793        wroteCoeff=(currRing->ShortOut==0);
794      }
795      else if (nacIsMOne(p->ko))
796      {
797        StringAppendS("-");
798      }
799      int  i;
800      for (i = 0; i <= naNumbOfPar - 1; i++)
801      {
802        if (p->e[i] > 0)
803        {
804          if (wroteCoeff)
805            StringAppendS("*");
806          else
807            wroteCoeff=(currRing->ShortOut==0);
808          StringAppendS(naParNames[i]);
809          if (p->e[i] > 1)
810          {
811            if (currRing->ShortOut == 0)
812              StringAppendS("^");
813            StringAppend("%d", p->e[i]);
814          }
815        }
816      }
817      p = p->ne;
818      if (p==NULL)
819        break;
820      if (nacGreaterZero(p->ko))
821        StringAppendS("+");
822    }
823    StringAppendS(")");
824  }
825}
826
827
828static char *napHandleMons(char *s, int i, PARAMETER_TYPE *ex)
829{
830  int  j;
831  if (strncmp(s,naParNames[i],strlen(naParNames[i]))==0)
832  {
833    s+=strlen(naParNames[i]);
834    if ((*s >= '0') && (*s <= '9'))
835    {
836      s = eati(s, &j);
837      ex[i] += j;
838    }
839    else
840      ex[i]++;
841  }
842  return s;
843}
844
845/*3  reads a monomial  */
846static char  *napRead(char *s, alg *b)
847{
848  alg a;
849  int  i;
850  a = (alg)omAlloc0(napMonomSize);
851  if ((*s >= '0') && (*s <= '9'))
852  {
853    s = nacRead(s, &(a->ko));
854    if (nacIsZero(a->ko))
855    {
856      napDelete1(&a);
857      *b = NULL;
858      return s;
859    }
860  }
861  else
862    a->ko = nacInit(1);
863  i = 0;
864  char  *olds;
865  loop
866  {
867    olds = s;
868    s = napHandleMons(s, i, a->e);
869    if (olds == s)
870      i++;
871    else
872      i = 0;
873    if ((*s == '\0') || (i >= naNumbOfPar))
874      break;
875  }
876  *b = a;
877  return s;
878}
879
880static int napExp(alg a, alg b)
881{
882  while (a->ne!=NULL) a = a->ne;
883  int m = a->e[0];
884  if (m==0) return 0;
885  while (b->ne!=NULL) b = b->ne;
886  if (m > b->e[0]) m = b->e[0];
887  return m;
888}
889
890#if FEHLER2
891/*meins
892* finds the smallest i-th exponent in a and b
893* used to find it in a fraction
894*/
895static int napExpi(int i, alg a, alg b)
896{
897  if (a==NULL || b==NULL) return 0;
898  int m = a->e[i];
899  if (m==0) return 0;
900  while (a->ne != NULL)
901  {
902    a = a->ne;
903    if (m > a->e[i])
904    {
905      m = a->e[i];
906      if (m==0) return 0;
907    }
908  }
909  do
910  {
911    if (m > b->e[i])
912    {
913      m = b->e[i];
914      if (m==0) return 0;
915    }
916    b = b->ne;
917  }
918  while (b != NULL);
919  return m;
920}
921#endif
922
923static void napContent(alg ph)
924{
925  number h,d;
926  alg p;
927
928  p = ph;
929  if (nacIsOne(p->ko))
930    return;
931  h = nacCopy(p->ko);
932  p = p->ne;
933  do
934  {
935    d=nacGcd(p->ko, h);
936    if(nacIsOne(d))
937    {
938      nacDelete(&h);
939      nacDelete(&d);
940      return;
941    }
942    nacDelete(&h);
943    h = d;
944    p = p->ne;
945  }
946  while (p!=NULL);
947  h = nacInvers(d);
948  nacDelete(&d);
949  p = ph;
950  while (p!=NULL)
951  {
952    d = nacMult(p->ko, h);
953    nacDelete(&(p->ko));
954    p->ko = d;
955    p = p->ne;
956  }
957  nacDelete(&h);
958}
959
960static void napCleardenom(alg ph)
961{
962  number d, h;
963  alg p;
964
965  if (!naIsChar0)
966    return;
967  p = ph;
968  h = nacInit(1);
969  while (p!=NULL)
970  {
971    d = nacLcm(h, p->ko);
972    nacDelete(&h);
973    h = d;
974    p = p->ne;
975  }
976  if(!nacIsOne(h))
977  {
978    p = ph;
979    while (p!=NULL)
980    {
981      d=nacMult(h, p->ko);
982      nacDelete(&(p->ko));
983      p->ko = d;
984      p = p->ne;
985    }
986    nacDelete(&h);
987  }
988  napContent(ph);
989}
990
991static alg napGcd0(alg a, alg b)
992{
993  number x, y;
994  if (!naIsChar0)
995    return napInit(1);
996  x = nacCopy(a->ko);
997  if (nacIsOne(x))
998    return napInitz(x);
999  while (a->ne!=NULL)
1000  {
1001    a = a->ne;
1002    y = nacGcd(x, a->ko);
1003    nacDelete(&x);
1004    x = y;
1005    if (nacIsOne(x))
1006      return napInitz(x);
1007  }
1008  do
1009  {
1010    y = nacGcd(x, b->ko);
1011    nacDelete(&x);
1012    x = y;
1013    if (nacIsOne(x))
1014      return napInitz(x);
1015    b = b->ne;
1016  }
1017  while (b!=NULL);
1018  return napInitz(x);
1019}
1020
1021/*3
1022* result =gcd(a,b)
1023*/
1024static alg napGcd(alg a, alg b)
1025{
1026  int i;
1027  alg g, x, y, h;
1028  if ((a==NULL)
1029  || ((a->ne==NULL)&&(nacIsZero(a->ko))))
1030  {
1031    if ((b==NULL)
1032    || ((b->ne==NULL)&&(nacIsZero(b->ko))))
1033    {
1034      return napInit(1);
1035    }
1036    return napCopy(b);
1037  }
1038  else
1039  if ((b==NULL)
1040  || ((b->ne==NULL)&&(nacIsZero(b->ko))))
1041  {
1042    return napCopy(a);
1043  }
1044  if (naMinimalPoly != NULL)
1045  {
1046    if (a->e[0] >= b->e[0])
1047    {
1048      x = a;
1049      y = b;
1050    }
1051    else
1052    {
1053      x = b;
1054      y = a;
1055    }
1056    if (!naIsChar0) g = napInit(1);
1057    else            g = napGcd0(x, y);
1058    if (y->ne==NULL)
1059    {
1060      g->e[0] = napExp(x, y);
1061      return g;
1062    }
1063    x = napCopy(x);
1064    y = napCopy(y);
1065    loop
1066    {
1067      h = napRemainder(x, y);
1068      if (h==NULL)
1069      {
1070        napCleardenom(y);
1071        if (!nacIsOne(g->ko)) napMultN(y, g->ko);
1072        napDelete1(&g);
1073        return y;
1074      }
1075      else if (h->ne==NULL)
1076        break;
1077      x = y;
1078      y = h;
1079    }
1080    napDelete(&y);
1081    napDelete1(&h);
1082    g->e[0] = napExp(a, b);
1083    return g;
1084  }
1085  // Hmm ... this is a memory leak
1086  // x = (alg)omAlloc0(napMonomSize);
1087  g=a;
1088  h=b;
1089  if (!naIsChar0) x = napInit(1);
1090  else            x = napGcd0(g,h);
1091  for (i=(naNumbOfPar-1); i>=0; i--)
1092  {
1093    x->e[i] = napExpi(i,a,b);
1094  }
1095  return x;
1096}
1097
1098
1099number napLcm(alg a)
1100{
1101  number h = nacInit(1);
1102
1103  if (naIsChar0)
1104  {
1105    number d;
1106    alg b = a;
1107
1108    while (b!=NULL)
1109    {
1110      d = nacLcm(h, b->ko);
1111      nacDelete(&h);
1112      h = d;
1113      b = b->ne;
1114    }
1115  }
1116  return h;
1117}
1118
1119
1120/*2
1121* meins  (for reduction in algebraic extension)
1122* checks if head of p divides head of q
1123* doesn't delete p and q
1124*/
1125BOOLEAN napDivPoly (alg p, alg q)
1126{
1127  int j=0;   /* evtl. von naNumber.. -1 abwaerts zaehlen */
1128
1129  while (p->e[j] <= q->e[j])
1130  {
1131    j++;
1132    if (j >= naNumbOfPar)
1133      return 1;
1134  }
1135  return 0;
1136}
1137
1138
1139/*2
1140* meins  (for reduction in algebraic extension)
1141* Normalform of poly with naI
1142* changes q and returns it
1143*/
1144alg napRedp (alg q)
1145{
1146  alg h = (alg)omAlloc0(napMonomSize);
1147  int i=0,j;
1148
1149  loop
1150  {
1151    if (napDivPoly (naI->liste[i], q))
1152    {
1153      omCheckAddrSize((ADDRESS)q,napMonomSize);
1154      //StringSetS("");
1155      //napWrite(q);
1156      //napWrite(naI->liste[i]);
1157      //Print(StringAppendS("\n"));
1158      /* h = lt(q)/lt(naI->liste[i])*/
1159      h->ko = nacCopy(q->ko);
1160      for (j=naNumbOfPar-1; j>=0; j--)
1161        h->e[j] = q->e[j] - naI->liste[i]->e[j];
1162      h = napMult (h, napCopy(naI->liste[i]));
1163      h = napNeg (h);
1164      q = napAdd (q, napCopy(h));
1165      napDelete (&(h->ne));
1166      if (q == NULL)
1167      {
1168        napDelete(&h);
1169        return q;
1170      }
1171      /* try to reduce further */
1172      i = 0;
1173    }
1174    else
1175    {
1176      i++;
1177      if (i >= naI->anz)
1178      {
1179        napDelete(&h);
1180        return q;
1181      }
1182    }
1183  }
1184}
1185
1186
1187/*2
1188* meins  (for reduction in algebraic extension)
1189* reduces the tail of Poly q
1190* needs q != NULL
1191* changes q and returns it
1192*/
1193alg napTailred (alg q)
1194{
1195  alg h;
1196
1197  h = q->ne;
1198  while (h != NULL)
1199  {
1200     h = napRedp (h);
1201     if (h == NULL)
1202        return q;
1203     h = h->ne;
1204  }
1205  return q;
1206}
1207
1208
1209/*================ procedure for rational functions: naXXXX =================*/
1210
1211/*2
1212*  z:= i
1213*/
1214number naInit(int i)
1215{
1216  if (i!=0)
1217  {
1218    lnumber l = (lnumber)omAllocBin(rnumber_bin);
1219    l->z = napInit(i);
1220    if (l->z==NULL)
1221    {
1222      omFreeBin((ADDRESS)l,  rnumber_bin);
1223      return NULL;
1224    }
1225    l->s = 2;
1226    l->n = NULL;
1227    return (number)l;
1228  }
1229  /*else*/
1230  return NULL;
1231}
1232
1233number  naPar(int i)
1234{
1235  lnumber l = (lnumber)omAllocBin(rnumber_bin);
1236  l->s = 2;
1237  l->z = napInit(1);
1238  l->z->e[i-1]=1;
1239  l->n = NULL;
1240  return (number)l;
1241}
1242
1243int     naParDeg(number n)     /* i := deg(n) */
1244{
1245  lnumber l = (lnumber)n;
1246  if (l==NULL) return -1;
1247  return napDeg(l->z);
1248}
1249
1250//int     naParDeg(number n)     /* i := deg(n) */
1251//{
1252//  lnumber l = (lnumber)n;
1253//  if (l==NULL) return -1;
1254//  return napMaxDeg(l->z)+napMaxDeg(l->n);
1255//}
1256
1257int     naSize(number n)     /* size desc. */
1258{
1259  lnumber l = (lnumber)n;
1260  if (l==NULL) return -1;
1261  int len_z;
1262  int len_n;
1263  int o=napMaxDegLen(l->z,len_z)+napMaxDegLen(l->n,len_n);
1264  return (len_z+len_n)+o;
1265}
1266
1267/*2
1268* convert a number to int (if possible)
1269*/
1270int naInt(number &n)
1271{
1272  lnumber l=(lnumber)n;
1273  if ((l!=NULL)&&(l->n==NULL)&&(napDeg(l->z)==0))
1274  {
1275    return nacInt(l->z->ko);
1276  }
1277  return 0;
1278}
1279
1280/*2
1281*  deletes p
1282*/
1283#ifdef LDEBUG
1284void naDBDelete(number *p,char *f, int lno)
1285#else
1286void naDelete(number *p)
1287#endif
1288{
1289  lnumber l = (lnumber) * p;
1290  if (l==NULL) return;
1291  napDelete(&(l->z));
1292  napDelete(&(l->n));
1293  omFreeBin((ADDRESS)l,  rnumber_bin);
1294  *p = NULL;
1295}
1296
1297/*2
1298* copy p to erg
1299*/
1300number naCopy(number p)
1301{
1302  if (p==NULL) return NULL;
1303  naTest(p);
1304  lnumber erg;
1305  lnumber src = (lnumber)p;
1306  erg = (lnumber)omAlloc0Bin(rnumber_bin);
1307  erg->z = napCopy(src->z);
1308  erg->n = napCopy(src->n);
1309  erg->s = src->s;
1310  return (number)erg;
1311}
1312
1313/*2
1314* a dummy number: 0
1315*/
1316void naNew(number *z)
1317{
1318  *z = NULL;
1319}
1320
1321/*2
1322*  addition; lu:= la + lb
1323*/
1324number naAdd(number la, number lb)
1325{
1326  alg x, y;
1327  lnumber lu;
1328  lnumber a = (lnumber)la;
1329  lnumber b = (lnumber)lb;
1330  if (a==NULL) return naCopy(lb);
1331  if (b==NULL) return naCopy(la);
1332  omCheckAddrSize(a,sizeof(rnumber));
1333  omCheckAddrSize(b,sizeof(rnumber));
1334  lu = (lnumber)omAllocBin(rnumber_bin);
1335  if (b->n!=NULL) x = napMult(napCopy(a->z), napCopy(b->n));
1336  else            x = napCopy(a->z);
1337  if (a->n!=NULL) y = napMult(napCopy(b->z), napCopy(a->n));
1338  else            y = napCopy(b->z);
1339  lu->z = napAdd(x, y);
1340  if (lu->z==NULL)
1341  {
1342    omFreeBin((ADDRESS)lu,  rnumber_bin);
1343    return (number)NULL;
1344  }
1345  if (a->n!=NULL)
1346  {
1347    if (b->n!=NULL) x = napMult(napCopy(a->n), napCopy(b->n));
1348    else            x = napCopy(a->n);
1349  }
1350  else
1351  {
1352    if (b->n!=NULL) x = napCopy(b->n);
1353    else            x = NULL;
1354  }
1355  if ((x!=NULL) && (napDeg(x)==0) && nacIsOne(x->ko))
1356    napDelete(&x);
1357  lu->n = x;
1358  lu->s = 0;
1359  naTest((number)lu);
1360  return (number)lu;
1361}
1362
1363/*2
1364*  subtraction; r:= la - lb
1365*/
1366number naSub(number la, number lb)
1367{
1368  lnumber lu;
1369
1370  if (lb==NULL) return naCopy(la);
1371  if (la==NULL)
1372  {
1373    //if (lb!=NULL)
1374    //{
1375      lu = (lnumber)naCopy(lb);
1376      lu->z = napNeg(lu->z);
1377      return (number)lu;
1378    //}
1379    //else
1380    //  return NULL;
1381  }
1382
1383  alg x, y;
1384  lnumber a = (lnumber)la;
1385  lnumber b = (lnumber)lb;
1386
1387  omCheckAddrSize(a,sizeof(rnumber));
1388  omCheckAddrSize(b,sizeof(rnumber));
1389  lu = (lnumber)omAllocBin(rnumber_bin);
1390  if (b->n!=NULL) x = napMult(napCopy(a->z), napCopy(b->n));
1391  else            x = napCopy(a->z);
1392  if (a->n!=NULL) y = napMult(napCopy(b->z), napCopyNeg(a->n));
1393  else            y = napCopyNeg(b->z);
1394  lu->z = napAdd(x, y);
1395  if (lu->z==NULL)
1396  {
1397    omFreeBin((ADDRESS)lu,  rnumber_bin);
1398    return (number)NULL;
1399  }
1400  if (a->n!=NULL)
1401  {
1402    if (b->n!=NULL) x = napMult(napCopy(a->n), napCopy(b->n));
1403    else            x = napCopy(a->n);
1404  }
1405  else
1406  {
1407    if (b->n!=NULL) x = napCopy(b->n);
1408    else            x = NULL;
1409  }
1410  if ((x!=NULL)&& (napDeg(x)==0) && nacIsOne(x->ko))
1411    napDelete(&x);
1412  lu->n = x;
1413  lu->s = 0;
1414  naTest((number)lu);
1415  return (number)lu;
1416}
1417
1418/*2
1419*  multiplication; r:= la * lb
1420*/
1421number naMult(number la, number lb)
1422{
1423  if ((la==NULL) || (lb==NULL))
1424    return NULL;
1425
1426  lnumber a = (lnumber)la;
1427  lnumber b = (lnumber)lb;
1428  lnumber lo;
1429  alg x;
1430
1431  omCheckAddrSize(a,sizeof(rnumber));
1432  omCheckAddrSize(b,sizeof(rnumber));
1433  naTest(la);
1434  naTest(lb);
1435
1436  lo = (lnumber)omAllocBin(rnumber_bin);
1437  lo->z = napMult(napCopy(a->z), napCopy(b->z));
1438
1439  if (a->n==NULL)
1440  {
1441    if (b->n==NULL)
1442      x = NULL;
1443    else
1444      x = napCopy(b->n);
1445  }
1446  else
1447  {
1448    if (b->n==NULL)
1449    {
1450      x = napCopy(a->n);
1451    }
1452    else
1453    {
1454      x = napMult(napCopy(b->n), napCopy(a->n));
1455    }
1456  }
1457  if (naMinimalPoly!=NULL)
1458  {
1459    if (lo->z->e[0] >= naMinimalPoly->e[0])
1460      lo->z = napRemainder(lo->z, naMinimalPoly);
1461    if ((x!=NULL) && (x->e[0] >= naMinimalPoly->e[0]))
1462      x = napRemainder(x, naMinimalPoly);
1463  }
1464#if FEHLER1
1465  if (naI!=NULL)
1466  {
1467    lo->z = napRedp (lo->z);
1468    if (lo->z != NULL)
1469       lo->z = napTailred (lo->z);
1470    if (x!=NULL)
1471    {
1472      x = napRedp (x);
1473      if (x!=NULL)
1474        x = napTailred (x);
1475    }
1476  }
1477#endif
1478  if ((x!=NULL) && (napDeg(x)==0) && nacIsOne(x->ko))
1479    napDelete(&x);
1480  lo->n = x;
1481  lo->s = 0;
1482  if(lo->z==NULL)
1483  {
1484    omFreeBin((ADDRESS)lo, rnumber_bin);
1485    lo=NULL;
1486  }
1487  naTest((number)lo);
1488  return (number)lo;
1489}
1490
1491number naIntDiv(number la, number lb)
1492{
1493  lnumber res;
1494  lnumber a = (lnumber)la;
1495  lnumber b = (lnumber)lb;
1496  if ((a==NULL) || (a->z==NULL))
1497    return NULL;
1498  if ((b==NULL) || (b->z==NULL))
1499  {
1500    WerrorS("div. by 0");
1501    return NULL;
1502  }
1503  res = (lnumber)omAllocBin(rnumber_bin);
1504  res->z = napCopy(a->z);
1505  res->n = napCopy(b->z);
1506  res->s = 0;
1507  number nres=(number)res;
1508  naNormalize(nres);
1509
1510  //napDelete(&res->n);
1511  naTest(nres);
1512  return nres;
1513}
1514
1515/*2
1516*  division; lo:= la / lb
1517*/
1518number naDiv(number la, number lb)
1519{
1520  lnumber lo;
1521  lnumber a = (lnumber)la;
1522  lnumber b = (lnumber)lb;
1523  alg x;
1524
1525  if ((a==NULL) || (a->z==NULL))
1526    return NULL;
1527
1528  if ((b==NULL) || (b->z==NULL))
1529  {
1530    WerrorS("div. by 0");
1531    return NULL;
1532  }
1533  omCheckAddrSize(a,sizeof(rnumber));
1534  omCheckAddrSize(b,sizeof(rnumber));
1535  lo = (lnumber)omAllocBin(rnumber_bin);
1536  if (b->n!=NULL)
1537    lo->z = napMult(napCopy(a->z), napCopy(b->n));
1538  else
1539    lo->z = napCopy(a->z);
1540  if (a->n!=NULL)
1541    x = napMult(napCopy(b->z), napCopy(a->n));
1542  else
1543    x = napCopy(b->z);
1544  if (naMinimalPoly!=NULL)
1545  {
1546    if (lo->z->e[0] >= naMinimalPoly->e[0])
1547      lo->z = napRemainder(lo->z, naMinimalPoly);
1548    if (x->e[0] >= naMinimalPoly->e[0])
1549      x = napRemainder(x, naMinimalPoly);
1550  }
1551#if FEHLER1
1552  if (naI!=NULL)
1553  {
1554    lo->z = napRedp (lo->z);
1555    if (lo->z != NULL)
1556       lo->z = napTailred (lo->z);
1557    if (x!=NULL)
1558    {
1559      x = napRedp (x);
1560      if (x!=NULL)
1561        x = napTailred (x);
1562    }
1563  }
1564#endif
1565  if ((napDeg(x)==0) && nacIsOne(x->ko))
1566    napDelete(&x);
1567  lo->s = 0;
1568  lo->n = x;
1569  naTest((number)lo);
1570  return (number)lo;
1571}
1572
1573/*2
1574*  za:= - za
1575*/
1576number naNeg(number za)
1577{
1578  if (za!=NULL)
1579  {
1580    lnumber e = (lnumber)za;
1581    naTest(za);
1582    e->z = napNeg(e->z);
1583  }
1584  return za;
1585}
1586
1587/*2
1588* 1/a
1589*/
1590number naInvers(number a)
1591{
1592  lnumber lo;
1593  lnumber b = (lnumber)a;
1594  alg x;
1595
1596  if (b==NULL)
1597  {
1598    WerrorS("div. by 0");
1599    return NULL;
1600  }
1601  omCheckAddrSize(b,sizeof(rnumber));
1602  lo = (lnumber)omAlloc0Bin(rnumber_bin);
1603  lo->s = b->s;
1604  if (b->n!=NULL)
1605    lo->z = napCopy(b->n);
1606  else
1607    lo->z = napInit(1);
1608  x = b->z;
1609  if ((napDeg(x)!=0) || !nacIsOne(x->ko))
1610    x = napCopy(x);
1611  else
1612  {
1613    lo->n = NULL;
1614    naTest((number)lo);
1615    return (number)lo;
1616  }
1617  if (naMinimalPoly!=NULL)
1618  {
1619    x = napInvers(x, naMinimalPoly);
1620    x = napMult(x, lo->z);
1621    if (x->e[0] >= naMinimalPoly->e[0])
1622      x = napRemainder(x, naMinimalPoly);
1623    lo->z = x;
1624    lo->n = NULL;
1625    lo->s = 2;
1626    while (x!=NULL)
1627    {
1628      nacNormalize(x->ko);
1629      x = x->ne;
1630    }
1631  }
1632  else
1633    lo->n = x;
1634  naTest((number)lo);
1635  return (number)lo;
1636}
1637
1638
1639BOOLEAN naIsZero(number za)
1640{
1641  lnumber zb = (lnumber)za;
1642  naTest(za);
1643#ifdef TEST
1644  if ((zb!=NULL) && (zb->z==NULL)) WerrorS("internal zero error(2)");
1645#endif
1646  return ((zb==NULL) || (zb->z==NULL));
1647}
1648
1649
1650BOOLEAN naGreaterZero(number za)
1651{
1652  lnumber zb = (lnumber)za;
1653#ifdef TEST
1654  if ((zb!=NULL) && (zb->z==NULL)) WerrorS("internal zero error(3)");
1655#endif
1656  naTest(za);
1657  if ((zb!=NULL) && (zb->z!=NULL))
1658  {
1659    if (zb->n!=NULL) return TRUE;
1660    if ((napDeg(zb->z)==0) && !nacGreaterZero(zb->z->ko)) return FALSE;
1661  }
1662  return TRUE;
1663}
1664
1665
1666/*2
1667* a = b ?
1668*/
1669BOOLEAN naEqual (number a, number b)
1670{
1671  if(a==b) return TRUE;
1672  if((a==NULL)&&(b!=NULL)) return FALSE;
1673  if((b==NULL)&&(a!=NULL)) return FALSE;
1674
1675  lnumber aa=(lnumber)a;
1676  lnumber bb=(lnumber)b;
1677
1678  int an_deg=0;
1679  if(aa->n!=NULL)
1680    an_deg=napDeg(aa->n);
1681  int bn_deg=0;
1682  if(bb->n!=NULL)
1683    bn_deg=napDeg(bb->n);
1684  if(an_deg+napDeg(bb->z)!=bn_deg+napDeg(aa->z))
1685    return FALSE;
1686#if 0
1687  naNormalize(a);
1688  aa=(lnumber)a;
1689  naNormalize(b);
1690  bb=(lnumber)b;
1691  if((aa->n==NULL)&&(bb->n!=NULL)) return FALSE;
1692  if((bb->n==NULL)&&(aa->n!=NULL)) return FALSE;
1693  if(napComp(aa->z,bb->z)!=0) return FALSE;
1694  if((aa->n!=NULL) && (napComp(aa->n,bb->n))) return FALSE;
1695#endif
1696  number h = naSub(a, b);
1697  BOOLEAN bo = naIsZero(h);
1698  naDelete(&h);
1699  return bo;
1700}
1701
1702
1703BOOLEAN naGreater (number a, number b)
1704{
1705  if (naIsZero(a))
1706    return FALSE;
1707  if (naIsZero(b))
1708    return TRUE; /* a!= 0)*/
1709  return napDeg(((lnumber)a)->z)>napDeg(((lnumber)b)->z);
1710}
1711
1712/*2
1713* reads a number
1714*/
1715char  *naRead(char *s, number *p)
1716{
1717  alg x;
1718  lnumber a;
1719  s = napRead(s, &x);
1720  if (x==NULL)
1721  {
1722    *p = NULL;
1723    return s;
1724  }
1725  *p = (number)omAlloc0Bin(rnumber_bin);
1726  a = (lnumber)*p;
1727  if ((naMinimalPoly!=NULL) && (x->e[0] >= naMinimalPoly->e[0]))
1728    a->z = napRemainder(x, naMinimalPoly);
1729#if FEHLER3
1730  else if (naI!=NULL)
1731  {
1732    a->z = napRedp(x);
1733    if (a->z != NULL)
1734      a->z = napTailred (a->z);
1735  }
1736#endif
1737  else
1738    a->z = x;
1739  if(a->z==NULL)
1740  {
1741    omFreeBin((ADDRESS)*p, rnumber_bin);
1742    *p=NULL;
1743  }
1744  else
1745  {
1746    a->n = NULL;
1747    a->s = 0;
1748    naTest(*p);
1749  }
1750  return s;
1751}
1752
1753/*2
1754* tries to convert a number to a name
1755*/
1756char * naName(number n)
1757{
1758  lnumber ph = (lnumber)n;
1759  if ((ph==NULL)||(ph->z==NULL))
1760    return NULL;
1761  int i;
1762  char *s=(char *)omAlloc(4* naNumbOfPar);
1763  char *t=(char *)omAlloc(8);
1764  s[0]='\0';
1765  for (i = 0; i <= naNumbOfPar - 1; i++)
1766  {
1767    if (ph->z->e[i] > 0)
1768    {
1769      if (ph->z->e[i] >1)
1770      {
1771        sprintf(t,"%s%d",naParNames[i],ph->z->e[i]);
1772        strcat(s,t);
1773      }
1774      else
1775      {
1776        strcat(s,naParNames[i]);
1777      }
1778    }
1779  }
1780  omFreeSize((ADDRESS)t,8);
1781  if (s[0]=='\0')
1782  {
1783    omFree((ADDRESS)s);
1784    return NULL;
1785  }
1786  return s;
1787}
1788
1789/*2
1790*  writes a number
1791*/
1792void naWrite(number &phn)
1793{
1794  lnumber ph = (lnumber)phn;
1795  if ((ph==NULL)||(ph->z==NULL))
1796    StringAppendS("0");
1797  else
1798  {
1799    phn->s = 0;
1800    naNormalize(phn);
1801    napWrite(ph->z);
1802    if (ph->n!=NULL)
1803    {
1804      StringAppendS("/");
1805      napWrite(ph->n);
1806    }
1807  }
1808}
1809
1810/*2
1811* za == 1 ?
1812*/
1813BOOLEAN naIsOne(number za)
1814{
1815  lnumber a = (lnumber)za;
1816  alg x, y;
1817  number t;
1818  if (a==NULL) return FALSE;
1819  omCheckAddrSize(a,sizeof(rnumber));
1820#ifdef TEST
1821  if (a->z==NULL) WerrorS("internal zero error(4)");
1822#endif
1823  if (a->n==NULL)
1824  {
1825    if (napDeg(a->z)==0) return nacIsOne(a->z->ko);
1826    else                 return FALSE;
1827  }
1828  x = a->z;
1829  y = a->n;
1830  do
1831  {
1832    if (napComp(x, y))
1833      return FALSE;
1834    else
1835    {
1836      t = nacSub(x->ko, y->ko);
1837      if (!nacIsZero(t))
1838      {
1839        nacDelete(&t);
1840        return FALSE;
1841      }
1842      else
1843        nacDelete(&t);
1844    }
1845    x = x->ne;
1846    y = y->ne;
1847  }
1848  while ((x!=NULL) && (y!=NULL));
1849  if ((x!=NULL) || (y!=NULL)) return FALSE;
1850  napDelete(&a->z);
1851  napDelete(&a->n);
1852  a->z = napInit(1);
1853  a->n = NULL;
1854  a->s = 2;
1855  return TRUE;
1856}
1857
1858/*2
1859* za == -1 ?
1860*/
1861BOOLEAN naIsMOne(number za)
1862{
1863  lnumber a = (lnumber)za;
1864  alg x, y;
1865  number t;
1866  if (a==NULL) return FALSE;
1867  omCheckAddrSize(a,sizeof(rnumber));
1868#ifdef TEST
1869  if (a->z==NULL)
1870  {
1871    WerrorS("internal zero error(5)");
1872    return FALSE;
1873  }
1874#endif
1875  if (a->n==NULL)
1876  {
1877    if (napDeg(a->z)==0) return nacIsMOne(a->z->ko);
1878    /*else                 return FALSE;*/
1879  }
1880  return FALSE;
1881}
1882
1883/*2
1884* returns the i-th power of p (i>=0)
1885*/
1886void naPower(number p, int i, number *rc)
1887{
1888  number x;
1889  *rc = naInit(1);
1890  for (; i > 0; i--)
1891  {
1892    x = naMult(*rc, p);
1893    naDelete(rc);
1894    *rc = x;
1895  }
1896}
1897
1898/*2
1899* result =gcd(a,b)
1900*/
1901number naGcd(number a, number b)
1902{
1903  lnumber x, y;
1904  lnumber result = (lnumber)omAlloc0Bin(rnumber_bin);
1905
1906  x = (lnumber)a;
1907  y = (lnumber)b;
1908  if (naNumbOfPar == 1)
1909  {
1910    if (naMinimalPoly!=NULL)
1911    {
1912      if (x->z->ne!=NULL)
1913        result->z = napCopy(x->z);
1914      else
1915        result->z = napGcd0(x->z, y->z);
1916    }
1917    else
1918      result->z = napGcd(x->z, y->z);
1919  }
1920  else
1921    result->z = napGcd(x->z, y->z); // change frpm napGcd0
1922  naTest((number)result);
1923  return (number)result;
1924}
1925
1926/*2
1927* naNumbOfPar = 1:
1928* clears denominator         algebraic case;
1929* tries to simplify ratio    transcendental case;
1930*
1931* cancels monomials
1932* occuring in denominator
1933* and enumerator  ?          naNumbOfPar != 1;
1934*
1935* #defines for Factory:
1936* FACTORY_GCD_TEST: do not apply built in gcd for
1937*   univariate polynomials, always use Factory
1938*/
1939void naNormalize(number &pp)
1940{
1941
1942  //naTest(pp); // input may not be "normal"
1943  lnumber p = (lnumber)pp;
1944
1945  if ((p==NULL) /*|| (p->s==2)*/)
1946    return;
1947  p->s = 2;
1948  alg x = p->z;
1949  alg y = p->n;
1950  if ((y!=NULL) && (naMinimalPoly!=NULL))
1951  {
1952    y = napInvers(y, naMinimalPoly);
1953    x = napMult(x, y);
1954    if (x->e[0] >= naMinimalPoly->e[0])
1955    x = napRemainder(x, naMinimalPoly);
1956    p->z = x;
1957    p->n = y = NULL;
1958  }
1959  /* check for degree of x too high: */
1960  if ((x!=NULL) && (naMinimalPoly!=NULL) && (x!=naMinimalPoly) 
1961  && (x->e[0]>naMinimalPoly->e[0])) // DO NOT REDUCE naMinimalPoly with itself
1962  {
1963    x = napRemainder(x, naMinimalPoly);
1964    p->z = x;
1965  }
1966  /* normalize all coefficients in n and z (if in Q) */
1967  if (naIsChar0)
1968  {
1969    while(x!=NULL)
1970    {
1971      nacNormalize(x->ko);
1972      x=x->ne;
1973    }
1974    x = p->z;
1975  }
1976  if (y==NULL) return;
1977  if (naIsChar0)
1978  {
1979    while(y!=NULL)
1980    {
1981      nacNormalize(y->ko);
1982      y=y->ne;
1983    }
1984    y = p->n;
1985  }
1986  // p->n !=NULL:
1987  /* collect all denoms from y and multiply x and y by it */
1988  if (naIsChar0)
1989  {
1990    number n=napLcm(y);
1991    napMultN(x,n);
1992    napMultN(y,n);
1993    nacDelete(&n);
1994    while(x!=NULL)
1995    {
1996      nacNormalize(x->ko);
1997      x=x->ne;
1998    }
1999    x = p->z;
2000    while(y!=NULL)
2001    {
2002      nacNormalize(y->ko);
2003      y=y->ne;
2004    }
2005    y = p->n;
2006  }
2007#if FEHLER1
2008  if (naMinimalPoly == NULL)
2009  {
2010    int i;
2011    for (i=naNumbOfPar-1; i>=0; i--)
2012    {
2013      alg xx=x;
2014      alg yy=y;
2015      int m = napExpi(i, yy, xx);
2016      if (m != 0)          // in this case xx!=NULL!=yy
2017      {
2018        while (xx != NULL)
2019        {
2020           xx->e[i] -= m;
2021           xx = xx->ne;
2022        }
2023        while (yy != NULL)
2024        {
2025          yy->e[i] -= m;
2026          yy = yy->ne;
2027        }
2028      }
2029    }
2030  }
2031#endif
2032  if (napDeg(y)==0) /* i.e. y=const => simplify to (1/c)*z / monom */
2033  {
2034    if (nacIsOne(y->ko))
2035    {
2036      napDelete1(&y);
2037      p->n = NULL;
2038      naTest(pp);
2039      return;
2040    }
2041    number h1 = nacInvers(y->ko);
2042    nacNormalize(h1);
2043    napMultN(x, h1);
2044    nacDelete(&h1);
2045    napDelete1(&y);
2046    p->n = NULL;
2047    naTest(pp);
2048    return;
2049  }
2050#ifndef FACTORY_GCD_TEST
2051  if (naNumbOfPar == 1) /* apply built-in gcd */
2052  {
2053    alg x1,y1;
2054    if (x->e[0] >= y->e[0])
2055    {
2056      x1 = napCopy(x);
2057      y1 = napCopy(y);
2058    }
2059    else
2060    {
2061      x1 = napCopy(y);
2062      y1 = napCopy(x);
2063    }
2064    alg r;
2065    loop
2066    {
2067      r = napRemainder(x1, y1);
2068      if ((r==NULL) || (r->ne==NULL)) break;
2069      x1 = y1;
2070      y1 = r;
2071    }
2072    if (r!=NULL)
2073    {
2074      napDelete(&r);
2075      napDelete(&y1);
2076    }
2077    else
2078    {
2079      napDivMod(x, y1, &(p->z), &r);
2080      napDivMod(y, y1, &(p->n), &r);
2081      napDelete(&y1);
2082    }
2083    x = p->z;
2084    y = p->n;
2085    /* collect all denoms from y and multiply x and y by it */
2086    if (naIsChar0)
2087    {
2088      number n=napLcm(y);
2089      napMultN(x,n);
2090      napMultN(y,n);
2091      nacDelete(&n);
2092      while(x!=NULL)
2093      {
2094        nacNormalize(x->ko);
2095        x=x->ne;
2096      }
2097      x = p->z;
2098      while(y!=NULL)
2099      {
2100        nacNormalize(y->ko);
2101        y=y->ne;
2102      }
2103      y = p->n;
2104    }
2105    if (y->ne==NULL)
2106    {
2107      if (nacIsOne(y->ko))
2108      {
2109        if (y->e[0]==0)
2110        {
2111          napDelete1(&y);
2112          p->n = NULL;
2113        }
2114        naTest(pp);
2115        return;
2116      }
2117    }
2118  }
2119#endif /* FACTORY_GCD_TEST */
2120#ifdef HAVE_FACTORY
2121#ifndef FACTORY_GCD_TEST
2122  else
2123#endif
2124  {
2125    alg xx,yy;
2126    singclap_algdividecontent(x,y,xx,yy);
2127    if (xx!=NULL)
2128    {
2129      p->z=xx;
2130      p->n=yy;
2131      napDelete(&x);
2132      napDelete(&y);
2133    }
2134  }
2135#endif
2136  /* remove common factors from z and n */
2137  x=p->z;
2138  y=p->n;
2139  if(!nacGreaterZero(napGetCoeff(y)))
2140  {
2141    x=napNeg(x);
2142    y=napNeg(y);
2143  }
2144  number g=nacCopy(napGetCoeff(x));
2145  napIter(x);
2146  while (x!=NULL)
2147  {
2148    number d=nacGcd(g,napGetCoeff(x));
2149    if(nacIsOne(d))
2150    {
2151      nacDelete(&g);
2152      nacDelete(&d);
2153      naTest(pp);
2154      return;
2155    }
2156    nacDelete(&g);
2157    g = d;
2158    napIter(x);
2159  }
2160  while (y!=NULL)
2161  {
2162    number d=nacGcd(g,napGetCoeff(y));
2163    if(nacIsOne(d))
2164    {
2165      nacDelete(&g);
2166      nacDelete(&d);
2167      naTest(pp);
2168      return;
2169    }
2170    nacDelete(&g);
2171    g = d;
2172    napIter(y);
2173  }
2174  x=p->z;
2175  y=p->n;
2176  while (x!=NULL)
2177  {
2178    number d = nacIntDiv(napGetCoeff(x),g);
2179    napSetCoeff(x,d);
2180    napIter(x);
2181  }
2182  while (y!=NULL)
2183  {
2184    number d = nacIntDiv(napGetCoeff(y),g);
2185    napSetCoeff(y,d);
2186    napIter(y);
2187  }
2188  nacDelete(&g);
2189  naTest(pp);
2190}
2191
2192/*2
2193* returns in result->n 1
2194* and in     result->z the lcm(a->z,b->n)
2195*/
2196number naLcm(number la, number lb)
2197{
2198  lnumber result;
2199  lnumber a = (lnumber)la;
2200  lnumber b = (lnumber)lb;
2201  result = (lnumber)omAlloc0Bin(rnumber_bin);
2202  //if (((naMinimalPoly==NULL) && (naI==NULL)) || !naIsChar0)
2203  //{
2204  //  result->z = napInit(1);
2205  //  return (number)result;
2206  //}
2207  naNormalize(lb);
2208  naTest(la);
2209  naTest(lb);
2210  alg x = napCopy(a->z);
2211  number t = napLcm(b->z); // get all denom of b->z
2212  if (!nacIsOne(t))
2213  {
2214    number bt, r;
2215    alg xx=x;
2216    while (xx!=NULL)
2217    {
2218      bt = nacGcd(t, xx->ko);
2219      r = nacMult(t, xx->ko);
2220      nacDelete(&(xx->ko));
2221      xx->ko = nacDiv(r, bt);
2222      nacNormalize(xx->ko);
2223      nacDelete(&bt);
2224      nacDelete(&r);
2225      xx=xx->ne;
2226    }
2227  }
2228  nacDelete(&t);
2229  result->z = x;
2230#ifdef HAVE_FACTORY
2231  if (b->n!=NULL)
2232  {
2233    result->z=singclap_alglcm(result->z,b->n);
2234    napDelete(&x);
2235  }
2236#endif
2237  naTest(la);
2238  naTest(lb);
2239  naTest((number)result);
2240  return ((number)result);
2241}
2242
2243/*2
2244* input: a set of constant polynomials
2245* sets the global variable naI
2246*/
2247void naSetIdeal(ideal I)
2248{
2249  int i;
2250
2251  if (idIs0(I))
2252  {
2253    for (i=naI->anz-1; i>=0; i--)
2254      napDelete(&naI->liste[i]);
2255    omFreeBin((ADDRESS)naI, snaIdeal_bin);
2256    naI=NULL;
2257  }
2258  else
2259  {
2260    lnumber h;
2261    number a;
2262    alg x;
2263
2264    naI=(naIdeal)omAllocBin(snaIdeal_bin);
2265    naI->anz=IDELEMS(I);
2266    naI->liste=(alg*)omAlloc(naI->anz*sizeof(alg));
2267    for (i=IDELEMS(I)-1; i>=0; i--)
2268    {
2269      h=(lnumber)pGetCoeff(I->m[i]);
2270      /* We only need the enumerator of h, as we expect it to be a polynomial */
2271      naI->liste[i]=napCopy(h->z);
2272      /* If it isn't normalized (lc = 1) do this */
2273      if (!nacIsOne(naI->liste[i]->ko))
2274      {
2275        x=naI->liste[i];
2276        a=nacCopy(x->ko);
2277        a=nacDiv(nacInit(1),a);
2278        napMultN(x,a);
2279        nacDelete(&a);
2280      }
2281    }
2282  }
2283}
2284
2285/*2
2286* map Z/p -> Q(a)
2287*/
2288number naMapP0(number c)
2289{
2290  if (npIsZero(c)) return NULL;
2291  lnumber l=(lnumber)omAllocBin(rnumber_bin);
2292  l->s=2;
2293  l->z=(alg)omAlloc0(napMonomSize);
2294  int i=(int)c;
2295  if (i>(naPrimeM>>2)) i-=naPrimeM;
2296  l->z->ko=nlInit(i);
2297  l->n=NULL;
2298  return (number)l;
2299}
2300
2301/*2
2302* map Q -> Q(a)
2303*/
2304number naMap00(number c)
2305{
2306  if (nlIsZero(c)) return NULL;
2307  lnumber l=(lnumber)omAllocBin(rnumber_bin);
2308  l->s=0;
2309  l->z=(alg)omAlloc0(napMonomSize);
2310  l->z->ko=nlCopy(c);
2311  l->n=NULL;
2312  return (number)l;
2313}
2314
2315/*2
2316* map Z/p -> Z/p(a)
2317*/
2318number naMapPP(number c)
2319{
2320  if (npIsZero(c)) return NULL;
2321  lnumber l=(lnumber)omAllocBin(rnumber_bin);
2322  l->s=2;
2323  l->z=(alg)omAlloc0(napMonomSize);
2324  l->z->ko=c; /* omit npCopy, because npCopy is a no-op */
2325  l->n=NULL;
2326  return (number)l;
2327}
2328
2329/*2
2330* map Z/p' -> Z/p(a)
2331*/
2332number naMapPP1(number c)
2333{
2334  if (npIsZero(c)) return NULL;
2335  int i=(int)c;
2336  if (i>naPrimeM) i-=naPrimeM;
2337  number n=npInit(i);
2338  if (npIsZero(n)) return NULL;
2339  lnumber l=(lnumber)omAllocBin(rnumber_bin);
2340  l->s=2;
2341  l->z=(alg)omAlloc0(napMonomSize);
2342  l->z->ko=n;
2343  l->n=NULL;
2344  return (number)l;
2345}
2346
2347/*2
2348* map Q -> Z/p(a)
2349*/
2350number naMap0P(number c)
2351{
2352  if (nlIsZero(c)) return NULL;
2353  number n=npInit(nlInt(c));
2354  if (npIsZero(n)) return NULL;
2355  lnumber l=(lnumber)omAllocBin(rnumber_bin);
2356  l->s=2;
2357  l->z=(alg)omAlloc0(napMonomSize);
2358  l->z->ko=n;
2359  l->n=NULL;
2360  return (number)l;
2361}
2362
2363static number (*nacMap)(number);
2364static int naParsToCopy;
2365static alg napMap(alg p)
2366{
2367  alg w, a;
2368
2369  if (p==NULL) return NULL;
2370  a = w = (alg)omAlloc0(napMonomSize);
2371  memcpy(a->e, p->e, naParsToCopy * SIZEOF_PARAMETER);
2372  w->ko = nacMap(p->ko);
2373  loop
2374  {
2375    p=p->ne;
2376    if (p==NULL) break;
2377    a->ne = (alg)omAlloc0(napMonomSize);
2378    a = a->ne;
2379    memcpy(a->e, p->e, naParsToCopy * SIZEOF_PARAMETER);
2380    a->ko = nacMap(p->ko);
2381  }
2382  a->ne = NULL;
2383  return w;
2384}
2385
2386/*2
2387* map _(a) -> _(b)
2388*/
2389number naMapQaQb(number c)
2390{
2391  if (c==NULL) return NULL;
2392  lnumber erg= (lnumber)omAlloc0Bin(rnumber_bin);
2393  lnumber src =(lnumber)c;
2394  erg->s=src->s;
2395  erg->z=napMap(src->z);
2396  erg->n=napMap(src->n);
2397  if (naMinimalPoly!=NULL)
2398  {
2399    if (erg->z->e[0] >= naMinimalPoly->e[0])
2400    {
2401      erg->z = napRemainder(erg->z, naMinimalPoly);
2402      if (erg->z==NULL)
2403      {
2404        number t_erg=(number)erg;
2405        naDelete(&t_erg);
2406        return (number)NULL;
2407      }
2408    }
2409    if (erg->n!=NULL)
2410    {
2411      if (erg->n->e[0] >= naMinimalPoly->e[0])
2412        erg->n = napRemainder(erg->n, naMinimalPoly);
2413      if ((napDeg(erg->n)==0) && nacIsOne(erg->n->ko))
2414        napDelete(&(erg->n));
2415    }
2416  }
2417  return (number)erg;
2418}
2419
2420BOOLEAN naSetMap(ring r)
2421{
2422  if (rField_is_Q_a()) /* -> Q(a) */
2423  {
2424    if (rField_is_Q(r))
2425    {
2426      nMap = naMap00;   /*Q -> Q(a)*/
2427      return TRUE;
2428    }
2429    if (rField_is_Zp(r))
2430    {
2431      naPrimeM = rChar(r);
2432      nMap = naMapP0;  /* Z/p -> Q(a)*/
2433      return TRUE;
2434    }
2435    if (rField_is_Q_a(r))
2436    {
2437      int i;
2438      naParsToCopy=0;
2439      for(i=0;i<rPar(r);i++)
2440      {
2441        if ((i>=rPar(currRing))
2442        ||(strcmp(r->parameter[i],currRing->parameter[i])!=0))
2443           return FALSE;
2444        naParsToCopy++;
2445      }
2446      nacMap=nacCopy;
2447      nMap=naMapQaQb;
2448      return TRUE;   /* Q(a) -> Q(a) */
2449    }
2450  }
2451  /*-----------------------------------------------------*/
2452  if (rField_is_Zp_a()) /* -> Z/p(a) */
2453  {
2454    if (rField_is_Q(r))
2455    {
2456      nMap = naMap0P;   /*Q -> Z/p(a)*/
2457      return TRUE;
2458    }
2459    if (rField_is_Zp(r))
2460    {
2461      int c=rChar(r);
2462      if (c==npPrimeM)
2463      {
2464        nMap = naMapPP;  /* Z/p -> Z/p(a)*/
2465      }
2466      else
2467      {
2468        naPrimeM = c;
2469        nMap = naMapPP1;  /* Z/p' -> Z/p(a)*/
2470      }
2471      return TRUE;
2472    }
2473    if (rField_is_Zp_a(r))
2474    {
2475      if (rChar(r)==rChar())
2476      {
2477        nacMap=nacCopy;
2478      }
2479      else
2480      {
2481        npMapPrime=rChar(r);
2482        nacMap = npMapP;
2483      }
2484      int i;
2485      naParsToCopy=0;
2486      for(i=0;i<rPar(r);i++)
2487      {
2488        if ((i>=rPar(currRing))
2489        ||(strcmp(r->parameter[i],currRing->parameter[i])!=0))
2490           return FALSE;
2491        naParsToCopy++;
2492      }
2493      nMap=naMapQaQb;
2494      return TRUE;   /* Z/p(a),Z/p'(a) -> Z/p(b)*/
2495    }
2496  }
2497  return FALSE;      /* default */
2498}
2499
2500/*2
2501* convert a alg number into a poly
2502*/
2503poly naPermNumber(number z, int * par_perm, int P)
2504{
2505  if (z==NULL) return NULL;
2506  poly res=NULL;
2507  poly p;
2508  napoly za=((lnumber)z)->z;
2509  do
2510  {
2511    p = pInit();
2512    pNext(p)=NULL;
2513    nNew(&pGetCoeff(p));
2514    int i;
2515    for(i=pVariables;i;i--)
2516       pSetExp(p,i, 0);
2517    pSetComp(p, 0);
2518    napoly pa=NULL;
2519    if (currRing->parameter!=NULL)
2520    {
2521      pGetCoeff(p)=(number)omAlloc0Bin(rnumber_bin);
2522      ((lnumber)pGetCoeff(p))->s=2;
2523      ((lnumber)pGetCoeff(p))->z=napInitz(nacCopy(napGetCoeff(za)));
2524      pa=((lnumber)pGetCoeff(p))->z;
2525    }
2526    else
2527    {
2528      pGetCoeff(p)=nCopy(napGetCoeff(za));
2529    }
2530    for(i=0;i<P;i++)
2531    {
2532      if(za->e[i]!=0)
2533      {
2534        if(par_perm==NULL)
2535        {
2536          if ((rPar(currRing)>=i) && (pa!=NULL)) pa->e[i]=za->e[i];
2537          else
2538          {
2539            pDelete(&p);
2540            break;
2541          }
2542        }
2543        else if(par_perm[i]>0)
2544          pSetExp(p,par_perm[i],za->e[i]);
2545        else if((par_perm[i]<0)&&(pa!=NULL))
2546          pa->e[-par_perm[i]-1]=za->e[i];
2547        else
2548        {
2549          pDelete(&p);
2550          break;
2551        }
2552      }
2553    }
2554    if (p!=NULL)
2555    {
2556      pSetm(p);
2557      pTest(p);
2558      res=pAdd(res,p);
2559    }
2560    za=za->ne;
2561  }
2562  while (za!=NULL);
2563  pTest(res);
2564  return res;
2565}
2566
2567number   naGetDenom(number &n)
2568{
2569  naNormalize(n);
2570  lnumber x=(lnumber)n;
2571  if (x->n!=NULL)
2572  {
2573    lnumber r=(lnumber)omAlloc0Bin(rnumber_bin);
2574    r->z=napCopy(naGetDenom0(x));
2575    r->s = 2;
2576    return (number)r;
2577  }
2578  return naInit(1);
2579}
2580
2581#ifdef LDEBUG
2582BOOLEAN naDBTest(number a, char *f,int l)
2583{
2584  lnumber x=(lnumber)a;
2585  if (x == NULL)
2586    return TRUE;
2587  omCheckAddrSize(a, sizeof(rnumber));
2588  alg p = x->z;
2589  if (p==NULL)
2590  {
2591    Print("0/* in %s:%d\n",f,l);
2592    return FALSE;
2593  }
2594  while(p!=NULL)
2595  {
2596    if ((naIsChar0 && nlIsZero(p->ko))
2597    || ((!naIsChar0) && npIsZero(p->ko)))
2598    {
2599      Print("coeff 0 in %s:%d\n",f,l);
2600      return FALSE;
2601    }
2602    if((naMinimalPoly!=NULL)&&(p->e[0]>naMinimalPoly->e[0])
2603    &&(p!=naMinimalPoly))
2604    {
2605      Print("deg>minpoly in %s:%d\n",f,l);
2606      return FALSE;
2607    }
2608    //if (naIsChar0 && (((int)p->ko &3) == 0) && (p->ko->s==0) && (x->s==2))
2609    //{
2610    //  Print("normalized with non-normal coeffs in %s:%d\n",f,l);
2611    //  return FALSE;
2612    //}
2613    if (naIsChar0 && !(nlDBTest(p->ko,f,l)))
2614      return FALSE;
2615    if (omCheckAddrSize(p, napMonomSize)) return FALSE;
2616    p = p->ne;
2617  }
2618  p = naGetDenom0(x);
2619  while(p!=NULL)
2620  {
2621    if (naIsChar0 && !(nlDBTest(p->ko,f,l)))
2622      return FALSE;
2623    if (omCheckAddrSize(p, napMonomSize)) return FALSE;
2624    p = p->ne;
2625  }
2626  return TRUE;
2627}
2628#endif
2629
Note: See TracBrowser for help on using the repository browser.