source: git/Singular/polys.cc @ c1489f2

fieker-DuValspielwiese
Last change on this file since c1489f2 was c1489f2, checked in by Olaf Bachmann <obachman@…>, 25 years ago
* stuff from Thomas * various bug fixes git-svn-id: file:///usr/local/Singular/svn/trunk@3730 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 36.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: polys.cc,v 1.50 1999-10-19 12:42:47 obachman Exp $ */
5
6/*
7* ABSTRACT - all basic methods to manipulate polynomials
8*/
9
10/* includes */
11#include <stdio.h>
12#include <string.h>
13#include <ctype.h>
14#include "mod2.h"
15#include "tok.h"
16#include "mmemory.h"
17#include "febase.h"
18#include "numbers.h"
19#include "polys.h"
20#include "ring.h"
21#include "binom.h"
22#include "polys-comp.h"
23
24/* ----------- global variables, set by pSetGlobals --------------------- */
25/* initializes the internal data from the exp vector */
26pSetmProc pSetm;
27/* computes length and maximal degree of a POLYnomial */
28pLDegProc pLDeg;
29/* computes the degree of the initial term, used for std */
30pFDegProc pFDeg;
31/* the monomial ordering of the head monomials a and b */
32/* returns -1 if a comes before b, 0 if a=b, 1 otherwise */
33pCompProc pComp0;
34
35int pVariables;     // number of variables
36//int pVariablesW;    // number of words of pVariables exponents
37//int pVariables1W;   // number of words of (pVariables+1) exponents
38int pMonomSize;     // size of monom (in bytes)
39int pMonomSizeW;    // size of monom (in words)
40int *pVarOffset;    // controls the way exponents are stored in a vector
41//int pVarLowIndex;   // lowest exponent index
42//int pVarHighIndex;  // highest exponent index
43//int pVarCompIndex;  // Location of component in exponent vector
44
45/* 1 for polynomial ring, -1 otherwise */
46int     pOrdSgn;
47/* TRUE for momomial output as x2y, FALSE for x^2*y */
48int pShortOut = (int)TRUE;
49// it is of type int, not BOOLEAN because it is also in ip
50/* TRUE if the monomial ordering is not compatible with pFDeg */
51BOOLEAN pLexOrder;
52/* TRUE if the monomial ordering has polynomial and power series blocks */
53BOOLEAN pMixedOrder;
54/* 1 for c ordering, -1 otherwise (i.e. for C ordering) */
55int  pComponentOrder;
56
57/* ----------- global variables, set by procedures from hecke/kstd1 ----- */
58/* the highest monomial below pHEdge */
59poly      ppNoether = NULL;
60
61/* -------------- static variables --------------------------------------- */
62/*is the basic comparing procedure during a computation of syzygies*/
63static pCompProc pCompOld;
64/*for grouping module indicies during computations*/
65int pMaxBound = 0;
66
67/*contains the headterms for the Schreyer orderings*/
68static int* SchreyerOrd;
69static int maxSchreyer=0;
70static int indexShift=0;
71static pLDegProc pLDegOld;
72
73static int**   polys_wv;
74static short *   firstwv;
75static int * block0;
76static int * block1;
77static int firstBlockEnds;
78static int * order;
79
80/*0 implementation*/
81/*-------- the several possibilities for pSetm:-----------------------*/
82
83void rSetm(poly p)
84{
85  int pos=0;
86  if (currRing->typ!=NULL)
87  {
88    loop
89    {
90      sro_ord* o=&(currRing->typ[pos]);
91      switch(o->ord_typ)
92      {
93        case ro_dp:
94        {
95          int a,e;
96          a=o->data.dp.start;
97          e=o->data.dp.end;
98          long ord=0;
99          for(int i=a;i<=e;i++) ord+=pGetExp(p,i);
100          p->exp.l[o->data.dp.place]=ord;
101          break;
102        }
103        case ro_wp:
104        {
105          int a,e;
106          a=o->data.wp.start;
107          e=o->data.wp.end;
108          int *w=o->data.wp.weights;
109          long ord=0;
110          for(int i=a;i<=e;i++) ord+=pGetExp(p,i)*w[i-a];
111          p->exp.l[o->data.wp.place]=ord;
112          break;
113        }
114        case ro_cp:
115        {
116          int a,e;
117          a=o->data.cp.start;
118          e=o->data.cp.end;
119          int pl=o->data.cp.place;
120          for(int i=a;i<=e;i++) { p->exp.e[pl]=pGetExp(p,i); pl++; }
121          break;
122        }
123        case ro_syzcomp:
124        {
125          int c=pGetComp(p);
126          long sc = c;
127#if 1
128          if (o->data.syzcomp.ShiftedComponents != NULL)
129          {
130            assume(o->data.syzcomp.Components != NULL);
131            assume(c == 0 || o->data.syzcomp.Components[c] != 0);
132            sc =
133              o->data.syzcomp.ShiftedComponents[o->data.syzcomp.Components[c]];
134            assume(c == 0 || sc != 0);
135          }
136          p->exp.l[o->data.syzcomp.place]=sc;
137#endif
138          break;
139        }
140        case ro_syz:
141        {
142          int c=pGetComp(p);
143          if (c > o->data.syz.limit)
144            p->exp.l[o->data.syz.place]= 1;
145          else
146            p->exp.l[o->data.syz.place]= 0;
147          break;
148        }
149        default:
150          Print("wrong ord in rSetm:%d\n",o->ord_typ);
151          return;
152      }
153      pos++;
154      if(pos==currRing->OrdSize) return;
155    }
156  }
157}
158
159void rSetmS(poly p, int* Components, long* ShiftedComponents)
160{
161  int pos=0;
162  assume(Components != NULL && ShiftedComponents != NULL);
163  if (currRing->typ!=NULL)
164  {
165    loop
166    {
167      sro_ord* o=&(currRing->typ[pos]);
168      switch(o->ord_typ)
169      {
170        case ro_dp:
171        {
172          int a,e;
173          a=o->data.dp.start;
174          e=o->data.dp.end;
175          long ord=0;
176          for(int i=a;i<=e;i++) ord+=pGetExp(p,i);
177          p->exp.l[o->data.dp.place]=ord;
178          break;
179        }
180        case ro_wp:
181        {
182          int a,e;
183          a=o->data.wp.start;
184          e=o->data.wp.end;
185          int *w=o->data.wp.weights;
186          long ord=0;
187          for(int i=a;i<=e;i++) ord+=pGetExp(p,i)*w[i-a];
188          p->exp.l[o->data.wp.place]=ord;
189          break;
190        }
191        case ro_cp:
192        {
193          int a,e;
194          a=o->data.cp.start;
195          e=o->data.cp.end;
196          int pl=o->data.cp.place;
197          for(int i=a;i<=e;i++) { p->exp.e[pl]=pGetExp(p,i); pl++; }
198          break;
199        }
200        case ro_syzcomp:
201        {
202#if 1
203          int c=pGetComp(p);
204          long sc  = ShiftedComponents[Components[c]];
205          assume(c == 0 || Components[c] != 0);
206          assume(c == 0 || sc != 0);
207          p->exp.l[o->data.syzcomp.place]=sc;
208#endif
209          break;
210        }
211        default:
212          Print("wrong ord in rSetm:%d\n",o->ord_typ);
213          return;
214      }
215      pos++;
216      if(pos==currRing->OrdSize) return;
217    }
218  }
219}
220
221/*-------- IMPLEMENTATION OF MONOMIAL COMPARISONS ---------------------*/
222
223
224#define NonZeroR(l, actionG, actionS)           \
225do                                              \
226{                                               \
227  long _l = l;                                  \
228  if (_l)                                       \
229  {                                             \
230    if (_l > 0) actionG;                        \
231    actionS;                                    \
232  }                                             \
233}                                               \
234while(0)
235
236#define Mreturn(d, multiplier)                      \
237{                                                   \
238  if (d > 0) return multiplier;                     \
239  return -multiplier;                               \
240}
241
242
243/*---------------------------------------------------*/
244
245int pComp(poly p1, poly p2)
246{
247  if (p2==NULL)
248    return 1;
249  if (p1==NULL)
250    return -1;
251  return pComp0(p1,p2);
252}
253
254
255/*----------pComp handling for syzygies---------------------*/
256static void newHeadsB(polyset actHeads,int length)
257{
258  int i;
259  int* newOrder=(int*)Alloc(length*sizeof(int));
260
261  for (i=0;i<length;i++)
262  {
263    if (actHeads[i]!=NULL)
264    {
265      newOrder[i] = SchreyerOrd[pGetComp(actHeads[i])-1];
266    }
267    else
268    {
269      newOrder[i]=0;
270    }
271  }
272  Free((ADDRESS)SchreyerOrd,maxSchreyer*sizeof(int));
273  SchreyerOrd = newOrder;
274  maxSchreyer = length;
275/*
276*for (i=0;i<maxSchreyer;i++); Print("%d  ",SchreyerOrd[i]);
277*PrintLn();
278*/
279}
280
281int mcompSchrB(poly p1,poly p2)
282{
283  int CompP1=pGetComp(p1),CompP2=pGetComp(p2),result,
284      cP1=SchreyerOrd[CompP1-1],cP2=SchreyerOrd[CompP2-1];
285
286  if (CompP1==CompP2) return pCompOld(p1,p2);
287  pSetComp(p1,cP1);
288  pSetComp(p2,cP2);
289  result = pCompOld(p1,p2);
290  pSetComp(p1,CompP1);
291  pSetComp(p2,CompP2);
292  if (!result)
293  {
294    if (CompP1>CompP2)
295      return -1;
296    else if (CompP1<CompP2)
297      return 1;
298  }
299  return result;
300}
301
302
303static void newHeadsM(polyset actHeads,int length)
304{
305  int i;
306  int* newOrder=
307    (int*)Alloc0((length+maxSchreyer-indexShift)*sizeof(int));
308
309  //for (i=0;i<length+maxSchreyer-indexShift;i++)
310  //  newOrder[i]=0;
311  for (i=indexShift;i<maxSchreyer;i++)
312  {
313    newOrder[i-indexShift] = SchreyerOrd[i];
314    SchreyerOrd[i] = 0;
315  }
316  for (i=maxSchreyer-indexShift;i<length+maxSchreyer-indexShift;i++)
317    newOrder[i] = newOrder[pGetComp(actHeads[i-maxSchreyer+indexShift])-1];
318  Free((ADDRESS)SchreyerOrd,maxSchreyer*sizeof(int));
319  SchreyerOrd = newOrder;
320  indexShift = maxSchreyer-indexShift;
321  maxSchreyer = length+indexShift;
322}
323
324/*2
325* compute the length of a polynomial (in l)
326* and the degree of the monomial with maximal degree:
327* this is NOT the last one and the module component
328* has to be <= indexShift
329*/
330static int ldegSchrM(poly p,int *l)
331{
332  int  t,max;
333
334  (*l)=1;
335  max=pFDeg(p);
336  while ((pNext(p)!=NULL) && (pGetComp(pNext(p))<=indexShift))
337  {
338    pIter(p);
339    t=pFDeg(p);
340    if (t>max) max=t;
341    (*l)++;
342  }
343  return max;
344}
345
346int mcompSchrM(poly p1,poly p2)
347{
348  if ( pGetComp(p1)<=indexShift)
349  {
350    if ( pGetComp(p2)>indexShift) return 1;
351  }
352  else if ( pGetComp(p2)<=indexShift)  return -1;
353  return mcompSchrB(p1,p2);
354}
355
356void pSetSchreyerOrdM(polyset nextOrder, int length,int comps)
357{
358  int i;
359
360  if (length!=0)
361  {
362    if (maxSchreyer!=0)
363      newHeadsM(nextOrder, length);
364    else
365    {
366      indexShift = comps;
367      if (indexShift==0) indexShift = 1;
368      SchreyerOrd = (int*)Alloc((indexShift+length)*sizeof(int));
369      maxSchreyer = length+indexShift;
370      for (i=0;i<indexShift;i++)
371        SchreyerOrd[i] = i;
372      for (i=indexShift;i<maxSchreyer;i++)
373        SchreyerOrd[i] = pGetComp(nextOrder[i-indexShift]);
374      pCompOld = pComp0;
375      pComp0 = mcompSchrM;
376      pLDegOld = pLDeg;
377      pLDeg = ldegSchrM;
378    }
379  }
380  else
381  {
382    if (maxSchreyer!=0)
383    {
384      Free((ADDRESS)SchreyerOrd,maxSchreyer*sizeof(int));
385      maxSchreyer = 0;
386      indexShift = 0;
387      pComp0 = pCompOld;
388      pLDeg = pLDegOld;
389    }
390  }
391}
392
393void pSetSyzComp(int k)
394{
395  pMaxBound=k;
396  if((currRing->typ!=NULL) && (currRing->typ[0].ord_typ==ro_syz))
397  {
398    if (currRing->typ!=NULL)
399      currRing->typ[0].data.syz.limit=k;
400  }
401  else if ((currRing->order[0]!=ringorder_c) && (k!=0))
402  {
403    WarnS("syzcomp in incompatible ring");
404  }
405}
406
407/*2
408* the type of the module ordering: C: -1, c: 1
409*/
410int pModuleOrder()
411{
412  return pComponentOrder;
413}
414
415/* -------------------------------------------------------------------*/
416/* several possibilities for pFDeg: the degree of the head term       */
417/*2
418* compute the degree of the leading monomial of p
419* the ordering is compatible with degree, use a->order
420*/
421int pDeg(poly a)
422{
423  return pGetOrder(a);
424}
425
426/*2
427* compute the degree of the leading monomial of p
428* with respect to weigths 1
429* (all are 1 so save multiplications or they are of different signs)
430* the ordering is not compatible with degree so do not use p->Order
431*/
432int pTotaldegree(poly p)
433{
434  return pExpQuerSum(p);
435}
436
437/*2
438* compute the degree of the leading monomial of p
439* with respect to weigths from the ordering
440* the ordering is not compatible with degree so do not use p->Order
441*/
442int pWTotaldegree(poly p)
443{
444  assume(p != NULL);
445  int i, k;
446  int j =0;
447
448  // iterate through each block:
449  for (i=0;order[i]!=0;i++)
450  {
451    switch(order[i])
452    {
453      case ringorder_wp:
454      case ringorder_ws:
455      case ringorder_Wp:
456      case ringorder_Ws:
457        for (k=block0[i];k<=block1[i];k++)
458        { // in jedem block:
459          j+= pGetExp(p,k)*polys_wv[i][k-block0[i]];
460        }
461        break;
462      case ringorder_M:
463      case ringorder_lp:
464      case ringorder_dp:
465      case ringorder_ds:
466      case ringorder_Dp:
467      case ringorder_Ds:
468        for (k=block0[i];k<=block1[i];k++)
469        {
470          j+= pGetExp(p,k);
471        }
472        break;
473      case ringorder_c:
474      case ringorder_C:
475      case ringorder_S:
476        break;
477      case ringorder_a:
478        for (k=block0[i];k<=block1[i];k++)
479        { // only one line
480          j+= pGetExp(p,k)*polys_wv[i][k-block0[i]];
481        }
482        return j;
483    }
484  }
485  return  j;
486}
487int pWDegree(poly p)
488{
489  int i, k;
490  int j =0;
491
492  for(i=1;i<=pVariables;i++)
493    j+=pGetExp(p,i)*pWeight(i);
494  return j;
495}
496
497/* ---------------------------------------------------------------------*/
498/* several possibilities for pLDeg: the maximal degree of a monomial in p*/
499/*  compute in l also the pLength of p                                   */
500
501/*2
502* compute the length of a polynomial (in l)
503* and the degree of the monomial with maximal degree: the last one
504*/
505static int ldeg0(poly p,int *l)
506{
507  Exponent_t k= pGetComp(p);
508  int ll=1;
509
510  while ((pNext(p)!=NULL) && (pGetComp(pNext(p))==k))
511  {
512    pIter(p);
513    ll++;
514  }
515  *l=ll;
516  return pGetOrder(p);
517}
518
519/*2
520* compute the length of a polynomial (in l)
521* and the degree of the monomial with maximal degree: the last one
522* but search in all components before syzcomp
523*/
524static int ldeg0c(poly p,int *l)
525{
526  int o=pFDeg(p);
527  int ll=1;
528
529  if (pMaxBound/*syzComp*/==0)
530  {
531    while ((p=pNext(p))!=NULL)
532    {
533      o=pFDeg(p);
534      ll++;
535    }
536  }
537  else
538  {
539    while ((p=pNext(p))!=NULL)
540    {
541      if (pGetComp(p)<=pMaxBound/*syzComp*/)
542      {
543        o=pFDeg(p);
544        ll++;
545      }
546      else break;
547    }
548  }
549  *l=ll;
550  return o;
551}
552
553/*2
554* compute the length of a polynomial (in l)
555* and the degree of the monomial with maximal degree: the first one
556* this works for the polynomial case with degree orderings
557* (both c,dp and dp,c)
558*/
559static int ldegb(poly p,int *l)
560{
561  Exponent_t k= pGetComp(p);
562  int o = pFDeg(p);
563  int ll=1;
564
565  while (((p=pNext(p))!=NULL) && (pGetComp(p)==k))
566  {
567    ll++;
568  }
569  *l=ll;
570  return o;
571}
572
573/*2
574* compute the length of a polynomial (in l)
575* and the degree of the monomial with maximal degree:
576* this is NOT the last one, we have to look for it
577*/
578static int ldeg1(poly p,int *l)
579{
580  Exponent_t k= pGetComp(p);
581  int ll=1;
582  int  t,max;
583
584  max=pFDeg(p);
585  while (((p=pNext(p))!=NULL) && (pGetComp(p)==k))
586  {
587    t=pFDeg(p);
588    if (t>max) max=t;
589    ll++;
590  }
591  *l=ll;
592  return max;
593}
594
595/*2
596* compute the length of a polynomial (in l)
597* and the degree of the monomial with maximal degree:
598* this is NOT the last one, we have to look for it
599* in all components
600*/
601static int ldeg1c(poly p,int *l)
602{
603  int ll=1;
604  int  t,max;
605
606  max=pFDeg(p);
607  while ((p=pNext(p))!=NULL)
608  {
609    if ((pMaxBound/*syzComp*/==0) || (pGetComp(p)<=pMaxBound/*syzComp*/))
610    {
611       if ((t=pFDeg(p))>max) max=t;
612       ll++;
613    }
614    else break;
615  }
616  *l=ll;
617  return max;
618}
619
620/* -------------------------------------------------------- */
621/* set the variables for a choosen ordering                 */
622
623
624/*2
625* sets the comparision routine for monomials: for all but the first
626* block of variables (ip is the block number, o_r the number of the ordering)
627*/
628static void HighSet(int ip, int o_r)
629{
630  switch(o_r)
631  {
632    case ringorder_lp:
633    case ringorder_dp:
634    case ringorder_Dp:
635    case ringorder_wp:
636    case ringorder_Wp:
637    case ringorder_a:
638      if (pOrdSgn==-1) pMixedOrder=TRUE;
639      break;
640    case ringorder_ls:
641    case ringorder_ds:
642    case ringorder_Ds:
643    case ringorder_ws:
644    case ringorder_Ws:
645    case ringorder_s:
646      break;
647    case ringorder_c:
648      pComponentOrder=1;
649      break;
650    case ringorder_C:
651    case ringorder_S:
652      pComponentOrder=-1;
653      break;
654    case ringorder_M:
655      pMixedOrder=TRUE;
656      break;
657#ifdef TEST
658    default:
659      Werror("wrong internal ordering:%d at %s, l:%d\n",o_r,__FILE__,__LINE__);
660#endif
661  }
662}
663
664/* -------------------------------------------------------- */
665/*2
666* change all variables to fit the description of the new ring
667*/
668
669//void pChangeRing(ring newRing)
670//{
671//  rComplete(newRing);
672//  pSetGlobals(newRing);
673//}
674
675void pSetGlobals(ring r, BOOLEAN complete)
676{
677  int i;
678  pComponentOrder=1;
679  if (ppNoether!=NULL) pDelete(&ppNoether);
680  pVariables = r->N;
681
682  // set the various size parameters and initialize memory
683  pMonomSize = POLYSIZE + r->ExpLSize * sizeof(long);
684  pMonomSizeW = pMonomSize/sizeof(void*);
685
686  // Initialize memory management
687  mm_specHeap = r->mm_specHeap;
688
689  pVarOffset = r->VarOffset;
690
691  pOrdSgn = r->OrdSgn;
692  pVectorOut=(r->order[0]==ringorder_c);
693  order=r->order;
694  block0=r->block0;
695  block1=r->block1;
696  firstwv=NULL;
697  polys_wv=r->wvhdl;
698  if (order[0]==ringorder_S)
699  {
700    order++;
701    block0++;
702    block1++;
703    polys_wv++;
704  }
705  pFDeg=pTotaldegree;
706  /*------- only one real block ----------------------*/
707  pLexOrder=FALSE;
708  pMixedOrder=FALSE;
709  if (pOrdSgn == 1) pLDeg = ldegb;
710  else              pLDeg = ldeg0;
711  /*======== ordering type is (_,c) =========================*/
712  if ((order[0]==ringorder_unspec)
713  ||(
714    ((order[1]==ringorder_c)||(order[1]==ringorder_C)||(order[1]==ringorder_S))
715    && (order[0]!=ringorder_M)
716    && (order[2]==0))
717  )
718  {
719    if ((order[0]!=ringorder_unspec)
720    && ((order[1]==ringorder_C)||(order[1]==ringorder_S)))
721      pComponentOrder=-1;
722    if (pOrdSgn == -1) pLDeg = ldeg0c;
723    if ((order[0] == ringorder_lp) || (order[0] == ringorder_ls))
724    {
725      pLexOrder=TRUE;
726      pLDeg = ldeg1c;
727    }
728    if (order[0] == ringorder_wp || order[0] == ringorder_Wp ||
729        order[0] == ringorder_ws || order[0] == ringorder_Ws)
730      pFDeg = pWTotaldegree;
731    firstBlockEnds=block1[0];
732  }
733  /*======== ordering type is (c,_) =========================*/
734  else if (((order[0]==ringorder_c)
735    ||(order[0]==ringorder_C)
736    ||(order[0]==ringorder_S))
737  && (order[1]!=ringorder_M)
738  &&  (order[2]==0))
739  {
740    /* pLDeg = ldeg0; is standard*/
741    if ((order[0]==ringorder_C)||(order[0]==ringorder_S))
742      pComponentOrder=-1;
743    if ((order[1] == ringorder_lp) || (order[1] == ringorder_ls))
744    {
745      pLexOrder=TRUE;
746      pLDeg = ldeg1c;
747    }
748    firstBlockEnds=block1[1];
749    if (order[1] == ringorder_wp || order[1] == ringorder_Wp ||
750        order[1] == ringorder_ws || order[1] == ringorder_Ws)
751      pFDeg = pWTotaldegree;
752  }
753  /*------- more than one block ----------------------*/
754  else
755  {
756    //pGetVarIndicies(pVariables, pVarOffset, pVarCompIndex, pVarLowIndex,
757    //                pVarHighIndex);
758    //pLexOrder=TRUE;
759    pVectorOut=order[0]==ringorder_c;
760    if ((pVectorOut)||(order[0]==ringorder_C)||(order[0]==ringorder_S))
761    {
762      if(block1[1]!=pVariables) pLexOrder=TRUE;
763      firstBlockEnds=block1[1];
764    }
765    else
766    {
767      if(block1[0]!=pVariables) pLexOrder=TRUE;
768      firstBlockEnds=block1[0];
769    }
770    /*the number of orderings:*/
771    i = 0;
772    while (order[++i] != 0);
773    do
774    {
775      i--;
776      HighSet(i, order[i]);/*sets also pMixedOrder to TRUE, if...*/
777    }
778    while (i != 0);
779
780    if ((order[0]!=ringorder_c)
781    &&(order[0]!=ringorder_C)
782    &&(order[0]!=ringorder_S))
783    {
784      pLDeg = ldeg1c;
785    }
786    else
787    {
788      pLDeg = ldeg1;
789    }
790    pFDeg = pWTotaldegree; // may be improved: pTotaldegree for lp/dp/ls/.. blocks
791  }
792  if (complete)
793  {
794    if ((pLexOrder) || (pOrdSgn==-1))
795    {
796      test &= ~Sy_bit(OPT_REDTAIL); /* noredTail */
797    }
798    pSetm=rSetm;
799    pComp0=rComp0;
800  }
801  if (pFDeg!=pWTotaldegree) pFDeg=pTotaldegree;
802}
803
804/* -------------------------------------------------------- */
805
806static Exponent_t pMultT_nok;
807/*2
808* update the polynomial a by multipying it by
809* the (number) coefficient
810* and the exponent vector (of) exp (a well initialized polynomial)
811*/
812poly pMultT(poly a, poly exp )
813{
814  int i;
815  number t,x,y=pGetCoeff(exp);
816  poly aa=a;
817  poly prev=NULL;
818
819  pMultT_nok = pGetComp(exp);
820#ifdef PDEBUG
821  pTest(a);
822  pTest(exp);
823#endif
824  while (a !=NULL)
825  {
826    x=pGetCoeff(a);
827    t=nMult(x/*pGetCoeff(a)*/,y/*pGetCoeff(exp)*/);
828    nDelete(&x/*pGetCoeff(a)*/);
829    pSetCoeff0(a,t);
830    if (nIsZero(t))
831    {
832      if (prev==NULL) { pDelete1(&a); aa=a; }
833      else            { pDelete1(&prev->next); a=prev->next;}
834    }
835    else
836    {
837      {
838        if (pMultT_nok)  /* comp of exp != 0 */
839        {
840          if (pGetComp(a) != 0)
841          {
842            return NULL /*FALSE*/;
843          }
844        }
845        pMonAddOn(a,exp);
846      }
847      prev=a;
848      pIter(a);
849    }
850  }
851  pMultT_nok=0;
852  pTest(aa);
853  return aa; /*TRUE*/
854}
855
856/*2
857* multiply p1 with p2, p1 and p2 are destroyed
858* do not put attention on speed: the procedure is only used in the interpreter
859*/
860poly pMult(poly p1, poly p2)
861{
862  poly res, r, rn, a;
863  BOOLEAN cont;
864
865  if ((p1!=NULL) && (p2!=NULL))
866  {
867#ifdef PDEBUG
868    pTest(p1);
869    pTest(p2);
870#endif
871    cont = TRUE;
872    a = p1;
873    if (pNext(p2)!=NULL)
874      a = pCopy(a);
875    else
876      cont = FALSE;
877    res = pMultT(a, p2);
878    if (pMultT_nok)
879    {
880      if (cont) pDelete(&p1);
881      pDelete(&res);
882      pDelete(&p2);
883      return NULL;
884    }
885    pTest(res);
886    pDelete1(&p2);
887    r = res;
888    if (r!=NULL) rn = pNext(r);
889    else         rn=NULL;
890    while (cont)
891    {
892      if (pNext(p2)==NULL)
893      {
894        a = p1;
895        cont = FALSE;
896      }
897      else
898      {
899        a = pCopy(p1);
900      }
901      a=pMultT(a, p2); //sets pMultT_nok
902      pTest(a);
903      if (pMultT_nok)
904      {
905        if (cont) pDelete(&p1);
906        pDelete(&a);
907        pDelete(&res);
908        pDelete(&p2);
909        return NULL;
910      }
911      while ((rn!=NULL) && (pComp0(rn,a)>0))
912      {
913        r = rn;
914        pIter(rn);
915      }
916      if (r!=NULL) pNext(r) = rn = pAdd(a, rn);
917      else         res=r=a;
918      pDelete1(&p2);
919    }
920    pTest(res);
921    return res;
922  }
923  pDelete(&p1);
924  pDelete(&p2);
925  return NULL;
926}
927
928/*2
929* update a by multiplying it with c (c will not be destroyed)
930*/
931void pMultN(poly a, number c)
932{
933  number t;
934
935  while (a!=NULL)
936  {
937    t=nMult(pGetCoeff(a), c);
938    //nNormalize(t);
939    pSetCoeff(a,t);
940    pIter(a);
941  }
942}
943
944/*2
945* return a copy of the poly a times the number c (a,c will not be destroyed)
946*/
947poly pMultCopyN(poly a, number c)
948{
949  poly result=NULL,hp;
950
951  if (a != NULL)
952  {
953    result=pNew();
954    pCopy2(result,a);
955    pNext(result)=NULL;
956    pGetCoeff(result)=nMult(pGetCoeff(a),c);
957    pIter(a);
958    hp=result;
959    while (a!=NULL)
960    {
961      hp=pNext(hp)=pNew();
962      pCopy2(hp,a);
963      pSetCoeff0(hp,nMult(pGetCoeff(a), c));
964      pIter(a);
965    }
966    pNext(hp)=NULL;
967  }
968  return result;
969}
970
971/*2
972* assumes that the head term of b is a multiple of the head term of a
973* and return the multiplicant *m
974*/
975poly pDivide(poly a, poly b)
976{
977  int i;
978  poly result=pInit();
979
980  for(i=(int)pVariables; i; i--)
981    pSetExp(result,i, pGetExp(a,i)- pGetExp(b,i));
982  pSetComp(result, pGetComp(a) - pGetComp(b));
983  pSetm(result);
984  return result;
985}
986
987/*2
988* divides a by the monomial b, ignores monomials wihich are not divisible
989* assumes that b is not NULL
990*/
991poly pDivideM(poly a, poly b)
992{
993  if (a==NULL) return NULL;
994  poly result=a;
995  poly prev=NULL;
996  int i;
997  number inv=nInvers(pGetCoeff(b));
998
999  while (a!=NULL)
1000  {
1001    if (pDivisibleBy(b,a))
1002    {
1003      for(i=(int)pVariables; i; i--)
1004         pSubExp(a,i, pGetExp(b,i));
1005      pSubComp(a, pGetComp(b));
1006      pSetm(a);
1007      prev=a;
1008      pIter(a);
1009    }
1010    else
1011    {
1012      if (prev==NULL)
1013      {
1014        pDelete1(&result);
1015        a=result;
1016      }
1017      else
1018      {
1019        pDelete1(&pNext(prev));
1020        a=pNext(prev);
1021      }
1022    }
1023  }
1024  pMultN(result,inv);
1025  nDelete(&inv);
1026  pDelete(&b);
1027  return result;
1028}
1029
1030/*2
1031* returns the LCM of the head terms of a and b in *m
1032*/
1033void pLcm(poly a, poly b, poly m)
1034{
1035  int i;
1036  for (i=pVariables; i; i--)
1037  {
1038    pSetExp(m,i, max( pGetExp(a,i), pGetExp(b,i)));
1039  }
1040  pSetComp(m, max(pGetComp(a), pGetComp(b)));
1041}
1042
1043/*2
1044* convert monomial given as string to poly, e.g. 1x3y5z
1045*/
1046poly pmInit(char *st, BOOLEAN &ok)
1047{
1048  int i,j;
1049  ok=FALSE;
1050  BOOLEAN b=FALSE;
1051  poly rc = pInit();
1052  char *s = nRead(st,&(rc->coef));
1053  if (s==st)
1054  /* i.e. it does not start with a coeff: test if it is a ringvar*/
1055  {
1056    j = rIsRingVar(s);
1057    if (j >= 0)
1058    {
1059      pIncrExp(rc,1+j);
1060      goto done;
1061    }
1062  }
1063  else
1064    b=TRUE;
1065  while (*s!='\0')
1066  {
1067    char ss[2];
1068    ss[0] = *s++;
1069    ss[1] = '\0';
1070    j = rIsRingVar(ss);
1071    if (j >= 0)
1072    {
1073      s = eati(s,&i);
1074      pAddExp(rc,1+j, (Exponent_t)i);
1075    }
1076    else
1077    {
1078      if ((s!=st)&&isdigit(st[0]))
1079      {
1080        errorreported=TRUE;
1081      }
1082      pDelete(&rc);
1083      return NULL;
1084    }
1085  }
1086done:
1087  ok=!errorreported;
1088  if (nIsZero(pGetCoeff(rc))) pDelete1(&rc);
1089  else
1090  {
1091    pSetm(rc);
1092  }
1093  return rc;
1094}
1095
1096/*2
1097*make p homgeneous by multiplying the monomials by powers of x_varnum
1098*/
1099poly pHomogen (poly p, int varnum)
1100{
1101  poly q=NULL;
1102  poly res;
1103  int  o,ii;
1104
1105  if (p!=NULL)
1106  {
1107    if ((varnum < 1) || (varnum > pVariables))
1108    {
1109      return NULL;
1110    }
1111    o=pWTotaldegree(p);
1112    q=pNext(p);
1113    while (q != NULL)
1114    {
1115      ii=pWTotaldegree(q);
1116      if (ii>o) o=ii;
1117      pIter(q);
1118    }
1119    q = pCopy(p);
1120    res = q;
1121    while (q != NULL)
1122    {
1123      ii = o-pWTotaldegree(q);
1124      if (ii!=0)
1125      {
1126        pAddExp(q,varnum, (Exponent_t)ii);
1127        pSetm(q);
1128      }
1129      pIter(q);
1130    }
1131    q = pOrdPolyInsertSetm(res);
1132  }
1133  return q;
1134}
1135
1136
1137/*2
1138*replaces the maximal powers of the leading monomial of p2 in p1 by
1139*the same powers of n, utility for dehomogenization
1140*/
1141poly pDehomogen (poly p1,poly p2,number n)
1142{
1143  polyset P;
1144  int     SizeOfSet=5;
1145  int     i;
1146  poly    p;
1147  number  nn;
1148
1149  P = (polyset)Alloc0(5*sizeof(poly));
1150  //for (i=0; i<5; i++)
1151  //{
1152  //  P[i] = NULL;
1153  //}
1154  pCancelPolyByMonom(p1,p2,&P,&SizeOfSet);
1155  p = P[0];
1156  //P[0] = NULL ;// for safety, may be remoeved later
1157  for (i=1; i<SizeOfSet; i++)
1158  {
1159    if (P[i] != NULL)
1160    {
1161      nPower(n,i,&nn);
1162      pMultN(P[i],nn);
1163      p = pAdd(p,P[i]);
1164      //P[i] =NULL; // for safety, may be removed later
1165      nDelete(&nn);
1166    }
1167  }
1168  Free((ADDRESS)P,SizeOfSet*sizeof(poly));
1169  return p;
1170}
1171
1172/*4
1173*Returns the exponent of the maximal power of the leading monomial of
1174*p2 in that of p1
1175*/
1176static int pGetMaxPower (poly p1,poly p2)
1177{
1178  int     i,k,res = 32000; /*a very large integer*/
1179
1180  if (p1 == NULL) return 0;
1181  for (i=1; i<=pVariables; i++)
1182  {
1183    if ( pGetExp(p2,i) != 0)
1184    {
1185      k =  pGetExp(p1,i) /  pGetExp(p2,i);
1186      if (k < res) res = k;
1187    }
1188  }
1189  return res;
1190}
1191
1192/*2
1193*Returns as i-th entry of P the coefficient of the (i-1) power of
1194*the leading monomial of p2 in p1
1195*/
1196void pCancelPolyByMonom (poly p1,poly p2,polyset * P,int * SizeOfSet)
1197{
1198  int   maxPow;
1199  poly  p,qp,Coeff;
1200
1201  if (*P == NULL)
1202  {
1203    *P = (polyset) Alloc(5*sizeof(poly));
1204    *SizeOfSet = 5;
1205  }
1206  p = pCopy(p1);
1207  while (p != NULL)
1208  {
1209    qp = p->next;
1210    p->next = NULL;
1211    maxPow = pGetMaxPower(p,p2);
1212    Coeff = pDivByMonom(p,p2);
1213    if (maxPow > *SizeOfSet)
1214    {
1215      pEnlargeSet(P,*SizeOfSet,maxPow+1-*SizeOfSet);
1216      *SizeOfSet = maxPow+1;
1217    }
1218    (*P)[maxPow] = pAdd((*P)[maxPow],Coeff);
1219    pDelete(&p);
1220    p = qp;
1221  }
1222}
1223
1224/*2
1225*returns the leading monomial of p1 divided by the maximal power of that
1226*of p2
1227*/
1228poly pDivByMonom (poly p1,poly p2)
1229{
1230  int     k, i;
1231
1232  if (p1 == NULL) return NULL;
1233  k = pGetMaxPower(p1,p2);
1234  if (k == 0)
1235    return pHead(p1);
1236  else
1237  {
1238    number n;
1239    poly p = pInit();
1240
1241    p->next = NULL;
1242    for (i=1; i<=pVariables; i++)
1243    {
1244       pSetExp(p,i, pGetExp(p1,i)-k* pGetExp(p2,i));
1245    }
1246    nPower(p2->coef,k,&n);
1247    pSetCoeff0(p,nDiv(p1->coef,n));
1248    nDelete(&n);
1249    pSetm(p);
1250    return p;
1251  }
1252}
1253/*----------utilities for syzygies--------------*/
1254poly pTakeOutComp(poly * p, int k)
1255{
1256  poly q = *p,qq=NULL,result = NULL;
1257
1258  if (q==NULL) return NULL;
1259  if (pGetComp(q)==k)
1260  {
1261    result = q;
1262    while ((q!=NULL) && (pGetComp(q)==k))
1263    {
1264      pSetComp(q,0);
1265      qq = q;
1266      pIter(q);
1267    }
1268    *p = q;
1269    pNext(qq) = NULL;
1270  }
1271  if (q==NULL) return result;
1272  if (pGetComp(q) > k) pDecrComp(q);
1273  poly pNext_q;
1274  while ((pNext_q=pNext(q))!=NULL)
1275  {
1276    if (pGetComp(pNext_q)==k)
1277    {
1278      if (result==NULL)
1279      {
1280        result = pNext_q;
1281        qq = result;
1282      }
1283      else
1284      {
1285        pNext(qq) = pNext_q;
1286        pIter(qq);
1287      }
1288      pNext(q) = pNext(pNext_q);
1289      pNext(qq) =NULL;
1290      pSetComp(qq,0);
1291    }
1292    else
1293    {
1294      /*pIter(q);*/ q=pNext_q;
1295      if (pGetComp(q) > k) pDecrComp(q);
1296    }
1297  }
1298  return result;
1299}
1300
1301// Splits *p into two polys: *q which consists of all monoms with
1302// component == comp and *p of all other monoms *lq == pLength(*q)
1303void pTakeOutComp(poly *r_p, Exponent_t comp, poly *r_q, int *lq)
1304{
1305  spolyrec pp, qq;
1306  poly p, q, p_prev;
1307  int l = 0;
1308
1309#ifdef HAVE_ASSUME
1310  int lp = pLength(*r_p);
1311#endif
1312
1313  pNext(&pp) = *r_p;
1314  p = *r_p;
1315  p_prev = &pp;
1316  q = &qq;
1317
1318  while(p != NULL)
1319  {
1320    while (pGetComp(p) == comp)
1321    {
1322      pNext(q) = p;
1323      pIter(q);
1324      pSetComp(p, 0);
1325      pIter(p);
1326      l++;
1327      if (p == NULL)
1328      {
1329        pNext(p_prev) = NULL;
1330        goto Finish;
1331      }
1332    }
1333    pNext(p_prev) = p;
1334    p_prev = p;
1335    pIter(p);
1336  }
1337
1338  Finish:
1339  pNext(q) = NULL;
1340  *r_p = pNext(&pp);
1341  *r_q = pNext(&qq);
1342  *lq = l;
1343#ifdef HAVE_ASSUME
1344  assume(pLength(*r_p) + pLength(*r_q) == lp);
1345#endif
1346  pTest(*r_p);
1347  pTest(*r_q);
1348}
1349
1350void pDecrOrdTakeOutComp(poly *r_p, Exponent_t comp, Order_t order,
1351                         poly *r_q, int *lq)
1352{
1353  spolyrec pp, qq;
1354  poly p, q, p_prev;
1355  int l = 0;
1356
1357  pNext(&pp) = *r_p;
1358  p = *r_p;
1359  p_prev = &pp;
1360  q = &qq;
1361
1362#ifdef HAVE_ASSUME
1363  if (p != NULL)
1364  {
1365    while (pNext(p) != NULL)
1366    {
1367      assume(pGetOrder(p) >= pGetOrder(pNext(p)));
1368      pIter(p);
1369    }
1370  }
1371  p = *r_p;
1372#endif
1373
1374  while (p != NULL && pGetOrder(p) > order) pIter(p);
1375
1376  while(p != NULL && pGetOrder(p) == order)
1377  {
1378    while (pGetComp(p) == comp)
1379    {
1380      pNext(q) = p;
1381      pIter(q);
1382      pIter(p);
1383      pSetComp(p, 0);
1384      l++;
1385      if (p == NULL || pGetOrder(p) != order)
1386      {
1387        pNext(p_prev) = p;
1388        goto Finish;
1389      }
1390    }
1391    pNext(p_prev) = p;
1392    p_prev = p;
1393    pIter(p);
1394  }
1395
1396  Finish:
1397  pNext(q) = NULL;
1398  *r_p = pNext(&pp);
1399  *r_q = pNext(&qq);
1400  *lq = l;
1401}
1402
1403#if 1
1404poly pTakeOutComp1(poly * p, int k)
1405{
1406  poly q = *p;
1407
1408  if (q==NULL) return NULL;
1409
1410  poly qq=NULL,result = NULL;
1411
1412  if (pGetComp(q)==k)
1413  {
1414    result = q; /* *p */
1415    while ((q!=NULL) && (pGetComp(q)==k))
1416    {
1417      pSetComp(q,0);
1418      qq = q;
1419      pIter(q);
1420    }
1421    *p = q;
1422    pNext(qq) = NULL;
1423  }
1424  if (q==NULL) return result;
1425//  if (pGetComp(q) > k) pGetComp(q)--;
1426  while (pNext(q)!=NULL)
1427  {
1428    if (pGetComp(pNext(q))==k)
1429    {
1430      if (result==NULL)
1431      {
1432        result = pNext(q);
1433        qq = result;
1434      }
1435      else
1436      {
1437        pNext(qq) = pNext(q);
1438        pIter(qq);
1439      }
1440      pNext(q) = pNext(pNext(q));
1441      pNext(qq) =NULL;
1442      pSetComp(qq,0);
1443    }
1444    else
1445    {
1446      pIter(q);
1447//      if (pGetComp(q) > k) pGetComp(q)--;
1448    }
1449  }
1450  return result;
1451}
1452#endif
1453
1454void pDeleteComp(poly * p,int k)
1455{
1456  poly q;
1457
1458  while ((*p!=NULL) && (pGetComp(*p)==k)) pDelete1(p);
1459  if (*p==NULL) return;
1460  q = *p;
1461  if (pGetComp(q)>k) pDecrComp(q);
1462  while (pNext(q)!=NULL)
1463  {
1464    if (pGetComp(pNext(q))==k)
1465      pDelete1(&(pNext(q)));
1466    else
1467    {
1468      pIter(q);
1469      if (pGetComp(q)>k) pDecrComp(q);
1470    }
1471  }
1472}
1473/*----------end of utilities for syzygies--------------*/
1474
1475/*2
1476* pair has no common factor ? or is no polynomial
1477*/
1478BOOLEAN pHasNotCF(poly p1, poly p2)
1479{
1480
1481  if (pGetComp(p1) > 0 || pGetComp(p2) > 0)
1482    return FALSE;
1483  int i = 1;
1484  loop
1485  {
1486    if ((pGetExp(p1, i) > 0) && (pGetExp(p2, i) > 0))   return FALSE;
1487    if (i == pVariables)                                return TRUE;
1488    i++;
1489  }
1490}
1491
1492
1493/*2
1494*should return 1 if p divides q and p<q,
1495*             -1 if q divides p and q<p
1496*              0 otherwise
1497*/
1498int     pDivComp(poly p, poly q)
1499{
1500  if (pGetComp(p) == pGetComp(q))
1501  {
1502    int i=pVariables;
1503    long d;
1504    BOOLEAN a=FALSE, b=FALSE;
1505    for (; i>0; i--)
1506    {
1507      d = pGetExpDiff(p, q, i);
1508      if (d)
1509      {
1510        if (d < 0)
1511        {
1512          if (b) return 0;
1513          a =TRUE;
1514        }
1515        else
1516        {
1517          if (a) return 0;
1518          b = TRUE;
1519        }
1520      }
1521    }
1522    if (a) return 1;
1523    else if (b)  return -1;
1524  }
1525  return 0;
1526}
1527/*2
1528*divides p1 by its leading monomial
1529*/
1530void pNorm(poly p1)
1531{
1532  poly h;
1533  number k, c;
1534
1535  if (p1!=NULL)
1536  {
1537    if (!nIsOne(pGetCoeff(p1)))
1538    {
1539      nNormalize(pGetCoeff(p1));
1540      k=pGetCoeff(p1);
1541      c = nInit(1);
1542      pSetCoeff0(p1,c);
1543      h = pNext(p1);
1544      while (h!=NULL)
1545      {
1546        c=nDiv(pGetCoeff(h),k);
1547        if (!nIsOne(c)) nNormalize(c);
1548        pSetCoeff(h,c);
1549        pIter(h);
1550      }
1551      nDelete(&k);
1552    }
1553    else
1554    {
1555      h = pNext(p1);
1556      while (h!=NULL)
1557      {
1558        nNormalize(pGetCoeff(h));
1559        pIter(h);
1560      }
1561    }
1562  }
1563}
1564
1565/*2
1566*normalize all coeffizients
1567*/
1568void pNormalize(poly p)
1569{
1570  while (p!=NULL)
1571  {
1572    nTest(pGetCoeff(p));
1573    nNormalize(pGetCoeff(p));
1574    pIter(p);
1575  }
1576}
1577
1578// splits p into polys with Exp(n) == 0 and Exp(n) != 0
1579// Poly with Exp(n) != 0 is reversed
1580static void pSplitAndReversePoly(poly p, int n, poly *non_zero, poly *zero)
1581{
1582  if (p == NULL)
1583  {
1584    *non_zero = NULL;
1585    *zero = NULL;
1586    return;
1587  }
1588  spolyrec sz;
1589  poly z, n_z, next;
1590  z = &sz;
1591  n_z = NULL;
1592
1593  while(p != NULL)
1594  {
1595    next = pNext(p);
1596    if (pGetExp(p, n) == 0)
1597    {
1598      pNext(z) = p;
1599      pIter(z);
1600    }
1601    else
1602    {
1603      pNext(p) = n_z;
1604      n_z = p;
1605    }
1606    p = next;
1607  }
1608  pNext(z) = NULL;
1609  *zero = pNext(&sz);
1610  *non_zero = n_z;
1611  return;
1612}
1613 
1614/*3
1615* substitute the n-th variable by 1 in p
1616* destroy p
1617*/
1618static poly pSubst1 (poly p,int n)
1619{
1620  poly qq,result = NULL;
1621  poly zero, non_zero;
1622
1623  // reverse, so that add is likely to be linear
1624  pSplitAndReversePoly(p, n, &non_zero, &zero);
1625
1626  while (non_zero != NULL)
1627  {
1628    assume(pGetExp(non_zero, n) != 0);
1629    qq = non_zero;
1630    pIter(non_zero);
1631    qq->next = NULL;
1632    pSetExp(qq,n,0);
1633    pSetm(qq);
1634    result = pAdd(result,qq);
1635  }
1636  p = pAdd(result, zero);
1637  pTest(p);
1638  return p;
1639}
1640
1641/*3
1642* substitute the n-th variable by number e in p
1643* destroy p
1644*/
1645static poly pSubst2 (poly p,int n, number e)
1646{
1647  assume( ! nIsZero(e) );
1648  poly qq,result = NULL;
1649  number nn, nm;
1650  poly zero, non_zero;
1651
1652  // reverse, so that add is likely to be linear
1653  pSplitAndReversePoly(p, n, &non_zero, &zero);
1654
1655  while (non_zero != NULL)
1656  {
1657    assume(pGetExp(non_zero, n) != 0);
1658    qq = non_zero;
1659    pIter(non_zero);
1660    qq->next = NULL;
1661    nPower(e, pGetExp(qq, n), &nn);
1662    nm = nMult(nn, pGetCoeff(qq));
1663    pSetCoeff(qq, nm);
1664    nDelete(&nn);
1665    pSetExp(qq, n, 0);
1666    pSetm(qq);
1667    result = pAdd(result,qq);
1668  }
1669  p = pAdd(result, zero);
1670  pTest(p);
1671  return p;
1672}
1673
1674
1675/* delete monoms whose n-th exponent is different from zero */
1676poly pSubst0(poly p, int n)
1677{
1678  spolyrec res;
1679  poly h = &res;
1680  pNext(h) = p;
1681
1682  while (pNext(h)!=NULL)
1683  {
1684    if (pGetExp(pNext(h),n)!=0)
1685    {
1686      pDelete1(&pNext(h));
1687    }
1688    else
1689    {
1690      pIter(h);
1691    }
1692  }
1693  pTest(pNext(&res));
1694  return pNext(&res);
1695}
1696
1697/*2
1698* substitute the n-th variable by e in p
1699* destroy p
1700*/
1701poly pSubst(poly p, int n, poly e)
1702{
1703  if (e == NULL) return pSubst0(p, n);
1704
1705  if (pIsConstant(e))
1706  {
1707    if (nIsOne(pGetCoeff(e))) return pSubst1(p,n);
1708    else return pSubst2(p, n, pGetCoeff(e));
1709  }
1710
1711  int exponent,i;
1712  poly h, res, m;
1713  Exponent_t *me,*ee;
1714  number nu,nu1;
1715
1716  me=(Exponent_t *)Alloc((pVariables+1)*sizeof(Exponent_t));
1717  ee=(Exponent_t *)Alloc((pVariables+1)*sizeof(Exponent_t));
1718  if (e!=NULL) pGetExpV(e,ee);
1719  res=NULL;
1720  h=p;
1721  while (h!=NULL)
1722  {
1723    if ((e!=NULL) || (pGetExp(h,n)==0))
1724    {
1725      m=pHead(h);
1726      pGetExpV(m,me);
1727      exponent=me[n];
1728      me[n]=0;
1729      for(i=pVariables;i>0;i--)
1730        me[i]+=exponent*ee[i];
1731      pSetExpV(m,me);
1732      if (e!=NULL)
1733      {
1734        nPower(pGetCoeff(e),exponent,&nu);
1735        nu1=nMult(pGetCoeff(m),nu);
1736        nDelete(&nu);
1737        pSetCoeff(m,nu1);
1738      }
1739      res=pAdd(res,m);
1740    }
1741    pDelete1(&h);
1742  }
1743  Free((ADDRESS)me,(pVariables+1)*sizeof(Exponent_t));
1744  Free((ADDRESS)ee,(pVariables+1)*sizeof(Exponent_t));
1745  return res;
1746}
1747
1748BOOLEAN pCompareChain (poly p,poly p1,poly p2,poly lcm)
1749{
1750  int k, j;
1751
1752  if (lcm==NULL) return FALSE;
1753
1754  for (j=pVariables; j; j--)
1755    if ( pGetExp(p,j) >  pGetExp(lcm,j)) return FALSE;
1756  if ( pGetComp(p) !=  pGetComp(lcm)) return FALSE;
1757  for (j=pVariables; j; j--)
1758  {
1759    if (pGetExp(p1,j)!=pGetExp(lcm,j))
1760    {
1761      if (pGetExp(p,j)!=pGetExp(lcm,j))
1762      {
1763        for (k=pVariables; k>j; k--)
1764        {
1765          if ((pGetExp(p,k)!=pGetExp(lcm,k))
1766          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
1767            return TRUE;
1768        }
1769        for (k=j-1; k; k--)
1770        {
1771          if ((pGetExp(p,k)!=pGetExp(lcm,k))
1772          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
1773            return TRUE;
1774        }
1775        return FALSE;
1776      }
1777    }
1778    else if (pGetExp(p2,j)!=pGetExp(lcm,j))
1779    {
1780      if (pGetExp(p,j)!=pGetExp(lcm,j))
1781      {
1782        for (k=pVariables; k>j; k--)
1783        {
1784          if ((pGetExp(p,k)!=pGetExp(lcm,k))
1785          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
1786            return TRUE;
1787        }
1788        for (k=j-1; k!=0 ; k--)
1789        {
1790          if ((pGetExp(p,k)!=pGetExp(lcm,k))
1791          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
1792            return TRUE;
1793        }
1794        return FALSE;
1795      }
1796    }
1797  }
1798  return FALSE;
1799}
1800
1801int pWeight(int i)
1802{
1803  if ((firstwv==NULL) || (i>firstBlockEnds))
1804  {
1805    return 1;
1806  }
1807  return firstwv[i-1];
1808}
1809
Note: See TracBrowser for help on using the repository browser.