Index: libpolys/polys/ext_fields/transext.cc
===================================================================
--- libpolys/polys/ext_fields/transext.cc	(revision 8d1432ec89236ac387a78cc9cc8071a2127d8f1e)
+++ libpolys/polys/ext_fields/transext.cc	(revision 9ccaaf932b4894e5b87bdbc89ad0e50527144dac)
@@ -68,9 +68,9 @@
 #define NUMIS1(f) (p_IsOne(NUM(f), cf->extRing))
 
-#define COM(f) f->complexity
+#define COM(f) (f)->complexity
 
 
 #ifdef LDEBUG
-BOOLEAN  ntDBTest(number a, const char *f, const int l, const coeffs r);
+static BOOLEAN  ntDBTest(number a, const char *f, const int l, const coeffs r);
 #endif
 
@@ -91,38 +91,7 @@
 
 /// forward declarations
-BOOLEAN  ntGreaterZero(number a, const coeffs cf);
-BOOLEAN  ntGreater(number a, number b, const coeffs cf);
-BOOLEAN  ntEqual(number a, number b, const coeffs cf);
-BOOLEAN  ntIsOne(number a, const coeffs cf);
-BOOLEAN  ntIsMOne(number a, const coeffs cf);
-BOOLEAN  ntIsZero(number a, const coeffs cf);
-number   ntInit(long i, const coeffs cf);
-long     ntInt(number &a, const coeffs cf);
-number   ntNeg(number a, const coeffs cf);
-number   ntInvers(number a, const coeffs cf);
-number   ntAdd(number a, number b, const coeffs cf);
-number   ntSub(number a, number b, const coeffs cf);
-number   ntMult(number a, number b, const coeffs cf);
-number   ntDiv(number a, number b, const coeffs cf);
-void     ntPower(number a, int exp, number *b, const coeffs cf);
-number   ntCopy(number a, const coeffs cf);
-void     ntWriteLong(number a, const coeffs cf);
-void     ntWriteShort(number a, const coeffs cf);
-number   ntRePart(number a, const coeffs cf);
-number   ntImPart(number a, const coeffs cf);
-number   ntGetDenom(number &a, const coeffs cf);
-number   ntGetNumerator(number &a, const coeffs cf);
-number   ntGcd(number a, number b, const coeffs cf);
-number   ntNormalizeHelper(number a, number b, const coeffs cf);
-int      ntSize(number a, const coeffs cf);
-void     ntDelete(number * a, const coeffs cf);
-void     ntCoeffWrite(const coeffs cf, BOOLEAN details);
-const char * ntRead(const char *s, number *a, const coeffs cf);
-static BOOLEAN ntCoeffIsEqual(const coeffs cf, n_coeffType n, void * param);
-
-void heuristicGcdCancellation(number a, const coeffs cf);
-void definiteGcdCancellation(number a, const coeffs cf,
+static void heuristicGcdCancellation(number a, const coeffs cf);
+static void definiteGcdCancellation(number a, const coeffs cf,
                              BOOLEAN simpleTestsHaveAlreadyBeenPerformed);
-void handleNestedFractionsOverQ(fraction f, const coeffs cf);
 
 /* test routine, usualy disabled *
@@ -170,5 +139,5 @@
 
 #ifdef LDEBUG
-BOOLEAN ntDBTest(number a, const char *f, const int l, const coeffs cf)
+static BOOLEAN ntDBTest(number a, const char *f, const int l, const coeffs cf)
 {
   assume(getCoeffType(cf) == n_transExt);
@@ -323,5 +292,5 @@
 }
 
-BOOLEAN ntIsZero(number a, const coeffs cf)
+static BOOLEAN ntIsZero(number a, const coeffs cf)
 {
   //check_N(a,cf);
@@ -330,5 +299,5 @@
 }
 
-void ntDelete(number * a, const coeffs cf)
+static void ntDelete(number * a, const coeffs cf)
 {
   //check_N(*a,cf);
@@ -343,5 +312,5 @@
 }
 
-BOOLEAN ntEqual(number a, number b, const coeffs cf)
+static BOOLEAN ntEqual(number a, number b, const coeffs cf)
 {
   //check_N(a,cf);
@@ -389,5 +358,5 @@
 }
 
-number ntCopy(number a, const coeffs cf)
+static number ntCopy(number a, const coeffs cf)
 {
   //check_N(a,cf);
@@ -404,759 +373,4 @@
   ntTest((number)result);
   return (number)result;
-}
-
-/// TODO: normalization of a!?
-number ntGetNumerator(number &a, const coeffs cf)
-{
-  //check_N(a,cf);
-  ntTest(a);
-  if (IS0(a)) return NULL;
-
-  definiteGcdCancellation(a, cf, FALSE);
-
-  fraction f = (fraction)a;
-  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
-
-  const BOOLEAN denis1= DENIS1 (f);
-
-  if (getCoeffType (ntCoeffs) == n_Q && !denis1)
-    handleNestedFractionsOverQ (f, cf);
-
-  if (getCoeffType (ntCoeffs) == n_Q && denis1)
-  {
-    assume( DEN (f) == NULL );
-
-    number g;
-    // TODO/NOTE: the following should not be necessary (due to
-    // Hannes!) as NUM (f) should be over Z!!!
-    CPolyCoeffsEnumerator itr(NUM(f));
-
-
-    n_ClearDenominators(itr, g, ntCoeffs);
-
-    if( !n_GreaterZero(g, ntCoeffs) )
-    {
-      NUM (f) = p_Neg(NUM (f), ntRing);
-      g = n_InpNeg(g, ntCoeffs);
-    }
-
-    // g should be a positive integer now!
-    assume( n_GreaterZero(g, ntCoeffs) );
-
-    if( !n_IsOne(g, ntCoeffs) )
-    {
-      DEN (f) = p_NSet(g, ntRing);
-      COM (f) ++;
-      assume( DEN (f) != NULL );
-    }
-    else
-      n_Delete(&g, ntCoeffs);
-
-    ntTest(a);
-  }
-
-  // Call ntNormalize instead of above?!?
-
-  NUM (result) = p_Copy (NUM (f), ntRing); // ???
-  //DEN (result) = NULL; // done by ..Alloc0..
-  //COM (result) = 0; // done by ..Alloc0..
-
-  ntTest((number)result);
-  //check_N((number)result,cf);
-  return (number)result;
-}
-
-/// TODO: normalization of a!?
-number ntGetDenom(number &a, const coeffs cf)
-{
-  //check_N(a,cf);
-  ntTest(a);
-
-  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
-  //DEN (result)= NULL; // done by ..Alloc0..
-  //COM (result)= 0; // done by ..Alloc0..
-
-  if (IS0(a))
-  {
-    NUM (result) = p_One(ntRing);
-    return (number)result;
-  }
-
-  definiteGcdCancellation(a, cf, FALSE);
-
-  fraction f = (fraction)a;
-
-  assume( !IS0(f) );
-
-  const BOOLEAN denis1 = DENIS1 (f);
-
-  if( denis1 && (getCoeffType (ntCoeffs) != n_Q) ) // */1 or 0
-  {
-    NUM (result)= p_One(ntRing);
-    ntTest((number)result);
-    return (number)result;
-  }
-
-  if (!denis1) // */* / Q
-  {
-    assume( DEN (f) != NULL );
-
-    if (getCoeffType (ntCoeffs) == n_Q)
-      handleNestedFractionsOverQ (f, cf);
-
-    ntTest(a);
-
-    if( DEN (f) != NULL ) // is it ?? // 1 now???
-    {
-      assume( !p_IsOne(DEN (f), ntRing) );
-
-      NUM (result) = p_Copy (DEN (f), ntRing);
-      ntTest((number)result);
-      return (number)result;
-    }
-//    NUM (result) = p_One(ntRing); // NOTE: just in order to be sure...
-  }
-
-  // */1 / Q
-  assume( getCoeffType (ntCoeffs) == n_Q );
-  assume( DEN (f) == NULL );
-
-  number g;
-//    poly num= p_Copy (NUM (f), ntRing); // ???
-
-
-  // TODO/NOTE: the following should not be necessary (due to
-  // Hannes!) as NUM (f) should be over Z!!!
-  CPolyCoeffsEnumerator itr(NUM(f));
-
-  n_ClearDenominators(itr, g, ntCoeffs); // may return -1 :(((
-
-  if( !n_GreaterZero(g, ntCoeffs) )
-  {
-//     NUM (f) = p_Neg(NUM (f), ntRing); // Ugly :(((
-//     g = n_InpNeg(g, ntCoeffs);
-    NUM (f) = p_Neg(NUM (f), ntRing); // Ugly :(((
-    g = n_InpNeg(g, ntCoeffs);
-  }
-
-  // g should be a positive integer now!
-  assume( n_GreaterZero(g, ntCoeffs) );
-
-  if( !n_IsOne(g, ntCoeffs) )
-  {
-    assume( n_GreaterZero(g, ntCoeffs) );
-    assume( !n_IsOne(g, ntCoeffs) );
-
-    DEN (f) = p_NSet(g, ntRing); // update COM(f)???
-    assume( DEN (f) != NULL );
-    COM (f) ++;
-
-    NUM (result)= p_Copy (DEN (f), ntRing);
-  }
-  else
-  { // common denom == 1?
-    NUM (result)= p_NSet(g, ntRing); // p_Copy (DEN (f), ntRing);
-//  n_Delete(&g, ntCoeffs);
-  }
-
-//    if (!p_IsConstant (num, ntRing) && pNext(num) != NULL)
-//    else
-//      g= p_GetAllDenom (num, ntRing);
-//    result= (fraction) ntSetMap (ntCoeffs, cf) (g, ntCoeffs, cf);
-
-  ntTest((number)result);
-  //check_N((number)result,cf);
-  return (number)result;
-}
-
-BOOLEAN ntIsOne(number a, const coeffs cf)
-{
-  //check_N(a,cf);
-  ntTest(a); // !!!
-  definiteGcdCancellation(a, cf, FALSE);
-  fraction f = (fraction)a;
-  return (f!=NULL) && DENIS1(f) && NUMIS1(f);
-}
-
-BOOLEAN ntIsMOne(number a, const coeffs cf)
-{
-  //check_N(a,cf);
-  ntTest(a);
-  definiteGcdCancellation(a, cf, FALSE);
-  fraction f = (fraction)a;
-  if ((f==NULL) || (!DENIS1(f))) return FALSE;
-  poly g = NUM(f);
-  if (!p_IsConstant(g, ntRing)) return FALSE;
-  return n_IsMOne(p_GetCoeff(g, ntRing), ntCoeffs);
-}
-
-/// this is in-place, modifies a
-number ntNeg(number a, const coeffs cf)
-{
-  //check_N(a,cf);
-  ntTest(a);
-  if (!IS0(a))
-  {
-    fraction f = (fraction)a;
-    NUM(f) = p_Neg(NUM(f), ntRing);
-  }
-  ntTest(a);
-  return a;
-}
-
-number ntImPart(number a, const coeffs cf)
-{
-  ntTest(a);
-  return NULL;
-}
-
-number ntInit(long i, const coeffs cf)
-{
-  if (i != 0)
-  {
-    poly p=p_ISet(i, ntRing);
-    if (p!=NULL)
-    {
-      fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
-      NUM(result) = p;
-      //DEN(result) = NULL; // done by omAlloc0Bin
-      //COM(result) = 0; // done by omAlloc0Bin
-      ntTest((number)result);
-      //check_N((number)result,cf);
-      return (number)result;
-    }
-  }
-  return NULL;
-}
-
-
-/// takes over p!
-number ntInit(poly p, const coeffs cf)
-{
-  if (p == NULL) return NULL;
-
-  p_Test( p, ntRing);
-  fraction f = (fraction)omAlloc0Bin(fractionObjectBin);
-
-  if (nCoeff_is_Q(ntCoeffs))
-  {
-    number g;
-    // the following is necessary because
-    // NUM (f) should be over Z,
-    // while p may be over Q
-    CPolyCoeffsEnumerator itr(p);
-
-    n_ClearDenominators(itr, g, ntCoeffs);
-
-    if( !n_GreaterZero(g, ntCoeffs) )
-    {
-      p = p_Neg(p, ntRing);
-      g = n_InpNeg(g, ntCoeffs);
-    }
-
-    // g should be a positive integer now!
-    assume( n_GreaterZero(g, ntCoeffs) );
-
-    if( !n_IsOne(g, ntCoeffs) )
-    {
-      DEN (f) = p_NSet(g, ntRing);
-      p_Normalize(DEN(f), ntRing);
-      assume( DEN (f) != NULL );
-    }
-    else
-    {
-      //DEN(f) = NULL; // done by omAlloc0
-      n_Delete(&g, ntCoeffs);
-    }
-  }
-
-  p_Normalize(p, ntRing);
-  NUM(f) = p;
-  //COM(f) = 0; // done by omAlloc0
-
-  //check_N((number)f,cf);
-  ntTest((number)f);
-  return (number)f;
-}
-
-long ntInt(number &a, const coeffs cf)
-{
-  //check_N(a,cf);
-  ntTest(a);
-  if (IS0(a)) return 0;
-  definiteGcdCancellation(a, cf, FALSE);
-  fraction f = (fraction)a;
-  if (!DENIS1(f)) return 0;
-
-  const poly aAsPoly = NUM(f);
-
-  if(aAsPoly == NULL)
-    return 0;
-
-  if (!p_IsConstant(aAsPoly, ntRing))
-    return 0;
-
-  assume( aAsPoly != NULL );
-
-  return n_Int(p_GetCoeff(aAsPoly, ntRing), ntCoeffs);
-}
-
-/* This method will only consider the numerators of a and b, without
-   cancelling gcd's before.
-   Moreover it may return TRUE only if one or both numerators
-   are zero or if their degrees are equal. Then TRUE is returned iff
-   coeff(numerator(a)) > coeff(numerator(b));
-   In all other cases, FALSE will be returned. */
-BOOLEAN ntGreater(number a, number b, const coeffs cf)
-{
-  //check_N(a,cf);
-  //check_N(b,cf);
-  ntTest(a);
-  ntTest(b);
-  number aNumCoeff = NULL; int aNumDeg = 0;
-  number aDenCoeff = NULL; int aDenDeg = 0;
-  number bNumCoeff = NULL; int bNumDeg = 0;
-  number bDenCoeff = NULL; int bDenDeg = 0;
-  if (!IS0(a))
-  {
-    fraction fa = (fraction)a;
-    aNumDeg = p_Totaldegree(NUM(fa), ntRing);
-    aNumCoeff = p_GetCoeff(NUM(fa), ntRing);
-    if (DEN(fa)!=NULL)
-    {
-      aDenDeg = p_Totaldegree(DEN(fa), ntRing);
-      aDenCoeff=p_GetCoeff(DEN(fa),ntRing);
-    }
-  }
-  else return !(ntGreaterZero (b,cf));
-  if (!IS0(b))
-  {
-    fraction fb = (fraction)b;
-    bNumDeg = p_Totaldegree(NUM(fb), ntRing);
-    bNumCoeff = p_GetCoeff(NUM(fb), ntRing);
-    if (DEN(fb)!=NULL)
-    {
-      bDenDeg = p_Totaldegree(DEN(fb), ntRing);
-      bDenCoeff=p_GetCoeff(DEN(fb),ntRing);
-    }
-  }
-  else return ntGreaterZero(a,cf);
-  if (aNumDeg-aDenDeg > bNumDeg-bDenDeg) return TRUE;
-  if (aNumDeg-aDenDeg < bNumDeg-bDenDeg) return FALSE;
-  number aa;
-  number bb;
-  if (bDenCoeff==NULL) aa=n_Copy(aNumCoeff,ntCoeffs);
-  else                 aa=n_Mult(aNumCoeff,bDenCoeff,ntCoeffs);
-  if (aDenCoeff==NULL) bb=n_Copy(bNumCoeff,ntCoeffs);
-  else                 bb=n_Mult(bNumCoeff,aDenCoeff,ntCoeffs);
-  BOOLEAN rr= n_Greater(aa, bb, ntCoeffs);
-  n_Delete(&aa,ntCoeffs);
-  n_Delete(&bb,ntCoeffs);
-  return rr;
-}
-
-/* this method will only consider the numerator of a, without cancelling
-   the gcd before;
-   returns TRUE iff the leading coefficient of the numerator of a is > 0
-                    or the leading term of the numerator of a is not a
-                    constant */
-BOOLEAN ntGreaterZero(number a, const coeffs cf)
-{
-  //check_N(a,cf);
-  ntTest(a);
-  if (IS0(a)) return FALSE;
-  fraction f = (fraction)a;
-  poly g = NUM(f);
-  return (!p_LmIsConstant(g,ntRing)|| n_GreaterZero(pGetCoeff(g), ntCoeffs));
-}
-
-void ntCoeffWrite(const coeffs cf, BOOLEAN details)
-{
-  assume( cf != NULL );
-
-  const ring A = cf->extRing;
-
-  assume( A != NULL );
-  assume( A->cf != NULL );
-
-  n_CoeffWrite(A->cf, details);
-
-//  rWrite(A);
-
-  const int P = rVar(A);
-  assume( P > 0 );
-
-  PrintS("(");
-
-  for (int nop=0; nop < P; nop ++)
-  {
-    Print("%s", rRingVar(nop, A));
-    if (nop!=P-1) PrintS(", ");
-  }
-
-  PrintS(")");
-
-  assume( A->qideal == NULL );
-
-/*
-  PrintS("//   Coefficients live in the rational function field\n");
-  Print("//   K(");
-  for (int i = 0; i < rVar(ntRing); i++)
-  {
-    if (i > 0) PrintS(" ");
-    Print("%s", rRingVar(i, ntRing));
-  }
-  PrintS(") with\n");
-  PrintS("//   K: "); n_CoeffWrite(cf->extRing->cf);
-*/
-}
-
-number ntDiff(number a, number d, const coeffs cf)
-{
-  //check_N(a,cf);
-  //check_N(d,cf);
-  ntTest(a);
-  ntTest(d);
-
-  if (IS0(d))
-  {
-    WerrorS("ringvar expected");
-    return NULL;
-  }
-  fraction t = (fraction) d;
-  if (!DENIS1(t))
-  {
-    WerrorS("expected differentiation by a variable");
-    return NULL;
-  }
-  int k=p_Var(NUM(t),ntRing);
-  if (k==0)
-  {
-    WerrorS("expected differentiation by a variable");
-    return NULL;
-  }
-
-  if (IS0(a)) return ntCopy(a, cf);
-
-  fraction fa = (fraction)a;
-  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
-  if (DENIS1(fa))
-  {
-     NUM(result) = p_Diff(NUM(fa),k,ntRing);
-     //DEN(result) = NULL; // done by ..Alloc0..
-     if (NUM(result)==NULL)
-     {
-       omFreeBin((ADDRESS)result, fractionObjectBin);
-       return(NULL);
-     }
-     COM(result) = COM(fa);
-     //check_N((number)result,cf);
-     ntTest((number)result);
-     return (number)result;
-  }
-
-  poly fg = p_Mult_q(p_Copy(DEN(fa),ntRing),p_Diff(NUM(fa),k,ntRing),ntRing);
-  poly gf = p_Mult_q(p_Copy(NUM(fa),ntRing),p_Diff(DEN(fa),k,ntRing),ntRing);
-  NUM(result) = p_Sub(fg,gf,ntRing);
-  if (NUM(result)==NULL) return(NULL);
-  DEN(result) = pp_Mult_qq(DEN(fa), DEN(fa), ntRing);
-  COM(result) = COM(fa) + COM(fa) + DIFF_COMPLEXITY;
-  heuristicGcdCancellation((number)result, cf);
-
-  //check_N((number)result,cf);
-  ntTest((number)result);
-  return (number)result;
-}
-
-
-number ntAdd(number a, number b, const coeffs cf)
-{
-  //check_N(a,cf);
-  //check_N(b,cf);
-  ntTest(a);
-  ntTest(b);
-  if (IS0(a)) return ntCopy(b, cf);
-  if (IS0(b)) return ntCopy(a, cf);
-
-  fraction fa = (fraction)a;
-  fraction fb = (fraction)b;
-
-  poly g = p_Copy(NUM(fa), ntRing);
-  if (!DENIS1(fb)) g = p_Mult_q(g, p_Copy(DEN(fb), ntRing), ntRing);
-  poly h = p_Copy(NUM(fb), ntRing);
-  if (!DENIS1(fa)) h = p_Mult_q(h, p_Copy(DEN(fa), ntRing), ntRing);
-  g = p_Add_q(g, h, ntRing);
-
-  if (g == NULL) return NULL;
-
-  poly f;
-  if      (DENIS1(fa) && DENIS1(fb))  f = NULL;
-  else if (!DENIS1(fa) && DENIS1(fb)) f = p_Copy(DEN(fa), ntRing);
-  else if (DENIS1(fa) && !DENIS1(fb)) f = p_Copy(DEN(fb), ntRing);
-  else /* both denom's are != 1 */    f = p_Mult_q(p_Copy(DEN(fa), ntRing),
-                                                   p_Copy(DEN(fb), ntRing),
-                                                   ntRing);
-
-  fraction result = (fraction)omAllocBin(fractionObjectBin);
-  NUM(result) = g;
-  DEN(result) = f;
-  COM(result) = COM(fa) + COM(fb) + ADD_COMPLEXITY;
-  heuristicGcdCancellation((number)result, cf);
-
-//  ntTest((number)result);
-
-  //check_N((number)result,cf);
-  ntTest((number)result);
-  return (number)result;
-}
-
-number ntSub(number a, number b, const coeffs cf)
-{
-  //check_N(a,cf);
-  //check_N(b,cf);
-  ntTest(a);
-  ntTest(b);
-  if (IS0(a)) return ntNeg(ntCopy(b, cf), cf);
-  if (IS0(b)) return ntCopy(a, cf);
-
-  fraction fa = (fraction)a;
-  fraction fb = (fraction)b;
-
-  poly g = p_Copy(NUM(fa), ntRing);
-  if (!DENIS1(fb)) g = p_Mult_q(g, p_Copy(DEN(fb), ntRing), ntRing);
-  poly h = p_Copy(NUM(fb), ntRing);
-  if (!DENIS1(fa)) h = p_Mult_q(h, p_Copy(DEN(fa), ntRing), ntRing);
-  g = p_Add_q(g, p_Neg(h, ntRing), ntRing);
-
-  if (g == NULL) return NULL;
-
-  poly f;
-  if      (DENIS1(fa) && DENIS1(fb))  f = NULL;
-  else if (!DENIS1(fa) && DENIS1(fb)) f = p_Copy(DEN(fa), ntRing);
-  else if (DENIS1(fa) && !DENIS1(fb)) f = p_Copy(DEN(fb), ntRing);
-  else /* both den's are != 1 */      f = p_Mult_q(p_Copy(DEN(fa), ntRing),
-                                                   p_Copy(DEN(fb), ntRing),
-                                                   ntRing);
-
-  fraction result = (fraction)omAllocBin(fractionObjectBin);
-  NUM(result) = g;
-  DEN(result) = f;
-  COM(result) = COM(fa) + COM(fb) + ADD_COMPLEXITY;
-  heuristicGcdCancellation((number)result, cf);
-//  ntTest((number)result);
-  //check_N((number)result,cf);
-  ntTest((number)result);
-  return (number)result;
-}
-
-number ntMult(number a, number b, const coeffs cf)
-{
-  //check_N(a,cf);
-  //check_N(b,cf);
-  ntTest(a); // !!!?
-  ntTest(b); // !!!?
-
-  if (IS0(a) || IS0(b)) return NULL;
-
-  fraction fa = (fraction)a;
-  fraction fb = (fraction)b;
-
-  const poly g = pp_Mult_qq(NUM(fa), NUM(fb), ntRing);
-
-  if (g == NULL) return NULL; // may happen due to zero divisors???
-
-  fraction result = (fraction)omAllocBin(fractionObjectBin);
-
-  NUM(result) = g;
-
-  const poly da = DEN(fa);
-  const poly db = DEN(fb);
-
-
-  //check_N((number)result,cf);
-  if (db == NULL)
-  {
-    // b = ? // NULL
-
-    if(da == NULL)
-    { // both fa && fb are ?? // NULL!
-      assume (da == NULL && db == NULL);
-      DEN(result) = NULL;
-      COM(result) = 0;
-    }
-    else
-    {
-      assume (da != NULL && db == NULL);
-      DEN(result) = p_Copy(da, ntRing);
-      COM(result) = COM(fa) + MULT_COMPLEXITY;
-      heuristicGcdCancellation((number)result, cf);
-      //check_N((number)result,cf);
-    }
-  }
-  else
-  { // b = ?? / ??
-    if (da == NULL)
-    { // a == ? // NULL
-      assume( db != NULL && da == NULL);
-      DEN(result) = p_Copy(db, ntRing);
-      COM(result) = COM(fb) + MULT_COMPLEXITY;
-      heuristicGcdCancellation((number)result, cf);
-      //check_N((number)result,cf);
-    }
-    else /* both den's are != 1 */
-    {
-      assume (da != NULL && db != NULL);
-      DEN(result) = pp_Mult_qq(da, db, ntRing);
-      COM(result) = COM(fa) + COM(fb) + MULT_COMPLEXITY;
-      heuristicGcdCancellation((number)result, cf);
-      //check_N((number)result,cf);
-    }
-  }
-
-//  ntTest((number)result);
-
-  //check_N((number)result,cf);
-  ntTest((number)result);
-  return (number)result;
-}
-
-static void ntNormalizeDen(fraction result, const ring R)
-{
-  if ((nCoeff_has_simple_inverse(R->cf))
-  && (result!=NULL)
-  && (DEN(result)!=NULL))
-  {
-    poly n=DEN(result);
-    if (!n_IsOne(pGetCoeff(n),R->cf))
-    {
-      number inv=n_Invers(pGetCoeff(n),R->cf);
-      DEN(result)=p_Mult_nn(n,inv,R);
-      NUM(result)=p_Mult_nn(NUM(result),inv,R);
-      n_Delete(&inv,R->cf);
-      if (p_IsOne(DEN(result), R))
-      {
-        n=DEN(result);
-        DEN(result)=NULL;
-        COM(result) = 0;
-        p_Delete(&n,R);
-      }
-    }
-  }
-}
-
-number ntDiv(number a, number b, const coeffs cf)
-{
-  //check_N(a,cf);
-  //check_N(b,cf);
-  ntTest(a);
-  ntTest(b);
-  if (IS0(a)) return NULL;
-  if (IS0(b)) WerrorS(nDivBy0);
-
-  fraction fa = (fraction)a;
-  fraction fb = (fraction)b;
-
-  poly g = p_Copy(NUM(fa), ntRing);
-  if (!DENIS1(fb)) g = p_Mult_q(g, p_Copy(DEN(fb), ntRing), ntRing);
-
-  if (g == NULL) return NULL;   /* may happen due to zero divisors */
-
-  poly f = p_Copy(NUM(fb), ntRing);
-  if (!DENIS1(fa)) f = p_Mult_q(f, p_Copy(DEN(fa), ntRing), ntRing);
-
-  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
-  NUM(result) = g;
-  if (!n_GreaterZero(pGetCoeff(f),ntCoeffs))
-  {
-    g=p_Neg(g,ntRing);
-    f=p_Neg(f,ntRing);
-    NUM(result) = g;
-  }
-  if (!p_IsConstant(f,ntRing) || !n_IsOne(pGetCoeff(f),ntCoeffs))
-  {
-    DEN(result) = f;
-  }
-  COM(result) = COM(fa) + COM(fb) + MULT_COMPLEXITY;
-//  definiteGcdCancellation((number)result, cf,FALSE);
-  heuristicGcdCancellation((number)result, cf);
-//  ntTest((number)result);
-  //check_N((number)result,cf);
-  ntNormalizeDen(result,ntRing);
-  ntTest((number)result);
-  return (number)result;
-}
-
-/* 0^0 = 0;
-   for |exp| <= 7 compute power by a simple multiplication loop;
-   for |exp| >= 8 compute power along binary presentation of |exp|, e.g.
-      p^13 = p^1 * p^4 * p^8, where we utilise that
-      p^(2^(k+1)) = p^(2^k) * p^(2^k);
-   intermediate cancellation is controlled by the in-place method
-   heuristicGcdCancellation; see there.
-*/
-void ntPower(number a, int exp, number *b, const coeffs cf)
-{
-  ntTest(a);
-
-  /* special cases first */
-  if (IS0(a))
-  {
-    if (exp >= 0) *b = NULL;
-    else          WerrorS(nDivBy0);
-  }
-  else if (exp ==  0) { *b = ntInit(1, cf); return;}
-  else if (exp ==  1) { *b = ntCopy(a, cf); return;}
-  else if (exp == -1) { *b = ntInvers(a, cf); return;}
-
-  int expAbs = exp; if (expAbs < 0) expAbs = -expAbs;
-
-  /* now compute a^expAbs */
-  number pow; number t;
-  if (expAbs <= 7)
-  {
-    pow = ntCopy(a, cf);
-    for (int i = 2; i <= expAbs; i++)
-    {
-      t = ntMult(pow, a, cf);
-      ntDelete(&pow, cf);
-      pow = t;
-      heuristicGcdCancellation(pow, cf);
-    }
-  }
-  else
-  {
-    pow = ntInit(1, cf);
-    number factor = ntCopy(a, cf);
-    while (expAbs != 0)
-    {
-      if (expAbs & 1)
-      {
-        t = ntMult(pow, factor, cf);
-        ntDelete(&pow, cf);
-        pow = t;
-        heuristicGcdCancellation(pow, cf);
-      }
-      expAbs = expAbs / 2;
-      if (expAbs != 0)
-      {
-        t = ntMult(factor, factor, cf);
-        ntDelete(&factor, cf);
-        factor = t;
-        heuristicGcdCancellation(factor, cf);
-      }
-    }
-    ntDelete(&factor, cf);
-  }
-
-  /* invert if original exponent was negative */
-  if (exp < 0)
-  {
-    t = ntInvers(pow, cf);
-    ntDelete(&pow, cf);
-    pow = t;
-  }
-  *b = pow;
-  ntTest(*b);
-  //check_N(*b,cf);
 }
 
@@ -1185,5 +399,5 @@
    calling procedure);
    modifies f */
-void handleNestedFractionsOverQ(fraction f, const coeffs cf)
+static void handleNestedFractionsOverQ(fraction f, const coeffs cf)
 {
   assume(nCoeff_is_Q(ntCoeffs));
@@ -1273,11 +487,817 @@
       DEN(f) = p_Neg(DEN(f), ntRing);
     }
-
+  COM(f)=BOUND_COMPLEXITY+1;
   ntTest((number)f); // TODO!
+}
+
+/// TODO: normalization of a!?
+static number ntGetNumerator(number &a, const coeffs cf)
+{
+  //check_N(a,cf);
+  ntTest(a);
+  if (IS0(a)) return NULL;
+
+  definiteGcdCancellation(a, cf, FALSE);
+
+  fraction f = (fraction)a;
+  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
+
+  const BOOLEAN denis1= DENIS1 (f);
+
+  if (getCoeffType (ntCoeffs) == n_Q && !denis1)
+    handleNestedFractionsOverQ (f, cf);
+
+  if (getCoeffType (ntCoeffs) == n_Q && denis1)
+  {
+    assume( DEN (f) == NULL );
+
+    number g;
+    // TODO/NOTE: the following should not be necessary (due to
+    // Hannes!) as NUM (f) should be over Z!!!
+    CPolyCoeffsEnumerator itr(NUM(f));
+
+
+    n_ClearDenominators(itr, g, ntCoeffs);
+
+    if( !n_GreaterZero(g, ntCoeffs) )
+    {
+      NUM (f) = p_Neg(NUM (f), ntRing);
+      g = n_InpNeg(g, ntCoeffs);
+    }
+
+    // g should be a positive integer now!
+    assume( n_GreaterZero(g, ntCoeffs) );
+
+    if( !n_IsOne(g, ntCoeffs) )
+    {
+      DEN (f) = p_NSet(g, ntRing);
+      COM (f) ++;
+      assume( DEN (f) != NULL );
+    }
+    else
+      n_Delete(&g, ntCoeffs);
+
+    ntTest(a);
+  }
+
+  // Call ntNormalize instead of above?!?
+
+  NUM (result) = p_Copy (NUM (f), ntRing); // ???
+  //DEN (result) = NULL; // done by ..Alloc0..
+  //COM (result) = 0; // done by ..Alloc0..
+
+  ntTest((number)result);
+  //check_N((number)result,cf);
+  return (number)result;
+}
+
+/// TODO: normalization of a!?
+static number ntGetDenom(number &a, const coeffs cf)
+{
+  //check_N(a,cf);
+  ntTest(a);
+
+  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
+  //DEN (result)= NULL; // done by ..Alloc0..
+  //COM (result)= 0; // done by ..Alloc0..
+
+  if (IS0(a))
+  {
+    NUM (result) = p_One(ntRing);
+    return (number)result;
+  }
+
+  definiteGcdCancellation(a, cf, FALSE);
+
+  fraction f = (fraction)a;
+
+  assume( !IS0(f) );
+
+  const BOOLEAN denis1 = DENIS1 (f);
+
+  if( denis1 && (getCoeffType (ntCoeffs) != n_Q) ) // */1 or 0
+  {
+    NUM (result)= p_One(ntRing);
+    ntTest((number)result);
+    return (number)result;
+  }
+
+  if (!denis1) // */* / Q
+  {
+    assume( DEN (f) != NULL );
+
+    if (getCoeffType (ntCoeffs) == n_Q)
+      handleNestedFractionsOverQ (f, cf);
+
+    ntTest(a);
+
+    if( DEN (f) != NULL ) // is it ?? // 1 now???
+    {
+      assume( !p_IsOne(DEN (f), ntRing) );
+
+      NUM (result) = p_Copy (DEN (f), ntRing);
+      ntTest((number)result);
+      return (number)result;
+    }
+//    NUM (result) = p_One(ntRing); // NOTE: just in order to be sure...
+  }
+
+  // */1 / Q
+  assume( getCoeffType (ntCoeffs) == n_Q );
+  assume( DEN (f) == NULL );
+
+  number g;
+//    poly num= p_Copy (NUM (f), ntRing); // ???
+
+
+  // TODO/NOTE: the following should not be necessary (due to
+  // Hannes!) as NUM (f) should be over Z!!!
+  CPolyCoeffsEnumerator itr(NUM(f));
+
+  n_ClearDenominators(itr, g, ntCoeffs); // may return -1 :(((
+
+  if( !n_GreaterZero(g, ntCoeffs) )
+  {
+//     NUM (f) = p_Neg(NUM (f), ntRing); // Ugly :(((
+//     g = n_InpNeg(g, ntCoeffs);
+    NUM (f) = p_Neg(NUM (f), ntRing); // Ugly :(((
+    g = n_InpNeg(g, ntCoeffs);
+  }
+
+  // g should be a positive integer now!
+  assume( n_GreaterZero(g, ntCoeffs) );
+
+  if( !n_IsOne(g, ntCoeffs) )
+  {
+    assume( n_GreaterZero(g, ntCoeffs) );
+    assume( !n_IsOne(g, ntCoeffs) );
+
+    DEN (f) = p_NSet(g, ntRing); // update COM(f)???
+    assume( DEN (f) != NULL );
+    COM (f) ++;
+
+    NUM (result)= p_Copy (DEN (f), ntRing);
+  }
+  else
+  { // common denom == 1?
+    NUM (result)= p_NSet(g, ntRing); // p_Copy (DEN (f), ntRing);
+//  n_Delete(&g, ntCoeffs);
+  }
+
+//    if (!p_IsConstant (num, ntRing) && pNext(num) != NULL)
+//    else
+//      g= p_GetAllDenom (num, ntRing);
+//    result= (fraction) ntSetMap (ntCoeffs, cf) (g, ntCoeffs, cf);
+
+  ntTest((number)result);
+  //check_N((number)result,cf);
+  return (number)result;
+}
+
+static BOOLEAN ntIsOne(number a, const coeffs cf)
+{
+  //check_N(a,cf);
+  ntTest(a); // !!!
+  definiteGcdCancellation(a, cf, FALSE);
+  fraction f = (fraction)a;
+  return (f!=NULL) && DENIS1(f) && NUMIS1(f);
+}
+
+static BOOLEAN ntIsMOne(number a, const coeffs cf)
+{
+  //check_N(a,cf);
+  ntTest(a);
+  definiteGcdCancellation(a, cf, FALSE);
+  fraction f = (fraction)a;
+  if ((f==NULL) || (!DENIS1(f))) return FALSE;
+  poly g = NUM(f);
+  if (!p_IsConstant(g, ntRing)) return FALSE;
+  return n_IsMOne(p_GetCoeff(g, ntRing), ntCoeffs);
+}
+
+/// this is in-place, modifies a
+static number ntNeg(number a, const coeffs cf)
+{
+  //check_N(a,cf);
+  ntTest(a);
+  if (!IS0(a))
+  {
+    fraction f = (fraction)a;
+    NUM(f) = p_Neg(NUM(f), ntRing);
+  }
+  ntTest(a);
+  return a;
+}
+
+number ntInit(long i, const coeffs cf)
+{
+  if (i != 0)
+  {
+    poly p=p_ISet(i, ntRing);
+    if (p!=NULL)
+    {
+      fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
+      NUM(result) = p;
+      //DEN(result) = NULL; // done by omAlloc0Bin
+      //COM(result) = 0; // done by omAlloc0Bin
+      ntTest((number)result);
+      //check_N((number)result,cf);
+      return (number)result;
+    }
+  }
+  return NULL;
+}
+
+
+/// takes over p!
+number ntInit(poly p, const coeffs cf)
+{
+  if (p == NULL) return NULL;
+
+  p_Test( p, ntRing);
+  fraction f = (fraction)omAlloc0Bin(fractionObjectBin);
+
+  if (nCoeff_is_Q(ntCoeffs))
+  {
+    number g;
+    // the following is necessary because
+    // NUM (f) should be over Z,
+    // while p may be over Q
+    CPolyCoeffsEnumerator itr(p);
+
+    n_ClearDenominators(itr, g, ntCoeffs);
+
+    if( !n_GreaterZero(g, ntCoeffs) )
+    {
+      p = p_Neg(p, ntRing);
+      g = n_InpNeg(g, ntCoeffs);
+    }
+
+    // g should be a positive integer now!
+    assume( n_GreaterZero(g, ntCoeffs) );
+
+    if( !n_IsOne(g, ntCoeffs) )
+    {
+      DEN (f) = p_NSet(g, ntRing);
+      p_Normalize(DEN(f), ntRing);
+      assume( DEN (f) != NULL );
+    }
+    else
+    {
+      //DEN(f) = NULL; // done by omAlloc0
+      n_Delete(&g, ntCoeffs);
+    }
+  }
+
+  p_Normalize(p, ntRing);
+  NUM(f) = p;
+  //COM(f) = 0; // done by omAlloc0
+
+  //check_N((number)f,cf);
+  ntTest((number)f);
+  return (number)f;
+}
+
+static long ntInt(number &a, const coeffs cf)
+{
+  //check_N(a,cf);
+  ntTest(a);
+  if (IS0(a)) return 0;
+  definiteGcdCancellation(a, cf, FALSE);
+  fraction f = (fraction)a;
+  if (!DENIS1(f)) return 0;
+
+  const poly aAsPoly = NUM(f);
+
+  if(aAsPoly == NULL)
+    return 0;
+
+  if (!p_IsConstant(aAsPoly, ntRing))
+    return 0;
+
+  assume( aAsPoly != NULL );
+
+  return n_Int(p_GetCoeff(aAsPoly, ntRing), ntCoeffs);
+}
+
+/* this method will only consider the numerator of a, without cancelling
+   the gcd before;
+   returns TRUE iff the leading coefficient of the numerator of a is > 0
+                    or the leading term of the numerator of a is not a
+                    constant */
+static BOOLEAN ntGreaterZero(number a, const coeffs cf)
+{
+  //check_N(a,cf);
+  ntTest(a);
+  if (IS0(a)) return FALSE;
+  fraction f = (fraction)a;
+  poly g = NUM(f);
+  return (!p_LmIsConstant(g,ntRing)|| n_GreaterZero(pGetCoeff(g), ntCoeffs));
+}
+
+/* This method will only consider the numerators of a and b, without
+   cancelling gcd's before.
+   Moreover it may return TRUE only if one or both numerators
+   are zero or if their degrees are equal. Then TRUE is returned iff
+   coeff(numerator(a)) > coeff(numerator(b));
+   In all other cases, FALSE will be returned. */
+static BOOLEAN ntGreater(number a, number b, const coeffs cf)
+{
+  //check_N(a,cf);
+  //check_N(b,cf);
+  ntTest(a);
+  ntTest(b);
+  number aNumCoeff = NULL; int aNumDeg = 0;
+  number aDenCoeff = NULL; int aDenDeg = 0;
+  number bNumCoeff = NULL; int bNumDeg = 0;
+  number bDenCoeff = NULL; int bDenDeg = 0;
+  if (!IS0(a))
+  {
+    fraction fa = (fraction)a;
+    aNumDeg = p_Totaldegree(NUM(fa), ntRing);
+    aNumCoeff = p_GetCoeff(NUM(fa), ntRing);
+    if (DEN(fa)!=NULL)
+    {
+      aDenDeg = p_Totaldegree(DEN(fa), ntRing);
+      aDenCoeff=p_GetCoeff(DEN(fa),ntRing);
+    }
+  }
+  else return !(ntGreaterZero (b,cf));
+  if (!IS0(b))
+  {
+    fraction fb = (fraction)b;
+    bNumDeg = p_Totaldegree(NUM(fb), ntRing);
+    bNumCoeff = p_GetCoeff(NUM(fb), ntRing);
+    if (DEN(fb)!=NULL)
+    {
+      bDenDeg = p_Totaldegree(DEN(fb), ntRing);
+      bDenCoeff=p_GetCoeff(DEN(fb),ntRing);
+    }
+  }
+  else return ntGreaterZero(a,cf);
+  if (aNumDeg-aDenDeg > bNumDeg-bDenDeg) return TRUE;
+  if (aNumDeg-aDenDeg < bNumDeg-bDenDeg) return FALSE;
+  number aa;
+  number bb;
+  if (bDenCoeff==NULL) aa=n_Copy(aNumCoeff,ntCoeffs);
+  else                 aa=n_Mult(aNumCoeff,bDenCoeff,ntCoeffs);
+  if (aDenCoeff==NULL) bb=n_Copy(bNumCoeff,ntCoeffs);
+  else                 bb=n_Mult(bNumCoeff,aDenCoeff,ntCoeffs);
+  BOOLEAN rr= n_Greater(aa, bb, ntCoeffs);
+  n_Delete(&aa,ntCoeffs);
+  n_Delete(&bb,ntCoeffs);
+  return rr;
+}
+
+static void ntCoeffWrite(const coeffs cf, BOOLEAN details)
+{
+  assume( cf != NULL );
+
+  const ring A = cf->extRing;
+
+  assume( A != NULL );
+  assume( A->cf != NULL );
+
+  n_CoeffWrite(A->cf, details);
+
+//  rWrite(A);
+
+  const int P = rVar(A);
+  assume( P > 0 );
+
+  PrintS("(");
+
+  for (int nop=0; nop < P; nop ++)
+  {
+    Print("%s", rRingVar(nop, A));
+    if (nop!=P-1) PrintS(", ");
+  }
+
+  PrintS(")");
+
+  assume( A->qideal == NULL );
+
+/*
+  PrintS("//   Coefficients live in the rational function field\n");
+  Print("//   K(");
+  for (int i = 0; i < rVar(ntRing); i++)
+  {
+    if (i > 0) PrintS(" ");
+    Print("%s", rRingVar(i, ntRing));
+  }
+  PrintS(") with\n");
+  PrintS("//   K: "); n_CoeffWrite(cf->extRing->cf);
+*/
+}
+
+number ntDiff(number a, number d, const coeffs cf)
+{
+  //check_N(a,cf);
+  //check_N(d,cf);
+  ntTest(a);
+  ntTest(d);
+
+  if (IS0(d))
+  {
+    WerrorS("ringvar expected");
+    return NULL;
+  }
+  fraction t = (fraction) d;
+  if (!DENIS1(t))
+  {
+    WerrorS("expected differentiation by a variable");
+    return NULL;
+  }
+  int k=p_Var(NUM(t),ntRing);
+  if (k==0)
+  {
+    WerrorS("expected differentiation by a variable");
+    return NULL;
+  }
+
+  if (IS0(a)) return ntCopy(a, cf);
+
+  fraction fa = (fraction)a;
+  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
+  if (DENIS1(fa))
+  {
+     NUM(result) = p_Diff(NUM(fa),k,ntRing);
+     //DEN(result) = NULL; // done by ..Alloc0..
+     if (NUM(result)==NULL)
+     {
+       omFreeBin((ADDRESS)result, fractionObjectBin);
+       return(NULL);
+     }
+     COM(result) = COM(fa)+DIFF_COMPLEXITY;
+     //check_N((number)result,cf);
+     ntTest((number)result);
+     return (number)result;
+  }
+
+  poly fg = p_Mult_q(p_Copy(DEN(fa),ntRing),p_Diff(NUM(fa),k,ntRing),ntRing);
+  poly gf = p_Mult_q(p_Copy(NUM(fa),ntRing),p_Diff(DEN(fa),k,ntRing),ntRing);
+  NUM(result) = p_Sub(fg,gf,ntRing);
+  if (NUM(result)==NULL) return(NULL);
+  DEN(result) = pp_Mult_qq(DEN(fa), DEN(fa), ntRing);
+  COM(result) = COM(fa) + COM(fa) + DIFF_COMPLEXITY;
+  heuristicGcdCancellation((number)result, cf);
+
+  //check_N((number)result,cf);
+  ntTest((number)result);
+  return (number)result;
+}
+
+static number ntAdd(number a, number b, const coeffs cf)
+{
+  //check_N(a,cf);
+  //check_N(b,cf);
+  ntTest(a);
+  ntTest(b);
+  if (IS0(a)) return ntCopy(b, cf);
+  if (IS0(b)) return ntCopy(a, cf);
+
+  fraction fa = (fraction)a;
+  fraction fb = (fraction)b;
+
+  poly g = p_Copy(NUM(fa), ntRing);
+  if (!DENIS1(fb)) g = p_Mult_q(g, p_Copy(DEN(fb), ntRing), ntRing);
+  poly h = p_Copy(NUM(fb), ntRing);
+  if (!DENIS1(fa)) h = p_Mult_q(h, p_Copy(DEN(fa), ntRing), ntRing);
+  g = p_Add_q(g, h, ntRing);
+
+  if (g == NULL) return NULL;
+
+  poly f;
+  if      (DENIS1(fa) && DENIS1(fb))  f = NULL;
+  else if (!DENIS1(fa) && DENIS1(fb)) f = p_Copy(DEN(fa), ntRing);
+  else if (DENIS1(fa) && !DENIS1(fb)) f = p_Copy(DEN(fb), ntRing);
+  else /* both denom's are != 1 */    f = p_Mult_q(p_Copy(DEN(fa), ntRing),
+                                                   p_Copy(DEN(fb), ntRing),
+                                                   ntRing);
+
+  fraction result = (fraction)omAllocBin(fractionObjectBin);
+  NUM(result) = g;
+  DEN(result) = f;
+  COM(result) = COM(fa) + COM(fb) + ADD_COMPLEXITY;
+  heuristicGcdCancellation((number)result, cf);
+
+//  ntTest((number)result);
+
+  //check_N((number)result,cf);
+  ntTest((number)result);
+  return (number)result;
+}
+
+static number ntSub(number a, number b, const coeffs cf)
+{
+  //check_N(a,cf);
+  //check_N(b,cf);
+  ntTest(a);
+  ntTest(b);
+  if (IS0(a)) return ntNeg(ntCopy(b, cf), cf);
+  if (IS0(b)) return ntCopy(a, cf);
+
+  fraction fa = (fraction)a;
+  fraction fb = (fraction)b;
+
+  poly g = p_Copy(NUM(fa), ntRing);
+  if (!DENIS1(fb)) g = p_Mult_q(g, p_Copy(DEN(fb), ntRing), ntRing);
+  poly h = p_Copy(NUM(fb), ntRing);
+  if (!DENIS1(fa)) h = p_Mult_q(h, p_Copy(DEN(fa), ntRing), ntRing);
+  g = p_Add_q(g, p_Neg(h, ntRing), ntRing);
+
+  if (g == NULL) return NULL;
+
+  poly f;
+  if      (DENIS1(fa) && DENIS1(fb))  f = NULL;
+  else if (!DENIS1(fa) && DENIS1(fb)) f = p_Copy(DEN(fa), ntRing);
+  else if (DENIS1(fa) && !DENIS1(fb)) f = p_Copy(DEN(fb), ntRing);
+  else /* both den's are != 1 */      f = p_Mult_q(p_Copy(DEN(fa), ntRing),
+                                                   p_Copy(DEN(fb), ntRing),
+                                                   ntRing);
+
+  fraction result = (fraction)omAllocBin(fractionObjectBin);
+  NUM(result) = g;
+  DEN(result) = f;
+  COM(result) = COM(fa) + COM(fb) + ADD_COMPLEXITY;
+  heuristicGcdCancellation((number)result, cf);
+//  ntTest((number)result);
+  //check_N((number)result,cf);
+  ntTest((number)result);
+  return (number)result;
+}
+
+static number ntMult(number a, number b, const coeffs cf)
+{
+  //check_N(a,cf);
+  //check_N(b,cf);
+  ntTest(a); // !!!?
+  ntTest(b); // !!!?
+
+  if (IS0(a) || IS0(b)) return NULL;
+
+  fraction fa = (fraction)a;
+  fraction fb = (fraction)b;
+
+  const poly g = pp_Mult_qq(NUM(fa), NUM(fb), ntRing);
+
+  if (g == NULL) return NULL; // may happen due to zero divisors???
+
+  fraction result = (fraction)omAllocBin(fractionObjectBin);
+
+  NUM(result) = g;
+
+  const poly da = DEN(fa);
+  const poly db = DEN(fb);
+
+
+  //check_N((number)result,cf);
+  if (db == NULL)
+  {
+    // b = ? // NULL
+
+    if(da == NULL)
+    { // both fa && fb are ?? // NULL!
+      assume (da == NULL && db == NULL);
+      DEN(result) = NULL;
+      COM(result) = 0;
+    }
+    else
+    {
+      assume (da != NULL && db == NULL);
+      DEN(result) = p_Copy(da, ntRing);
+      COM(result) = COM(fa) + MULT_COMPLEXITY;
+      heuristicGcdCancellation((number)result, cf);
+      //check_N((number)result,cf);
+    }
+  }
+  else
+  { // b = ?? / ??
+    if (da == NULL)
+    { // a == ? // NULL
+      assume( db != NULL && da == NULL);
+      DEN(result) = p_Copy(db, ntRing);
+      COM(result) = COM(fb) + MULT_COMPLEXITY;
+      heuristicGcdCancellation((number)result, cf);
+      //check_N((number)result,cf);
+    }
+    else /* both den's are != 1 */
+    {
+      assume (da != NULL && db != NULL);
+      DEN(result) = pp_Mult_qq(da, db, ntRing);
+      COM(result) = COM(fa) + COM(fb) + MULT_COMPLEXITY;
+      heuristicGcdCancellation((number)result, cf);
+      //check_N((number)result,cf);
+    }
+  }
+
+//  ntTest((number)result);
+
+  //check_N((number)result,cf);
+  ntTest((number)result);
+  return (number)result;
+}
+
+static void ntNormalizeDen(fraction result, const ring R)
+{
+  if ((nCoeff_has_simple_inverse(R->cf))
+  && (result!=NULL)
+  && (DEN(result)!=NULL))
+  {
+    poly n=DEN(result);
+    if (!n_IsOne(pGetCoeff(n),R->cf))
+    {
+      number inv=n_Invers(pGetCoeff(n),R->cf);
+      DEN(result)=p_Mult_nn(n,inv,R);
+      NUM(result)=p_Mult_nn(NUM(result),inv,R);
+      n_Delete(&inv,R->cf);
+      if (p_IsOne(DEN(result), R))
+      {
+        n=DEN(result);
+        DEN(result)=NULL;
+        COM(result) = 0;
+        p_Delete(&n,R);
+      }
+    }
+  }
+}
+
+static number ntDiv(number a, number b, const coeffs cf)
+{
+  //check_N(a,cf);
+  //check_N(b,cf);
+  ntTest(a);
+  ntTest(b);
+  if (IS0(a)) return NULL;
+  if (IS0(b)) WerrorS(nDivBy0);
+
+  fraction fa = (fraction)a;
+  fraction fb = (fraction)b;
+
+  poly g = p_Copy(NUM(fa), ntRing);
+  if (!DENIS1(fb)) g = p_Mult_q(g, p_Copy(DEN(fb), ntRing), ntRing);
+
+  if (g == NULL) return NULL;   /* may happen due to zero divisors */
+
+  poly f = p_Copy(NUM(fb), ntRing);
+  if (!DENIS1(fa)) f = p_Mult_q(f, p_Copy(DEN(fa), ntRing), ntRing);
+
+  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
+  NUM(result) = g;
+  if (!n_GreaterZero(pGetCoeff(f),ntCoeffs))
+  {
+    g=p_Neg(g,ntRing);
+    f=p_Neg(f,ntRing);
+    NUM(result) = g;
+  }
+  if (!p_IsConstant(f,ntRing) || !n_IsOne(pGetCoeff(f),ntCoeffs))
+  {
+    DEN(result) = f;
+  }
+  COM(result) = COM(fa) + COM(fb) + MULT_COMPLEXITY;
+//  definiteGcdCancellation((number)result, cf,FALSE);
+  heuristicGcdCancellation((number)result, cf);
+//  ntTest((number)result);
+  //check_N((number)result,cf);
+  ntNormalizeDen(result,ntRing);
+  ntTest((number)result);
+  return (number)result;
+}
+
+static number ntInvers(number a, const coeffs cf)
+{
+  //check_N(a,cf);
+  ntTest(a);
+  if (IS0(a))
+  {
+    WerrorS(nDivBy0);
+    return NULL;
+  }
+  fraction f = (fraction)a;
+  assume( f != NULL );
+
+  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
+
+  assume( NUM(f) != NULL );
+  const poly den = DEN(f);
+
+  if (den == NULL)
+    NUM(result) = p_One(ntRing);
+  else
+    NUM(result) = p_Copy(den, ntRing);
+
+  if( !NUMIS1(f) )
+  {
+    poly num_f=NUM(f);
+    BOOLEAN neg= !n_GreaterZero(pGetCoeff(num_f),ntCoeffs);
+    if (neg)
+    {
+      num_f=p_Neg(p_Copy(num_f, ntRing), ntRing);
+      NUM(result)=p_Neg(NUM(result), ntRing);
+    }
+    else
+    {
+      num_f=p_Copy(num_f, ntRing);
+    }
+    DEN(result) = num_f;
+    COM(result) = COM(f);
+    if (neg)
+    {
+      if (p_IsOne(num_f, ntRing))
+      {
+        DEN(result)=NULL;
+        //COM(result) = 0;
+        p_Delete(&num_f,ntRing);
+      }
+    }
+  }
+  //else// Alloc0
+  //{
+  //  DEN(result) = NULL;
+  //  COM(result) = 0;
+  //}
+  ntNormalizeDen(result,ntRing);
+  ntTest((number)result); // !!!!
+  //check_N((number)result,cf);
+  return (number)result;
+}
+
+/* 0^0 = 0;
+   for |exp| <= 7 compute power by a simple multiplication loop;
+   for |exp| >= 8 compute power along binary presentation of |exp|, e.g.
+      p^13 = p^1 * p^4 * p^8, where we utilise that
+      p^(2^(k+1)) = p^(2^k) * p^(2^k);
+   intermediate cancellation is controlled by the in-place method
+   heuristicGcdCancellation; see there.
+*/
+static void ntPower(number a, int exp, number *b, const coeffs cf)
+{
+  ntTest(a);
+
+  /* special cases first */
+  if (IS0(a))
+  {
+    if (exp >= 0) *b = NULL;
+    else          WerrorS(nDivBy0);
+  }
+  else if (exp ==  0) { *b = ntInit(1, cf); return;}
+  else if (exp ==  1) { *b = ntCopy(a, cf); return;}
+  else if (exp == -1) { *b = ntInvers(a, cf); return;}
+
+  int expAbs = exp; if (expAbs < 0) expAbs = -expAbs;
+
+  /* now compute a^expAbs */
+  number pow; number t;
+  if (expAbs <= 7)
+  {
+    pow = ntCopy(a, cf);
+    for (int i = 2; i <= expAbs; i++)
+    {
+      t = ntMult(pow, a, cf);
+      ntDelete(&pow, cf);
+      pow = t;
+      heuristicGcdCancellation(pow, cf);
+    }
+  }
+  else
+  {
+    pow = ntInit(1, cf);
+    number factor = ntCopy(a, cf);
+    while (expAbs != 0)
+    {
+      if (expAbs & 1)
+      {
+        t = ntMult(pow, factor, cf);
+        ntDelete(&pow, cf);
+        pow = t;
+        heuristicGcdCancellation(pow, cf);
+      }
+      expAbs = expAbs / 2;
+      if (expAbs != 0)
+      {
+        t = ntMult(factor, factor, cf);
+        ntDelete(&factor, cf);
+        factor = t;
+        heuristicGcdCancellation(factor, cf);
+      }
+    }
+    ntDelete(&factor, cf);
+  }
+
+  /* invert if original exponent was negative */
+  if (exp < 0)
+  {
+    t = ntInvers(pow, cf);
+    ntDelete(&pow, cf);
+    pow = t;
+  }
+  *b = pow;
+  ntTest(*b);
+  //check_N(*b,cf);
 }
 
 /* modifies a */
 /* this is an intermediate simplification routine - not a comple "normalize" */
-void heuristicGcdCancellation(number a, const coeffs cf)
+static void heuristicGcdCancellation(number a, const coeffs cf)
 {
   if (IS0(a)) return;
@@ -1364,5 +1384,5 @@
 
 /// modifies a
-void definiteGcdCancellation(number a, const coeffs cf,
+static void definiteGcdCancellation(number a, const coeffs cf,
                              BOOLEAN simpleTestsHaveAlreadyBeenPerformed)
 {
@@ -1372,4 +1392,5 @@
 
   if (IS0(a)) return;
+  if (COM(f)==0) return;
   if (DENIS1(f) || NUMIS1(f)) { COM(f) = 0; ntTest(a); return; }
   if (!simpleTestsHaveAlreadyBeenPerformed)
@@ -1441,4 +1462,5 @@
 
   /* here we assume: NUM(f), DEN(f) !=NULL, in Z_a reqp. Z/p_a */
+  //StringSetS("");ntWriteLong(a,cf);
   poly pGcd = singclap_gcd_and_divide(NUM(f), DEN(f), ntRing);
   //PrintS("gcd= ");p_wrp(pGcd,ntRing);PrintLn();
@@ -1493,4 +1515,5 @@
   }
   p_Delete(&pGcd, ntRing);
+//  StringAppendS(" -> ");ntWriteLong(a,cf);StringAppendS("\n");{ char* s = StringEndS(); Print("%s", s); omFree(s); }
   COM(f) = 0;
 
@@ -1513,5 +1536,5 @@
 }
 
-void ntWriteLong(number a, const coeffs cf)
+static void ntWriteLong(number a, const coeffs cf)
 {
   ntTest(a);
@@ -1538,5 +1561,5 @@
 }
 
-void ntWriteShort(number a, const coeffs cf)
+static void ntWriteShort(number a, const coeffs cf)
 {
   ntTest(a);
@@ -1563,5 +1586,5 @@
 }
 
-const char * ntRead(const char *s, number *a, const coeffs cf)
+static const char * ntRead(const char *s, number *a, const coeffs cf)
 {
   poly p;
@@ -1573,5 +1596,5 @@
 }
 
-void ntNormalize (number &a, const coeffs cf)
+static void ntNormalize (number &a, const coeffs cf)
 {
   if ( /*(*/ a!=NULL /*)*/ )
@@ -1579,5 +1602,5 @@
     //PrintS("num=");p_wrp(NUM(a),ntRing);
     //PrintS(" den=");p_wrp(DEN(a),ntRing);PrintLn();
-    definiteGcdCancellation(a, cf, FALSE);
+    if (COM((fraction)a)>0) definiteGcdCancellation(a, cf, FALSE);
     if ((DEN((fraction)a)!=NULL)
     &&(!n_GreaterZero(pGetCoeff(DEN((fraction)a)),ntCoeffs)))
@@ -1614,5 +1637,5 @@
 }
 
-number ntNormalizeHelper(number a, number b, const coeffs cf)
+static number ntNormalizeHelper(number a, number b, const coeffs cf)
 {
   ntTest(a);
@@ -1702,5 +1725,5 @@
 }
 
-number ntGcd(number a, number b, const coeffs cf)
+static number ntGcd(number a, number b, const coeffs cf)
 {
   ntTest(a);
@@ -1778,5 +1801,5 @@
 //}
 
-int ntSize(number a, const coeffs cf)
+static int ntSize(number a, const coeffs cf)
 {
   ntTest(a);
@@ -1805,64 +1828,6 @@
 }
 
-number ntInvers(number a, const coeffs cf)
-{
-  //check_N(a,cf);
-  ntTest(a);
-  if (IS0(a))
-  {
-    WerrorS(nDivBy0);
-    return NULL;
-  }
-  fraction f = (fraction)a;
-  assume( f != NULL );
-
-  fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
-
-  assume( NUM(f) != NULL );
-  const poly den = DEN(f);
-
-  if (den == NULL)
-    NUM(result) = p_One(ntRing);
-  else
-    NUM(result) = p_Copy(den, ntRing);
-
-  if( !NUMIS1(f) )
-  {
-    poly num_f=NUM(f);
-    BOOLEAN neg= !n_GreaterZero(pGetCoeff(num_f),ntCoeffs);
-    if (neg)
-    {
-      num_f=p_Neg(p_Copy(num_f, ntRing), ntRing);
-      NUM(result)=p_Neg(NUM(result), ntRing);
-    }
-    else
-    {
-      num_f=p_Copy(num_f, ntRing);
-    }
-    DEN(result) = num_f;
-    COM(result) = COM(f);
-    if (neg)
-    {
-      if (p_IsOne(num_f, ntRing))
-      {
-        DEN(result)=NULL;
-        //COM(result) = 0;
-        p_Delete(&num_f,ntRing);
-      }
-    }
-  }
-  //else// Alloc0
-  //{
-  //  DEN(result) = NULL;
-  //  COM(result) = 0;
-  //}
-  ntNormalizeDen(result,ntRing);
-  ntTest((number)result); // !!!!
-  //check_N((number)result,cf);
-  return (number)result;
-}
-
 /* assumes that src = Q or Z, dst = Q(t_1, ..., t_s) */
-number ntMap00(number a, const coeffs src, const coeffs dst)
+static number ntMap00(number a, const coeffs src, const coeffs dst)
 {
   n_Test(a, src);
@@ -1888,5 +1853,5 @@
 }
 
-number ntMapZ0(number a, const coeffs src, const coeffs dst)
+static number ntMapZ0(number a, const coeffs src, const coeffs dst)
 {
   n_Test(a, src);
@@ -1902,5 +1867,5 @@
 
 /* assumes that src = Z/p, dst = Q(t_1, ..., t_s) */
-number ntMapP0(number a, const coeffs src, const coeffs dst)
+static number ntMapP0(number a, const coeffs src, const coeffs dst)
 {
   n_Test(a, src);
@@ -1918,5 +1883,5 @@
 
  /* assumes that either src = K(t_1, ..., t_s), dst = K(t_1, ..., t_s) */
-number ntCopyMap(number a, const coeffs cf, const coeffs dst)
+static number ntCopyMap(number a, const coeffs cf, const coeffs dst)
 {
   ntTest(a);
@@ -1947,5 +1912,5 @@
 }
 
-number ntGenMap(number a, const coeffs cf, const coeffs dst)
+static number ntGenMap(number a, const coeffs cf, const coeffs dst)
 {
   ntTest(a);
@@ -2026,5 +1991,5 @@
 }
 
-number ntCopyAlg(number a, const coeffs cf, const coeffs dst)
+static number ntCopyAlg(number a, const coeffs cf, const coeffs dst)
 {
   n_Test(a, cf) ;
@@ -2033,5 +1998,5 @@
 }
 
-number ntGenAlg(number a, const coeffs cf, const coeffs dst)
+static number ntGenAlg(number a, const coeffs cf, const coeffs dst)
 {
   n_Test(a, cf) ;
@@ -2043,5 +2008,5 @@
 
 /* assumes that src = Q, dst = Z/p(t_1, ..., t_s) */
-number ntMap0P(number a, const coeffs src, const coeffs dst)
+static number ntMap0P(number a, const coeffs src, const coeffs dst)
 {
   n_Test(a, src) ;
@@ -2067,5 +2032,5 @@
 
 /* assumes that src = Z/p, dst = Z/p(t_1, ..., t_s) */
-number ntMapPP(number a, const coeffs src, const coeffs dst)
+static number ntMapPP(number a, const coeffs src, const coeffs dst)
 {
   n_Test(a, src) ;
@@ -2082,5 +2047,5 @@
 
 /* assumes that src = Z/u, dst = Z/p(t_1, ..., t_s), where u != p */
-number ntMapUP(number a, const coeffs src, const coeffs dst)
+static number ntMapUP(number a, const coeffs src, const coeffs dst)
 {
   n_Test(a, src) ;
@@ -2181,10 +2146,10 @@
 #endif
 
-void ntKillChar(coeffs cf)
+static void ntKillChar(coeffs cf)
 {
   if ((--cf->extRing->ref) == 0)
     rDelete(cf->extRing);
 }
-number ntConvFactoryNSingN( const CanonicalForm n, const coeffs cf)
+static number ntConvFactoryNSingN( const CanonicalForm n, const coeffs cf)
 {
   if (n.isZero()) return NULL;
@@ -2198,5 +2163,5 @@
   return (number)result;
 }
-CanonicalForm ntConvSingNFactoryN( number n, BOOLEAN /*setChar*/, const coeffs cf )
+static CanonicalForm ntConvSingNFactoryN( number n, BOOLEAN /*setChar*/, const coeffs cf )
 {
   ntTest(n);
@@ -2497,5 +2462,5 @@
 }
 
-number  ntChineseRemainder(number *x, number *q,int rl, BOOLEAN /*sym*/,CFArray &inv_cache,const coeffs cf)
+static number ntChineseRemainder(number *x, number *q,int rl, BOOLEAN /*sym*/,CFArray &inv_cache,const coeffs cf)
 {
   fraction result = (fraction)omAlloc0Bin(fractionObjectBin);
@@ -2527,5 +2492,5 @@
 }
 
-number  ntFarey(number p, number n, const coeffs cf)
+static number ntFarey(number p, number n, const coeffs cf)
 {
   // n is really a bigint
@@ -2595,6 +2560,6 @@
   cf->cfGetDenom     = ntGetDenom;
   cf->cfGetNumerator = ntGetNumerator;
-  cf->cfRePart       = ntCopy;
-  cf->cfImPart       = ntImPart;
+  //cf->cfRePart       = ntCopy;
+  //cf->cfImPart       = ntImPart;
   cf->cfCoeffWrite   = ntCoeffWrite;
 #ifdef LDEBUG
