source: git/Singular/polys.cc @ 110345

spielwiese
Last change on this file since 110345 was a3bc95e, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: namespaces ->ns git-svn-id: file:///usr/local/Singular/svn/trunk@5651 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 17.1 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id: polys.cc,v 1.78 2001-10-09 16:36:18 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 "omalloc.h"
17#include "febase.h"
18#include "numbers.h"
19#include "polys.h"
20#include "ring.h"
21
22/* ----------- global variables, set by pSetGlobals --------------------- */
23/* computes length and maximal degree of a POLYnomial */
24pLDegProc pLDeg;
25/* computes the degree of the initial term, used for std */
26pFDegProc pFDeg;
27/* the monomial ordering of the head monomials a and b */
28/* returns -1 if a comes before b, 0 if a=b, 1 otherwise */
29
30int pVariables;     // number of variables
31
32/* 1 for polynomial ring, -1 otherwise */
33int     pOrdSgn;
34// it is of type int, not BOOLEAN because it is also in ip
35/* TRUE if the monomial ordering is not compatible with pFDeg */
36BOOLEAN pLexOrder;
37
38/* ----------- global variables, set by procedures from hecke/kstd1 ----- */
39/* the highest monomial below pHEdge */
40poly      ppNoether = NULL;
41
42/* -------------------------------------------------------- */
43/*2
44* change all global variables to fit the description of the new ring
45*/
46
47
48void pSetGlobals(ring r, BOOLEAN complete)
49{
50  int i;
51  if (ppNoether!=NULL) pDelete(&ppNoether);
52  pVariables = r->N;
53  pOrdSgn = r->OrdSgn;
54  pFDeg=r->pFDeg;
55  pLDeg=r->pLDeg;
56  pLexOrder=r->LexOrder;
57
58  if (complete)
59  {
60    test &= ~ TEST_RINGDEP_OPTS;
61    test |= r->options;
62  }
63}
64
65// resets the pFDeg and pLDeg: if pLDeg is not given, it is
66// set to currRing->pLDegOrig, i.e. to the respective LDegProc which
67// only uses pFDeg (and not pDeg, or pTotalDegree, etc)
68void pSetDegProcs(pFDegProc new_FDeg, pLDegProc new_lDeg)
69{
70  assume(new_FDeg != NULL);
71  pFDeg = new_FDeg;
72  currRing->pFDeg = new_FDeg;
73
74  if (new_lDeg == NULL)
75    new_lDeg = currRing->pLDegOrig;
76
77  pLDeg = new_lDeg;
78  currRing->pLDeg = new_lDeg;
79}
80
81
82// restores pFDeg and pLDeg:
83extern void pRestoreDegProcs(pFDegProc old_FDeg, pLDegProc old_lDeg)
84{
85  assume(old_FDeg != NULL && old_lDeg != NULL);
86  pFDeg = old_FDeg;
87  currRing->pFDeg = old_FDeg;
88  pLDeg = old_lDeg;
89  currRing->pLDeg = old_lDeg;
90}
91
92/*2
93* assumes that the head term of b is a multiple of the head term of a
94* and return the multiplicant *m
95*/
96poly pDivide(poly a, poly b)
97{
98  int i;
99  poly result = pInit();
100
101  for(i=(int)pVariables; i; i--)
102    pSetExp(result,i, pGetExp(a,i)- pGetExp(b,i));
103  pSetComp(result, pGetComp(a) - pGetComp(b));
104  pSetm(result);
105  return result;
106}
107
108/*2
109* divides a by the monomial b, ignores monomials wihich are not divisible
110* assumes that b is not NULL
111*/
112poly pDivideM(poly a, poly b)
113{
114  if (a==NULL) return NULL;
115  poly result=a;
116  poly prev=NULL;
117  int i;
118  number inv=nInvers(pGetCoeff(b));
119
120  while (a!=NULL)
121  {
122    if (pDivisibleBy(b,a))
123    {
124      for(i=(int)pVariables; i; i--)
125         pSubExp(a,i, pGetExp(b,i));
126      pSubComp(a, pGetComp(b));
127      pSetm(a);
128      prev=a;
129      pIter(a);
130    }
131    else
132    {
133      if (prev==NULL)
134      {
135        pDeleteLm(&result);
136        a=result;
137      }
138      else
139      {
140        pDeleteLm(&pNext(prev));
141        a=pNext(prev);
142      }
143    }
144  }
145  pMult_nn(result,inv);
146  nDelete(&inv);
147  pDelete(&b);
148  return result;
149}
150
151/*2
152* returns the LCM of the head terms of a and b in *m
153*/
154void pLcm(poly a, poly b, poly m)
155{
156  int i;
157  for (i=pVariables; i; i--)
158  {
159    pSetExp(m,i, max( pGetExp(a,i), pGetExp(b,i)));
160  }
161  pSetComp(m, max(pGetComp(a), pGetComp(b)));
162  /* Don't do a pSetm here, otherwise hres/lres chockes */
163}
164
165/*2
166* convert monomial given as string to poly, e.g. 1x3y5z
167*/
168char * p_Read(char *st, poly &rc, ring r)
169{
170  if (r==NULL) { rc=NULL;return st;}
171  int i,j;
172  rc = p_Init(r);
173  char *s = r->cf->nRead(st,&(rc->coef));
174  if (s==st)
175  /* i.e. it does not start with a coeff: test if it is a ringvar*/
176  {
177    j = r_IsRingVar(s,r);
178    if (j >= 0)
179    {
180      p_IncrExp(rc,1+j,r);
181      while (*s!='\0') s++;
182      goto done;
183    }
184  }
185  while (*s!='\0')
186  {
187    char ss[2];
188    ss[0] = *s++;
189    ss[1] = '\0';
190    j = r_IsRingVar(ss,r);
191    if (j >= 0)
192    {
193      s = eati(s,&i);
194      p_AddExp(rc,1+j, (Exponent_t)i, r);
195    }
196    else
197    {
198      s--;
199      return s;
200    }
201  }
202done:
203  if (r->cf->nIsZero(pGetCoeff(rc))) p_DeleteLm(&rc,r);
204  else
205  {
206    p_Setm(rc,r);
207  }
208  return s;
209}
210
211poly pmInit(char *st, BOOLEAN &ok)
212{
213  poly p;
214  char *s=p_Read(st,p,currRing);
215  if (*s!='\0')
216  {
217    if ((s!=st)&&isdigit(st[0]))
218    {
219      errorreported=TRUE;
220    }
221    ok=FALSE;
222    pDelete(&p);
223    return NULL;
224  }
225  ok=!errorreported;
226  return p;
227}
228
229/*2
230*make p homgeneous by multiplying the monomials by powers of x_varnum
231*/
232poly pHomogen (poly p, int varnum)
233{
234  poly q=NULL, qn;
235  int  o,ii;
236  sBucket_pt bp;
237
238  if (p!=NULL)
239  {
240    if ((varnum < 1) || (varnum > pVariables))
241    {
242      return NULL;
243    }
244    o=pWTotaldegree(p);
245    q=pNext(p);
246    while (q != NULL)
247    {
248      ii=pWTotaldegree(q);
249      if (ii>o) o=ii;
250      pIter(q);
251    }
252    q = pCopy(p);
253    bp = sBucketCreate(currRing);
254    while (q != NULL)
255    {
256      ii = o-pWTotaldegree(q);
257      if (ii!=0)
258      {
259        pAddExp(q,varnum, (Exponent_t)ii);
260        pSetm(q);
261      }
262      qn = pNext(q);
263      pNext(q) = NULL;
264      sBucket_Add_p(bp, q, 1);
265      q = qn;
266    }
267    sBucketDestroyAdd(bp, &q, &ii);
268  }
269  return q;
270}
271
272/*2
273*replaces the maximal powers of the leading monomial of p2 in p1 by
274*the same powers of n, utility for dehomogenization
275*/
276poly pDehomogen (poly p1,poly p2,number n)
277{
278  polyset P;
279  int     SizeOfSet=5;
280  int     i;
281  poly    p;
282  number  nn;
283
284  P = (polyset)omAlloc0(5*sizeof(poly));
285  //for (i=0; i<5; i++)
286  //{
287  //  P[i] = NULL;
288  //}
289  pCancelPolyByMonom(p1,p2,&P,&SizeOfSet);
290  p = P[0];
291  //P[0] = NULL ;// for safety, may be remoeved later
292  for (i=1; i<SizeOfSet; i++)
293  {
294    if (P[i] != NULL)
295    {
296      nPower(n,i,&nn);
297      pMult_nn(P[i],nn);
298      p = pAdd(p,P[i]);
299      //P[i] =NULL; // for safety, may be removed later
300      nDelete(&nn);
301    }
302  }
303  omFreeSize((ADDRESS)P,SizeOfSet*sizeof(poly));
304  return p;
305}
306
307/*4
308*Returns the exponent of the maximal power of the leading monomial of
309*p2 in that of p1
310*/
311static int pGetMaxPower (poly p1,poly p2)
312{
313  int     i,k,res = 32000; /*a very large integer*/
314
315  if (p1 == NULL) return 0;
316  for (i=1; i<=pVariables; i++)
317  {
318    if ( pGetExp(p2,i) != 0)
319    {
320      k =  pGetExp(p1,i) /  pGetExp(p2,i);
321      if (k < res) res = k;
322    }
323  }
324  return res;
325}
326
327/*2
328*Returns as i-th entry of P the coefficient of the (i-1) power of
329*the leading monomial of p2 in p1
330*/
331void pCancelPolyByMonom (poly p1,poly p2,polyset * P,int * SizeOfSet)
332{
333  int   maxPow;
334  poly  p,qp,Coeff;
335
336  if (*P == NULL)
337  {
338    *P = (polyset) omAlloc(5*sizeof(poly));
339    *SizeOfSet = 5;
340  }
341  p = pCopy(p1);
342  while (p != NULL)
343  {
344    qp = p->next;
345    p->next = NULL;
346    maxPow = pGetMaxPower(p,p2);
347    Coeff = pDivByMonom(p,p2);
348    if (maxPow > *SizeOfSet)
349    {
350      pEnlargeSet(P,*SizeOfSet,maxPow+1-*SizeOfSet);
351      *SizeOfSet = maxPow+1;
352    }
353    (*P)[maxPow] = pAdd((*P)[maxPow],Coeff);
354    pDelete(&p);
355    p = qp;
356  }
357}
358
359/*2
360*returns the leading monomial of p1 divided by the maximal power of that
361*of p2
362*/
363poly pDivByMonom (poly p1,poly p2)
364{
365  int     k, i;
366
367  if (p1 == NULL) return NULL;
368  k = pGetMaxPower(p1,p2);
369  if (k == 0)
370    return pHead(p1);
371  else
372  {
373    number n;
374    poly p = pInit();
375
376    p->next = NULL;
377    for (i=1; i<=pVariables; i++)
378    {
379       pSetExp(p,i, pGetExp(p1,i)-k* pGetExp(p2,i));
380    }
381    nPower(p2->coef,k,&n);
382    pSetCoeff0(p,nDiv(p1->coef,n));
383    nDelete(&n);
384    pSetm(p);
385    return p;
386  }
387}
388/*----------utilities for syzygies--------------*/
389poly pTakeOutComp(poly * p, int k)
390{
391  poly q = *p,qq=NULL,result = NULL;
392
393  if (q==NULL) return NULL;
394  if (pGetComp(q)==k)
395  {
396    result = q;
397    while ((q!=NULL) && (pGetComp(q)==k))
398    {
399      pSetComp(q,0);
400      pSetmComp(q);
401      qq = q;
402      pIter(q);
403    }
404    *p = q;
405    pNext(qq) = NULL;
406  }
407  if (q==NULL) return result;
408  if (pGetComp(q) > k)
409  {
410    pDecrComp(q);
411    pSetmComp(q);
412  }
413  poly pNext_q;
414  while ((pNext_q=pNext(q))!=NULL)
415  {
416    if (pGetComp(pNext_q)==k)
417    {
418      if (result==NULL)
419      {
420        result = pNext_q;
421        qq = result;
422      }
423      else
424      {
425        pNext(qq) = pNext_q;
426        pIter(qq);
427      }
428      pNext(q) = pNext(pNext_q);
429      pNext(qq) =NULL;
430      pSetComp(qq,0);
431      pSetmComp(qq);
432    }
433    else
434    {
435      /*pIter(q);*/ q=pNext_q;
436      if (pGetComp(q) > k)
437      {
438        pDecrComp(q);
439        pSetmComp(q);
440      }
441    }
442  }
443  return result;
444}
445
446// Splits *p into two polys: *q which consists of all monoms with
447// component == comp and *p of all other monoms *lq == pLength(*q)
448void pTakeOutComp(poly *r_p, Exponent_t comp, poly *r_q, int *lq)
449{
450  spolyrec pp, qq;
451  poly p, q, p_prev;
452  int l = 0;
453
454#ifdef HAVE_ASSUME
455  int lp = pLength(*r_p);
456#endif
457
458  pNext(&pp) = *r_p;
459  p = *r_p;
460  p_prev = &pp;
461  q = &qq;
462
463  while(p != NULL)
464  {
465    while (pGetComp(p) == comp)
466    {
467      pNext(q) = p;
468      pIter(q);
469      pSetComp(p, 0);
470      pSetmComp(p);
471      pIter(p);
472      l++;
473      if (p == NULL)
474      {
475        pNext(p_prev) = NULL;
476        goto Finish;
477      }
478    }
479    pNext(p_prev) = p;
480    p_prev = p;
481    pIter(p);
482  }
483
484  Finish:
485  pNext(q) = NULL;
486  *r_p = pNext(&pp);
487  *r_q = pNext(&qq);
488  *lq = l;
489#ifdef HAVE_ASSUME
490  assume(pLength(*r_p) + pLength(*r_q) == lp);
491#endif
492  pTest(*r_p);
493  pTest(*r_q);
494}
495
496void pDecrOrdTakeOutComp(poly *r_p, Exponent_t comp, Order_t order,
497                         poly *r_q, int *lq)
498{
499  spolyrec pp, qq;
500  poly p, q, p_prev;
501  int l = 0;
502
503  pNext(&pp) = *r_p;
504  p = *r_p;
505  p_prev = &pp;
506  q = &qq;
507
508#ifdef HAVE_ASSUME
509  if (p != NULL)
510  {
511    while (pNext(p) != NULL)
512    {
513      assume(pGetOrder(p) >= pGetOrder(pNext(p)));
514      pIter(p);
515    }
516  }
517  p = *r_p;
518#endif
519
520  while (p != NULL && pGetOrder(p) > order) pIter(p);
521
522  while(p != NULL && pGetOrder(p) == order)
523  {
524    while (pGetComp(p) == comp)
525    {
526      pNext(q) = p;
527      pIter(q);
528      pIter(p);
529      pSetComp(p, 0);
530      pSetmComp(p);
531      l++;
532      if (p == NULL || pGetOrder(p) != order)
533      {
534        pNext(p_prev) = p;
535        goto Finish;
536      }
537    }
538    pNext(p_prev) = p;
539    p_prev = p;
540    pIter(p);
541  }
542
543  Finish:
544  pNext(q) = NULL;
545  *r_p = pNext(&pp);
546  *r_q = pNext(&qq);
547  *lq = l;
548}
549
550#if 1
551poly pTakeOutComp1(poly * p, int k)
552{
553  poly q = *p;
554
555  if (q==NULL) return NULL;
556
557  poly qq=NULL,result = NULL;
558
559  if (pGetComp(q)==k)
560  {
561    result = q; /* *p */
562    while ((q!=NULL) && (pGetComp(q)==k))
563    {
564      pSetComp(q,0);
565      pSetmComp(q);
566      qq = q;
567      pIter(q);
568    }
569    *p = q;
570    pNext(qq) = NULL;
571  }
572  if (q==NULL) return result;
573//  if (pGetComp(q) > k) pGetComp(q)--;
574  while (pNext(q)!=NULL)
575  {
576    if (pGetComp(pNext(q))==k)
577    {
578      if (result==NULL)
579      {
580        result = pNext(q);
581        qq = result;
582      }
583      else
584      {
585        pNext(qq) = pNext(q);
586        pIter(qq);
587      }
588      pNext(q) = pNext(pNext(q));
589      pNext(qq) =NULL;
590      pSetComp(qq,0);
591      pSetmComp(qq);
592    }
593    else
594    {
595      pIter(q);
596//      if (pGetComp(q) > k) pGetComp(q)--;
597    }
598  }
599  return result;
600}
601#endif
602
603void pDeleteComp(poly * p,int k)
604{
605  poly q;
606
607  while ((*p!=NULL) && (pGetComp(*p)==k)) pDeleteLm(p);
608  if (*p==NULL) return;
609  q = *p;
610  if (pGetComp(q)>k)
611  {
612    pDecrComp(q);
613    pSetmComp(q);
614  }
615  while (pNext(q)!=NULL)
616  {
617    if (pGetComp(pNext(q))==k)
618      pDeleteLm(&(pNext(q)));
619    else
620    {
621      pIter(q);
622      if (pGetComp(q)>k)
623      {
624        pDecrComp(q);
625        pSetmComp(q);
626      }
627    }
628  }
629}
630/*----------end of utilities for syzygies--------------*/
631
632/*2
633* pair has no common factor ? or is no polynomial
634*/
635BOOLEAN pHasNotCF(poly p1, poly p2)
636{
637
638  if (pGetComp(p1) > 0 || pGetComp(p2) > 0)
639    return FALSE;
640  int i = 1;
641  loop
642  {
643    if ((pGetExp(p1, i) > 0) && (pGetExp(p2, i) > 0))   return FALSE;
644    if (i == pVariables)                                return TRUE;
645    i++;
646  }
647}
648
649
650/*2
651*divides p1 by its leading monomial
652*/
653void pNorm(poly p1)
654{
655  poly h;
656  number k, c;
657
658  if (p1!=NULL)
659  {
660    if (!nIsOne(pGetCoeff(p1)))
661    {
662      nNormalize(pGetCoeff(p1));
663      k=pGetCoeff(p1);
664      c = nInit(1);
665      pSetCoeff0(p1,c);
666      h = pNext(p1);
667      while (h!=NULL)
668      {
669        c=nDiv(pGetCoeff(h),k);
670        if (!nIsOne(c)) nNormalize(c);
671        pSetCoeff(h,c);
672        pIter(h);
673      }
674      nDelete(&k);
675    }
676    else
677    {
678      if (nNormalize != nDummy2)
679      {
680        h = pNext(p1);
681        while (h!=NULL)
682        {
683          nNormalize(pGetCoeff(h));
684          pIter(h);
685        }
686      }
687    }
688  }
689}
690
691/*2
692*normalize all coeffizients
693*/
694void pNormalize(poly p)
695{
696  if (rField_has_simple_inverse()) return; /* Z/p, GF(p,n), R, long R/C */
697  while (p!=NULL)
698  {
699    nTest(pGetCoeff(p));
700    nNormalize(pGetCoeff(p));
701    pIter(p);
702  }
703}
704
705// splits p into polys with Exp(n) == 0 and Exp(n) != 0
706// Poly with Exp(n) != 0 is reversed
707static void pSplitAndReversePoly(poly p, int n, poly *non_zero, poly *zero)
708{
709  if (p == NULL)
710  {
711    *non_zero = NULL;
712    *zero = NULL;
713    return;
714  }
715  spolyrec sz;
716  poly z, n_z, next;
717  z = &sz;
718  n_z = NULL;
719
720  while(p != NULL)
721  {
722    next = pNext(p);
723    if (pGetExp(p, n) == 0)
724    {
725      pNext(z) = p;
726      pIter(z);
727    }
728    else
729    {
730      pNext(p) = n_z;
731      n_z = p;
732    }
733    p = next;
734  }
735  pNext(z) = NULL;
736  *zero = pNext(&sz);
737  *non_zero = n_z;
738  return;
739}
740
741/*3
742* substitute the n-th variable by 1 in p
743* destroy p
744*/
745static poly pSubst1 (poly p,int n)
746{
747  poly qq,result = NULL;
748  poly zero, non_zero;
749
750  // reverse, so that add is likely to be linear
751  pSplitAndReversePoly(p, n, &non_zero, &zero);
752
753  while (non_zero != NULL)
754  {
755    assume(pGetExp(non_zero, n) != 0);
756    qq = non_zero;
757    pIter(non_zero);
758    qq->next = NULL;
759    pSetExp(qq,n,0);
760    pSetm(qq);
761    result = pAdd(result,qq);
762  }
763  p = pAdd(result, zero);
764  pTest(p);
765  return p;
766}
767
768/*3
769* substitute the n-th variable by number e in p
770* destroy p
771*/
772static poly pSubst2 (poly p,int n, number e)
773{
774  assume( ! nIsZero(e) );
775  poly qq,result = NULL;
776  number nn, nm;
777  poly zero, non_zero;
778
779  // reverse, so that add is likely to be linear
780  pSplitAndReversePoly(p, n, &non_zero, &zero);
781
782  while (non_zero != NULL)
783  {
784    assume(pGetExp(non_zero, n) != 0);
785    qq = non_zero;
786    pIter(non_zero);
787    qq->next = NULL;
788    nPower(e, pGetExp(qq, n), &nn);
789    nm = nMult(nn, pGetCoeff(qq));
790    pSetCoeff(qq, nm);
791    nDelete(&nn);
792    pSetExp(qq, n, 0);
793    pSetm(qq);
794    result = pAdd(result,qq);
795  }
796  p = pAdd(result, zero);
797  pTest(p);
798  return p;
799}
800
801
802/* delete monoms whose n-th exponent is different from zero */
803poly pSubst0(poly p, int n)
804{
805  spolyrec res;
806  poly h = &res;
807  pNext(h) = p;
808
809  while (pNext(h)!=NULL)
810  {
811    if (pGetExp(pNext(h),n)!=0)
812    {
813      pDeleteLm(&pNext(h));
814    }
815    else
816    {
817      pIter(h);
818    }
819  }
820  pTest(pNext(&res));
821  return pNext(&res);
822}
823
824/*2
825* substitute the n-th variable by e in p
826* destroy p
827*/
828poly pSubst(poly p, int n, poly e)
829{
830  if (e == NULL) return pSubst0(p, n);
831
832  if (pIsConstant(e))
833  {
834    if (nIsOne(pGetCoeff(e))) return pSubst1(p,n);
835    else return pSubst2(p, n, pGetCoeff(e));
836  }
837
838  int exponent,i;
839  poly h, res, m;
840  Exponent_t *me,*ee;
841  number nu,nu1;
842
843  me=(Exponent_t *)omAlloc((pVariables+1)*sizeof(Exponent_t));
844  ee=(Exponent_t *)omAlloc((pVariables+1)*sizeof(Exponent_t));
845  if (e!=NULL) pGetExpV(e,ee);
846  res=NULL;
847  h=p;
848  while (h!=NULL)
849  {
850    if ((e!=NULL) || (pGetExp(h,n)==0))
851    {
852      m=pHead(h);
853      pGetExpV(m,me);
854      exponent=me[n];
855      me[n]=0;
856      for(i=pVariables;i>0;i--)
857        me[i]+=exponent*ee[i];
858      pSetExpV(m,me);
859      if (e!=NULL)
860      {
861        nPower(pGetCoeff(e),exponent,&nu);
862        nu1=nMult(pGetCoeff(m),nu);
863        nDelete(&nu);
864        pSetCoeff(m,nu1);
865      }
866      res=pAdd(res,m);
867    }
868    pDeleteLm(&h);
869  }
870  omFreeSize((ADDRESS)me,(pVariables+1)*sizeof(Exponent_t));
871  omFreeSize((ADDRESS)ee,(pVariables+1)*sizeof(Exponent_t));
872  return res;
873}
874
875BOOLEAN pCompareChain (poly p,poly p1,poly p2,poly lcm)
876{
877  int k, j;
878
879  if (lcm==NULL) return FALSE;
880
881  for (j=pVariables; j; j--)
882    if ( pGetExp(p,j) >  pGetExp(lcm,j)) return FALSE;
883  if ( pGetComp(p) !=  pGetComp(lcm)) return FALSE;
884  for (j=pVariables; j; j--)
885  {
886    if (pGetExp(p1,j)!=pGetExp(lcm,j))
887    {
888      if (pGetExp(p,j)!=pGetExp(lcm,j))
889      {
890        for (k=pVariables; k>j; k--)
891        {
892          if ((pGetExp(p,k)!=pGetExp(lcm,k))
893          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
894            return TRUE;
895        }
896        for (k=j-1; k; k--)
897        {
898          if ((pGetExp(p,k)!=pGetExp(lcm,k))
899          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
900            return TRUE;
901        }
902        return FALSE;
903      }
904    }
905    else if (pGetExp(p2,j)!=pGetExp(lcm,j))
906    {
907      if (pGetExp(p,j)!=pGetExp(lcm,j))
908      {
909        for (k=pVariables; k>j; k--)
910        {
911          if ((pGetExp(p,k)!=pGetExp(lcm,k))
912          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
913            return TRUE;
914        }
915        for (k=j-1; k!=0 ; k--)
916        {
917          if ((pGetExp(p,k)!=pGetExp(lcm,k))
918          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
919            return TRUE;
920        }
921        return FALSE;
922      }
923    }
924  }
925  return FALSE;
926}
Note: See TracBrowser for help on using the repository browser.