source: git/Singular/polys.cc @ 50cbdc

spielwiese
Last change on this file since 50cbdc was 50cbdc, checked in by Hans Schönemann <hannes@…>, 23 years ago
*hannes: merge-2-0-2 git-svn-id: file:///usr/local/Singular/svn/trunk@5619 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.76 2001-08-27 14:47:32 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  int i,j;
171  rc = p_Init(r);
172  char *s = r->cf->nRead(st,&(rc->coef));
173  if (s==st)
174  /* i.e. it does not start with a coeff: test if it is a ringvar*/
175  {
176    j = r_IsRingVar(s,r);
177    if (j >= 0)
178    {
179      p_IncrExp(rc,1+j,r);
180      while (*s!='\0') s++;
181      goto done;
182    }
183  }
184  while (*s!='\0')
185  {
186    char ss[2];
187    ss[0] = *s++;
188    ss[1] = '\0';
189    j = r_IsRingVar(ss,r);
190    if (j >= 0)
191    {
192      s = eati(s,&i);
193      p_AddExp(rc,1+j, (Exponent_t)i, r);
194    }
195    else
196    {
197      s--;
198      return s;
199    }
200  }
201done:
202  if (r->cf->nIsZero(pGetCoeff(rc))) p_DeleteLm(&rc,r);
203  else
204  {
205    p_Setm(rc,r);
206  }
207  return s;
208}
209
210poly pmInit(char *st, BOOLEAN &ok)
211{
212  poly p;
213  char *s=p_Read(st,p,currRing);
214  if (*s!='\0')
215  {
216    if ((s!=st)&&isdigit(st[0]))
217    {
218      errorreported=TRUE;
219    }
220    ok=FALSE;
221    pDelete(&p);
222    return NULL;
223  }
224  ok=!errorreported;
225  return p;
226}
227
228/*2
229*make p homgeneous by multiplying the monomials by powers of x_varnum
230*/
231poly pHomogen (poly p, int varnum)
232{
233  poly q=NULL, qn;
234  int  o,ii;
235  sBucket_pt bp;
236
237  if (p!=NULL)
238  {
239    if ((varnum < 1) || (varnum > pVariables))
240    {
241      return NULL;
242    }
243    o=pWTotaldegree(p);
244    q=pNext(p);
245    while (q != NULL)
246    {
247      ii=pWTotaldegree(q);
248      if (ii>o) o=ii;
249      pIter(q);
250    }
251    q = pCopy(p);
252    bp = sBucketCreate(currRing);
253    while (q != NULL)
254    {
255      ii = o-pWTotaldegree(q);
256      if (ii!=0)
257      {
258        pAddExp(q,varnum, (Exponent_t)ii);
259        pSetm(q);
260      }
261      qn = pNext(q);
262      pNext(q) = NULL;
263      sBucket_Add_p(bp, q, 1);
264      q = qn;
265    }
266    sBucketDestroyAdd(bp, &q, &ii);
267  }
268  return q;
269}
270
271/*2
272*replaces the maximal powers of the leading monomial of p2 in p1 by
273*the same powers of n, utility for dehomogenization
274*/
275poly pDehomogen (poly p1,poly p2,number n)
276{
277  polyset P;
278  int     SizeOfSet=5;
279  int     i;
280  poly    p;
281  number  nn;
282
283  P = (polyset)omAlloc0(5*sizeof(poly));
284  //for (i=0; i<5; i++)
285  //{
286  //  P[i] = NULL;
287  //}
288  pCancelPolyByMonom(p1,p2,&P,&SizeOfSet);
289  p = P[0];
290  //P[0] = NULL ;// for safety, may be remoeved later
291  for (i=1; i<SizeOfSet; i++)
292  {
293    if (P[i] != NULL)
294    {
295      nPower(n,i,&nn);
296      pMult_nn(P[i],nn);
297      p = pAdd(p,P[i]);
298      //P[i] =NULL; // for safety, may be removed later
299      nDelete(&nn);
300    }
301  }
302  omFreeSize((ADDRESS)P,SizeOfSet*sizeof(poly));
303  return p;
304}
305
306/*4
307*Returns the exponent of the maximal power of the leading monomial of
308*p2 in that of p1
309*/
310static int pGetMaxPower (poly p1,poly p2)
311{
312  int     i,k,res = 32000; /*a very large integer*/
313
314  if (p1 == NULL) return 0;
315  for (i=1; i<=pVariables; i++)
316  {
317    if ( pGetExp(p2,i) != 0)
318    {
319      k =  pGetExp(p1,i) /  pGetExp(p2,i);
320      if (k < res) res = k;
321    }
322  }
323  return res;
324}
325
326/*2
327*Returns as i-th entry of P the coefficient of the (i-1) power of
328*the leading monomial of p2 in p1
329*/
330void pCancelPolyByMonom (poly p1,poly p2,polyset * P,int * SizeOfSet)
331{
332  int   maxPow;
333  poly  p,qp,Coeff;
334
335  if (*P == NULL)
336  {
337    *P = (polyset) omAlloc(5*sizeof(poly));
338    *SizeOfSet = 5;
339  }
340  p = pCopy(p1);
341  while (p != NULL)
342  {
343    qp = p->next;
344    p->next = NULL;
345    maxPow = pGetMaxPower(p,p2);
346    Coeff = pDivByMonom(p,p2);
347    if (maxPow > *SizeOfSet)
348    {
349      pEnlargeSet(P,*SizeOfSet,maxPow+1-*SizeOfSet);
350      *SizeOfSet = maxPow+1;
351    }
352    (*P)[maxPow] = pAdd((*P)[maxPow],Coeff);
353    pDelete(&p);
354    p = qp;
355  }
356}
357
358/*2
359*returns the leading monomial of p1 divided by the maximal power of that
360*of p2
361*/
362poly pDivByMonom (poly p1,poly p2)
363{
364  int     k, i;
365
366  if (p1 == NULL) return NULL;
367  k = pGetMaxPower(p1,p2);
368  if (k == 0)
369    return pHead(p1);
370  else
371  {
372    number n;
373    poly p = pInit();
374
375    p->next = NULL;
376    for (i=1; i<=pVariables; i++)
377    {
378       pSetExp(p,i, pGetExp(p1,i)-k* pGetExp(p2,i));
379    }
380    nPower(p2->coef,k,&n);
381    pSetCoeff0(p,nDiv(p1->coef,n));
382    nDelete(&n);
383    pSetm(p);
384    return p;
385  }
386}
387/*----------utilities for syzygies--------------*/
388poly pTakeOutComp(poly * p, int k)
389{
390  poly q = *p,qq=NULL,result = NULL;
391
392  if (q==NULL) return NULL;
393  if (pGetComp(q)==k)
394  {
395    result = q;
396    while ((q!=NULL) && (pGetComp(q)==k))
397    {
398      pSetComp(q,0);
399      pSetmComp(q);
400      qq = q;
401      pIter(q);
402    }
403    *p = q;
404    pNext(qq) = NULL;
405  }
406  if (q==NULL) return result;
407  if (pGetComp(q) > k)
408  {
409    pDecrComp(q);
410    pSetmComp(q);
411  }
412  poly pNext_q;
413  while ((pNext_q=pNext(q))!=NULL)
414  {
415    if (pGetComp(pNext_q)==k)
416    {
417      if (result==NULL)
418      {
419        result = pNext_q;
420        qq = result;
421      }
422      else
423      {
424        pNext(qq) = pNext_q;
425        pIter(qq);
426      }
427      pNext(q) = pNext(pNext_q);
428      pNext(qq) =NULL;
429      pSetComp(qq,0);
430      pSetmComp(qq);
431    }
432    else
433    {
434      /*pIter(q);*/ q=pNext_q;
435      if (pGetComp(q) > k)
436      {
437        pDecrComp(q);
438        pSetmComp(q);
439      }
440    }
441  }
442  return result;
443}
444
445// Splits *p into two polys: *q which consists of all monoms with
446// component == comp and *p of all other monoms *lq == pLength(*q)
447void pTakeOutComp(poly *r_p, Exponent_t comp, poly *r_q, int *lq)
448{
449  spolyrec pp, qq;
450  poly p, q, p_prev;
451  int l = 0;
452
453#ifdef HAVE_ASSUME
454  int lp = pLength(*r_p);
455#endif
456
457  pNext(&pp) = *r_p;
458  p = *r_p;
459  p_prev = &pp;
460  q = &qq;
461
462  while(p != NULL)
463  {
464    while (pGetComp(p) == comp)
465    {
466      pNext(q) = p;
467      pIter(q);
468      pSetComp(p, 0);
469      pSetmComp(p);
470      pIter(p);
471      l++;
472      if (p == NULL)
473      {
474        pNext(p_prev) = NULL;
475        goto Finish;
476      }
477    }
478    pNext(p_prev) = p;
479    p_prev = p;
480    pIter(p);
481  }
482
483  Finish:
484  pNext(q) = NULL;
485  *r_p = pNext(&pp);
486  *r_q = pNext(&qq);
487  *lq = l;
488#ifdef HAVE_ASSUME
489  assume(pLength(*r_p) + pLength(*r_q) == lp);
490#endif
491  pTest(*r_p);
492  pTest(*r_q);
493}
494
495void pDecrOrdTakeOutComp(poly *r_p, Exponent_t comp, Order_t order,
496                         poly *r_q, int *lq)
497{
498  spolyrec pp, qq;
499  poly p, q, p_prev;
500  int l = 0;
501
502  pNext(&pp) = *r_p;
503  p = *r_p;
504  p_prev = &pp;
505  q = &qq;
506
507#ifdef HAVE_ASSUME
508  if (p != NULL)
509  {
510    while (pNext(p) != NULL)
511    {
512      assume(pGetOrder(p) >= pGetOrder(pNext(p)));
513      pIter(p);
514    }
515  }
516  p = *r_p;
517#endif
518
519  while (p != NULL && pGetOrder(p) > order) pIter(p);
520
521  while(p != NULL && pGetOrder(p) == order)
522  {
523    while (pGetComp(p) == comp)
524    {
525      pNext(q) = p;
526      pIter(q);
527      pIter(p);
528      pSetComp(p, 0);
529      pSetmComp(p);
530      l++;
531      if (p == NULL || pGetOrder(p) != order)
532      {
533        pNext(p_prev) = p;
534        goto Finish;
535      }
536    }
537    pNext(p_prev) = p;
538    p_prev = p;
539    pIter(p);
540  }
541
542  Finish:
543  pNext(q) = NULL;
544  *r_p = pNext(&pp);
545  *r_q = pNext(&qq);
546  *lq = l;
547}
548
549#if 1
550poly pTakeOutComp1(poly * p, int k)
551{
552  poly q = *p;
553
554  if (q==NULL) return NULL;
555
556  poly qq=NULL,result = NULL;
557
558  if (pGetComp(q)==k)
559  {
560    result = q; /* *p */
561    while ((q!=NULL) && (pGetComp(q)==k))
562    {
563      pSetComp(q,0);
564      pSetmComp(q);
565      qq = q;
566      pIter(q);
567    }
568    *p = q;
569    pNext(qq) = NULL;
570  }
571  if (q==NULL) return result;
572//  if (pGetComp(q) > k) pGetComp(q)--;
573  while (pNext(q)!=NULL)
574  {
575    if (pGetComp(pNext(q))==k)
576    {
577      if (result==NULL)
578      {
579        result = pNext(q);
580        qq = result;
581      }
582      else
583      {
584        pNext(qq) = pNext(q);
585        pIter(qq);
586      }
587      pNext(q) = pNext(pNext(q));
588      pNext(qq) =NULL;
589      pSetComp(qq,0);
590      pSetmComp(qq);
591    }
592    else
593    {
594      pIter(q);
595//      if (pGetComp(q) > k) pGetComp(q)--;
596    }
597  }
598  return result;
599}
600#endif
601
602void pDeleteComp(poly * p,int k)
603{
604  poly q;
605
606  while ((*p!=NULL) && (pGetComp(*p)==k)) pDeleteLm(p);
607  if (*p==NULL) return;
608  q = *p;
609  if (pGetComp(q)>k)
610  {
611    pDecrComp(q);
612    pSetmComp(q);
613  }
614  while (pNext(q)!=NULL)
615  {
616    if (pGetComp(pNext(q))==k)
617      pDeleteLm(&(pNext(q)));
618    else
619    {
620      pIter(q);
621      if (pGetComp(q)>k)
622      {
623        pDecrComp(q);
624        pSetmComp(q);
625      }
626    }
627  }
628}
629/*----------end of utilities for syzygies--------------*/
630
631/*2
632* pair has no common factor ? or is no polynomial
633*/
634BOOLEAN pHasNotCF(poly p1, poly p2)
635{
636
637  if (pGetComp(p1) > 0 || pGetComp(p2) > 0)
638    return FALSE;
639  int i = 1;
640  loop
641  {
642    if ((pGetExp(p1, i) > 0) && (pGetExp(p2, i) > 0))   return FALSE;
643    if (i == pVariables)                                return TRUE;
644    i++;
645  }
646}
647
648
649/*2
650*divides p1 by its leading monomial
651*/
652void pNorm(poly p1)
653{
654  poly h;
655  number k, c;
656
657  if (p1!=NULL)
658  {
659    if (!nIsOne(pGetCoeff(p1)))
660    {
661      nNormalize(pGetCoeff(p1));
662      k=pGetCoeff(p1);
663      c = nInit(1);
664      pSetCoeff0(p1,c);
665      h = pNext(p1);
666      while (h!=NULL)
667      {
668        c=nDiv(pGetCoeff(h),k);
669        if (!nIsOne(c)) nNormalize(c);
670        pSetCoeff(h,c);
671        pIter(h);
672      }
673      nDelete(&k);
674    }
675    else
676    {
677      if (nNormalize != nDummy2)
678      {
679        h = pNext(p1);
680        while (h!=NULL)
681        {
682          nNormalize(pGetCoeff(h));
683          pIter(h);
684        }
685      }
686    }
687  }
688}
689
690/*2
691*normalize all coeffizients
692*/
693void pNormalize(poly p)
694{
695  if (rField_has_simple_inverse()) return; /* Z/p, GF(p,n), R, long R/C */
696  while (p!=NULL)
697  {
698    nTest(pGetCoeff(p));
699    nNormalize(pGetCoeff(p));
700    pIter(p);
701  }
702}
703
704// splits p into polys with Exp(n) == 0 and Exp(n) != 0
705// Poly with Exp(n) != 0 is reversed
706static void pSplitAndReversePoly(poly p, int n, poly *non_zero, poly *zero)
707{
708  if (p == NULL)
709  {
710    *non_zero = NULL;
711    *zero = NULL;
712    return;
713  }
714  spolyrec sz;
715  poly z, n_z, next;
716  z = &sz;
717  n_z = NULL;
718
719  while(p != NULL)
720  {
721    next = pNext(p);
722    if (pGetExp(p, n) == 0)
723    {
724      pNext(z) = p;
725      pIter(z);
726    }
727    else
728    {
729      pNext(p) = n_z;
730      n_z = p;
731    }
732    p = next;
733  }
734  pNext(z) = NULL;
735  *zero = pNext(&sz);
736  *non_zero = n_z;
737  return;
738}
739
740/*3
741* substitute the n-th variable by 1 in p
742* destroy p
743*/
744static poly pSubst1 (poly p,int n)
745{
746  poly qq,result = NULL;
747  poly zero, non_zero;
748
749  // reverse, so that add is likely to be linear
750  pSplitAndReversePoly(p, n, &non_zero, &zero);
751
752  while (non_zero != NULL)
753  {
754    assume(pGetExp(non_zero, n) != 0);
755    qq = non_zero;
756    pIter(non_zero);
757    qq->next = NULL;
758    pSetExp(qq,n,0);
759    pSetm(qq);
760    result = pAdd(result,qq);
761  }
762  p = pAdd(result, zero);
763  pTest(p);
764  return p;
765}
766
767/*3
768* substitute the n-th variable by number e in p
769* destroy p
770*/
771static poly pSubst2 (poly p,int n, number e)
772{
773  assume( ! nIsZero(e) );
774  poly qq,result = NULL;
775  number nn, nm;
776  poly zero, non_zero;
777
778  // reverse, so that add is likely to be linear
779  pSplitAndReversePoly(p, n, &non_zero, &zero);
780
781  while (non_zero != NULL)
782  {
783    assume(pGetExp(non_zero, n) != 0);
784    qq = non_zero;
785    pIter(non_zero);
786    qq->next = NULL;
787    nPower(e, pGetExp(qq, n), &nn);
788    nm = nMult(nn, pGetCoeff(qq));
789    pSetCoeff(qq, nm);
790    nDelete(&nn);
791    pSetExp(qq, n, 0);
792    pSetm(qq);
793    result = pAdd(result,qq);
794  }
795  p = pAdd(result, zero);
796  pTest(p);
797  return p;
798}
799
800
801/* delete monoms whose n-th exponent is different from zero */
802poly pSubst0(poly p, int n)
803{
804  spolyrec res;
805  poly h = &res;
806  pNext(h) = p;
807
808  while (pNext(h)!=NULL)
809  {
810    if (pGetExp(pNext(h),n)!=0)
811    {
812      pDeleteLm(&pNext(h));
813    }
814    else
815    {
816      pIter(h);
817    }
818  }
819  pTest(pNext(&res));
820  return pNext(&res);
821}
822
823/*2
824* substitute the n-th variable by e in p
825* destroy p
826*/
827poly pSubst(poly p, int n, poly e)
828{
829  if (e == NULL) return pSubst0(p, n);
830
831  if (pIsConstant(e))
832  {
833    if (nIsOne(pGetCoeff(e))) return pSubst1(p,n);
834    else return pSubst2(p, n, pGetCoeff(e));
835  }
836
837  int exponent,i;
838  poly h, res, m;
839  Exponent_t *me,*ee;
840  number nu,nu1;
841
842  me=(Exponent_t *)omAlloc((pVariables+1)*sizeof(Exponent_t));
843  ee=(Exponent_t *)omAlloc((pVariables+1)*sizeof(Exponent_t));
844  if (e!=NULL) pGetExpV(e,ee);
845  res=NULL;
846  h=p;
847  while (h!=NULL)
848  {
849    if ((e!=NULL) || (pGetExp(h,n)==0))
850    {
851      m=pHead(h);
852      pGetExpV(m,me);
853      exponent=me[n];
854      me[n]=0;
855      for(i=pVariables;i>0;i--)
856        me[i]+=exponent*ee[i];
857      pSetExpV(m,me);
858      if (e!=NULL)
859      {
860        nPower(pGetCoeff(e),exponent,&nu);
861        nu1=nMult(pGetCoeff(m),nu);
862        nDelete(&nu);
863        pSetCoeff(m,nu1);
864      }
865      res=pAdd(res,m);
866    }
867    pDeleteLm(&h);
868  }
869  omFreeSize((ADDRESS)me,(pVariables+1)*sizeof(Exponent_t));
870  omFreeSize((ADDRESS)ee,(pVariables+1)*sizeof(Exponent_t));
871  return res;
872}
873
874BOOLEAN pCompareChain (poly p,poly p1,poly p2,poly lcm)
875{
876  int k, j;
877
878  if (lcm==NULL) return FALSE;
879
880  for (j=pVariables; j; j--)
881    if ( pGetExp(p,j) >  pGetExp(lcm,j)) return FALSE;
882  if ( pGetComp(p) !=  pGetComp(lcm)) return FALSE;
883  for (j=pVariables; j; j--)
884  {
885    if (pGetExp(p1,j)!=pGetExp(lcm,j))
886    {
887      if (pGetExp(p,j)!=pGetExp(lcm,j))
888      {
889        for (k=pVariables; k>j; k--)
890        {
891          if ((pGetExp(p,k)!=pGetExp(lcm,k))
892          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
893            return TRUE;
894        }
895        for (k=j-1; k; k--)
896        {
897          if ((pGetExp(p,k)!=pGetExp(lcm,k))
898          && (pGetExp(p2,k)!=pGetExp(lcm,k)))
899            return TRUE;
900        }
901        return FALSE;
902      }
903    }
904    else if (pGetExp(p2,j)!=pGetExp(lcm,j))
905    {
906      if (pGetExp(p,j)!=pGetExp(lcm,j))
907      {
908        for (k=pVariables; k>j; k--)
909        {
910          if ((pGetExp(p,k)!=pGetExp(lcm,k))
911          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
912            return TRUE;
913        }
914        for (k=j-1; k!=0 ; k--)
915        {
916          if ((pGetExp(p,k)!=pGetExp(lcm,k))
917          && (pGetExp(p1,k)!=pGetExp(lcm,k)))
918            return TRUE;
919        }
920        return FALSE;
921      }
922    }
923  }
924  return FALSE;
925}
Note: See TracBrowser for help on using the repository browser.