source: git/Singular/polys.cc @ f3810e

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