source: git/Singular/longalg.cc @ 4508ce5

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