source: git/Singular/polys.cc @ 1a2ca6

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