source: git/Singular/polys.cc @ f6b5f0

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