source: git/kernel/GBEngine/kspoly.cc @ 85d7d3

fieker-DuValspielwiese
Last change on this file since 85d7d3 was 85d7d3, checked in by Karim Abou Zeid <karim23697@…>, 6 years ago
Merge branch 'spielwiese' into letterplace_kernel_multiplication
  • Property mode set to 100644
File size: 37.5 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
10
11
12#include "kernel/mod2.h"
13#include "misc/options.h"
14#include "kernel/GBEngine/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 HAVE_RINGS
20#include "kernel/polys.h"
21#endif
22#include "kernel/GBEngine/shiftgb.h"
23
24#ifdef KDEBUG
25int red_count = 0;
26int create_count = 0;
27// define this if reductions are reported on TEST_OPT_DEBUG
28#define TEST_OPT_DEBUG_RED
29#endif
30
31/***************************************************************
32 *
33 * Reduces PR with PW
34 * Assumes PR != NULL, PW != NULL, Lm(PW) divides Lm(PR)
35 *
36 * returns 0: okay
37 *         1: tailRing changed
38 *         -1: cannot change tailRing
39 *         2: cannot change tailRing: strat==NULL
40 *
41 ***************************************************************/
42int ksReducePoly(LObject* PR,
43                 TObject* PW,
44                 poly spNoether,
45                 number *coef,
46                 kStrategy strat)
47{
48#ifdef KDEBUG
49  red_count++;
50#ifdef TEST_OPT_DEBUG_RED
51//  if (TEST_OPT_DEBUG)
52//  {
53//    Print("Red %d:", red_count); PR->wrp(); Print(" with:");
54//    PW->wrp();
55//    //printf("\necart(PR)-ecart(PW): %i\n",PR->ecart-PW->ecart);
56//    //pWrite(PR->p);
57//  }
58#endif
59#endif
60  int ret = 0;
61  ring tailRing = PR->tailRing;
62  kTest_L(PR);
63  kTest_T(PW);
64
65  poly p1 = PR->GetLmTailRing();   // p2 | p1
66  poly p2 = PW->GetLmTailRing();   // i.e. will reduce p1 with p2; lm = LT(p1) / LM(p2)
67  poly t2 = pNext(p2), lm = p1;    // t2 = p2 - LT(p2); really compute P = LC(p2)*p1 - LT(p1)/LM(p2)*p2
68  assume(p1 != NULL && p2 != NULL);// Attention, we have rings and there LC(p2) and LC(p1) are special
69  p_CheckPolyRing(p1, tailRing);
70  p_CheckPolyRing(p2, tailRing);
71
72  pAssume1(p2 != NULL && p1 != NULL &&
73           p_DivisibleBy(p2,  p1, tailRing));
74
75  pAssume1(p_GetComp(p1, tailRing) == p_GetComp(p2, tailRing) ||
76           (p_GetComp(p2, tailRing) == 0 &&
77            p_MaxComp(pNext(p2),tailRing) == 0));
78
79#ifdef HAVE_PLURAL
80  if (rIsPluralRing(currRing))
81  {
82    // for the time being: we know currRing==strat->tailRing
83    // no exp-bound checking needed
84    // (only needed if exp-bound(tailring)<exp-b(currRing))
85    if (PR->bucket!=NULL)  nc_kBucketPolyRed_Z(PR->bucket, p2,coef);
86    else
87    {
88      poly _p = (PR->t_p != NULL ? PR->t_p : PR->p);
89      assume(_p != NULL);
90      nc_PolyPolyRed(_p, p2,coef, currRing);
91      if (PR->t_p!=NULL) PR->t_p=_p; else PR->p=_p;
92      PR->pLength=0; // usually not used, GetpLength re-computes it if needed
93    }
94    return 0;
95  }
96#endif
97
98  if (t2==NULL)           // Divisor is just one term, therefore it will
99  {                       // just cancel the leading term
100    PR->LmDeleteAndIter();
101    if (coef != NULL) *coef = n_Init(1, tailRing->cf);
102    return 0;
103  }
104
105  p_ExpVectorSub(lm, p2, tailRing); // Calculate the Monomial we must multiply to p2
106
107  //if (tailRing != currRing)
108  {
109    // check that reduction does not violate exp bound
110    while (PW->max_exp != NULL && !p_LmExpVectorAddIsOk(lm, PW->max_exp, tailRing))
111    {
112      // undo changes of lm
113      p_ExpVectorAdd(lm, p2, tailRing);
114      if (strat == NULL) return 2;
115      if (! kStratChangeTailRing(strat, PR, PW)) return -1;
116      tailRing = strat->tailRing;
117      p1 = PR->GetLmTailRing();
118      p2 = PW->GetLmTailRing();
119      t2 = pNext(p2);
120      lm = p1;
121      p_ExpVectorSub(lm, p2, tailRing);
122      ret = 1;
123    }
124  }
125
126  poly lmRight;
127  if (tailRing->isLPring) {
128    k_SplitFrame(lm, lmRight, PW->shift + 1, tailRing);
129  }
130
131  // take care of coef buisness
132  if (! n_IsOne(pGetCoeff(p2), tailRing->cf))
133  {
134    number bn = pGetCoeff(lm);
135    number an = pGetCoeff(p2);
136    int ct = ksCheckCoeff(&an, &bn, tailRing->cf);    // Calculate special LC
137    p_SetCoeff(lm, bn, tailRing);
138    if (tailRing->isLPring) pSetCoeff0(p1, bn); // lm doesn't point to p1 anymore, if the coef was a pointer, it has been deleted
139    if ((ct == 0) || (ct == 2))
140      PR->Tail_Mult_nn(an);
141    if (coef != NULL) *coef = an;
142    else n_Delete(&an, tailRing->cf);
143  }
144  else
145  {
146    if (coef != NULL) *coef = n_Init(1, tailRing->cf);
147  }
148
149
150  // and finally,
151  if (tailRing->isLPring) {
152    PR->Tail_Minus_mm_Mult_qq(lm, tailRing->p_Procs->pp_Mult_mm(t2, lmRight, tailRing), pLength(t2), spNoether);
153  } else {
154    PR->Tail_Minus_mm_Mult_qq(lm, t2, pLength(t2) /*PW->GetpLength() - 1*/, spNoether);
155  }
156  assume(PW->GetpLength() == pLength(PW->p != NULL ? PW->p : PW->t_p));
157  PR->LmDeleteAndIter();
158
159  return ret;
160}
161
162/* Computes a reduction of the lead coefficient only. We have already tested
163 * that lm(PW) divides lm(PR), but lc(PW) does not divide lc(PR). We have
164 * computed division with remainder on the lead coefficients, parameter
165 * coef is the corresponding multiple for PW we need. The new lead
166 * coefficient, i.e. the remainder of lc division has already been
167 * set before calling this function. We do not drop the lead term at
168 * the end, but keep the adjusted, correct lead term. */
169int ksReducePolyLC(LObject* PR,
170                 TObject* PW,
171                 poly spNoether,
172                 number *coef,
173                 kStrategy strat)
174{
175#ifdef KDEBUG
176  red_count++;
177#ifdef TEST_OPT_DEBUG_RED
178//  if (TEST_OPT_DEBUG)
179//  {
180//    Print("Red %d:", red_count); PR->wrp(); Print(" with:");
181//    PW->wrp();
182//    //printf("\necart(PR)-ecart(PW): %i\n",PR->ecart-PW->ecart);
183//    //pWrite(PR->p);
184//  }
185#endif
186#endif
187  /* printf("PR->P: ");
188   * p_Write(PR->p, currRing, PR->tailRing); */
189  int ret = 0;
190  ring tailRing = PR->tailRing;
191  kTest_L(PR);
192  kTest_T(PW);
193
194  poly p1 = PR->GetLmTailRing();   // p2 | p1
195  poly p2 = PW->GetLmTailRing();   // i.e. will reduce p1 with p2; lm = LT(p1) / LM(p2)
196  poly t2 = pNext(p2), lm = p1;    // t2 = p2 - LT(p2); really compute P = LC(p2)*p1 - LT(p1)/LM(p2)*p2
197  assume(p1 != NULL && p2 != NULL);// Attention, we have rings and there LC(p2) and LC(p1) are special
198  p_CheckPolyRing(p1, tailRing);
199  p_CheckPolyRing(p2, tailRing);
200
201  pAssume1(p2 != NULL && p1 != NULL &&
202           p_DivisibleBy(p2,  p1, tailRing));
203
204  pAssume1(p_GetComp(p1, tailRing) == p_GetComp(p2, tailRing) ||
205           (p_GetComp(p2, tailRing) == 0 &&
206            p_MaxComp(pNext(p2),tailRing) == 0));
207
208#ifdef HAVE_PLURAL
209  if (rIsPluralRing(currRing))
210  {
211    // for the time being: we know currRing==strat->tailRing
212    // no exp-bound checking needed
213    // (only needed if exp-bound(tailring)<exp-b(currRing))
214    if (PR->bucket!=NULL)  nc_kBucketPolyRed_Z(PR->bucket, p2,coef);
215    else
216    {
217      poly _p = (PR->t_p != NULL ? PR->t_p : PR->p);
218      assume(_p != NULL);
219      nc_PolyPolyRed(_p, p2,coef, currRing);
220      if (PR->t_p!=NULL) PR->t_p=_p; else PR->p=_p;
221      PR->pLength=0; // usually not used, GetpLength re-computes it if needed
222    }
223    return 0;
224  }
225#endif
226  /* printf("PR->P2: ");
227   * pWrite(PR->p); */
228
229  /* this part never happens since t2 = p2 and NOT t2 = pNext(p2) */
230  /* if (t2==NULL)           // Divisor is just one term, therefore it will
231   * {                       // just cancel the leading term
232   *   PR->LmDeleteAndIter();
233   *   if (coef != NULL) *coef = n_Init(1, tailRing->cf);
234   *   return 0;
235   * } */
236
237  p_ExpVectorSub(lm, p2, tailRing); // Calculate the Monomial we must multiply to p2
238  p_SetCoeff(lm, n_Init(1, tailRing), tailRing);
239  //if (tailRing != currRing)
240  {
241    // check that reduction does not violate exp bound
242    while (PW->max_exp != NULL && !p_LmExpVectorAddIsOk(lm, PW->max_exp, tailRing))
243    {
244      // undo changes of lm
245      p_ExpVectorAdd(lm, p2, tailRing);
246      if (strat == NULL) return 2;
247      /* if (! kStratChangeTailRing(strat, PR, PW)) return -1; */
248      tailRing = strat->tailRing;
249      p1 = PR->GetLmTailRing();
250      p2 = PW->GetLmTailRing();
251      t2 = pNext(p2);
252      lm = p1;
253      p_ExpVectorSub(lm, p2, tailRing);
254      ret = 1;
255    }
256  }
257
258  // take care of coef buisness
259  // we have done this already in redRingNew
260  /* if (! n_IsOne(pGetCoeff(p2), tailRing->cf))
261   * {
262   *   number bn = pGetCoeff(lm);
263   *   number an = pGetCoeff(p2);
264   *   int ct = ksCheckCoeff(&an, &bn, tailRing->cf);    // Calculate special LC
265   *   p_SetCoeff(lm, bn, tailRing);
266   *   if ((ct == 0) || (ct == 2))
267   *     PR->Tail_Mult_nn(an);
268   *   if (coef != NULL) *coef = an;
269   *   else n_Delete(&an, tailRing->cf);
270   * }
271   * else
272   * {
273   *   if (coef != NULL) *coef = n_Init(1, tailRing->cf);
274   * } */
275
276  // and finally,
277  /* printf("NOW WE REDUCE:\n");
278   * p_Write(lm, tailRing);
279   * p_Write(p2, tailRing); */
280  /* we use p2, since then lm(p2) is the gcd lead monomial and we are done! */
281  PR->Tail_Minus_mm_Mult_qq(lm, p2, pLength(p2) /*PW->GetpLength() - 1*/, spNoether);
282  /* PR->Tail_Minus_mm_Mult_qq(lm, t2, pLength(t2) [>PW->GetpLength() - 1<], spNoether); */
283  assume(PW->GetpLength() == pLength(PW->p != NULL ? PW->p : PW->t_p));
284
285  PR->LmDeleteAndIter();
286  p_SetCoeff(PR->p, *coef, currRing);
287  /* p_SetCoeff(PR->t_p, *coef, tailRing); */
288
289
290  // the following is commented out: shrinking
291#ifdef HAVE_SHIFTBBA_NONEXISTENT
292  if ( (currRing->isLPring) && (!strat->homog) )
293  {
294    // assume? h->p in currRing
295    PR->GetP();
296    poly qq = p_Shrink(PR->p, currRing->isLPring, currRing);
297    PR->Clear(); // does the right things
298    PR->p = qq;
299    PR->t_p = NULL;
300    PR->SetShortExpVector();
301  }
302#endif
303
304#if defined(KDEBUG) && defined(TEST_OPT_DEBUG_RED)
305  if (TEST_OPT_DEBUG)
306  {
307    Print(" to: "); PR->wrp(); Print("\n");
308    //printf("\nt^%i ", PR->ecart);pWrite(pHead(PR->p));
309  }
310#endif
311  return ret;
312}
313
314int ksReducePolyBound(LObject* PR,
315                 TObject* PW,
316                 int bound,
317                 poly spNoether,
318                 number *coef,
319                 kStrategy strat)
320{
321#ifdef KDEBUG
322  red_count++;
323#ifdef TEST_OPT_DEBUG_RED
324  if (TEST_OPT_DEBUG)
325  {
326    Print("Red %d:", red_count); PR->wrp(); Print(" with:");
327    PW->wrp();
328    //printf("\necart(PR)-ecart(PW): %i\n",PR->ecart-PW->ecart);
329    //pWrite(PR->p);
330  }
331#endif
332#endif
333  int ret = 0;
334  ring tailRing = PR->tailRing;
335  kTest_L(PR);
336  kTest_T(PW);
337
338  poly p1 = PR->GetLmTailRing();   // p2 | p1
339  poly p2 = PW->GetLmTailRing();   // i.e. will reduce p1 with p2; lm = LT(p1) / LM(p2)
340  poly t2 = pNext(p2), lm = p1;    // t2 = p2 - LT(p2); really compute P = LC(p2)*p1 - LT(p1)/LM(p2)*p2
341  assume(p1 != NULL && p2 != NULL);// Attention, we have rings and there LC(p2) and LC(p1) are special
342  p_CheckPolyRing(p1, tailRing);
343  p_CheckPolyRing(p2, tailRing);
344
345  pAssume1(p2 != NULL && p1 != NULL &&
346           p_DivisibleBy(p2,  p1, tailRing));
347
348  pAssume1(p_GetComp(p1, tailRing) == p_GetComp(p2, tailRing) ||
349           (p_GetComp(p2, tailRing) == 0 &&
350            p_MaxComp(pNext(p2),tailRing) == 0));
351
352#ifdef HAVE_PLURAL
353  if (rIsPluralRing(currRing))
354  {
355    // for the time being: we know currRing==strat->tailRing
356    // no exp-bound checking needed
357    // (only needed if exp-bound(tailring)<exp-b(currRing))
358    if (PR->bucket!=NULL)  nc_kBucketPolyRed_Z(PR->bucket, p2,coef);
359    else
360    {
361      poly _p = (PR->t_p != NULL ? PR->t_p : PR->p);
362      assume(_p != NULL);
363      nc_PolyPolyRed(_p, p2,coef, currRing);
364      if (PR->t_p!=NULL) PR->t_p=_p; else PR->p=_p;
365      PR->pLength=0; // usually not used, GetpLength re-computes it if needed
366    }
367    return 0;
368  }
369#endif
370
371  if (t2==NULL)           // Divisor is just one term, therefore it will
372  {                       // just cancel the leading term
373    PR->LmDeleteAndIter();
374    if (coef != NULL) *coef = n_Init(1, tailRing);
375    return 0;
376  }
377
378  p_ExpVectorSub(lm, p2, tailRing); // Calculate the Monomial we must multiply to p2
379
380  if (tailRing != currRing)
381  {
382    // check that reduction does not violate exp bound
383    while (PW->max_exp != NULL && !p_LmExpVectorAddIsOk(lm, PW->max_exp, tailRing))
384    {
385      // undo changes of lm
386      p_ExpVectorAdd(lm, p2, tailRing);
387      if (strat == NULL) return 2;
388      if (! kStratChangeTailRing(strat, PR, PW)) return -1;
389      tailRing = strat->tailRing;
390      p1 = PR->GetLmTailRing();
391      p2 = PW->GetLmTailRing();
392      t2 = pNext(p2);
393      lm = p1;
394      p_ExpVectorSub(lm, p2, tailRing);
395      ret = 1;
396    }
397  }
398
399  poly lmRight;
400  if (tailRing->isLPring) {
401    k_SplitFrame(lm, lmRight, PW->shift + 1, tailRing);
402  }
403
404  // take care of coef buisness
405  if (! n_IsOne(pGetCoeff(p2), tailRing))
406  {
407    number bn = pGetCoeff(lm);
408    number an = pGetCoeff(p2);
409    int ct = ksCheckCoeff(&an, &bn, tailRing->cf);    // Calculate special LC
410    p_SetCoeff(lm, bn, tailRing);
411    if (tailRing->isLPring) pSetCoeff0(p1, bn); // lm doesn't point to p1 anymore, if the coef was a pointer, it has been deleted
412    if ((ct == 0) || (ct == 2))
413      PR->Tail_Mult_nn(an);
414    if (coef != NULL) *coef = an;
415    else n_Delete(&an, tailRing);
416  }
417  else
418  {
419    if (coef != NULL) *coef = n_Init(1, tailRing);
420  }
421
422
423  // and finally,
424  if (tailRing->isLPring) {
425    PR->Tail_Minus_mm_Mult_qq(lm, tailRing->p_Procs->pp_Mult_mm(t2, lmRight, tailRing), pLength(t2), spNoether);
426  } else {
427    PR->Tail_Minus_mm_Mult_qq(lm, t2, pLength(t2) /*PW->GetpLength() - 1*/, spNoether);
428  }
429  assume(PW->GetpLength() == pLength(PW->p != NULL ? PW->p : PW->t_p));
430  PR->LmDeleteAndIter();
431
432#if defined(KDEBUG) && defined(TEST_OPT_DEBUG_RED)
433  if (TEST_OPT_DEBUG)
434  {
435    Print(" to: "); PR->wrp(); Print("\n");
436    //printf("\nt^%i ", PR->ecart);pWrite(pHead(PR->p));
437  }
438#endif
439  return ret;
440}
441
442/***************************************************************
443 *
444 * Reduces PR with PW
445 * Assumes PR != NULL, PW != NULL, Lm(PW) divides Lm(PR)
446 *
447 ***************************************************************/
448
449int ksReducePolySig(LObject* PR,
450                 TObject* PW,
451                 long /*idx*/,
452                 poly spNoether,
453                 number *coef,
454                 kStrategy strat)
455{
456#ifdef KDEBUG
457  red_count++;
458#ifdef TEST_OPT_DEBUG_RED
459  if (TEST_OPT_DEBUG)
460  {
461    Print("Red %d:", red_count); PR->wrp(); Print(" with:");
462    PW->wrp();
463  }
464#endif
465#endif
466  int ret = 0;
467  ring tailRing = PR->tailRing;
468  kTest_L(PR);
469  kTest_T(PW);
470
471  // signature-based stuff:
472  // checking for sig-safeness first
473  // NOTE: This has to be done in the current ring
474  //
475  /**********************************************
476   *
477   * TODO:
478   * --------------------------------------------
479   * if strat->sbaOrder == 1
480   * Since we are subdividing lower index and
481   * current index reductions it is enough to
482   * look at the polynomial part of the signature
483   * for a check. This should speed-up checking
484   * a lot!
485   * if !strat->sbaOrder == 0
486   * We are not subdividing lower and current index
487   * due to the fact that we are using the induced
488   * Schreyer order
489   *
490   * nevertheless, this different behaviour is
491   * taken care of by is_sigsafe
492   * => one reduction procedure can be used for
493   * both, the incremental and the non-incremental
494   * attempt!
495   * --------------------------------------------
496   *
497   *********************************************/
498  //printf("COMPARE IDX: %ld -- %ld\n",idx,strat->currIdx);
499  if (!PW->is_sigsafe)
500  {
501    poly sigMult = pCopy(PW->sig);   // copy signature of reducer
502//#if 1
503#ifdef DEBUGF5
504    printf("IN KSREDUCEPOLYSIG: \n");
505    pWrite(pHead(f1));
506    pWrite(pHead(f2));
507    pWrite(sigMult);
508    printf("--------------\n");
509#endif
510    p_ExpVectorAddSub(sigMult,PR->GetLmCurrRing(),PW->GetLmCurrRing(),currRing);
511//#if 1
512#ifdef DEBUGF5
513    printf("------------------- IN KSREDUCEPOLYSIG: --------------------\n");
514    pWrite(pHead(f1));
515    pWrite(pHead(f2));
516    pWrite(sigMult);
517    pWrite(PR->sig);
518    printf("--------------\n");
519#endif
520    int sigSafe = p_LmCmp(PR->sig,sigMult,currRing);
521    // now we can delete the copied polynomial data used for checking for
522    // sig-safeness of the reduction step
523//#if 1
524#ifdef DEBUGF5
525    printf("%d -- %d sig\n",sigSafe,PW->is_sigsafe);
526
527#endif
528    //pDelete(&f1);
529    pDelete(&sigMult);
530    // go on with the computations only if the signature of p2 is greater than the
531    // signature of fm*p1
532    if(sigSafe != 1)
533    {
534      PR->is_redundant = TRUE;
535      return 3;
536    }
537    //PW->is_sigsafe  = TRUE;
538  }
539  PR->is_redundant = FALSE;
540  poly p1 = PR->GetLmTailRing();   // p2 | p1
541  poly p2 = PW->GetLmTailRing();   // i.e. will reduce p1 with p2; lm = LT(p1) / LM(p2)
542  poly t2 = pNext(p2), lm = p1;    // t2 = p2 - LT(p2); really compute P = LC(p2)*p1 - LT(p1)/LM(p2)*p2
543  assume(p1 != NULL && p2 != NULL);// Attention, we have rings and there LC(p2) and LC(p1) are special
544  p_CheckPolyRing(p1, tailRing);
545  p_CheckPolyRing(p2, tailRing);
546
547  pAssume1(p2 != NULL && p1 != NULL &&
548      p_DivisibleBy(p2,  p1, tailRing));
549
550  pAssume1(p_GetComp(p1, tailRing) == p_GetComp(p2, tailRing) ||
551      (p_GetComp(p2, tailRing) == 0 &&
552       p_MaxComp(pNext(p2),tailRing) == 0));
553
554#ifdef HAVE_PLURAL
555  if (rIsPluralRing(currRing))
556  {
557    // for the time being: we know currRing==strat->tailRing
558    // no exp-bound checking needed
559    // (only needed if exp-bound(tailring)<exp-b(currRing))
560    if (PR->bucket!=NULL)  nc_kBucketPolyRed_Z(PR->bucket, p2,coef);
561    else
562    {
563      poly _p = (PR->t_p != NULL ? PR->t_p : PR->p);
564      assume(_p != NULL);
565      nc_PolyPolyRed(_p, p2, coef, currRing);
566      if (PR->t_p!=NULL) PR->t_p=_p; else PR->p=_p;
567      PR->pLength=0; // usaully not used, GetpLength re-comoutes it if needed
568    }
569    return 0;
570  }
571#endif
572
573  if (t2==NULL)           // Divisor is just one term, therefore it will
574  {                       // just cancel the leading term
575    PR->LmDeleteAndIter();
576    if (coef != NULL) *coef = n_Init(1, tailRing->cf);
577    return 0;
578  }
579
580  p_ExpVectorSub(lm, p2, tailRing); // Calculate the Monomial we must multiply to p2
581
582  if (tailRing != currRing)
583  {
584    // check that reduction does not violate exp bound
585    while (PW->max_exp != NULL && !p_LmExpVectorAddIsOk(lm, PW->max_exp, tailRing))
586    {
587      // undo changes of lm
588      p_ExpVectorAdd(lm, p2, tailRing);
589      if (strat == NULL) return 2;
590      if (! kStratChangeTailRing(strat, PR, PW)) return -1;
591      tailRing = strat->tailRing;
592      p1 = PR->GetLmTailRing();
593      p2 = PW->GetLmTailRing();
594      t2 = pNext(p2);
595      lm = p1;
596      p_ExpVectorSub(lm, p2, tailRing);
597      ret = 1;
598    }
599  }
600
601  poly lmRight;
602  if (tailRing->isLPring) {
603    k_SplitFrame(lm, lmRight, PW->shift + 1, tailRing);
604  }
605
606  // take care of coef buisness
607  if (! n_IsOne(pGetCoeff(p2), tailRing->cf))
608  {
609    number bn = pGetCoeff(lm);
610    number an = pGetCoeff(p2);
611    int ct = ksCheckCoeff(&an, &bn, tailRing->cf);    // Calculate special LC
612    p_SetCoeff(lm, bn, tailRing);
613    if (tailRing->isLPring) pSetCoeff0(p1, bn); // lm doesn't point to p1 anymore, if the coef was a pointer, it has been deleted
614    if ((ct == 0) || (ct == 2))
615      PR->Tail_Mult_nn(an);
616    if (coef != NULL) *coef = an;
617    else n_Delete(&an, tailRing->cf);
618  }
619  else
620  {
621    if (coef != NULL) *coef = n_Init(1, tailRing->cf);
622  }
623
624
625  // and finally,
626  if (tailRing->isLPring) {
627    PR->Tail_Minus_mm_Mult_qq(lm, tailRing->p_Procs->pp_Mult_mm(t2, lmRight, tailRing), pLength(t2), spNoether);
628  } else {
629    PR->Tail_Minus_mm_Mult_qq(lm, t2, PW->GetpLength() - 1, spNoether);
630  }
631  assume(PW->GetpLength() == pLength(PW->p != NULL ? PW->p : PW->t_p));
632  PR->LmDeleteAndIter();
633
634#if defined(KDEBUG) && defined(TEST_OPT_DEBUG_RED)
635  if (TEST_OPT_DEBUG)
636  {
637    Print(" to: "); PR->wrp(); Print("\n");
638  }
639#endif
640  return ret;
641}
642
643int ksReducePolySigRing(LObject* PR,
644                 TObject* PW,
645                 long /*idx*/,
646                 poly spNoether,
647                 number *coef,
648                 kStrategy strat)
649{
650#ifdef KDEBUG
651  red_count++;
652#ifdef TEST_OPT_DEBUG_RED
653  if (TEST_OPT_DEBUG)
654  {
655    Print("Red %d:", red_count); PR->wrp(); Print(" with:");
656    PW->wrp();
657  }
658#endif
659#endif
660  int ret = 0;
661  ring tailRing = PR->tailRing;
662  kTest_L(PR);
663  kTest_T(PW);
664
665  // signature-based stuff:
666  // checking for sig-safeness first
667  // NOTE: This has to be done in the current ring
668  //
669  /**********************************************
670   *
671   * TODO:
672   * --------------------------------------------
673   * if strat->sbaOrder == 1
674   * Since we are subdividing lower index and
675   * current index reductions it is enough to
676   * look at the polynomial part of the signature
677   * for a check. This should speed-up checking
678   * a lot!
679   * if !strat->sbaOrder == 0
680   * We are not subdividing lower and current index
681   * due to the fact that we are using the induced
682   * Schreyer order
683   *
684   * nevertheless, this different behaviour is
685   * taken care of by is_sigsafe
686   * => one reduction procedure can be used for
687   * both, the incremental and the non-incremental
688   * attempt!
689   * --------------------------------------------
690   *
691   *********************************************/
692  //printf("COMPARE IDX: %ld -- %ld\n",idx,strat->currIdx);
693  if (!PW->is_sigsafe)
694  {
695    poly sigMult = pCopy(PW->sig);   // copy signature of reducer
696//#if 1
697#ifdef DEBUGF5
698    printf("IN KSREDUCEPOLYSIG: \n");
699    pWrite(pHead(f1));
700    pWrite(pHead(f2));
701    pWrite(sigMult);
702    printf("--------------\n");
703#endif
704    p_ExpVectorAddSub(sigMult,PR->GetLmCurrRing(),PW->GetLmCurrRing(),currRing);
705    //I have also to set the leading coeficient for sigMult (in the case of rings)
706    if(rField_is_Ring(currRing))
707    {
708      pSetCoeff(sigMult,nMult(nDiv(pGetCoeff(PR->p),pGetCoeff(PW->p)), pGetCoeff(sigMult)));
709      if(nIsZero(pGetCoeff(sigMult)))
710      {
711        sigMult = NULL;
712      }
713    }
714//#if 1
715#ifdef DEBUGF5
716    printf("------------------- IN KSREDUCEPOLYSIG: --------------------\n");
717    pWrite(pHead(f1));
718    pWrite(pHead(f2));
719    pWrite(sigMult);
720    pWrite(PR->sig);
721    printf("--------------\n");
722#endif
723    int sigSafe;
724    if(!rField_is_Ring(currRing))
725      sigSafe = p_LmCmp(PR->sig,sigMult,currRing);
726    // now we can delete the copied polynomial data used for checking for
727    // sig-safeness of the reduction step
728//#if 1
729#ifdef DEBUGF5
730    printf("%d -- %d sig\n",sigSafe,PW->is_sigsafe);
731
732#endif
733    if(rField_is_Ring(currRing))
734    {
735      // Set the sig
736      poly origsig = pCopy(PR->sig);
737      if(sigMult != NULL)
738        PR->sig = pHead(pSub(PR->sig, sigMult));
739      //The sigs have the same lm, have to substract
740      //It may happen that now the signature is 0 (drop)
741      if(PR->sig == NULL)
742      {
743        strat->sigdrop=TRUE;
744      }
745      else
746      {
747        if(pLtCmp(PR->sig,origsig) == 1)
748        {
749          // do not allow this reduction - it will increase it's signature
750          // and the partially standard basis is just till the old sig, not the new one
751          PR->is_redundant = TRUE;
752          pDelete(&PR->sig);
753          PR->sig = origsig;
754          strat->blockred++;
755          return 3;
756        }
757        if(pLtCmp(PR->sig,origsig) == -1)
758        {
759          strat->sigdrop=TRUE;
760        }
761      }
762      pDelete(&origsig);
763    }
764    //pDelete(&f1);
765    // go on with the computations only if the signature of p2 is greater than the
766    // signature of fm*p1
767    if(sigSafe != 1 && !rField_is_Ring(currRing))
768    {
769      PR->is_redundant = TRUE;
770      return 3;
771    }
772    //PW->is_sigsafe  = TRUE;
773  }
774  PR->is_redundant = FALSE;
775  poly p1 = PR->GetLmTailRing();   // p2 | p1
776  poly p2 = PW->GetLmTailRing();   // i.e. will reduce p1 with p2; lm = LT(p1) / LM(p2)
777  poly t2 = pNext(p2), lm = p1;    // t2 = p2 - LT(p2); really compute P = LC(p2)*p1 - LT(p1)/LM(p2)*p2
778  assume(p1 != NULL && p2 != NULL);// Attention, we have rings and there LC(p2) and LC(p1) are special
779  p_CheckPolyRing(p1, tailRing);
780  p_CheckPolyRing(p2, tailRing);
781
782  pAssume1(p2 != NULL && p1 != NULL &&
783      p_DivisibleBy(p2,  p1, tailRing));
784
785  pAssume1(p_GetComp(p1, tailRing) == p_GetComp(p2, tailRing) ||
786      (p_GetComp(p2, tailRing) == 0 &&
787       p_MaxComp(pNext(p2),tailRing) == 0));
788
789#ifdef HAVE_PLURAL
790  if (rIsPluralRing(currRing))
791  {
792    // for the time being: we know currRing==strat->tailRing
793    // no exp-bound checking needed
794    // (only needed if exp-bound(tailring)<exp-b(currRing))
795    if (PR->bucket!=NULL)  nc_kBucketPolyRed_Z(PR->bucket, p2,coef);
796    else
797    {
798      poly _p = (PR->t_p != NULL ? PR->t_p : PR->p);
799      assume(_p != NULL);
800      nc_PolyPolyRed(_p, p2, coef, currRing);
801      if (PR->t_p!=NULL) PR->t_p=_p; else PR->p=_p;
802      PR->pLength=0; // usaully not used, GetpLength re-comoutes it if needed
803    }
804    return 0;
805  }
806#endif
807
808  if (t2==NULL)           // Divisor is just one term, therefore it will
809  {                       // just cancel the leading term
810    PR->LmDeleteAndIter();
811    if (coef != NULL) *coef = n_Init(1, tailRing->cf);
812    return 0;
813  }
814
815  p_ExpVectorSub(lm, p2, tailRing); // Calculate the Monomial we must multiply to p2
816
817  if (tailRing != currRing)
818  {
819    // check that reduction does not violate exp bound
820    while (PW->max_exp != NULL && !p_LmExpVectorAddIsOk(lm, PW->max_exp, tailRing))
821    {
822      // undo changes of lm
823      p_ExpVectorAdd(lm, p2, tailRing);
824      if (strat == NULL) return 2;
825      if (! kStratChangeTailRing(strat, PR, PW)) return -1;
826      tailRing = strat->tailRing;
827      p1 = PR->GetLmTailRing();
828      p2 = PW->GetLmTailRing();
829      t2 = pNext(p2);
830      lm = p1;
831      p_ExpVectorSub(lm, p2, tailRing);
832      ret = 1;
833    }
834  }
835
836  poly lmRight;
837  if (tailRing->isLPring) {
838    k_SplitFrame(lm, lmRight, PW->shift + 1, tailRing);
839  }
840
841  // take care of coef buisness
842  if(rField_is_Ring(currRing))
843  {
844    p_SetCoeff(lm, nDiv(pGetCoeff(lm),pGetCoeff(p2)), tailRing);
845    if (tailRing->isLPring) pSetCoeff0(p1, pGetCoeff(lm)); // lm doesn't point to p1 anymore, if the coef was a pointer, it has been deleted
846    if (coef != NULL) *coef = n_Init(1, tailRing->cf);
847  }
848  else
849  {
850    if (! n_IsOne(pGetCoeff(p2), tailRing->cf))
851    {
852      number bn = pGetCoeff(lm);
853      number an = pGetCoeff(p2);
854      int ct = ksCheckCoeff(&an, &bn, tailRing->cf);    // Calculate special LC
855      p_SetCoeff(lm, bn, tailRing);
856      if (tailRing->isLPring) pSetCoeff0(p1, bn); // lm doesn't point to p1 anymore, if the coef was a pointer, it has been deleted
857      if (((ct == 0) || (ct == 2)))
858        PR->Tail_Mult_nn(an);
859      if (coef != NULL) *coef = an;
860      else n_Delete(&an, tailRing->cf);
861    }
862    else
863    {
864      if (coef != NULL) *coef = n_Init(1, tailRing->cf);
865    }
866  }
867
868  // and finally,
869  if (tailRing->isLPring) {
870    PR->Tail_Minus_mm_Mult_qq(lm, tailRing->p_Procs->pp_Mult_mm(t2, lmRight, tailRing), pLength(t2), spNoether);
871  } else {
872    PR->Tail_Minus_mm_Mult_qq(lm, t2, PW->GetpLength() - 1, spNoether);
873  }
874  assume(PW->GetpLength() == pLength(PW->p != NULL ? PW->p : PW->t_p));
875  PR->LmDeleteAndIter();
876
877#if defined(KDEBUG) && defined(TEST_OPT_DEBUG_RED)
878  if (TEST_OPT_DEBUG)
879  {
880    Print(" to: "); PR->wrp(); Print("\n");
881  }
882#endif
883  return ret;
884}
885
886/***************************************************************
887 *
888 * Creates S-Poly of p1 and p2
889 *
890 *
891 ***************************************************************/
892void ksCreateSpoly(LObject* Pair,   poly spNoether,
893                   int use_buckets, ring tailRing,
894                   poly m1, poly m2, TObject** R)
895{
896#ifdef KDEBUG
897  create_count++;
898#endif
899  kTest_L(Pair);
900  poly p1 = Pair->p1;
901  poly p2 = Pair->p2;
902  Pair->tailRing = tailRing;
903
904  assume(p1 != NULL);
905  assume(p2 != NULL);
906  assume(tailRing != NULL);
907
908  poly a1 = pNext(p1), a2 = pNext(p2);
909  number lc1 = pGetCoeff(p1), lc2 = pGetCoeff(p2);
910  int co=0/*, ct = ksCheckCoeff(&lc1, &lc2, currRing->cf)*/; // gcd and zero divisors
911  (void) ksCheckCoeff(&lc1, &lc2, currRing->cf);
912
913  int l1=0, l2=0;
914
915  if (currRing->pCompIndex >= 0)
916  {
917    if (__p_GetComp(p1, currRing)!=__p_GetComp(p2, currRing))
918    {
919      if (__p_GetComp(p1, currRing)==0)
920      {
921        co=1;
922        p_SetCompP(p1,__p_GetComp(p2, currRing), currRing, tailRing);
923      }
924      else
925      {
926        co=2;
927        p_SetCompP(p2, __p_GetComp(p1, currRing), currRing, tailRing);
928      }
929    }
930  }
931
932  // get m1 = LCM(LM(p1), LM(p2))/LM(p1)
933  //     m2 = LCM(LM(p1), LM(p2))/LM(p2)
934  if (m1 == NULL)
935    k_GetLeadTerms(p1, p2, currRing, m1, m2, tailRing);
936
937  poly m12, m22;
938  if (tailRing->isLPring)
939  {
940    // note: because of the crits, p2 is never shifted
941    int split = p_mFirstVblock(p1, tailRing);
942    // TODO: shouldn't we use p1 AND p2 here??
943    k_SplitFrame(m1, m12, split, tailRing);
944    k_SplitFrame(m2, m22, split, tailRing);
945    // manually free the coeffs, because pSetCoeff0 is used in the next step
946    n_Delete(&(m1->coef), tailRing->cf);
947    n_Delete(&(m2->coef), tailRing->cf);
948
949    a1 = p_LPshift(p_Copy(a1, tailRing), 1 - split, tailRing); // unshift a1
950  }
951
952  pSetCoeff0(m1, lc2);
953  pSetCoeff0(m2, lc1);  // and now, m1 * LT(p1) == m2 * LT(p2)
954
955  if (R != NULL)
956  {
957    if (Pair->i_r1 == -1)
958    {
959      l1 = pLength(p1) - 1;
960    }
961    else
962    {
963      l1 = (R[Pair->i_r1])->GetpLength() - 1;
964    }
965    if ((Pair->i_r2 == -1)||(R[Pair->i_r2]==NULL))
966    {
967      l2 = pLength(p2) - 1;
968    }
969    else
970    {
971      l2 = (R[Pair->i_r2])->GetpLength() - 1;
972    }
973  }
974
975  // get m2 * a2
976  if (spNoether != NULL)
977  {
978    l2 = -1;
979    a2 = tailRing->p_Procs->pp_Mult_mm_Noether(a2, m2, spNoether, l2, tailRing);
980    assume(l2 == pLength(a2));
981  }
982  else
983    if (tailRing->isLPring) {
984      // m2*a2*m22
985      a2 = tailRing->p_Procs->pp_Mult_mm(tailRing->p_Procs->pp_mm_Mult(a2, m2, tailRing), m22, tailRing);
986    } else {
987      a2 = tailRing->p_Procs->pp_Mult_mm(a2, m2, tailRing);
988    }
989#ifdef HAVE_RINGS
990  if (!(rField_is_Domain(currRing))) l2 = pLength(a2);
991#endif
992
993  Pair->SetLmTail(m2, a2, l2, use_buckets, tailRing);
994
995  if (tailRing->isLPring) {
996    // get m2*a2*m22 - m1*a1*m12
997    Pair->Tail_Minus_mm_Mult_qq(m1, tailRing->p_Procs->pp_Mult_mm(a1, m12, tailRing), l1, spNoether);
998  } else {
999    // get m2*a2 - m1*a1
1000    Pair->Tail_Minus_mm_Mult_qq(m1, a1, l1, spNoether);
1001  }
1002
1003  // Clean-up time
1004  Pair->LmDeleteAndIter();
1005  p_LmDelete(m1, tailRing);
1006  if (tailRing->isLPring) {
1007    p_LmDelete(m12, tailRing);
1008    p_LmDelete(m22, tailRing);
1009    // m2 is already deleted
1010    p_Delete(&a1, tailRing); // a1 is a copy: safe to destroy
1011  }
1012
1013  if (co != 0)
1014  {
1015    if (co==1)
1016    {
1017      p_SetCompP(p1,0, currRing, tailRing);
1018    }
1019    else
1020    {
1021      p_SetCompP(p2,0, currRing, tailRing);
1022    }
1023  }
1024}
1025
1026int ksReducePolyTail(LObject* PR, TObject* PW, poly Current, poly spNoether)
1027{
1028  BOOLEAN ret;
1029  number coef;
1030  poly Lp =     PR->GetLmCurrRing();
1031  poly Save =   PW->GetLmCurrRing();
1032
1033  kTest_L(PR);
1034  kTest_T(PW);
1035  pAssume(pIsMonomOf(Lp, Current));
1036
1037  assume(Lp != NULL && Current != NULL && pNext(Current) != NULL);
1038  assume(PR->bucket == NULL);
1039
1040  LObject Red(pNext(Current), PR->tailRing);
1041  TObject With(PW, Lp == Save);
1042
1043  pAssume(!pHaveCommonMonoms(Red.p, With.p));
1044  ret = ksReducePoly(&Red, &With, spNoether, &coef);
1045
1046  if (!ret)
1047  {
1048    if (! n_IsOne(coef, currRing->cf))
1049    {
1050      pNext(Current) = NULL;
1051      if (Current == PR->p && PR->t_p != NULL)
1052        pNext(PR->t_p) = NULL;
1053      PR->Mult_nn(coef);
1054    }
1055
1056    n_Delete(&coef, currRing->cf);
1057    pNext(Current) = Red.GetLmTailRing();
1058    if (Current == PR->p && PR->t_p != NULL)
1059      pNext(PR->t_p) = pNext(Current);
1060  }
1061
1062  if (Lp == Save)
1063    With.Delete();
1064
1065  return ret;
1066}
1067
1068int ksReducePolyTailBound(LObject* PR, TObject* PW, int bound, poly Current, poly spNoether)
1069{
1070  BOOLEAN ret;
1071  number coef;
1072  poly Lp =     PR->GetLmCurrRing();
1073  poly Save =   PW->GetLmCurrRing();
1074
1075  kTest_L(PR);
1076  kTest_T(PW);
1077  pAssume(pIsMonomOf(Lp, Current));
1078
1079  assume(Lp != NULL && Current != NULL && pNext(Current) != NULL);
1080  assume(PR->bucket == NULL);
1081
1082  LObject Red(pNext(Current), PR->tailRing);
1083  TObject With(PW, Lp == Save);
1084
1085  pAssume(!pHaveCommonMonoms(Red.p, With.p));
1086  ret = ksReducePolyBound(&Red, &With,bound, spNoether, &coef);
1087
1088  if (!ret)
1089  {
1090    if (! n_IsOne(coef, currRing))
1091    {
1092      pNext(Current) = NULL;
1093      if (Current == PR->p && PR->t_p != NULL)
1094        pNext(PR->t_p) = NULL;
1095      PR->Mult_nn(coef);
1096    }
1097
1098    n_Delete(&coef, currRing);
1099    pNext(Current) = Red.GetLmTailRing();
1100    if (Current == PR->p && PR->t_p != NULL)
1101      pNext(PR->t_p) = pNext(Current);
1102  }
1103
1104  if (Lp == Save)
1105    With.Delete();
1106
1107  return ret;
1108}
1109
1110/***************************************************************
1111 *
1112 * Auxillary Routines
1113 *
1114 *
1115 ***************************************************************/
1116
1117/*2
1118* creates the leading term of the S-polynomial of p1 and p2
1119* do not destroy p1 and p2
1120* remarks:
1121*   1. the coefficient is 0 (p_Init)
1122*   1. a) in the case of coefficient ring, the coefficient is calculated
1123*   2. pNext is undefined
1124*/
1125//static void bbb() { int i=0; }
1126poly ksCreateShortSpoly(poly p1, poly p2, ring tailRing)
1127{
1128  poly a1 = pNext(p1), a2 = pNext(p2);
1129  long c1=p_GetComp(p1, currRing),c2=p_GetComp(p2, currRing);
1130  long c;
1131  poly m1,m2;
1132  number t1 = NULL,t2 = NULL;
1133  int cm,i;
1134  BOOLEAN equal;
1135
1136#ifdef HAVE_RINGS
1137  BOOLEAN is_Ring=rField_is_Ring(currRing);
1138  number lc1 = pGetCoeff(p1), lc2 = pGetCoeff(p2);
1139  if (is_Ring)
1140  {
1141    ksCheckCoeff(&lc1, &lc2, currRing->cf); // gcd and zero divisors
1142    if (a1 != NULL) t2 = nMult(pGetCoeff(a1),lc2);
1143    if (a2 != NULL) t1 = nMult(pGetCoeff(a2),lc1);
1144    while (a1 != NULL && nIsZero(t2))
1145    {
1146      pIter(a1);
1147      nDelete(&t2);
1148      if (a1 != NULL) t2 = nMult(pGetCoeff(a1),lc2);
1149    }
1150    while (a2 != NULL && nIsZero(t1))
1151    {
1152      pIter(a2);
1153      nDelete(&t1);
1154      if (a2 != NULL) t1 = nMult(pGetCoeff(a2),lc1);
1155    }
1156  }
1157#endif
1158
1159  if (a1==NULL)
1160  {
1161    if(a2!=NULL)
1162    {
1163      m2=p_Init(currRing);
1164x2:
1165      for (i = (currRing->N); i; i--)
1166      {
1167        c = p_GetExpDiff(p1, p2,i, currRing);
1168        if (c>0)
1169        {
1170          p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)),currRing);
1171        }
1172        else
1173        {
1174          p_SetExp(m2,i,p_GetExp(a2,i,tailRing),currRing);
1175        }
1176      }
1177      if ((c1==c2)||(c2!=0))
1178      {
1179        p_SetComp(m2,p_GetComp(a2,tailRing), currRing);
1180      }
1181      else
1182      {
1183        p_SetComp(m2,c1,currRing);
1184      }
1185      p_Setm(m2, currRing);
1186#ifdef HAVE_RINGS
1187      if (is_Ring)
1188      {
1189          nDelete(&lc1);
1190          nDelete(&lc2);
1191          nDelete(&t2);
1192          pSetCoeff0(m2, t1);
1193      }
1194#endif
1195      return m2;
1196    }
1197    else
1198    {
1199#ifdef HAVE_RINGS
1200      if (is_Ring)
1201      {
1202        nDelete(&lc1);
1203        nDelete(&lc2);
1204        nDelete(&t1);
1205        nDelete(&t2);
1206      }
1207#endif
1208      return NULL;
1209    }
1210  }
1211  if (a2==NULL)
1212  {
1213    m1=p_Init(currRing);
1214x1:
1215    for (i = (currRing->N); i; i--)
1216    {
1217      c = p_GetExpDiff(p2, p1,i,currRing);
1218      if (c>0)
1219      {
1220        p_SetExp(m1,i,(c+p_GetExp(a1,i, tailRing)),currRing);
1221      }
1222      else
1223      {
1224        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
1225      }
1226    }
1227    if ((c1==c2)||(c1!=0))
1228    {
1229      p_SetComp(m1,p_GetComp(a1,tailRing),currRing);
1230    }
1231    else
1232    {
1233      p_SetComp(m1,c2,currRing);
1234    }
1235    p_Setm(m1, currRing);
1236#ifdef HAVE_RINGS
1237    if (is_Ring)
1238    {
1239      pSetCoeff0(m1, t2);
1240      nDelete(&lc1);
1241      nDelete(&lc2);
1242      nDelete(&t1);
1243    }
1244#endif
1245    return m1;
1246  }
1247  m1 = p_Init(currRing);
1248  m2 = p_Init(currRing);
1249  loop
1250  {
1251    for (i = (currRing->N); i; i--)
1252    {
1253      c = p_GetExpDiff(p1, p2,i,currRing);
1254      if (c > 0)
1255      {
1256        p_SetExp(m2,i,(c+p_GetExp(a2,i,tailRing)), currRing);
1257        p_SetExp(m1,i,p_GetExp(a1,i, tailRing), currRing);
1258      }
1259      else
1260      {
1261        p_SetExp(m1,i,(p_GetExp(a1,i,tailRing)-c), currRing);
1262        p_SetExp(m2,i,p_GetExp(a2,i, tailRing), currRing);
1263      }
1264    }
1265    if(c1==c2)
1266    {
1267      p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
1268      p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
1269    }
1270    else
1271    {
1272      if(c1!=0)
1273      {
1274        p_SetComp(m1,p_GetComp(a1, tailRing), currRing);
1275        p_SetComp(m2,c1, currRing);
1276      }
1277      else
1278      {
1279        p_SetComp(m2,p_GetComp(a2, tailRing), currRing);
1280        p_SetComp(m1,c2, currRing);
1281      }
1282    }
1283    p_Setm(m1,currRing);
1284    p_Setm(m2,currRing);
1285    cm = p_LmCmp(m1, m2,currRing);
1286    if (cm!=0)
1287    {
1288      if(cm==1)
1289      {
1290        p_LmFree(m2,currRing);
1291#ifdef HAVE_RINGS
1292        if (is_Ring)
1293        {
1294          pSetCoeff0(m1, t2);
1295          nDelete(&lc1);
1296          nDelete(&lc2);
1297          nDelete(&t1);
1298        }
1299#endif
1300        return m1;
1301      }
1302      else
1303      {
1304        p_LmFree(m1,currRing);
1305#ifdef HAVE_RINGS
1306        if (is_Ring)
1307        {
1308          pSetCoeff0(m2, t1);
1309          nDelete(&lc1);
1310          nDelete(&lc2);
1311          nDelete(&t2);
1312        }
1313#endif
1314        return m2;
1315      }
1316    }
1317#ifdef HAVE_RINGS
1318    if (is_Ring)
1319    {
1320      equal = nEqual(t1,t2);
1321    }
1322    else
1323#endif
1324    {
1325      t1 = nMult(pGetCoeff(a2),pGetCoeff(p1));
1326      t2 = nMult(pGetCoeff(a1),pGetCoeff(p2));
1327      equal = nEqual(t1,t2);
1328      nDelete(&t2);
1329      nDelete(&t1);
1330    }
1331    if (!equal)
1332    {
1333      p_LmFree(m2,currRing);
1334#ifdef HAVE_RINGS
1335      if (is_Ring)
1336      {
1337          pSetCoeff0(m1, nSub(t1, t2));
1338          nDelete(&lc1);
1339          nDelete(&lc2);
1340          nDelete(&t1);
1341          nDelete(&t2);
1342      }
1343#endif
1344      return m1;
1345    }
1346    pIter(a1);
1347    pIter(a2);
1348#ifdef HAVE_RINGS
1349    if (is_Ring)
1350    {
1351      if (a2 != NULL)
1352      {
1353        nDelete(&t1);
1354        t1 = nMult(pGetCoeff(a2),lc1);
1355      }
1356      if (a1 != NULL)
1357      {
1358        nDelete(&t2);
1359        t2 = nMult(pGetCoeff(a1),lc2);
1360      }
1361      while ((a1 != NULL) && nIsZero(t2))
1362      {
1363        pIter(a1);
1364        if (a1 != NULL)
1365        {
1366          nDelete(&t2);
1367          t2 = nMult(pGetCoeff(a1),lc2);
1368        }
1369      }
1370      while ((a2 != NULL) && nIsZero(t1))
1371      {
1372        pIter(a2);
1373        if (a2 != NULL)
1374        {
1375          nDelete(&t1);
1376          t1 = nMult(pGetCoeff(a2),lc1);
1377        }
1378      }
1379    }
1380#endif
1381    if (a2==NULL)
1382    {
1383      p_LmFree(m2,currRing);
1384      if (a1==NULL)
1385      {
1386#ifdef HAVE_RINGS
1387        if (is_Ring)
1388        {
1389          nDelete(&lc1);
1390          nDelete(&lc2);
1391          nDelete(&t1);
1392          nDelete(&t2);
1393        }
1394#endif
1395        p_LmFree(m1,currRing);
1396        return NULL;
1397      }
1398      goto x1;
1399    }
1400    if (a1==NULL)
1401    {
1402      p_LmFree(m1,currRing);
1403      goto x2;
1404    }
1405  }
1406}
Note: See TracBrowser for help on using the repository browser.