source: git/kernel/kspoly.cc @ 246bbb

spielwiese
Last change on this file since 246bbb was 16f511, checked in by Oleksandr Motsak <motsak@…>, 11 years ago
Fixed the usage of "config.h" (if defined HAVE_CONFIG_H)
  • Property mode set to 100644
File size: 20.4 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/*
5*  ABSTRACT -  Routines for Spoly creation and reductions
6*/
7
8// #define PDEBUG 2
9#ifdef HAVE_CONFIG_H
10#include "config.h"
11#endif /* HAVE_CONFIG_H */
12#include <kernel/mod2.h>
13#include <misc/options.h>
14#include <kernel/kutil.h>
15#include <coeffs/numbers.h>
16#include <polys/monomials/p_polys.h>
17#include <polys/templates/p_Procs.h>
18#include <polys/nc/nc.h>
19#ifdef KDEBUG
20#include <kernel/febase.h>
21#endif
22#ifdef HAVE_RINGS
23#include <kernel/polys.h>
24#endif
25
26#ifdef KDEBUG
27int red_count = 0;
28int create_count = 0;
29// define this if reductions are reported on TEST_OPT_DEBUG
30#define TEST_OPT_DEBUG_RED
31#endif
32
33/***************************************************************
34 *
35 * Reduces PR with PW
36 * Assumes PR != NULL, PW != NULL, Lm(PW) divides Lm(PR)
37 *
38 ***************************************************************/
39int ksReducePoly(LObject* PR,
40                 TObject* PW,
41                 poly spNoether,
42                 number *coef,
43                 kStrategy strat)
44{
45#ifdef KDEBUG
46  red_count++;
47#ifdef TEST_OPT_DEBUG_RED
48  if (TEST_OPT_DEBUG)
49  {
50    Print("Red %d:", red_count); PR->wrp(); Print(" with:");
51    PW->wrp();
52  }
53#endif
54#endif
55  int ret = 0;
56  ring tailRing = PR->tailRing;
57  assume(kTest_L(PR));
58  assume(kTest_T(PW));
59
60  poly p1 = PR->GetLmTailRing();   // p2 | p1
61  poly p2 = PW->GetLmTailRing();   // i.e. will reduce p1 with p2; lm = LT(p1) / LM(p2)
62  poly t2 = pNext(p2), lm = p1;    // t2 = p2 - LT(p2); really compute P = LC(p2)*p1 - LT(p1)/LM(p2)*p2
63  assume(p1 != NULL && p2 != NULL);// Attention, we have rings and there LC(p2) and LC(p1) are special
64  p_CheckPolyRing(p1, tailRing);
65  p_CheckPolyRing(p2, tailRing);
66
67  pAssume1(p2 != NULL && p1 != NULL &&
68           p_DivisibleBy(p2,  p1, tailRing));
69
70  pAssume1(p_GetComp(p1, tailRing) == p_GetComp(p2, tailRing) ||
71           (p_GetComp(p2, tailRing) == 0 &&
72            p_MaxComp(pNext(p2),tailRing) == 0));
73
74#ifdef HAVE_PLURAL
75  if (rIsPluralRing(currRing))
76  {
77    // for the time being: we know currRing==strat->tailRing
78    // no exp-bound checking needed
79    // (only needed if exp-bound(tailring)<exp-b(currRing))
80    if (PR->bucket!=NULL)  nc_kBucketPolyRed(PR->bucket, p2,coef);
81    else 
82    {
83      poly _p = (PR->t_p != NULL ? PR->t_p : PR->p);
84      assume(_p != NULL);
85      nc_PolyPolyRed(_p, p2,coef, currRing);
86      if (PR->t_p!=NULL) PR->t_p=_p; else PR->p=_p;
87      PR->pLength=0; // usually not used, GetpLength re-computes it if needed
88    }
89    return 0;
90  }
91#endif
92
93  if (t2==NULL)           // Divisor is just one term, therefore it will
94  {                       // just cancel the leading term
95    PR->LmDeleteAndIter();
96    if (coef != NULL) *coef = n_Init(1, tailRing);
97    return 0;
98  }
99
100  p_ExpVectorSub(lm, p2, tailRing); // Calculate the Monomial we must multiply to p2
101
102  if (tailRing != currRing)
103  {
104    // check that reduction does not violate exp bound
105    while (PW->max != NULL && !p_LmExpVectorAddIsOk(lm, PW->max, tailRing))
106    {
107      // undo changes of lm
108      p_ExpVectorAdd(lm, p2, tailRing);
109      if (strat == NULL) return 2;
110      if (! kStratChangeTailRing(strat, PR, PW)) return -1;
111      tailRing = strat->tailRing;
112      p1 = PR->GetLmTailRing();
113      p2 = PW->GetLmTailRing();
114      t2 = pNext(p2);
115      lm = p1;
116      p_ExpVectorSub(lm, p2, tailRing);
117      ret = 1;
118    }
119  }
120
121  // take care of coef buisness
122  if (! n_IsOne(pGetCoeff(p2), tailRing))
123  {
124    number bn = pGetCoeff(lm);
125    number an = pGetCoeff(p2);
126    int ct = ksCheckCoeff(&an, &bn, tailRing->cf);    // Calculate special LC
127    p_SetCoeff(lm, bn, tailRing);
128    if ((ct == 0) || (ct == 2))
129      PR->Tail_Mult_nn(an);
130    if (coef != NULL) *coef = an;
131    else n_Delete(&an, tailRing);
132  }
133  else
134  {
135    if (coef != NULL) *coef = n_Init(1, tailRing);
136  }
137
138
139  // and finally,
140  PR->Tail_Minus_mm_Mult_qq(lm, t2, PW->GetpLength() - 1, spNoether);
141  assume(PW->GetpLength() == pLength(PW->p != NULL ? PW->p : PW->t_p));
142  PR->LmDeleteAndIter();
143
144  // the following is commented out: shrinking
145#ifdef HAVE_SHIFTBBA_NONEXISTENT
146  if ( (currRing->isLPring) && (!strat->homog) )
147  {
148    // assume? h->p in currRing
149    PR->GetP();
150    poly qq = p_Shrink(PR->p, currRing->isLPring, currRing);
151    PR->Clear(); // does the right things
152    PR->p = qq; 
153    PR->t_p = NULL;
154    PR->SetShortExpVector();
155  }
156#endif
157 
158#if defined(KDEBUG) && defined(TEST_OPT_DEBUG_RED)
159  if (TEST_OPT_DEBUG)
160  {
161    Print(" to: "); PR->wrp(); Print("\n");
162  }
163#endif
164  return ret;
165}
166
167/***************************************************************
168 *
169 * Reduces PR with PW
170 * Assumes PR != NULL, PW != NULL, Lm(PW) divides Lm(PR)
171 *
172 ***************************************************************/
173int ksReducePolySig(LObject* PR,
174                 TObject* PW,
175                 long /*idx*/,
176                 poly spNoether,
177                 number *coef,
178                 kStrategy strat)
179{
180#ifdef KDEBUG
181  red_count++;
182#ifdef TEST_OPT_DEBUG_RED
183  if (TEST_OPT_DEBUG)
184  {
185    Print("Red %d:", red_count); PR->wrp(); Print(" with:");
186    PW->wrp();
187  }
188#endif
189#endif
190  int ret = 0;
191  ring tailRing = PR->tailRing;
192  assume(kTest_L(PR));
193  assume(kTest_T(PW));
194
195  // signature-based stuff:
196  // checking for sig-safeness first
197  // NOTE: This has to be done in the current ring
198  //
199  /**********************************************
200   *
201   * TODO:
202   * --------------------------------------------
203   * if strat->incremental
204   * Since we are subdividing lower index and
205   * current index reductions it is enough to
206   * look at the polynomial part of the signature
207   * for a check. This should speed-up checking
208   * a lot!
209   * if !strat->incremental
210   * We are not subdividing lower and current index
211   * due to the fact that we are using the induced
212   * Schreyer order
213   *
214   * nevertheless, this different behaviour is
215   * taken care of by is_sigsafe
216   * => one reduction procedure can be used for
217   * both, the incremental and the non-incremental
218   * attempt!
219   * --------------------------------------------
220   *
221   *********************************************/
222  //printf("COMPARE IDX: %ld -- %ld\n",idx,strat->currIdx);
223  if (!PW->is_sigsafe)
224  {
225    poly f1 = p_Copy(PR->GetLmCurrRing(),currRing);
226    poly f2 = PW->GetLmCurrRing();
227    poly sigMult = pCopy(PW->sig);   // copy signature of reducer
228    p_ExpVectorSub(f1, f2, currRing); // Calculate the Monomial we must multiply to p2
229//#if 1
230#ifdef DEBUGF5
231    printf("IN KSREDUCEPOLYSIG: \n");
232    pWrite(pHead(f1));
233    pWrite(pHead(f2));
234    pWrite(sigMult);
235    printf("--------------\n");
236#endif
237    sigMult = pp_Mult_qq(f1,sigMult,currRing);
238//#if 1
239#ifdef DEBUGF5
240    printf("------------------- IN KSREDUCEPOLYSIG: --------------------\n");
241    pWrite(pHead(f1));
242    pWrite(pHead(f2));
243    pWrite(sigMult);
244    pWrite(PR->sig);
245    printf("--------------\n");
246#endif
247    int sigSafe = p_LmCmp(PR->sig,sigMult,currRing);
248    // now we can delete the copied polynomial data used for checking for
249    // sig-safeness of the reduction step
250//#if 1
251#ifdef DEBUGF5
252    printf("%d -- %d sig\n",sigSafe,PW->is_sigsafe);
253
254#endif
255    pDelete(&f1);
256    pDelete(&sigMult);
257    // go on with the computations only if the signature of p2 is greater than the
258    // signature of fm*p1
259    if(sigSafe != 1)
260    { 
261      PR->is_redundant = TRUE;
262      return 3;
263    }
264    PW->is_sigsafe  = TRUE;
265  }
266  PR->is_redundant = FALSE;
267  poly p1 = PR->GetLmTailRing();   // p2 | p1
268  poly p2 = PW->GetLmTailRing();   // i.e. will reduce p1 with p2; lm = LT(p1) / LM(p2)
269  poly t2 = pNext(p2), lm = p1;    // t2 = p2 - LT(p2); really compute P = LC(p2)*p1 - LT(p1)/LM(p2)*p2
270  assume(p1 != NULL && p2 != NULL);// Attention, we have rings and there LC(p2) and LC(p1) are special
271  p_CheckPolyRing(p1, tailRing);
272  p_CheckPolyRing(p2, tailRing);
273
274  pAssume1(p2 != NULL && p1 != NULL &&
275      p_DivisibleBy(p2,  p1, tailRing));
276
277  pAssume1(p_GetComp(p1, tailRing) == p_GetComp(p2, tailRing) ||
278      (p_GetComp(p2, tailRing) == 0 &&
279       p_MaxComp(pNext(p2),tailRing) == 0));
280
281#ifdef HAVE_PLURAL
282  if (rIsPluralRing(currRing))
283  {
284    // for the time being: we know currRing==strat->tailRing
285    // no exp-bound checking needed
286    // (only needed if exp-bound(tailring)<exp-b(currRing))
287    if (PR->bucket!=NULL)  nc_kBucketPolyRed(PR->bucket, p2,coef);
288    else 
289    {
290      poly _p = (PR->t_p != NULL ? PR->t_p : PR->p);
291      assume(_p != NULL);
292      nc_PolyPolyRed(_p, p2, coef, currRing);
293      if (PR->t_p!=NULL) PR->t_p=_p; else PR->p=_p;
294      PR->pLength=0; // usaully not used, GetpLength re-comoutes it if needed
295    }
296    return 0;
297  }
298#endif
299
300  if (t2==NULL)           // Divisor is just one term, therefore it will
301  {                       // just cancel the leading term
302    PR->LmDeleteAndIter();
303    if (coef != NULL) *coef = n_Init(1, tailRing);
304    return 0;
305  }
306
307  p_ExpVectorSub(lm, p2, tailRing); // Calculate the Monomial we must multiply to p2
308
309  if (tailRing != currRing)
310  {
311    // check that reduction does not violate exp bound
312    while (PW->max != NULL && !p_LmExpVectorAddIsOk(lm, PW->max, tailRing))
313    {
314      // undo changes of lm
315      p_ExpVectorAdd(lm, p2, tailRing);
316      if (strat == NULL) return 2;
317      if (! kStratChangeTailRing(strat, PR, PW)) return -1;
318      tailRing = strat->tailRing;
319      p1 = PR->GetLmTailRing();
320      p2 = PW->GetLmTailRing();
321      t2 = pNext(p2);
322      lm = p1;
323      p_ExpVectorSub(lm, p2, tailRing);
324      ret = 1;
325    }
326  }
327
328  // take care of coef buisness
329  if (! n_IsOne(pGetCoeff(p2), tailRing))
330  {
331    number bn = pGetCoeff(lm);
332    number an = pGetCoeff(p2);
333    int ct = ksCheckCoeff(&an, &bn, tailRing->cf);    // Calculate special LC
334    p_SetCoeff(lm, bn, tailRing);
335    if ((ct == 0) || (ct == 2))
336      PR->Tail_Mult_nn(an);
337    if (coef != NULL) *coef = an;
338    else n_Delete(&an, tailRing);
339  }
340  else
341  {
342    if (coef != NULL) *coef = n_Init(1, tailRing);
343  }
344
345
346  // and finally,
347  PR->Tail_Minus_mm_Mult_qq(lm, t2, PW->GetpLength() - 1, spNoether);
348  assume(PW->GetpLength() == pLength(PW->p != NULL ? PW->p : PW->t_p));
349  PR->LmDeleteAndIter();
350
351  // the following is commented out: shrinking
352#ifdef HAVE_SHIFTBBA_NONEXISTENT
353  if ( (currRing->isLPring) && (!strat->homog) )
354  {
355    // assume? h->p in currRing
356    PR->GetP();
357    poly qq = p_Shrink(PR->p, currRing->isLPring, currRing);
358    PR->Clear(); // does the right things
359    PR->p = qq; 
360    PR->t_p = NULL;
361    PR->SetShortExpVector();
362  }
363#endif
364
365#if defined(KDEBUG) && defined(TEST_OPT_DEBUG_RED)
366  if (TEST_OPT_DEBUG)
367  {
368    Print(" to: "); PR->wrp(); Print("\n");
369  }
370#endif
371  return ret;
372}
373
374/***************************************************************
375 *
376 * Creates S-Poly of p1 and p2
377 *
378 *
379 ***************************************************************/
380void ksCreateSpoly(LObject* Pair,   poly spNoether,
381                   int use_buckets, ring tailRing,
382                   poly m1, poly m2, TObject** R)
383{
384#ifdef KDEBUG
385  create_count++;
386#endif
387  assume(kTest_L(Pair));
388  poly p1 = Pair->p1;
389  poly p2 = Pair->p2;
390  Pair->tailRing = tailRing;
391
392  assume(p1 != NULL);
393  assume(p2 != NULL);
394  assume(tailRing != NULL);
395
396  poly a1 = pNext(p1), a2 = pNext(p2);
397  number lc1 = pGetCoeff(p1), lc2 = pGetCoeff(p2);
398  int co=0/*, ct = ksCheckCoeff(&lc1, &lc2, currRing->cf)*/; // gcd and zero divisors
399  (void) ksCheckCoeff(&lc1, &lc2, currRing->cf);
400
401  int l1=0, l2=0;
402
403  if (p_GetComp(p1, currRing)!=p_GetComp(p2, currRing))
404  {
405    if (p_GetComp(p1, currRing)==0)
406    {
407      co=1;
408      p_SetCompP(p1,p_GetComp(p2, currRing), currRing, tailRing);
409    }
410    else
411    {
412      co=2;
413      p_SetCompP(p2, p_GetComp(p1, currRing), currRing, tailRing);
414    }
415  }
416
417  // get m1 = LCM(LM(p1), LM(p2))/LM(p1)
418  //     m2 = LCM(LM(p1), LM(p2))/LM(p2)
419  if (m1 == NULL)
420    k_GetLeadTerms(p1, p2, currRing, m1, m2, tailRing);
421
422  pSetCoeff0(m1, lc2);
423  pSetCoeff0(m2, lc1);  // and now, m1 * LT(p1) == m2 * LT(p2)
424
425  if (R != NULL)
426  {
427    if (Pair->i_r1 == -1)
428    {
429      l1 = pLength(p1) - 1;
430    }
431    else
432    {
433      l1 = (R[Pair->i_r1])->GetpLength() - 1;
434    }
435    if (Pair->i_r2 == -1)
436    {
437      l2 = pLength(p2) - 1;
438    }
439    else
440    {
441      l2 = (R[Pair->i_r2])->GetpLength() - 1;
442    }
443  }
444
445  // get m2 * a2
446  if (spNoether != NULL)
447  {
448    l2 = -1;
449    a2 = tailRing->p_Procs->pp_Mult_mm_Noether(a2, m2, spNoether, l2, tailRing);
450    assume(l2 == pLength(a2));
451  }
452  else
453    a2 = tailRing->p_Procs->pp_Mult_mm(a2, m2, tailRing);
454#ifdef HAVE_RINGS
455  if (!(rField_is_Domain(currRing))) l2 = pLength(a2);
456#endif
457
458  Pair->SetLmTail(m2, a2, l2, use_buckets, tailRing);
459
460  // get m2*a2 - m1*a1
461  Pair->Tail_Minus_mm_Mult_qq(m1, a1, l1, spNoether);
462
463  // Clean-up time
464  Pair->LmDeleteAndIter();
465  p_LmDelete(m1, tailRing);
466
467  if (co != 0)
468  {
469    if (co==1)
470    {
471      p_SetCompP(p1,0, currRing, tailRing);
472    }
473    else
474    {
475      p_SetCompP(p2,0, currRing, tailRing);
476    }
477  }
478
479  // the following is commented out: shrinking
480#ifdef HAVE_SHIFTBBA_NONEXISTENT
481  if (currRing->isLPring)
482  {
483    // assume? h->p in currRing
484    Pair->GetP();
485    poly qq = p_Shrink(Pair->p, currRing->isLPring, currRing);
486    Pair->Clear(); // does the right things
487    Pair->p = qq; 
488    Pair->t_p = NULL;
489    Pair->SetShortExpVector();
490  }
491#endif
492
493}
494
495int ksReducePolyTail(LObject* PR, TObject* PW, poly Current, poly spNoether)
496{
497  BOOLEAN ret;
498  number coef;
499  poly Lp =     PR->GetLmCurrRing();
500  poly Save =   PW->GetLmCurrRing();
501
502  assume(kTest_L(PR));
503  assume(kTest_T(PW));
504  pAssume(pIsMonomOf(Lp, Current));
505
506  assume(Lp != NULL && Current != NULL && pNext(Current) != NULL);
507  assume(PR->bucket == NULL);
508
509  LObject Red(pNext(Current), PR->tailRing);
510  TObject With(PW, Lp == Save);
511
512  pAssume(!pHaveCommonMonoms(Red.p, With.p));
513  ret = ksReducePoly(&Red, &With, spNoether, &coef);
514
515  if (!ret)
516  {
517    if (! n_IsOne(coef, currRing))
518    {
519      pNext(Current) = NULL;
520      if (Current == PR->p && PR->t_p != NULL)
521        pNext(PR->t_p) = NULL;
522      PR->Mult_nn(coef);
523    }
524
525    n_Delete(&coef, currRing);
526    pNext(Current) = Red.GetLmTailRing();
527    if (Current == PR->p && PR->t_p != NULL)
528      pNext(PR->t_p) = pNext(Current);
529  }
530
531  if (Lp == Save)
532    With.Delete();
533
534  // the following is commented out: shrinking
535#ifdef HAVE_SHIFTBBA_NONEXISTENT
536  if (currRing->isLPring)
537  {
538    // assume? h->p in currRing
539    PR->GetP();
540    poly qq = p_Shrink(PR->p, currRing->isLPring, currRing);
541    PR->Clear(); // does the right things
542    PR->p = qq; 
543    PR->t_p = NULL;
544    PR->SetShortExpVector();
545  }
546#endif
547
548  return ret;
549}
550
551/***************************************************************
552 *
553 * Auxillary Routines
554 *
555 *
556 ***************************************************************/
557
558/*2
559* creates the leading term of the S-polynomial of p1 and p2
560* do not destroy p1 and p2
561* remarks:
562*   1. the coefficient is 0 (nNew)
563*   1. a) in the case of coefficient ring, the coefficient is calculated
564*   2. pNext is undefined
565*/
566//static void bbb() { int i=0; }
567poly ksCreateShortSpoly(poly p1, poly p2, ring tailRing)
568{
569  poly a1 = pNext(p1), a2 = pNext(p2);
570  long c1=p_GetComp(p1, currRing),c2=p_GetComp(p2, currRing);
571  long c;
572  poly m1,m2;
573  number t1 = NULL,t2 = NULL;
574  int cm,i;
575  BOOLEAN equal;
576
577#ifdef HAVE_RINGS
578  BOOLEAN is_Ring=rField_is_Ring(currRing);
579  number lc1 = pGetCoeff(p1), lc2 = pGetCoeff(p2);
580  if (is_Ring)
581  {
582    ksCheckCoeff(&lc1, &lc2, currRing->cf); // gcd and zero divisors
583    if (a1 != NULL) t2 = nMult(pGetCoeff(a1),lc2);
584    if (a2 != NULL) t1 = nMult(pGetCoeff(a2),lc1);
585    while (a1 != NULL && nIsZero(t2))
586    {
587      pIter(a1);
588      nDelete(&t2);
589      if (a1 != NULL) t2 = nMult(pGetCoeff(a1),lc2);
590    }
591    while (a2 != NULL && nIsZero(t1))
592    {
593      pIter(a2);
594      nDelete(&t1);
595      if (a2 != NULL) t1 = nMult(pGetCoeff(a2),lc1);
596    }
597  }
598#endif
599
600  if (a1==NULL)
601  {
602    if(a2!=NULL)
603    {
604      m2=p_Init(currRing);
605x2:
606      for (i = (currRing->N); i; i--)
607      {
608        c = p_GetExpDiff(p1, p2,i, currRing);
609        if (c>0)
610        {
611          p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)),currRing);
612        }
613        else
614        {
615          p_SetExp(m2,i,p_GetExp(a2,i,tailRing),currRing);
616        }
617      }
618      if ((c1==c2)||(c2!=0))
619      {
620        p_SetComp(m2,p_GetComp(a2,tailRing), currRing);
621      }
622      else
623      {
624        p_SetComp(m2,c1,currRing);
625      }
626      p_Setm(m2, currRing);
627#ifdef HAVE_RINGS
628      if (is_Ring)
629      {
630          nDelete(&lc1);
631          nDelete(&lc2);
632          nDelete(&t2);
633          pSetCoeff0(m2, t1);
634      }
635      else
636#endif
637        nNew(&(pGetCoeff(m2)));
638      return m2;
639    }
640    else
641    {
642#ifdef HAVE_RINGS
643      if (is_Ring)
644      {
645        nDelete(&lc1);
646        nDelete(&lc2);
647        nDelete(&t1);
648        nDelete(&t2);
649      }
650#endif
651      return NULL;
652    }
653  }
654  if (a2==NULL)
655  {
656    m1=p_Init(currRing);
657x1:
658    for (i = (currRing->N); i; i--)
659    {
660      c = p_GetExpDiff(p2, p1,i,currRing);
661      if (c>0)
662      {
663        p_SetExp(m1,i,(c+p_GetExp(a1,i, tailRing)),currRing);
664      }
665      else
666      {
667        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
668      }
669    }
670    if ((c1==c2)||(c1!=0))
671    {
672      p_SetComp(m1,p_GetComp(a1,tailRing),currRing);
673    }
674    else
675    {
676      p_SetComp(m1,c2,currRing);
677    }
678    p_Setm(m1, currRing);
679#ifdef HAVE_RINGS
680    if (is_Ring)
681    {
682      pSetCoeff0(m1, t2);
683      nDelete(&lc1);
684      nDelete(&lc2);
685      nDelete(&t1);
686    }
687    else
688#endif
689      nNew(&(pGetCoeff(m1)));
690    return m1;
691  }
692  m1 = p_Init(currRing);
693  m2 = p_Init(currRing);
694  loop
695  {
696    for (i = (currRing->N); i; i--)
697    {
698      c = p_GetExpDiff(p1, p2,i,currRing);
699      if (c > 0)
700      {
701        p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)), currRing);
702        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
703      }
704      else
705      {
706        p_SetExp(m1,i,(p_GetExp(a1,i,tailRing)-c), currRing);
707        p_SetExp(m2,i,p_GetExp(a2,i, tailRing), currRing);
708      }
709    }
710    if(c1==c2)
711    {
712      p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
713      p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
714    }
715    else
716    {
717      if(c1!=0)
718      {
719        p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
720        p_SetComp(m2,c1, currRing);
721      }
722      else
723      {
724        p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
725        p_SetComp(m1,c2, currRing);
726      }
727    }
728    p_Setm(m1,currRing);
729    p_Setm(m2,currRing);
730    cm = p_LmCmp(m1, m2,currRing);
731    if (cm!=0)
732    {
733      if(cm==1)
734      {
735        p_LmFree(m2,currRing);
736#ifdef HAVE_RINGS
737        if (is_Ring)
738        {
739          pSetCoeff0(m1, t2);
740          nDelete(&lc1);
741          nDelete(&lc2);
742          nDelete(&t1);
743        }
744        else
745#endif
746          nNew(&(pGetCoeff(m1)));
747        return m1;
748      }
749      else
750      {
751        p_LmFree(m1,currRing);
752#ifdef HAVE_RINGS
753        if (is_Ring)
754        {
755          pSetCoeff0(m2, t1);
756          nDelete(&lc1);
757          nDelete(&lc2);
758          nDelete(&t2);
759        }
760        else
761#endif
762          nNew(&(pGetCoeff(m2)));
763        return m2;
764      }
765    }
766#ifdef HAVE_RINGS
767    if (is_Ring)
768    {
769      equal = nEqual(t1,t2);
770    }
771    else
772#endif
773    {
774      t1 = nMult(pGetCoeff(a2),pGetCoeff(p1));
775      t2 = nMult(pGetCoeff(a1),pGetCoeff(p2));
776      equal = nEqual(t1,t2);
777      nDelete(&t2);
778      nDelete(&t1);
779    }
780    if (!equal)
781    {
782      p_LmFree(m2,currRing);
783#ifdef HAVE_RINGS
784      if (is_Ring)
785      {
786          pSetCoeff0(m1, nSub(t1, t2));
787          nDelete(&lc1);
788          nDelete(&lc2);
789          nDelete(&t1);
790          nDelete(&t2);
791      }
792      else
793#endif
794        nNew(&(pGetCoeff(m1)));
795      return m1;
796    }
797    pIter(a1);
798    pIter(a2);
799#ifdef HAVE_RINGS
800    if (is_Ring)
801    {
802      if (a2 != NULL)
803      {
804        nDelete(&t1);
805        t1 = nMult(pGetCoeff(a2),lc1);
806      }
807      if (a1 != NULL)
808      {
809        nDelete(&t2);
810        t2 = nMult(pGetCoeff(a1),lc2);
811      }
812      while ((a1 != NULL) && nIsZero(t2))
813      {
814        pIter(a1);
815        if (a1 != NULL)
816        {
817          nDelete(&t2);
818          t2 = nMult(pGetCoeff(a1),lc2);
819        }
820      }
821      while ((a2 != NULL) && nIsZero(t1))
822      {
823        pIter(a2);
824        if (a2 != NULL)
825        {
826          nDelete(&t1);
827          t1 = nMult(pGetCoeff(a2),lc1);
828        }
829      }
830    }
831#endif
832    if (a2==NULL)
833    {
834      p_LmFree(m2,currRing);
835      if (a1==NULL)
836      {
837#ifdef HAVE_RINGS
838        if (is_Ring)
839        {
840          nDelete(&lc1);
841          nDelete(&lc2);
842          nDelete(&t1);
843          nDelete(&t2);
844        }
845#endif
846        p_LmFree(m1,currRing);
847        return NULL;
848      }
849      goto x1;
850    }
851    if (a1==NULL)
852    {
853      p_LmFree(m1,currRing);
854      goto x2;
855    }
856  }
857}
Note: See TracBrowser for help on using the repository browser.