source: git/Singular/polys.cc @ 82ac59

spielwiese
Last change on this file since 82ac59 was 82ac59, checked in by Olaf Bachmann <obachman@…>, 26 years ago
* small bug fix git-svn-id: file:///usr/local/Singular/svn/trunk@1301 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 50.3 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: polys.cc,v 1.20 1998-03-31 12:18:45 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 "ipid.h"
23#include "polys-comp.h"
24
25/* ----------- global variables, set by pChangeRing --------------------- */
26/* initializes the internal data from the exp vector */
27pSetmProc pSetm;
28/* computes length and maximal degree of a POLYnomial */
29pLDegProc pLDeg;
30/* computes the degree of the initial term, used for std */
31pFDegProc pFDeg;
32/* the monomial ordering of the head monomials a and b */
33/* returns -1 if a comes before b, 0 if a=b, 1 otherwise */
34pCompProc pComp0;
35
36int pVariables;     // number of variables
37int pVariablesW;    // number of words of pVariables exponents
38int pVariables1W;   // number of words of (pVariables+1) exponents
39int pMonomSize;     // size of monom (in bytes)
40int pMonomSizeW;    // size of monom (in words)
41int pLexSgn;        // 1, for lex monom comps; -1 otherwise (exception: ls)
42int pVarOffset;     // controls the way exponents are stored in a vector
43int pVarLowIndex;   // lowest exponent index
44int pVarHighIndex;  // highest exponent index
45int pVarCompIndex;  // Location of component in exponent vector
46
47/* 1 for polynomial ring, -1 otherwise */
48int     pOrdSgn;
49/* TRUE for momomial output as x2y, FALSE for x^2*y */
50int pShortOut = (int)TRUE;
51// it is of type int, not BOOLEAN because it is also in ip
52/* TRUE if the monomial ordering is not compatible with pFDeg */
53BOOLEAN pLexOrder;
54/* TRUE if the monomial ordering has polynomial and power series blocks */
55BOOLEAN pMixedOrder;
56/* 1 for c ordering, -1 otherwise (i.e. for C ordering) */
57int  pComponentOrder;
58
59#ifdef DRING
60int      p2;
61BOOLEAN  pDRING=FALSE;
62#endif
63
64#ifdef SRING
65int      pAltVars;
66BOOLEAN  pSRING=FALSE;
67#endif
68
69#ifdef SDRING
70BOOLEAN  pSDRING=FALSE;
71#include "polys.inc"
72#endif
73
74/* ----------- global variables, set by procedures from hecke/kstd1 ----- */
75/* the highest monomial below pHEdge */
76poly      ppNoether = NULL;
77
78/* -------------- static variables --------------------------------------- */
79/*is the basic comparing procedure during a computation of syzygies*/
80static pCompProc pCompOld;
81/*for grouping module indicies during computations*/
82int pMaxBound = 0;
83
84/*contains the headterms for the Schreyer orderings*/
85static int* SchreyerOrd;
86static int maxSchreyer=0;
87static int indexShift=0;
88static pLDegProc pLDegOld;
89
90typedef int (*bcompProc)(poly p1, poly p2, int i1, int i2, short * w);
91static bcompProc bcomph[20];
92static short**   polys_wv;
93static short *   firstwv;
94static int * block0;
95static int * block1;
96static int firstBlockEnds;
97static int * order;
98
99/*0 implementation*/
100/*-------- the several possibilities for pSetm:-----------------------*/
101
102/* Remark: These could be made more efficient by avoiding using pGetExp */
103
104/*2
105* define the order of p with respect to lex. ordering, N=1
106*/
107static void setlex1(poly p)
108{
109  p->Order = (Order_t)pGetExp(p,1);
110}
111
112/*2
113* define the order of p with respect to lex. ordering, N>1
114*/
115static void setlex2(poly p)
116{
117  p->Order = (((Order_t)pGetExp(p,1))<<(sizeof(Exponent_t)*8))
118    + (Order_t)pGetExp(p,2); 
119}
120
121/*2
122* define the order of p with respect to a degree ordering
123*/
124static void setdeg1(poly p)
125{
126  p->Order = pExpQuerSum1(p, firstBlockEnds);
127}
128
129/*2
130* define the order of p with respect to a degree ordering
131* with weigthts
132*/
133static void setdeg1w(poly p)
134{
135  Order_t i, j = 0;
136
137  for (i = firstBlockEnds; i>0; i--)
138  {
139     j += ((Order_t) pGetExp(p,i))*firstwv[i-1];
140  }
141  p->Order = j;
142}
143
144
145/*-------- IMPLEMENTATION OF MONOMIAL COMPARISONS ---------------------*/
146
147
148#define NonZeroR(l, actionG, actionS)           \
149do                                              \
150{                                               \
151  long _l = l;                                  \
152  if (_l)                                       \
153  {                                             \
154    if (_l > 0) actionG;                        \
155    actionS;                                    \
156  }                                             \
157}                                               \
158while(0)
159 
160#define Mreturn(d, multiplier)                      \
161{                                                   \
162  if (d > 0) return multiplier;                     \
163  return -multiplier;                               \
164}                                               
165
166static int pComp_otEXP_nwONE(poly p1, poly p2);
167static int pComp_otCOMPEXP_nwONE(poly p1, poly p2);
168static int pComp_otEXPCOMP_nwONE(poly p1, poly p2);
169static int pComp_otEXP_nwTWO(poly p1, poly p2);
170static int pComp_otCOMPEXP_nwTWO(poly p1, poly p2);
171static int pComp_otEXPCOMP_nwTWO(poly p1, poly p2);
172static int pComp_otEXP_nwEVEN(poly p1, poly p2);
173static int pComp_otCOMPEXP_nwEVEN(poly p1, poly p2);
174static int pComp_otEXPCOMP_nwEVEN(poly p1, poly p2);
175static int pComp_otEXP_nwODD(poly p1, poly p2);
176static int pComp_otCOMPEXP_nwODD(poly p1, poly p2);
177static int pComp_otEXPCOMP_nwODD(poly p1, poly p2);
178
179 
180// comp_nwONE is used if pVariables1W == 1 and component is compatible
181// with ordering
182static int pComp_otEXP_nwONE(poly p1, poly p2) 
183{
184  register long d = pGetOrder(p1) - pGetOrder(p2);
185
186  if (d) Mreturn(d, pOrdSgn);
187  _pMonComp_otEXP_nwONE(p1, p2, d, goto NotEqual, return 0);
188
189  NotEqual:
190  Mreturn(d, pLexSgn);
191}
192
193// comp_otEXPCOMP_nwONE :  pVariables1W == 1, priority is
194// given to exponents, component is incompatible with ordering
195static int pComp_otEXPCOMP_nwONE(poly p1, poly p2) 
196{
197  register long d = pGetOrder(p1) - pGetOrder(p2);
198
199  if (d) Mreturn(d, pOrdSgn);
200  _pMonComp_otEXPCOMP_nwONE(p1, p2, d, goto NotEqual , return 0);
201
202  NotEqual:
203  Mreturn(d, pLexSgn)
204}
205
206// comp_otEXPCOMP_nwONE :  pVariables1W == 1, priority is given to component,
207// component is incompatible with ordering
208static int pComp_otCOMPEXP_nwONE(poly p1, poly p2) 
209{
210  register long d = pGetComp(p2) - pGetComp(p1);
211  if (d) Mreturn(d, pComponentOrder);
212  d = pGetOrder(p1) - pGetOrder(p2);
213  if (d) Mreturn(d, pOrdSgn);
214  _pMonComp_otEXP_nwONE(p1, p2, d, goto NotEqual , return 0);
215 
216  NotEqual:
217  Mreturn(d, pLexSgn);
218}
219
220// comp_nwTWO :  pVariables1W == 2 and component is compatible with ordering
221static int pComp_otEXP_nwTWO(poly p1, poly p2) 
222{
223  register long d = pGetOrder(p1) - pGetOrder(p2);
224
225  if (d) Mreturn(d, pOrdSgn);
226  _pMonComp_otEXP_nwTWO(p1, p2, d, goto NotEqual , return 0);
227
228  NotEqual:
229  Mreturn(d, pLexSgn);
230}
231
232// comp_otEXPCOMP_nwTWO :  pVariables1W == 2, priority is given to exponents,
233// component is incompatible with ordering
234static int pComp_otEXPCOMP_nwTWO(poly p1, poly p2) 
235{
236  register long d = pGetOrder(p1) - pGetOrder(p2);
237
238  if (d) Mreturn(d, pOrdSgn);
239  _pMonComp_otEXPCOMP_nwTWO(p1, p2, d, goto NotEqual, return 0);
240 
241  NotEqual:
242  Mreturn(d, pLexSgn);
243}
244
245// comp_otEXPCOMP_nwTWO :  pVariables1W == 2, priority is given to component,
246// component is incompatible with ordering
247static int pComp_otCOMPEXP_nwTWO(poly p1, poly p2) 
248{
249  register long d = pGetComp(p2) - pGetComp(p1);
250  if (d) Mreturn(d, pComponentOrder);
251  d = pGetOrder(p1) - pGetOrder(p2);
252  if (d) Mreturn(d, pOrdSgn);
253  _pMonComp_otEXP_nwTWO(p1, p2, d, goto NotEqual , return 0);
254 
255  NotEqual:
256  Mreturn(d, pLexSgn);
257}
258
259// comp_nwEVEN :  pVariables1W == 2*i and component is compatible
260// with ordering
261static int pComp_otEXP_nwEVEN(poly p1, poly p2) 
262{
263  register long d = pGetOrder(p1) - pGetOrder(p2);
264
265  if (d) Mreturn(d, pOrdSgn);
266  _pMonComp_otEXP_nwEVEN(p1, p2, pVariables1W, d, goto NotEqual , return 0);
267
268  NotEqual:
269  Mreturn(d, pLexSgn);
270}
271
272// comp_otEXPCOMP_nwEVEN : pVariables1W == 2*i, priority is given to exponents,
273// component is incompatible with ordering
274static int pComp_otEXPCOMP_nwEVEN(poly p1, poly p2) 
275{
276  register long d = pGetOrder(p1) - pGetOrder(p2);
277
278  if (d) Mreturn(d, pOrdSgn);
279  _pMonComp_otEXPCOMP_nwEVEN(p1, p2, pVariables1W, d, goto NotEqual , return 0);
280
281  NotEqual:
282  Mreturn(d, pLexSgn);
283}
284
285// comp_otEXPCOMP_nwEVEN : pVariables1W == 2*i, priority is given to component,
286// component is incompatible with ordering
287static int pComp_otCOMPEXP_nwEVEN(poly p1, poly p2) 
288{
289  register long d = pGetComp(p2) - pGetComp(p1);
290  if (d) Mreturn(d, pComponentOrder);
291  d = pGetOrder(p1) - pGetOrder(p2);
292  if (d) Mreturn(d, pOrdSgn);
293  _pMonComp_otEXP_nwEVEN(p1, p2, pVariablesW, d, goto NotEqual, return 0);
294 
295  NotEqual:
296  Mreturn(d, pLexSgn);
297}
298
299// comp_nwODD : pVariables1W == 2*i and component is compatible
300// with ordering
301static int pComp_otEXP_nwODD(poly p1, poly p2) 
302{
303  register long d = pGetOrder(p1) - pGetOrder(p2);
304
305  if (d) Mreturn(d, pOrdSgn);
306  _pMonComp_otEXP_nwODD(p1, p2, pVariables1W, d, goto NotEqual, return 0);
307
308  NotEqual:
309  Mreturn(d, pLexSgn);
310}
311
312// comp_otEXPCOMP_nwODD : pVariables1W == 2*i, priority is given to exponents,
313// component is incompatible with ordering
314static int pComp_otEXPCOMP_nwODD(poly p1, poly p2) 
315{
316  register long d = pGetOrder(p1) - pGetOrder(p2);
317  if (d) 
318  {
319    if (d > 0) return pOrdSgn;
320    return -pOrdSgn;
321  }
322 
323  _pMonComp_otEXPCOMP_nwODD(p1, p2, pVariables1W, d, goto NotEqual , return 0);
324 
325  NotEqual:
326  Mreturn(d, pLexSgn);
327}
328
329// comp_otCOMPEXP_nwODD : pVariables1W == 2*i, priority is given to component,
330// component is incompatible with ordering
331static int pComp_otCOMPEXP_nwODD(poly p1, poly p2) 
332{
333  register long d = pGetComp(p2) - pGetComp(p1);
334  if (d) Mreturn(d, pComponentOrder);
335  d = pGetOrder(p1) - pGetOrder(p2);
336  if (d) Mreturn(d, pOrdSgn);
337  _pMonComp_otEXP_nwODD(p1, p2, pVariablesW, d, goto NotEqual, return 0);
338 
339  NotEqual:
340  Mreturn(d, pLexSgn);
341}
342/*2
343* compare the head monomial of p1 and p2 with weight vector
344*/
345static int comp1a  ( poly p1, poly p2, int f, int l, short * w )
346{
347  int d= pGetOrder(p1) - pGetOrder(p2);
348  if ( d > 0 /*p1->Order > p2->Order*/ )
349    return 1;
350  else if ( d < 0 /*p1->Order < p2->Order*/ )
351    return -1;
352  return 0;
353}
354
355
356/*---------------------------------------------------*/
357
358/* These functions could be made faster if you use pointers to the
359* exponent vectors and pointer arithmetic instead of using the
360* macro pGetExp !!!
361*/
362
363/*2
364* compare the head monomial of p1 and p2 with lexicographic ordering
365*/
366static int comp_lp ( poly p1, poly p2, int f, int l, short * w )
367{
368  int i = f;
369  while ( ( i <= l ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
370    i++;
371  if ( i > l )
372    return 0;
373  if ( pGetExp(p1,i) > pGetExp(p2,i) )
374    return 1;
375  return -1;
376}
377
378/*2
379* compare the head monomial of p1 and p2 with degree reverse lexicographic
380* ordering
381*/
382static int comp_dp ( poly p1, poly p2, int f, int l, short * w )
383{
384  int i, s1 = 0, s2 = 0;
385
386  for ( i = f; i <= l; i++ )
387  {
388    s1 += pGetExp(p1,i);
389    s2 += pGetExp(p2,i);
390  }
391  if ( s1 == s2 )
392  {
393    i = l;
394    while ( (i >= f ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
395      i--;
396    if ( i < f )
397      return 0;
398    if ( pGetExp(p1,i) > pGetExp(p2,i) )
399      return -1;
400    return 1;
401  }
402  if ( s1 > s2 )
403    return 1;
404  return -1;
405}
406
407/*2
408* compare the head monomial of p1 and p2 with degree lexicographic ordering
409*/
410static int comp_Dp ( poly p1, poly p2, int f, int l, short * w )
411{
412  int i, s1 = 0, s2 = 0;
413
414  for ( i = f; i <= l; i++ )
415  {
416    s1 += pGetExp(p1,i);
417    s2 += pGetExp(p2,i);
418  }
419  if ( s1 == s2 )
420  {
421    i = f;
422    while ( ( i <= l ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
423      i++;
424    if ( i > l )
425      return 0;
426    if ( pGetExp(p1,i) > pGetExp(p2,i) )
427      return 1;
428    return -1;
429  }
430  if ( s1 > s2 )
431    return 1;
432  return -1;
433}
434
435/*2
436* compare the head monomial of p1 and p2 with weighted degree reverse
437* lexicographic ordering
438*/
439static int comp_wp ( poly p1, poly p2, int f, int l, short * w )
440{
441  int i, s1 = 0, s2 = 0;
442
443  for ( i = f; i <= l; i++, w++ )
444  {
445    s1 += (int)pGetExp(p1,i)*(*w);
446    s2 += (int)pGetExp(p2,i)*(*w);
447  }
448  if ( s1 == s2 )
449  {
450    i = l;
451    while ( ( i >= f ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
452      i--;
453    if ( i < f )
454      return 0;
455    if ( pGetExp(p1,i) > pGetExp(p2,i) )
456      return -1;
457    return 1;
458  }
459  if ( s1 > s2 )
460    return 1;
461  return -1;
462}
463
464/*2
465* compare the head monomial of p1 and p2 with weighted degree lexicographic
466* ordering
467*/
468static int comp_Wp ( poly p1, poly p2, int f, int l, short * w )
469{
470  int i, s1 = 0, s2 = 0;
471
472  for ( i = f; i <= l; i++, w++ )
473  {
474    s1 += (int)pGetExp(p1,i)*(*w);
475    s2 += (int)pGetExp(p2,i)*(*w);
476  }
477  if ( s1 == s2 )
478  {
479    i = f;
480    while ( ( i <= l ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
481      i++;
482    if ( i > l )
483      return 0;
484    if ( pGetExp(p1,i) > pGetExp(p2,i) )
485      return 1;
486    return -1;
487  }
488  if ( s1 > s2 )
489    return 1;
490  return -1;
491}
492
493/*2
494* compare the head monomial of p1 and p2 with lexicographic ordering
495* (power series case)
496*/
497static int comp_ls ( poly p1, poly p2, int f, int l, short * w )
498{
499  int i;
500
501  i = f;
502  while ( ( i <= l ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
503    i++;
504  if ( i > l )
505    return 0;
506  if ( pGetExp(p1,i) < pGetExp(p2,i) )
507    return 1;
508  return -1;
509}
510
511/*2
512* compare the head monomial of p1 and p2 with degree reverse lexicographic
513* ordering (power series case)
514*/
515static int comp_ds ( poly p1, poly p2, int f, int l, short * w )
516{
517  int i, s1 = 0, s2 = 0;
518
519  for ( i = f; i <= l; i++ )
520  {
521    s1 += pGetExp(p1,i);
522    s2 += pGetExp(p2,i);
523  }
524  if ( s1 == s2 )
525  {
526    i = l;
527    while ( ( i >= f ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
528      i--;
529    if ( i < f )
530      return 0;
531    if ( pGetExp(p1,i) < pGetExp(p2,i) )
532      return 1;
533    return -1;
534  }
535  if ( s1 < s2 )
536    return 1;
537  return -1;
538}
539
540/*2
541* compare the head monomial of p1 and p2 with degree lexicographic ordering
542* (power series case)
543*/
544static int comp_Ds ( poly p1, poly p2, int f, int l, short * w )
545{
546  int i, s1 = 0, s2 = 0;
547
548  for ( i = f; i <= l; i++ )
549  {
550    s1 += pGetExp(p1,i);
551    s2 += pGetExp(p2,i);
552  }
553  if ( s1 == s2 )
554  {
555    i = f;
556    while ( ( i <= l ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
557      i++;
558    if ( i > l )
559      return 0;
560    if ( pGetExp(p1,i) < pGetExp(p2,i) )
561      return -1;
562    return 1;
563  }
564  if ( s1 < s2 )
565    return 1;
566  return -1;
567}
568
569/*2
570* compare the head monomial of p1 and p2 with weighted degree reverse
571* lexicographic ordering (power series case)
572*/
573static int comp_ws ( poly p1, poly p2, int f, int l, short * w )
574{
575  int i, s1 = 0, s2 = 0;
576
577  for ( i = f; i <= l; i++, w++ )
578  {
579    s1 += (int)pGetExp(p1,i)*(*w);
580    s2 += (int)pGetExp(p2,i)*(*w);
581  }
582  if ( s1 == s2 )
583  {
584    i = l;
585    while ( ( i >= f ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
586      i--;
587    if ( i < f )
588      return 0;
589    if ( pGetExp(p1,i) < pGetExp(p2,i) )
590      return 1;
591    return -1;
592  }
593  if ( s1 < s2 )
594    return 1;
595  return -1;
596}
597
598/*2
599* compare the head monomial of p1 and p2 with weighted degree lexicographic
600* ordering (power series case)
601*/
602static int comp_Ws ( poly p1, poly p2, int f, int l, short * w )
603{
604  int i, s1 = 0, s2 = 0;
605
606  for ( i = f; i <= l; i++, w++ )
607  {
608    s1 += (int)pGetExp(p1,i)*(*w);
609    s2 += (int)pGetExp(p2,i)*(*w);
610  }
611  if ( s1 == s2 )
612  {
613    i = f;
614    while ( ( i <= l ) && ( pGetExp(p1,i) == pGetExp(p2,i) ) )
615      i++;
616    if ( i > l )
617      return 0;
618    if ( pGetExp(p1,i) < pGetExp(p2,i) )
619      return -1;
620    return 1;
621  }
622  if ( s1 < s2 )
623    return 1;
624  return -1;
625}
626
627/*2
628* compare the head monomial of p1 and p2 with matrix order
629* w contains a series of l-f+1 lines
630*/
631static int comp_M ( poly p1, poly p2, int f, int l, short * w )
632{
633  int i, j, s1, s2;
634
635  for ( i = f; i <= l; i++ )
636  {
637    s1 = s2 = 0;
638    for ( j = f; j <= l; j++, w++ )
639    {
640      s1 += (int)pGetExp(p1,j)*(int)(*w);
641      s2 += (int)pGetExp(p2,j)*(int)(*w);
642    }
643    if ( s1 < s2 )
644      return -1;
645    if ( s1 > s2 )
646      return 1;
647    /* now w points to the last element of the current row, the next w++ */
648    /* moves on to the first element of the next row ! */
649  }
650  return 0;
651}
652
653/*2
654* compare the head monomial of p1 and p2 with weight vector
655*/
656static int comp_a  ( poly p1, poly p2, int f, int l, short * w )
657{
658  int i, s1 = 0, s2 = 0;
659
660  for ( i = f; i <= l; i++, w++ )
661  {
662    s1 += (int)pGetExp(p1,i)*(*w);
663    s2 += (int)pGetExp(p2,i)*(*w);
664  }
665  if ( s1 > s2 )
666    return 1;
667  if ( s1 < s2 )
668    return -1;
669  return 0;
670}
671
672/*2
673* compare the head monomial of p1 and p2 with module component
674*/
675static int comp_c  ( poly p1, poly p2, int f, int l, short * w )
676{
677  if ( pGetComp(p1) > pGetComp(p2) )
678    return -pComponentOrder;
679  if ( pGetComp(p1) < pGetComp(p2) )
680    return pComponentOrder;
681  return 0;
682}
683
684/*---------------------------------------------------------------*/
685
686/*2
687* compare p1 and p2 by a block ordering
688* uses (*bcomph[])() to do the real work
689*/
690static int BlockComp(poly p1, poly p2)
691{
692  int res, i, e, a;
693
694  /*4 compare in all blocks,*
695  * each block has var numbers a(=block0[i]) to e (=block1[i])*
696  * the block number starts with 0*/
697  e = 0;
698  i = 0;
699  loop
700  {
701    a = block0[i];
702    e = block1[i];
703    res = (*bcomph[i])(p1, p2, a, e , polys_wv[i]);
704    if (res)
705      return res;
706    i++;
707    if (order[i]==0)
708      break;
709  }
710  return 0;
711}
712
713int pComp(poly p1, poly p2)
714{
715  if (p2==NULL)
716    return 1;
717  if (p1==NULL)
718    return -1;
719  return pComp0(p1,p2);
720}
721
722/*----------pComp handling for syzygies---------------------*/
723static void newHeadsB(polyset actHeads,int length)
724{
725  int i;
726  int* newOrder=(int*)Alloc(length*sizeof(int));
727
728  for (i=0;i<length;i++)
729  {
730    if (actHeads[i])
731    {
732      newOrder[i] = SchreyerOrd[pGetComp(actHeads[i])-1];
733    }
734    else
735    {
736      newOrder[i]=0;
737    }
738  }
739  Free((ADDRESS)SchreyerOrd,maxSchreyer*sizeof(int));
740  SchreyerOrd = newOrder;
741  maxSchreyer = length;
742/*
743*for (i=0;i<maxSchreyer;i++); Print("%d  ",SchreyerOrd[i]);
744*PrintLn();
745*/
746}
747
748int mcompSchrB(poly p1,poly p2)
749{
750  int CompP1=pGetComp(p1),CompP2=pGetComp(p2),result,
751      cP1=SchreyerOrd[CompP1-1],cP2=SchreyerOrd[CompP2-1];
752
753  if (CompP1==CompP2) return pCompOld(p1,p2);
754  pSetComp(p1,cP1);
755  pSetComp(p2,cP2);
756  result = pCompOld(p1,p2);
757  pSetComp(p1,CompP1);
758  pSetComp(p2,CompP2);
759  if (!result)
760  {
761    if (CompP1>CompP2)
762      return -1;
763    else if (CompP1<CompP2)
764      return 1;
765  }
766  return result;
767}
768
769
770static void newHeadsM(polyset actHeads,int length)
771{
772  int i;
773  int* newOrder=
774    (int*)Alloc((length+maxSchreyer-indexShift)*sizeof(int));
775
776  for (i=0;i<length+maxSchreyer-indexShift;i++)
777    newOrder[i]=0;
778  for (i=indexShift;i<maxSchreyer;i++)
779  {
780    newOrder[i-indexShift] = SchreyerOrd[i];
781    SchreyerOrd[i] = 0;
782  }
783  for (i=maxSchreyer-indexShift;i<length+maxSchreyer-indexShift;i++)
784    newOrder[i] = newOrder[pGetComp(actHeads[i-maxSchreyer+indexShift])-1];
785  Free((ADDRESS)SchreyerOrd,maxSchreyer*sizeof(int));
786  SchreyerOrd = newOrder;
787  indexShift = maxSchreyer-indexShift;
788  maxSchreyer = length+indexShift;
789}
790
791/*2
792* compute the length of a polynomial (in l)
793* and the degree of the monomial with maximal degree:
794* this is NOT the last one and the module component
795* has to be <= indexShift
796*/
797static int ldegSchrM(poly p,int *l)
798{
799  int  t,max;
800
801  (*l)=1;
802  max=pFDeg(p);
803  while ((pNext(p)!=NULL) && (pGetComp(pNext(p))<=indexShift))
804  {
805    pIter(p);
806    t=pFDeg(p);
807    if (t>max) max=t;
808    (*l)++;
809  }
810  return max;
811}
812
813int mcompSchrM(poly p1,poly p2)
814{
815  if ( pGetComp(p1)<=indexShift)
816  {
817    if ( pGetComp(p2)>indexShift) return 1;
818  }
819  else if ( pGetComp(p2)<=indexShift)  return -1;
820  return mcompSchrB(p1,p2);
821}
822
823void pSetSchreyerOrdM(polyset nextOrder, int length,int comps)
824{
825  int i;
826
827  if (length!=0)
828  {
829    if (maxSchreyer!=0)
830      newHeadsM(nextOrder, length);
831    else
832    {
833      indexShift = comps;
834      if (!indexShift) indexShift = 1;
835      SchreyerOrd = (int*)Alloc((indexShift+length)*sizeof(int));
836      maxSchreyer = length+indexShift;
837      for (i=0;i<indexShift;i++)
838        SchreyerOrd[i] = i;
839      for (i=indexShift;i<maxSchreyer;i++)
840        SchreyerOrd[i] = pGetComp(nextOrder[i-indexShift]);
841      pCompOld = pComp0;
842      pComp0 = mcompSchrM;
843      pLDegOld = pLDeg;
844      pLDeg = ldegSchrM;
845    }
846  }
847  else
848  {
849    if (maxSchreyer!=0)
850    {
851      Free((ADDRESS)SchreyerOrd,maxSchreyer*sizeof(int));
852      maxSchreyer = 0;
853      indexShift = 0;
854      pComp0 = pCompOld;
855      pLDeg = pLDegOld;
856    }
857  }
858}
859
860/*2
861*the pComp0 for normal syzygies
862*compares monomials in the usual ring order (pCompOld)
863*but groups module indecees according indexBounds befor
864*/
865static int mcompSyz(poly p1,poly p2)
866{
867  if (pGetComp(p1)<=pMaxBound)
868  {
869    if (pGetComp(p2)>pMaxBound) return 1;
870  }
871  else if (pGetComp(p2)<=pMaxBound)
872  {
873    return -1;
874  }
875  return pCompOld(p1,p2);
876}
877
878void pSetSyzComp(int k)
879{
880  if (k!=0)
881  {
882    if (pMaxBound==0)
883    {
884      pCompOld = pComp0;
885      pComp0 = mcompSyz;
886    }
887    pMaxBound = k;
888  }
889  else
890  {
891    if (pMaxBound!=0)
892    {
893      pComp0 = pCompOld;
894      pMaxBound = 0;
895    }
896  }
897}
898
899/*2
900* the type of the module ordering: C: -1, c: 1
901*/
902int pModuleOrder()
903{
904  return pComponentOrder;
905}
906
907/* -------------------------------------------------------------------*/
908/* several possibilities for pFDeg: the degree of the head term       */
909/*2
910* compute the degree of the leading monomial of p
911* the ordering is compatible with degree, use a->order
912*/
913int pDeg(poly a)
914{
915  return ((a!=NULL) ? (a->Order) : (-1));
916}
917
918/*2
919* compute the degree of the leading monomial of p
920* with respect to weigths 1
921* (all are 1 so save multiplications or they are of different signs)
922* the ordering is not compatible with degree so do not use p->Order
923*/
924int pTotaldegree(poly p)
925{
926  return pExpQuerSum(p); 
927}
928
929/*2
930* compute the degree of the leading monomial of p
931* with respect to weigths from the ordering
932* the ordering is not compatible with degree so do not use p->Order
933*/
934int pWTotaldegree(poly p)
935{
936  int i, k;
937  int j =0;
938
939  // iterate through each block:
940  for (i=0;order[i]!=0;i++)
941  {
942    switch(order[i])
943    {
944      case ringorder_wp:
945      case ringorder_ws:
946      case ringorder_Wp:
947      case ringorder_Ws:
948        for (k=block0[i];k<=block1[i];k++)
949        { // in jedem block:
950          j+= pGetExp(p,k)*polys_wv[i][k-block0[i]];
951        }
952        break;
953      case ringorder_M:
954      case ringorder_lp:
955      case ringorder_dp:
956      case ringorder_ds:
957      case ringorder_Dp:
958      case ringorder_Ds:
959        for (k=block0[i];k<=block1[i];k++)
960        {
961          j+= pGetExp(p,k);
962        }
963        break;
964      case ringorder_c:
965      case ringorder_C:
966        break;
967      case ringorder_a:
968        for (k=block0[i];k<=block1[i];k++)
969        { // only one line
970          j+= pGetExp(p,k)*polys_wv[i][k-block0[i]];
971        }
972        return j;
973    }
974  }
975  return  j;
976}
977/* ---------------------------------------------------------------------*/
978/* several possibilities for pLDeg: the maximal degree of a monomial in p*/
979/*  compute in l also the pLength of p                                   */
980
981/*2
982* compute the length of a polynomial (in l)
983* and the degree of the monomial with maximal degree: the last one
984*/
985static int ldeg0(poly p,int *l)
986{
987  Exponent_t k= pGetComp(p);
988  int ll=1;
989
990  while ((pNext(p)!=NULL) && (pGetComp(pNext(p))==k))
991  {
992    pIter(p);
993    ll++;
994  }
995  *l=ll;
996  return (p->Order);
997}
998
999/*2
1000* compute the length of a polynomial (in l)
1001* and the degree of the monomial with maximal degree: the last one
1002* but search in all components before syzcomp
1003*/
1004static int ldeg0c(poly p,int *l)
1005{
1006  int o=pFDeg(p);
1007  int ll=1;
1008
1009  if (pMaxBound/*syzComp*/==0)
1010  {
1011    while ((p=pNext(p))!=NULL)
1012    {
1013      o=pFDeg(p);
1014      ll++;
1015    }
1016  }
1017  else
1018  {
1019    while ((p=pNext(p))!=NULL)
1020    {
1021      if (pGetComp(p)<=pMaxBound/*syzComp*/)
1022      {
1023        o=pFDeg(p);
1024        ll++;
1025      }
1026      else break;
1027    }
1028  }
1029  *l=ll;
1030  return o;
1031}
1032
1033/*2
1034* compute the length of a polynomial (in l)
1035* and the degree of the monomial with maximal degree: the first one
1036* this works for the polynomial case with degree orderings
1037* (both c,dp and dp,c)
1038*/
1039static int ldegb(poly p,int *l)
1040{
1041  Exponent_t k= pGetComp(p);
1042  int o = p->Order;
1043  int ll=1;
1044
1045  while (((p=pNext(p))!=NULL) && (pGetComp(p)==k))
1046  {
1047    ll++;
1048  }
1049  *l=ll;
1050  return o;
1051}
1052
1053/*2
1054* compute the length of a polynomial (in l)
1055* and the degree of the monomial with maximal degree:
1056* this is NOT the last one, we have to look for it
1057*/
1058static int ldeg1(poly p,int *l)
1059{
1060  Exponent_t k= pGetComp(p);
1061  int ll=1;
1062  int  t,max;
1063
1064  max=pFDeg(p);
1065  while (((p=pNext(p))!=NULL) && (pGetComp(p)==k))
1066  {
1067    t=pFDeg(p);
1068    if (t>max) max=t;
1069    ll++;
1070  }
1071  *l=ll;
1072  return max;
1073}
1074
1075/*2
1076* compute the length of a polynomial (in l)
1077* and the degree of the monomial with maximal degree:
1078* this is NOT the last one, we have to look for it
1079* in all components
1080*/
1081static int ldeg1c(poly p,int *l)
1082{
1083  int ll=1;
1084  int  t,max;
1085
1086  max=pFDeg(p);
1087  while ((p=pNext(p))!=NULL)
1088  {
1089    if ((pMaxBound/*syzComp*/==0) || (pGetComp(p)<=pMaxBound/*syzComp*/))
1090    {
1091       if ((t=pFDeg(p))>max) max=t;
1092       ll++;
1093    }
1094    else break;
1095  }
1096  *l=ll;
1097  return max;
1098}
1099
1100/* -------------------------------------------------------- */
1101/* set the variables for a choosen ordering                 */
1102
1103
1104/*
1105* sets the comparision routine for monomials: for simple monomial orderings
1106* Priority is given to exponent vector
1107*/
1108static void SimpleChoose(int o_r, int comp_order, pCompProc *p)
1109{
1110  switch(o_r)
1111  {
1112      case ringorder_dp:
1113      case ringorder_wp:
1114      case ringorder_ds:
1115      case ringorder_ws:
1116      case ringorder_ls:
1117      case ringorder_unspec:
1118        pSetVarIndicies_RevLex(pVariables);
1119        pLexSgn = -1;
1120        if (comp_order == ringorder_C || o_r == ringorder_unspec)
1121        {
1122          if (pVariables1W == 1)        *p = pComp_otEXPCOMP_nwONE;
1123          else if (pVariables1W == 2)   *p = pComp_otEXPCOMP_nwTWO;
1124          else if (pVariables1W & 1)    *p = pComp_otEXPCOMP_nwODD;
1125          else                          *p = pComp_otEXPCOMP_nwEVEN;
1126        }
1127        else
1128        {
1129          // component is compatible with exponent vector
1130          if (pVariables1W == 1)        *p = pComp_otEXP_nwONE;
1131          else if (pVariables1W == 2)   *p = pComp_otEXP_nwTWO;
1132          else if (pVariables1W & 1)    *p = pComp_otEXP_nwODD;
1133          else                          *p = pComp_otEXP_nwEVEN;
1134        }
1135        break;
1136       
1137#ifdef PDEBUG
1138      case ringorder_lp:
1139      case ringorder_Dp:
1140      case ringorder_Wp:
1141      case ringorder_Ds:
1142      case ringorder_Ws:
1143#else
1144      default:
1145#endif
1146        pSetVarIndicies_Lex(pVariables);
1147        pLexSgn = 1;
1148        if (comp_order == ringorder_c)
1149        {
1150          if (pVariables1W == 1)        *p = pComp_otEXPCOMP_nwONE;
1151          else if (pVariables1W == 2)   *p = pComp_otEXPCOMP_nwTWO;
1152          else if (pVariables1W & 1)    *p = pComp_otEXPCOMP_nwODD;
1153          else                          *p = pComp_otEXPCOMP_nwEVEN;
1154        }
1155        else
1156        {
1157          // component is compatible with exponent vector
1158          if (pVariables1W == 1)        *p = pComp_otEXP_nwONE;
1159          else if (pVariables1W == 2)   *p = pComp_otEXP_nwTWO;
1160          else if (pVariables1W & 1)    *p = pComp_otEXP_nwODD;
1161          else                          *p = pComp_otEXP_nwEVEN;
1162        }
1163#ifdef PDEBUG
1164        break;
1165      default:
1166        Werror("wrong internal ordering:%d at %s, l:%d\n",o_r,__FILE__,__LINE__);
1167#endif
1168  }
1169 
1170  if (o_r == ringorder_lp || o_r == ringorder_ls)
1171  {
1172    pLexOrder=TRUE;
1173    pFDeg = pTotaldegree;
1174    pLDeg = ldeg1c;
1175    if (o_r == ringorder_ls)
1176      pSetVarIndicies_Lex(pVariables);
1177  }
1178}
1179
1180/*
1181* sets the comparision routine for monomials: for simple monomial orderings
1182* Priority is given to component
1183*/
1184static void SimpleChooseC(int o_r, pCompProc *p)
1185{
1186  switch(o_r)
1187  {
1188      case ringorder_dp:
1189      case ringorder_wp:
1190      case ringorder_ds:
1191      case ringorder_ls:
1192      case ringorder_ws:
1193        pSetVarIndicies_RevLex(pVariables);
1194        pLexSgn = -1;
1195        if (pVariablesW == 1)
1196          *p = pComp_otCOMPEXP_nwONE;
1197        else if (pVariablesW == 2)
1198          *p = pComp_otCOMPEXP_nwTWO;
1199        else if (pVariablesW & 1)
1200          *p = pComp_otCOMPEXP_nwODD;
1201        else
1202          *p = pComp_otCOMPEXP_nwEVEN;
1203        break;
1204       
1205#ifdef PDEBUG
1206      case ringorder_lp:
1207      case ringorder_Dp:
1208      case ringorder_Wp:
1209      case ringorder_Ds:
1210      case ringorder_Ws:
1211#else
1212      default:
1213#endif
1214        pSetVarIndicies_Lex(pVariables);
1215        pLexSgn = 1;
1216        if (pVariablesW == 1)
1217          *p = pComp_otCOMPEXP_nwONE;
1218        else if (pVariablesW == 2)
1219          *p = pComp_otCOMPEXP_nwTWO;
1220        else if (pVariablesW & 1)
1221          *p = pComp_otCOMPEXP_nwODD;
1222        else
1223          *p = pComp_otCOMPEXP_nwEVEN;
1224#ifdef PDEBUG
1225        break;
1226      default:
1227        Werror("wrong internal ordering:%d at %s, l:%d\n",o_r,__FILE__,__LINE__);
1228#endif
1229  }
1230  if (o_r == ringorder_lp || o_r == ringorder_ls)
1231  {
1232    pLexOrder=TRUE;
1233    pFDeg = pTotaldegree;
1234    pLDeg = ldeg1c;
1235    if (o_r == ringorder_ls)
1236     pSetVarIndicies_Lex(pVariables);
1237  }
1238}
1239
1240/*2
1241* sets pSetm
1242* (according o_r = order of first block)
1243*/
1244static void SetpSetm(int o_r, int ip)
1245{
1246  switch(o_r)
1247  {
1248    case ringorder_lp:
1249    case ringorder_ls:
1250      if (pVariables>1)
1251        pSetm= setlex2;
1252      else
1253        pSetm= setlex1;
1254      break;
1255    case ringorder_dp:
1256    case ringorder_Dp:
1257    case ringorder_ds:
1258    case ringorder_Ds:
1259    case ringorder_unspec:
1260      pSetm= setdeg1;
1261      break;
1262    case ringorder_a:
1263    case ringorder_wp:
1264    case ringorder_Wp:
1265    case ringorder_ws:
1266    case ringorder_Ws:
1267    case ringorder_M:
1268      pSetm= setdeg1w;
1269      firstwv=polys_wv[ip];
1270      break;
1271    case ringorder_c:
1272    case ringorder_C:
1273      return;
1274      /*do not set firstBlockEnds for this orderings*/
1275#ifdef TEST
1276    default:
1277      Werror("wrong internal ordering:%d at %s, l:%d\n",o_r,__FILE__,__LINE__);
1278#endif
1279  }
1280  firstBlockEnds=block1[ip];
1281}
1282
1283
1284/*2
1285* sets the comparision routine for monomials: for all but the first
1286* block of variables (ip is the block number, o_r the number of the ordering)
1287*/
1288static void HighSet(int ip, int o_r)
1289{
1290  switch(o_r)
1291  {
1292    case ringorder_lp:
1293      bcomph[ip]=comp_lp;
1294      if (pOrdSgn==-1) pMixedOrder=TRUE;
1295      break;
1296    case ringorder_dp:
1297      bcomph[ip]=comp_dp;
1298      if (pOrdSgn==-1) pMixedOrder=TRUE;
1299      break;
1300    case ringorder_Dp:
1301      bcomph[ip]=comp_Dp;
1302      if (pOrdSgn==-1) pMixedOrder=TRUE;
1303      break;
1304    case ringorder_wp:
1305      bcomph[ip]=comp_wp;
1306      if (pOrdSgn==-1) pMixedOrder=TRUE;
1307      break;
1308    case ringorder_Wp:
1309      bcomph[ip]=comp_Wp;
1310      if (pOrdSgn==-1) pMixedOrder=TRUE;
1311      break;
1312    case ringorder_ls:
1313      bcomph[ip]=comp_ls;
1314      break;
1315    case ringorder_ds:
1316      bcomph[ip]=comp_ds;
1317      break;
1318    case ringorder_Ds:
1319      bcomph[ip]=comp_Ds;
1320      break;
1321    case ringorder_ws:
1322      bcomph[ip]=comp_ws;
1323      break;
1324    case ringorder_Ws:
1325      bcomph[ip]=comp_Ws;
1326      break;
1327    case ringorder_c:
1328      pComponentOrder=1;
1329      bcomph[ip]=comp_c;
1330      break;
1331    case ringorder_C:
1332      pComponentOrder=-1;
1333      bcomph[ip]=comp_c;
1334      break;
1335    case ringorder_M:
1336      bcomph[ip]=comp_M;
1337      pMixedOrder=TRUE;
1338      break;
1339    case ringorder_a:
1340      if (pOrdSgn==-1) pMixedOrder=TRUE;
1341      if (ip==0)
1342        bcomph[0]=comp1a;
1343      else
1344        bcomph[ip]=comp_a;
1345      break;
1346#ifdef TEST
1347    default:
1348      Werror("wrong internal ordering:%d at %s, l:%d\n",o_r,__FILE__,__LINE__);
1349#endif
1350  }
1351}
1352
1353/* -------------------------------------------------------- */
1354/*2
1355* change all variables to fit the description of the new ring
1356*/
1357
1358void pChangeRing(int n, int Sgn, int * orders, int * b0, int * b1,
1359         short ** wv)
1360{
1361  sip_sring tmpR;
1362  memset(&tmpR, 0, sizeof(sip_sring));
1363  tmpR.N = n;
1364  tmpR.OrdSgn = Sgn;
1365  tmpR.order = orders;
1366  tmpR.block0 = b0;
1367  tmpR.block1 = b1;
1368  tmpR.wvhdl = wv;
1369  pSetGlobals(&tmpR);
1370}
1371
1372void pSetGlobals(ring r, BOOLEAN complete)
1373{
1374  int i;
1375  pComponentOrder=1;
1376  if (ppNoether!=NULL) pDelete(&ppNoether);
1377#ifdef SRING
1378  pSRING=FALSE;
1379  pAltVars=r->N+1;
1380#endif
1381  pVariables = r->N;
1382
1383  // set the various size parameters and initialize memory
1384  if ((((pVariables+1)*sizeof(Exponent_t)) % sizeof(void*)) == 0)
1385    pVariables1W = (pVariables+1)*sizeof(Exponent_t) / sizeof(void*);
1386  else
1387    pVariables1W = ((pVariables+1)*sizeof(Exponent_t) / sizeof(void*)) + 1;
1388
1389  if ((((pVariables)*sizeof(Exponent_t)) % sizeof(void*)) == 0)
1390    pVariablesW = (pVariables)*sizeof(Exponent_t) / sizeof(void*);
1391  else
1392    pVariablesW = ((pVariables)*sizeof(Exponent_t) / sizeof(void*)) + 1;
1393
1394  pMonomSize = POLYSIZE + (pVariables + 1) * sizeof(Exponent_t);
1395  if ((pMonomSize % sizeof(void*)) == 0)
1396  {
1397    pMonomSizeW = pMonomSize/sizeof(void*);
1398  }
1399  else
1400  {
1401    pMonomSizeW = pMonomSize/sizeof(void*) + 1;
1402    pMonomSize = pMonomSizeW*sizeof(void*);
1403  }
1404 
1405  // Set default Var Indicies
1406  pSetVarIndicies(pVariables);
1407
1408  // Initialize memory management
1409  mmSpecializeBlock(pMonomSize);
1410 
1411  pOrdSgn = r->OrdSgn;
1412  pVectorOut=(r->order[0]==ringorder_c);
1413  order=r->order;
1414  block0=r->block0;
1415  block1=r->block1;
1416  firstwv=NULL;
1417  polys_wv=r->wvhdl;
1418  /*------- only one real block ----------------------*/
1419  pLexOrder=FALSE;
1420  pMixedOrder=FALSE;
1421  pFDeg=pDeg;
1422  if (pOrdSgn == 1) pLDeg = ldegb;
1423  else              pLDeg = ldeg0;
1424  /*======== ordering type is (_,c) =========================*/
1425  if ((order[0]==ringorder_unspec)
1426  ||(
1427    ((order[1]==ringorder_c)||(order[1]==ringorder_C))
1428    && (order[0]!=ringorder_M)
1429    && (order[2]==0))
1430  )
1431  {
1432    if ((order[0]!=ringorder_unspec)
1433    && (order[1]==ringorder_C))
1434      pComponentOrder=-1;
1435    if (pOrdSgn == -1) pLDeg = ldeg0c;
1436    SimpleChoose(order[0],order[1], &pComp0);
1437    SetpSetm(order[0],0);
1438  }
1439  /*======== ordering type is (c,_) =========================*/
1440  else if (((order[0]==ringorder_c)||(order[0]==ringorder_C))
1441  && (order[1]!=ringorder_M)
1442  &&  (order[2]==0))
1443  {
1444    /* pLDeg = ldeg0; is standard*/
1445    if (order[0]==ringorder_C)
1446      pComponentOrder=-1;
1447    SimpleChooseC(order[1], &pComp0);
1448    SetpSetm(order[1],1);
1449  }
1450  /*------- more than one block ----------------------*/
1451  else
1452  {
1453    //pLexOrder=TRUE;
1454    pVectorOut=order[0]==ringorder_c;
1455    if ((pVectorOut)||(order[0]==ringorder_C))
1456    {
1457      if(block1[1]!=pVariables) pLexOrder=TRUE;
1458    } 
1459    else
1460    {
1461      if(block1[0]!=pVariables) pLexOrder=TRUE;
1462    }
1463    /*the number of orderings:*/
1464    i = 0;
1465    while (order[++i] != 0);
1466    do
1467    {
1468      i--;
1469      HighSet(i, order[i]);/*sets also pMixedOrder to TRUE, if...*/
1470      SetpSetm(order[i],i);
1471    }
1472    while (i != 0);
1473
1474    pComp0 = BlockComp;
1475    if ((order[0]!=ringorder_c)&&(order[0]!=ringorder_C))
1476    {
1477      pLDeg = ldeg1c;
1478    }
1479    else
1480    {
1481      pLDeg = ldeg1; 
1482    }
1483    pFDeg = pWTotaldegree; // may be improved: pTotaldegree for lp/dp/ls/.. blocks
1484  }
1485  if ((pLexOrder) || (pOrdSgn==-1))
1486  {
1487    test &= ~Sy_bit(OPT_REDTAIL); /* noredTail */
1488  }
1489}
1490
1491/* -------------------------------------------------------- */
1492
1493static BOOLEAN pMultT_nok;
1494/*2
1495* update the polynomial a by multipying it by
1496* the (number) coefficient
1497* and the exponent vector (of) exp (a well initialized polynomial)
1498*/
1499poly pMultT(poly a, poly exp )
1500{
1501  int i;
1502  number t,x,y=pGetCoeff(exp);
1503  poly aa=a;
1504  poly prev=NULL;
1505#ifdef SDRING
1506  poly pDRINGres=NULL;
1507#endif
1508
1509  pMultT_nok = pGetComp(exp);
1510#ifdef PDEBUG
1511  pTest(a);
1512  pTest(exp);
1513#endif
1514  while (a !=NULL)
1515  {
1516    x=pGetCoeff(a);
1517    t=nMult(x/*pGetCoeff(a)*/,y/*pGetCoeff(exp)*/);
1518    nDelete(&x/*pGetCoeff(a)*/);
1519    pSetCoeff0(a,t);
1520    if (nIsZero(t))
1521    {
1522      if (prev==NULL) { pDelete1(&a); aa=a; }
1523      else            { pDelete1(&prev->next); a=prev->next;}
1524    }
1525    else
1526    {
1527#ifdef DRING
1528      if (pDRING)
1529      {
1530         if (pdDFlag(a)==1)
1531         {
1532           if (pdDFlag(exp)==1)
1533           {
1534             pDRINGres=pAdd(pDRINGres,pMultDD(a,exp));
1535           }
1536           else
1537           {
1538             pDRINGres=pAdd(pDRINGres,pMultDT(a,exp));
1539           }
1540         }
1541         else
1542         {
1543           if (pdDFlag(exp)==1)
1544           {
1545             pDRINGres=pAdd(pDRINGres,pMultDD(a,exp));
1546           }
1547           else
1548           {
1549             pDRINGres=pAdd(pDRINGres,pMultTT(a,exp));
1550           }
1551         }
1552      }
1553      else
1554#endif
1555#ifdef SRING
1556      if (pSRING)
1557      {
1558        pDRINGres=pAdd(pDRINGres,psMultM(a,exp));
1559      }
1560      else
1561#endif
1562      {
1563        for (i=pVariables; i != 0; i--)
1564        {
1565           pAddExp(a,i, pGetExp(exp,i));
1566        }
1567        #ifdef TEST_MAC_ORDER
1568        if (bNoAdd)
1569          pSetm(a);
1570        else
1571        #endif
1572          a->Order += exp->Order;
1573        if (pMultT_nok)
1574        {
1575          if (pGetComp(a) == 0)
1576          {
1577             pSetComp(a, pGetComp(exp));
1578          }
1579          else
1580          {
1581            return NULL /*FALSE*/;
1582          }
1583        }
1584      }
1585      prev=a;
1586      pIter(a);
1587    }
1588  }
1589  pMultT_nok=0;
1590#ifdef DRING
1591   if (pDRING)
1592   {
1593     pDelete(&aa);
1594     return pDRINGres;
1595   }
1596#endif
1597#ifdef SRING
1598   if (pSRING)
1599   {
1600     pDelete(&aa);
1601     return pDRINGres;
1602   }
1603#endif
1604   return aa; /*TRUE*/
1605}
1606
1607/*2
1608* multiply p1 with p2, p1 and p2 are destroyed
1609* do not put attention on speed: the procedure is only used in the interpreter
1610*/
1611poly pMult(poly p1, poly p2)
1612{
1613  poly res, r, rn, a;
1614  BOOLEAN cont;
1615
1616  if ((p1!=NULL) && (p2!=NULL))
1617  {
1618#ifdef PDEBUG
1619    pTest(p1);
1620    pTest(p2);
1621#endif
1622    cont = TRUE;
1623    a = p1;
1624    if (pNext(p2)!=NULL)
1625      a = pCopy(a);
1626    else
1627      cont = FALSE;
1628    res = pMultT(a, p2);
1629    if (pMultT_nok)
1630    {
1631      if (cont) pDelete(&p1);
1632      pDelete(&res);
1633      pDelete(&p2);
1634      return NULL;
1635    }
1636    pDelete1(&p2);
1637    r = res;
1638    if (r!=NULL) rn = pNext(r);
1639    else         rn=NULL;
1640    while (cont)
1641    {
1642      if (pNext(p2)==NULL)
1643      {
1644        a = p1;
1645        cont = FALSE;
1646      }
1647      else
1648      {
1649        a = pCopy(p1);
1650      }
1651      a=pMultT(a, p2); //sets pMultT_nok
1652      if (pMultT_nok)
1653      {
1654        if (cont) pDelete(&p1);
1655        pDelete(&a);
1656        pDelete(&res);
1657        pDelete(&p2);
1658        return NULL;
1659      }
1660      while ((rn!=NULL) && (pComp0(rn,a)>0))
1661      {
1662        r = rn;
1663        pIter(rn);
1664      }
1665      if (r!=NULL) pNext(r) = rn = pAdd(a, rn);
1666      else         res=r=a;
1667      pDelete1(&p2);
1668    }
1669    return res;
1670  }
1671  pDelete(&p1);
1672  pDelete(&p2);
1673  return NULL;
1674}
1675
1676/*2
1677* update a by multiplying it with c (c will not be destroyed)
1678*/
1679void pMultN(poly a, number c)
1680{
1681  number t;
1682
1683  while (a!=NULL)
1684  {
1685    t=nMult(pGetCoeff(a), c);
1686    //nNormalize(t);
1687    pSetCoeff(a,t);
1688    pIter(a);
1689  }
1690}
1691
1692/*2
1693* return a copy of the poly a times the number c (a,c will not be destroyed)
1694*/
1695poly pMultCopyN(poly a, number c)
1696{
1697  poly result=NULL,hp;
1698
1699  if (a != NULL)
1700  {
1701    result=pNew();
1702    pCopy2(result,a);
1703    pNext(result)=NULL;
1704    pGetCoeff(result)=nMult(pGetCoeff(a),c);
1705    pIter(a);
1706    hp=result;
1707    while (a)
1708    {
1709      hp=pNext(hp)=pNew();
1710      pCopy2(hp,a);
1711      pSetCoeff0(hp,nMult(pGetCoeff(a), c));
1712      pIter(a);
1713    }
1714    pNext(hp)=NULL;
1715  }
1716  return result;
1717}
1718
1719/*2
1720* returns TRUE if the head term of b is a multiple of the head term of a
1721*/
1722#if defined(macintosh)
1723BOOLEAN pDivisibleBy(poly a, poly b)
1724{
1725  if ((a!=NULL)&&(( pGetComp(a)==0) || ( pGetComp(a) ==  pGetComp(b))))
1726  {
1727    int i=pVariables;
1728    Exponent_t *e1=&( pGetExp(a,1));
1729    Exponent_t *e2=&( pGetExp(b,1));
1730    if ((*e1) > (*e2)) return FALSE;
1731    do
1732    {
1733      i--;
1734      if (i == 0) return TRUE;
1735      e1++;
1736      e2++;
1737     } while ((*e1) <= (*e2));
1738   }
1739   return FALSE;
1740}
1741#endif
1742
1743
1744/*2
1745* assumes that the head term of b is a multiple of the head term of a
1746* and return the multiplicant *m
1747*/
1748poly pDivide(poly a, poly b)
1749{
1750  int i;
1751  poly result=pInit();
1752
1753  for(i=(int)pVariables; i; i--)
1754    pSetExp(result,i, pGetExp(a,i)- pGetExp(b,i));
1755  pSetComp(result, pGetComp(a) - pGetComp(b));
1756  pSetm(result);
1757  return result;
1758}
1759
1760/*2
1761* divides a by the monomial b, ignores monomials wihich are not divisible
1762* assumes that b is not NULL
1763*/
1764poly pDivideM(poly a, poly b)
1765{
1766  if (a==NULL) return NULL;
1767  poly result=a;
1768  poly prev=NULL;
1769  int i;
1770  number inv=nInvers(pGetCoeff(b));
1771
1772  while (a!=NULL)
1773  {
1774    if (pDivisibleBy(b,a))
1775    {
1776      for(i=(int)pVariables; i; i--)
1777         pSubExp(a,i, pGetExp(b,i));
1778      pSubComp(a, pGetComp(b));
1779      pSetm(a);
1780      prev=a;
1781      pIter(a);
1782    }
1783    else
1784    {
1785      if (prev==NULL)
1786      {
1787        pDelete1(&result);
1788        a=result;
1789      }
1790      else
1791      {
1792        pDelete1(&pNext(prev));
1793        a=pNext(prev);
1794      }
1795    }
1796  }
1797  pMultN(result,inv);
1798  nDelete(&inv);
1799  pDelete(&b);
1800  return result;
1801}
1802
1803/*2
1804* returns the LCM of the head terms of a and b in *m
1805*/
1806void pLcm(poly a, poly b, poly m)
1807{
1808  int i;
1809  for (i=pVariables; i; i--)
1810  {
1811    pSetExp(m,i, max( pGetExp(a,i), pGetExp(b,i)));
1812  }
1813  pSetComp(m, max(pGetComp(a), pGetComp(b)));
1814}
1815
1816/*2
1817* convert monomial given as string to poly, e.g. 1x3y5z
1818*/
1819poly pmInit(char *st, BOOLEAN &ok)
1820{
1821  int i,j;
1822  ok=FALSE;
1823  BOOLEAN b=FALSE;
1824  poly rc = pInit();
1825  char *s = nRead(st,&(rc->coef));
1826  if (s==st)
1827  /* i.e. it does not start with a coeff: test if it is a ringvar*/
1828  {
1829    j = rIsRingVar(s);
1830    if (j >= 0)
1831    {
1832      pIncrExp(rc,1+j);
1833      goto done;
1834    }
1835  }
1836  else
1837    b=TRUE;
1838  while (*s!='\0')
1839  {
1840    char ss[2];
1841    ss[0] = *s++;
1842    ss[1] = '\0';
1843    j = rIsRingVar(ss);
1844    if (j >= 0)
1845    {
1846      s = eati(s,&i);
1847      pAddExp(rc,1+j, (Exponent_t)i);
1848    }
1849    else
1850    {
1851      if ((s!=st)&&isdigit(st[0]))
1852      {
1853        errorreported=TRUE;
1854      }
1855      pDelete(&rc);
1856      return NULL;
1857    }
1858  }
1859done:
1860  ok=!errorreported;
1861  if (nIsZero(pGetCoeff(rc))) pDelete1(&rc);
1862  else
1863  {
1864#ifdef DRING
1865    if (pDRING)
1866    {
1867      for(i=1;i<=pdN;i++)
1868      {
1869        if(pGetExp(rc,pdDX(i))>0)
1870        {
1871          pdDFlag(rc)=1;
1872          break;
1873        }
1874      }
1875    }
1876#endif
1877    pSetm(rc);
1878  }
1879  return rc;
1880}
1881
1882/*2
1883*make p homgeneous by multiplying the monomials by powers of x_varnum
1884*/
1885poly pHomogen (poly p, int varnum)
1886{
1887  poly q=NULL;
1888  poly res;
1889  int  o,ii;
1890
1891  if (p!=NULL)
1892  {
1893    if ((varnum < 1) || (varnum > pVariables))
1894    {
1895      return NULL;
1896    }
1897    o=pWTotaldegree(p);
1898    q=pNext(p);
1899    while (q != NULL)
1900    {
1901      ii=pWTotaldegree(q);
1902      if (ii>o) o=ii;
1903      pIter(q);
1904    }
1905    q = pCopy(p);
1906    res = q;
1907    while (q != NULL)
1908    {
1909      ii = o-pWTotaldegree(q);
1910      if (ii!=0)
1911      {
1912        pAddExp(q,varnum, (Exponent_t)ii);
1913        pSetm(q);
1914      }
1915      pIter(q);
1916    }
1917    q = pOrdPolyInsertSetm(res);
1918  }
1919  return q;
1920}
1921
1922
1923/*2
1924*replaces the maximal powers of the leading monomial of p2 in p1 by
1925*the same powers of n, utility for dehomogenization
1926*/
1927poly pDehomogen (poly p1,poly p2,number n)
1928{
1929  polyset P;
1930  int     SizeOfSet=5;
1931  int     i;
1932  poly    p;
1933  number  nn;
1934
1935  P = (polyset)Alloc(5*sizeof(poly));
1936  for (i=0; i<5; i++)
1937  {
1938    P[i] = NULL;
1939  }
1940  pCancelPolyByMonom(p1,p2,&P,&SizeOfSet);
1941  p = P[0];
1942  //P[0] = NULL ;// for safety, may be remoeved later
1943  for (i=1; i<SizeOfSet; i++)
1944  {
1945    if (P[i] != NULL)
1946    {
1947      nPower(n,i,&nn);
1948      pMultN(P[i],nn);
1949      p = pAdd(p,P[i]);
1950      //P[i] =NULL; // for safety, may be removed later
1951      nDelete(&nn);
1952    }
1953  }
1954  Free((ADDRESS)P,SizeOfSet*sizeof(poly));
1955  return p;
1956}
1957
1958/*4
1959*Returns the exponent of the maximal power of the leading monomial of
1960*p2 in that of p1
1961*/
1962static int pGetMaxPower (poly p1,poly p2)
1963{
1964  int     i,k,res = 32000; /*a very large integer*/
1965
1966  if (p1 == NULL) return 0;
1967  for (i=1; i<=pVariables; i++)
1968  {
1969    if ( pGetExp(p2,i) != 0)
1970    {
1971      k =  pGetExp(p1,i) /  pGetExp(p2,i);
1972      if (k < res) res = k;
1973    }
1974  }
1975  return res;
1976}
1977
1978/*2
1979*Returns as i-th entry of P the coefficient of the (i-1) power of
1980*the leading monomial of p2 in p1
1981*/
1982void pCancelPolyByMonom (poly p1,poly p2,polyset * P,int * SizeOfSet)
1983{
1984  int   maxPow;
1985  poly  p,qp,Coeff;
1986
1987  if (*P == NULL)
1988  {
1989    *P = (polyset) Alloc(5*sizeof(poly));
1990    *SizeOfSet = 5;
1991  }
1992  p = pCopy(p1);
1993  while (p != NULL)
1994  {
1995    qp = p->next;
1996    p->next = NULL;
1997    maxPow = pGetMaxPower(p,p2);
1998    Coeff = pDivByMonom(p,p2);
1999    if (maxPow > *SizeOfSet)
2000    {
2001      pEnlargeSet(P,*SizeOfSet,maxPow+1-*SizeOfSet);
2002      *SizeOfSet = maxPow+1;
2003    }
2004    (*P)[maxPow] = pAdd((*P)[maxPow],Coeff);
2005    pDelete(&p);
2006    p = qp;
2007  }
2008}
2009
2010/*2
2011*returns the leading monomial of p1 divided by the maximal power of that
2012*of p2
2013*/
2014poly pDivByMonom (poly p1,poly p2)
2015{
2016  int     k, i;
2017
2018  if (p1 == NULL) return NULL;
2019  k = pGetMaxPower(p1,p2);
2020  if (k == 0)
2021    return pHead(p1);
2022  else
2023  {
2024    number n;
2025    poly p = pInit();
2026
2027    p->next = NULL;
2028    for (i=1; i<=pVariables; i++)
2029    {
2030       pSetExp(p,i, pGetExp(p1,i)-k* pGetExp(p2,i));
2031    }
2032    nPower(p2->coef,k,&n);
2033    pSetCoeff0(p,nDiv(p1->coef,n));
2034    nDelete(&n);
2035    pSetm(p);
2036    return p;
2037  }
2038}
2039/*----------utilities for syzygies--------------*/
2040poly pTakeOutComp(poly * p, int k)
2041{
2042  poly q = *p,qq=NULL,result = NULL;
2043
2044  if (q==NULL) return NULL;
2045  if (pGetComp(q)==k)
2046  {
2047    result = q;
2048    while ((q!=NULL) && (pGetComp(q)==k))
2049    {
2050      pSetComp(q,0);
2051      qq = q;
2052      pIter(q);
2053    }
2054    *p = q;
2055    pNext(qq) = NULL;
2056  }
2057  if (q==NULL) return result;
2058  if (pGetComp(q) > k) pDecrComp(q);
2059  poly pNext_q;
2060  while ((pNext_q=pNext(q))!=NULL)
2061  {
2062    if (pGetComp(pNext_q)==k)
2063    {
2064      if (result==NULL)
2065      {
2066        result = pNext_q;
2067        qq = result;
2068      }
2069      else
2070      {
2071        pNext(qq) = pNext_q;
2072        pIter(qq);
2073      }
2074      pNext(q) = pNext(pNext_q);
2075      pNext(qq) =NULL;
2076      pSetComp(qq,0);
2077    }
2078    else
2079    {
2080      /*pIter(q);*/ q=pNext_q;
2081      if (pGetComp(q) > k) pDecrComp(q);
2082    }
2083  }
2084  return result;
2085}
2086
2087poly pTakeOutComp1(poly * p, int k)
2088{
2089  poly q = *p;
2090
2091  if (q==NULL) return NULL;
2092
2093  poly qq=NULL,result = NULL;
2094
2095  if (pGetComp(q)==k)
2096  {
2097    result = q; /* *p */
2098    while ((q!=NULL) && (pGetComp(q)==k))
2099    {
2100      pSetComp(q,0);
2101      qq = q;
2102      pIter(q);
2103    }
2104    *p = q;
2105    pNext(qq) = NULL;
2106  }
2107  if (q==NULL) return result;
2108//  if (pGetComp(q) > k) pGetComp(q)--;
2109  while (pNext(q)!=NULL)
2110  {
2111    if (pGetComp(pNext(q))==k)
2112    {
2113      if (result==NULL)
2114      {
2115        result = pNext(q);
2116        qq = result;
2117      }
2118      else
2119      {
2120        pNext(qq) = pNext(q);
2121        pIter(qq);
2122      }
2123      pNext(q) = pNext(pNext(q));
2124      pNext(qq) =NULL;
2125      pSetComp(qq,0);
2126    }
2127    else
2128    {
2129      pIter(q);
2130//      if (pGetComp(q) > k) pGetComp(q)--;
2131    }
2132  }
2133  return result;
2134}
2135
2136void pDeleteComp(poly * p,int k)
2137{
2138  poly q;
2139
2140  while ((*p!=NULL) && (pGetComp(*p)==k)) pDelete1(p);
2141  if (*p==NULL) return;
2142  q = *p;
2143  if (pGetComp(q)>k) pDecrComp(q);
2144  while (pNext(q)!=NULL)
2145  {
2146    if (pGetComp(pNext(q))==k)
2147      pDelete1(&(pNext(q)));
2148    else
2149    {
2150      pIter(q);
2151      if (pGetComp(q)>k) pDecrComp(q);
2152    }
2153  }
2154}
2155/*----------end of utilities for syzygies--------------*/
2156
2157/*2
2158* pair has no common factor ? or is no polynomial
2159*/
2160BOOLEAN pHasNotCF(poly p1, poly p2)
2161{
2162#ifdef SRING
2163  if (pSRING)
2164    return FALSE;
2165#endif
2166
2167  if (pGetComp(p1) > 0 || pGetComp(p2) > 0)
2168    return FALSE;
2169  int i = 1;
2170  loop
2171  {
2172    if ((pGetExp(p1, i) > 0) && (pGetExp(p2, i) > 0))   return FALSE;
2173    if (i == pVariables)                                return TRUE;
2174    i++;
2175  }
2176}
2177
2178
2179/*2
2180*should return 1 if p divides q and p<q,
2181*             -1 if q divides p and q<p
2182*              0 otherwise
2183*/
2184int     pDivComp(poly p, poly q)
2185{
2186  if (pGetComp(p) == pGetComp(q))
2187  {
2188    int i=pVariables;
2189    long d;
2190    BOOLEAN a=FALSE, b=FALSE;
2191    for (; i>0; i--)
2192    {
2193      d = pGetExpDiff(p, q, i);
2194      if (d)
2195      {
2196        if (d < 0)
2197        {
2198          if (b) return 0;
2199          a =TRUE;
2200        }
2201        else
2202        {
2203          if (a) return 0;
2204          b = TRUE;
2205        }
2206      }
2207    }
2208    if (a) return 1;
2209    else if (b)  return -1;
2210  }
2211  return 0;
2212}
2213/*2
2214*divides p1 by its leading monomial
2215*/
2216void pNorm(poly p1)
2217{
2218  poly h;
2219  number k, c;
2220
2221  if (p1!=NULL)
2222  {
2223    if (!nIsOne(pGetCoeff(p1)))
2224    {
2225      nNormalize(pGetCoeff(p1));
2226      k=pGetCoeff(p1);
2227      c = nInit(1);
2228      pSetCoeff0(p1,c);
2229      h = pNext(p1);
2230      while (h!=NULL)
2231      {
2232        c=nDiv(pGetCoeff(h),k);
2233        if (!nIsOne(c)) nNormalize(c);
2234        pSetCoeff(h,c);
2235        pIter(h);
2236      }
2237      nDelete(&k);
2238    }
2239    else
2240    {
2241      h = pNext(p1);
2242      while (h!=NULL)
2243      {
2244        nNormalize(pGetCoeff(h));
2245        pIter(h);
2246      }
2247    }
2248  }
2249}
2250
2251/*2
2252*normalize all coeffizients
2253*/
2254void pNormalize(poly p)
2255{
2256  while (p!=NULL)
2257  {
2258    nTest(pGetCoeff(p));
2259    nNormalize(pGetCoeff(p));
2260    pIter(p);
2261  }
2262}
2263
2264/*3
2265* substitute the n-th variable by 1 in p
2266* destroy p
2267*/
2268static poly pSubst1 (poly p,int n)
2269{
2270  poly qq,result = NULL;
2271
2272  while (p != NULL)
2273  {
2274    qq = p;
2275    pIter(p);
2276    qq->next = NULL;
2277    pSetExp(qq,n,0);
2278    pSetm(qq);
2279    result = pAdd(result,qq);
2280  }
2281  return result;
2282}
2283
2284/*2
2285* substitute the n-th variable by e in p
2286* destroy p
2287*/
2288poly pSubst(poly p, int n, poly e)
2289{
2290  if ((e!=NULL)&&(pIsConstant(e))&&(nIsOne(pGetCoeff(e))))
2291    return pSubst1(p,n);
2292
2293  int exponent,i;
2294  poly h, res, m;
2295  Exponent_t *me,*ee;
2296  number nu,nu1;
2297
2298  me=(Exponent_t *)Alloc((pVariables+1)*sizeof(Exponent_t));
2299  ee=(Exponent_t *)Alloc((pVariables+1)*sizeof(Exponent_t));
2300  if (e!=NULL) pGetExpV(e,ee);
2301  res=NULL;
2302  h=p;
2303  while (h!=NULL)
2304  {
2305    if ((e!=NULL) || (pGetExp(h,n)==0))
2306    {
2307      m=pHead(h);
2308      pGetExpV(m,me);
2309      exponent=me[n];
2310      me[n]=0;
2311      for(i=1;i<=pVariables;i++)
2312        me[i]+=exponent*ee[i];
2313      pSetExpV(m,me);
2314      if (e!=NULL)
2315      {
2316        nPower(pGetCoeff(e),exponent,&nu);
2317        nu1=nMult(pGetCoeff(m),nu);
2318        nDelete(&nu);
2319        pSetCoeff(m,nu1);
2320      }
2321      res=pAdd(res,m);
2322    }
2323    pDelete1(&h);
2324  }
2325  Free((ADDRESS)me,(pVariables+1)*sizeof(Exponent_t));
2326  Free((ADDRESS)ee,(pVariables+1)*sizeof(Exponent_t));
2327  return res;
2328}
2329
2330BOOLEAN pCompareChain (poly p,poly p1,poly p2,poly lcm)
2331{
2332  int k, j;
2333
2334  if (lcm==NULL) return FALSE;
2335
2336  for (j=pVariables; j; j--)
2337    if ( pGetExp(p,j) >  pGetExp(lcm,j)) return FALSE;
2338  if ( pGetComp(p) !=  pGetComp(lcm)) return FALSE;
2339  for (j=pVariables; j; j--)
2340  {
2341    if (pGetExp(p1,j)!=pGetExp(lcm,j))
2342    {
2343      if (pGetExp(p,j)!=pGetExp(lcm,j))
2344      {
2345        for (k=pVariables; k>j; k--)        {
2346          if ((pGetExp(p,k)!=pGetExp(lcm,k))
2347          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
2348            return TRUE;
2349        }
2350        for (k=j-1; k; k--)
2351        {
2352          if ((pGetExp(p,k)!=pGetExp(lcm,k))
2353          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
2354            return TRUE;
2355        }
2356        return FALSE;
2357      }
2358    }
2359    else if (pGetExp(p2,j)!=pGetExp(lcm,j))
2360    {
2361      if (pGetExp(p,j)!=pGetExp(lcm,j))
2362      {
2363        for (k=pVariables; k>j; k--)
2364        {
2365          if ((pGetExp(p,k)!=pGetExp(lcm,k))
2366          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
2367            return TRUE;
2368        }
2369        for (k=j-1; k; k--)
2370        {
2371          if ((pGetExp(p,k)!=pGetExp(lcm,k))
2372          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
2373            return TRUE;
2374        }
2375        return FALSE;
2376      }
2377    }
2378  }
2379  return FALSE;
2380}
2381
2382int pWeight(int i)
2383{
2384  if ((firstwv==NULL) || (i>firstBlockEnds))
2385  {
2386    return 1;
2387  }
2388  return firstwv[i-1];
2389}
2390
2391
Note: See TracBrowser for help on using the repository browser.