source: git/kernel/longalg.cc @ e475e3

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