source: git/libpolys/polys/monomials/p_polys.h @ 260672

spielwiese
Last change on this file since 260672 was 260672, checked in by Oleksandr Motsak <motsak@…>, 12 years ago
minor cleanup chg: better indentation chg: converted comments into doxygen documentation for some declaration
  • Property mode set to 100644
File size: 50.9 KB
RevLine 
[35aab3]1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/***************************************************************
[b84b400]5 *  File:    p_polys.h
[35aab3]6 *  Purpose: declaration of poly stuf which are independent of
7 *           currRing
8 *  Author:  obachman (Olaf Bachmann)
9 *  Created: 9/00
[341696]10 *  Version: $Id$
[35aab3]11 *******************************************************************/
[4f0f42]12/***************************************************************
13 *  Purpose: implementation of poly procs which iter over ExpVector
14 *  Author:  obachman (Olaf Bachmann)
15 *  Created: 8/00
16 *  Version: $Id$
17 *******************************************************************/
[35aab3]18#ifndef P_POLYS_H
19#define P_POLYS_H
20
[4f0f42]21#include <omalloc/omalloc.h>
22#include <misc/mylimits.h>
23#include <coeffs/coeffs.h>
24
[20b794]25#include <polys/monomials/ring.h>
[8a8c9e]26#include <polys/monomials/monomials.h>
[4f0f42]27
28#include <polys/templates/p_MemAdd.h>
[2b85f31]29#include <polys/templates/p_MemCmp.h>
[8a8c9e]30#include <polys/templates/p_Procs.h>
[4f0f42]31
[8a8c9e]32#include <polys/sbuckets.h>
[35aab3]33
[4f0f42]34#ifdef HAVE_PLURAL
35#include <polys/nc/nc.h>
36#endif
37
38
[35aab3]39/***************************************************************
40 *
41 * Primitives for accessing and setting fields of a poly
42 * poly must be != NULL
43 *
44 ***************************************************************/
45// next
[367c32]46#define pNext(p)            ((p)->next)
47#define pIter(p)            ((p) = (p)->next)
[35aab3]48
49// coeff
[afa93a]50// #define pGetCoeff(p)        ((p)->coef)
51static inline number& pGetCoeff(poly p)
52{
53  assume(p != NULL);
54  return p->coef;
55}
56
[6c98d52]57#define p_GetCoeff(p,r)     pGetCoeff(p)
58//static inline number& p_GetCoeff(poly p, const ring r)
59//{
60//  assume(r != NULL);
61//  return pGetCoeff(p);
62//}
[afa93a]63
64
65
66//
67// deletes old coeff before setting the new one???
[367c32]68#define pSetCoeff0(p,n)     (p)->coef=(n)
[afa93a]69
[367c32]70#define p_SetCoeff0(p,n,r)  pSetCoeff0(p,n)
[35aab3]71
[5948a8]72#define __p_GetComp(p, r)   (p)->exp[r->pCompIndex]
73#define p_GetComp(p, r)    ((long) (r->pCompIndex >= 0 ? __p_GetComp(p, r) : 0))
74
[35aab3]75/***************************************************************
76 *
77 * Divisiblity tests, args must be != NULL, except for
78 * pDivisbleBy
79 *
80 ***************************************************************/
[cf02b22]81unsigned long p_GetShortExpVector(poly a, const ring r);
82
[260672]83#ifdef HAVE_RINGS
84/*! divisibility check over ground ring (which may contain zero divisors);
[3d0808]85   TRUE iff LT(f) divides LT(g), i.e., LT(f)*c*m = LT(g), for some
86   coefficient c and some monomial m;
[260672]87   does not take components into account
88 */
[3d0808]89BOOLEAN p_DivisibleByRingCase(poly f, poly g, const ring r);
90#endif
[35aab3]91
92/***************************************************************
93 *
94 * Misc things on polys
95 *
96 ***************************************************************/
[028192]97
98poly p_One(const ring r);
99
[ba0fc3]100int p_MinDeg(poly p,intvec *w, const ring R);
101
102long p_DegW(poly p, const short *w, const ring R);
103
[260672]104/// return TRUE if all monoms have the same component
[cf02b22]105BOOLEAN   p_OneComp(poly p, const ring r);
[2f0d83f]106
[260672]107/// return i, if head depends only on var(i)
[35aab3]108int       p_IsPurePower(const poly p, const ring r);
109
[260672]110/// return i, if poly depends only on var(i)
[2f0d83f]111int       p_IsUnivariate(poly p, const ring r);
112
[260672]113/// set entry e[i] to 1 if var(i) occurs in p, ignore var(j) if e[j]>0
114/// return #(e[i]>0)
[f46646]115int      p_GetVariables(poly p, int * e, const ring r);
[95450e]116
[260672]117/// returns the poly representing the integer i
[cf02b22]118poly      p_ISet(int i, const ring r);
[2f0d83f]119
[260672]120/// returns the poly representing the number n, destroys n
[cf02b22]121poly      p_NSet(number n, const ring r);
122
123void  p_Vec2Polys(poly v, poly**p, int *len, const ring r);
[35aab3]124
125/***************************************************************
126 *
127 * Copying/Deletion of polys: args may be NULL
128 *
129 ***************************************************************/
130
131// simply deletes monomials, does not free coeffs
132void p_ShallowDelete(poly *p, const ring r);
133
[f550e86]134
[35aab3]135
136/***************************************************************
137 *
138 * Copying/Deleteion of polys: args may be NULL
139 *  - p/q as arg mean a poly
140 *  - m a monomial
141 *  - n a number
142 *  - pp (resp. qq, mm, nn) means arg is constant
143 *  - p (resp, q, m, n)     means arg is destroyed
144 *
145 ***************************************************************/
146
[bf183f]147poly      p_Sub(poly a, poly b, const ring r);
148
149poly      p_Power(poly p, int i, const ring r);
[5948a8]150
151
152/***************************************************************
153 *
154 * PDEBUG stuff
155 *
156 ***************************************************************/
157#ifdef PDEBUG
158// Returns TRUE if m is monom of p, FALSE otherwise
159BOOLEAN pIsMonomOf(poly p, poly m);
160// Returns TRUE if p and q have common monoms
161BOOLEAN pHaveCommonMonoms(poly p, poly q);
162
163// p_Check* routines return TRUE if everything is ok,
164// else, they report error message and return false
165
166// check if Lm(p) is from ring r
167BOOLEAN p_LmCheckIsFromRing(poly p, ring r);
168// check if Lm(p) != NULL, r != NULL and initialized && Lm(p) is from r
169BOOLEAN p_LmCheckPolyRing(poly p, ring r);
170// check if all monoms of p are from ring r
171BOOLEAN p_CheckIsFromRing(poly p, ring r);
172// check r != NULL and initialized && all monoms of p are from r
173BOOLEAN p_CheckPolyRing(poly p, ring r);
174// check if r != NULL and initialized
175BOOLEAN p_CheckRing(ring r);
176// only do check if cond
177
178
179#define pIfThen(cond, check) do {if (cond) {check;}} while (0)
180
181BOOLEAN _p_Test(poly p, ring r, int level);
182BOOLEAN _p_LmTest(poly p, ring r, int level);
183BOOLEAN _pp_Test(poly p, ring lmRing, ring tailRing, int level);
184
185#define p_Test(p,r)     _p_Test(p, r, PDEBUG)
186#define p_LmTest(p,r)   _p_LmTest(p, r, PDEBUG)
187#define pp_Test(p, lmRing, tailRing)    _pp_Test(p, lmRing, tailRing, PDEBUG)
188
189#else // ! PDEBUG
190
191#define pIsMonomOf(p, q)        (TRUE)
192#define pHaveCommonMonoms(p, q) (TRUE)
193#define p_LmCheckIsFromRing(p,r)  ((void)0)
194#define p_LmCheckPolyRing(p,r)    ((void)0)
195#define p_CheckIsFromRing(p,r)  ((void)0)
196#define p_CheckPolyRing(p,r)    ((void)0)
197#define p_CheckRing(r)          ((void)0)
198#define P_CheckIf(cond, check)  ((void)0)
199
[021751]200#define p_Test(p,r)     ((void) 1)
201#define p_LmTest(p,r)   ((void) 1)
202#define pp_Test(p, lmRing, tailRing) ((void) 1)
[5948a8]203
204#endif
205
[35aab3]206/***************************************************************
207 *
208 * Misc stuff
209 *
210 ***************************************************************/
[c1a2b20]211/*2
[ba2359]212* returns the length of a polynomial (numbers of monomials)
[c1a2b20]213*/
214static inline int pLength(poly a)
215{
216  int l = 0;
217  while (a!=NULL)
218  {
219    pIter(a);
220    l++;
221  }
222  return l;
223}
224
[71ba5b8]225void      p_Norm(poly p1, const ring r);
[8d1d30c]226void      p_Normalize(poly p,const ring r);
227
228void      p_Content(poly p, const ring r);
[e48172]229#if 1
230// currently only used by Singular/janet
[fe66ba8]231void      p_SimpleContent(poly p, int s, const ring r);
[e48172]232#endif
[8d1d30c]233
234poly      p_Cleardenom(poly p, const ring r);
235void      p_Cleardenom_n(poly p, const ring r,number &c);
236number    p_GetAllDenom(poly ph, const ring r);
237
[b27c052]238int       p_Size( poly p, const ring r );
[fbf8a6]239
[4e8ef90]240// homogenizes p by multiplying certain powers of the varnum-th variable
241poly      p_Homogen (poly p, int varnum, const ring r);
[a30a39a]242
[4e8ef90]243BOOLEAN   p_IsHomogeneous (poly p, const ring r);
244
[a04c5e]245static inline void p_Setm(poly p, const ring r);
[35aab3]246p_SetmProc p_GetSetmProc(ring r);
247
[71ba5b8]248poly      p_Subst(poly p, int n, poly e, const ring r);
249
[35aab3]250// TODO:
251#define p_SetmComp  p_Setm
252
[20d9284]253// component
254static inline  unsigned long p_SetComp(poly p, unsigned long c, ring r)
255{
256  p_LmCheckPolyRing2(p, r);
257  pAssume2(rRing_has_Comp(r));
258  __p_GetComp(p,r) = c;
259  return c;
260}
[a22a82]261// sets component of poly a to i, returns length of p
262static inline   void p_SetCompP(poly p, int i, ring r)
[5a3ae8]263{
264  if (p != NULL)
265  {
266#ifdef PDEBUG
267    poly q = p;
268    int l = 0;
269#endif
270
271    if (rOrd_SetCompRequiresSetm(r))
272    {
273      do
274      {
275        p_SetComp(p, i, r);
276        p_SetmComp(p, r);
277#ifdef PDEBUG
278        l++;
279#endif
280        pIter(p);
281      }
282      while (p != NULL);
283    }
284    else
285    {
286      do
287      {
288        p_SetComp(p, i, r);
289#ifdef PDEBUG
290        l++;
291#endif
292        pIter(p);
293      }
294      while(p != NULL);
295    }
296#ifdef PDEBUG
297    p_Test(q, r);
298    assume(l == pLength(q));
299#endif
300  }
301}
302
[a22a82]303static inline   void p_SetCompP(poly p, int i, ring lmRing, ring tailRing)
[5a3ae8]304{
305  if (p != NULL)
306  {
307    p_SetComp(p, i, lmRing);
308    p_SetmComp(p, lmRing);
309    p_SetCompP(pNext(p), i, tailRing);
310  }
311}
[c462b55]312
313// returns maximal column number in the modul element a (or 0)
314static inline long p_MaxComp(poly p, ring lmRing, ring tailRing)
315{
316  long result,i;
317
318  if(p==NULL) return 0;
319  result = p_GetComp(p, lmRing);
320  if (result != 0)
321  {
322    loop
323    {
324      pIter(p);
325      if(p==NULL) break;
326      i = p_GetComp(p, tailRing);
327      if (i>result) result = i;
328    }
329  }
330  return result;
331}
332
333static inline long p_MaxComp(poly p,ring lmRing) {return p_MaxComp(p,lmRing,lmRing);}
334
335static inline   long p_MinComp(poly p, ring lmRing, ring tailRing)
336{
337  long result,i;
338
339  if(p==NULL) return 0;
340  result = p_GetComp(p,lmRing);
341  if (result != 0)
342  {
343    loop
344    {
345      pIter(p);
346      if(p==NULL) break;
347      i = p_GetComp(p,tailRing);
348      if (i<result) result = i;
349    }
350  }
351  return result;
352}
353
354static inline long p_MinComp(poly p,ring lmRing) {return p_MinComp(p,lmRing,lmRing);}
[35aab3]355
[45d2332]356
[20d9284]357static inline poly pReverse(poly p)
358{
359  if (p == NULL || pNext(p) == NULL) return p;
360
361  poly q = pNext(p), // == pNext(p)
362    qn;
363  pNext(p) = NULL;
364  do
365  {
366    qn = pNext(q);
367    pNext(q) = p;
368    p = q;
369    q = qn;
370  }
371  while (qn != NULL);
372  return p;
373}
[c6a3eb2]374void      pEnlargeSet(poly**p, int length, int increment);
[35aab3]375
376
377/***************************************************************
378 *
379 * I/O
380 *
381 ***************************************************************/
382char*     p_String(poly p, ring lmRing, ring tailRing);
383char*     p_String0(poly p, ring lmRing, ring tailRing);
384void      p_Write(poly p, ring lmRing, ring tailRing);
385void      p_Write0(poly p, ring lmRing, ring tailRing);
386void      p_wrp(poly p, ring lmRing, ring tailRing);
387
388/***************************************************************
389 *
390 * Degree stuff -- see p_polys.cc for explainations
391 *
392 ***************************************************************/
[aa450d]393
394static inline long  p_FDeg(const poly p, const ring r)  { return r->pFDeg(p,r); }
395static inline long  p_LDeg(const poly p, int *l, const ring r)  { return r->pLDeg(p,l,r); }
396
[19ae652]397long p_WFirstTotalDegree(poly p, ring r);
398long p_WTotaldegree(poly p, const ring r);
[bf183f]399long p_WDegree(poly p,const ring r);
[35aab3]400long pLDeg0(poly p,int *l, ring r);
401long pLDeg0c(poly p,int *l, ring r);
402long pLDegb(poly p,int *l, ring r);
403long pLDeg1(poly p,int *l, ring r);
404long pLDeg1c(poly p,int *l, ring r);
405long pLDeg1_Deg(poly p,int *l, ring r);
406long pLDeg1c_Deg(poly p,int *l, ring r);
407long pLDeg1_Totaldegree(poly p,int *l, ring r);
408long pLDeg1c_Totaldegree(poly p,int *l, ring r);
409long pLDeg1_WFirstTotalDegree(poly p,int *l, ring r);
410long pLDeg1c_WFirstTotalDegree(poly p,int *l, ring r);
[f82bd3]411BOOLEAN p_EqualPolys(poly p1, poly p2, const ring r);
[c6a3eb2]412
413long p_Deg(poly a, const ring r);
[35aab3]414
415
[a04c5e]416/***************************************************************
417 *
418 * Primitives for accessing and setting fields of a poly
419 *
420 ***************************************************************/
421
422static inline number p_SetCoeff(poly p, number n, ring r)
423{
424  p_LmCheckPolyRing2(p, r);
[8a8c9e]425  n_Delete(&(p->coef), r->cf);
[a04c5e]426  (p)->coef=n;
427  return n;
428}
429
430// order
431static inline long p_GetOrder(poly p, ring r)
432{
433  p_LmCheckPolyRing2(p, r);
434  if (r->typ==NULL) return ((p)->exp[r->pOrdIndex]);
435  int i=0;
436  loop
437  {
438    switch(r->typ[i].ord_typ)
439    {
440      case ro_wp_neg:
441        return (((long)((p)->exp[r->pOrdIndex]))-POLY_NEGWEIGHT_OFFSET);
442      case ro_syzcomp:
443      case ro_syz:
444      case ro_cp:
445        i++;
446        break;
447      //case ro_dp:
448      //case ro_wp:
449      default:
450        return ((p)->exp[r->pOrdIndex]);
451    }
452  }
453}
454
455// Setm
456static inline void p_Setm(poly p, const ring r)
457{
458  p_CheckRing2(r);
459  r->p_Setm(p, r);
460}
461
[20d9284]462
[a04c5e]463static inline unsigned long p_AddComp(poly p, unsigned long v, ring r)
464{
465  p_LmCheckPolyRing2(p, r);
466  pAssume2(rRing_has_Comp(r));
467  return __p_GetComp(p,r) += v;
468}
469static inline unsigned long p_SubComp(poly p, unsigned long v, ring r)
470{
471  p_LmCheckPolyRing2(p, r);
472  pAssume2(rRing_has_Comp(r));
[8a8c9e]473  _pPolyAssume2(__p_GetComp(p,r) >= v,p,r);
[a04c5e]474  return __p_GetComp(p,r) -= v;
475}
476
477#ifndef HAVE_EXPSIZES
478
479/// get a single variable exponent
480/// @Note:
481/// the integer VarOffset encodes:
482/// 1. the position of a variable in the exponent vector p->exp (lower 24 bits)
483/// 2. number of bits to shift to the right in the upper 8 bits (which takes at most 6 bits for 64 bit)
484/// Thus VarOffset always has 2 zero higher bits!
485static inline long p_GetExp(const poly p, const unsigned long iBitmask, const int VarOffset)
486{
487  pAssume2((VarOffset >> (24 + 6)) == 0);
488#if 0
489  int pos=(VarOffset & 0xffffff);
490  int bitpos=(VarOffset >> 24);
491  unsigned long exp=(p->exp[pos] >> bitmask) & iBitmask;
492  return exp;
493#else
494  return (long)
495         ((p->exp[(VarOffset & 0xffffff)] >> (VarOffset >> 24))
496          & iBitmask);
497#endif
498}
499
500
501/// set a single variable exponent
502/// @Note:
503/// VarOffset encodes the position in p->exp @see p_GetExp
504static inline unsigned long p_SetExp(poly p, const unsigned long e, const unsigned long iBitmask, const int VarOffset)
505{
506  pAssume2(e>=0);
507  pAssume2(e<=iBitmask);
508  pAssume2((VarOffset >> (24 + 6)) == 0);
509
510  // shift e to the left:
511  register int shift = VarOffset >> 24;
512  unsigned long ee = e << shift /*(VarOffset >> 24)*/;
513  // find the bits in the exponent vector
514  register int offset = (VarOffset & 0xffffff);
515  // clear the bits in the exponent vector:
516  p->exp[offset]  &= ~( iBitmask << shift );
517  // insert e with |
518  p->exp[ offset ] |= ee;
519  return e;
520}
521
522
523#else // #ifdef HAVE_EXPSIZES // EXPERIMENTAL!!!
524
525static inline unsigned long BitMask(unsigned long bitmask, int twobits)
526{
527  // bitmask = 00000111111111111
528  // 0 must give bitmask!
529  // 1, 2, 3 - anything like 00011..11
530  pAssume2((twobits >> 2) == 0);
531  static const unsigned long _bitmasks[4] = {-1, 0x7fff, 0x7f, 0x3};
532  return bitmask & _bitmasks[twobits];
533}
534
535
536/// @Note: we may add some more info (6 ) into VarOffset and thus encode
537static inline long p_GetExp(const poly p, const unsigned long iBitmask, const int VarOffset)
538{
539  int pos  =(VarOffset & 0xffffff);
540  int hbyte= (VarOffset >> 24); // the highest byte
541  int bitpos = hbyte & 0x3f; // last 6 bits
542  long bitmask = BitMask(iBitmask, hbyte >> 6);
543
544  long exp=(p->exp[pos] >> bitpos) & bitmask;
545  return exp;
546
547}
548
549static inline long p_SetExp(poly p, const long e, const unsigned long iBitmask, const int VarOffset)
550{
551  pAssume2(e>=0);
552  pAssume2(e <= BitMask(iBitmask, VarOffset >> 30));
553
554  // shift e to the left:
555  register int hbyte = VarOffset >> 24;
556  int bitmask = BitMask(iBitmask, hbyte >> 6);
557  register int shift = hbyte & 0x3f;
558  long ee = e << shift;
559  // find the bits in the exponent vector
560  register int offset = (VarOffset & 0xffffff);
561  // clear the bits in the exponent vector:
562  p->exp[offset]  &= ~( bitmask << shift );
563  // insert e with |
564  p->exp[ offset ] |= ee;
565  return e;
566}
567
568#endif // #ifndef HAVE_EXPSIZES
569
570
571static inline long p_GetExp(const poly p, const ring r, const int VarOffset)
572{
573  p_LmCheckPolyRing2(p, r);
574  pAssume2(VarOffset != -1);
575  return p_GetExp(p, r->bitmask, VarOffset);
576}
577
578static inline long p_SetExp(poly p, const long e, const ring r, const int VarOffset)
579{
580  p_LmCheckPolyRing2(p, r);
581  pAssume2(VarOffset != -1);
582  return p_SetExp(p, e, r->bitmask, VarOffset);
583}
584
585
586
587/// get v^th exponent for a monomial
588static inline long p_GetExp(const poly p, const int v, const ring r)
589{
590  p_LmCheckPolyRing2(p, r);
591  pAssume2(v>0 && v <= r->N);
592  pAssume2(r->VarOffset[v] != -1);
593  return p_GetExp(p, r->bitmask, r->VarOffset[v]);
594}
595
596
597/// set v^th exponent for a monomial
598static inline long p_SetExp(poly p, const int v, const long e, const ring r)
599{
600  p_LmCheckPolyRing2(p, r);
601  pAssume2(v>0 && v <= r->N);
602  pAssume2(r->VarOffset[v] != -1);
603  return p_SetExp(p, e, r->bitmask, r->VarOffset[v]);
604}
605
606// the following should be implemented more efficiently
607static inline  long p_IncrExp(poly p, int v, ring r)
608{
609  p_LmCheckPolyRing2(p, r);
610  int e = p_GetExp(p,v,r);
611  e++;
612  return p_SetExp(p,v,e,r);
613}
614static inline  long p_DecrExp(poly p, int v, ring r)
615{
616  p_LmCheckPolyRing2(p, r);
617  int e = p_GetExp(p,v,r);
618  pAssume2(e > 0);
619  e--;
620  return p_SetExp(p,v,e,r);
621}
622static inline  long p_AddExp(poly p, int v, long ee, ring r)
623{
624  p_LmCheckPolyRing2(p, r);
625  int e = p_GetExp(p,v,r);
626  e += ee;
627  return p_SetExp(p,v,e,r);
628}
629static inline  long p_SubExp(poly p, int v, long ee, ring r)
630{
631  p_LmCheckPolyRing2(p, r);
632  long e = p_GetExp(p,v,r);
633  pAssume2(e >= ee);
634  e -= ee;
635  return p_SetExp(p,v,e,r);
636}
637static inline  long p_MultExp(poly p, int v, long ee, ring r)
638{
639  p_LmCheckPolyRing2(p, r);
640  long e = p_GetExp(p,v,r);
641  e *= ee;
642  return p_SetExp(p,v,e,r);
643}
644
645static inline long p_GetExpSum(poly p1, poly p2, int i, ring r)
646{
647  p_LmCheckPolyRing2(p1, r);
648  p_LmCheckPolyRing2(p2, r);
649  return p_GetExp(p1,i,r) + p_GetExp(p2,i,r);
650}
651static inline long p_GetExpDiff(poly p1, poly p2, int i, ring r)
652{
653  return p_GetExp(p1,i,r) - p_GetExp(p2,i,r);
654}
655
[5948a8]656static inline int p_Comp_k_n(poly a, poly b, int k, ring r)
657{
658  if ((a==NULL) || (b==NULL) ) return FALSE;
659  p_LmCheckPolyRing2(a, r);
660  p_LmCheckPolyRing2(b, r);
661  pAssume2(k > 0 && k <= r->N);
662  int i=k;
663  for(;i<=r->N;i++)
664  {
665    if (p_GetExp(a,i,r) != p_GetExp(b,i,r)) return FALSE;
666    //    if (a->exp[(r->VarOffset[i] & 0xffffff)] != b->exp[(r->VarOffset[i] & 0xffffff)]) return FALSE;
667  }
668  return TRUE;
669}
670
[a04c5e]671
672/***************************************************************
673 *
674 * Allocation/Initalization/Deletion
675 *
676 ***************************************************************/
[0276c1]677#if PDEBUG > 2
678static inline poly p_New(const ring r, omBin bin)
679#else
[c2e8c5]680static inline poly p_New(const ring r, omBin bin)
[0276c1]681#endif
[a04c5e]682{
683  p_CheckRing2(r);
[aa2b525]684  pAssume2(bin != NULL && omSizeWOfBin(r->PolyBin) == omSizeWOfBin(bin));
[a04c5e]685  poly p;
686  omTypeAllocBin(poly, p, bin);
687  p_SetRingOfLm(p, r);
688  return p;
689}
690
691static inline poly p_New(ring r)
692{
693  return p_New(r, r->PolyBin);
694}
695
[0276c1]696#if PDEBUG > 2
[a04c5e]697static inline void p_LmFree(poly p, ring r)
[0276c1]698#else
699static inline void p_LmFree(poly p, ring)
700#endif
[a04c5e]701{
702  p_LmCheckPolyRing2(p, r);
703  omFreeBinAddr(p);
704}
[0276c1]705#if PDEBUG > 2
[a04c5e]706static inline void p_LmFree(poly *p, ring r)
[0276c1]707#else
708static inline void p_LmFree(poly *p, ring) 
709#endif
[a04c5e]710{
711  p_LmCheckPolyRing2(*p, r);
712  poly h = *p;
713  *p = pNext(h);
714  omFreeBinAddr(h);
715}
[0276c1]716#if PDEBUG > 2
[a04c5e]717static inline poly p_LmFreeAndNext(poly p, ring r)
[0276c1]718#else
719static inline poly p_LmFreeAndNext(poly p, ring)
720#endif
[a04c5e]721{
722  p_LmCheckPolyRing2(p, r);
723  poly pnext = pNext(p);
724  omFreeBinAddr(p);
725  return pnext;
726}
[8a8c9e]727static inline void p_LmDelete(poly p, const ring r)
[a04c5e]728{
729  p_LmCheckPolyRing2(p, r);
[8a8c9e]730  n_Delete(&pGetCoeff(p), r->cf);
[a04c5e]731  omFreeBinAddr(p);
732}
[8a8c9e]733static inline void p_LmDelete(poly *p, const ring r)
[a04c5e]734{
735  p_LmCheckPolyRing2(*p, r);
736  poly h = *p;
737  *p = pNext(h);
[8a8c9e]738  n_Delete(&pGetCoeff(h), r->cf);
[a04c5e]739  omFreeBinAddr(h);
740}
[8a8c9e]741static inline poly p_LmDeleteAndNext(poly p, const ring r)
[a04c5e]742{
743  p_LmCheckPolyRing2(p, r);
744  poly pnext = pNext(p);
[8a8c9e]745  n_Delete(&pGetCoeff(p), r->cf);
[a04c5e]746  omFreeBinAddr(p);
747  return pnext;
748}
749
750/***************************************************************
751 *
752 * Misc routines
753 *
754 ***************************************************************/
[20d9284]755
[21c6b3]756/// return the maximal exponent of p in form of the maximal long var
757unsigned long p_GetMaxExpL(poly p, const ring r, unsigned long l_max = 0);
[a04c5e]758
[21c6b3]759/// return monomial r such that GetExp(r,i) is maximum of all
760/// monomials in p; coeff == 0, next == NULL, ord is not set
761poly p_GetMaxExpP(poly p, ring r);
[a04c5e]762
763static inline unsigned long p_GetMaxExp(const unsigned long l, const ring r)
764{
765  unsigned long bitmask = r->bitmask;
766  unsigned long max = (l & bitmask);
767  unsigned long j = r->ExpPerLong - 1;
768
769  if (j > 0)
770  {
771    unsigned long i = r->BitsPerExp;
772    long e;
773    loop
774    {
775      e = ((l >> i) & bitmask);
776      if ((unsigned long) e > max)
777        max = e;
778      j--;
779      if (j==0) break;
780      i += r->BitsPerExp;
781    }
782  }
783  return max;
784}
785
[21c6b3]786static inline unsigned long p_GetMaxExp(const poly p, const ring r)
787{
788  return p_GetMaxExp(p_GetMaxExpL(p, r), r);
789}
790
[a04c5e]791static inline unsigned long
792p_GetTotalDegree(const unsigned long l, const ring r, const int number_of_exps)
793{
794  const unsigned long bitmask = r->bitmask;
795  unsigned long sum = (l & bitmask);
796  unsigned long j = number_of_exps - 1;
797
798  if (j > 0)
799  {
800    unsigned long i = r->BitsPerExp;
801    loop
802    {
803      sum += ((l >> i) & bitmask);
804      j--;
805      if (j==0) break;
806      i += r->BitsPerExp;
807    }
808  }
809  return sum;
810}
811
812static inline unsigned long
813p_GetTotalDegree(const unsigned long l, const ring r)
814{
815  return p_GetTotalDegree(l, r, r->ExpPerLong);
816}
817
818/***************************************************************
819 *
820 * Dispatcher to r->p_Procs, they do the tests/checks
821 *
822 ***************************************************************/
823// returns a copy of p
824static inline poly p_Copy(poly p, const ring r)
825{
826#ifdef PDEBUG
827  poly pp= r->p_Procs->p_Copy(p, r);
828  p_Test(pp,r);
829  return pp;
830#else
831  return r->p_Procs->p_Copy(p, r);
832#endif
833}
834
[20d9284]835static inline poly p_Head(poly p, const ring r)
836{
837  if (p == NULL) return NULL;
838  p_LmCheckPolyRing1(p, r);
839  poly np;
840  omTypeAllocBin(poly, np, r->PolyBin);
841  p_SetRingOfLm(np, r);
[304ad9b]842  memcpy(np->exp, p->exp, r->ExpL_Size*sizeof(long));
[20d9284]843  pNext(np) = NULL;
844  pSetCoeff0(np, n_Copy(pGetCoeff(p), r->cf));
845  return np;
846}
847
848// returns a copy of p with Lm(p) from lmRing and Tail(p) from tailRing
[a04c5e]849static inline poly p_Copy(poly p, const ring lmRing, const ring tailRing)
850{
851#ifndef PDEBUG
852  if (tailRing == lmRing)
853    return tailRing->p_Procs->p_Copy(p, tailRing);
854#endif
855  if (p != NULL)
856  {
857    poly pres = p_Head(p, lmRing);
858    pNext(pres) = tailRing->p_Procs->p_Copy(pNext(p), tailRing);
859    return pres;
860  }
861  else
862    return NULL;
863}
864
865// deletes *p, and sets *p to NULL
866static inline void p_Delete(poly *p, const ring r)
867{
868  r->p_Procs->p_Delete(p, r);
869}
870
871static inline void p_Delete(poly *p,  const ring lmRing, const ring tailRing)
872{
873#ifndef PDEBUG
874  if (tailRing == lmRing)
875  {
876    tailRing->p_Procs->p_Delete(p, tailRing);
877    return;
878  }
879#endif
880  if (*p != NULL)
881  {
882    if (pNext(*p) != NULL)
883      tailRing->p_Procs->p_Delete(&pNext(*p), tailRing);
884    p_LmDelete(p, lmRing);
885  }
886}
887
[20d9284]888// copys monomials of p, allocates new monomials from bin,
889// deletes monomoals of p
[a04c5e]890static inline poly p_ShallowCopyDelete(poly p, const ring r, omBin bin)
891{
892  p_LmCheckPolyRing2(p, r);
[aa2b525]893  pAssume2(omSizeWOfBin(r->PolyBin) == omSizeWOfBin(bin));
[a04c5e]894  return r->p_Procs->p_ShallowCopyDelete(p, r, bin);
895}
896
897// returns p+q, destroys p and q
898static inline poly p_Add_q(poly p, poly q, const ring r)
899{
[5f4015a]900  assume( (p != q) || (p == NULL && q == NULL) );
[a04c5e]901  int shorter;
902  return r->p_Procs->p_Add_q(p, q, shorter, r);
903}
904
[20d9284]905/// like p_Add_q, except that if lp == pLength(lp) lq == pLength(lq) then lp == pLength(p+q)
[a04c5e]906static inline poly p_Add_q(poly p, poly q, int &lp, int lq, const ring r)
907{
[5f4015a]908  assume( (p != q) || (p == NULL && q == NULL) );
[a04c5e]909  int shorter;
910  poly res = r->p_Procs->p_Add_q(p, q, shorter, r);
911  lp = (lp + lq) - shorter;
912  return res;
913}
[35aab3]914
[a04c5e]915// returns p*n, destroys p
916static inline poly p_Mult_nn(poly p, number n, const ring r)
917{
[8a8c9e]918  if (n_IsOne(n, r->cf))
[a04c5e]919    return p;
920  else
921    return r->p_Procs->p_Mult_nn(p, n, r);
922}
923
924static inline poly p_Mult_nn(poly p, number n, const ring lmRing,
925                        const ring tailRing)
926{
927#ifndef PDEBUG
928  if (lmRing == tailRing)
929  {
930    return p_Mult_nn(p, n, tailRing);
931  }
932#endif
933  poly pnext = pNext(p);
934  pNext(p) = NULL;
935  p = lmRing->p_Procs->p_Mult_nn(p, n, lmRing);
936  pNext(p) = tailRing->p_Procs->p_Mult_nn(pnext, n, tailRing);
937  return p;
938}
939
940// returns p*n, does not destroy p
941static inline poly pp_Mult_nn(poly p, number n, const ring r)
942{
[8a8c9e]943  if (n_IsOne(n, r->cf))
[a04c5e]944    return p_Copy(p, r);
945  else
946    return r->p_Procs->pp_Mult_nn(p, n, r);
947}
948
[20d9284]949// test if the monomial is a constant as a vector component
950// i.e., test if all exponents are zero
951static inline BOOLEAN p_LmIsConstantComp(const poly p, const ring r)
952{
953  //p_LmCheckPolyRing(p, r);
954  int i = r->VarL_Size - 1;
955
956  do
957  {
958    if (p->exp[r->VarL_Offset[i]] != 0)
959      return FALSE;
960    i--;
961  }
962  while (i >= 0);
963  return TRUE;
964}
965
966// test if monomial is a constant, i.e. if all exponents and the component
967// is zero
968static inline BOOLEAN p_LmIsConstant(const poly p, const ring r)
969{
970  if (p_LmIsConstantComp(p, r))
971    return (p_GetComp(p, r) == 0);
972  return FALSE;
973}
974
[a04c5e]975// returns Copy(p)*m, does neither destroy p nor m
976static inline poly pp_Mult_mm(poly p, poly m, const ring r)
977{
978  if (p_LmIsConstant(m, r))
979    return pp_Mult_nn(p, pGetCoeff(m), r);
980  else
981  {
982    poly last;
983    return r->p_Procs->pp_Mult_mm(p, m, r, last);
984  }
985}
986
987// returns p*m, destroys p, const: m
988static inline poly p_Mult_mm(poly p, poly m, const ring r)
989{
990  if (p_LmIsConstant(m, r))
991    return p_Mult_nn(p, pGetCoeff(m), r);
992  else
993    return r->p_Procs->p_Mult_mm(p, m, r);
994}
995
996// return p - m*Copy(q), destroys p; const: p,m
997static inline poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, const ring r)
998{
999#ifdef HAVE_PLURAL
1000  if (rIsPluralRing(r))
1001  {
1002    int lp, lq;
1003    poly spNoether;
1004    return nc_p_Minus_mm_Mult_qq(p, m, q, lp, lq, spNoether, r);
1005  }
1006#endif
1007
1008  int shorter;
1009  poly last;
1010
1011  return r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, NULL, r, last); // !!!
1012}
1013
[20d9284]1014// like p_Minus_mm_Mult_qq, except that if lp == pLength(lp) lq == pLength(lq)
1015// then lp == pLength(p -m*q)
[a04c5e]1016static inline poly p_Minus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,
1017                                 poly spNoether, const ring r)
1018{
1019#ifdef HAVE_PLURAL
1020  if (rIsPluralRing(r))
1021     return nc_p_Minus_mm_Mult_qq(p, m, q, lp, lq, spNoether, r);
1022#endif
1023
1024  int shorter;
1025  poly last,res;
1026  res = r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, spNoether, r, last);
1027  lp = (lp + lq) - shorter;
1028  return res;
1029}
1030
[20d9284]1031// returns p*Coeff(m) for such monomials pm of p, for which m is divisble by pm
[a04c5e]1032static inline poly pp_Mult_Coeff_mm_DivSelect(poly p, const poly m, const ring r)
1033{
1034  int shorter;
1035  return r->p_Procs->pp_Mult_Coeff_mm_DivSelect(p, m, shorter, r);
1036}
1037
[20d9284]1038// returns p*Coeff(m) for such monomials pm of p, for which m is divisble by pm
1039// if lp is length of p on input then lp is length of returned poly on output
[a04c5e]1040static inline poly pp_Mult_Coeff_mm_DivSelect(poly p, int &lp, const poly m, const ring r)
1041{
1042  int shorter;
1043  poly pp = r->p_Procs->pp_Mult_Coeff_mm_DivSelect(p, m, shorter, r);
1044  lp -= shorter;
1045  return pp;
1046}
1047
1048// returns -p, destroys p
1049static inline poly p_Neg(poly p, const ring r)
1050{
1051  return r->p_Procs->p_Neg(p, r);
1052}
1053
1054extern poly  _p_Mult_q(poly p, poly q, const int copy, const ring r);
1055// returns p*q, destroys p and q
1056static inline poly p_Mult_q(poly p, poly q, const ring r)
1057{
[5f4015a]1058  assume( (p != q) || (p == NULL && q == NULL) );
1059 
[a04c5e]1060  if (p == NULL)
1061  {
1062    r->p_Procs->p_Delete(&q, r);
1063    return NULL;
1064  }
1065  if (q == NULL)
1066  {
1067    r->p_Procs->p_Delete(&p, r);
1068    return NULL;
1069  }
1070
1071  if (pNext(p) == NULL)
1072  {
1073#ifdef HAVE_PLURAL
1074    if (rIsPluralRing(r))
1075      q = nc_mm_Mult_p(p, q, r);
1076    else
1077#endif /* HAVE_PLURAL */
1078      q = r->p_Procs->p_Mult_mm(q, p, r);
1079
1080    r->p_Procs->p_Delete(&p, r);
1081    return q;
1082  }
1083
1084  if (pNext(q) == NULL)
1085  {
1086  // NEEDED
1087#ifdef HAVE_PLURAL
1088/*    if (rIsPluralRing(r))
1089      p = gnc_p_Mult_mm(p, q, r); // ???
1090    else*/
1091#endif /* HAVE_PLURAL */
1092      p = r->p_Procs->p_Mult_mm(p, q, r);
1093
1094    r->p_Procs->p_Delete(&q, r);
1095    return p;
1096  }
1097#ifdef HAVE_PLURAL
1098  if (rIsPluralRing(r))
1099    return _nc_p_Mult_q(p, q, r);
1100  else
1101#endif
1102  return _p_Mult_q(p, q, 0, r);
1103}
1104
1105// returns p*q, does neither destroy p nor q
1106static inline poly pp_Mult_qq(poly p, poly q, const ring r)
1107{
1108  poly last;
1109  if (p == NULL || q == NULL) return NULL;
1110
1111  if (pNext(p) == NULL)
1112  {
1113#ifdef HAVE_PLURAL
1114    if (rIsPluralRing(r))
1115      return nc_mm_Mult_pp(p, q, r);
1116#endif
1117    return r->p_Procs->pp_Mult_mm(q, p, r, last);
1118  }
1119
1120  if (pNext(q) == NULL)
1121  {
1122    return r->p_Procs->pp_Mult_mm(p, q, r, last);
1123  }
1124
1125  poly qq = q;
1126  if (p == q)
1127    qq = p_Copy(q, r);
1128
1129  poly res;
1130#ifdef HAVE_PLURAL
1131  if (rIsPluralRing(r))
1132    res = _nc_pp_Mult_qq(p, qq, r);
1133  else
1134#endif
1135    res = _p_Mult_q(p, qq, 1, r);
1136
1137  if (qq != q)
1138    p_Delete(&qq, r);
1139  return res;
1140}
1141
1142// returns p + m*q destroys p, const: q, m
1143static inline poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, int &lp, int lq,
1144                                const ring r)
1145{
1146#ifdef HAVE_PLURAL
1147  if (rIsPluralRing(r))
1148    return nc_p_Plus_mm_Mult_qq(p, m, q, lp, lq, r);
1149#endif
1150
1151// this should be implemented more efficiently
1152  poly res, last;
1153  int shorter;
1154  number n_old = pGetCoeff(m);
[8a8c9e]1155  number n_neg = n_Copy(n_old, r->cf);
1156  n_neg = n_Neg(n_neg, r->cf);
[a04c5e]1157  pSetCoeff0(m, n_neg);
1158  res = r->p_Procs->p_Minus_mm_Mult_qq(p, m, q, shorter, NULL, r, last);
1159  lp = (lp + lq) - shorter;
1160  pSetCoeff0(m, n_old);
[8a8c9e]1161  n_Delete(&n_neg, r->cf);
[a04c5e]1162  return res;
1163}
1164
1165static inline poly p_Plus_mm_Mult_qq(poly p, poly m, poly q, const ring r)
1166{
1167  int lp = 0, lq = 0;
1168  return p_Plus_mm_Mult_qq(p, m, q, lp, lq, r);
1169}
1170
[20d9284]1171// returns merged p and q, assumes p and q have no monomials which are equal
[a04c5e]1172static inline poly p_Merge_q(poly p, poly q, const ring r)
1173{
[5f4015a]1174  assume( (p != q) || (p == NULL && q == NULL) );
[a04c5e]1175  return r->p_Procs->p_Merge_q(p, q, r);
1176}
1177
[20d9284]1178// like p_SortMerge, except that p may have equal monimals
1179static inline poly p_SortAdd(poly p, const ring r, BOOLEAN revert= FALSE)
[a04c5e]1180{
1181  if (revert) p = pReverse(p);
1182  return sBucketSortAdd(p, r);
1183}
1184
[20d9284]1185// sorts p using bucket sort: returns sorted poly
1186// assumes that monomials of p are all different
1187// reverses it first, if revert == TRUE, use this if input p is "almost" sorted
1188// correctly
1189static inline poly p_SortMerge(poly p, const ring r, BOOLEAN revert= FALSE)
[a04c5e]1190{
1191  if (revert) p = pReverse(p);
1192  return sBucketSortMerge(p, r);
1193}
1194
1195/***************************************************************
1196 *
1197 * I/O
1198 *
1199 ***************************************************************/
1200static inline char*     p_String(poly p, ring p_ring)
1201{
1202  return p_String(p, p_ring, p_ring);
1203}
1204static inline char*     p_String0(poly p, ring p_ring)
1205{
1206  return p_String0(p, p_ring, p_ring);
1207}
1208static inline void      p_Write(poly p, ring p_ring)
1209{
1210  p_Write(p, p_ring, p_ring);
1211}
1212static inline void      p_Write0(poly p, ring p_ring)
1213{
1214  p_Write0(p, p_ring, p_ring);
1215}
1216static inline void      p_wrp(poly p, ring p_ring)
1217{
1218  p_wrp(p, p_ring, p_ring);
1219}
1220
1221
1222#if PDEBUG > 0
1223
1224#define _p_LmCmpAction(p, q, r, actionE, actionG, actionS)  \
1225do                                                          \
1226{                                                           \
1227  int _cmp = p_LmCmp(p,q,r);                                \
1228  if (_cmp == 0) actionE;                                   \
1229  if (_cmp == 1) actionG;                                   \
1230  actionS;                                                  \
1231}                                                           \
1232while(0)
1233
1234#else
1235
1236#define _p_LmCmpAction(p, q, r, actionE, actionG, actionS)                      \
1237 p_MemCmp_LengthGeneral_OrdGeneral(p->exp, q->exp, r->CmpL_Size, r->ordsgn,    \
1238                                   actionE, actionG, actionS)
1239
1240#endif
1241
1242#define pDivAssume(x)   ((void)0)
1243
[4f0f42]1244
[a04c5e]1245
1246/***************************************************************
1247 *
1248 * Allocation/Initalization/Deletion
1249 *
1250 ***************************************************************/
1251// adjustments for negative weights
1252static inline void p_MemAdd_NegWeightAdjust(poly p, const ring r)
1253{
1254  if (r->NegWeightL_Offset != NULL)
1255  {
1256    for (int i=r->NegWeightL_Size-1; i>=0; i--)
1257    {
1258      p->exp[r->NegWeightL_Offset[i]] -= POLY_NEGWEIGHT_OFFSET;
1259    }
1260  }
1261}
1262static inline void p_MemSub_NegWeightAdjust(poly p, const ring r)
1263{
1264  if (r->NegWeightL_Offset != NULL)
1265  {
1266    for (int i=r->NegWeightL_Size-1; i>=0; i--)
1267    {
1268      p->exp[r->NegWeightL_Offset[i]] += POLY_NEGWEIGHT_OFFSET;
1269    }
1270  }
1271}
1272// ExpVextor(d_p) = ExpVector(s_p)
1273static inline void p_ExpVectorCopy(poly d_p, poly s_p, const ring r)
1274{
1275  p_LmCheckPolyRing1(d_p, r);
1276  p_LmCheckPolyRing1(s_p, r);
[304ad9b]1277  memcpy(d_p->exp, s_p->exp, r->ExpL_Size*sizeof(long));
[a04c5e]1278}
1279
1280static inline poly p_Init(const ring r, omBin bin)
1281{
1282  p_CheckRing1(r);
[aa2b525]1283  pAssume1(bin != NULL && omSizeWOfBin(r->PolyBin) == omSizeWOfBin(bin));
[a04c5e]1284  poly p;
1285  omTypeAlloc0Bin(poly, p, bin);
1286  p_MemAdd_NegWeightAdjust(p, r);
1287  p_SetRingOfLm(p, r);
1288  return p;
1289}
1290static inline poly p_Init(const ring r)
1291{
1292  return p_Init(r, r->PolyBin);
1293}
1294
1295static inline poly p_LmInit(poly p, const ring r)
1296{
1297  p_LmCheckPolyRing1(p, r);
1298  poly np;
1299  omTypeAllocBin(poly, np, r->PolyBin);
1300  p_SetRingOfLm(np, r);
[304ad9b]1301  memcpy(np->exp, p->exp, r->ExpL_Size*sizeof(long));
[a04c5e]1302  pNext(np) = NULL;
1303  pSetCoeff0(np, NULL);
1304  return np;
1305}
1306static inline poly p_LmInit(poly s_p, const ring s_r, const ring d_r, omBin d_bin)
1307{
1308  p_LmCheckPolyRing1(s_p, s_r);
1309  p_CheckRing(d_r);
1310  pAssume1(d_r->N <= s_r->N);
1311  poly d_p = p_Init(d_r, d_bin);
1312  for (int i=d_r->N; i>0; i--)
1313  {
1314    p_SetExp(d_p, i, p_GetExp(s_p, i,s_r), d_r);
1315  }
1316  if (rRing_has_Comp(d_r))
1317  {
1318    p_SetComp(d_p, p_GetComp(s_p,s_r), d_r);
1319  }
1320  p_Setm(d_p, d_r);
1321  return d_p;
1322}
1323static inline poly p_LmInit(poly s_p, const ring s_r, const ring d_r)
1324{
1325  pAssume1(d_r != NULL);
1326  return p_LmInit(s_p, s_r, d_r, d_r->PolyBin);
1327}
[20d9284]1328
[f550e86]1329// set all exponents l..k to 0, assume exp. k+1..n and 1..l-1 are in
[a04c5e]1330// different blocks
1331// set coeff to 1
1332static inline poly p_GetExp_k_n(poly p, int l, int k, const ring r)
1333{
1334  if (p == NULL) return NULL;
1335  p_LmCheckPolyRing1(p, r);
1336  poly np;
1337  omTypeAllocBin(poly, np, r->PolyBin);
1338  p_SetRingOfLm(np, r);
[304ad9b]1339  memcpy(np->exp, p->exp, r->ExpL_Size*sizeof(long));
[a04c5e]1340  pNext(np) = NULL;
[8a8c9e]1341  pSetCoeff0(np, n_Init(1, r->cf));
[a04c5e]1342  int i;
1343  for(i=l;i<=k;i++)
1344  {
1345    //np->exp[(r->VarOffset[i] & 0xffffff)] =0;
1346    p_SetExp(np,i,0,r);
1347  }
1348  p_Setm(np,r);
1349  return np;
1350}
1351
[20d9284]1352// simialar to p_ShallowCopyDelete but does it only for leading monomial
[0276c1]1353static inline poly p_LmShallowCopyDelete(poly p, const ring r)
[a04c5e]1354{
1355  p_LmCheckPolyRing1(p, r);
[aa2b525]1356  pAssume1(omSizeWOfBin(bin) == omSizeWOfBin(r->PolyBin));
[a04c5e]1357  poly new_p = p_New(r);
[304ad9b]1358  memcpy(new_p->exp, p->exp, r->ExpL_Size*sizeof(long));
[a04c5e]1359  pSetCoeff0(new_p, pGetCoeff(p));
1360  pNext(new_p) = pNext(p);
1361  omFreeBinAddr(p);
1362  return new_p;
1363}
1364
1365/***************************************************************
1366 *
1367 * Operation on ExpVectors
1368 *
1369 ***************************************************************/
1370// ExpVector(p1) += ExpVector(p2)
1371static inline void p_ExpVectorAdd(poly p1, poly p2, const ring r)
1372{
1373  p_LmCheckPolyRing1(p1, r);
1374  p_LmCheckPolyRing1(p2, r);
1375#if PDEBUG >= 1
1376  for (int i=1; i<=r->N; i++)
1377    pAssume1((unsigned long) (p_GetExp(p1, i, r) + p_GetExp(p2, i, r)) <= r->bitmask);
1378  pAssume1(p_GetComp(p1, r) == 0 || p_GetComp(p2, r) == 0);
1379#endif
1380
1381  p_MemAdd_LengthGeneral(p1->exp, p2->exp, r->ExpL_Size);
1382  p_MemAdd_NegWeightAdjust(p1, r);
1383}
[304ad9b]1384// ExpVector(pr) = ExpVector(p1) + ExpVector(p2)
1385static inline void p_ExpVectorSum(poly pr, poly p1, poly p2, const ring r)
1386{
1387  p_LmCheckPolyRing1(p1, r);
1388  p_LmCheckPolyRing1(p2, r);
1389  p_LmCheckPolyRing1(pr, r);
1390#if PDEBUG >= 1
1391  for (int i=1; i<=r->N; i++)
1392    pAssume1((unsigned long) (p_GetExp(p1, i, r) + p_GetExp(p2, i, r)) <= r->bitmask);
1393  pAssume1(p_GetComp(p1, r) == 0 || p_GetComp(p2, r) == 0);
1394#endif
1395
1396  p_MemSum_LengthGeneral(pr->exp, p1->exp, p2->exp, r->ExpL_Size);
1397  p_MemAdd_NegWeightAdjust(pr, r);
1398}
[a04c5e]1399// ExpVector(p1) -= ExpVector(p2)
1400static inline void p_ExpVectorSub(poly p1, poly p2, const ring r)
1401{
1402  p_LmCheckPolyRing1(p1, r);
1403  p_LmCheckPolyRing1(p2, r);
1404#if PDEBUG >= 1
1405  for (int i=1; i<=r->N; i++)
1406    pAssume1(p_GetExp(p1, i, r) >= p_GetExp(p2, i, r));
1407  pAssume1(p_GetComp(p1, r) == 0 || p_GetComp(p2, r) == 0 ||
1408          p_GetComp(p1, r) == p_GetComp(p2, r));
1409#endif
1410
1411  p_MemSub_LengthGeneral(p1->exp, p2->exp, r->ExpL_Size);
1412  p_MemSub_NegWeightAdjust(p1, r);
1413
1414}
1415// ExpVector(p1) += ExpVector(p2) - ExpVector(p3)
[304ad9b]1416//static inline void p_ExpVectorAddSub(poly p1, poly p2, poly p3, const ring r)
1417//{
1418//  p_LmCheckPolyRing1(p1, r);
1419//  p_LmCheckPolyRing1(p2, r);
1420//  p_LmCheckPolyRing1(p3, r);
1421//#if PDEBUG >= 1
1422//  for (int i=1; i<=r->N; i++)
1423//    pAssume1(p_GetExp(p1, i, r) + p_GetExp(p2, i, r) >= p_GetExp(p3, i, r));
1424//  pAssume1(p_GetComp(p1, r) == 0 ||
1425//           (p_GetComp(p2, r) - p_GetComp(p3, r) == 0) ||
1426//           (p_GetComp(p1, r) == p_GetComp(p2, r) - p_GetComp(p3, r)));
1427//#endif
1428//
1429//  p_MemAddSub_LengthGeneral(p1->exp, p2->exp, p3->exp, r->ExpL_Size);
1430//  // no need to adjust in case of NegWeights
1431//}
[a04c5e]1432
1433// ExpVector(pr) = ExpVector(p1) - ExpVector(p2)
1434static inline void p_ExpVectorDiff(poly pr, poly p1, poly p2, const ring r)
1435{
1436  p_LmCheckPolyRing1(p1, r);
1437  p_LmCheckPolyRing1(p2, r);
1438  p_LmCheckPolyRing1(pr, r);
1439#if PDEBUG >= 2
1440  for (int i=1; i<=r->N; i++)
1441    pAssume1(p_GetExp(p1, i, r) >= p_GetExp(p2, i, r));
1442  pAssume1(!rRing_has_Comp(r) || p_GetComp(p1, r) == p_GetComp(p2, r));
1443#endif
1444
1445  p_MemDiff_LengthGeneral(pr->exp, p1->exp, p2->exp, r->ExpL_Size);
1446  p_MemSub_NegWeightAdjust(pr, r);
1447}
1448
1449static inline BOOLEAN p_ExpVectorEqual(poly p1, poly p2, const ring r)
1450{
1451  p_LmCheckPolyRing1(p1, r);
1452  p_LmCheckPolyRing1(p2, r);
1453
1454  int i = r->ExpL_Size;
1455  unsigned long *ep = p1->exp;
1456  unsigned long *eq = p2->exp;
1457
1458  do
1459  {
1460    i--;
1461    if (ep[i] != eq[i]) return FALSE;
1462  }
1463  while (i);
1464  return TRUE;
1465}
1466
1467static inline long p_Totaldegree(poly p, const ring r)
1468{
1469  p_LmCheckPolyRing1(p, r);
1470  unsigned long s = p_GetTotalDegree(p->exp[r->VarL_Offset[0]],
1471                                     r,
1472                                     r->MinExpPerLong);
1473  for (int i=r->VarL_Size-1; i>0; i--)
1474  {
1475    s += p_GetTotalDegree(p->exp[r->VarL_Offset[i]], r);
1476  }
1477  return (long)s;
1478}
1479
1480static inline void p_GetExpV(poly p, int *ev, const ring r)
1481{
1482  p_LmCheckPolyRing1(p, r);
1483  for (int j = r->N; j; j--)
1484      ev[j] = p_GetExp(p, j, r);
1485
1486  ev[0] = p_GetComp(p, r);
1487}
1488static inline void p_SetExpV(poly p, int *ev, const ring r)
1489{
1490  p_LmCheckPolyRing1(p, r);
1491  for (int j = r->N; j; j--)
1492      p_SetExp(p, j, ev[j], r);
1493
1494  p_SetComp(p, ev[0],r);
1495  p_Setm(p, r);
1496}
1497
1498/***************************************************************
1499 *
1500 * Comparison w.r.t. monomial ordering
1501 *
1502 ***************************************************************/
[304ad9b]1503
[a04c5e]1504static inline int p_LmCmp(poly p, poly q, const ring r)
1505{
1506  p_LmCheckPolyRing1(p, r);
1507  p_LmCheckPolyRing1(q, r);
1508
[304ad9b]1509  const unsigned long* _s1 = ((unsigned long*) p->exp);
1510  const unsigned long* _s2 = ((unsigned long*) q->exp);
1511  register unsigned long _v1;
1512  register unsigned long _v2;
1513  const unsigned long _l = r->CmpL_Size;
1514
1515  register unsigned long _i=0;
1516
1517  LengthGeneral_OrdGeneral_LoopTop:
1518  _v1 = _s1[_i];
1519  _v2 = _s2[_i];
1520  if (_v1 == _v2)
1521  {
1522    _i++;
1523    if (_i == _l) return 0;
1524    goto LengthGeneral_OrdGeneral_LoopTop;
1525  }
1526  const long* _ordsgn = (long*) r->ordsgn;
1527  if (_v1 > _v2)
1528  {
1529    if (_ordsgn[_i] == 1) return 1;
1530    return -1;
1531  }
1532  if (_ordsgn[_i] == 1) return -1;
1533  return 1;
1534
[a04c5e]1535}
1536
[32d07a5]1537/// returns TRUE if p1 is a skalar multiple of p2
1538/// assume p1 != NULL and p2 != NULL
1539BOOLEAN p_ComparePolys(poly p1,poly p2, const ring r);
[a04c5e]1540
[bb6c8a]1541
1542/***************************************************************
1543 *
1544 * Comparisons: they are all done without regarding coeffs
1545 *
1546 ***************************************************************/
1547#define p_LmCmpAction(p, q, r, actionE, actionG, actionS) \
1548  _p_LmCmpAction(p, q, r, actionE, actionG, actionS)
1549
1550// returns 1 if ExpVector(p)==ExpVector(q): does not compare numbers !!
1551#define p_LmEqual(p1, p2, r) p_ExpVectorEqual(p1, p2, r)
1552
1553// pCmp: args may be NULL
1554// returns: (p2==NULL ? 1 : (p1 == NULL ? -1 : p_LmCmp(p1, p2)))
1555static inline int p_Cmp(poly p1, poly p2, ring r)
1556{
1557  if (p2==NULL)
1558    return 1;
1559  if (p1==NULL)
1560    return -1;
1561  return p_LmCmp(p1,p2,r);
1562}
1563
1564
[a04c5e]1565/***************************************************************
1566 *
1567 * divisibility
1568 *
1569 ***************************************************************/
1570// return: FALSE, if there exists i, such that a->exp[i] > b->exp[i]
1571//         TRUE, otherwise
1572// (1) Consider long vars, instead of single exponents
1573// (2) Clearly, if la > lb, then FALSE
1574// (3) Suppose la <= lb, and consider first bits of single exponents in l:
1575//     if TRUE, then value of these bits is la ^ lb
1576//     if FALSE, then la-lb causes an "overflow" into one of those bits, i.e.,
1577//               la ^ lb != la - lb
1578static inline BOOLEAN _p_LmDivisibleByNoComp(poly a, poly b, const ring r)
1579{
1580  int i=r->VarL_Size - 1;
1581  unsigned long divmask = r->divmask;
1582  unsigned long la, lb;
1583
1584  if (r->VarL_LowIndex >= 0)
1585  {
1586    i += r->VarL_LowIndex;
1587    do
1588    {
1589      la = a->exp[i];
1590      lb = b->exp[i];
1591      if ((la > lb) ||
1592          (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask)))
1593      {
1594        pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == FALSE);
1595        return FALSE;
1596      }
1597      i--;
1598    }
1599    while (i>=r->VarL_LowIndex);
1600  }
1601  else
1602  {
1603    do
1604    {
1605      la = a->exp[r->VarL_Offset[i]];
1606      lb = b->exp[r->VarL_Offset[i]];
1607      if ((la > lb) ||
1608          (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask)))
1609      {
1610        pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == FALSE);
1611        return FALSE;
1612      }
1613      i--;
1614    }
1615    while (i>=0);
1616  }
1617#ifdef HAVE_RINGS
1618  pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == nDivBy(p_GetCoeff(b, r), p_GetCoeff(a, r)));
[8a8c9e]1619  return (!rField_is_Ring(r)) || n_DivBy(p_GetCoeff(b, r), p_GetCoeff(a, r), r->cf);
[a04c5e]1620#else
1621  pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == TRUE);
1622  return TRUE;
1623#endif
1624}
1625
1626static inline BOOLEAN _p_LmDivisibleByNoComp(poly a, const ring r_a, poly b, const ring r_b)
1627{
1628  int i=r_a->N;
1629  pAssume1(r_a->N == r_b->N);
1630
1631  do
1632  {
1633    if (p_GetExp(a,i,r_a) > p_GetExp(b,i,r_b))
1634      return FALSE;
1635    i--;
1636  }
1637  while (i);
1638#ifdef HAVE_RINGS
[8a8c9e]1639  return n_DivBy(p_GetCoeff(b, r_b), p_GetCoeff(a, r_a), r_a->cf);
[a04c5e]1640#else
1641  return TRUE;
1642#endif
1643}
1644
1645#ifdef HAVE_RATGRING
1646static inline BOOLEAN _p_LmDivisibleByNoCompPart(poly a, const ring r_a, poly b, const ring r_b,const int start, const int end)
1647{
1648  int i=end;
1649  pAssume1(r_a->N == r_b->N);
1650
1651  do
1652  {
1653    if (p_GetExp(a,i,r_a) > p_GetExp(b,i,r_b))
1654      return FALSE;
1655    i--;
1656  }
1657  while (i>=start);
1658#ifdef HAVE_RINGS
1659  return nDivBy(p_GetCoeff(b, r), p_GetCoeff(a, r));
1660#else
1661  return TRUE;
1662#endif
1663}
1664static inline BOOLEAN _p_LmDivisibleByPart(poly a, const ring r_a, poly b, const ring r_b,const int start, const int end)
1665{
1666  if (p_GetComp(a, r_a) == 0 || p_GetComp(a,r_a) == p_GetComp(b,r_b))
1667    return _p_LmDivisibleByNoCompPart(a, r_a, b, r_b,start,end);
1668  return FALSE;
1669}
1670static inline BOOLEAN p_LmDivisibleByPart(poly a, poly b, const ring r,const int start, const int end)
1671{
1672  p_LmCheckPolyRing1(b, r);
1673  pIfThen1(a != NULL, p_LmCheckPolyRing1(b, r));
1674  if (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r))
1675    return _p_LmDivisibleByNoCompPart(a, r, b, r,start, end);
1676  return FALSE;
1677}
1678#endif
1679static inline BOOLEAN _p_LmDivisibleBy(poly a, poly b, const ring r)
1680{
1681  if (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r))
1682    return _p_LmDivisibleByNoComp(a, b, r);
1683  return FALSE;
1684}
1685static inline BOOLEAN _p_LmDivisibleBy(poly a, const ring r_a, poly b, const ring r_b)
1686{
1687  if (p_GetComp(a, r_a) == 0 || p_GetComp(a,r_a) == p_GetComp(b,r_b))
1688    return _p_LmDivisibleByNoComp(a, r_a, b, r_b);
1689  return FALSE;
1690}
1691static inline BOOLEAN p_LmDivisibleByNoComp(poly a, poly b, const ring r)
1692{
1693  p_LmCheckPolyRing1(a, r);
1694  p_LmCheckPolyRing1(b, r);
1695  return _p_LmDivisibleByNoComp(a, b, r);
1696}
1697static inline BOOLEAN p_LmDivisibleBy(poly a, poly b, const ring r)
1698{
1699  p_LmCheckPolyRing1(b, r);
1700  pIfThen1(a != NULL, p_LmCheckPolyRing1(b, r));
1701  if (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r))
1702    return _p_LmDivisibleByNoComp(a, b, r);
1703  return FALSE;
1704}
1705
1706static inline BOOLEAN p_DivisibleBy(poly a, poly b, const ring r)
1707{
1708  pIfThen1(b!=NULL, p_LmCheckPolyRing1(b, r));
1709  pIfThen1(a!=NULL, p_LmCheckPolyRing1(a, r));
1710
1711  if (a != NULL && (p_GetComp(a, r) == 0 || p_GetComp(a,r) == p_GetComp(b,r)))
1712      return _p_LmDivisibleByNoComp(a,b,r);
1713  return FALSE;
1714}
1715static inline BOOLEAN p_DivisibleBy(poly a, const ring r_a, poly b, const ring r_b)
1716{
1717  pIfThen1(b!=NULL, p_LmCheckPolyRing1(b, r_b));
1718  pIfThen1(a!=NULL, p_LmCheckPolyRing1(a, r_a));
1719  if (a != NULL) {
1720      return _p_LmDivisibleBy(a, r_a, b, r_b);
1721  }
1722  return FALSE;
1723}
1724static inline BOOLEAN p_LmDivisibleBy(poly a, const ring r_a, poly b, const ring r_b)
1725{
1726  p_LmCheckPolyRing(a, r_a);
1727  p_LmCheckPolyRing(b, r_b);
1728  return _p_LmDivisibleBy(a, r_a, b, r_b);
1729}
1730static inline BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a,
1731                                    poly b, unsigned long not_sev_b, const ring r)
1732{
1733  p_LmCheckPolyRing1(a, r);
1734  p_LmCheckPolyRing1(b, r);
1735#ifndef PDIV_DEBUG
[8a8c9e]1736  _pPolyAssume2(p_GetShortExpVector(a, r) == sev_a, a, r);
1737  _pPolyAssume2(p_GetShortExpVector(b, r) == ~ not_sev_b, b, r);
[a04c5e]1738
1739  if (sev_a & not_sev_b)
1740  {
1741    pAssume1(p_LmDivisibleByNoComp(a, b, r) == FALSE);
1742    return FALSE;
1743  }
1744  return p_LmDivisibleBy(a, b, r);
1745#else
1746  return pDebugLmShortDivisibleBy(a, sev_a, r, b, not_sev_b, r);
1747#endif
1748}
1749
1750static inline BOOLEAN p_LmShortDivisibleBy(poly a, unsigned long sev_a, const ring r_a,
1751                                      poly b, unsigned long not_sev_b, const ring r_b)
1752{
1753  p_LmCheckPolyRing1(a, r_a);
1754  p_LmCheckPolyRing1(b, r_b);
1755#ifndef PDIV_DEBUG
[8a8c9e]1756  _pPolyAssume2(p_GetShortExpVector(a, r_a) == sev_a, a, r_a);
1757  _pPolyAssume2(p_GetShortExpVector(b, r_b) == ~ not_sev_b, b, r_b);
[a04c5e]1758
1759  if (sev_a & not_sev_b)
1760  {
1761    pAssume1(_p_LmDivisibleByNoComp(a, r_a, b, r_b) == FALSE);
1762    return FALSE;
1763  }
1764  return _p_LmDivisibleBy(a, r_a, b, r_b);
1765#else
1766  return pDebugLmShortDivisibleBy(a, sev_a, r_a, b, not_sev_b, r_b);
1767#endif
1768}
1769
1770/***************************************************************
1771 *
1772 * Misc things on Lm
1773 *
1774 ***************************************************************/
1775
1776
1777// like the respective p_LmIs* routines, except that p might be empty
1778static inline BOOLEAN p_IsConstantComp(const poly p, const ring r)
1779{
1780  if (p == NULL) return TRUE;
1781  return (pNext(p)==NULL) && p_LmIsConstantComp(p, r);
1782}
1783
1784static inline BOOLEAN p_IsConstant(const poly p, const ring r)
1785{
1786  if (p == NULL) return TRUE;
1787  return (pNext(p)==NULL) && p_LmIsConstant(p, r);
1788}
1789
[20d9284]1790static inline BOOLEAN p_IsConstantPoly(const poly p, const ring r)
1791{
1792  poly pp=p;
1793  while(pp!=NULL)
1794  {
1795    if (! p_LmIsConstantComp(pp, r))
1796      return FALSE;
1797    pIter(pp);
1798  }
1799  return TRUE;
1800}
1801
[a04c5e]1802static inline BOOLEAN p_IsUnit(const poly p, const ring r)
1803{
1804  if (p == NULL) return FALSE;
1805#ifdef HAVE_RINGS
1806  if (rField_is_Ring(r))
[cf5c05]1807    return (p_LmIsConstant(p, r) && n_IsUnit(pGetCoeff(p),r->cf));
[a04c5e]1808#endif
1809  return p_LmIsConstant(p, r);
1810}
1811
1812static inline BOOLEAN p_LmExpVectorAddIsOk(const poly p1, const poly p2,
1813                                      const ring r)
1814{
1815  p_LmCheckPolyRing(p1, r);
1816  p_LmCheckPolyRing(p2, r);
1817  unsigned long l1, l2, divmask = r->divmask;
1818  int i;
1819
1820  for (i=0; i<r->VarL_Size; i++)
1821  {
1822    l1 = p1->exp[r->VarL_Offset[i]];
1823    l2 = p2->exp[r->VarL_Offset[i]];
1824    // do the divisiblity trick
1825    if ( (l1 > ULONG_MAX - l2) ||
1826         (((l1 & divmask) ^ (l2 & divmask)) != ((l1 + l2) & divmask)))
1827      return FALSE;
1828  }
1829  return TRUE;
1830}
[f34215]1831void      p_Split(poly p, poly * r);   /*p => IN(p), r => REST(p) */
1832BOOLEAN p_HasNotCF(poly p1, poly p2, const ring r);
1833poly      p_mInit(const char *s, BOOLEAN &ok, const ring r); /* monom s -> poly, interpreter */
1834const char *    p_Read(const char *s, poly &p,const ring r); /* monom -> poly */
[fb4075b]1835poly      p_Divide(poly a, poly b, const ring r);
1836poly      p_DivideM(poly a, poly b, const ring r);
[b27c052]1837poly      p_Div_nn(poly p, const number n, const ring r);
[a7ee69]1838void      p_Lcm(poly a, poly b, poly m, const ring r);
[ac0bd6]1839poly      p_Diff(poly a, int k, const ring r);
[5162db]1840poly      p_DiffOp(poly a, poly b,BOOLEAN multiply, const ring r);
[bf183f]1841int       p_Weight(int c, const ring r);
1842
[f0b01f]1843/* assumes that p and divisor are univariate polynomials in r,
[ba2359]1844   mentioning the same variable;
1845   assumes divisor != NULL;
[f0b01f]1846   p may be NULL;
[ba2359]1847   assumes a global monomial ordering in r;
[f0b01f]1848   performs polynomial division of p by divisor:
1849     - afterwards p contains the remainder of the division, i.e.,
1850       p_before = result * divisor + p_afterwards;
[ba2359]1851     - if needResult == TRUE, then the method computes and returns 'result',
1852       otherwise NULL is returned (This parametrization can be used when
1853       one is only interested in the remainder of the division. In this
[f0b01f]1854       case, the method will be slightly faster.)
1855   leaves divisor unmodified */
1856poly      p_PolyDiv(poly &p, poly divisor, BOOLEAN needResult, ring r);
[ba2359]1857
[c28ecf]1858/* returns NULL if p == NULL, otherwise makes p monic by dividing
1859   by its leading coefficient (only done if this is not already 1);
1860   this assumes that we are over a ground field so that division
1861   is well-defined;
1862   modifies p */
[90aec7]1863void      p_Monic(poly p, const ring r);
[c28ecf]1864
[ba2359]1865/* assumes that p and q are univariate polynomials in r,
1866   mentioning the same variable;
1867   assumes a global monomial ordering in r;
1868   assumes that not both p and q are NULL;
[f0b01f]1869   returns the gcd of p and q;
1870   leaves p and q unmodified */
[ba2359]1871poly      p_Gcd(poly p, poly q, ring r);
1872
1873/* assumes that p and q are univariate polynomials in r,
1874   mentioning the same variable;
1875   assumes a global monomial ordering in r;
1876   assumes that not both p and q are NULL;
1877   returns the gcd of p and q;
[f0b01f]1878   moreover, afterwards pFactor and qFactor contain appropriate
1879   factors such that gcd(p, q) = p * pFactor + q * qFactor;
1880   leaves p and q unmodified */
1881poly      p_ExtGcd(poly p, poly &pFactor, poly q, poly &qFactor, ring r);
[ba2359]1882
[cd246b]1883/* syszygy stuff */
1884BOOLEAN   p_VectorHasUnitB(poly p, int * k, const ring r);
1885void      p_VectorHasUnit(poly p, int * k, int * len, const ring r);
1886poly      p_TakeOutComp1(poly * p, int k, const ring r);
[74021a]1887// Splits *p into two polys: *q which consists of all monoms with
1888// component == comp and *p of all other monoms *lq == pLength(*q)
1889// On return all components pf *q == 0
1890void p_TakeOutComp(poly *p, long comp, poly *q, int *lq, const ring r);
1891
1892// This is something weird -- Don't use it, unless you know what you are doing
[1a20e5]1893poly      p_TakeOutComp(poly * p, int k, const ring r);
[74021a]1894
1895void      p_DeleteComp(poly * p,int k, const ring r);
1896
[5c39a9]1897/*-------------ring management:----------------------*/
1898
[949e57]1899// resets the pFDeg and pLDeg: if pLDeg is not given, it is
1900// set to currRing->pLDegOrig, i.e. to the respective LDegProc which
1901// only uses pFDeg (and not pDeg, or pTotalDegree, etc).
1902// If you use this, make sure your procs does not make any assumptions
1903// on ordering and/or OrdIndex -- otherwise they might return wrong results
1904// on strat->tailRing
[8a8c9e]1905void pSetDegProcs(ring r, pFDegProc new_FDeg, pLDegProc new_lDeg = NULL);
[949e57]1906// restores pFDeg and pLDeg:
[8a8c9e]1907void pRestoreDegProcs(ring r, pFDegProc old_FDeg, pLDegProc old_lDeg);
[949e57]1908
[5bc2461]1909/*-------------pComp for syzygies:-------------------*/
1910void p_SetModDeg(intvec *w, ring r);
[949e57]1911
[f550e86]1912/*------------ Jet ----------------------------------*/
1913poly pp_Jet(poly p, int m, const ring R);
1914poly p_Jet(poly p, int m,const ring R);
1915poly pp_JetW(poly p, int m, short *w, const ring R);
1916poly p_JetW(poly p, int m, short *w, const ring R);
[deca086]1917
[83a1714]1918poly n_PermNumber(const number z, const int *par_perm, const int OldPar, const ring src, const ring dst);
[deca086]1919
[83a1714]1920poly p_PermPoly (poly p, const int * perm,const ring OldRing, const ring dst,
1921                     nMapFunc nMap, const int *par_perm=NULL, int OldPar=0);
[deca086]1922
[a4081e5]1923/*----------------------------------------------------*/
1924poly p_Series(int n,poly p,poly u, intvec *w, const ring R);
1925poly p_Invers(int n,poly u,intvec *w, const ring R);
1926
1927
[aa450d]1928
1929/*----------------------------------------------------*/
[d914cf0]1930int   p_Var(poly mi, const ring r);
[73ad0c]1931/// the minimal index of used variables - 1
[d914cf0]1932int   p_LowVar (poly p, const ring r);
[aa450d]1933
[1fdb6e]1934/*----------------------------------------------------*/
1935// returns the length of a polynomial (numbers of monomials) and the last mon.
1936// respect syzComp
1937poly p_Last(poly a, int &l, const ring r);
[b7cfaf]1938
1939/// shifts components of the vector p by i
1940void p_Shift (poly * p,int i, const ring r);
[35aab3]1941#endif // P_POLYS_H
1942
Note: See TracBrowser for help on using the repository browser.