Changeset a04c5e in git


Ignore:
Timestamp:
Nov 5, 2010, 3:58:04 PM (13 years ago)
Author:
Hans Schoenemann <hannes@…>
Branches:
(u'spielwiese', 'd1ba061a762c62d3a25159d8da8b6e17332291fa')
Children:
f34215cd2606c6fc99bffc25e1a276b416786dca
Parents:
356ffbba88cc2728b3ebccc4ab980a11e23ac7d7
git-author:
Hans Schoenemann <hannes@mathematik.uni-kl.de>2010-11-05 15:58:04+01:00
git-committer:
Mohamed Barakat <mohamed.barakat@rwth-aachen.de>2011-11-09 11:55:35+01:00
Message:
included pInline[12] into p_poly.h
Location:
polys
Files:
2 deleted
2 edited

Legend:

Unmodified
Added
Removed
  • polys/monomials/monomials.h

    r356ffbb ra04c5e  
    4141#define __p_GetComp(p, r)   (p)->exp[r->pCompIndex]
    4242#define p_GetComp(p, r)    ((long) (r->pCompIndex >= 0 ? __p_GetComp(p, r) : 0))
    43 
    44 /***************************************************************
    45  *
    46  * What should be inlined and debugged?
    47  *
    48  ***************************************************************/
    49 // determines inlining of poly procs which iter through polys
    50 #if defined(DO_PINLINE0) && !defined(PDEBUG)
    51 #define PINLINE0 static inline
    52 #else
    53 #define PINLINE0
    54 #endif
    55 
    56 // determines inlining of poly procs which iter over ExpVector
    57 #undef NO_PINLINE1
    58 #if PDEBUG <= 0 && !defined(NO_INLINE1)
    59 #define PINLINE1 static inline
    60 #else
    61 #define PINLINE1
    62 #define NO_PINLINE1 1
    63 #endif
    64 
    65 // determines inlining of constant time poly procs
    66 #undef NO_PINLINE2
    67 #if PDEBUG <= 1 && !defined(NO_INLINE2)
    68 #define PINLINE2 static inline
    69 #else
    70 #define PINLINE2
    71 #define NO_PINLINE2 1
    72 #endif
    73 
    74 // determines inlining of stuff from polys-impl.h
    75 #undef NO_PINLINE3
    76 #if PDEBUG <= 2 && !defined(NO_INLINE3)
    77 #define PINLINE3 static inline
    78 #else
    79 #define PINLINE3
    80 #define NO_PINLINE3 1
    81 #endif
    8243
    8344/***************************************************************
  • polys/monomials/p_polys.h

    r356ffbb ra04c5e  
    1515#include "ring.h"
    1616#include "polys-impl.h"
    17 /*
    18  Some general remarks:
    19  We divide poly operations into roughly 4 categories:
    20  Level 2: operations on monomials/polynomials with constant time,
    21           or operations which are just dispatchers to other
    22           poly routines
    23           - implemented in: pInline2.h
    24           - debugging only if PDEBUG >= 2
    25           - normally inlined, unless PDEBUG >= 2 || NO_INLINE2
    26  Level 1: operations on monomials with time proportional to length
    27           - implemented in: pInline1.h
    28           - debugging only if PDEBUG >= 1
    29           - normally inlined, unless PDEBUG >= 1 || NO_INLINE1
    30  Level 0: short operations on polynomials with time proportional to
    31           length of poly
    32           - implemented in pInline0.cc
    33           - debugging if PDEBUG
    34           - normally _not_ inlined: can be forced with
    35             #define DO_PINLINE0
    36             #include "pInline0.h"
    37  Misc   : operations on polynomials which do not fit in any of the
    38           above categories
    39           - implemented in: polys*.cc
    40           - never inlined
    41           - debugging if PDEBUG >= 0
    42 
    43  You can set PDEBUG on a per-file basis, before including "mod2.h" like
    44    #define PDEBUG 2
    45    #include "mod2.h"
    46  However, PDEBUG will only be in effect, if !NDEBUG.
    47 */
    4817
    4918/***************************************************************
     
    6433#define p_SetCoeff0(p,n,r)  pSetCoeff0(p,n)
    6534// deletes old p->coef and sets new one
    66 PINLINE2 number p_SetCoeff(poly p, number n, ring r);
     35static inline number p_SetCoeff(poly p, number n, ring r);
    6736
    6837// get Order
    69 PINLINE2 long p_GetOrder(poly p, ring r);
     38static inline long p_GetOrder(poly p, ring r);
    7039
    7140// Component
    7241#define p_GetComp(p, r)     _p_GetComp(p, r)
    73 PINLINE2 unsigned long p_SetComp(poly p, unsigned long c, ring r);
    74 PINLINE2 unsigned long p_AddComp(poly p, unsigned long v, ring r);
    75 PINLINE2 unsigned long p_SubComp(poly p, unsigned long v, ring r);
     42static inline unsigned long p_SetComp(poly p, unsigned long c, ring r);
     43static inline unsigned long p_AddComp(poly p, unsigned long v, ring r);
     44static inline unsigned long p_SubComp(poly p, unsigned long v, ring r);
    7645
    7746// Exponent
    78 PINLINE2 long p_GetExp(poly p, int v, ring r);
    79 PINLINE2 long p_SetExp(poly p, int v, long e, ring r);
    80 PINLINE2 long p_IncrExp(poly p, int v, ring r);
    81 PINLINE2 long p_DecrExp(poly p, int v, ring r);
    82 PINLINE2 long p_AddExp(poly p, int v, long ee, ring r);
    83 PINLINE2 long p_SubExp(poly p, int v, long ee, ring r);
    84 PINLINE2 long p_MultExp(poly p, int v, long ee, ring r);
    85 PINLINE2 long p_GetExpSum(poly p1, poly p2, int i, ring r);
    86 PINLINE2 long p_GetExpDiff(poly p1, poly p2, int i, ring r);
     47static inline long p_GetExp(poly p, int v, ring r);
     48static inline long p_SetExp(poly p, int v, long e, ring r);
     49static inline long p_IncrExp(poly p, int v, ring r);
     50static inline long p_DecrExp(poly p, int v, ring r);
     51static inline long p_AddExp(poly p, int v, long ee, ring r);
     52static inline long p_SubExp(poly p, int v, long ee, ring r);
     53static inline long p_MultExp(poly p, int v, long ee, ring r);
     54static inline long p_GetExpSum(poly p1, poly p2, int i, ring r);
     55static inline long p_GetExpDiff(poly p1, poly p2, int i, ring r);
    8756
    8857/***************************************************************
     
    9261 *
    9362 ***************************************************************/
    94 PINLINE2 poly p_New(ring r);
    95 PINLINE2 poly p_New(ring r, omBin bin);
    96 PINLINE1 poly p_Init(ring r);
    97 PINLINE1 poly p_Init(ring r, omBin bin);
    98 PINLINE1 poly p_LmInit(poly p, ring r);
    99 PINLINE1 poly p_LmInit(poly s_p, ring s_r, ring d_p);
    100 PINLINE1 poly p_LmInit(poly s_p, ring s_r, ring d_p, omBin d_bin);
    101 PINLINE1 poly p_Head(poly p, ring r);
    102 PINLINE2 void p_LmFree(poly p, ring r);
    103 PINLINE2 void p_LmFree(poly *p, ring r);
    104 PINLINE2 poly p_LmFreeAndNext(poly p, ring r);
    105 PINLINE2 void p_LmDelete(poly p, ring r);
    106 PINLINE2 void p_LmDelete(poly *p, ring r);
    107 PINLINE2 poly p_LmDeleteAndNext(poly p, ring r);
     63static inline poly p_New(ring r);
     64static inline poly p_New(ring r, omBin bin);
     65static inline poly p_Init(ring r);
     66static inline poly p_Init(ring r, omBin bin);
     67static inline poly p_LmInit(poly p, ring r);
     68static inline poly p_LmInit(poly s_p, ring s_r, ring d_p);
     69static inline poly p_LmInit(poly s_p, ring s_r, ring d_p, omBin d_bin);
     70static inline poly p_Head(poly p, ring r);
     71static inline void p_LmFree(poly p, ring r);
     72static inline void p_LmFree(poly *p, ring r);
     73static inline poly p_LmFreeAndNext(poly p, ring r);
     74static inline void p_LmDelete(poly p, ring r);
     75static inline void p_LmDelete(poly *p, ring r);
     76static inline poly p_LmDeleteAndNext(poly p, ring r);
    10877
    10978/***************************************************************
     
    11382 ***************************************************************/
    11483// ExpVextor(d_p) = ExpVector(s_p)
    115 PINLINE1 void p_ExpVectorCopy(poly d_p, poly s_p, ring r);
     84static inline void p_ExpVectorCopy(poly d_p, poly s_p, ring r);
    11685// adjustments for negative weights
    117 PINLINE1 void p_MemAdd_NegWeightAdjust(poly p, ring r);
    118 PINLINE1 void p_MemSub_NegWeightAdjust(poly p, ring r);
     86static inline void p_MemAdd_NegWeightAdjust(poly p, ring r);
     87static inline void p_MemSub_NegWeightAdjust(poly p, ring r);
    11988// ExpVector(p1) += ExpVector(p2)
    120 PINLINE1 void p_ExpVectorAdd(poly p1, poly p2, ring r);
     89static inline void p_ExpVectorAdd(poly p1, poly p2, ring r);
    12190// ExpVector(p1) -= ExpVector(p2)
    122 PINLINE1 void p_ExpVectorSub(poly p1, poly p2, ring r);
     91static inline void p_ExpVectorSub(poly p1, poly p2, ring r);
    12392// ExpVector(p1) += ExpVector(p2) - ExpVector(p3)
    124 PINLINE1 void p_ExpVectorAddSub(poly p1, poly p2, poly p3, ring r);
     93static inline void p_ExpVectorAddSub(poly p1, poly p2, poly p3, ring r);
    12594// ExpVector(pr) = ExpVector(p1) + ExpVector(p2)
    126 PINLINE1 void p_ExpVectorSum(poly pr, poly p1, poly p2, ring r);
     95static inline void p_ExpVectorSum(poly pr, poly p1, poly p2, ring r);
    12796/// ExpVector(pr) = ExpVector(p1) + ExpVector(p2)
    128 PINLINE1 void p_ExpVectorDiff(poly pr, poly p1, poly p2, ring r);
     97static inline void p_ExpVectorDiff(poly pr, poly p1, poly p2, ring r);
    12998/// returns TRUE if ExpVector(p1) == ExpVector(p2), FALSE, otherwise
    130 PINLINE1 BOOLEAN p_ExpVectorEqual(poly p1, poly p2, ring r);
     99static inline BOOLEAN p_ExpVectorEqual(poly p1, poly p2, ring r);
    131100/// compute the degree of the leading monomial of p
    132101/// with respect to weigths 1
    133102/// the ordering may not be compatible with degree so do not use p->Order
    134 PINLINE1 long p_Totaldegree(poly p, ring r);
    135 
    136 PINLINE1 void p_GetExpV(poly p, int *ev, ring r);
    137 PINLINE1 void p_SetExpV(poly p, int *ev, ring r);
     103static inline long p_Totaldegree(poly p, ring r);
     104
     105static inline void p_GetExpV(poly p, int *ev, ring r);
     106static inline void p_SetExpV(poly p, int *ev, ring r);
    138107
    139108
     
    143112 *
    144113 ***************************************************************/
    145 PINLINE1 int p_LmCmp(poly p, poly q, ring r);
     114static inline int p_LmCmp(poly p, poly q, ring r);
    146115#define p_LmCmpAction(p, q, r, actionE, actionG, actionS) \
    147116  _p_LmCmpAction(p, q, r, actionE, actionG, actionS)
     
    152121// pCmp: args may be NULL
    153122// returns: (p2==NULL ? 1 : (p1 == NULL ? -1 : p_LmCmp(p1, p2)))
    154 PINLINE2 int p_Cmp(poly p1, poly p2, ring r);
     123static inline int p_Cmp(poly p1, poly p2, ring r);
    155124
    156125
     
    161130 *
    162131 ***************************************************************/
    163 PINLINE1 BOOLEAN p_DivisibleBy(poly a, poly b, ring r);
    164 PINLINE1 BOOLEAN p_LmDivisibleBy(poly a, poly b, ring r);
    165 PINLINE1 BOOLEAN p_LmDivisibleByNoComp(poly a, poly b, ring r);
     132static inline BOOLEAN p_DivisibleBy(poly a, poly b, ring r);
     133static inline BOOLEAN p_LmDivisibleBy(poly a, poly b, ring r);
     134static inline BOOLEAN p_LmDivisibleByNoComp(poly a, poly b, ring r);
    166135unsigned long p_GetShortExpVector(poly a, ring r);
    167 PINLINE1 BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a,
     136static inline BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a,
    168137                                      poly b, unsigned long not_sev_b, ring r);
    169138
    170 PINLINE1 BOOLEAN p_DivisibleBy(poly a, ring r_a, poly b, ring r_b);
    171 PINLINE1 BOOLEAN p_LmDivisibleBy(poly a, ring r_a, poly b, ring r_b);
    172 PINLINE1 BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a, ring r_a,
     139static inline BOOLEAN p_DivisibleBy(poly a, ring r_a, poly b, ring r_b);
     140static inline BOOLEAN p_LmDivisibleBy(poly a, ring r_a, poly b, ring r_b);
     141static inline BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a, ring r_a,
    173142                                      poly b, unsigned long not_sev_b, ring r_b);
    174143
     
    180149// test if the monomial is a constant as a vector component
    181150// i.e., test if all exponents are zero
    182 PINLINE1 BOOLEAN p_LmIsConstantComp(const poly p, const ring r);
    183 PINLINE1 BOOLEAN p_LmIsConstant(const poly p, const ring r);
     151static inline BOOLEAN p_LmIsConstantComp(const poly p, const ring r);
     152static inline BOOLEAN p_LmIsConstant(const poly p, const ring r);
    184153
    185154// return TRUE, if p_LmExpVectorAdd stays within ExpBound of ring r,
    186155//       FALSE, otherwise
    187 PINLINE1 BOOLEAN p_LmExpVectorAddIsOk(const poly p1, const poly p2, ring r);
     156static inline BOOLEAN p_LmExpVectorAddIsOk(const poly p1, const poly p2, ring r);
    188157
    189158/***************************************************************
     
    193162 ***************************************************************/
    194163// return the maximal exponent of p
    195 PINLINE2 unsigned long p_GetMaxExp(poly p, ring r);
     164static inline unsigned long p_GetMaxExp(poly p, ring r);
    196165// return the maximal exponent of p in form of the maximal long var
    197166unsigned long p_GetMaxExpL(poly p, const ring r, unsigned long l_max = 0);
     
    201170
    202171// suppose that l is a long var in r, return maximal exponent of l
    203 PINLINE2 unsigned long p_GetMaxExp(const unsigned long l, const ring r);
     172static inline unsigned long p_GetMaxExp(const unsigned long l, const ring r);
    204173
    205174// return the TotalDegree of the long var l
    206 PINLINE2 unsigned long p_GetTotalDegree(const unsigned long l, const ring r);
     175static inline unsigned long p_GetTotalDegree(const unsigned long l, const ring r);
    207176// return the total degree of the long var l containing number_of_exp exponents
    208 PINLINE2 unsigned long p_GetTotalDegree(const unsigned long l, const ring r, const int number_of_exps);
     177static inline unsigned long p_GetTotalDegree(const unsigned long l, const ring r, const int number_of_exps);
    209178
    210179
    211180// like the respective p_LmIs* routines, except that p might be empty
    212 PINLINE1 BOOLEAN p_IsConstantComp(const poly p, const ring r);
    213 PINLINE1 BOOLEAN p_IsConstant(const poly p, const ring r);
     181static inline BOOLEAN p_IsConstantComp(const poly p, const ring r);
     182static inline BOOLEAN p_IsConstant(const poly p, const ring r);
    214183PINLINE0 BOOLEAN p_IsConstantPoly(const poly p, const ring r);
    215184
     
    239208 ***************************************************************/
    240209// returns a copy of p
    241 PINLINE2 poly p_Copy(poly p, const ring r);
     210static inline poly p_Copy(poly p, const ring r);
    242211// returns a copy of p with Lm(p) from lmRing and Tail(p) from tailRing
    243 PINLINE2 poly p_Copy(poly p, const ring lmRing, const ring tailRing);
     212static inline poly p_Copy(poly p, const ring lmRing, const ring tailRing);
    244213// deletes *p, and sets *p to NULL
    245 PINLINE2 void p_Delete(poly *p, const ring r);
    246 PINLINE2 void p_Delete(poly *p, const ring lmRing, const ring tailRing);
     214static inline void p_Delete(poly *p, const ring r);
     215static inline void p_Delete(poly *p, const ring lmRing, const ring tailRing);
    247216
    248217// copys monomials of p, allocates new monomials from bin,
    249218// deletes monomoals of p
    250 PINLINE2 poly p_ShallowCopyDelete(poly p, const ring r, omBin bin);
     219static inline poly p_ShallowCopyDelete(poly p, const ring r, omBin bin);
    251220// simial but does it only for leading monomial
    252 PINLINE1 poly p_LmShallowCopyDelete(poly p, const ring r, omBin bin);
     221static inline poly p_LmShallowCopyDelete(poly p, const ring r, omBin bin);
    253222// simply deletes monomials, does not free coeffs
    254223void p_ShallowDelete(poly *p, const ring r);
     
    267236 ***************************************************************/
    268237// returns -p, p is destroyed
    269 PINLINE2 poly p_Neg(poly p, const ring r);
     238static inline poly p_Neg(poly p, const ring r);
    270239
    271240// returns p*n, p is const (i.e. copied)
    272 PINLINE2 poly pp_Mult_nn(poly p, number n, const ring r);
     241static inline poly pp_Mult_nn(poly p, number n, const ring r);
    273242// returns p*n, destroys p
    274 PINLINE2 poly p_Mult_nn(poly p, number n, const ring r);
    275 PINLINE2 poly p_Mult_nn(poly p, number n, const ring lmRing, const ring tailRing);
     243static inline poly p_Mult_nn(poly p, number n, const ring r);
     244static inline poly p_Mult_nn(poly p, number n, const ring lmRing, const ring tailRing);
    276245
    277246// returns p*m, does neither destroy p nor m
    278 PINLINE2 poly pp_Mult_mm(poly p, poly m, const ring r);
     247static inline poly pp_Mult_mm(poly p, poly m, const ring r);
    279248// returns p*m, destroys p, const: m
    280 PINLINE2 poly p_Mult_mm(poly p, poly m, const ring r);
     249static inline poly p_Mult_mm(poly p, poly m, const ring r);
    281250
    282251// returns p+q, destroys p and q
    283 PINLINE2 poly p_Add_q(poly p, poly q, const ring r);
     252static inline poly p_Add_q(poly p, poly q, const ring r);
    284253// like p_Add_q, except that if lp == pLength(lp) lq == pLength(lq)
    285254// then lp == pLength(p+q)
    286 PINLINE2 poly p_Add_q(poly p, poly q, int &lp, int lq, const ring r);
     255static inline poly p_Add_q(poly p, poly q, int &lp, int lq, const ring r);
    287256
    288257// return p - m*q, destroys p; const: q,m
    289 PINLINE2 poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, const ring r);
     258static inline poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, const ring r);
    290259// like p_Minus_mm_Mult_qq, except that if lp == pLength(lp) lq == pLength(lq)
    291260// then lp == pLength(p -m*q)
    292 PINLINE2 poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,
     261static inline poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,
    293262                                 poly spNoether, const ring r);
    294263// returns p + m*q destroys p, const: q, m
    295 PINLINE2 poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, const ring r);
     264static inline poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, const ring r);
    296265
    297266// returns p + m*q destroys p, const: q, m
    298 PINLINE2 poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,
     267static inline poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,
    299268                                const ring r);
    300269
    301270// returns p*q, destroys p and q
    302 PINLINE2 poly p_Mult_q(poly p, poly q, const ring r);
     271static inline poly p_Mult_q(poly p, poly q, const ring r);
    303272// returns p*q, does neither destroy p nor q
    304 PINLINE2 poly pp_Mult_qq(poly p, poly q, const ring r);
     273static inline poly pp_Mult_qq(poly p, poly q, const ring r);
    305274
    306275// returns p*Coeff(m) for such monomials pm of p, for which m is divisble by pm
    307 PINLINE2 poly pp_Mult_Coeff_mm_DivSelect(poly p, const poly m, const ring r);
     276static inline poly pp_Mult_Coeff_mm_DivSelect(poly p, const poly m, const ring r);
    308277
    309278// returns p*Coeff(m) for such monomials pm of p, for which m is divisble by pm
    310279// if lp is length of p on input then lp is length of returned poly on output
    311 PINLINE2 poly pp_Mult_Coeff_mm_DivSelect(poly p, int &lp, const poly m, const ring r);
     280static inline poly pp_Mult_Coeff_mm_DivSelect(poly p, int &lp, const poly m, const ring r);
    312281
    313282// returns merged p and q, assumes p and q have no monomials which are equal
    314 PINLINE2 poly p_Merge_q(poly p, poly c, const ring r);
     283static inline poly p_Merge_q(poly p, poly c, const ring r);
    315284// sorts p using bucket sort: returns sorted poly
    316285// assumes that monomials of p are all different
    317286// reverses it first, if revert == TRUE, use this if input p is "almost" sorted
    318287// correctly
    319 PINLINE2 poly p_SortMerge(poly p, const ring r, BOOLEAN revert = FALSE);
     288static inline poly p_SortMerge(poly p, const ring r, BOOLEAN revert = FALSE);
    320289// like SortMerge, except that p may have equal monimals
    321 PINLINE2 poly p_SortAdd(poly p, const ring r, BOOLEAN revert = FALSE);
     290static inline poly p_SortAdd(poly p, const ring r, BOOLEAN revert = FALSE);
    322291
    323292/***************************************************************
     
    326295 *
    327296 ***************************************************************/
    328 PINLINE2 void p_Setm(poly p, const ring r);
     297static inline void p_Setm(poly p, const ring r);
    329298p_SetmProc p_GetSetmProc(ring r);
    330299
     
    362331void      p_wrp(poly p, ring lmRing, ring tailRing);
    363332
    364 PINLINE2 char*     p_String(poly p, ring p_ring);
    365 PINLINE2 char*     p_String0(poly p, ring p_ring);
    366 PINLINE2 void      p_Write(poly p, ring p_ring);
    367 PINLINE2 void      p_Write0(poly p, ring p_ring);
    368 PINLINE2 void      p_wrp(poly p, ring p_ring);
     333static inline char*     p_String(poly p, ring p_ring);
     334static inline char*     p_String0(poly p, ring p_ring);
     335static inline void      p_Write(poly p, ring p_ring);
     336static inline void      p_Write0(poly p, ring p_ring);
     337static inline void      p_wrp(poly p, ring p_ring);
    369338
    370339
     
    447416#endif
    448417
    449 #include <kernel/pInline2.h>
    450 #include <kernel/pInline1.h>
    451 
     418/***************************************************************
     419 *
     420 * Primitives for accessing and setting fields of a poly
     421 *
     422 ***************************************************************/
     423
     424static inline number p_SetCoeff(poly p, number n, ring r)
     425{
     426  p_LmCheckPolyRing2(p, r);
     427  n_Delete(&(p->coef), r);
     428  (p)->coef=n;
     429  return n;
     430}
     431
     432// order
     433static inline long p_GetOrder(poly p, ring r)
     434{
     435  p_LmCheckPolyRing2(p, r);
     436  if (r->typ==NULL) return ((p)->exp[r->pOrdIndex]);
     437  int i=0;
     438  loop
     439  {
     440    switch(r->typ[i].ord_typ)
     441    {
     442      case ro_wp_neg:
     443        return (((long)((p)->exp[r->pOrdIndex]))-POLY_NEGWEIGHT_OFFSET);
     444      case ro_syzcomp:
     445      case ro_syz:
     446      case ro_cp:
     447        i++;
     448        break;
     449      //case ro_dp:
     450      //case ro_wp:
     451      default:
     452        return ((p)->exp[r->pOrdIndex]);
     453    }
     454  }
     455}
     456
     457// Setm
     458static inline void p_Setm(poly p, const ring r)
     459{
     460  p_CheckRing2(r);
     461  r->p_Setm(p, r);
     462}
     463
     464// component
     465static inline  unsigned long p_SetComp(poly p, unsigned long c, ring r)
     466{
     467  p_LmCheckPolyRing2(p, r);
     468  pAssume2(rRing_has_Comp(r));
     469  __p_GetComp(p,r) = c;
     470  return c;
     471}
     472static inline unsigned long p_AddComp(poly p, unsigned long v, ring r)
     473{
     474  p_LmCheckPolyRing2(p, r);
     475  pAssume2(rRing_has_Comp(r));
     476  return __p_GetComp(p,r) += v;
     477}
     478static inline unsigned long p_SubComp(poly p, unsigned long v, ring r)
     479{
     480  p_LmCheckPolyRing2(p, r);
     481  pAssume2(rRing_has_Comp(r));
     482  pPolyAssume2(__p_GetComp(p,r) >= v,p,r);
     483  return __p_GetComp(p,r) -= v;
     484}
     485static inline int p_Comp_k_n(poly a, poly b, int k, ring r)
     486{
     487  if ((a==NULL) || (b==NULL) ) return FALSE;
     488  p_LmCheckPolyRing2(a, r);
     489  p_LmCheckPolyRing2(b, r);
     490  pAssume2(k > 0 && k <= r->N);
     491  int i=k;
     492  for(;i<=r->N;i++)
     493  {
     494    if (p_GetExp(a,i,r) != p_GetExp(b,i,r)) return FALSE;
     495    //    if (a->exp[(r->VarOffset[i] & 0xffffff)] != b->exp[(r->VarOffset[i] & 0xffffff)]) return FALSE;
     496  }
     497  return TRUE;
     498}
     499
     500#ifndef HAVE_EXPSIZES
     501
     502/// get a single variable exponent
     503/// @Note:
     504/// the integer VarOffset encodes:
     505/// 1. the position of a variable in the exponent vector p->exp (lower 24 bits)
     506/// 2. number of bits to shift to the right in the upper 8 bits (which takes at most 6 bits for 64 bit)
     507/// Thus VarOffset always has 2 zero higher bits!
     508static inline long p_GetExp(const poly p, const unsigned long iBitmask, const int VarOffset)
     509{
     510  pAssume2((VarOffset >> (24 + 6)) == 0);
     511#if 0
     512  int pos=(VarOffset & 0xffffff);
     513  int bitpos=(VarOffset >> 24);
     514  unsigned long exp=(p->exp[pos] >> bitmask) & iBitmask;
     515  return exp;
     516#else
     517  return (long)
     518         ((p->exp[(VarOffset & 0xffffff)] >> (VarOffset >> 24))
     519          & iBitmask);
     520#endif
     521}
     522
     523
     524/// set a single variable exponent
     525/// @Note:
     526/// VarOffset encodes the position in p->exp @see p_GetExp
     527static inline unsigned long p_SetExp(poly p, const unsigned long e, const unsigned long iBitmask, const int VarOffset)
     528{
     529  pAssume2(e>=0);
     530  pAssume2(e<=iBitmask);
     531  pAssume2((VarOffset >> (24 + 6)) == 0);
     532
     533  // shift e to the left:
     534  register int shift = VarOffset >> 24;
     535  unsigned long ee = e << shift /*(VarOffset >> 24)*/;
     536  // find the bits in the exponent vector
     537  register int offset = (VarOffset & 0xffffff);
     538  // clear the bits in the exponent vector:
     539  p->exp[offset]  &= ~( iBitmask << shift );
     540  // insert e with |
     541  p->exp[ offset ] |= ee;
     542  return e;
     543}
     544
     545
     546#else // #ifdef HAVE_EXPSIZES // EXPERIMENTAL!!!
     547
     548static inline unsigned long BitMask(unsigned long bitmask, int twobits)
     549{
     550  // bitmask = 00000111111111111
     551  // 0 must give bitmask!
     552  // 1, 2, 3 - anything like 00011..11
     553  pAssume2((twobits >> 2) == 0);
     554  static const unsigned long _bitmasks[4] = {-1, 0x7fff, 0x7f, 0x3};
     555  return bitmask & _bitmasks[twobits];
     556}
     557
     558
     559/// @Note: we may add some more info (6 ) into VarOffset and thus encode
     560static inline long p_GetExp(const poly p, const unsigned long iBitmask, const int VarOffset)
     561{
     562  int pos  =(VarOffset & 0xffffff);
     563  int hbyte= (VarOffset >> 24); // the highest byte
     564  int bitpos = hbyte & 0x3f; // last 6 bits
     565  long bitmask = BitMask(iBitmask, hbyte >> 6);
     566
     567  long exp=(p->exp[pos] >> bitpos) & bitmask;
     568  return exp;
     569
     570}
     571
     572static inline long p_SetExp(poly p, const long e, const unsigned long iBitmask, const int VarOffset)
     573{
     574  pAssume2(e>=0);
     575  pAssume2(e <= BitMask(iBitmask, VarOffset >> 30));
     576
     577  // shift e to the left:
     578  register int hbyte = VarOffset >> 24;
     579  int bitmask = BitMask(iBitmask, hbyte >> 6);
     580  register int shift = hbyte & 0x3f;
     581  long ee = e << shift;
     582  // find the bits in the exponent vector
     583  register int offset = (VarOffset & 0xffffff);
     584  // clear the bits in the exponent vector:
     585  p->exp[offset]  &= ~( bitmask << shift );
     586  // insert e with |
     587  p->exp[ offset ] |= ee;
     588  return e;
     589}
     590
     591#endif // #ifndef HAVE_EXPSIZES
     592
     593
     594static inline long p_GetExp(const poly p, const ring r, const int VarOffset)
     595{
     596  p_LmCheckPolyRing2(p, r);
     597  pAssume2(VarOffset != -1);
     598  return p_GetExp(p, r->bitmask, VarOffset);
     599}
     600
     601static inline long p_SetExp(poly p, const long e, const ring r, const int VarOffset)
     602{
     603  p_LmCheckPolyRing2(p, r);
     604  pAssume2(VarOffset != -1);
     605  return p_SetExp(p, e, r->bitmask, VarOffset);
     606}
     607
     608
     609
     610/// get v^th exponent for a monomial
     611static inline long p_GetExp(const poly p, const int v, const ring r)
     612{
     613  p_LmCheckPolyRing2(p, r);
     614  pAssume2(v>0 && v <= r->N);
     615  pAssume2(r->VarOffset[v] != -1);
     616  return p_GetExp(p, r->bitmask, r->VarOffset[v]);
     617}
     618
     619
     620/// set v^th exponent for a monomial
     621static inline long p_SetExp(poly p, const int v, const long e, const ring r)
     622{
     623  p_LmCheckPolyRing2(p, r);
     624  pAssume2(v>0 && v <= r->N);
     625  pAssume2(r->VarOffset[v] != -1);
     626  return p_SetExp(p, e, r->bitmask, r->VarOffset[v]);
     627}
     628
     629
     630
     631
     632
     633// the following should be implemented more efficiently
     634static inline  long p_IncrExp(poly p, int v, ring r)
     635{
     636  p_LmCheckPolyRing2(p, r);
     637  int e = p_GetExp(p,v,r);
     638  e++;
     639  return p_SetExp(p,v,e,r);
     640}
     641static inline  long p_DecrExp(poly p, int v, ring r)
     642{
     643  p_LmCheckPolyRing2(p, r);
     644  int e = p_GetExp(p,v,r);
     645  pAssume2(e > 0);
     646  e--;
     647  return p_SetExp(p,v,e,r);
     648}
     649static inline  long p_AddExp(poly p, int v, long ee, ring r)
     650{
     651  p_LmCheckPolyRing2(p, r);
     652  int e = p_GetExp(p,v,r);
     653  e += ee;
     654  return p_SetExp(p,v,e,r);
     655}
     656static inline  long p_SubExp(poly p, int v, long ee, ring r)
     657{
     658  p_LmCheckPolyRing2(p, r);
     659  long e = p_GetExp(p,v,r);
     660  pAssume2(e >= ee);
     661  e -= ee;
     662  return p_SetExp(p,v,e,r);
     663}
     664static inline  long p_MultExp(poly p, int v, long ee, ring r)
     665{
     666  p_LmCheckPolyRing2(p, r);
     667  long e = p_GetExp(p,v,r);
     668  e *= ee;
     669  return p_SetExp(p,v,e,r);
     670}
     671
     672static inline long p_GetExpSum(poly p1, poly p2, int i, ring r)
     673{
     674  p_LmCheckPolyRing2(p1, r);
     675  p_LmCheckPolyRing2(p2, r);
     676  return p_GetExp(p1,i,r) + p_GetExp(p2,i,r);
     677}
     678static inline long p_GetExpDiff(poly p1, poly p2, int i, ring r)
     679{
     680  return p_GetExp(p1,i,r) - p_GetExp(p2,i,r);
     681}
     682
     683
     684/***************************************************************
     685 *
     686 * Allocation/Initalization/Deletion
     687 *
     688 ***************************************************************/
     689static inline poly p_New(ring r, omBin bin)
     690{
     691  p_CheckRing2(r);
     692  pAssume2(bin != NULL && r->PolyBin->sizeW == bin->sizeW);
     693  poly p;
     694  omTypeAllocBin(poly, p, bin);
     695  p_SetRingOfLm(p, r);
     696  return p;
     697}
     698
     699static inline poly p_New(ring r)
     700{
     701  return p_New(r, r->PolyBin);
     702}
     703
     704static inline void p_LmFree(poly p, ring r)
     705{
     706  p_LmCheckPolyRing2(p, r);
     707  omFreeBinAddr(p);
     708}
     709static inline void p_LmFree(poly *p, ring r)
     710{
     711  p_LmCheckPolyRing2(*p, r);
     712  poly h = *p;
     713  *p = pNext(h);
     714  omFreeBinAddr(h);
     715}
     716static inline poly p_LmFreeAndNext(poly p, ring r)
     717{
     718  p_LmCheckPolyRing2(p, r);
     719  poly pnext = pNext(p);
     720  omFreeBinAddr(p);
     721  return pnext;
     722}
     723static inline void p_LmDelete(poly p, ring r)
     724{
     725  p_LmCheckPolyRing2(p, r);
     726  n_Delete(&pGetCoeff(p), r);
     727  omFreeBinAddr(p);
     728}
     729static inline void p_LmDelete(poly *p, ring r)
     730{
     731  p_LmCheckPolyRing2(*p, r);
     732  poly h = *p;
     733  *p = pNext(h);
     734  n_Delete(&pGetCoeff(h), r);
     735  omFreeBinAddr(h);
     736}
     737static inline poly p_LmDeleteAndNext(poly p, ring r)
     738{
     739  p_LmCheckPolyRing2(p, r);
     740  poly pnext = pNext(p);
     741  n_Delete(&pGetCoeff(p), r);
     742  omFreeBinAddr(p);
     743  return pnext;
     744}
     745
     746/***************************************************************
     747 *
     748 * Misc routines
     749 *
     750 ***************************************************************/
     751static inline int p_Cmp(poly p1, poly p2, ring r)
     752{
     753  if (p2==NULL)
     754    return 1;
     755  if (p1==NULL)
     756    return -1;
     757  return p_LmCmp(p1,p2,r);
     758}
     759
     760static inline unsigned long p_GetMaxExp(const poly p, const ring r)
     761{
     762  return p_GetMaxExp(p_GetMaxExpL(p, r), r);
     763}
     764
     765static inline unsigned long p_GetMaxExp(const unsigned long l, const ring r)
     766{
     767  unsigned long bitmask = r->bitmask;
     768  unsigned long max = (l & bitmask);
     769  unsigned long j = r->ExpPerLong - 1;
     770
     771  if (j > 0)
     772  {
     773    unsigned long i = r->BitsPerExp;
     774    long e;
     775    loop
     776    {
     777      e = ((l >> i) & bitmask);
     778      if ((unsigned long) e > max)
     779        max = e;
     780      j--;
     781      if (j==0) break;
     782      i += r->BitsPerExp;
     783    }
     784  }
     785  return max;
     786}
     787
     788static inline unsigned long
     789p_GetTotalDegree(const unsigned long l, const ring r, const int number_of_exps)
     790{
     791  const unsigned long bitmask = r->bitmask;
     792  unsigned long sum = (l & bitmask);
     793  unsigned long j = number_of_exps - 1;
     794
     795  if (j > 0)
     796  {
     797    unsigned long i = r->BitsPerExp;
     798    loop
     799    {
     800      sum += ((l >> i) & bitmask);
     801      j--;
     802      if (j==0) break;
     803      i += r->BitsPerExp;
     804    }
     805  }
     806  return sum;
     807}
     808
     809static inline unsigned long
     810p_GetTotalDegree(const unsigned long l, const ring r)
     811{
     812  return p_GetTotalDegree(l, r, r->ExpPerLong);
     813}
     814
     815/***************************************************************
     816 *
     817 * Dispatcher to r->p_Procs, they do the tests/checks
     818 *
     819 ***************************************************************/
     820// returns a copy of p
     821static inline poly p_Copy(poly p, const ring r)
     822{
     823#ifdef PDEBUG
     824  poly pp= r->p_Procs->p_Copy(p, r);
     825  p_Test(pp,r);
     826  return pp;
     827#else
     828  return r->p_Procs->p_Copy(p, r);
     829#endif
     830}
     831
     832static inline poly p_Copy(poly p, const ring lmRing, const ring tailRing)
     833{
     834#ifndef PDEBUG
     835  if (tailRing == lmRing)
     836    return tailRing->p_Procs->p_Copy(p, tailRing);
     837#endif
     838  if (p != NULL)
     839  {
     840    poly pres = p_Head(p, lmRing);
     841    pNext(pres) = tailRing->p_Procs->p_Copy(pNext(p), tailRing);
     842    return pres;
     843  }
     844  else
     845    return NULL;
     846}
     847
     848// deletes *p, and sets *p to NULL
     849static inline void p_Delete(poly *p, const ring r)
     850{
     851  r->p_Procs->p_Delete(p, r);
     852}
     853
     854static inline void p_Delete(poly *p,  const ring lmRing, const ring tailRing)
     855{
     856#ifndef PDEBUG
     857  if (tailRing == lmRing)
     858  {
     859    tailRing->p_Procs->p_Delete(p, tailRing);
     860    return;
     861  }
     862#endif
     863  if (*p != NULL)
     864  {
     865    if (pNext(*p) != NULL)
     866      tailRing->p_Procs->p_Delete(&pNext(*p), tailRing);
     867    p_LmDelete(p, lmRing);
     868  }
     869}
     870
     871static inline poly p_ShallowCopyDelete(poly p, const ring r, omBin bin)
     872{
     873  p_LmCheckPolyRing2(p, r);
     874  pAssume2(r->PolyBin->sizeW == bin->sizeW);
     875  return r->p_Procs->p_ShallowCopyDelete(p, r, bin);
     876}
     877
     878// returns p+q, destroys p and q
     879static inline poly p_Add_q(poly p, poly q, const ring r)
     880{
     881  int shorter;
     882  return r->p_Procs->p_Add_q(p, q, shorter, r);
     883}
     884
     885static inline poly p_Add_q(poly p, poly q, int &lp, int lq, const ring r)
     886{
     887  int shorter;
     888  poly res = r->p_Procs->p_Add_q(p, q, shorter, r);
     889  lp = (lp + lq) - shorter;
     890  return res;
     891}
     892
     893// returns p*n, destroys p
     894static inline poly p_Mult_nn(poly p, number n, const ring r)
     895{
     896  if (n_IsOne(n, r))
     897    return p;
     898  else
     899    return r->p_Procs->p_Mult_nn(p, n, r);
     900}
     901
     902static inline poly p_Mult_nn(poly p, number n, const ring lmRing,
     903                        const ring tailRing)
     904{
     905#ifndef PDEBUG
     906  if (lmRing == tailRing)
     907  {
     908    return p_Mult_nn(p, n, tailRing);
     909  }
     910#endif
     911  poly pnext = pNext(p);
     912  pNext(p) = NULL;
     913  p = lmRing->p_Procs->p_Mult_nn(p, n, lmRing);
     914  pNext(p) = tailRing->p_Procs->p_Mult_nn(pnext, n, tailRing);
     915  return p;
     916}
     917
     918// returns p*n, does not destroy p
     919static inline poly pp_Mult_nn(poly p, number n, const ring r)
     920{
     921  if (n_IsOne(n, r))
     922    return p_Copy(p, r);
     923  else
     924    return r->p_Procs->pp_Mult_nn(p, n, r);
     925}
     926
     927// returns Copy(p)*m, does neither destroy p nor m
     928static inline poly pp_Mult_mm(poly p, poly m, const ring r)
     929{
     930  if (p_LmIsConstant(m, r))
     931    return pp_Mult_nn(p, pGetCoeff(m), r);
     932  else
     933  {
     934    poly last;
     935    return r->p_Procs->pp_Mult_mm(p, m, r, last);
     936  }
     937}
     938
     939// returns p*m, destroys p, const: m
     940static inline poly p_Mult_mm(poly p, poly m, const ring r)
     941{
     942  if (p_LmIsConstant(m, r))
     943    return p_Mult_nn(p, pGetCoeff(m), r);
     944  else
     945    return r->p_Procs->p_Mult_mm(p, m, r);
     946}
     947
     948// return p - m*Copy(q), destroys p; const: p,m
     949static inline poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, const ring r)
     950{
     951#ifdef HAVE_PLURAL
     952  if (rIsPluralRing(r))
     953  {
     954    int lp, lq;
     955    poly spNoether;
     956    return nc_p_Minus_mm_Mult_qq(p, m, q, lp, lq, spNoether, r);
     957  }
     958#endif
     959
     960  int shorter;
     961  poly last;
     962
     963  return r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, NULL, r, last); // !!!
     964}
     965
     966static inline poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,
     967                                 poly spNoether, const ring r)
     968{
     969#ifdef HAVE_PLURAL
     970  if (rIsPluralRing(r))
     971     return nc_p_Minus_mm_Mult_qq(p, m, q, lp, lq, spNoether, r);
     972#endif
     973
     974  int shorter;
     975  poly last,res;
     976  res = r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, spNoether, r, last);
     977  lp = (lp + lq) - shorter;
     978  return res;
     979}
     980
     981static inline poly pp_Mult_Coeff_mm_DivSelect(poly p, const poly m, const ring r)
     982{
     983  int shorter;
     984  return r->p_Procs->pp_Mult_Coeff_mm_DivSelect(p, m, shorter, r);
     985}
     986
     987static inline poly pp_Mult_Coeff_mm_DivSelect(poly p, int &lp, const poly m, const ring r)
     988{
     989  int shorter;
     990  poly pp = r->p_Procs->pp_Mult_Coeff_mm_DivSelect(p, m, shorter, r);
     991  lp -= shorter;
     992  return pp;
     993}
     994
     995// returns -p, destroys p
     996static inline poly p_Neg(poly p, const ring r)
     997{
     998  return r->p_Procs->p_Neg(p, r);
     999}
     1000
     1001extern poly  _p_Mult_q(poly p, poly q, const int copy, const ring r);
     1002// returns p*q, destroys p and q
     1003static inline poly p_Mult_q(poly p, poly q, const ring r)
     1004{
     1005  if (p == NULL)
     1006  {
     1007    r->p_Procs->p_Delete(&q, r);
     1008    return NULL;
     1009  }
     1010  if (q == NULL)
     1011  {
     1012    r->p_Procs->p_Delete(&p, r);
     1013    return NULL;
     1014  }
     1015
     1016  if (pNext(p) == NULL)
     1017  {
     1018#ifdef HAVE_PLURAL
     1019    if (rIsPluralRing(r))
     1020      q = nc_mm_Mult_p(p, q, r);
     1021    else
     1022#endif /* HAVE_PLURAL */
     1023      q = r->p_Procs->p_Mult_mm(q, p, r);
     1024
     1025    r->p_Procs->p_Delete(&p, r);
     1026    return q;
     1027  }
     1028
     1029  if (pNext(q) == NULL)
     1030  {
     1031  // NEEDED
     1032#ifdef HAVE_PLURAL
     1033/*    if (rIsPluralRing(r))
     1034      p = gnc_p_Mult_mm(p, q, r); // ???
     1035    else*/
     1036#endif /* HAVE_PLURAL */
     1037      p = r->p_Procs->p_Mult_mm(p, q, r);
     1038
     1039    r->p_Procs->p_Delete(&q, r);
     1040    return p;
     1041  }
     1042#ifdef HAVE_PLURAL
     1043  if (rIsPluralRing(r))
     1044    return _nc_p_Mult_q(p, q, r);
     1045  else
     1046#endif
     1047  return _p_Mult_q(p, q, 0, r);
     1048}
     1049
     1050// returns p*q, does neither destroy p nor q
     1051static inline poly pp_Mult_qq(poly p, poly q, const ring r)
     1052{
     1053  poly last;
     1054  if (p == NULL || q == NULL) return NULL;
     1055
     1056  if (pNext(p) == NULL)
     1057  {
     1058#ifdef HAVE_PLURAL
     1059    if (rIsPluralRing(r))
     1060      return nc_mm_Mult_pp(p, q, r);
     1061#endif
     1062    return r->p_Procs->pp_Mult_mm(q, p, r, last);
     1063  }
     1064
     1065  if (pNext(q) == NULL)
     1066  {
     1067    return r->p_Procs->pp_Mult_mm(p, q, r, last);
     1068  }
     1069
     1070  poly qq = q;
     1071  if (p == q)
     1072    qq = p_Copy(q, r);
     1073
     1074  poly res;
     1075#ifdef HAVE_PLURAL
     1076  if (rIsPluralRing(r))
     1077    res = _nc_pp_Mult_qq(p, qq, r);
     1078  else
     1079#endif
     1080    res = _p_Mult_q(p, qq, 1, r);
     1081
     1082  if (qq != q)
     1083    p_Delete(&qq, r);
     1084  return res;
     1085}
     1086
     1087// returns p + m*q destroys p, const: q, m
     1088static inline poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,
     1089                                const ring r)
     1090{
     1091#ifdef HAVE_PLURAL
     1092  if (rIsPluralRing(r))
     1093    return nc_p_Plus_mm_Mult_qq(p, m, q, lp, lq, r);
     1094#endif
     1095
     1096// this should be implemented more efficiently
     1097  poly res, last;
     1098  int shorter;
     1099  number n_old = pGetCoeff(m);
     1100  number n_neg = n_Copy(n_old, r);
     1101  n_neg = n_Neg(n_neg, r);
     1102  pSetCoeff0(m, n_neg);
     1103  res = r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, NULL, r, last);
     1104  lp = (lp + lq) - shorter;
     1105  pSetCoeff0(m, n_old);
     1106  n_Delete(&n_neg, r);
     1107  return res;
     1108}
     1109
     1110static inline poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, const ring r)
     1111{
     1112  int lp = 0, lq = 0;
     1113  return p_Plus_mm_Mult_qq(p, m, q, lp, lq, r);
     1114}
     1115
     1116static inline poly p_Merge_q(poly p, poly q, const ring r)
     1117{
     1118  return r->p_Procs->p_Merge_q(p, q, r);
     1119}
     1120
     1121static inline poly p_SortAdd(poly p, const ring r, BOOLEAN revert)
     1122{
     1123  if (revert) p = pReverse(p);
     1124  return sBucketSortAdd(p, r);
     1125}
     1126
     1127static inline poly p_SortMerge(poly p, const ring r, BOOLEAN revert)
     1128{
     1129  if (revert) p = pReverse(p);
     1130  return sBucketSortMerge(p, r);
     1131}
     1132
     1133/***************************************************************
     1134 *
     1135 * I/O
     1136 *
     1137 ***************************************************************/
     1138static inline char*     p_String(poly p, ring p_ring)
     1139{
     1140  return p_String(p, p_ring, p_ring);
     1141}
     1142static inline char*     p_String0(poly p, ring p_ring)
     1143{
     1144  return p_String0(p, p_ring, p_ring);
     1145}
     1146static inline void      p_Write(poly p, ring p_ring)
     1147{
     1148  p_Write(p, p_ring, p_ring);
     1149}
     1150static inline void      p_Write0(poly p, ring p_ring)
     1151{
     1152  p_Write0(p, p_ring, p_ring);
     1153}
     1154static inline void      p_wrp(poly p, ring p_ring)
     1155{
     1156  p_wrp(p, p_ring, p_ring);
     1157}
     1158
     1159/***************************************************************
     1160 *  Purpose: implementation of poly procs which iter over ExpVector
     1161 *  Author:  obachman (Olaf Bachmann)
     1162 *  Created: 8/00
     1163 *  Version: $Id$
     1164 *******************************************************************/
     1165#include <mylimits.h>
     1166#include "p_MemCmp.h"
     1167#include "structs.h"
     1168#include "ring.h"
     1169#include <coeffs.h>
     1170
     1171#if PDEBUG > 0
     1172
     1173#define _p_LmCmpAction(p, q, r, actionE, actionG, actionS)  \
     1174do                                                          \
     1175{                                                           \
     1176  int _cmp = p_LmCmp(p,q,r);                                \
     1177  if (_cmp == 0) actionE;                                   \
     1178  if (_cmp == 1) actionG;                                   \
     1179  actionS;                                                  \
     1180}                                                           \
     1181while(0)
     1182
     1183#else
     1184
     1185#define _p_LmCmpAction(p, q, r, actionE, actionG, actionS)                      \
     1186 p_MemCmp_LengthGeneral_OrdGeneral(p->exp, q->exp, r->CmpL_Size, r->ordsgn,    \
     1187                                   actionE, actionG, actionS)
     1188
     1189#endif
     1190
     1191#define pDivAssume(x)   ((void)0)
     1192
     1193#include <omalloc.h>
     1194#include <coeffs.h>
     1195#include "p_polys.h"
     1196#include "p_MemAdd.h"
     1197#include "p_MemCopy.h"
     1198
     1199/***************************************************************
     1200 *
     1201 * Allocation/Initalization/Deletion
     1202 *
     1203 ***************************************************************/
     1204// adjustments for negative weights
     1205static inline void p_MemAdd_NegWeightAdjust(poly p, const ring r)
     1206{
     1207  if (r->NegWeightL_Offset != NULL)
     1208  {
     1209    for (int i=r->NegWeightL_Size-1; i>=0; i--)
     1210    {
     1211      p->exp[r->NegWeightL_Offset[i]] -= POLY_NEGWEIGHT_OFFSET;
     1212    }
     1213  }
     1214}
     1215static inline void p_MemSub_NegWeightAdjust(poly p, const ring r)
     1216{
     1217  if (r->NegWeightL_Offset != NULL)
     1218  {
     1219    for (int i=r->NegWeightL_Size-1; i>=0; i--)
     1220    {
     1221      p->exp[r->NegWeightL_Offset[i]] += POLY_NEGWEIGHT_OFFSET;
     1222    }
     1223  }
     1224}
     1225// ExpVextor(d_p) = ExpVector(s_p)
     1226static inline void p_ExpVectorCopy(poly d_p, poly s_p, const ring r)
     1227{
     1228  p_LmCheckPolyRing1(d_p, r);
     1229  p_LmCheckPolyRing1(s_p, r);
     1230  p_MemCopy_LengthGeneral(d_p->exp, s_p->exp, r->ExpL_Size);
     1231}
     1232
     1233static inline poly p_Init(const ring r, omBin bin)
     1234{
     1235  p_CheckRing1(r);
     1236  pAssume1(bin != NULL && r->PolyBin->sizeW == bin->sizeW);
     1237  poly p;
     1238  omTypeAlloc0Bin(poly, p, bin);
     1239  p_MemAdd_NegWeightAdjust(p, r);
     1240  p_SetRingOfLm(p, r);
     1241  return p;
     1242}
     1243static inline poly p_Init(const ring r)
     1244{
     1245  return p_Init(r, r->PolyBin);
     1246}
     1247
     1248static inline poly p_LmInit(poly p, const ring r)
     1249{
     1250  p_LmCheckPolyRing1(p, r);
     1251  poly np;
     1252  omTypeAllocBin(poly, np, r->PolyBin);
     1253  p_SetRingOfLm(np, r);
     1254  p_MemCopy_LengthGeneral(np->exp, p->exp, r->ExpL_Size);
     1255  pNext(np) = NULL;
     1256  pSetCoeff0(np, NULL);
     1257  return np;
     1258}
     1259static inline poly p_LmInit(poly s_p, const ring s_r, const ring d_r, omBin d_bin)
     1260{
     1261  p_LmCheckPolyRing1(s_p, s_r);
     1262  p_CheckRing(d_r);
     1263  pAssume1(d_r->N <= s_r->N);
     1264  poly d_p = p_Init(d_r, d_bin);
     1265  for (int i=d_r->N; i>0; i--)
     1266  {
     1267    p_SetExp(d_p, i, p_GetExp(s_p, i,s_r), d_r);
     1268  }
     1269  if (rRing_has_Comp(d_r))
     1270  {
     1271    p_SetComp(d_p, p_GetComp(s_p,s_r), d_r);
     1272  }
     1273  p_Setm(d_p, d_r);
     1274  return d_p;
     1275}
     1276static inline poly p_LmInit(poly s_p, const ring s_r, const ring d_r)
     1277{
     1278  pAssume1(d_r != NULL);
     1279  return p_LmInit(s_p, s_r, d_r, d_r->PolyBin);
     1280}
     1281static inline poly p_Head(poly p, const ring r)
     1282{
     1283  if (p == NULL) return NULL;
     1284  p_LmCheckPolyRing1(p, r);
     1285  poly np;
     1286  omTypeAllocBin(poly, np, r->PolyBin);
     1287  p_SetRingOfLm(np, r);
     1288  p_MemCopy_LengthGeneral(np->exp, p->exp, r->ExpL_Size);
     1289  pNext(np) = NULL;
     1290  pSetCoeff0(np, n_Copy(pGetCoeff(p), r));
     1291  return np;
     1292}
     1293// set all exponents l..k to 0, assume exp. k+1..n and 1..l-1 are in
     1294// different blocks
     1295// set coeff to 1
     1296static inline poly p_GetExp_k_n(poly p, int l, int k, const ring r)
     1297{
     1298  if (p == NULL) return NULL;
     1299  p_LmCheckPolyRing1(p, r);
     1300  poly np;
     1301  omTypeAllocBin(poly, np, r->PolyBin);
     1302  p_SetRingOfLm(np, r);
     1303  p_MemCopy_LengthGeneral(np->exp, p->exp, r->ExpL_Size);
     1304  pNext(np) = NULL;
     1305  pSetCoeff0(np, n_Init(1, r));
     1306  int i;
     1307  for(i=l;i<=k;i++)
     1308  {
     1309    //np->exp[(r->VarOffset[i] & 0xffffff)] =0;
     1310    p_SetExp(np,i,0,r);
     1311  }
     1312  p_Setm(np,r);
     1313  return np;
     1314}
     1315
     1316static inline poly p_LmShallowCopyDelete(poly p, const ring r, omBin bin)
     1317{
     1318  p_LmCheckPolyRing1(p, r);
     1319  pAssume1(bin->sizeW == r->PolyBin->sizeW);
     1320  poly new_p = p_New(r);
     1321  p_MemCopy_LengthGeneral(new_p->exp, p->exp, r->ExpL_Size);
     1322  pSetCoeff0(new_p, pGetCoeff(p));
     1323  pNext(new_p) = pNext(p);
     1324  omFreeBinAddr(p);
     1325  return new_p;
     1326}
     1327
     1328/***************************************************************
     1329 *
     1330 * Operation on ExpVectors
     1331 *
     1332 ***************************************************************/
     1333// ExpVector(p1) += ExpVector(p2)
     1334static inline void p_ExpVectorAdd(poly p1, poly p2, const ring r)
     1335{
     1336  p_LmCheckPolyRing1(p1, r);
     1337  p_LmCheckPolyRing1(p2, r);
     1338#if PDEBUG >= 1
     1339  for (int i=1; i<=r->N; i++)
     1340    pAssume1((unsigned long) (p_GetExp(p1, i, r) + p_GetExp(p2, i, r)) <= r->bitmask);
     1341  pAssume1(p_GetComp(p1, r) == 0 || p_GetComp(p2, r) == 0);
     1342#endif
     1343
     1344  p_MemAdd_LengthGeneral(p1->exp, p2->exp, r->ExpL_Size);
     1345  p_MemAdd_NegWeightAdjust(p1, r);
     1346}
     1347// ExpVector(p1) -= ExpVector(p2)
     1348static inline void p_ExpVectorSub(poly p1, poly p2, const ring r)
     1349{
     1350  p_LmCheckPolyRing1(p1, r);
     1351  p_LmCheckPolyRing1(p2, r);
     1352#if PDEBUG >= 1
     1353  for (int i=1; i<=r->N; i++)
     1354    pAssume1(p_GetExp(p1, i, r) >= p_GetExp(p2, i, r));
     1355  pAssume1(p_GetComp(p1, r) == 0 || p_GetComp(p2, r) == 0 ||
     1356          p_GetComp(p1, r) == p_GetComp(p2, r));
     1357#endif
     1358
     1359  p_MemSub_LengthGeneral(p1->exp, p2->exp, r->ExpL_Size);
     1360  p_MemSub_NegWeightAdjust(p1, r);
     1361
     1362}
     1363// ExpVector(p1) += ExpVector(p2) - ExpVector(p3)
     1364static inline void p_ExpVectorAddSub(poly p1, poly p2, poly p3, const ring r)
     1365{
     1366  p_LmCheckPolyRing1(p1, r);
     1367  p_LmCheckPolyRing1(p2, r);
     1368  p_LmCheckPolyRing1(p3, r);
     1369#if PDEBUG >= 1
     1370  for (int i=1; i<=r->N; i++)
     1371    pAssume1(p_GetExp(p1, i, r) + p_GetExp(p2, i, r) >= p_GetExp(p3, i, r));
     1372  pAssume1(p_GetComp(p1, r) == 0 ||
     1373           (p_GetComp(p2, r) - p_GetComp(p3, r) == 0) ||
     1374           (p_GetComp(p1, r) == p_GetComp(p2, r) - p_GetComp(p3, r)));
     1375#endif
     1376
     1377  p_MemAddSub_LengthGeneral(p1->exp, p2->exp, p3->exp, r->ExpL_Size);
     1378  // no need to adjust in case of NegWeights
     1379}
     1380
     1381// ExpVector(pr) = ExpVector(p1) + ExpVector(p2)
     1382static inline void p_ExpVectorSum(poly pr, poly p1, poly p2, const ring r)
     1383{
     1384  p_LmCheckPolyRing1(p1, r);
     1385  p_LmCheckPolyRing1(p2, r);
     1386  p_LmCheckPolyRing1(pr, r);
     1387#if PDEBUG >= 1
     1388  for (int i=1; i<=r->N; i++)
     1389    pAssume1((unsigned long) (p_GetExp(p1, i, r) + p_GetExp(p2, i, r)) <= r->bitmask);
     1390  pAssume1(p_GetComp(p1, r) == 0 || p_GetComp(p2, r) == 0);
     1391#endif
     1392
     1393  p_MemSum_LengthGeneral(pr->exp, p1->exp, p2->exp, r->ExpL_Size);
     1394  p_MemAdd_NegWeightAdjust(pr, r);
     1395}
     1396// ExpVector(pr) = ExpVector(p1) - ExpVector(p2)
     1397static inline void p_ExpVectorDiff(poly pr, poly p1, poly p2, const ring r)
     1398{
     1399  p_LmCheckPolyRing1(p1, r);
     1400  p_LmCheckPolyRing1(p2, r);
     1401  p_LmCheckPolyRing1(pr, r);
     1402#if PDEBUG >= 2
     1403  for (int i=1; i<=r->N; i++)
     1404    pAssume1(p_GetExp(p1, i, r) >= p_GetExp(p2, i, r));
     1405  pAssume1(!rRing_has_Comp(r) || p_GetComp(p1, r) == p_GetComp(p2, r));
     1406#endif
     1407
     1408  p_MemDiff_LengthGeneral(pr->exp, p1->exp, p2->exp, r->ExpL_Size);
     1409  p_MemSub_NegWeightAdjust(pr, r);
     1410}
     1411
     1412static inline BOOLEAN p_ExpVectorEqual(poly p1, poly p2, const ring r)
     1413{
     1414  p_LmCheckPolyRing1(p1, r);
     1415  p_LmCheckPolyRing1(p2, r);
     1416
     1417  int i = r->ExpL_Size;
     1418  unsigned long *ep = p1->exp;
     1419  unsigned long *eq = p2->exp;
     1420
     1421  do
     1422  {
     1423    i--;
     1424    if (ep[i] != eq[i]) return FALSE;
     1425  }
     1426  while (i);
     1427  return TRUE;
     1428}
     1429
     1430static inline long p_Totaldegree(poly p, const ring r)
     1431{
     1432  p_LmCheckPolyRing1(p, r);
     1433  unsigned long s = p_GetTotalDegree(p->exp[r->VarL_Offset[0]],
     1434                                     r,
     1435                                     r->MinExpPerLong);
     1436  for (int i=r->VarL_Size-1; i>0; i--)
     1437  {
     1438    s += p_GetTotalDegree(p->exp[r->VarL_Offset[i]], r);
     1439  }
     1440  return (long)s;
     1441}
     1442
     1443static inline void p_GetExpV(poly p, int *ev, const ring r)
     1444{
     1445  p_LmCheckPolyRing1(p, r);
     1446  for (int j = r->N; j; j--)
     1447      ev[j] = p_GetExp(p, j, r);
     1448
     1449  ev[0] = p_GetComp(p, r);
     1450}
     1451static inline void p_SetExpV(poly p, int *ev, const ring r)
     1452{
     1453  p_LmCheckPolyRing1(p, r);
     1454  for (int j = r->N; j; j--)
     1455      p_SetExp(p, j, ev[j], r);
     1456
     1457  p_SetComp(p, ev[0],r);
     1458  p_Setm(p, r);
     1459}
     1460
     1461/***************************************************************
     1462 *
     1463 * Comparison w.r.t. monomial ordering
     1464 *
     1465 ***************************************************************/
     1466static inline int p_LmCmp(poly p, poly q, const ring r)
     1467{
     1468  p_LmCheckPolyRing1(p, r);
     1469  p_LmCheckPolyRing1(q, r);
     1470
     1471  p_MemCmp_LengthGeneral_OrdGeneral(p->exp, q->exp, r->CmpL_Size, r->ordsgn,
     1472                                    return 0, return 1, return -1);
     1473}
     1474
     1475
     1476/***************************************************************
     1477 *
     1478 * divisibility
     1479 *
     1480 ***************************************************************/
     1481// return: FALSE, if there exists i, such that a->exp[i] > b->exp[i]
     1482//         TRUE, otherwise
     1483// (1) Consider long vars, instead of single exponents
     1484// (2) Clearly, if la > lb, then FALSE
     1485// (3) Suppose la <= lb, and consider first bits of single exponents in l:
     1486//     if TRUE, then value of these bits is la ^ lb
     1487//     if FALSE, then la-lb causes an "overflow" into one of those bits, i.e.,
     1488//               la ^ lb != la - lb
     1489static inline BOOLEAN _p_LmDivisibleByNoComp(poly a, poly b, const ring r)
     1490{
     1491  int i=r->VarL_Size - 1;
     1492  unsigned long divmask = r->divmask;
     1493  unsigned long la, lb;
     1494
     1495  if (r->VarL_LowIndex >= 0)
     1496  {
     1497    i += r->VarL_LowIndex;
     1498    do
     1499    {
     1500      la = a->exp[i];
     1501      lb = b->exp[i];
     1502      if ((la > lb) ||
     1503          (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask)))
     1504      {
     1505        pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == FALSE);
     1506        return FALSE;
     1507      }
     1508      i--;
     1509    }
     1510    while (i>=r->VarL_LowIndex);
     1511  }
     1512  else
     1513  {
     1514    do
     1515    {
     1516      la = a->exp[r->VarL_Offset[i]];
     1517      lb = b->exp[r->VarL_Offset[i]];
     1518      if ((la > lb) ||
     1519          (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask)))
     1520      {
     1521        pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == FALSE);
     1522        return FALSE;
     1523      }
     1524      i--;
     1525    }
     1526    while (i>=0);
     1527  }
     1528#ifdef HAVE_RINGS
     1529  pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == nDivBy(p_GetCoeff(b, r), p_GetCoeff(a, r)));
     1530  return (!rField_is_Ring(r)) || nDivBy(p_GetCoeff(b, r), p_GetCoeff(a, r));
     1531#else
     1532  pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == TRUE);
     1533  return TRUE;
     1534#endif
     1535}
     1536
     1537static inline BOOLEAN _p_LmDivisibleByNoComp(poly a, const ring r_a, poly b, const ring r_b)
     1538{
     1539  int i=r_a->N;
     1540  pAssume1(r_a->N == r_b->N);
     1541
     1542  do
     1543  {
     1544    if (p_GetExp(a,i,r_a) > p_GetExp(b,i,r_b))
     1545      return FALSE;
     1546    i--;
     1547  }
     1548  while (i);
     1549#ifdef HAVE_RINGS
     1550  return nDivBy(p_GetCoeff(b, r), p_GetCoeff(a, r));
     1551#else
     1552  return TRUE;
     1553#endif
     1554}
     1555
     1556#ifdef HAVE_RATGRING
     1557static inline BOOLEAN _p_LmDivisibleByNoCompPart(poly a, const ring r_a, poly b, const ring r_b,const int start, const int end)
     1558{
     1559  int i=end;
     1560  pAssume1(r_a->N == r_b->N);
     1561
     1562  do
     1563  {
     1564    if (p_GetExp(a,i,r_a) > p_GetExp(b,i,r_b))
     1565      return FALSE;
     1566    i--;
     1567  }
     1568  while (i>=start);
     1569#ifdef HAVE_RINGS
     1570  return nDivBy(p_GetCoeff(b, r), p_GetCoeff(a, r));
     1571#else
     1572  return TRUE;
     1573#endif
     1574}
     1575static inline BOOLEAN _p_LmDivisibleByPart(poly a, const ring r_a, poly b, const ring r_b,const int start, const int end)
     1576{
     1577  if (p_GetComp(a, r_a) == 0 || p_GetComp(a,r_a) == p_GetComp(b,r_b))
     1578    return _p_LmDivisibleByNoCompPart(a, r_a, b, r_b,start,end);
     1579  return FALSE;
     1580}
     1581static inline BOOLEAN p_LmDivisibleByPart(poly a, poly b, const ring r,const int start, const int end)
     1582{
     1583  p_LmCheckPolyRing1(b, r);
     1584  pIfThen1(a != NULL, p_LmCheckPolyRing1(b, r));
     1585  if (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r))
     1586    return _p_LmDivisibleByNoCompPart(a, r, b, r,start, end);
     1587  return FALSE;
     1588}
     1589#endif
     1590static inline BOOLEAN _p_LmDivisibleBy(poly a, poly b, const ring r)
     1591{
     1592  if (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r))
     1593    return _p_LmDivisibleByNoComp(a, b, r);
     1594  return FALSE;
     1595}
     1596static inline BOOLEAN _p_LmDivisibleBy(poly a, const ring r_a, poly b, const ring r_b)
     1597{
     1598  if (p_GetComp(a, r_a) == 0 || p_GetComp(a,r_a) == p_GetComp(b,r_b))
     1599    return _p_LmDivisibleByNoComp(a, r_a, b, r_b);
     1600  return FALSE;
     1601}
     1602static inline BOOLEAN p_LmDivisibleByNoComp(poly a, poly b, const ring r)
     1603{
     1604  p_LmCheckPolyRing1(a, r);
     1605  p_LmCheckPolyRing1(b, r);
     1606  return _p_LmDivisibleByNoComp(a, b, r);
     1607}
     1608static inline BOOLEAN p_LmDivisibleBy(poly a, poly b, const ring r)
     1609{
     1610  p_LmCheckPolyRing1(b, r);
     1611  pIfThen1(a != NULL, p_LmCheckPolyRing1(b, r));
     1612  if (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r))
     1613    return _p_LmDivisibleByNoComp(a, b, r);
     1614  return FALSE;
     1615}
     1616
     1617static inline BOOLEAN p_DivisibleBy(poly a, poly b, const ring r)
     1618{
     1619  pIfThen1(b!=NULL, p_LmCheckPolyRing1(b, r));
     1620  pIfThen1(a!=NULL, p_LmCheckPolyRing1(a, r));
     1621
     1622  if (a != NULL && (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r)))
     1623      return _p_LmDivisibleByNoComp(a,b,r);
     1624  return FALSE;
     1625}
     1626static inline BOOLEAN p_DivisibleBy(poly a, const ring r_a, poly b, const ring r_b)
     1627{
     1628  pIfThen1(b!=NULL, p_LmCheckPolyRing1(b, r_b));
     1629  pIfThen1(a!=NULL, p_LmCheckPolyRing1(a, r_a));
     1630  if (a != NULL) {
     1631      return _p_LmDivisibleBy(a, r_a, b, r_b);
     1632  }
     1633  return FALSE;
     1634}
     1635static inline BOOLEAN p_LmDivisibleBy(poly a, const ring r_a, poly b, const ring r_b)
     1636{
     1637  p_LmCheckPolyRing(a, r_a);
     1638  p_LmCheckPolyRing(b, r_b);
     1639  return _p_LmDivisibleBy(a, r_a, b, r_b);
     1640}
     1641static inline BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a,
     1642                                    poly b, unsigned long not_sev_b, const ring r)
     1643{
     1644  p_LmCheckPolyRing1(a, r);
     1645  p_LmCheckPolyRing1(b, r);
     1646#ifndef PDIV_DEBUG
     1647  pPolyAssume2(p_GetShortExpVector(a, r) == sev_a, a, r);
     1648  pPolyAssume2(p_GetShortExpVector(b, r) == ~ not_sev_b, b, r);
     1649
     1650  if (sev_a & not_sev_b)
     1651  {
     1652    pAssume1(p_LmDivisibleByNoComp(a, b, r) == FALSE);
     1653    return FALSE;
     1654  }
     1655  return p_LmDivisibleBy(a, b, r);
     1656#else
     1657  return pDebugLmShortDivisibleBy(a, sev_a, r, b, not_sev_b, r);
     1658#endif
     1659}
     1660
     1661static inline BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a, const ring r_a,
     1662                                      poly b, unsigned long not_sev_b, const ring r_b)
     1663{
     1664  p_LmCheckPolyRing1(a, r_a);
     1665  p_LmCheckPolyRing1(b, r_b);
     1666#ifndef PDIV_DEBUG
     1667  pPolyAssume2(p_GetShortExpVector(a, r_a) == sev_a, a, r_a);
     1668  pPolyAssume2(p_GetShortExpVector(b, r_b) == ~ not_sev_b, b, r_b);
     1669
     1670  if (sev_a & not_sev_b)
     1671  {
     1672    pAssume1(_p_LmDivisibleByNoComp(a, r_a, b, r_b) == FALSE);
     1673    return FALSE;
     1674  }
     1675  return _p_LmDivisibleBy(a, r_a, b, r_b);
     1676#else
     1677  return pDebugLmShortDivisibleBy(a, sev_a, r_a, b, not_sev_b, r_b);
     1678#endif
     1679}
     1680
     1681/***************************************************************
     1682 *
     1683 * Misc things on Lm
     1684 *
     1685 ***************************************************************/
     1686// test if the monomial is a constant as a vector component
     1687// i.e., test if all exponents are zero
     1688static inline BOOLEAN p_LmIsConstantComp(const poly p, const ring r)
     1689{
     1690  //p_LmCheckPolyRing(p, r);
     1691  int i = r->VarL_Size - 1;
     1692
     1693  do
     1694  {
     1695    if (p->exp[r->VarL_Offset[i]] != 0)
     1696      return FALSE;
     1697    i--;
     1698  }
     1699  while (i >= 0);
     1700  return TRUE;
     1701}
     1702// test if monomial is a constant, i.e. if all exponents and the component
     1703// is zero
     1704static inline BOOLEAN p_LmIsConstant(const poly p, const ring r)
     1705{
     1706  if (p_LmIsConstantComp(p, r))
     1707    return (p_GetComp(p, r) == 0);
     1708  return FALSE;
     1709}
     1710
     1711// like the respective p_LmIs* routines, except that p might be empty
     1712static inline BOOLEAN p_IsConstantComp(const poly p, const ring r)
     1713{
     1714  if (p == NULL) return TRUE;
     1715  return (pNext(p)==NULL) && p_LmIsConstantComp(p, r);
     1716}
     1717
     1718static inline BOOLEAN p_IsConstant(const poly p, const ring r)
     1719{
     1720  if (p == NULL) return TRUE;
     1721  return (pNext(p)==NULL) && p_LmIsConstant(p, r);
     1722}
     1723
     1724static inline BOOLEAN p_IsUnit(const poly p, const ring r)
     1725{
     1726  if (p == NULL) return FALSE;
     1727#ifdef HAVE_RINGS
     1728  if (rField_is_Ring(r))
     1729    return (p_LmIsConstant(p, r) && nIsUnit(pGetCoeff(p),r->cf));
     1730#endif
     1731  return p_LmIsConstant(p, r);
     1732}
     1733
     1734static inline BOOLEAN p_LmExpVectorAddIsOk(const poly p1, const poly p2,
     1735                                      const ring r)
     1736{
     1737  p_LmCheckPolyRing(p1, r);
     1738  p_LmCheckPolyRing(p2, r);
     1739  unsigned long l1, l2, divmask = r->divmask;
     1740  int i;
     1741
     1742  for (i=0; i<r->VarL_Size; i++)
     1743  {
     1744    l1 = p1->exp[r->VarL_Offset[i]];
     1745    l2 = p2->exp[r->VarL_Offset[i]];
     1746    // do the divisiblity trick
     1747    if ( (l1 > ULONG_MAX - l2) ||
     1748         (((l1 & divmask) ^ (l2 & divmask)) != ((l1 + l2) & divmask)))
     1749      return FALSE;
     1750  }
     1751  return TRUE;
     1752}
    4521753#endif // P_POLYS_H
    4531754
Note: See TracChangeset for help on using the changeset viewer.