source: git/Singular/polys.cc @ 2c694a2

spielwiese
Last change on this file since 2c694a2 was 416465, checked in by Olaf Bachmann <obachman@…>, 24 years ago
* bug-fixes from work with Thomas git-svn-id: file:///usr/local/Singular/svn/trunk@3826 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.52 1999-11-15 17:20:40 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
65/*contains the headterms for the Schreyer orderings*/
66static int* SchreyerOrd;
67static int maxSchreyer=0;
68static int indexShift=0;
69static pLDegProc pLDegOld;
70
71static int**   polys_wv;
72static short *   firstwv;
73static int * block0;
74static int * block1;
75static int firstBlockEnds;
76static int * order;
77
78/*0 implementation*/
79/*-------- the several possibilities for pSetm:-----------------------*/
80
81void rSetm(poly p)
82{
83  int pos=0;
84  if (currRing->typ!=NULL)
85  {
86    loop
87    {
88      sro_ord* o=&(currRing->typ[pos]);
89      switch(o->ord_typ)
90      {
91        case ro_dp:
92        {
93          int a,e;
94          a=o->data.dp.start;
95          e=o->data.dp.end;
96          long ord=0;
97          for(int i=a;i<=e;i++) ord+=pGetExp(p,i);
98          p->exp.l[o->data.dp.place]=ord;
99          break;
100        }
101        case ro_wp:
102        {
103          int a,e;
104          a=o->data.wp.start;
105          e=o->data.wp.end;
106          int *w=o->data.wp.weights;
107          long ord=0;
108          for(int i=a;i<=e;i++) ord+=pGetExp(p,i)*w[i-a];
109          p->exp.l[o->data.wp.place]=ord;
110          break;
111        }
112        case ro_cp:
113        {
114          int a,e;
115          a=o->data.cp.start;
116          e=o->data.cp.end;
117          int pl=o->data.cp.place;
118          for(int i=a;i<=e;i++) { p->exp.e[pl]=pGetExp(p,i); pl++; }
119          break;
120        }
121        case ro_syzcomp:
122        {
123          int c=pGetComp(p);
124          long sc = c;
125          if (o->data.syzcomp.ShiftedComponents != NULL)
126          {
127            assume(o->data.syzcomp.Components != NULL);
128            assume(c == 0 || o->data.syzcomp.Components[c] != 0);
129            sc =
130              o->data.syzcomp.ShiftedComponents[o->data.syzcomp.Components[c]];
131            assume(c == 0 || sc != 0);
132          }
133          p->exp.l[o->data.syzcomp.place]=sc;
134          break;
135        }
136        case ro_syz:
137        {
138          int c=pGetComp(p);
139          if (c > o->data.syz.limit)
140            p->exp.l[o->data.syz.place] = o->data.syz.curr_index;
141          else if (c > 0)
142            p->exp.l[o->data.syz.place]= o->data.syz.syz_index[c];
143          else
144          {
145            assume(c == 0);
146            p->exp.l[o->data.syz.place]= 0;
147          }
148          break;
149        }
150        default:
151          Print("wrong ord in rSetm:%d\n",o->ord_typ);
152          return;
153      }
154      pos++;
155      if(pos==currRing->OrdSize) return;
156    }
157  }
158}
159
160void rSetmS(poly p, int* Components, long* ShiftedComponents)
161{
162  int pos=0;
163  assume(Components != NULL && ShiftedComponents != NULL);
164  if (currRing->typ!=NULL)
165  {
166    loop
167    {
168      sro_ord* o=&(currRing->typ[pos]);
169      switch(o->ord_typ)
170      {
171        case ro_dp:
172        {
173          int a,e;
174          a=o->data.dp.start;
175          e=o->data.dp.end;
176          long ord=0;
177          for(int i=a;i<=e;i++) ord+=pGetExp(p,i);
178          p->exp.l[o->data.dp.place]=ord;
179          break;
180        }
181        case ro_wp:
182        {
183          int a,e;
184          a=o->data.wp.start;
185          e=o->data.wp.end;
186          int *w=o->data.wp.weights;
187          long ord=0;
188          for(int i=a;i<=e;i++) ord+=pGetExp(p,i)*w[i-a];
189          p->exp.l[o->data.wp.place]=ord;
190          break;
191        }
192        case ro_cp:
193        {
194          int a,e;
195          a=o->data.cp.start;
196          e=o->data.cp.end;
197          int pl=o->data.cp.place;
198          for(int i=a;i<=e;i++) { p->exp.e[pl]=pGetExp(p,i); pl++; }
199          break;
200        }
201        case ro_syzcomp:
202        {
203#if 1
204          int c=pGetComp(p);
205          long sc  = ShiftedComponents[Components[c]];
206          assume(c == 0 || Components[c] != 0);
207          assume(c == 0 || sc != 0);
208          p->exp.l[o->data.syzcomp.place]=sc;
209#endif
210          break;
211        }
212        default:
213          Print("wrong ord in rSetm:%d\n",o->ord_typ);
214          return;
215      }
216      pos++;
217      if(pos==currRing->OrdSize) return;
218    }
219  }
220}
221
222/*-------- IMPLEMENTATION OF MONOMIAL COMPARISONS ---------------------*/
223
224
225#define NonZeroR(l, actionG, actionS)           \
226do                                              \
227{                                               \
228  long _l = l;                                  \
229  if (_l)                                       \
230  {                                             \
231    if (_l > 0) actionG;                        \
232    actionS;                                    \
233  }                                             \
234}                                               \
235while(0)
236
237#define Mreturn(d, multiplier)                      \
238{                                                   \
239  if (d > 0) return multiplier;                     \
240  return -multiplier;                               \
241}
242
243
244/*---------------------------------------------------*/
245
246int pComp(poly p1, poly p2)
247{
248  if (p2==NULL)
249    return 1;
250  if (p1==NULL)
251    return -1;
252  return pComp0(p1,p2);
253}
254
255
256/*----------pComp handling for syzygies---------------------*/
257static void newHeadsB(polyset actHeads,int length)
258{
259  int i;
260  int* newOrder=(int*)Alloc(length*sizeof(int));
261
262  for (i=0;i<length;i++)
263  {
264    if (actHeads[i]!=NULL)
265    {
266      newOrder[i] = SchreyerOrd[pGetComp(actHeads[i])-1];
267    }
268    else
269    {
270      newOrder[i]=0;
271    }
272  }
273  Free((ADDRESS)SchreyerOrd,maxSchreyer*sizeof(int));
274  SchreyerOrd = newOrder;
275  maxSchreyer = length;
276/*
277*for (i=0;i<maxSchreyer;i++); Print("%d  ",SchreyerOrd[i]);
278*PrintLn();
279*/
280}
281
282int mcompSchrB(poly p1,poly p2)
283{
284  int CompP1=pGetComp(p1),CompP2=pGetComp(p2),result,
285      cP1=SchreyerOrd[CompP1-1],cP2=SchreyerOrd[CompP2-1];
286
287  if (CompP1==CompP2) return pCompOld(p1,p2);
288  pSetComp(p1,cP1);
289  pSetComp(p2,cP2);
290  result = pCompOld(p1,p2);
291  pSetComp(p1,CompP1);
292  pSetComp(p2,CompP2);
293  if (!result)
294  {
295    if (CompP1>CompP2)
296      return -1;
297    else if (CompP1<CompP2)
298      return 1;
299  }
300  return result;
301}
302
303
304static void newHeadsM(polyset actHeads,int length)
305{
306  int i;
307  int* newOrder=
308    (int*)Alloc0((length+maxSchreyer-indexShift)*sizeof(int));
309
310  //for (i=0;i<length+maxSchreyer-indexShift;i++)
311  //  newOrder[i]=0;
312  for (i=indexShift;i<maxSchreyer;i++)
313  {
314    newOrder[i-indexShift] = SchreyerOrd[i];
315    SchreyerOrd[i] = 0;
316  }
317  for (i=maxSchreyer-indexShift;i<length+maxSchreyer-indexShift;i++)
318    newOrder[i] = newOrder[pGetComp(actHeads[i-maxSchreyer+indexShift])-1];
319  Free((ADDRESS)SchreyerOrd,maxSchreyer*sizeof(int));
320  SchreyerOrd = newOrder;
321  indexShift = maxSchreyer-indexShift;
322  maxSchreyer = length+indexShift;
323}
324
325/*2
326* compute the length of a polynomial (in l)
327* and the degree of the monomial with maximal degree:
328* this is NOT the last one and the module component
329* has to be <= indexShift
330*/
331static int ldegSchrM(poly p,int *l)
332{
333  int  t,max;
334
335  (*l)=1;
336  max=pFDeg(p);
337  while ((pNext(p)!=NULL) && (pGetComp(pNext(p))<=indexShift))
338  {
339    pIter(p);
340    t=pFDeg(p);
341    if (t>max) max=t;
342    (*l)++;
343  }
344  return max;
345}
346
347int mcompSchrM(poly p1,poly p2)
348{
349  if ( pGetComp(p1)<=indexShift)
350  {
351    if ( pGetComp(p2)>indexShift) return 1;
352  }
353  else if ( pGetComp(p2)<=indexShift)  return -1;
354  return mcompSchrB(p1,p2);
355}
356
357void pSetSchreyerOrdM(polyset nextOrder, int length,int comps)
358{
359  int i;
360
361  if (length!=0)
362  {
363    if (maxSchreyer!=0)
364      newHeadsM(nextOrder, length);
365    else
366    {
367      indexShift = comps;
368      if (indexShift==0) indexShift = 1;
369      SchreyerOrd = (int*)Alloc((indexShift+length)*sizeof(int));
370      maxSchreyer = length+indexShift;
371      for (i=0;i<indexShift;i++)
372        SchreyerOrd[i] = i;
373      for (i=indexShift;i<maxSchreyer;i++)
374        SchreyerOrd[i] = pGetComp(nextOrder[i-indexShift]);
375      pCompOld = pComp0;
376      pComp0 = mcompSchrM;
377      pLDegOld = pLDeg;
378      pLDeg = ldegSchrM;
379    }
380  }
381  else
382  {
383    if (maxSchreyer!=0)
384    {
385      Free((ADDRESS)SchreyerOrd,maxSchreyer*sizeof(int));
386      maxSchreyer = 0;
387      indexShift = 0;
388      pComp0 = pCompOld;
389      pLDeg = pLDegOld;
390    }
391  }
392}
393
394/*2
395* the type of the module ordering: C: -1, c: 1
396*/
397int pModuleOrder()
398{
399  return pComponentOrder;
400}
401
402/* -------------------------------------------------------------------*/
403/* several possibilities for pFDeg: the degree of the head term       */
404/*2
405* compute the degree of the leading monomial of p
406* the ordering is compatible with degree, use a->order
407*/
408int pDeg(poly a)
409{
410  return pGetOrder(a);
411}
412
413/*2
414* compute the degree of the leading monomial of p
415* with respect to weigths 1
416* (all are 1 so save multiplications or they are of different signs)
417* the ordering is not compatible with degree so do not use p->Order
418*/
419int pTotaldegree(poly p)
420{
421  return pExpQuerSum(p);
422}
423
424/*2
425* compute the degree of the leading monomial of p
426* with respect to weigths from the ordering
427* the ordering is not compatible with degree so do not use p->Order
428*/
429int pWTotaldegree(poly p)
430{
431  assume(p != NULL);
432  int i, k;
433  int j =0;
434
435  // iterate through each block:
436  for (i=0;order[i]!=0;i++)
437  {
438    switch(order[i])
439    {
440      case ringorder_wp:
441      case ringorder_ws:
442      case ringorder_Wp:
443      case ringorder_Ws:
444        for (k=block0[i];k<=block1[i];k++)
445        { // in jedem block:
446          j+= pGetExp(p,k)*polys_wv[i][k-block0[i]];
447        }
448        break;
449      case ringorder_M:
450      case ringorder_lp:
451      case ringorder_dp:
452      case ringorder_ds:
453      case ringorder_Dp:
454      case ringorder_Ds:
455        for (k=block0[i];k<=block1[i];k++)
456        {
457          j+= pGetExp(p,k);
458        }
459        break;
460      case ringorder_c:
461      case ringorder_C:
462      case ringorder_S:
463      case ringorder_s:
464        break;
465      case ringorder_a:
466        for (k=block0[i];k<=block1[i];k++)
467        { // only one line
468          j+= pGetExp(p,k)*polys_wv[i][k-block0[i]];
469        }
470        return j;
471    }
472  }
473  return  j;
474}
475int pWDegree(poly p)
476{
477  int i, k;
478  int j =0;
479
480  for(i=1;i<=pVariables;i++)
481    j+=pGetExp(p,i)*pWeight(i);
482  return j;
483}
484
485/* ---------------------------------------------------------------------*/
486/* several possibilities for pLDeg: the maximal degree of a monomial in p*/
487/*  compute in l also the pLength of p                                   */
488
489/*2
490* compute the length of a polynomial (in l)
491* and the degree of the monomial with maximal degree: the last one
492*/
493static int ldeg0(poly p,int *l)
494{
495  Exponent_t k= pGetComp(p);
496  int ll=1;
497
498  while ((pNext(p)!=NULL) && (pGetComp(pNext(p))==k))
499  {
500    pIter(p);
501    ll++;
502  }
503  *l=ll;
504  return pGetOrder(p);
505}
506
507/*2
508* compute the length of a polynomial (in l)
509* and the degree of the monomial with maximal degree: the last one
510* but search in all components before syzcomp
511*/
512static int ldeg0c(poly p,int *l)
513{
514  int o=pFDeg(p);
515  int ll=1;
516
517  if (! rIsSyzIndexRing(currRing))
518  {
519    while ((p=pNext(p))!=NULL)
520    {
521      o=pFDeg(p);
522      ll++;
523    }
524  }
525  else
526  {
527    int curr_limit = rGetCurrSyzLimit();
528    while ((p=pNext(p))!=NULL)
529    {
530      if (pGetComp(p)<=curr_limit/*syzComp*/)
531      {
532        o=pFDeg(p);
533        ll++;
534      }
535      else break;
536    }
537  }
538  *l=ll;
539  return o;
540}
541
542/*2
543* compute the length of a polynomial (in l)
544* and the degree of the monomial with maximal degree: the first one
545* this works for the polynomial case with degree orderings
546* (both c,dp and dp,c)
547*/
548static int ldegb(poly p,int *l)
549{
550  Exponent_t k= pGetComp(p);
551  int o = pFDeg(p);
552  int ll=1;
553
554  while (((p=pNext(p))!=NULL) && (pGetComp(p)==k))
555  {
556    ll++;
557  }
558  *l=ll;
559  return o;
560}
561
562/*2
563* compute the length of a polynomial (in l)
564* and the degree of the monomial with maximal degree:
565* this is NOT the last one, we have to look for it
566*/
567static int ldeg1(poly p,int *l)
568{
569  Exponent_t k= pGetComp(p);
570  int ll=1;
571  int  t,max;
572
573  max=pFDeg(p);
574  while (((p=pNext(p))!=NULL) && (pGetComp(p)==k))
575  {
576    t=pFDeg(p);
577    if (t>max) max=t;
578    ll++;
579  }
580  *l=ll;
581  return max;
582}
583
584/*2
585* compute the length of a polynomial (in l)
586* and the degree of the monomial with maximal degree:
587* this is NOT the last one, we have to look for it
588* in all components
589*/
590static int ldeg1c(poly p,int *l)
591{
592  int ll=1;
593  int  t,max;
594
595  max=pFDeg(p);
596  while ((p=pNext(p))!=NULL)
597  {
598    if (! rIsSyzIndexRing(currRing) || 
599        (pGetComp(p)<=rGetCurrSyzLimit()))
600    {
601       if ((t=pFDeg(p))>max) max=t;
602       ll++;
603    }
604    else break;
605  }
606  *l=ll;
607  return max;
608}
609
610/* -------------------------------------------------------- */
611/* set the variables for a choosen ordering                 */
612
613
614/*2
615* sets the comparision routine for monomials: for all but the first
616* block of variables (ip is the block number, o_r the number of the ordering)
617*/
618static void HighSet(int ip, int o_r)
619{
620  switch(o_r)
621  {
622    case ringorder_lp:
623    case ringorder_dp:
624    case ringorder_Dp:
625    case ringorder_wp:
626    case ringorder_Wp:
627    case ringorder_a:
628      if (pOrdSgn==-1) pMixedOrder=TRUE;
629      break;
630    case ringorder_ls:
631    case ringorder_ds:
632    case ringorder_Ds:
633    case ringorder_ws:
634    case ringorder_Ws:
635    case ringorder_s:
636      break;
637    case ringorder_c:
638      pComponentOrder=1;
639      break;
640    case ringorder_C:
641    case ringorder_S:
642      pComponentOrder=-1;
643      break;
644    case ringorder_M:
645      pMixedOrder=TRUE;
646      break;
647#ifdef TEST
648    default:
649      Werror("wrong internal ordering:%d at %s, l:%d\n",o_r,__FILE__,__LINE__);
650#endif
651  }
652}
653
654/* -------------------------------------------------------- */
655/*2
656* change all variables to fit the description of the new ring
657*/
658
659//void pChangeRing(ring newRing)
660//{
661//  rComplete(newRing);
662//  pSetGlobals(newRing);
663//}
664
665void pSetGlobals(ring r, BOOLEAN complete)
666{
667  int i;
668  pComponentOrder=1;
669  if (ppNoether!=NULL) pDelete(&ppNoether);
670  pVariables = r->N;
671
672  // set the various size parameters and initialize memory
673  pMonomSize = POLYSIZE + r->ExpLSize * sizeof(long);
674  pMonomSizeW = pMonomSize/sizeof(void*);
675
676  // Initialize memory management
677  mm_specHeap = r->mm_specHeap;
678
679  pVarOffset = r->VarOffset;
680
681  pOrdSgn = r->OrdSgn;
682  pVectorOut=(r->order[0]==ringorder_c);
683  order=r->order;
684  block0=r->block0;
685  block1=r->block1;
686  firstwv=NULL;
687  polys_wv=r->wvhdl;
688  if (order[0]==ringorder_S ||order[0]==ringorder_s)
689  {
690    order++;
691    block0++;
692    block1++;
693    polys_wv++;
694  }
695  pFDeg=pTotaldegree;
696  /*------- only one real block ----------------------*/
697  pLexOrder=FALSE;
698  pMixedOrder=FALSE;
699  if (pOrdSgn == 1) pLDeg = ldegb;
700  else              pLDeg = ldeg0;
701  /*======== ordering type is (_,c) =========================*/
702  if ((order[0]==ringorder_unspec)
703      ||(
704    ((order[1]==ringorder_c)||(order[1]==ringorder_C)
705     ||(order[1]==ringorder_S)
706     ||(order[1]==ringorder_s))
707    && (order[0]!=ringorder_M)
708    && (order[2]==0))
709    )
710  {
711    if ((order[0]!=ringorder_unspec)
712    && ((order[1]==ringorder_C)||(order[1]==ringorder_S)||
713        (order[1]==ringorder_s)))
714      pComponentOrder=-1;
715    if (pOrdSgn == -1) pLDeg = ldeg0c;
716    if ((order[0] == ringorder_lp) || (order[0] == ringorder_ls))
717    {
718      pLexOrder=TRUE;
719      pLDeg = ldeg1c;
720    }
721    if (order[0] == ringorder_wp || order[0] == ringorder_Wp ||
722        order[0] == ringorder_ws || order[0] == ringorder_Ws)
723      pFDeg = pWTotaldegree;
724    firstBlockEnds=block1[0];
725  }
726  /*======== ordering type is (c,_) =========================*/
727  else if (((order[0]==ringorder_c)
728            ||(order[0]==ringorder_C)
729            ||(order[0]==ringorder_S)
730            ||(order[0]==ringorder_s))
731  && (order[1]!=ringorder_M)
732  &&  (order[2]==0))
733  {
734    /* pLDeg = ldeg0; is standard*/
735    if ((order[0]==ringorder_C)||(order[0]==ringorder_S)||
736        order[0]==ringorder_s)
737      pComponentOrder=-1;
738    if ((order[1] == ringorder_lp) || (order[1] == ringorder_ls))
739    {
740      pLexOrder=TRUE;
741      pLDeg = ldeg1c;
742    }
743    firstBlockEnds=block1[1];
744    if (order[1] == ringorder_wp || order[1] == ringorder_Wp ||
745        order[1] == ringorder_ws || order[1] == ringorder_Ws)
746      pFDeg = pWTotaldegree;
747  }
748  /*------- more than one block ----------------------*/
749  else
750  {
751    //pGetVarIndicies(pVariables, pVarOffset, pVarCompIndex, pVarLowIndex,
752    //                pVarHighIndex);
753    //pLexOrder=TRUE;
754    pVectorOut=order[0]==ringorder_c;
755    if ((pVectorOut)||(order[0]==ringorder_C)||(order[0]==ringorder_S)||(order[0]==ringorder_s))
756    {
757      if(block1[1]!=pVariables) pLexOrder=TRUE;
758      firstBlockEnds=block1[1];
759    }
760    else
761    {
762      if(block1[0]!=pVariables) pLexOrder=TRUE;
763      firstBlockEnds=block1[0];
764    }
765    /*the number of orderings:*/
766    i = 0;
767    while (order[++i] != 0);
768    do
769    {
770      i--;
771      HighSet(i, order[i]);/*sets also pMixedOrder to TRUE, if...*/
772    }
773    while (i != 0);
774
775    if ((order[0]!=ringorder_c)
776        && (order[0]!=ringorder_C)
777        && (order[0]!=ringorder_S)
778        && (order[0]!=ringorder_s))
779    {
780      pLDeg = ldeg1c;
781    }
782    else
783    {
784      pLDeg = ldeg1;
785    }
786    pFDeg = pWTotaldegree; // may be improved: pTotaldegree for lp/dp/ls/.. blocks
787  }
788  if (complete)
789  {
790    if ((pLexOrder) || (pOrdSgn==-1))
791    {
792      test &= ~Sy_bit(OPT_REDTAIL); /* noredTail */
793    }
794    pSetm=rSetm;
795    pComp0=rComp0;
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.