source: git/Singular/longalg.cc @ a6a239

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