source: git/kernel/tgb.cc @ 44fac1

spielwiese
Last change on this file since 44fac1 was 44fac1, checked in by Hans Schoenemann <hannes@…>, 11 years ago
fix: omalloc -> omAlloc from master
  • Property mode set to 100644
File size: 113.6 KB
RevLine 
[b553e5]1//! \file tgb.cc
[4f858ce]2//       multiple rings
3//       shorten_tails und dessen Aufrufe pruefen wlength!!!
[6b9532]4/****************************************
5*  Computer Algebra System SINGULAR     *
6****************************************/
7/*
8* ABSTRACT: slimgb and F4 implementation
9*/
[f0d1e8]10//#include <vector>
11//using namespace std;
[d64382]12
[731d628]13///@TODO: delay nur auf Sugarvergr?erung
[d64382]14///@TODO: grade aus ecartS, setze dazu strat->honey; und nutze p.ecart
[731d628]15///@TODO: no tail reductions in syz comp
[47e836b]16#include <stdlib.h>
17#include <stdio.h>
18#include <queue>
[762407]19#include "config.h"
[599326]20#include <kernel/mod2.h>
21#include <kernel/tgb.h>
22#include <kernel/tgb_internal.h>
23#include <kernel/tgbgauss.h>
[fb0a2c0]24
[f478f5b]25#include <misc/options.h>
[599326]26#include <kernel/digitech.h>
[210e07]27#include <polys/nc/nc.h>
[76cfef]28#include <polys/nc/sca.h>
29#include <polys/prCopy.h>
[599326]30#include <kernel/longrat.h>
[f478f5b]31#include <coeffs/modulop.h>
[cc4d094]32#define BUCKETS_FOR_NORO_RED 1
[5bf76c]33#define SR_HDL(A) ((long)(A))
[410ea0f]34static const int bundle_size = 100;
35static const int bundle_size_noro = 10000;
36static const int delay_factor = 3;
37int QlogSize (number n);
[1c6ea1]38#define ADD_LATER_SIZE 500
[4f858ce]39#if 1
[410ea0f]40static omBin lm_bin = NULL;
[3ea446]41
[db83bf]42static void simplify_poly (poly p, ring r)
[a0d9be]43{
[410ea0f]44  assume (r == currRing);
[db83bf]45  if(!rField_is_Zp (r))
[410ea0f]46  {
47    p_Cleardenom (p, r);
48    //p_Content(p,r); //is a duplicate call, but belongs here
49  }
50  else
51    pNorm (p);
[3ea446]52}
[410ea0f]53
[03f3269]54//static const BOOLEAN up_to_radical=TRUE;
55
[db83bf]56int slim_nsize (number n, ring r)
[31279e]57{
[db83bf]58  if(rField_is_Zp (r))
[31279e]59  {
60    return 1;
61  }
[db83bf]62  if(rField_is_Q (r))
[31279e]63  {
[410ea0f]64    return QlogSize (n);
[31279e]65  }
66  else
67  {
[410ea0f]68    return n_Size (n, r);
[6b4fbf7]69  }
70}
[410ea0f]71
[db83bf]72static BOOLEAN monomial_root (poly m, ring r)
[2fc974]73{
[410ea0f]74  BOOLEAN changed = FALSE;
75  int i;
[db83bf]76  for(i = 1; i <= rVar (r); i++)
[410ea0f]77  {
78    int e = p_GetExp (m, i, r);
[db83bf]79    if(e > 1)
[2fc974]80    {
[410ea0f]81      p_SetExp (m, i, 1, r);
82      changed = TRUE;
[03f3269]83    }
[410ea0f]84  }
[db83bf]85  if(changed)
[410ea0f]86  {
87    p_Setm (m, r);
88  }
89  return changed;
[03f3269]90}
[410ea0f]91
[db83bf]92static BOOLEAN polynomial_root (poly h, ring r)
[2fc974]93{
[410ea0f]94  poly got = gcd_of_terms (h, r);
95  BOOLEAN changed = FALSE;
[db83bf]96  if((got != NULL) && (TEST_V_UPTORADICAL))
[410ea0f]97  {
98    poly copy = p_Copy (got, r);
[03f3269]99    //p_wrp(got,c->r);
[410ea0f]100    changed = monomial_root (got, r);
[db83bf]101    if(changed)
[03f3269]102    {
[410ea0f]103      poly div_by = pDivide (copy, got);
104      poly iter = h;
[db83bf]105      while(iter)
[410ea0f]106      {
[db83bf]107        pExpVectorSub (iter, div_by);
108        pIter (iter);
[410ea0f]109      }
110      p_Delete (&div_by, r);
[db83bf]111      if(TEST_OPT_PROT)
112        PrintS ("U");
[03f3269]113    }
[410ea0f]114    p_Delete (&copy, r);
[03f3269]115  }
[410ea0f]116  p_Delete (&got, r);
[03f3269]117  return changed;
118}
[410ea0f]119
[db83bf]120static inline poly p_Init_Special (const ring r)
[4f858ce]121{
[410ea0f]122  return p_Init (r, lm_bin);
[4f858ce]123}
[410ea0f]124
[db83bf]125static inline poly pOne_Special (const ring r = currRing)
[4f858ce]126{
[410ea0f]127  poly rc = p_Init_Special (r);
128  pSetCoeff0 (rc, n_Init (1, r));
[4f858ce]129  return rc;
130}
[410ea0f]131
[4f858ce]132// zum Initialiseren: in t_rep_gb plazieren:
133
134#endif
135#define LEN_VAR3
136#define degbound(p) assume(pTotaldegree(p)<10)
137//#define inDebug(p) assume((debug_Ideal==NULL)||(kNF(debug_Ideal,NULL,p,0,0)==0))
138
139//die meisten Varianten stossen sich an coef_buckets
[9cd599]140
[4f858ce]141#ifdef LEN_VAR1
142// erste Variante: Laenge: Anzahl der Monome
[db83bf]143static inline int pSLength (poly p, int l)
[410ea0f]144{
145  return l;
146}
147
[db83bf]148static inline int kSBucketLength (kBucket * bucket, poly lm)
[410ea0f]149{
150  return bucket_guess (bucket);
151}
[4f858ce]152#endif
153
154#ifdef LEN_VAR2
155// 2. Variante: Laenge: Platz fuer die Koeff.
[db83bf]156int pSLength (poly p, int l)
[4f858ce]157{
[410ea0f]158  int s = 0;
[db83bf]159  while(p != NULL)
[410ea0f]160  {
161    s += nSize (pGetCoeff (p));
162    pIter (p);
163  }
[4f858ce]164  return s;
165}
[410ea0f]166
[db83bf]167int kSBucketLength (kBucket * b, poly lm)
[4f858ce]168{
[410ea0f]169  int s = 0;
[4f858ce]170  int i;
[db83bf]171  for(i = MAX_BUCKET; i >= 0; i--)
[4f858ce]172  {
[410ea0f]173    s += pSLength (b->buckets[i], 0);
[4f858ce]174  }
175  return s;
176}
177#endif
[47e836b]178struct snumber_dummy
179{
180  mpz_t z;
181  mpz_t n;
182  #if defined(LDEBUG)
183  int debug;
184  #endif
185  BOOLEAN s;
186};
187typedef struct snumber_dummy  *number_dummy;
188
[4f858ce]189
[db83bf]190int QlogSize (number n)
[2fc974]191{
[47e836b]192  long nl=n_Size(n,currRing->cf);
193  if (nl==0L) return 0;
194  if (nl==1L)
[410ea0f]195  {
[47e836b]196    long i = n_Int(n,currRing->cf);
[410ea0f]197    unsigned long v;
198    v = (i >= 0) ? i : -i;
199    int r = 0;
[5bf76c]200
[db83bf]201    while(v >>= 1)
[410ea0f]202    {
203      r++;
[5bf76c]204    }
[410ea0f]205    return r + 1;
206  }
207  //assume denominator is 0
[47e836b]208  number_dummy nn=(number_dummy)n;
209  return mpz_sizeinbase (nn->z, 2);
[5bf76c]210}
211
[9cd599]212#ifdef LEN_VAR3
[db83bf]213static inline wlen_type pSLength (poly p, int l)
[4f858ce]214{
[ca4a891]215  wlen_type c;
[410ea0f]216  number coef = pGetCoeff (p);
[db83bf]217  if(rField_is_Q (currRing))
[2fc974]218  {
[410ea0f]219    c = QlogSize (coef);
[1821d6]220  }
221  else
[410ea0f]222    c = nSize (coef);
[db83bf]223  if(!(TEST_V_COEFSTRAT))
224  {
[410ea0f]225    return (wlen_type) c *(wlen_type) l /*pLength(p) */ ;
[db83bf]226  }
[2fc974]227  else
228  {
[410ea0f]229    wlen_type res = l;
230    res *= c;
231    res *= c;
[1c6ea1]232    return res;
233  }
[4f858ce]234}
[410ea0f]235
[5a9e7b]236//! TODO CoefBuckets bercksichtigen
[db83bf]237wlen_type kSBucketLength (kBucket * b, poly lm = NULL)
[4f858ce]238{
[410ea0f]239  int s = 0;
[ca4a891]240  wlen_type c;
[1821d6]241  number coef;
[db83bf]242  if(lm == NULL)
[410ea0f]243    coef = pGetCoeff (kBucketGetLm (b));
244  //c=nSize(pGetCoeff(kBucketGetLm(b)));
[1821d6]245  else
[410ea0f]246    coef = pGetCoeff (lm);
247  //c=nSize(pGetCoeff(lm));
[db83bf]248  if(rField_is_Q (currRing))
[2fc974]249  {
[410ea0f]250    c = QlogSize (coef);
[1821d6]251  }
[4f858ce]252  else
[410ea0f]253    c = nSize (coef);
[31279e]254
[4f858ce]255  int i;
[db83bf]256  for(i = b->buckets_used; i >= 0; i--)
[4f858ce]257  {
[410ea0f]258    assume ((b->buckets_length[i] == 0) || (b->buckets[i] != NULL));
259    s += b->buckets_length[i] /*pLength(b->buckets[i]) */ ;
[4f858ce]260  }
[410ea0f]261#ifdef HAVE_COEF_BUCKETS
262  assume (b->buckets[0] == kBucketGetLm (b));
[db83bf]263  if(b->coef[0] != NULL)
[2fc974]264  {
[db83bf]265    if(rField_is_Q (currRing))
[2fc974]266    {
[410ea0f]267      int modifier = QlogSize (pGetCoeff (b->coef[0]));
268      c += modifier;
[2fc974]269    }
270    else
271    {
[410ea0f]272      int modifier = nSize (pGetCoeff (b->coef[0]));
273      c *= modifier;
[1821d6]274    }
[2fc974]275  }
[410ea0f]276#endif
[db83bf]277  if(!(TEST_V_COEFSTRAT))
[2fc974]278  {
[410ea0f]279    return s * c;
[2fc974]280  }
281  else
[1c6ea1]282  {
[410ea0f]283    wlen_type res = s;
284    res *= c;
285    res *= c;
[1c6ea1]286    return res;
287  }
[4f858ce]288}
289#endif
[9cd599]290#ifdef LEN_VAR5
[db83bf]291static inline wlen_type pSLength (poly p, int l)
[9cd599]292{
293  int c;
[410ea0f]294  number coef = pGetCoeff (p);
[db83bf]295  if(rField_is_Q (currRing))
[2fc974]296  {
[410ea0f]297    c = QlogSize (coef);
[9cd599]298  }
299  else
[410ea0f]300    c = nSize (coef);
301  wlen_type erg = l;
302  erg *= c;
303  erg *= c;
[9cd599]304  //PrintS("lenvar 5");
[410ea0f]305  assume (erg >= 0);
306  return erg; /*pLength(p) */ ;
[9cd599]307}
[410ea0f]308
[5a9e7b]309//! TODO CoefBuckets bercksichtigen
[db83bf]310wlen_type kSBucketLength (kBucket * b, poly lm = NULL)
[9cd599]311{
[410ea0f]312  wlen_type s = 0;
[9cd599]313  int c;
314  number coef;
[db83bf]315  if(lm == NULL)
[410ea0f]316    coef = pGetCoeff (kBucketGetLm (b));
317  //c=nSize(pGetCoeff(kBucketGetLm(b)));
[9cd599]318  else
[410ea0f]319    coef = pGetCoeff (lm);
320  //c=nSize(pGetCoeff(lm));
[db83bf]321  if(rField_is_Q (currRing))
[2fc974]322  {
[410ea0f]323    c = QlogSize (coef);
[9cd599]324  }
325  else
[410ea0f]326    c = nSize (coef);
[31279e]327
[9cd599]328  int i;
[db83bf]329  for(i = b->buckets_used; i >= 0; i--)
[9cd599]330  {
[410ea0f]331    assume ((b->buckets_length[i] == 0) || (b->buckets[i] != NULL));
332    s += b->buckets_length[i] /*pLength(b->buckets[i]) */ ;
[9cd599]333  }
[410ea0f]334#ifdef HAVE_COEF_BUCKETS
335  assume (b->buckets[0] == kBucketGetLm (b));
[db83bf]336  if(b->coef[0] != NULL)
[2fc974]337  {
[db83bf]338    if(rField_is_Q (currRing))
[2fc974]339    {
[410ea0f]340      int modifier = QlogSize (pGetCoeff (b->coef[0]));
341      c += modifier;
[2fc974]342    }
343    else
344    {
[410ea0f]345      int modifier = nSize (pGetCoeff (b->coef[0]));
346      c *= modifier;
[9cd599]347    }
[410ea0f]348  }
349#endif
350  wlen_type erg = s;
351  erg *= c;
352  erg *= c;
[9cd599]353  return erg;
354}
355#endif
[4f858ce]356
357#ifdef LEN_VAR4
358// 4.Variante: Laenge: Platz fuer Leitk * (1+Platz fuer andere Koeff.)
[db83bf]359int pSLength (poly p, int l)
[4f858ce]360{
[410ea0f]361  int s = 1;
362  int c = nSize (pGetCoeff (p));
363  pIter (p);
[db83bf]364  while(p != NULL)
[410ea0f]365  {
366    s += nSize (pGetCoeff (p));
367    pIter (p);
368  }
369  return s * c;
[4f858ce]370}
[410ea0f]371
[db83bf]372int kSBucketLength (kBucket * b)
[4f858ce]373{
[410ea0f]374  int s = 1;
375  int c = nSize (pGetCoeff (kBucketGetLm (b)));
[4f858ce]376  int i;
[db83bf]377  for(i = MAX_BUCKET; i > 0; i--)
[4f858ce]378  {
[db83bf]379    if(b->buckets[i] == NULL)
[410ea0f]380      continue;
381    s += pSLength (b->buckets[i], 0);
[4f858ce]382  }
[410ea0f]383  return s * c;
[4f858ce]384}
385#endif
[bfcd46]386//BUG/TODO this stuff will fail on internal Schreyer orderings
[db83bf]387static BOOLEAN elength_is_normal_length (poly p, slimgb_alg * c)
[2fc974]388{
[410ea0f]389  ring r = c->r;
[db83bf]390  if(p_GetComp (p, r) != 0)
[410ea0f]391    return FALSE;
[1f637e]392  if(c->lastDpBlockStart <= (currRing->N))
[410ea0f]393  {
394    int i;
[db83bf]395    for(i = 1; i < c->lastDpBlockStart; i++)
[2fc974]396    {
[db83bf]397      if(p_GetExp (p, i, r) != 0)
[410ea0f]398      {
[db83bf]399        break;
[410ea0f]400      }
401    }
[db83bf]402    if(i >= c->lastDpBlockStart)
[410ea0f]403    {
404      //wrp(p);
405      //PrintS("\n");
406      return TRUE;
[2fc974]407    }
408    else
[410ea0f]409      return FALSE;
410  }
411  else
[2921f5]412    return FALSE;
413}
[f2b5839]414
[db83bf]415static BOOLEAN lies_in_last_dp_block (poly p, slimgb_alg * c)
[2fc974]416{
[410ea0f]417  ring r = c->r;
[db83bf]418  if(p_GetComp (p, r) != 0)
[410ea0f]419    return FALSE;
[1f637e]420  if(c->lastDpBlockStart <= (currRing->N))
[410ea0f]421  {
422    int i;
[db83bf]423    for(i = 1; i < c->lastDpBlockStart; i++)
[2fc974]424    {
[db83bf]425      if(p_GetExp (p, i, r) != 0)
[410ea0f]426      {
[db83bf]427        break;
[410ea0f]428      }
429    }
[db83bf]430    if(i >= c->lastDpBlockStart)
[410ea0f]431    {
432      //wrp(p);
433      //PrintS("\n");
434      return TRUE;
[2fc974]435    }
436    else
[410ea0f]437      return FALSE;
438  }
439  else
[f2b5839]440    return FALSE;
441}
442
[db83bf]443static int get_last_dp_block_start (ring r)
[2fc974]444{
[410ea0f]445  //ring r=c->r;
446  int last_block;
[5a9e7b]447
[db83bf]448  if(rRing_has_CompLastBlock (r))
[410ea0f]449  {
450    last_block = rBlocks (r) - 3;
451  }
452  else
453  {
454    last_block = rBlocks (r) - 2;
455  }
456  assume (last_block >= 0);
[db83bf]457  if(r->order[last_block] == ringorder_dp)
[410ea0f]458    return r->block0[last_block];
[1f637e]459  return (currRing->N) + 1;
[2921f5]460}
461
[db83bf]462static wlen_type do_pELength (poly p, slimgb_alg * c, int dlm = -1)
[2fc974]463{
[db83bf]464  if(p == NULL)
[410ea0f]465    return 0;
466  wlen_type s = 0;
467  poly pi = p;
[db83bf]468  if(dlm < 0)
[2fc974]469  {
[410ea0f]470    dlm = c->pTotaldegree (p);
471    s = 1;
472    pi = p->next;
[4f858ce]473  }
[31279e]474
[db83bf]475  while(pi)
[2fc974]476  {
[410ea0f]477    int d = c->pTotaldegree (pi);
[db83bf]478    if(d > dlm)
[410ea0f]479      s += 1 + d - dlm;
[4f858ce]480    else
481      ++s;
[410ea0f]482    pi = pi->next;
[4f858ce]483  }
484  return s;
485}
[e65be8e]486
[db83bf]487wlen_type pELength (poly p, slimgb_alg * c, ring r)
[2fc974]488{
[db83bf]489  if(p == NULL)
[410ea0f]490    return 0;
491  wlen_type s = 0;
492  poly pi = p;
[e65be8e]493  int dlm;
[410ea0f]494  dlm = c->pTotaldegree (p);
495  s = 1;
496  pi = p->next;
[31279e]497
[db83bf]498  while(pi)
[2fc974]499  {
[410ea0f]500    int d = c->pTotaldegree (pi);
[db83bf]501    if(d > dlm)
[410ea0f]502      s += 1 + d - dlm;
[e65be8e]503    else
504      ++s;
[410ea0f]505    pi = pi->next;
[e65be8e]506  }
507  return s;
508}
509
[db83bf]510wlen_type kEBucketLength (kBucket * b, poly lm, int sugar, slimgb_alg * ca)
[4f858ce]511{
[410ea0f]512  wlen_type s = 0;
[db83bf]513  if(lm == NULL)
[2fc974]514  {
[410ea0f]515    lm = kBucketGetLm (b);
[4f858ce]516  }
[db83bf]517  if(lm == NULL)
[410ea0f]518    return 0;
[db83bf]519  if(elength_is_normal_length (lm, ca))
[2fc974]520  {
[410ea0f]521    return bucket_guess (b);
[2921f5]522  }
[410ea0f]523  int d = ca->pTotaldegree (lm);
524#if 0
525  assume (sugar >= d);
526  s = 1 + (bucket_guess (b) - 1) * (sugar - d + 1);
[d64382]527  return s;
[410ea0f]528#else
[5a9e7b]529
[d64382]530  //int d=pTotaldegree(lm,ca->r);
[4f858ce]531  int i;
[db83bf]532  for(i = b->buckets_used; i >= 0; i--)
[4f858ce]533  {
[db83bf]534    if(b->buckets[i] == NULL)
[410ea0f]535      continue;
[5a9e7b]536
[db83bf]537    if((ca->pTotaldegree (b->buckets[i]) <= d)
538       && (elength_is_normal_length (b->buckets[i], ca)))
[2fc974]539    {
[410ea0f]540      s += b->buckets_length[i];
[2fc974]541    }
542    else
[2921f5]543    {
[410ea0f]544      s += do_pELength (b->buckets[i], ca, d);
[2921f5]545    }
[4f858ce]546  }
547  return s;
[410ea0f]548#endif
[4f858ce]549}
550
[db83bf]551static inline int pELength (poly p, slimgb_alg * c, int l)
[2fc974]552{
[db83bf]553  if(p == NULL)
[410ea0f]554    return 0;
[db83bf]555  if((l > 0) && (elength_is_normal_length (p, c)))
[2921f5]556    return l;
[410ea0f]557  return do_pELength (p, c);
[4f858ce]558}
[d491e3]559
[db83bf]560static inline wlen_type pQuality (poly p, slimgb_alg * c, int l = -1)
[2fc974]561{
[db83bf]562  if(l < 0)
[410ea0f]563    l = pLength (p);
[db83bf]564  if(c->isDifficultField)
[410ea0f]565  {
[db83bf]566    if(c->eliminationProblem)
[2fc974]567    {
[ca4a891]568      wlen_type cs;
[410ea0f]569      number coef = pGetCoeff (p);
[db83bf]570      if(rField_is_Q (currRing))
[2fc974]571      {
[db83bf]572        cs = QlogSize (coef);
[d491e3]573      }
574      else
[db83bf]575        cs = nSize (coef);
[410ea0f]576      wlen_type erg = cs;
[db83bf]577      if(TEST_V_COEFSTRAT)
578        erg *= cs;
[410ea0f]579      //erg*=cs;//for quadratic
580      erg *= pELength (p, c, l);
581      //FIXME: not quadratic coeff size
[9cd599]582      //return cs*pELength(p,c,l);
583      return erg;
[d491e3]584    }
[a610ee]585    //PrintS("I am here");
[410ea0f]586    wlen_type r = pSLength (p, l);
587    assume (r >= 0);
[9cd599]588    return r;
[d491e3]589  }
[db83bf]590  if(c->eliminationProblem)
[410ea0f]591    return pELength (p, c, l);
[4f858ce]592  return l;
593}
[d491e3]594
[db83bf]595static inline int pTotaldegree_full (poly p)
[2fc974]596{
[410ea0f]597  int r = 0;
[db83bf]598  while(p)
[2fc974]599  {
[410ea0f]600    int d = pTotaldegree (p);
601    r = si_max (r, d);
602    pIter (p);
[4f858ce]603  }
604  return r;
605}
606
[db83bf]607wlen_type red_object::guess_quality (slimgb_alg * c)
[2fc974]608{
[410ea0f]609  //works at the moment only for lenvar 1, because in different
610  //case, you have to look on coefs
611  wlen_type s = 0;
[db83bf]612  if(c->isDifficultField)
[410ea0f]613  {
614    //s=kSBucketLength(bucket,this->p);
[db83bf]615    if(c->eliminationProblem)
[2fc974]616    {
[410ea0f]617      wlen_type cs;
618      number coef;
[31279e]619
[410ea0f]620      coef = pGetCoeff (kBucketGetLm (bucket));
621      //c=nSize(pGetCoeff(kBucketGetLm(b)));
[31279e]622
[410ea0f]623      //c=nSize(pGetCoeff(lm));
[db83bf]624      if(rField_is_Q (currRing))
[2fc974]625      {
[db83bf]626        cs = QlogSize (coef);
[e4e1c2a]627      }
[2fc974]628      else
[db83bf]629        cs = nSize (coef);
[410ea0f]630#ifdef HAVE_COEF_BUCKETS
[db83bf]631      if(bucket->coef[0] != NULL)
[2fc974]632      {
[db83bf]633        if(rField_is_Q (currRing))
634        {
635          int modifier = QlogSize (pGetCoeff (bucket->coef[0]));
636          cs += modifier;
637        }
638        else
639        {
640          int modifier = nSize (pGetCoeff (bucket->coef[0]));
641          cs *= modifier;
642        }
[d491e3]643      }
[410ea0f]644#endif
645      //FIXME:not quadratic
646      wlen_type erg = kEBucketLength (this->bucket, this->p, this->sugar, c);
647      //erg*=cs;//for quadratic
648      erg *= cs;
[db83bf]649      if(TEST_V_COEFSTRAT)
650        erg *= cs;
[410ea0f]651      //return cs*kEBucketLength(this->bucket,this->p,c);
652      return erg;
[d491e3]653    }
[410ea0f]654    s = kSBucketLength (bucket, NULL);
655  }
656  else
657  {
[db83bf]658    if(c->eliminationProblem)
[410ea0f]659      //if (false)
660      s = kEBucketLength (this->bucket, this->p, this->sugar, c);
[31279e]661    else
[410ea0f]662      s = bucket_guess (bucket);
663  }
664  return s;
[4f858ce]665}
[d491e3]666
[db83bf]667#if 0                           //currently unused
668static void finalize_reduction_step (reduction_step * r)
[2fc974]669{
[4f858ce]670  delete r;
671}
[a41623]672#endif
[db83bf]673#if 0                           //currently unused
674static int LObject_better_gen (const void *ap, const void *bp)
[4f858ce]675{
[410ea0f]676  LObject *a = *(LObject **) ap;
677  LObject *b = *(LObject **) bp;
678  return (pLmCmp (a->p, b->p));
[4f858ce]679}
[a41623]680#endif
[db83bf]681static int red_object_better_gen (const void *ap, const void *bp)
[4f858ce]682{
[410ea0f]683  return (pLmCmp (((red_object *) ap)->p, ((red_object *) bp)->p));
[4f858ce]684}
685
[db83bf]686#if 0                           //currently unused
687static int pLmCmp_func_inverted (const void *ap1, const void *ap2)
[2fc974]688{
[410ea0f]689  poly p1, p2;
690  p1 = *((poly *) ap1);
691  p2 = *((poly *) ap2);
692  return -pLmCmp (p1, p2);
[4f858ce]693}
[a41623]694#endif
[4f858ce]695
[db83bf]696int tgb_pair_better_gen2 (const void *ap, const void *bp)
[2fc974]697{
[410ea0f]698  return (-tgb_pair_better_gen (ap, bp));
[4f858ce]699}
[410ea0f]700
[db83bf]701int kFindDivisibleByInS_easy (kStrategy strat, const red_object & obj)
[2fc974]702{
[4f858ce]703  int i;
[410ea0f]704  long not_sev = ~obj.sev;
705  poly p = obj.p;
[db83bf]706  for(i = 0; i <= strat->sl; i++)
[2fc974]707  {
[db83bf]708    if(pLmShortDivisibleBy (strat->S[i], strat->sevS[i], p, not_sev))
[4f858ce]709      return i;
710  }
711  return -1;
712}
[410ea0f]713
[db83bf]714int kFindDivisibleByInS_easy (kStrategy strat, poly p, long sev)
[2fc974]715{
[4f858ce]716  int i;
[410ea0f]717  long not_sev = ~sev;
[db83bf]718  for(i = 0; i <= strat->sl; i++)
[2fc974]719  {
[db83bf]720    if(pLmShortDivisibleBy (strat->S[i], strat->sevS[i], p, not_sev))
[4f858ce]721      return i;
722  }
723  return -1;
724}
[410ea0f]725
726static int
727posInPairs (sorted_pair_node ** p, int pn, sorted_pair_node * qe,
[db83bf]728            slimgb_alg * c, int an = 0)
[4f858ce]729{
[db83bf]730  if(pn == 0)
[410ea0f]731    return 0;
[4f858ce]732
[410ea0f]733  int length = pn - 1;
[4f858ce]734  int i;
735  //int an = 0;
[410ea0f]736  int en = length;
[4f858ce]737
[db83bf]738  if(pair_better (qe, p[en], c))
[410ea0f]739    return length + 1;
[4f858ce]740
[db83bf]741  while(1)
[410ea0f]742  {
743    //if (an >= en-1)
[db83bf]744    if(en - 1 <= an)
[4f858ce]745    {
[db83bf]746      if(pair_better (p[an], qe, c))
747        return an;
[410ea0f]748      return en;
[4f858ce]749    }
[410ea0f]750    i = (an + en) / 2;
[db83bf]751    if(pair_better (p[i], qe, c))
[410ea0f]752      en = i;
753    else
754      an = i;
755  }
[4f858ce]756}
757
[db83bf]758static BOOLEAN ascending (int *i, int top)
[2fc974]759{
[db83bf]760  if(top < 1)
[410ea0f]761    return TRUE;
[db83bf]762  if(i[top] < i[top - 1])
[410ea0f]763    return FALSE;
764  return ascending (i, top - 1);
[4f858ce]765}
766
[db83bf]767sorted_pair_node **spn_merge (sorted_pair_node ** p, int pn,
768                              sorted_pair_node ** q, int qn, slimgb_alg * c)
[2fc974]769{
[4f858ce]770  int i;
[410ea0f]771  int *a = (int *) omalloc (qn * sizeof (int));
[4f858ce]772//   int mc;
773//   PrintS("Debug\n");
774//   for(mc=0;mc<qn;mc++)
775// {
776//     wrp(q[mc]->lcm_of_lm);
777//     PrintS("\n");
778// }
779//    PrintS("Debug they are in\n");
780//   for(mc=0;mc<pn;mc++)
781// {
782//     wrp(p[mc]->lcm_of_lm);
783//     PrintS("\n");
784// }
[410ea0f]785  int lastpos = 0;
[db83bf]786  for(i = 0; i < qn; i++)
[2fc974]787  {
[410ea0f]788    lastpos = posInPairs (p, pn, q[i], c, si_max (lastpos - 1, 0));
[4f858ce]789    //   cout<<lastpos<<"\n";
[410ea0f]790    a[i] = lastpos;
[4f858ce]791  }
[db83bf]792  if((pn + qn) > c->max_pairs)
[2fc974]793  {
[410ea0f]794    p =
795      (sorted_pair_node **) omrealloc (p,
[db83bf]796                                       2 * (pn +
797                                            qn) *
798                                       sizeof (sorted_pair_node *));
[410ea0f]799    c->max_pairs = 2 * (pn + qn);
[4f858ce]800  }
[db83bf]801  for(i = qn - 1; i >= 0; i--)
[2fc974]802  {
[4f858ce]803    size_t size;
[db83bf]804    if(qn - 1 > i)
[410ea0f]805      size = (a[i + 1] - a[i]) * sizeof (sorted_pair_node *);
[4f858ce]806    else
[db83bf]807      size = (pn - a[i]) * sizeof (sorted_pair_node *); //as indices begin with 0
[410ea0f]808    memmove (p + a[i] + (1 + i), p + a[i], size);
809    p[a[i] + i] = q[i];
[4f858ce]810  }
[410ea0f]811  omfree (a);
[4f858ce]812  return p;
813}
814
[410ea0f]815static BOOLEAN
816trivial_syzygie (int pos1, int pos2, poly bound, slimgb_alg * c)
[2fc974]817{
[410ea0f]818  poly p1 = c->S->m[pos1];
819  poly p2 = c->S->m[pos2];
[31279e]820
[db83bf]821  if(pGetComp (p1) > 0 || pGetComp (p2) > 0)
[4f858ce]822    return FALSE;
823  int i = 1;
[410ea0f]824  poly m = NULL;
825  poly gcd1 = c->gcd_of_terms[pos1];
826  poly gcd2 = c->gcd_of_terms[pos2];
[31279e]827
[db83bf]828  if((gcd1 != NULL) && (gcd2 != NULL))
[2fc974]829  {
[db83bf]830    gcd1->next = gcd2;          //may ordered incorrect
[410ea0f]831    m = gcd_of_terms (gcd1, c->r);
832    gcd1->next = NULL;
[2fc974]833  }
[db83bf]834  if(m == NULL)
[4f858ce]835  {
[410ea0f]836    loop
837    {
[db83bf]838      if(pGetExp (p1, i) + pGetExp (p2, i) > pGetExp (bound, i))
839        return FALSE;
[1f637e]840      if(i == (currRing->N))
[4f858ce]841      {
[db83bf]842        //PrintS("trivial");
843        return TRUE;
[4f858ce]844      }
[410ea0f]845      i++;
846    }
[4f858ce]847  }
[31279e]848  else
[4f858ce]849  {
850    loop
[410ea0f]851    {
[db83bf]852      if(pGetExp (p1, i) - pGetExp (m, i) + pGetExp (p2, i) >
853         pGetExp (bound, i))
[4f858ce]854      {
[db83bf]855        pDelete (&m);
856        return FALSE;
[410ea0f]857      }
[1f637e]858      if(i == (currRing->N))
[410ea0f]859      {
[db83bf]860        pDelete (&m);
861        //PrintS("trivial");
862        return TRUE;
[4f858ce]863      }
[410ea0f]864      i++;
865    }
[4f858ce]866  }
867}
868
[b553e5]869//! returns position sets w as weight
[db83bf]870int find_best (red_object * r, int l, int u, wlen_type & w, slimgb_alg * c)
[2fc974]871{
[410ea0f]872  int best = l;
[4f858ce]873  int i;
[410ea0f]874  w = r[l].guess_quality (c);
[db83bf]875  for(i = l + 1; i <= u; i++)
[2fc974]876  {
[410ea0f]877    wlen_type w2 = r[i].guess_quality (c);
[db83bf]878    if(w2 < w)
[2fc974]879    {
[410ea0f]880      w = w2;
881      best = i;
[4f858ce]882    }
883  }
[410ea0f]884  return best;
[4f858ce]885}
886
[db83bf]887void red_object::canonicalize ()
[2fc974]888{
[410ea0f]889  kBucketCanonicalize (bucket);
[4f858ce]890}
[2fc974]891
[db83bf]892BOOLEAN good_has_t_rep (int i, int j, slimgb_alg * c)
[2fc974]893{
[410ea0f]894  assume (i >= 0);
895  assume (j >= 0);
[db83bf]896  if(has_t_rep (i, j, c))
[410ea0f]897    return TRUE;
[4f858ce]898  //poly lm=pOne();
[410ea0f]899  assume (c->tmp_lm != NULL);
900  poly lm = c->tmp_lm;
[4f858ce]901
[410ea0f]902  pLcm (c->S->m[i], c->S->m[j], lm);
903  pSetm (lm);
904  assume (lm != NULL);
[4f858ce]905  //int deciding_deg= pTotaldegree(lm);
[410ea0f]906  int *i_con = make_connections (i, j, lm, c);
[4f858ce]907  //p_Delete(&lm,c->r);
908
[db83bf]909  for(int n = 0; ((n < c->n) && (i_con[n] >= 0)); n++)
[2fc974]910  {
[db83bf]911    if(i_con[n] == j)
[2fc974]912    {
[410ea0f]913      now_t_rep (i, j, c);
[44fac1]914      omFree (i_con);
[4f858ce]915      return TRUE;
916    }
917  }
[410ea0f]918  omfree (i_con);
[4f858ce]919
920  return FALSE;
921}
[410ea0f]922
[db83bf]923BOOLEAN lenS_correct (kStrategy strat)
[2fc974]924{
[4f858ce]925  int i;
[db83bf]926  for(i = 0; i <= strat->sl; i++)
[2fc974]927  {
[db83bf]928    if(strat->lenS[i] != pLength (strat->S[i]))
[4f858ce]929      return FALSE;
930  }
931  return TRUE;
932}
933
934
[db83bf]935static void cleanS (kStrategy strat, slimgb_alg * c)
[8047af8]936{
[410ea0f]937  int i = 0;
[4f858ce]938  LObject P;
[db83bf]939  while(i <= strat->sl)
[391323]940  {
[410ea0f]941    P.p = strat->S[i];
942    P.sev = strat->sevS[i];
[a41623]943    //int dummy=strat->sl;
[5eccfaa]944    //if(kFindDivisibleByInS(strat,&dummy,&P)!=i)
[db83bf]945    if(kFindDivisibleByInS_easy (strat, P.p, P.sev) != i)
[4f858ce]946    {
[410ea0f]947      deleteInS (i, strat);
[4f858ce]948      //remember destroying poly
[410ea0f]949      BOOLEAN found = FALSE;
[4f858ce]950      int j;
[db83bf]951      for(j = 0; j < c->n; j++)
[391323]952      {
[db83bf]953        if(c->S->m[j] == P.p)
954        {
955          found = TRUE;
956          break;
957        }
[391323]958      }
[db83bf]959      if(!found)
960        pDelete (&P.p);
[4f858ce]961      //remember additional reductors
962    }
[410ea0f]963    else
964      i++;
[4f858ce]965  }
966}
[410ea0f]967
[db83bf]968static int bucket_guess (kBucket * bucket)
[2fc974]969{
[410ea0f]970  int sum = 0;
[4f858ce]971  int i;
[db83bf]972  for(i = bucket->buckets_used; i >= 0; i--)
[2fc974]973  {
[db83bf]974    if(bucket->buckets[i])
[410ea0f]975      sum += bucket->buckets_length[i];
[4f858ce]976  }
977  return sum;
978}
979
[410ea0f]980static int
981add_to_reductors (slimgb_alg * c, poly h, int len, int ecart,
[db83bf]982                  BOOLEAN simplified)
[a0d9be]983{
[4f858ce]984  //inDebug(h);
[410ea0f]985  assume (lenS_correct (c->strat));
986  assume (len == pLength (h));
[4f858ce]987  int i;
[c57134]988//   if (c->isDifficultField)
989//        i=simple_posInS(c->strat,h,pSLength(h,len),c->isDifficultField);
[4f858ce]990//   else
[c57134]991//     i=simple_posInS(c->strat,h,len,c->isDifficultField);
[4f858ce]992
[410ea0f]993  LObject P;
994  memset (&P, 0, sizeof (P));
995  P.tailRing = c->r;
[db83bf]996  P.p = h;                      /*p_Copy(h,c->r); */
[410ea0f]997  P.ecart = ecart;
[47e836b]998  P.FDeg = c->r->pFDeg (P.p, c->r);
[db83bf]999  if(!(simplified))
[a0d9be]1000  {
[db83bf]1001    if(!rField_is_Zp (c->r))
[410ea0f]1002    {
1003      p_Cleardenom (P.p, c->r);
1004      //p_Content(P.p,c->r ); //is a duplicate call, but belongs here
[31279e]1005
[410ea0f]1006    }
1007    else
1008      pNorm (P.p);
1009    pNormalize (P.p);
[4f858ce]1010  }
[410ea0f]1011  wlen_type pq = pQuality (h, c, len);
1012  i = simple_posInS (c->strat, h, len, pq);
1013  c->strat->enterS (P, i, c->strat, -1);
[31279e]1014
[410ea0f]1015  c->strat->lenS[i] = len;
1016  assume (pLength (c->strat->S[i]) == c->strat->lenS[i]);
[db83bf]1017  if(c->strat->lenSw != NULL)
[410ea0f]1018    c->strat->lenSw[i] = pq;
[31279e]1019
[4f858ce]1020  return i;
1021}
[2fc974]1022
[db83bf]1023static void length_one_crit (slimgb_alg * c, int pos, int len)
[4f858ce]1024{
[db83bf]1025  if(c->nc)
[d491e3]1026    return;
[db83bf]1027  if(len == 1)
[4f858ce]1028  {
1029    int i;
[db83bf]1030    for(i = 0; i < pos; i++)
[4f858ce]1031    {
[db83bf]1032      if(c->lengths[i] == 1)
1033        c->states[pos][i] = HASTREP;
[4f858ce]1034    }
[db83bf]1035    for(i = pos + 1; i < c->n; i++)
[2fc974]1036    {
[db83bf]1037      if(c->lengths[i] == 1)
1038        c->states[i][pos] = HASTREP;
[4f858ce]1039    }
[db83bf]1040    if(!c->nc)
[410ea0f]1041      shorten_tails (c, c->S->m[pos]);
[4f858ce]1042  }
1043}
1044
[db83bf]1045static void move_forward_in_S (int old_pos, int new_pos, kStrategy strat)
[4f858ce]1046{
[410ea0f]1047  assume (old_pos >= new_pos);
1048  poly p = strat->S[old_pos];
1049  int ecart = strat->ecartS[old_pos];
1050  long sev = strat->sevS[old_pos];
1051  int s_2_r = strat->S_2_R[old_pos];
1052  int length = strat->lenS[old_pos];
1053  assume (length == pLength (strat->S[old_pos]));
[6bcdc53]1054  wlen_type length_w;
[db83bf]1055  if(strat->lenSw != NULL)
[410ea0f]1056    length_w = strat->lenSw[old_pos];
[4f858ce]1057  int i;
[db83bf]1058  for(i = old_pos; i > new_pos; i--)
[410ea0f]1059  {
1060    strat->S[i] = strat->S[i - 1];
1061    strat->ecartS[i] = strat->ecartS[i - 1];
1062    strat->sevS[i] = strat->sevS[i - 1];
1063    strat->S_2_R[i] = strat->S_2_R[i - 1];
1064  }
[db83bf]1065  if(strat->lenS != NULL)
1066    for(i = old_pos; i > new_pos; i--)
[410ea0f]1067      strat->lenS[i] = strat->lenS[i - 1];
[db83bf]1068  if(strat->lenSw != NULL)
1069    for(i = old_pos; i > new_pos; i--)
[410ea0f]1070      strat->lenSw[i] = strat->lenSw[i - 1];
1071
1072  strat->S[new_pos] = p;
1073  strat->ecartS[new_pos] = ecart;
1074  strat->sevS[new_pos] = sev;
1075  strat->S_2_R[new_pos] = s_2_r;
1076  strat->lenS[new_pos] = length;
[db83bf]1077  if(strat->lenSw != NULL)
[410ea0f]1078    strat->lenSw[new_pos] = length_w;
[4f858ce]1079  //assume(lenS_correct(strat));
1080}
1081
[db83bf]1082static void move_backward_in_S (int old_pos, int new_pos, kStrategy strat)
[9108d3]1083{
[410ea0f]1084  assume (old_pos <= new_pos);
1085  poly p = strat->S[old_pos];
1086  int ecart = strat->ecartS[old_pos];
1087  long sev = strat->sevS[old_pos];
1088  int s_2_r = strat->S_2_R[old_pos];
1089  int length = strat->lenS[old_pos];
1090  assume (length == pLength (strat->S[old_pos]));
[9108d3]1091  wlen_type length_w;
[db83bf]1092  if(strat->lenSw != NULL)
[410ea0f]1093    length_w = strat->lenSw[old_pos];
[9108d3]1094  int i;
[db83bf]1095  for(i = old_pos; i < new_pos; i++)
[410ea0f]1096  {
1097    strat->S[i] = strat->S[i + 1];
1098    strat->ecartS[i] = strat->ecartS[i + 1];
1099    strat->sevS[i] = strat->sevS[i + 1];
1100    strat->S_2_R[i] = strat->S_2_R[i + 1];
1101  }
[db83bf]1102  if(strat->lenS != NULL)
1103    for(i = old_pos; i < new_pos; i++)
[410ea0f]1104      strat->lenS[i] = strat->lenS[i + 1];
[db83bf]1105  if(strat->lenSw != NULL)
1106    for(i = old_pos; i < new_pos; i++)
[410ea0f]1107      strat->lenSw[i] = strat->lenSw[i + 1];
1108
1109  strat->S[new_pos] = p;
1110  strat->ecartS[new_pos] = ecart;
1111  strat->sevS[new_pos] = sev;
1112  strat->S_2_R[new_pos] = s_2_r;
1113  strat->lenS[new_pos] = length;
[db83bf]1114  if(strat->lenSw != NULL)
[410ea0f]1115    strat->lenSw[new_pos] = length_w;
[9108d3]1116  //assume(lenS_correct(strat));
1117}
1118
[db83bf]1119static int *make_connections (int from, int to, poly bound, slimgb_alg * c)
[4f858ce]1120{
[410ea0f]1121  ideal I = c->S;
[44fac1]1122  int *cans = (int *) omAlloc (c->n * sizeof (int));
1123  int *connected = (int *) omAlloc (c->n * sizeof (int));
[410ea0f]1124  cans[0] = to;
1125  int cans_length = 1;
1126  connected[0] = from;
1127  int last_cans_pos = -1;
1128  int connected_length = 1;
1129  long neg_bounds_short = ~p_GetShortExpVector (bound, c->r);
1130
1131  int not_yet_found = cans_length;
1132  int con_checked = 0;
[4f858ce]1133  int pos;
[31279e]1134
[db83bf]1135  while(TRUE)
[2fc974]1136  {
[db83bf]1137    if((con_checked < connected_length) && (not_yet_found > 0))
[2fc974]1138    {
[410ea0f]1139      pos = connected[con_checked];
[db83bf]1140      for(int i = 0; i < cans_length; i++)
[2fc974]1141      {
[db83bf]1142        if(cans[i] < 0)
1143          continue;
1144        //FIXME: triv. syz. does not hold on noncommutative, check it for modules
1145        if((has_t_rep (pos, cans[i], c))
1146           || ((!rIsPluralRing (c->r))
1147               && (trivial_syzygie (pos, cans[i], bound, c))))
1148        {
1149          connected[connected_length] = cans[i];
1150          connected_length++;
1151          cans[i] = -1;
1152          --not_yet_found;
1153
1154          if(connected[connected_length - 1] == to)
1155          {
1156            if(connected_length < c->n)
1157            {
1158              connected[connected_length] = -1;
1159            }
[44fac1]1160            omFree (cans);
[db83bf]1161            return connected;
1162          }
1163        }
[4f858ce]1164      }
1165      con_checked++;
1166    }
1167    else
1168    {
[db83bf]1169      for(last_cans_pos++; last_cans_pos <= c->n; last_cans_pos++)
[2fc974]1170      {
[db83bf]1171        if(last_cans_pos == c->n)
1172        {
1173          if(connected_length < c->n)
1174          {
1175            connected[connected_length] = -1;
1176          }
1177          omfree (cans);
1178          return connected;
1179        }
1180        if((last_cans_pos == from) || (last_cans_pos == to))
1181          continue;
1182        if(p_LmShortDivisibleBy
1183           (I->m[last_cans_pos], c->short_Exps[last_cans_pos], bound,
1184            neg_bounds_short, c->r))
1185        {
1186          cans[cans_length] = last_cans_pos;
1187          cans_length++;
1188          break;
1189        }
[4f858ce]1190      }
1191      not_yet_found++;
[db83bf]1192      for(int i = 0; i < con_checked; i++)
[2fc974]1193      {
[db83bf]1194        if(has_t_rep (connected[i], last_cans_pos, c))
1195        {
1196          connected[connected_length] = last_cans_pos;
1197          connected_length++;
1198          cans[cans_length - 1] = -1;
1199          --not_yet_found;
1200          if(connected[connected_length - 1] == to)
1201          {
1202            if(connected_length < c->n)
1203            {
1204              connected[connected_length] = -1;
1205            }
[44fac1]1206            omFree (cans);
[db83bf]1207            return connected;
1208          }
1209          break;
1210        }
[4f858ce]1211      }
1212    }
1213  }
[db83bf]1214  if(connected_length < c->n)
[2fc974]1215  {
[410ea0f]1216    connected[connected_length] = -1;
[4f858ce]1217  }
[410ea0f]1218  omfree (cans);
[4f858ce]1219  return connected;
1220}
[410ea0f]1221
[4f858ce]1222#ifdef HEAD_BIN
[db83bf]1223static inline poly p_MoveHead (poly p, omBin b)
[4f858ce]1224{
1225  poly np;
[410ea0f]1226  omTypeAllocBin (poly, np, b);
[aa2b525]1227  memmove (np, p, omSizeWOfBin(b) * sizeof (long));
[410ea0f]1228  omFreeBinAddr (p);
[4f858ce]1229  return np;
1230}
1231#endif
1232
[db83bf]1233static void replace_pair (int &i, int &j, slimgb_alg * c)
[2fd387d]1234{
[db83bf]1235  if(i < 0)
[410ea0f]1236    return;
1237  c->soon_free = NULL;
[2fd387d]1238  int syz_deg;
[410ea0f]1239  poly lm = pOne ();
[2fd387d]1240
[410ea0f]1241  pLcm (c->S->m[i], c->S->m[j], lm);
1242  pSetm (lm);
[31279e]1243
[410ea0f]1244  int *i_con = make_connections (i, j, lm, c);
[31279e]1245
[db83bf]1246  for(int n = 0; ((n < c->n) && (i_con[n] >= 0)); n++)
[5f4463]1247  {
[db83bf]1248    if(i_con[n] == j)
[5f4463]1249    {
[410ea0f]1250      now_t_rep (i, j, c);
[44fac1]1251      omFree (i_con);
[410ea0f]1252      p_Delete (&lm, c->r);
[2fd387d]1253      return;
1254    }
1255  }
1256
[410ea0f]1257  int *j_con = make_connections (j, i, lm, c);
[2fd387d]1258
[2fc974]1259//   if(c->n>1)
1260//   {
[2fd387d]1261//     if (i_con[1]>=0)
1262//       i=i_con[1];
[2fc974]1263//     else
1264//     {
[2fd387d]1265//       if (j_con[1]>=0)
1266//         j=j_con[1];
1267//     }
[410ea0f]1268  // }
[2fd387d]1269
[410ea0f]1270  int sugar = syz_deg = c->pTotaldegree (lm);
[2fc974]1271
[410ea0f]1272  p_Delete (&lm, c->r);
[db83bf]1273  if(c->T_deg_full)             //Sugar
[410ea0f]1274  {
1275    int t_i = c->T_deg_full[i] - c->T_deg[i];
1276    int t_j = c->T_deg_full[j] - c->T_deg[j];
1277    sugar += si_max (t_i, t_j);
1278    //Print("\n max: %d\n",max(t_i,t_j));
1279  }
[2fd387d]1280
[db83bf]1281  for(int m = 0; ((m < c->n) && (i_con[m] >= 0)); m++)
[5f4463]1282  {
[db83bf]1283    if(c->T_deg_full != NULL)
[5f4463]1284    {
[410ea0f]1285      int s1 = c->T_deg_full[i_con[m]] + syz_deg - c->T_deg[i_con[m]];
[db83bf]1286      if(s1 > sugar)
1287        continue;
[2fc974]1288    }
[db83bf]1289    if(c->weighted_lengths[i_con[m]] < c->weighted_lengths[i])
[410ea0f]1290      i = i_con[m];
1291  }
[db83bf]1292  for(int m = 0; ((m < c->n) && (j_con[m] >= 0)); m++)
[410ea0f]1293  {
[db83bf]1294    if(c->T_deg_full != NULL)
[5f4463]1295    {
[410ea0f]1296      int s1 = c->T_deg_full[j_con[m]] + syz_deg - c->T_deg[j_con[m]];
[db83bf]1297      if(s1 > sugar)
1298        continue;
[2fd387d]1299    }
[db83bf]1300    if(c->weighted_lengths[j_con[m]] < c->weighted_lengths[j])
[410ea0f]1301      j = j_con[m];
1302  }
[31279e]1303
[410ea0f]1304  //can also try dependend search
1305  omfree (i_con);
1306  omfree (j_con);
[2fc974]1307  return;
[2fd387d]1308}
[4f858ce]1309
[db83bf]1310static void add_later (poly p, const char *prot, slimgb_alg * c)
[6a2e9c]1311{
[410ea0f]1312  int i = 0;
1313  //check, if it is already in the queue
[31279e]1314
[db83bf]1315  while(c->add_later->m[i] != NULL)
[410ea0f]1316  {
[db83bf]1317    if(p_LmEqual (c->add_later->m[i], p, c->r))
[410ea0f]1318      return;
1319    i++;
1320  }
[db83bf]1321  if(TEST_OPT_PROT)
[410ea0f]1322    PrintS (prot);
1323  c->add_later->m[i] = p;
[03f3269]1324}
[410ea0f]1325
[db83bf]1326static int simple_posInS (kStrategy strat, poly p, int len, wlen_type wlen)
[25061a]1327{
[db83bf]1328  if(strat->sl == -1)
[410ea0f]1329    return 0;
[db83bf]1330  if(strat->lenSw)
[410ea0f]1331    return pos_helper (strat, p, (wlen_type) wlen, (wlen_set) strat->lenSw,
[db83bf]1332                       strat->S);
[410ea0f]1333  return pos_helper (strat, p, len, strat->lenS, strat->S);
[4f858ce]1334}
[25061a]1335
[4f858ce]1336/*2
1337 *if the leading term of p
1338 *divides the leading term of some S[i] it will be canceled
1339 */
[410ea0f]1340static inline void
1341clearS (poly p, unsigned long p_sev, int l, int *at, int *k, kStrategy strat)
[4f858ce]1342{
[410ea0f]1343  assume (p_sev == pGetShortExpVector (p));
[db83bf]1344  if(!pLmShortDivisibleBy (p, p_sev, strat->S[*at], ~strat->sevS[*at]))
[410ea0f]1345    return;
[db83bf]1346  if(l >= strat->lenS[*at])
[410ea0f]1347    return;
[db83bf]1348  if(TEST_OPT_PROT)
[410ea0f]1349    PrintS ("!");
1350  mflush ();
[4f858ce]1351  //pDelete(&strat->S[*at]);
[410ea0f]1352  deleteInS ((*at), strat);
[4f858ce]1353  (*at)--;
1354  (*k)--;
1355//  assume(lenS_correct(strat));
1356}
1357
[db83bf]1358static int iq_crit (const void *ap, const void *bp)
[5f4463]1359{
[410ea0f]1360  sorted_pair_node *a = *((sorted_pair_node **) ap);
1361  sorted_pair_node *b = *((sorted_pair_node **) bp);
1362  assume (a->i > a->j);
1363  assume (b->i > b->j);
1364
[db83bf]1365  if(a->deg < b->deg)
[410ea0f]1366    return -1;
[db83bf]1367  if(a->deg > b->deg)
[410ea0f]1368    return 1;
1369  int comp = pLmCmp (a->lcm_of_lm, b->lcm_of_lm);
[db83bf]1370  if(comp != 0)
[4f858ce]1371    return comp;
[db83bf]1372  if(a->expected_length < b->expected_length)
[410ea0f]1373    return -1;
[db83bf]1374  if(a->expected_length > b->expected_length)
[410ea0f]1375    return 1;
[db83bf]1376  if(a->j > b->j)
[410ea0f]1377    return 1;
[db83bf]1378  if(a->j < b->j)
[410ea0f]1379    return -1;
[4f858ce]1380  return 0;
1381}
[410ea0f]1382
[db83bf]1383static wlen_type coeff_mult_size_estimate (int s1, int s2, ring r)
[2fc974]1384{
[db83bf]1385  if(rField_is_Q (r))
[410ea0f]1386    return s1 + s2;
1387  else
1388    return s1 * s2;
[d20265]1389}
[31279e]1390
[db83bf]1391static wlen_type pair_weighted_length (int i, int j, slimgb_alg * c)
[410ea0f]1392{
[db83bf]1393  if((c->isDifficultField) && (c->eliminationProblem))
[410ea0f]1394  {
1395    int c1 = slim_nsize (p_GetCoeff (c->S->m[i], c->r), c->r);
1396    int c2 = slim_nsize (p_GetCoeff (c->S->m[j], c->r), c->r);
1397    wlen_type el1 = c->weighted_lengths[i] / c1;
1398    assume (el1 != 0);
1399    assume (c->weighted_lengths[i] % c1 == 0);
1400    wlen_type el2 = c->weighted_lengths[j] / c2;
1401    assume (el2 != 0);
1402    assume (c->weighted_lengths[j] % c2 == 0);
1403    //should be * for function fields
1404    //return (c1+c2) * (el1+el2-2);
1405    wlen_type res = coeff_mult_size_estimate (c1, c2, c->r);
1406    res *= el1 + el2 - 2;
1407    return res;
1408
1409  }
[db83bf]1410  if(c->isDifficultField)
[410ea0f]1411  {
1412    //int cs=slim_nsize(p_GetCoeff(c->S->m[i],c->r),c->r)+
1413    //    slim_nsize(p_GetCoeff(c->S->m[j],c->r),c->r);
[db83bf]1414    if(!(TEST_V_COEFSTRAT))
[410ea0f]1415    {
1416      wlen_type cs =
[db83bf]1417        coeff_mult_size_estimate (slim_nsize
1418                                  (p_GetCoeff (c->S->m[i], c->r), c->r),
1419                                  slim_nsize (p_GetCoeff (c->S->m[j], c->r),
1420                                              c->r), c->r);
[410ea0f]1421      return (wlen_type) (c->lengths[i] + c->lengths[j] - 2) * (wlen_type) cs;
[6b4fbf7]1422    }
[410ea0f]1423    else
1424    {
[3ecd5f]1425
[410ea0f]1426      wlen_type cs =
[db83bf]1427        coeff_mult_size_estimate (slim_nsize
1428                                  (p_GetCoeff (c->S->m[i], c->r), c->r),
1429                                  slim_nsize (p_GetCoeff (c->S->m[j], c->r),
1430                                              c->r), c->r);
[410ea0f]1431      cs *= cs;
1432      return (wlen_type) (c->lengths[i] + c->lengths[j] - 2) * (wlen_type) cs;
[3ecd5f]1433    }
[410ea0f]1434  }
[db83bf]1435  if(c->eliminationProblem)
[410ea0f]1436  {
1437
1438    return (c->weighted_lengths[i] + c->weighted_lengths[j] - 2);
1439  }
1440  return c->lengths[i] + c->lengths[j] - 2;
[31279e]1441
[6b4fbf7]1442}
[410ea0f]1443
[db83bf]1444sorted_pair_node **add_to_basis_ideal_quotient (poly h, slimgb_alg * c,
1445                                                int *ip)
[4f858ce]1446{
[410ea0f]1447  p_Test (h, c->r);
1448  assume (h != NULL);
1449  poly got = gcd_of_terms (h, c->r);
[db83bf]1450  if((got != NULL) && (TEST_V_UPTORADICAL))
[410ea0f]1451  {
1452    poly copy = p_Copy (got, c->r);
[03f3269]1453    //p_wrp(got,c->r);
[410ea0f]1454    BOOLEAN changed = monomial_root (got, c->r);
[db83bf]1455    if(changed)
[03f3269]1456    {
[410ea0f]1457      poly div_by = pDivide (copy, got);
1458      poly iter = h;
[db83bf]1459      while(iter)
[410ea0f]1460      {
[db83bf]1461        pExpVectorSub (iter, div_by);
1462        pIter (iter);
[410ea0f]1463      }
1464      p_Delete (&div_by, c->r);
1465      PrintS ("U");
[03f3269]1466    }
[410ea0f]1467    p_Delete (&copy, c->r);
[03f3269]1468  }
1469
[6d7605]1470#define ENLARGE(pointer, type) pointer=(type*) omrealloc(pointer, c->array_lengths*sizeof(type))
[4f858ce]1471//  BOOLEAN corr=lenS_correct(c->strat);
[321283]1472  int sugar;
[410ea0f]1473  int ecart = 0;
[4f858ce]1474  ++(c->n);
1475  ++(c->S->ncols);
[410ea0f]1476  int i, j;
1477  i = c->n - 1;
1478  sorted_pair_node **nodes =
1479    (sorted_pair_node **) omalloc (sizeof (sorted_pair_node *) * i);
1480  int spc = 0;
[db83bf]1481  if(c->n > c->array_lengths)
[410ea0f]1482  {
1483    c->array_lengths = c->array_lengths * 2;
1484    assume (c->array_lengths >= c->n);
1485    ENLARGE (c->T_deg, int);
1486    ENLARGE (c->tmp_pair_lm, poly);
1487    ENLARGE (c->tmp_spn, sorted_pair_node *);
1488
1489    ENLARGE (c->short_Exps, long);
1490    ENLARGE (c->lengths, int);
1491#ifndef HAVE_BOOST
1492#ifndef USE_STDVECBOOL
1493
1494    ENLARGE (c->states, char *);
1495#endif
1496#endif
1497    ENLARGE (c->gcd_of_terms, poly);
[6b4fbf7]1498    //if (c->weighted_lengths!=NULL) {
[410ea0f]1499    ENLARGE (c->weighted_lengths, wlen_type);
[6b4fbf7]1500    //}
[2d8ce9]1501    //ENLARGE(c->S->m,poly);
[6d7605]1502  }
[410ea0f]1503  pEnlargeSet (&c->S->m, c->n - 1, 1);
[db83bf]1504  if(c->T_deg_full)
[410ea0f]1505    ENLARGE (c->T_deg_full, int);
1506  sugar = c->T_deg[i] = c->pTotaldegree (h);
[db83bf]1507  if(c->T_deg_full)
[a0d9be]1508  {
[410ea0f]1509    sugar = c->T_deg_full[i] = c->pTotaldegree_full (h);
1510    ecart = sugar - c->T_deg[i];
1511    assume (ecart >= 0);
[4f858ce]1512  }
[410ea0f]1513  c->tmp_pair_lm[i] = pOne_Special (c->r);
[85eb7d]1514
[44fac1]1515  c->tmp_spn[i] = (sorted_pair_node *) omAlloc (sizeof (sorted_pair_node));
[4f858ce]1516
[410ea0f]1517  c->lengths[i] = pLength (h);
[31279e]1518
[6b4fbf7]1519  //necessary for correct weighted length
[31279e]1520
[db83bf]1521  if(!rField_is_Zp (c->r))
[a0d9be]1522  {
[410ea0f]1523    p_Cleardenom (h, c->r);
[a0d9be]1524    //p_Content(h,c->r); //is a duplicate call, but belongs here
[6b4fbf7]1525  }
[31279e]1526  else
[410ea0f]1527    pNorm (h);
1528  pNormalize (h);
[31279e]1529
[410ea0f]1530  c->weighted_lengths[i] = pQuality (h, c, c->lengths[i]);
1531  c->gcd_of_terms[i] = got;
1532#ifdef HAVE_BOOST
1533  c->states.push_back (dynamic_bitset <> (i));
[31279e]1534
[410ea0f]1535#else
1536#ifdef USE_STDVECBOOL
[5a9e7b]1537
[410ea0f]1538  c->states.push_back (vector < bool > (i));
[5a9e7b]1539
[410ea0f]1540#else
[db83bf]1541  if(i > 0)
[44fac1]1542    c->states[i] = (char *) omAlloc (i * sizeof (char));
[65c4dc]1543  else
[410ea0f]1544    c->states[i] = NULL;
1545#endif
1546#endif
[31279e]1547
[410ea0f]1548  c->S->m[i] = h;
1549  c->short_Exps[i] = p_GetShortExpVector (h, c->r);
[31279e]1550
[85eb7d]1551#undef ENLARGE
[db83bf]1552  if(p_GetComp (h, currRing) <= c->syz_comp)
[2fc974]1553  {
[db83bf]1554    for(j = 0; j < i; j++)
[410ea0f]1555    {
[31279e]1556
[5bf76c]1557
[410ea0f]1558#ifndef HAVE_BOOST
1559      c->states[i][j] = UNCALCULATED;
1560#endif
1561      assume (p_LmDivisibleBy (c->S->m[i], c->S->m[j], c->r) ==
[db83bf]1562              p_LmShortDivisibleBy (c->S->m[i], c->short_Exps[i], c->S->m[j],
1563                                    ~(c->short_Exps[j]), c->r));
[5bf76c]1564
[1f637e]1565      if(__p_GetComp (c->S->m[i], c->r) != __p_GetComp (c->S->m[j], c->r))
[410ea0f]1566      {
[db83bf]1567        //c->states[i][j]=UNCALCULATED;
1568        //WARNUNG: be careful
1569        continue;
[410ea0f]1570      }
[db83bf]1571      else if((!c->nc) && (c->lengths[i] == 1) && (c->lengths[j] == 1))
[410ea0f]1572      {
[db83bf]1573        c->states[i][j] = HASTREP;
[410ea0f]1574      }
[db83bf]1575      else if(((!c->nc) || (c->is_homog && rIsSCA (c->r)))
1576              && (pHasNotCF (c->S->m[i], c->S->m[j])))
[5a9e7b]1577//     else if ((!(c->nc)) &&  (pHasNotCF(c->S->m[i],c->S->m[j])))
[410ea0f]1578      {
[db83bf]1579        c->easy_product_crit++;
1580        c->states[i][j] = HASTREP;
1581        continue;
[410ea0f]1582      }
1583      else
[db83bf]1584        if(extended_product_criterion
1585           (c->S->m[i], c->gcd_of_terms[i], c->S->m[j], c->gcd_of_terms[j],
1586            c))
[410ea0f]1587      {
[db83bf]1588        c->states[i][j] = HASTREP;
1589        c->extended_product_crit++;
1590        //PrintS("E");
[410ea0f]1591      }
[2fc974]1592      //  if (c->states[i][j]==UNCALCULATED)
1593      //  {
[cae954]1594
[db83bf]1595      if((TEST_V_FINDMONOM) && (!c->nc))
[410ea0f]1596      {
[db83bf]1597        //PrintS("COMMU");
1598        //  if (c->lengths[i]==c->lengths[j])
1599        //  {
[03f3269]1600//             poly short_s=ksCreateShortSpoly(c->S->m[i],c->S->m[j],c->r);
[2fc974]1601//             if (short_s==NULL)
1602//             {
[03f3269]1603//                 c->states[i][j]=HASTREP;
[2fc974]1604//             }
1605//             else
[03f3269]1606//             {
1607//                 p_Delete(&short_s, currRing);
1608//             }
1609//         }
[db83bf]1610        if(c->lengths[i] + c->lengths[j] == 3)
1611        {
1612
1613
1614          poly short_s = ksCreateShortSpoly (c->S->m[i], c->S->m[j], c->r);
1615          if(short_s == NULL)
1616          {
1617            c->states[i][j] = HASTREP;
1618          }
1619          else
1620          {
1621            assume (pLength (short_s) == 1);
1622            if(TEST_V_UPTORADICAL)
1623              monomial_root (short_s, c->r);
1624            int iS = kFindDivisibleByInS_easy (c->strat, short_s,
1625                                               p_GetShortExpVector (short_s,
1626                                                                    c->r));
1627            if(iS < 0)
1628            {
1629              //PrintS("N");
1630              if(TRUE)
1631              {
1632                c->states[i][j] = HASTREP;
1633                add_later (short_s, "N", c);
1634              }
1635              else
1636                p_Delete (&short_s, currRing);
1637            }
1638            else
1639            {
1640              if(c->strat->lenS[iS] > 1)
1641              {
1642                //PrintS("O");
1643                if(TRUE)
1644                {
1645                  c->states[i][j] = HASTREP;
1646                  add_later (short_s, "O", c);
1647                }
1648                else
1649                  p_Delete (&short_s, currRing);
1650              }
1651              else
1652                p_Delete (&short_s, currRing);
1653              c->states[i][j] = HASTREP;
1654            }
1655
1656
1657          }
1658        }
[410ea0f]1659      }
[4f858ce]1660      //    if (short_s)
1661      //    {
[410ea0f]1662      assume (spc <= j);
[db83bf]1663      sorted_pair_node *s = c->tmp_spn[spc];    //(sorted_pair_node*) omalloc(sizeof(sorted_pair_node));
[410ea0f]1664      s->i = si_max (i, j);
1665      s->j = si_min (i, j);
1666      assume (s->j == j);
[db83bf]1667      s->expected_length = pair_weighted_length (i, j, c);      //c->lengths[i]+c->lengths[j]-2;
[31279e]1668
[db83bf]1669      poly lm = c->tmp_pair_lm[spc];    //=pOne_Special();
[31279e]1670
[410ea0f]1671      pLcm (c->S->m[i], c->S->m[j], lm);
1672      pSetm (lm);
1673      p_Test (lm, c->r);
1674      s->deg = c->pTotaldegree (lm);
[02e2f7]1675
[db83bf]1676      if(c->T_deg_full)         //Sugar
[410ea0f]1677      {
[db83bf]1678        int t_i = c->T_deg_full[s->i] - c->T_deg[s->i];
1679        int t_j = c->T_deg_full[s->j] - c->T_deg[s->j];
1680        s->deg += si_max (t_i, t_j);
1681        //Print("\n max: %d\n",max(t_i,t_j));
[410ea0f]1682      }
1683      p_Test (lm, c->r);
1684      s->lcm_of_lm = lm;
1685      //          pDelete(&short_s);
1686      //assume(lm!=NULL);
1687      nodes[spc] = s;
1688      spc++;
1689
1690      // }
1691      //else
1692      //{
1693      //c->states[i][j]=HASTREP;
1694      //}
[4f858ce]1695    }
[db83bf]1696  }                             //if syz_comp end
[31279e]1697
[410ea0f]1698  assume (spc <= i);
[4f858ce]1699  //now ideal quotient crit
[410ea0f]1700  qsort (nodes, spc, sizeof (sorted_pair_node *), iq_crit);
[31279e]1701
[410ea0f]1702  sorted_pair_node **nodes_final =
1703    (sorted_pair_node **) omalloc (sizeof (sorted_pair_node *) * i);
1704  int spc_final = 0;
1705  j = 0;
[db83bf]1706  while(j < spc)
[4f858ce]1707  {
[410ea0f]1708    int lower = j;
[4f858ce]1709    int upper;
[410ea0f]1710    BOOLEAN has = FALSE;
[db83bf]1711    for(upper = lower + 1; upper < spc; upper++)
[4f858ce]1712    {
[db83bf]1713      if(!pLmEqual (nodes[lower]->lcm_of_lm, nodes[upper]->lcm_of_lm))
[4f858ce]1714      {
[db83bf]1715        break;
[4f858ce]1716      }
[db83bf]1717      if(has_t_rep (nodes[upper]->i, nodes[upper]->j, c))
1718        has = TRUE;
[4f858ce]1719    }
[410ea0f]1720    upper = upper - 1;
[4f858ce]1721    int z;
[410ea0f]1722    assume (spc_final <= j);
[db83bf]1723    for(z = 0; z < spc_final; z++)
[4f858ce]1724    {
[db83bf]1725      if(p_LmDivisibleBy
1726         (nodes_final[z]->lcm_of_lm, nodes[lower]->lcm_of_lm, c->r))
[4f858ce]1727      {
[db83bf]1728        has = TRUE;
1729        break;
[4f858ce]1730      }
1731    }
[31279e]1732
[db83bf]1733    if(has)
[4f858ce]1734    {
[db83bf]1735      for(; lower <= upper; lower++)
[4f858ce]1736      {
[db83bf]1737        //free_sorted_pair_node(nodes[lower],c->r);
1738        //omfree(nodes[lower]);
1739        nodes[lower] = NULL;
[4f858ce]1740      }
[410ea0f]1741      j = upper + 1;
[4f858ce]1742      continue;
1743    }
1744    else
1745    {
[410ea0f]1746      p_Test (nodes[lower]->lcm_of_lm, c->r);
1747      nodes[lower]->lcm_of_lm = pCopy (nodes[lower]->lcm_of_lm);
[1f637e]1748      assume (__p_GetComp (c->S->m[nodes[lower]->i], c->r) ==
1749              __p_GetComp (c->S->m[nodes[lower]->j], c->r));
[410ea0f]1750      nodes_final[spc_final] =
[44fac1]1751        (sorted_pair_node *) omAlloc (sizeof (sorted_pair_node));
[410ea0f]1752
1753      *(nodes_final[spc_final++]) = *(nodes[lower]);
[02e2f7]1754      //c->tmp_spn[nodes[lower]->j]=(sorted_pair_node*) omalloc(sizeof(sorted_pair_node));
[410ea0f]1755      nodes[lower] = NULL;
[db83bf]1756      for(lower = lower + 1; lower <= upper; lower++)
[4f858ce]1757      {
[db83bf]1758        //  free_sorted_pair_node(nodes[lower],c->r);
1759        //omfree(nodes[lower]);
1760        nodes[lower] = NULL;
[4f858ce]1761      }
[410ea0f]1762      j = upper + 1;
[4f858ce]1763      continue;
1764    }
1765  }
1766
1767  //  Print("i:%d,spc_final:%d",i,spc_final);
1768
[410ea0f]1769  assume (spc_final <= spc);
[44fac1]1770  omFree (nodes);
[410ea0f]1771  nodes = NULL;
[4f858ce]1772
[410ea0f]1773  add_to_reductors (c, h, c->lengths[c->n - 1], ecart, TRUE);
[4f858ce]1774  //i=posInS(c->strat,c->strat->sl,h,0 ecart);
[db83bf]1775  if(!(c->nc))
[2fc974]1776  {
[db83bf]1777    if(c->lengths[c->n - 1] == 1)
[410ea0f]1778      shorten_tails (c, c->S->m[c->n - 1]);
[d491e3]1779  }
[4f858ce]1780  //you should really update c->lengths, c->strat->lenS, and the oder of polys in strat if you sort after lengths
1781
1782  //for(i=c->strat->sl; i>0;i--)
1783  //  if(c->strat->lenS[i]<c->strat->lenS[i-1]) printf("fehler bei %d\n",i);
[db83bf]1784  if(c->Rcounter > 50)
[410ea0f]1785  {
1786    c->Rcounter = 0;
1787    cleanS (c->strat, c);
[4f858ce]1788  }
[5a9e7b]1789
[1daae71]1790#ifdef HAVE_PLURAL
[5a9e7b]1791  // for SCA:
1792  // here write at the end of nodes_final[spc_final,...,spc_final+lmdeg-1]
[db83bf]1793  if(rIsSCA (c->r))
[5a9e7b]1794  {
[410ea0f]1795    const poly pNext = pNext (h);
[5a9e7b]1796
[db83bf]1797    if(pNext != NULL)
[5a9e7b]1798    {
1799      // for additional polynomials
[410ea0f]1800      const unsigned int m_iFirstAltVar = scaFirstAltVar (c->r);
1801      const unsigned int m_iLastAltVar = scaLastAltVar (c->r);
[5a9e7b]1802
[db83bf]1803      int N =                   // c->r->N;
1804        m_iLastAltVar - m_iFirstAltVar + 1;     // should be enough
[5a9e7b]1805      // TODO: but we may also use got = gcd({m}_{m\in f}))!
1806
[db83bf]1807      poly *array_arg = (poly *) omalloc (N * sizeof (poly));   // !
[410ea0f]1808      int j = 0;
[5a9e7b]1809
1810
[db83bf]1811      for(unsigned short v = m_iFirstAltVar; v <= m_iLastAltVar; v++)
1812        // for all x_v | Ann(lm(h))
1813        if(p_GetExp (h, v, c->r))       // TODO: use 'got' here!
1814        {
1815          assume (p_GetExp (h, v, c->r) == 1);
[5a9e7b]1816
[db83bf]1817          poly p = sca_pp_Mult_xi_pp (v, pNext, c->r);  // x_v * h;
[5a9e7b]1818
[db83bf]1819          if(p != NULL)         // if (x_v * h != 0)
1820            array_arg[j++] = p;
1821        }                       // for all x_v | Ann(lm(h))
[5a9e7b]1822
[410ea0f]1823      c->introduceDelayedPairs (array_arg, j);
[5a9e7b]1824
[44fac1]1825      omFree (array_arg);       // !!!
[5a9e7b]1826    }
[a610ee]1827//     PrintS("Saturation - done!!!\n");
[1daae71]1828  }
1829#endif // if SCAlgebra
[5a9e7b]1830
1831
[db83bf]1832  if(!ip)
[2fc974]1833  {
[410ea0f]1834    qsort (nodes_final, spc_final, sizeof (sorted_pair_node *),
[db83bf]1835           tgb_pair_better_gen2);
[31279e]1836
1837
[410ea0f]1838    c->apairs =
1839      spn_merge (c->apairs, c->pair_top + 1, nodes_final, spc_final, c);
1840    c->pair_top += spc_final;
1841    clean_top_of_pair_list (c);
[44fac1]1842    omFree (nodes_final);
[4f858ce]1843    return NULL;
1844  }
1845  {
[410ea0f]1846    *ip = spc_final;
[4f858ce]1847    return nodes_final;
1848  }
1849}
1850
[db83bf]1851static poly redNF2 (poly h, slimgb_alg * c, int &len, number & m, int n)
[4f858ce]1852{
[410ea0f]1853  m = nInit (1);
[db83bf]1854  if(h == NULL)
[410ea0f]1855    return NULL;
[4f858ce]1856
[410ea0f]1857  assume (len == pLength (h));
1858  kStrategy strat = c->strat;
[db83bf]1859  if(0 > strat->sl)
[4f858ce]1860  {
1861    return h;
1862  }
1863  int j;
[31279e]1864
[410ea0f]1865  LObject P (h);
1866  P.SetShortExpVector ();
1867  P.bucket = kBucketCreate (currRing);
[4f858ce]1868  // BOOLEAN corr=lenS_correct(strat);
[410ea0f]1869  kBucketInit (P.bucket, P.p, len /*pLength(P.p) */ );
[9cd599]1870  //wlen_set lenSw=(wlen_set) c->strat->lenS;
1871  //FIXME: plainly wrong
1872  //strat->lenS;
1873  //if (strat->lenSw!=NULL)
1874  //  lenSw=strat->lenSw;
[4f858ce]1875  //int max_pos=simple_posInS(strat,P.p);
1876  loop
[391323]1877  {
[410ea0f]1878    //int dummy=strat->sl;
1879    j = kFindDivisibleByInS_easy (strat, P.p, P.sev);
1880    //j=kFindDivisibleByInS(strat,&dummy,&P);
[db83bf]1881    if((j >= 0) && ((!n) ||
1882                    ((strat->lenS[j] <= n) &&
1883                     ((strat->lenSw == NULL) || (strat->lenSw[j] <= n)))))
[410ea0f]1884    {
1885      nNormalize (pGetCoeff (P.p));
[4f858ce]1886#ifdef KDEBUG
[db83bf]1887      if(TEST_OPT_DEBUG)
[410ea0f]1888      {
[db83bf]1889        PrintS ("red:");
1890        wrp (h);
1891        PrintS (" with ");
1892        wrp (strat->S[j]);
[410ea0f]1893      }
[4f858ce]1894#endif
[31279e]1895
[410ea0f]1896      number coef = kBucketPolyRed (P.bucket, strat->S[j],
[db83bf]1897                                    strat->lenS[j] /*pLength(strat->S[j]) */ ,
1898                                    strat->kNoether);
[410ea0f]1899      number m2 = nMult (m, coef);
1900      nDelete (&m);
1901      m = m2;
1902      nDelete (&coef);
1903      h = kBucketGetLm (P.bucket);
1904
[db83bf]1905      if(h == NULL)
[410ea0f]1906      {
[db83bf]1907        len = 0;
1908        kBucketDestroy (&P.bucket);
1909        return NULL;
[4f858ce]1910      }
[410ea0f]1911      P.p = h;
1912      P.t_p = NULL;
1913      P.SetShortExpVector ();
1914#ifdef KDEBUG
[db83bf]1915      if(TEST_OPT_DEBUG)
[4f858ce]1916      {
[db83bf]1917        PrintS ("\nto:");
1918        wrp (h);
1919        PrintLn ();
[4f858ce]1920      }
[410ea0f]1921#endif
1922    }
1923    else
1924    {
1925      kBucketClear (P.bucket, &(P.p), &len);
1926      kBucketDestroy (&P.bucket);
1927      pNormalize (P.p);
1928      assume (len == (pLength (P.p)));
1929      return P.p;
[4f858ce]1930    }
[410ea0f]1931  }
[4f858ce]1932}
1933
[db83bf]1934static poly redTailShort (poly h, kStrategy strat)
[2fc974]1935{
[db83bf]1936  if(h == NULL)
1937    return NULL;                //n_Init(1,currRing);
1938  if(TEST_V_MODPSOLVSB)
[2fc974]1939  {
[410ea0f]1940    bit_reduce (pNext (h), strat->tailRing);
[03f3269]1941  }
[4f858ce]1942  int i;
[410ea0f]1943  int len = pLength (h);
[db83bf]1944  for(i = 0; i <= strat->sl; i++)
[2fc974]1945  {
[db83bf]1946    if((strat->lenS[i] > 2)
1947       || ((strat->lenSw != NULL) && (strat->lenSw[i] > 2)))
[4f858ce]1948      break;
1949  }
[410ea0f]1950  return (redNFTail (h, i - 1, strat, len));
[4f858ce]1951}
1952
[db83bf]1953static void line_of_extended_prod (int fixpos, slimgb_alg * c)
[2fc974]1954{
[db83bf]1955  if(c->gcd_of_terms[fixpos] == NULL)
[4f858ce]1956  {
[410ea0f]1957    c->gcd_of_terms[fixpos] = gcd_of_terms (c->S->m[fixpos], c->r);
[db83bf]1958    if(c->gcd_of_terms[fixpos])
[4f858ce]1959    {
1960      int i;
[db83bf]1961      for(i = 0; i < fixpos; i++)
1962        if((c->states[fixpos][i] != HASTREP)
1963           &&
1964           (extended_product_criterion
1965            (c->S->m[fixpos], c->gcd_of_terms[fixpos], c->S->m[i],
1966             c->gcd_of_terms[i], c)))
1967        {
1968          c->states[fixpos][i] = HASTREP;
1969          c->extended_product_crit++;
1970        }
1971      for(i = fixpos + 1; i < c->n; i++)
1972        if((c->states[i][fixpos] != HASTREP)
1973           &&
1974           (extended_product_criterion
1975            (c->S->m[fixpos], c->gcd_of_terms[fixpos], c->S->m[i],
1976             c->gcd_of_terms[i], c)))
1977        {
1978          c->states[i][fixpos] = HASTREP;
1979          c->extended_product_crit++;
1980        }
[4f858ce]1981    }
1982  }
1983}
[410ea0f]1984
[db83bf]1985static void c_S_element_changed_hook (int pos, slimgb_alg * c)
[2fc974]1986{
[410ea0f]1987  length_one_crit (c, pos, c->lengths[pos]);
[db83bf]1988  if(!c->nc)
[410ea0f]1989    line_of_extended_prod (pos, c);
[4f858ce]1990}
[410ea0f]1991
1992class poly_tree_node
1993{
[4f858ce]1994public:
1995  poly p;
[410ea0f]1996  poly_tree_node *l;
1997  poly_tree_node *r;
[4f858ce]1998  int n;
[db83bf]1999  poly_tree_node (int sn):l (NULL), r (NULL), n (sn)
[410ea0f]2000  {
2001  }
[4f858ce]2002};
[410ea0f]2003class exp_number_builder
2004{
[4f858ce]2005public:
[410ea0f]2006  poly_tree_node * top_level;
[4f858ce]2007  int n;
[410ea0f]2008  int get_n (poly p);
[db83bf]2009  exp_number_builder ():top_level (0), n (0)
[410ea0f]2010  {
2011  }
[4f858ce]2012};
[db83bf]2013int exp_number_builder::get_n (poly p)
[2fc974]2014{
[410ea0f]2015  poly_tree_node **node = &top_level;
[db83bf]2016  while(*node != NULL)
[410ea0f]2017  {
2018    int c = pLmCmp (p, (*node)->p);
[db83bf]2019    if(c == 0)
[410ea0f]2020      return (*node)->n;
[db83bf]2021    if(c == -1)
[410ea0f]2022      node = &((*node)->r);
[4f858ce]2023    else
[410ea0f]2024      node = &((*node)->l);
[4f858ce]2025  }
[410ea0f]2026  (*node) = new poly_tree_node (n);
[4f858ce]2027  n++;
[410ea0f]2028  (*node)->p = pLmInit (p);
[4f858ce]2029  return (*node)->n;
2030}
2031
2032//mac_polys exp are smaller iff they are greater by monomial ordering
2033//corresponding to solving linear equations notation
[196cdf]2034
[b553e5]2035//! obsolete
[410ea0f]2036struct int_poly_pair
2037{
[4f858ce]2038  poly p;
2039  int n;
2040};
2041
[196cdf]2042
[b553e5]2043//! obsolete
[db83bf]2044void t2ippa_rec (poly * ip, int *ia, poly_tree_node * k, int &offset)
[2fc974]2045{
[db83bf]2046  if(!k)
[410ea0f]2047    return;
2048  t2ippa_rec (ip, ia, k->l, offset);
2049  ip[offset] = k->p;
2050  ia[k->n] = offset;
2051  ++offset;
[4f858ce]2052
[410ea0f]2053  t2ippa_rec (ip, ia, k->r, offset);
2054  delete k;
2055}
[196cdf]2056
[b553e5]2057//! obsolete
[db83bf]2058void t2ippa (poly * ip, int *ia, exp_number_builder & e)
[2fc974]2059{
[4f858ce]2060
[410ea0f]2061  int o = 0;
2062  t2ippa_rec (ip, ia, e.top_level, o);
[4f858ce]2063}
[410ea0f]2064
[db83bf]2065int anti_poly_order (const void *a, const void *b)
[2fc974]2066{
[410ea0f]2067  return -pLmCmp (((int_poly_pair *) a)->p, ((int_poly_pair *) b)->p);
[4f858ce]2068}
[81306a]2069
[db83bf]2070BOOLEAN is_valid_ro (red_object & ro)
[2fc974]2071{
[410ea0f]2072  red_object r2 = ro;
2073  ro.validate ();
[db83bf]2074  if((r2.p != ro.p) || (r2.sev != ro.sev))
[410ea0f]2075    return FALSE;
[4f858ce]2076  return TRUE;
2077}
[410ea0f]2078
[db83bf]2079int terms_sort_crit (const void *a, const void *b)
[2fc974]2080{
[410ea0f]2081  return -pLmCmp (*((poly *) a), *((poly *) b));
[b68048]2082}
[410ea0f]2083
[db83bf]2084#if 0                           // currently unused
2085static void unify_terms (poly * terms, int &sum)
[2fc974]2086{
[db83bf]2087  if(sum == 0)
[410ea0f]2088    return;
2089  int last = 0;
2090  int curr = 1;
[db83bf]2091  while(curr < sum)
[2fc974]2092  {
[db83bf]2093    if(!(pLmEqual (terms[curr], terms[last])))
[2fc974]2094    {
[410ea0f]2095      terms[++last] = terms[curr];
[b68048]2096    }
2097    ++curr;
2098  }
[410ea0f]2099  sum = last + 1;
[b68048]2100}
[a41623]2101#endif
[db83bf]2102#if 0                           // currently unused
[410ea0f]2103static void
2104export_mat (number * number_array, int pn, int tn, const char *format_str,
[db83bf]2105            int mat_nr)
[2fc974]2106{
[b68048]2107  char matname[20];
[410ea0f]2108  sprintf (matname, format_str, mat_nr);
2109  FILE *out = fopen (matname, "w");
2110  int i, j;
2111  fprintf (out, "mat=[\n");
[db83bf]2112  for(i = 0; i < pn; i++)
[410ea0f]2113  {
2114    fprintf (out, "[\n");
[db83bf]2115    for(j = 0; j < tn; j++)
[6a2e9c]2116    {
[db83bf]2117      if(j > 0)
[cf74cd6]2118      {
[db83bf]2119        fprintf (out, ", ");
[b68048]2120      }
[410ea0f]2121      fprintf (out, "%i", npInt (number_array[i * tn + j], currRing));
[b68048]2122    }
[db83bf]2123    if(i < pn - 1)
[410ea0f]2124      fprintf (out, "],\n");
[b68048]2125    else
[410ea0f]2126      fprintf (out, "],\n");
[b68048]2127  }
[410ea0f]2128  fprintf (out, "]\n");
2129  fclose (out);
[b68048]2130}
[a41623]2131#endif
[abce2e]2132//typedef unsigned short number_type;
[ebe987]2133
[e9ade0f]2134
[ebe987]2135#ifdef USE_NORO
2136#ifndef NORO_CACHE
[410ea0f]2137static void
2138linalg_step_modp (poly * p, poly * p_out, int &pn, poly * terms, int tn,
[db83bf]2139                  slimgb_alg * c)
[2fc974]2140{
[410ea0f]2141  static int export_n = 0;
2142  assume (terms[tn - 1] != NULL);
2143  assume (rField_is_Zp (c->r));
[ebe987]2144  //I don't do deletes, copies of number_types ...
[db83bf]2145  const number_type zero = 0;   //npInit(0);
[410ea0f]2146  int array_size = pn * tn;
2147  number_type *number_array =
2148    (number_type *) omalloc (pn * tn * sizeof (number_type));
[b68048]2149  int i;
[db83bf]2150  for(i = 0; i < array_size; i++)
[2fc974]2151  {
[410ea0f]2152    number_array[i] = zero;
[b68048]2153  }
[db83bf]2154  for(i = 0; i < pn; i++)
[2fc974]2155  {
[410ea0f]2156    poly h = p[i];
[8ba479]2157    //int base=tn*i;
[410ea0f]2158    write_poly_to_row (number_array + tn * i, h, terms, tn, c->r);
[8ba479]2159
[b68048]2160  }
2161#if 0
2162  //export matrix
[410ea0f]2163  export_mat (number_array, pn, tn, "mat%i.py", ++export_n);
[b68048]2164#endif
[410ea0f]2165  int rank = pn;
2166  simplest_gauss_modp (number_array, rank, tn);
2167  int act_row = 0;
2168  int p_pos = 0;
[db83bf]2169  for(i = 0; i < pn; i++)
[2fc974]2170  {
[410ea0f]2171    poly h = NULL;
[b68048]2172    int j;
[410ea0f]2173    int base = tn * i;
2174    number *row = number_array + base;
2175    h = row_to_poly (row, terms, tn, c->r);
[6a2e9c]2176
[db83bf]2177    if(h != NULL)
[410ea0f]2178    {
2179      p_out[p_pos++] = h;
2180    }
[b68048]2181  }
[410ea0f]2182  pn = p_pos;
[b68048]2183  //assert(p_pos==rank)
[db83bf]2184  while(p_pos < pn)
[2fc974]2185  {
[410ea0f]2186    p_out[p_pos++] = NULL;
[b68048]2187  }
2188#if 0
[410ea0f]2189  export_mat (number_array, pn, tn, "mat%i.py", ++export_n);
[b68048]2190#endif
2191}
[ebe987]2192#endif
[6a2e9c]2193#endif
[db83bf]2194static void mass_add (poly * p, int pn, slimgb_alg * c)
[2fc974]2195{
[410ea0f]2196  int j;
2197  int *ibuf = (int *) omalloc (pn * sizeof (int));
2198  sorted_pair_node ***sbuf =
2199    (sorted_pair_node ***) omalloc (pn * sizeof (sorted_pair_node **));
[db83bf]2200  for(j = 0; j < pn; j++)
[410ea0f]2201  {
2202    p_Test (p[j], c->r);
2203    sbuf[j] = add_to_basis_ideal_quotient (p[j], c, ibuf + j);
2204  }
2205  int sum = 0;
[db83bf]2206  for(j = 0; j < pn; j++)
[410ea0f]2207  {
2208    sum += ibuf[j];
2209  }
2210  sorted_pair_node **big_sbuf =
2211    (sorted_pair_node **) omalloc (sum * sizeof (sorted_pair_node *));
2212  int partsum = 0;
[db83bf]2213  for(j = 0; j < pn; j++)
[410ea0f]2214  {
2215    memmove (big_sbuf + partsum, sbuf[j],
[db83bf]2216             ibuf[j] * sizeof (sorted_pair_node *));
[44fac1]2217    omFree (sbuf[j]);
[410ea0f]2218    partsum += ibuf[j];
2219  }
2220
2221  qsort (big_sbuf, sum, sizeof (sorted_pair_node *), tgb_pair_better_gen2);
2222  c->apairs = spn_merge (c->apairs, c->pair_top + 1, big_sbuf, sum, c);
2223  c->pair_top += sum;
2224  clean_top_of_pair_list (c);
[44fac1]2225  omFree (big_sbuf);
[410ea0f]2226  omfree (sbuf);
2227  omfree (ibuf);
2228  //omfree(buf);
2229#ifdef TGB_DEBUG
2230  int z;
[db83bf]2231  for(z = 1; z <= c->pair_top; z++)
[410ea0f]2232  {
2233    assume (pair_better (c->apairs[z], c->apairs[z - 1], c));
2234  }
2235#endif
[6a2e9c]2236
[b68048]2237}
[89b59f]2238
2239#ifdef NORO_CACHE
[5ac8e5]2240#ifndef NORO_NON_POLY
[db83bf]2241void NoroCache::evaluateRows ()
[2fc974]2242{
[0cf2ccd]2243  //after that can evaluate placeholders
2244  int i;
[44fac1]2245  buffer = (number *) omAlloc (nIrreducibleMonomials * sizeof (number));
[db83bf]2246  for(i = 0; i < root.branches_len; i++)
[2fc974]2247  {
[410ea0f]2248    evaluateRows (1, root.branches[i]);
[0cf2ccd]2249  }
[44fac1]2250  omFree (buffer);
[410ea0f]2251  buffer = NULL;
[0cf2ccd]2252}
[410ea0f]2253
[db83bf]2254void NoroCache::evaluateRows (int level, NoroCacheNode * node)
[2fc974]2255{
[410ea0f]2256  assume (level >= 0);
[db83bf]2257  if(node == NULL)
[410ea0f]2258    return;
[1f637e]2259  if(level < (currRing->N))
[2fc974]2260  {
[410ea0f]2261    int i, sum;
[db83bf]2262    for(i = 0; i < node->branches_len; i++)
[2fc974]2263    {
[410ea0f]2264      evaluateRows (level + 1, node->branches[i]);
[0cf2ccd]2265    }
[2fc974]2266  }
2267  else
2268  {
[410ea0f]2269    DataNoroCacheNode *dn = (DataNoroCacheNode *) node;
[db83bf]2270    if(dn->value_len != backLinkCode)
[2fc974]2271    {
[410ea0f]2272      poly p = dn->value_poly;
2273#ifndef NORO_SPARSE_ROWS_PRE
2274      dn->row = new DenseRow ();
2275      DenseRow *row = dn->row;
2276      memset (buffer, 0, sizeof (number) * nIrreducibleMonomials);
2277
[db83bf]2278      if(p == NULL)
[410ea0f]2279      {
[db83bf]2280        row->array = NULL;
2281        row->begin = 0;
2282        row->end = 0;
2283        return;
[410ea0f]2284      }
2285      int i = 0;
[06ee23]2286      int idx;
[410ea0f]2287      number *a = buffer;
[db83bf]2288      while(p)
[2fc974]2289      {
[db83bf]2290        DataNoroCacheNode *ref = getCacheReference (p);
2291
2292        idx = ref->term_index;
2293        assume (idx >= 0);
2294        a[idx] = p_GetCoeff (p, currRing);
2295        if(i == 0)
2296          row->begin = idx;
2297        i++;
2298        pIter (p);
[06ee23]2299      }
[410ea0f]2300      row->end = idx + 1;
2301      assume (row->end > row->begin);
2302      int len = row->end - row->begin;
2303      row->array = (number *) omalloc ((len) * sizeof (number));
2304      memcpy (row->array, a + row->begin, len * sizeof (number));
2305#else
2306      assume (dn->value_len == pLength (dn->value_poly));
2307      dn->row = new SparseRow (dn->value_len);
2308      SparseRow *row = dn->row;
2309      int i = 0;
[db83bf]2310      while(p)
[2fc974]2311      {
[db83bf]2312        DataNoroCacheNode *ref = getCacheReference (p);
2313
2314        int idx = ref->term_index;
2315        assume (idx >= 0);
2316        row->idx_array[i] = idx;
2317        row->coef_array[i] = p_GetCoeff (p, currRing);
2318        i++;
2319        pIter (p);
[9f11ab]2320      }
[db83bf]2321      if(i != dn->value_len)
[2fc974]2322      {
[db83bf]2323        PrintS ("F4 calc wrong, as poly len was wrong\n");
[9f11ab]2324      }
[410ea0f]2325      assume (i == dn->value_len);
2326#endif
[6a2e9c]2327    }
[0cf2ccd]2328  }
2329}
[5ac8e5]2330
[410ea0f]2331void
[db83bf]2332  NoroCache::evaluatePlaceHolder (number * row,
2333                                  std::vector < NoroPlaceHolder >
2334                                  &place_holders)
[2fc974]2335{
[0cf2ccd]2336  int i;
[410ea0f]2337  int s = place_holders.size ();
[db83bf]2338  for(i = 0; i < s; i++)
[2fc974]2339  {
[410ea0f]2340    DataNoroCacheNode *ref = place_holders[i].ref;
2341    number coef = place_holders[i].coef;
[db83bf]2342    if(ref->value_len == backLinkCode)
[2fc974]2343    {
[410ea0f]2344      row[ref->term_index] = npAddM (row[ref->term_index], coef);
[2fc974]2345    }
2346    else
2347    {
[410ea0f]2348#ifndef NORO_SPARSE_ROWS_PRE
2349      DenseRow *ref_row = ref->row;
[db83bf]2350      if(ref_row == NULL)
2351        continue;
[410ea0f]2352      number *ref_begin = ref_row->array;
2353      number *ref_end = ref_row->array + (ref_row->end - ref_row->begin);
2354      number *my_pos = row + ref_row->begin;
[06ee23]2355      //TODO npisOne distinction
[db83bf]2356      if(!(npIsOne (coef)))
[2fc974]2357      {
[db83bf]2358        while(ref_begin != ref_end)
2359        {
[f23852]2360
[db83bf]2361          *my_pos = npAddM (*my_pos, npMult (coef, *ref_begin));
2362          ++ref_begin;
2363          ++my_pos;
2364        }
[f23852]2365      }
[2fc974]2366      else
2367      {
[db83bf]2368        while(ref_begin != ref_end)
2369        {
[f23852]2370
[db83bf]2371          *my_pos = npAddM (*my_pos, *ref_begin);
2372          ++ref_begin;
2373          ++my_pos;
2374        }
[f23852]2375      }
2376
[410ea0f]2377#else
2378      SparseRow *ref_row = ref->row;
[db83bf]2379      if(ref_row == NULL)
2380        continue;
[410ea0f]2381      int n = ref_row->len;
2382      int j;
2383      int *idx_array = ref_row->idx_array;
2384      number *coef_array = ref_row->coef_array;
[db83bf]2385      for(j = 0; j < n; j++)
[410ea0f]2386      {
[db83bf]2387        int idx = idx_array[j];
2388        number ref_coef = coef_array[j];
2389        row[idx] = npAddM (row[idx], npMult (coef, ref_coef));
[410ea0f]2390      }
2391#endif
[9f11ab]2392    }
[e01da4]2393  }
[0cf2ccd]2394}
[5ac8e5]2395#endif
2396
2397//poly noro_red_non_unique(poly p, int &len, NoroCache* cache,slimgb_alg* c);
[89b59f]2398
[5ac8e5]2399#ifndef NORO_NON_POLY
[410ea0f]2400MonRedRes
2401noro_red_mon (poly t, BOOLEAN force_unique, NoroCache * cache, slimgb_alg * c)
[2fc974]2402{
[fb0a2c0]2403  MonRedRes res_holder;
[0cf2ccd]2404
[89b59f]2405  //wrp(t);
[410ea0f]2406  res_holder.changed = TRUE;
[db83bf]2407  if(force_unique)
[2fc974]2408  {
[410ea0f]2409    DataNoroCacheNode *ref = cache->getCacheReference (t);
[db83bf]2410    if(ref != NULL)
[2fc974]2411    {
[410ea0f]2412      res_holder.len = ref->value_len;
[db83bf]2413      if(res_holder.len == NoroCache::backLinkCode)
[2fc974]2414      {
[db83bf]2415        res_holder.len = 1;
[b16a613]2416      }
[410ea0f]2417      res_holder.coef = p_GetCoeff (t, c->r);
2418      res_holder.p = ref->value_poly;
2419      res_holder.ref = ref;
2420      res_holder.onlyBorrowed = TRUE;
2421      res_holder.changed = TRUE;
2422      p_Delete (&t, c->r);
[b16a613]2423      return res_holder;
2424    }
[2fc974]2425  }
2426  else
2427  {
[0cf2ccd]2428    BOOLEAN succ;
[db83bf]2429    poly cache_lookup = cache->lookup (t, succ, res_holder.len);        //don't own this yet
2430    if(succ)
[2fc974]2431    {
[db83bf]2432      if(cache_lookup == t)
[2fc974]2433      {
[db83bf]2434        //know they are equal
2435        //res_holder.len=1;
[0cf2ccd]2436
[db83bf]2437        res_holder.changed = FALSE;
2438        res_holder.p = t;
2439        res_holder.coef = npInit (1);
[6a2e9c]2440
[db83bf]2441        res_holder.onlyBorrowed = FALSE;
2442        return res_holder;
[0cf2ccd]2443      }
[421e42]2444
[410ea0f]2445      res_holder.coef = p_GetCoeff (t, c->r);
2446      p_Delete (&t, c->r);
[421e42]2447
[410ea0f]2448      res_holder.p = cache_lookup;
[0cf2ccd]2449
[410ea0f]2450      res_holder.onlyBorrowed = TRUE;
[0cf2ccd]2451      return res_holder;
[421e42]2452
[0cf2ccd]2453    }
[b16a613]2454  }
[0cf2ccd]2455
[410ea0f]2456  unsigned long sev = p_GetShortExpVector (t, currRing);
2457  int i = kFindDivisibleByInS_easy (c->strat, t, sev);
[db83bf]2458  if(i >= 0)
[77afcd]2459  {
[410ea0f]2460    number coef_bak = p_GetCoeff (t, c->r);
[0cf2ccd]2461
[410ea0f]2462    p_SetCoeff (t, npInit (1), c->r);
2463    assume (npIsOne (p_GetCoeff (c->strat->S[i], c->r)));
2464    number coefstrat = p_GetCoeff (c->strat->S[i], c->r);
[0cf2ccd]2465
[410ea0f]2466    //poly t_copy_mon=p_Copy(t,c->r);
2467    poly exp_diff = cache->temp_term;
2468    p_ExpVectorDiff (exp_diff, t, c->strat->S[i], c->r);
2469    p_SetCoeff (exp_diff, npNeg (nInvers (coefstrat)), c->r);
2470    // nInvers may be npInvers or nvInvers
2471    p_Setm (exp_diff, c->r);
2472    assume (c->strat->S[i] != NULL);
2473    //poly t_to_del=t;
[0cf2ccd]2474    poly res;
[410ea0f]2475    res = pp_Mult_mm (pNext (c->strat->S[i]), exp_diff, c->r);
2476
2477    res_holder.len = c->strat->lenS[i] - 1;
2478    res = noro_red_non_unique (res, res_holder.len, cache, c);
2479
2480    DataNoroCacheNode *ref = cache->insert (t, res, res_holder.len);
2481    p_Delete (&t, c->r);
2482    //p_Delete(&t_copy_mon,c->r);
2483    //res=pMult_nn(res,coef_bak);
2484    res_holder.changed = TRUE;
2485    res_holder.p = res;
2486    res_holder.coef = coef_bak;
2487    res_holder.onlyBorrowed = TRUE;
2488    res_holder.ref = ref;
[0cf2ccd]2489    return res_holder;
[2fc974]2490  }
2491  else
2492  {
[410ea0f]2493    number coef_bak = p_GetCoeff (t, c->r);
2494    number one = npInit (1);
2495    p_SetCoeff (t, one, c->r);
2496    res_holder.len = 1;
[db83bf]2497    if(!(force_unique))
[2fc974]2498    {
[410ea0f]2499      res_holder.ref = cache->insert (t, t, res_holder.len);
2500      p_SetCoeff (t, coef_bak, c->r);
[fb0a2c0]2501      //return t;
[0cf2ccd]2502
[b16a613]2503      //we need distinction
[410ea0f]2504      res_holder.changed = FALSE;
2505      res_holder.p = t;
[0cf2ccd]2506
[410ea0f]2507      res_holder.coef = npInit (1);
2508      res_holder.onlyBorrowed = FALSE;
[fb0a2c0]2509      return res_holder;
[2fc974]2510    }
2511    else
2512    {
[410ea0f]2513      res_holder.ref = cache->insertAndTransferOwnerShip (t, c->r);
2514      res_holder.coef = coef_bak;
2515      res_holder.onlyBorrowed = TRUE;
2516      res_holder.changed = FALSE;
2517      res_holder.p = t;
[0cf2ccd]2518      return res_holder;
[89b59f]2519    }
[0cf2ccd]2520  }
2521
[89b59f]2522}
[5ac8e5]2523#endif
2524//SparseRow* noro_red_to_non_poly(poly p, int &len, NoroCache* cache,slimgb_alg* c);
2525#ifndef NORO_NON_POLY
[89b59f]2526//len input and out: Idea: reverse addition
[db83bf]2527poly noro_red_non_unique (poly p, int &len, NoroCache * cache, slimgb_alg * c)
[2fc974]2528{
[410ea0f]2529  assume (len == pLength (p));
2530  poly orig_p = p;
[db83bf]2531  if(p == NULL)
[410ea0f]2532  {
2533    len = 0;
[89b59f]2534    return NULL;
2535  }
[410ea0f]2536  kBucket_pt bucket = kBucketCreate (currRing);
2537  kBucketInit (bucket, NULL, 0);
2538  poly unchanged_head = NULL;
2539  poly unchanged_tail = NULL;
2540  int unchanged_size = 0;
[b16a613]2541
[db83bf]2542  while(p)
[2fc974]2543  {
[410ea0f]2544    poly t = p;
2545    pIter (p);
2546    pNext (t) = NULL;
[0cf2ccd]2547#ifndef NDEBUG
[410ea0f]2548    number coef_debug = p_GetCoeff (t, currRing);
[0cf2ccd]2549#endif
[410ea0f]2550    MonRedRes red = noro_red_mon (t, FALSE, cache, c);
[db83bf]2551    if((!(red.changed)) && (!(red.onlyBorrowed)))
[2fc974]2552    {
[89b59f]2553      unchanged_size++;
[410ea0f]2554      assume (npIsOne (red.coef));
2555      assume (p_GetCoeff (red.p, currRing) == coef_debug);
[db83bf]2556      if(unchanged_head)
[2fc974]2557      {
[db83bf]2558        pNext (unchanged_tail) = red.p;
2559        pIter (unchanged_tail);
[2fc974]2560      }
2561      else
2562      {
[db83bf]2563        unchanged_tail = red.p;
2564        unchanged_head = red.p;
[89b59f]2565      }
[2fc974]2566    }
2567    else
2568    {
[410ea0f]2569      assume (red.len == pLength (red.p));
[db83bf]2570      if(red.onlyBorrowed)
[2fc974]2571      {
[db83bf]2572        if(npIsOne (red.coef))
2573        {
2574          t = p_Copy (red.p, currRing);
2575        }
2576        else
2577          t = pp_Mult_nn (red.p, red.coef, currRing);
[2fc974]2578      }
2579      else
2580      {
[db83bf]2581        if(npIsOne (red.coef))
2582          t = red.p;
2583        else
2584          t = p_Mult_nn (red.p, red.coef, currRing);
[0cf2ccd]2585      }
[410ea0f]2586      kBucket_Add_q (bucket, t, &red.len);
[89b59f]2587    }
2588  }
[410ea0f]2589  poly res = NULL;
2590  len = 0;
2591  kBucket_Add_q (bucket, unchanged_head, &unchanged_size);
2592  kBucketClear (bucket, &res, &len);
2593  kBucketDestroy (&bucket);
[89b59f]2594  return res;
2595}
[5ac8e5]2596#endif
[e01da4]2597#ifdef NORO_SPARSE_ROWS_PRE
2598//len input and out: Idea: reverse addition
[b16a613]2599
[2fc974]2600/*template <class number_type> SparseRow<number_type>* noro_red_to_non_poly(poly p, int &len, NoroCache<number_type>* cache,slimgb_alg* c)
2601 * {
[47e836b]2602  if (n_GetChar(currRing->cf)<255)
[2fc974]2603  {
[abce2e]2604    return noro_red_to_non_poly_t<tgb_uint8>(p,len,cache,c);
[2fc974]2605  }
2606  else
2607  {
[47e836b]2608    if (n_GetChar(currRing->cf)<65000)
[2fc974]2609    {
[abce2e]2610      return noro_red_to_non_poly_t<tgb_uint16>(p,len,cache,c);
[2fc974]2611    }
2612    else
2613    {
[abce2e]2614      return noro_red_to_non_poly_t<tgb_uint32>(p,len,cache,c);
[421e42]2615    }
2616  }
[5ac8e5]2617}*/
[e01da4]2618#endif
[b16a613]2619//len input and out: Idea: reverse addition
[8e086c]2620#ifndef NORO_NON_POLY
[410ea0f]2621std::vector < NoroPlaceHolder > noro_red (poly p, int &len, NoroCache * cache,
[db83bf]2622                                          slimgb_alg * c)
[410ea0f]2623{
2624  std::vector < NoroPlaceHolder > res;
[db83bf]2625  while(p)
[410ea0f]2626  {
2627    poly t = p;
2628    pIter (p);
2629    pNext (t) = NULL;
2630
2631    MonRedRes red = noro_red_mon (t, TRUE, cache, c);
2632    assume (red.onlyBorrowed);
2633    assume (red.coef);
2634    assume (red.ref);
2635    NoroPlaceHolder h;
2636    h.ref = red.ref;
2637    h.coef = red.coef;
2638    assume (!((h.ref->value_poly == NULL) && (h.ref->value_len != 0)));
[db83bf]2639    if(h.ref->value_poly)
[410ea0f]2640      res.push_back (h);
2641  }
2642  return res;
[b16a613]2643}
[8e086c]2644#endif
[b16a613]2645
[a7d970]2646#endif
[ebe987]2647#ifdef USE_NORO
[b16a613]2648#ifndef NORO_CACHE
[db83bf]2649void noro_step (poly * p, int &pn, slimgb_alg * c)
[2fc974]2650{
[410ea0f]2651  poly *reduced = (poly *) omalloc (pn * sizeof (poly));
[b68048]2652  int j;
[410ea0f]2653  int *reduced_len = (int *) omalloc (pn * sizeof (int));
2654  int reduced_c = 0;
[89b59f]2655  //if (TEST_OPT_PROT)
2656  //  PrintS("reduced system:\n");
2657#ifdef NORO_CACHE
2658  NoroCache cache;
2659#endif
[db83bf]2660  for(j = 0; j < pn; j++)
[2fc974]2661  {
[6a2e9c]2662
[410ea0f]2663    poly h = p[j];
2664    int h_len = pLength (h);
[89b59f]2665
[b68048]2666    number coef;
[89b59f]2667#ifndef NORO_CACHE
[410ea0f]2668    h = redNF2 (p_Copy (h, c->r), c, h_len, coef, 0);
[89b59f]2669#else
[410ea0f]2670    h = noro_red (p_Copy (h, c->r), h_len, &cache, c);
2671    assume (pLength (h) == h_len);
[89b59f]2672#endif
[db83bf]2673    if(h != NULL)
[2fc974]2674    {
[89b59f]2675#ifndef NORO_CACHE
[6a2e9c]2676
[410ea0f]2677      h = redNFTail (h, c->strat->sl, c->strat, h_len);
2678      h_len = pLength (h);
[89b59f]2679#endif
[410ea0f]2680      reduced[reduced_c] = h;
2681      reduced_len[reduced_c] = h_len;
[b68048]2682      reduced_c++;
[db83bf]2683      if(TEST_OPT_PROT)
2684        Print ("%d ", h_len);
[b68048]2685    }
2686  }
[410ea0f]2687  int reduced_sum = 0;
[db83bf]2688  for(j = 0; j < reduced_c; j++)
[2fc974]2689  {
[410ea0f]2690    reduced_sum += reduced_len[j];
[b68048]2691  }
[410ea0f]2692  poly *terms = (poly *) omalloc (reduced_sum * sizeof (poly));
2693  int tc = 0;
[db83bf]2694  for(j = 0; j < reduced_c; j++)
[2fc974]2695  {
[410ea0f]2696    poly h = reduced[j];
[6a2e9c]2697
[db83bf]2698    while(h != NULL)
[2fc974]2699    {
[410ea0f]2700      terms[tc++] = h;
2701      pIter (h);
2702      assume (tc <= reduced_sum);
[b68048]2703    }
2704  }
[410ea0f]2705  assume (tc == reduced_sum);
2706  qsort (terms, reduced_sum, sizeof (poly), terms_sort_crit);
2707  int nterms = reduced_sum;
[f2b5839]2708  //if (TEST_OPT_PROT)
2709  //Print("orig estimation:%i\n",reduced_sum);
[410ea0f]2710  unify_terms (terms, nterms);
[f2b5839]2711  //if (TEST_OPT_PROT)
2712  //    Print("actual number of columns:%i\n",nterms);
[410ea0f]2713  int rank = reduced_c;
2714  linalg_step_modp (reduced, p, rank, terms, nterms, c);
2715  omfree (terms);
[6a2e9c]2716
[410ea0f]2717  pn = rank;
2718  omfree (reduced);
[89b59f]2719
[db83bf]2720  if(TEST_OPT_PROT)
[410ea0f]2721    PrintS ("\n");
[b68048]2722}
[b16a613]2723#else
[abce2e]2724
[b16a613]2725#endif
[ebe987]2726#endif
[db83bf]2727static void go_on (slimgb_alg * c)
[2fc974]2728{
[4f858ce]2729  //set limit of 1000 for multireductions, at the moment for
2730  //programming reasons
[410ea0f]2731#ifdef USE_NORO
[0cf2ccd]2732  //Print("module rank%d\n",c->S->rank);
[410ea0f]2733  const BOOLEAN use_noro = c->use_noro;
2734#else
2735  const BOOLEAN use_noro = FALSE;
2736#endif
2737  int i = 0;
2738  c->average_length = 0;
[db83bf]2739  for(i = 0; i < c->n; i++)
[2fc974]2740  {
[410ea0f]2741    c->average_length += c->lengths[i];
[4f858ce]2742  }
[410ea0f]2743  c->average_length = c->average_length / c->n;
2744  i = 0;
2745  int max_pairs = bundle_size;
[6a2e9c]2746
[410ea0f]2747#ifdef USE_NORO
[db83bf]2748  if((use_noro) || (c->use_noro_last_block))
[410ea0f]2749    max_pairs = bundle_size_noro;
2750#endif
[db83bf]2751  poly *p = (poly *) omalloc ((max_pairs + 1) * sizeof (poly)); //nullterminated
[4f858ce]2752
[410ea0f]2753  int curr_deg = -1;
[db83bf]2754  while(i < max_pairs)
[2fc974]2755  {
[db83bf]2756    sorted_pair_node *s = top_pair (c); //here is actually chain criterium done
[31279e]2757
[db83bf]2758    if(!s)
[410ea0f]2759      break;
[31279e]2760
[db83bf]2761    if(curr_deg >= 0)
[2fc974]2762    {
[db83bf]2763      if(s->deg > curr_deg)
2764        break;
[4f858ce]2765    }
[cae954]2766
[410ea0f]2767    else
2768      curr_deg = s->deg;
2769    quick_pop_pair (c);
[db83bf]2770    if(s->i >= 0)
[2fc974]2771    {
[d491e3]2772      //be careful replace_pair use createShortSpoly which is not noncommutative
[410ea0f]2773      now_t_rep (s->i, s->j, c);
2774      replace_pair (s->i, s->j, c);
[31279e]2775
[db83bf]2776      if(s->i == s->j)
[410ea0f]2777      {
[db83bf]2778        free_sorted_pair_node (s, c->r);
2779        continue;
[410ea0f]2780      }
2781      now_t_rep (s->i, s->j, c);
[4f858ce]2782    }
2783    poly h;
[db83bf]2784    if(s->i >= 0)
[1daae71]2785    {
2786#ifdef HAVE_PLURAL
[db83bf]2787      if(c->nc)
[a0d9be]2788      {
[db83bf]2789        h = nc_CreateSpoly (c->S->m[s->i], c->S->m[s->j] /*, NULL */ , c->r);
[6a2e9c]2790
[db83bf]2791        if(h != NULL)
2792          p_Cleardenom (h, c->r);
[612efe]2793      }
[d491e3]2794      else
[1daae71]2795#endif
[db83bf]2796        h = ksOldCreateSpoly (c->S->m[s->i], c->S->m[s->j], NULL, c->r);
[410ea0f]2797      p_Test (h, c->r);
[31279e]2798    }
[2fc974]2799    else
2800    {
[410ea0f]2801      h = s->lcm_of_lm;
2802      p_Test (h, c->r);
2803    }
[2fd387d]2804    // if(s->i>=0)
2805//       now_t_rep(s->j,s->i,c);
[4f858ce]2806    number coef;
[410ea0f]2807    int mlen = pLength (h);
2808    p_Test (h, c->r);
[db83bf]2809    if((!c->nc) & (!(use_noro)))
[2fc974]2810    {
[410ea0f]2811      h = redNF2 (h, c, mlen, coef, 2);
2812      redTailShort (h, c->strat);
2813      nDelete (&coef);
[d491e3]2814    }
[410ea0f]2815    p_Test (h, c->r);
2816    free_sorted_pair_node (s, c->r);
[db83bf]2817    if(!h)
[410ea0f]2818      continue;
2819    p[i] = h;
[4f858ce]2820    i++;
2821  }
[410ea0f]2822  p[i] = NULL;
[4f858ce]2823//  pre_comp(p,i,c);
[db83bf]2824  if(i == 0)
[2fc974]2825  {
[410ea0f]2826    omfree (p);
[4f858ce]2827    return;
2828  }
[410ea0f]2829#ifdef TGB_RESORT_PAIRS
2830  c->replaced = new bool[c->n];
2831  c->used_b = FALSE;
2832#endif
[6a2e9c]2833
[410ea0f]2834  c->normal_forms += i;
[4f858ce]2835  int j;
[ebe987]2836#ifdef USE_NORO
[2fc974]2837  //if ((!(c->nc))&&(rField_is_Zp(c->r)))
2838  //{
[db83bf]2839  if(use_noro)
[2fc974]2840  {
[410ea0f]2841    int pn = i;
[db83bf]2842    if(pn == 0)
[abce2e]2843    {
[410ea0f]2844      omfree (p);
2845      return;
2846    }
2847    {
[47e836b]2848      if(n_GetChar(currRing->cf) < 255)
[2fc974]2849      {
[db83bf]2850        noro_step < tgb_uint8 > (p, pn, c);
[2fc974]2851      }
2852      else
2853      {
[47e836b]2854        if(n_GetChar(currRing->cf) < 65000)
[db83bf]2855        {
2856          noro_step < tgb_uint16 > (p, pn, c);
2857        }
2858        else
2859        {
2860          noro_step < tgb_uint32 > (p, pn, c);
2861        }
[abce2e]2862      }
2863    }
[6a2e9c]2864
[2fc974]2865    //if (TEST_OPT_PROT)
2866    //{
[f2b5839]2867    //  Print("reported rank:%i\n",pn);
2868    //}
[410ea0f]2869    mass_add (p, pn, c);
2870    omfree (p);
[b68048]2871    return;
2872    /*if (TEST_OPT_PROT)
[410ea0f]2873       for(j=0;j<pn;j++)
2874       {
2875       p_wrp(p[j],c->r);
2876       } */
[b68048]2877  }
[f23852]2878#endif
[410ea0f]2879  red_object *buf = (red_object *) omalloc (i * sizeof (red_object));
[db83bf]2880  for(j = 0; j < i; j++)
[410ea0f]2881  {
2882    p_Test (p[j], c->r);
2883    buf[j].p = p[j];
2884    buf[j].sev = pGetShortExpVector (p[j]);
2885    buf[j].bucket = kBucketCreate (currRing);
2886    p_Test (p[j], c->r);
[db83bf]2887    if(c->eliminationProblem)
[2fc974]2888    {
[410ea0f]2889      buf[j].sugar = c->pTotaldegree_full (p[j]);
[d64382]2890    }
[410ea0f]2891    int len = pLength (p[j]);
2892    kBucketInit (buf[j].bucket, buf[j].p, len);
2893    buf[j].initial_quality = buf[j].guess_quality (c);
2894    assume (buf[j].initial_quality >= 0);
[4f858ce]2895  }
[410ea0f]2896  omfree (p);
2897  qsort (buf, i, sizeof (red_object), red_object_better_gen);
[4f858ce]2898//    Print("\ncurr_deg:%i\n",curr_deg);
[db83bf]2899  if(TEST_OPT_PROT)
[b17a5c]2900  {
[410ea0f]2901    Print ("%dM[%d,", curr_deg, i);
[b17a5c]2902  }
[b68048]2903
[410ea0f]2904  multi_reduction (buf, i, c);
2905#ifdef TGB_RESORT_PAIRS
[db83bf]2906  if(c->used_b)
[410ea0f]2907  {
[db83bf]2908    if(TEST_OPT_PROT)
[410ea0f]2909      PrintS ("B");
[c72471]2910    int e;
[db83bf]2911    for(e = 0; e <= c->pair_top; e++)
[2fc974]2912    {
[db83bf]2913      if(c->apairs[e]->i < 0)
2914        continue;
[410ea0f]2915      assume (c->apairs[e]->j >= 0);
[db83bf]2916      if((c->replaced[c->apairs[e]->i]) || (c->replaced[c->apairs[e]->j]))
[410ea0f]2917      {
[db83bf]2918        sorted_pair_node *s = c->apairs[e];
2919        s->expected_length = pair_weighted_length (s->i, s->j, c);
[410ea0f]2920      }
[c72471]2921    }
[410ea0f]2922    qsort (c->apairs, c->pair_top + 1, sizeof (sorted_pair_node *),
[db83bf]2923           tgb_pair_better_gen2);
[c72471]2924  }
[410ea0f]2925#endif
[4f858ce]2926#ifdef TGB_DEBUG
[410ea0f]2927  {
2928    int k;
[db83bf]2929    for(k = 0; k < i; k++)
[410ea0f]2930    {
2931      assume (kFindDivisibleByInS_easy (c->strat, buf[k]) < 0);
2932      int k2;
[db83bf]2933      for(k2 = 0; k2 < i; k2++)
[410ea0f]2934      {
[db83bf]2935        if(k == k2)
2936          continue;
2937        assume ((!(p_LmDivisibleBy (buf[k].p, buf[k2].p, c->r)))
2938                || (wrp (buf[k].p), Print (" k %d k2 %d ", k, k2),
2939                    wrp (buf[k2].p), FALSE));
[410ea0f]2940      }
2941    }
2942  }
[4f858ce]2943#endif
2944  //resort S
[31279e]2945
[db83bf]2946  if(TEST_OPT_PROT)
[410ea0f]2947    Print ("%i]", i);
[e4e1c2a]2948
[410ea0f]2949  poly *add_those = (poly *) omalloc (i * sizeof (poly));
[db83bf]2950  for(j = 0; j < i; j++)
[4f858ce]2951  {
[410ea0f]2952    int len;
2953    poly p;
2954    buf[j].flatten ();
2955    kBucketClear (buf[j].bucket, &p, &len);
2956    kBucketDestroy (&buf[j].bucket);
2957    p_Test (p, c->r);
2958    //if (!c->nc) {
[db83bf]2959    if((c->tailReductions) || (lies_in_last_dp_block (p, c)))
[410ea0f]2960    {
2961      p = redNFTail (p, c->strat->sl, c->strat, 0);
2962    }
2963    else
2964    {
2965      p = redTailShort (p, c->strat);
2966    }
2967    //}
2968    p_Test (p, c->r);
2969    add_those[j] = p;
[b68048]2970
[4f858ce]2971    //sbuf[j]=add_to_basis(p,-1,-1,c,ibuf+j);
2972  }
[410ea0f]2973  mass_add (add_those, i, c);
2974  omfree (add_those);
2975  omfree (buf);
[6a2e9c]2976
[db83bf]2977  if(TEST_OPT_PROT)
[410ea0f]2978    Print ("(%d)", c->pair_top + 1);
[b68048]2979  //TODO: implement that while(!(idIs0(c->add_later)))
[410ea0f]2980#ifdef TGB_RESORT_PAIRS
[c72471]2981  delete c->replaced;
[410ea0f]2982  c->replaced = NULL;
2983  c->used_b = FALSE;
2984#endif
[4f858ce]2985  return;
2986}
2987
2988#ifdef REDTAIL_S
2989
[db83bf]2990static poly redNFTail (poly h, const int sl, kStrategy strat, int len)
[4f858ce]2991{
[410ea0f]2992  BOOLEAN nc = rIsPluralRing (currRing);
[db83bf]2993  if(h == NULL)
[410ea0f]2994    return NULL;
2995  pTest (h);
[db83bf]2996  if(0 > sl)
[4f858ce]2997    return h;
[db83bf]2998  if(pNext (h) == NULL)
[410ea0f]2999    return h;
[4f858ce]3000
3001  int j;
[410ea0f]3002  poly res = h;
3003  poly act = res;
3004  LObject P (pNext (h));
3005  pNext (res) = NULL;
3006  P.bucket = kBucketCreate (currRing);
[4f858ce]3007  len--;
[410ea0f]3008  h = P.p;
[db83bf]3009  if(len <= 0)
[410ea0f]3010    len = pLength (h);
3011  kBucketInit (P.bucket, h /*P.p */ , len /*pLength(P.p) */ );
3012  pTest (h);
[4f858ce]3013  loop
3014  {
[410ea0f]3015    P.p = h;
3016    P.t_p = NULL;
3017    P.SetShortExpVector ();
3018    loop
3019    {
3020      //int dummy=strat->sl;
[db83bf]3021      j = kFindDivisibleByInS_easy (strat, P.p, P.sev); //kFindDivisibleByInS(strat,&dummy,&P);
3022      if(j >= 0)
[4f858ce]3023      {
3024#ifdef REDTAIL_PROT
[db83bf]3025        PrintS ("r");
[4f858ce]3026#endif
[db83bf]3027        nNormalize (pGetCoeff (P.p));
[4f858ce]3028#ifdef KDEBUG
[db83bf]3029        if(TEST_OPT_DEBUG)
3030        {
3031          PrintS ("red tail:");
3032          wrp (h);
3033          PrintS (" with ");
3034          wrp (strat->S[j]);
3035        }
[4f858ce]3036#endif
[db83bf]3037        number coef;
3038        pTest (strat->S[j]);
[1cc61e]3039#ifdef HAVE_PLURAL
[db83bf]3040        if(nc)
3041        {
3042          nc_BucketPolyRed_Z (P.bucket, strat->S[j], &coef);
3043        }
3044        else
[1cc61e]3045#endif
[db83bf]3046          coef = kBucketPolyRed (P.bucket, strat->S[j],
3047                                 strat->lenS[j] /*pLength(strat->S[j]) */ ,
3048                                 strat->kNoether);
3049        pMult_nn (res, coef);
3050        nDelete (&coef);
3051        h = kBucketGetLm (P.bucket);
3052        pTest (h);
3053        if(h == NULL)
3054        {
[4f858ce]3055#ifdef REDTAIL_PROT
[db83bf]3056          PrintS (" ");
[4f858ce]3057#endif
[db83bf]3058          kBucketDestroy (&P.bucket);
3059          return res;
3060        }
3061        pTest (h);
3062        P.p = h;
3063        P.t_p = NULL;
3064        P.SetShortExpVector ();
[4f858ce]3065#ifdef KDEBUG
[db83bf]3066        if(TEST_OPT_DEBUG)
3067        {
3068          PrintS ("\nto tail:");
3069          wrp (h);
3070          PrintLn ();
3071        }
[4f858ce]3072#endif
[410ea0f]3073      }
3074      else
[4f858ce]3075      {
3076#ifdef REDTAIL_PROT
[db83bf]3077        PrintS ("n");
[4f858ce]3078#endif
[db83bf]3079        break;
[4f858ce]3080      }
[db83bf]3081    }                           /* end loop current mon */
[410ea0f]3082    //   poly tmp=pHead(h /*kBucketGetLm(P.bucket)*/);
3083    //act->next=tmp;pIter(act);
3084    act->next = kBucketExtractLm (P.bucket);
3085    pIter (act);
3086    h = kBucketGetLm (P.bucket);
[db83bf]3087    if(h == NULL)
[410ea0f]3088    {
3089#ifdef REDTAIL_PROT
3090      PrintS (" ");
3091#endif
3092      kBucketDestroy (&P.bucket);
3093      return res;
3094    }
3095    pTest (h);
[4f858ce]3096  }
3097}
3098#endif
3099
3100
3101//try to fill, return FALSE iff queue is empty
3102
3103//transfers ownership of m to mat
[db83bf]3104void init_with_mac_poly (tgb_sparse_matrix * mat, int row, mac_poly m)
[2fc974]3105{
[410ea0f]3106  assume (mat->mp[row] == NULL);
3107  mat->mp[row] = m;
[4f858ce]3108#ifdef TGB_DEBUG
[410ea0f]3109  mac_poly r = m;
[db83bf]3110  while(r)
[2fc974]3111  {
[410ea0f]3112    assume (r->exp < mat->columns);
3113    r = r->next;
[4f858ce]3114  }
3115#endif
3116}
[410ea0f]3117
3118poly
3119free_row_to_poly (tgb_sparse_matrix * mat, int row, poly * monoms,
[db83bf]3120                  int monom_index)
[410ea0f]3121{
3122  poly p = NULL;
3123  poly *set_this = &p;
3124  mac_poly r = mat->mp[row];
3125  mat->mp[row] = NULL;
[db83bf]3126  while(r)
[410ea0f]3127  {
3128    (*set_this) = pLmInit (monoms[monom_index - 1 - r->exp]);
3129    pSetCoeff ((*set_this), r->coef);
3130    set_this = &((*set_this)->next);
3131    mac_poly old = r;
3132    r = r->next;
[4f858ce]3133    delete old;
[31279e]3134
[4f858ce]3135  }
3136  return p;
3137}
3138
[db83bf]3139static int poly_crit (const void *ap1, const void *ap2)
[2fc974]3140{
[410ea0f]3141  poly p1, p2;
3142  p1 = *((poly *) ap1);
3143  p2 = *((poly *) ap2);
3144
3145  int c = pLmCmp (p1, p2);
[db83bf]3146  if(c != 0)
[410ea0f]3147    return c;
3148  int l1 = pLength (p1);
3149  int l2 = pLength (p2);
[db83bf]3150  if(l1 < l2)
[410ea0f]3151    return -1;
[db83bf]3152  if(l1 > l2)
[410ea0f]3153    return 1;
[4f858ce]3154  return 0;
3155}
[2fc974]3156
[db83bf]3157void slimgb_alg::introduceDelayedPairs (poly * pa, int s)
[2fc974]3158{
[db83bf]3159  if(s == 0)
[410ea0f]3160    return;
3161  sorted_pair_node **si_array =
3162    (sorted_pair_node **) omalloc (s * sizeof (sorted_pair_node *));
3163
[db83bf]3164  for(int i = 0; i < s; i++)
[410ea0f]3165  {
3166    sorted_pair_node *si =
3167      (sorted_pair_node *) omalloc (sizeof (sorted_pair_node));
3168    si->i = -1;
3169    si->j = -2;
3170    poly p = pa[i];
3171    simplify_poly (p, r);
3172    si->expected_length = pQuality (p, this, pLength (p));
3173    p_Test (p, r);
3174    si->deg = this->pTotaldegree_full (p);
3175    /*if (!rField_is_Zp(r))
[a0d9be]3176       {
[410ea0f]3177       p_Content(p,r);
3178       p_Cleardenom(p,r);
3179       } */
[6a2e9c]3180
[410ea0f]3181    si->lcm_of_lm = p;
[5a9e7b]3182
[410ea0f]3183    //      c->apairs[n-1-i]=si;
3184    si_array[i] = si;
[5a9e7b]3185  }
3186
[410ea0f]3187  qsort (si_array, s, sizeof (sorted_pair_node *), tgb_pair_better_gen2);
3188  apairs = spn_merge (apairs, pair_top + 1, si_array, s, this);
3189  pair_top += s;
3190  omfree (si_array);
[6e08ad]3191}
[2fc974]3192
[410ea0f]3193slimgb_alg::slimgb_alg (ideal I, int syz_comp, BOOLEAN F4, int deg_pos)
[5f4463]3194{
[410ea0f]3195  this->deg_pos = deg_pos;
3196  lastCleanedDeg = -1;
3197  completed = FALSE;
3198  this->syz_comp = syz_comp;
3199  r = currRing;
3200  nc = rIsPluralRing (r);
3201  this->lastDpBlockStart = get_last_dp_block_start (r);
[2921f5]3202  //Print("last dp Block start: %i\n", this->lastDpBlockStart);
[410ea0f]3203  is_homog = TRUE;
[4f858ce]3204  {
[d76b58]3205    int hzz;
[db83bf]3206    for(hzz = 0; hzz < IDELEMS (I); hzz++)
[5f4463]3207    {
[410ea0f]3208      assume (I->m[hzz] != NULL);
3209      int d = this->pTotaldegree (I->m[hzz]);
3210      poly t = I->m[hzz]->next;
[db83bf]3211      while(t)
[4f858ce]3212      {
[db83bf]3213        if(d != this->pTotaldegree (t))
3214        {
3215          is_homog = FALSE;
3216          break;
3217        }
3218        t = t->next;
[4f858ce]3219      }
[db83bf]3220      if(!(is_homog))
3221        break;
[4f858ce]3222    }
3223  }
[fe89b98]3224  eliminationProblem = ((!(is_homog)) && ((currRing->pLexOrder) || (I->rank > 1)));
[410ea0f]3225  tailReductions = ((is_homog) || ((TEST_OPT_REDTAIL) && (!(I->rank > 1))));
[4f858ce]3226  //  Print("is homog:%d",c->is_homog);
[410ea0f]3227  void *h;
[a41623]3228  int i;
[410ea0f]3229  to_destroy = NULL;
3230  easy_product_crit = 0;
3231  extended_product_crit = 0;
[db83bf]3232  if(rField_is_Zp (r))
[410ea0f]3233    isDifficultField = FALSE;
[4f858ce]3234  else
[410ea0f]3235    isDifficultField = TRUE;
[4f858ce]3236  //not fully correct
[68ae61]3237  //(rChar()==0);
[410ea0f]3238  F4_mode = F4;
[c57134]3239
[410ea0f]3240  reduction_steps = 0;
3241  last_index = -1;
[4f858ce]3242
[410ea0f]3243  F = NULL;
3244  F_minus = NULL;
[4f858ce]3245
[410ea0f]3246  Rcounter = 0;
[4f858ce]3247
[410ea0f]3248  soon_free = NULL;
[4f858ce]3249
[410ea0f]3250  tmp_lm = pOne ();
[4f858ce]3251
[410ea0f]3252  normal_forms = 0;
3253  current_degree = 1;
[31279e]3254
[410ea0f]3255  max_pairs = 5 * IDELEMS (I);
[31279e]3256
[410ea0f]3257  apairs =
3258    (sorted_pair_node **) omalloc (sizeof (sorted_pair_node *) * max_pairs);
3259  pair_top = -1;
[4f858ce]3260
[410ea0f]3261  int n = IDELEMS (I);
3262  array_lengths = n;
[2fc974]3263
[31279e]3264
[410ea0f]3265  i = 0;
3266  this->n = 0;
3267  T_deg = (int *) omalloc (n * sizeof (int));
[db83bf]3268  if(eliminationProblem)
[410ea0f]3269    T_deg_full = (int *) omalloc (n * sizeof (int));
[4f858ce]3270  else
[410ea0f]3271    T_deg_full = NULL;
3272  tmp_pair_lm = (poly *) omalloc (n * sizeof (poly));
3273  tmp_spn = (sorted_pair_node **) omalloc (n * sizeof (sorted_pair_node *));
3274  lm_bin = omGetSpecBin (POLYSIZE + (r->ExpL_Size) * sizeof (long));
[4f858ce]3275#ifdef HEAD_BIN
[410ea0f]3276  HeadBin = omGetSpecBin (POLYSIZE + (currRing->ExpL_Size) * sizeof (long));
[4f858ce]3277#endif
3278  /* omUnGetSpecBin(&(c->HeadBin)); */
[410ea0f]3279#ifndef HAVE_BOOST
3280#ifdef USE_STDVECBOOL
3281#else
3282  h = omalloc (n * sizeof (char *));
3283
3284  states = (char **) h;
3285#endif
3286#endif
3287  h = omalloc (n * sizeof (int));
3288  lengths = (int *) h;
3289  weighted_lengths = (wlen_type *) omalloc (n * sizeof (wlen_type));
3290  gcd_of_terms = (poly *) omalloc (n * sizeof (poly));
3291
3292  short_Exps = (long *) omalloc (n * sizeof (long));
[db83bf]3293  if(F4_mode)
[410ea0f]3294    S = idInit (n, I->rank);
[f3c849]3295  else
[410ea0f]3296    S = idInit (1, I->rank);
3297  strat = new skStrategy;
[db83bf]3298  if(eliminationProblem)
[410ea0f]3299    strat->honey = TRUE;
[68ae61]3300  strat->syzComp = 0;
[410ea0f]3301  initBuchMoraCrit (strat);
3302  initBuchMoraPos (strat);
[68ae61]3303  strat->initEcart = initEcartBBA;
[410ea0f]3304  strat->tailRing = r;
[68ae61]3305  strat->enterS = enterSBba;
3306  strat->sl = -1;
[410ea0f]3307  i = n;
[db83bf]3308  i = 1;                        //some strange bug else
[4f858ce]3309  /* initS(c->S,NULL,c->strat); */
[68ae61]3310  /* intS start: */
[4f858ce]3311  // i=((i+IDELEMS(c->S)+15)/16)*16;
[db83bf]3312  strat->ecartS = (intset) omAlloc (i * sizeof (int));  /*initec(i); */
[410ea0f]3313  strat->sevS = (unsigned long *) omAlloc0 (i * sizeof (unsigned long));
3314  /*initsevS(i); */
[db83bf]3315  strat->S_2_R = (int *) omAlloc0 (i * sizeof (int));   /*initS_2_R(i); */
[410ea0f]3316  strat->fromQ = NULL;
3317  strat->Shdl = idInit (1, 1);
3318  strat->S = strat->Shdl->m;
3319  strat->lenS = (int *) omAlloc0 (i * sizeof (int));
[db83bf]3320  if((isDifficultField) || (eliminationProblem))
[410ea0f]3321    strat->lenSw = (wlen_type *) omAlloc0 (i * sizeof (wlen_type));
[4f858ce]3322  else
[410ea0f]3323    strat->lenSw = NULL;
3324  assume (n > 0);
3325  add_to_basis_ideal_quotient (I->m[0], this, NULL);
3326
3327  assume (strat->sl == IDELEMS (strat->Shdl) - 1);
[db83bf]3328  if(!(F4_mode))
[410ea0f]3329  {
3330    poly *array_arg = I->m;
3331    array_arg++;
3332    introduceDelayedPairs (array_arg, n - 1);
3333    /*
3334       for (i=1;i<n;i++)//the 1 is wanted, because first element is added to basis
3335       {
3336       //     add_to_basis(I->m[i],-1,-1,c);
3337       si=(sorted_pair_node*) omalloc(sizeof(sorted_pair_node));
3338       si->i=-1;
3339       si->j=-2;
3340       si->expected_length=pQuality(I->m[i],this,pLength(I->m[i]));
3341       si->deg=pTotaldegree(I->m[i]);
3342       if (!rField_is_Zp(r))
3343       {
3344       p_Cleardenom(I->m[i], r);
3345       }
3346       si->lcm_of_lm=I->m[i];
[31279e]3347
[410ea0f]3348       //      c->apairs[n-1-i]=si;
3349       apairs[n-i-1]=si;
3350       ++(pair_top);
3351       } */
[4f858ce]3352  }
3353  else
3354  {
[db83bf]3355    for(i = 1; i < n; i++)      //the 1 is wanted, because first element is added to basis
[410ea0f]3356      add_to_basis_ideal_quotient (I->m[i], this, NULL);
[4f858ce]3357  }
[db83bf]3358  for(i = 0; i < IDELEMS (I); i++)
[4f858ce]3359  {
[410ea0f]3360    I->m[i] = NULL;
[4f858ce]3361  }
[410ea0f]3362  idDelete (&I);
3363  add_later = idInit (ADD_LATER_SIZE, S->rank);
3364#ifdef USE_NORO
3365  use_noro = ((!(nc)) && (S->rank <= 1) && (rField_is_Zp (r))
[47e836b]3366              && (!(eliminationProblem)) && (n_GetChar(currRing->cf) <= 32003));
[410ea0f]3367  use_noro_last_block = false;
[1f637e]3368  if((!(use_noro)) && (lastDpBlockStart <= (currRing->N)))
[5f4463]3369  {
[410ea0f]3370    use_noro_last_block = ((!(nc)) && (S->rank <= 1) && (rField_is_Zp (r))
[47e836b]3371                           && (n_GetChar(currRing->cf) <= 32003));
[f2b5839]3372  }
[410ea0f]3373#else
3374  use_noro = false;
3375  use_noro_last_block = false;
3376#endif
[f2b5839]3377  //Print("NORO last block %i",use_noro_last_block);
[410ea0f]3378  memset (add_later->m, 0, ADD_LATER_SIZE * sizeof (poly));
[68ae61]3379}
[410ea0f]3380
3381slimgb_alg::~slimgb_alg ()
[5f4463]3382{
[2fc974]3383
[db83bf]3384  if(!(completed))
[5f4463]3385  {
[410ea0f]3386    poly *add = (poly *) omalloc ((pair_top + 2) * sizeof (poly));
3387    int piter;
3388    int pos = 0;
[db83bf]3389    for(piter = 0; piter <= pair_top; piter++)
[410ea0f]3390    {
3391      sorted_pair_node *s = apairs[piter];
[db83bf]3392      if(s->i < 0)
[2fc974]3393      {
[db83bf]3394        //delayed element
3395        if(s->lcm_of_lm != NULL)
3396        {
3397          add[pos] = s->lcm_of_lm;
3398          pos++;
3399        }
[2fc974]3400      }
[410ea0f]3401      free_sorted_pair_node (s, r);
3402      apairs[piter] = NULL;
3403    }
3404    pair_top = -1;
3405    add[pos] = NULL;
3406    pos = 0;
[db83bf]3407    while(add[pos] != NULL)
[410ea0f]3408    {
3409      add_to_basis_ideal_quotient (add[pos], this, NULL);
3410      pos++;
3411    }
[db83bf]3412    for(piter = 0; piter <= pair_top; piter++)
[410ea0f]3413    {
3414      sorted_pair_node *s = apairs[piter];
3415      assume (s->i >= 0);
3416      free_sorted_pair_node (s, r);
3417      apairs[piter] = NULL;
3418    }
3419    pair_top = -1;
[a60a21]3420  }
[410ea0f]3421  id_Delete (&add_later, r);
3422  int i, j;
3423  slimgb_alg *c = this;
[db83bf]3424  while(c->to_destroy)
[4f858ce]3425  {
[410ea0f]3426    pDelete (&(c->to_destroy->p));
3427    poly_list_node *old = c->to_destroy;
3428    c->to_destroy = c->to_destroy->next;
3429    omfree (old);
[4f858ce]3430  }
[db83bf]3431  while(c->F)
[4f858ce]3432  {
[db83bf]3433    for(i = 0; i < c->F->size; i++)
[5f4463]3434    {
[410ea0f]3435      pDelete (&(c->F->mp[i].m));
[4f858ce]3436    }
[410ea0f]3437    omfree (c->F->mp);
3438    c->F->mp = NULL;
3439    mp_array_list *old = c->F;
3440    c->F = c->F->next;
3441    omfree (old);
[4f858ce]3442  }
[db83bf]3443  while(c->F_minus)
[4f858ce]3444  {
[db83bf]3445    for(i = 0; i < c->F_minus->size; i++)
[5f4463]3446    {
[410ea0f]3447      pDelete (&(c->F_minus->p[i]));
[4f858ce]3448    }
[410ea0f]3449    omfree (c->F_minus->p);
3450    c->F_minus->p = NULL;
3451    poly_array_list *old = c->F_minus;
3452    c->F_minus = c->F_minus->next;
3453    omfree (old);
[4f858ce]3454  }
[410ea0f]3455#ifndef HAVE_BOOST
3456#ifndef USE_STDVECBOOL
[db83bf]3457  for(int z = 1 /* zero length at 0 */ ; z < c->n; z++)
[5f4463]3458  {
[410ea0f]3459    omfree (c->states[z]);
[4f858ce]3460  }
[410ea0f]3461  omfree (c->states);
3462#endif
3463#endif
[26914c]3464
[410ea0f]3465  omfree (c->lengths);
3466  omfree (c->weighted_lengths);
[db83bf]3467  for(int z = 0; z < c->n; z++)
[4f858ce]3468  {
[410ea0f]3469    pDelete (&c->tmp_pair_lm[z]);
3470    omfree (c->tmp_spn[z]);
[4f858ce]3471  }
[410ea0f]3472  omfree (c->tmp_pair_lm);
3473  omfree (c->tmp_spn);
[31279e]3474
[410ea0f]3475  omfree (c->T_deg);
[db83bf]3476  if(c->T_deg_full)
[410ea0f]3477    omfree (c->T_deg_full);
[4f858ce]3478
[410ea0f]3479  omFree (c->strat->ecartS);
3480  omFree (c->strat->sevS);
[4f858ce]3481//   initsevS(i);
[410ea0f]3482  omFree (c->strat->S_2_R);
[2fc974]3483
3484
[410ea0f]3485  omFree (c->strat->lenS);
[4f858ce]3486
[db83bf]3487  if(c->strat->lenSw)
[410ea0f]3488    omFree (c->strat->lenSw);
[4f858ce]3489
[db83bf]3490  for(i = 0; i < c->n; i++)
[5f4463]3491  {
[db83bf]3492    if(c->gcd_of_terms[i])
[410ea0f]3493      pDelete (&(c->gcd_of_terms[i]));
[4f858ce]3494  }
[410ea0f]3495  omfree (c->gcd_of_terms);
[4f858ce]3496
[410ea0f]3497  omfree (c->apairs);
[db83bf]3498  if(TEST_OPT_PROT)
[4f858ce]3499  {
[98e002]3500    //Print("calculated %d NFs\n",c->normal_forms);
[410ea0f]3501    Print ("\nNF:%i product criterion:%i, ext_product criterion:%i \n",
[db83bf]3502           c->normal_forms, c->easy_product_crit, c->extended_product_crit);
[4f858ce]3503  }
[31279e]3504
[db83bf]3505  for(i = 0; i <= c->strat->sl; i++)
[5f4463]3506  {
[db83bf]3507    if(!c->strat->S[i])
[410ea0f]3508      continue;
3509    BOOLEAN found = FALSE;
[db83bf]3510    for(j = 0; j < c->n; j++)
[5f4463]3511    {
[db83bf]3512      if(c->S->m[j] == c->strat->S[i])
[5f4463]3513      {
[db83bf]3514        found = TRUE;
3515        break;
[4f858ce]3516      }
3517    }
[db83bf]3518    if(!found)
[410ea0f]3519      pDelete (&c->strat->S[i]);
[4f858ce]3520  }
[2fc974]3521//   for(i=0;i<c->n;i++)
3522//   {
3523//     if (c->rep[i]!=i)
3524//     {
3525// //       for(j=0;j<=c->strat->sl;j++)
3526// {
3527// //   if(c->strat->S[j]==c->S->m[i])
3528// {
[e4e1c2a]3529// //     c->strat->S[j]=NULL;
3530// //     break;
3531// //   }
[4f858ce]3532// //       }
3533// //      PrintS("R_delete");
3534//       pDelete(&c->S->m[i]);
3535//     }
3536//   }
3537
[db83bf]3538  if(completed)
[cae954]3539  {
[db83bf]3540    for(i = 0; i < c->n; i++)
[cae954]3541    {
[410ea0f]3542      assume (c->S->m[i] != NULL);
[db83bf]3543      if(p_GetComp (c->S->m[i], currRing) > this->syz_comp)
3544        continue;
3545      for(j = 0; j < c->n; j++)
[2fc974]3546      {
[db83bf]3547        if((c->S->m[j] == NULL) || (i == j))
3548          continue;
3549        assume (p_LmShortDivisibleBy (c->S->m[j], c->short_Exps[j],
3550                                      c->S->m[i], ~c->short_Exps[i],
3551                                      c->r) == p_LmDivisibleBy (c->S->m[j],
3552                                                                c->S->m[i],
3553                                                                c->r));
3554        if(p_LmShortDivisibleBy (c->S->m[j], c->short_Exps[j],
3555                                 c->S->m[i], ~c->short_Exps[i], c->r))
3556        {
3557          pDelete (&c->S->m[i]);
3558          break;
3559        }
[4f858ce]3560      }
[cae954]3561    }
[4f858ce]3562  }
[410ea0f]3563  omfree (c->short_Exps);
[31279e]3564
[410ea0f]3565  ideal I = c->S;
3566  IDELEMS (I) = c->n;
3567  idSkipZeroes (I);
[db83bf]3568  for(i = 0; i <= c->strat->sl; i++)
[410ea0f]3569    c->strat->S[i] = NULL;
3570  id_Delete (&c->strat->Shdl, c->r);
3571  pDelete (&c->tmp_lm);
3572  omUnGetSpecBin (&lm_bin);
[4f858ce]3573  delete c->strat;
[68ae61]3574}
[6a2e9c]3575
[db83bf]3576ideal t_rep_gb (ring r, ideal arg_I, int syz_comp, BOOLEAN F4_mode)
[410ea0f]3577{
3578  assume (r == currRing);
3579  ring orig_ring = r;
3580  int pos;
3581  ring new_ring = rAssure_TDeg (orig_ring, 1, rVar (orig_ring), pos);
3582  ideal s_h;
[db83bf]3583  if(orig_ring != new_ring)
[410ea0f]3584  {
3585    rChangeCurrRing (new_ring);
[47e836b]3586    s_h = idrCopyR_NoSort (arg_I, orig_ring, new_ring);
[410ea0f]3587    idTest (s_h);
3588    /*int i;
3589       for(i=0;i<IDELEMS(s_h);i++)
3590       {
3591       poly p=s_h->m[i];
3592       while(p)
3593       {
3594       p_Setm(p,new_ring);
3595       pIter(p);
3596       }
3597       } */
3598  }
3599  else
3600  {
3601    s_h = id_Copy (arg_I, orig_ring);
3602  }
3603
3604  ideal s_result = do_t_rep_gb (new_ring, s_h, syz_comp, F4_mode, pos);
3605  ideal result;
[db83bf]3606  if(orig_ring != new_ring)
[410ea0f]3607  {
3608    idTest (s_result);
3609    rChangeCurrRing (orig_ring);
[47e836b]3610    result = idrMoveR_NoSort (s_result, new_ring, orig_ring);
[410ea0f]3611
3612    idTest (result);
3613    //rChangeCurrRing(new_ring);
[5fe834]3614    rDelete(new_ring);
[410ea0f]3615    //rChangeCurrRing(orig_ring);
3616  }
3617  else
3618    result = s_result;
3619  idTest (result);
3620  return result;
[86aa6a1]3621}
[6a2e9c]3622
[410ea0f]3623ideal
3624do_t_rep_gb (ring r, ideal arg_I, int syz_comp, BOOLEAN F4_mode, int deg_pos)
[2fc974]3625{
[1821d6]3626  //  Print("QlogSize(0) %d, QlogSize(1) %d,QlogSize(-2) %d, QlogSize(5) %d\n", QlogSize(nlInit(0)),QlogSize(nlInit(1)),QlogSize(nlInit(-2)),QlogSize(nlInit(5)));
[5a9e7b]3627
[db83bf]3628  if(TEST_OPT_PROT)
3629    if(F4_mode)
[410ea0f]3630      PrintS ("F4 Modus \n");
[31279e]3631
[68ae61]3632  //debug_Ideal=arg_debug_Ideal;
3633  //if (debug_Ideal) PrintS("DebugIdeal received\n");
3634  // Print("Idelems %i \n----------\n",IDELEMS(arg_I));
[410ea0f]3635  ideal I = arg_I;
[2e757c]3636  id_Compactify (I,currRing);
[db83bf]3637  if(idIs0 (I))
[410ea0f]3638    return I;
[10ea45f]3639  int i;
[db83bf]3640  for(i = 0; i < IDELEMS (I); i++)
[31279e]3641  {
[410ea0f]3642    assume (I->m[i] != NULL);
3643    simplify_poly (I->m[i], currRing);
[3ea446]3644  }
[5a9e7b]3645
[410ea0f]3646  qsort (I->m, IDELEMS (I), sizeof (poly), poly_crit);
[68ae61]3647  //Print("Idelems %i \n----------\n",IDELEMS(I));
3648  //slimgb_alg* c=(slimgb_alg*) omalloc(sizeof(slimgb_alg));
[625767]3649  //int syz_comp=arg_I->rank;
[410ea0f]3650  slimgb_alg *c = new slimgb_alg (I, syz_comp, F4_mode, deg_pos);
[31279e]3651
[db83bf]3652  while((c->pair_top >= 0)
3653        && ((!(TEST_OPT_DEGBOUND))
3654            || (c->apairs[c->pair_top]->deg <= Kstd1_deg)))
[68ae61]3655  {
[410ea0f]3656#ifdef HAVE_F4
[db83bf]3657    if(F4_mode)
[410ea0f]3658      go_on_F4 (c);
[68ae61]3659    else
[410ea0f]3660#endif
3661      go_on (c);
[68ae61]3662  }
[db83bf]3663  if(c->pair_top < 0)
[410ea0f]3664    c->completed = TRUE;
3665  I = c->S;
[68ae61]3666  delete c;
[db83bf]3667  if(TEST_OPT_REDSB)
[e7c6b22]3668  {
[410ea0f]3669    ideal erg = kInterRed (I, NULL);
3670    assume (I != erg);
3671    id_Delete (&I, currRing);
[83f7ec]3672    return erg;
3673  }
[227a50]3674  //qsort(I->m, IDELEMS(I),sizeof(poly),pLmCmp_func);
[7b25fe]3675  assume (I->rank >= id_RankFreeModule (I,currRing));
[410ea0f]3676  return (I);
[4f858ce]3677}
[2fc974]3678
[db83bf]3679void now_t_rep (const int &arg_i, const int &arg_j, slimgb_alg * c)
[d231ed]3680{
[410ea0f]3681  int i, j;
[db83bf]3682  if(arg_i == arg_j)
[d231ed]3683  {
[4f858ce]3684    return;
3685  }
[db83bf]3686  if(arg_i > arg_j)
[d231ed]3687  {
[410ea0f]3688    i = arg_j;
3689    j = arg_i;
[d231ed]3690  }
3691  else
3692  {
[410ea0f]3693    i = arg_i;
3694    j = arg_j;
[4f858ce]3695  }
[410ea0f]3696  c->states[j][i] = HASTREP;
[4f858ce]3697}
[ad6ad2]3698
[410ea0f]3699static BOOLEAN
3700has_t_rep (const int &arg_i, const int &arg_j, slimgb_alg * state)
[d231ed]3701{
[410ea0f]3702  assume (0 <= arg_i);
3703  assume (0 <= arg_j);
3704  assume (arg_i < state->n);
3705  assume (arg_j < state->n);
[db83bf]3706  if(arg_i == arg_j)
[4f858ce]3707  {
3708    return (TRUE);
3709  }
[db83bf]3710  if(arg_i > arg_j)
[4f858ce]3711  {
[410ea0f]3712    return (state->states[arg_i][arg_j] == HASTREP);
[d231ed]3713  }
3714  else
[4f858ce]3715  {
[410ea0f]3716    return (state->states[arg_j][arg_i] == HASTREP);
[4f858ce]3717  }
3718}
[a41623]3719
[db83bf]3720#if 0                           // unused
3721static int pLcmDeg (poly a, poly b)
[4f858ce]3722{
3723  int i;
[410ea0f]3724  int n = 0;
[1f637e]3725  for(i = (currRing->N); i; i--)
[4f858ce]3726  {
[410ea0f]3727    n += si_max (pGetExp (a, i), pGetExp (b, i));
[4f858ce]3728  }
3729  return n;
3730}
[a41623]3731#endif
[4f858ce]3732
[db83bf]3733static void shorten_tails (slimgb_alg * c, poly monom)
[4f858ce]3734{
3735  return;
3736// BOOLEAN corr=lenS_correct(c->strat);
[db83bf]3737  for(int i = 0; i < c->n; i++)
[4f858ce]3738  {
3739    //enter tail
[2fc974]3740
[db83bf]3741    if(c->S->m[i] == NULL)
[410ea0f]3742      continue;
3743    poly tail = c->S->m[i]->next;
3744    poly prev = c->S->m[i];
3745    BOOLEAN did_something = FALSE;
[db83bf]3746    while((tail != NULL) && (pLmCmp (tail, monom) >= 0))
[4f858ce]3747    {
[db83bf]3748      if(p_LmDivisibleBy (monom, tail, c->r))
[4f858ce]3749      {
[db83bf]3750        did_something = TRUE;
3751        prev->next = tail->next;
3752        tail->next = NULL;
3753        p_Delete (&tail, c->r);
3754        tail = prev;
3755        //PrintS("Shortened");
3756        c->lengths[i]--;
[4f858ce]3757      }
[410ea0f]3758      prev = tail;
3759      tail = tail->next;
[4f858ce]3760    }
[db83bf]3761    if(did_something)
[4f858ce]3762    {
3763      int new_pos;
[25061a]3764      wlen_type q;
[410ea0f]3765      q = pQuality (c->S->m[i], c, c->lengths[i]);
3766      new_pos = simple_posInS (c->strat, c->S->m[i], c->lengths[i], q);
[4f858ce]3767
[410ea0f]3768      int old_pos = -1;
[4f858ce]3769      //assume new_pos<old_pos
[db83bf]3770      for(int z = 0; z <= c->strat->sl; z++)
[4f858ce]3771      {
[db83bf]3772        if(c->strat->S[z] == c->S->m[i])
3773        {
3774          old_pos = z;
3775          break;
3776        }
[4f858ce]3777      }
[db83bf]3778      if(old_pos == -1)
3779        for(int z = new_pos - 1; z >= 0; z--)
3780        {
3781          if(c->strat->S[z] == c->S->m[i])
3782          {
3783            old_pos = z;
3784            break;
3785          }
3786        }
[410ea0f]3787      assume (old_pos >= 0);
3788      assume (new_pos <= old_pos);
3789      assume (pLength (c->strat->S[old_pos]) == c->lengths[i]);
3790      c->strat->lenS[old_pos] = c->lengths[i];
[db83bf]3791      if(c->strat->lenSw)
3792        c->strat->lenSw[old_pos] = q;
3793      if(new_pos < old_pos)
3794        move_forward_in_S (old_pos, new_pos, c->strat);
[410ea0f]3795      length_one_crit (c, i, c->lengths[i]);
[4f858ce]3796    }
3797  }
3798}
[2fc974]3799
[db83bf]3800#if 0                           // currently unused
3801static sorted_pair_node *pop_pair (slimgb_alg * c)
[d231ed]3802{
[410ea0f]3803  clean_top_of_pair_list (c);
[4f858ce]3804
[db83bf]3805  if(c->pair_top < 0)
[410ea0f]3806    return NULL;
3807  else
3808    return (c->apairs[c->pair_top--]);
[4f858ce]3809}
[a41623]3810#endif
[2fc974]3811
[db83bf]3812void slimgb_alg::cleanDegs (int lower, int upper)
[d231ed]3813{
[410ea0f]3814  assume (is_homog);
[9108d3]3815  int deg;
[db83bf]3816  if(TEST_OPT_PROT)
[d231ed]3817  {
[410ea0f]3818    PrintS ("C");
[9108d3]3819  }
[db83bf]3820  for(deg = lower; deg <= upper; deg++)
[d231ed]3821  {
[9108d3]3822    int i;
[db83bf]3823    for(i = 0; i < n; i++)
[d231ed]3824    {
[db83bf]3825      if(T_deg[i] == deg)
[d231ed]3826      {
[db83bf]3827        poly h;
3828        h = S->m[i];
3829        h = redNFTail (h, strat->sl, strat, lengths[i]);
3830        if(!rField_is_Zp (r))
3831        {
3832          p_Cleardenom (h, r);
3833          //p_Content(h,r);
3834        }
3835        else
3836          pNorm (h);
3837        //TODO:GCD of TERMS
3838        poly got =::gcd_of_terms (h, r);
3839        p_Delete (&gcd_of_terms[i], r);
3840        gcd_of_terms[i] = got;
3841        int len = pLength (h);
3842        wlen_type wlen = pQuality (h, this, len);
3843        if(weighted_lengths)
3844          weighted_lengths[i] = wlen;
3845        lengths[i] = len;
3846        assume (h == S->m[i]);
3847        int j;
3848        for(j = 0; j <= strat->sl; j++)
3849        {
3850          if(h == strat->S[j])
3851          {
3852            int new_pos = simple_posInS (strat, h, len, wlen);
3853            if(strat->lenS)
3854            {
3855              strat->lenS[j] = len;
3856            }
3857            if(strat->lenSw)
3858            {
3859              strat->lenSw[j] = wlen;
3860            }
3861            if(new_pos < j)
3862            {
3863              move_forward_in_S (j, new_pos, strat);
3864            }
3865            else
3866            {
3867              if(new_pos > j)
3868                new_pos = new_pos - 1;  //is identical with one element
3869              if(new_pos > j)
3870                move_backward_in_S (j, new_pos, strat);
3871            }
3872            break;
3873          }
3874        }
[410ea0f]3875      }
[9108d3]3876    }
3877  }
3878  {
[410ea0f]3879    int i, j;
[db83bf]3880    for(i = 0; i < this->n; i++)
[d231ed]3881    {
[db83bf]3882      for(j = 0; j < i; j++)
[d231ed]3883      {
[db83bf]3884        if(T_deg[i] + T_deg[j] <= upper)
3885        {
3886          now_t_rep (i, j, this);
3887        }
[9108d3]3888      }
3889    }
3890  }
3891  //TODO resort and update strat->S,strat->lenSw
3892  //TODO mark pairs
3893}
[2fc974]3894
[db83bf]3895sorted_pair_node *top_pair (slimgb_alg * c)
[d231ed]3896{
[db83bf]3897  while(c->pair_top >= 0)
[d231ed]3898  {
[db83bf]3899    super_clean_top_of_pair_list (c);   //yeah, I know, it's odd that I use a different proc here
3900    if((c->is_homog) && (c->pair_top >= 0)
3901       && (c->apairs[c->pair_top]->deg >= c->lastCleanedDeg + 2))
[d231ed]3902    {
[410ea0f]3903      int upper = c->apairs[c->pair_top]->deg - 1;
3904      c->cleanDegs (c->lastCleanedDeg + 1, upper);
3905      c->lastCleanedDeg = upper;
[d231ed]3906    }
3907    else
3908    {
[9108d3]3909      break;
3910    }
3911  }
[2fc974]3912
[db83bf]3913  if(c->pair_top < 0)
[410ea0f]3914    return NULL;
3915  else
3916    return (c->apairs[c->pair_top]);
[4f858ce]3917}
[2fc974]3918
[db83bf]3919sorted_pair_node *quick_pop_pair (slimgb_alg * c)
[d231ed]3920{
[db83bf]3921  if(c->pair_top < 0)
[410ea0f]3922    return NULL;
3923  else
3924    return (c->apairs[c->pair_top--]);
[4f858ce]3925}
[9cd599]3926
[db83bf]3927static void super_clean_top_of_pair_list (slimgb_alg * c)
[d231ed]3928{
[db83bf]3929  while((c->pair_top >= 0)
3930        && (c->apairs[c->pair_top]->i >= 0)
3931        &&
3932        (good_has_t_rep
3933         (c->apairs[c->pair_top]->j, c->apairs[c->pair_top]->i, c)))
[4f858ce]3934  {
[410ea0f]3935    free_sorted_pair_node (c->apairs[c->pair_top], c->r);
[4f858ce]3936    c->pair_top--;
3937  }
3938}
[2fc974]3939
[db83bf]3940void clean_top_of_pair_list (slimgb_alg * c)
[d231ed]3941{
[db83bf]3942  while((c->pair_top >= 0) && (c->apairs[c->pair_top]->i >= 0)
3943        &&
3944        (!state_is
3945         (UNCALCULATED, c->apairs[c->pair_top]->j, c->apairs[c->pair_top]->i,
3946          c)))
[d231ed]3947  {
[410ea0f]3948    free_sorted_pair_node (c->apairs[c->pair_top], c->r);
[4f858ce]3949    c->pair_top--;
3950  }
3951}
[2fc974]3952
[410ea0f]3953static BOOLEAN
3954state_is (calc_state state, const int &arg_i, const int &arg_j,
[db83bf]3955          slimgb_alg * c)
[d231ed]3956{
[410ea0f]3957  assume (0 <= arg_i);
3958  assume (0 <= arg_j);
3959  assume (arg_i < c->n);
3960  assume (arg_j < c->n);
[db83bf]3961  if(arg_i == arg_j)
[4f858ce]3962  {
3963    return (TRUE);
3964  }
[db83bf]3965  if(arg_i > arg_j)
[4f858ce]3966  {
[410ea0f]3967    return (c->states[arg_i][arg_j] == state);
[4f858ce]3968  }
[410ea0f]3969  else
3970    return (c->states[arg_j][arg_i] == state);
[4f858ce]3971}
[5bf76c]3972
[db83bf]3973void free_sorted_pair_node (sorted_pair_node * s, ring r)
[d231ed]3974{
[db83bf]3975  if(s->i >= 0)
[410ea0f]3976    p_Delete (&s->lcm_of_lm, r);
3977  omfree (s);
[4f858ce]3978}
[2fc974]3979
[410ea0f]3980static BOOLEAN
3981pair_better (sorted_pair_node * a, sorted_pair_node * b, slimgb_alg * c)
[d231ed]3982{
[db83bf]3983  if(a->deg < b->deg)
[410ea0f]3984    return TRUE;
[db83bf]3985  if(a->deg > b->deg)
[410ea0f]3986    return FALSE;
[4f858ce]3987
[410ea0f]3988  int comp = pLmCmp (a->lcm_of_lm, b->lcm_of_lm);
[db83bf]3989  if(comp == 1)
[410ea0f]3990    return FALSE;
[db83bf]3991  if(-1 == comp)
[410ea0f]3992    return TRUE;
[db83bf]3993  if(a->expected_length < b->expected_length)
[410ea0f]3994    return TRUE;
[db83bf]3995  if(a->expected_length > b->expected_length)
[410ea0f]3996    return FALSE;
[db83bf]3997  if(a->i + a->j < b->i + b->j)
[410ea0f]3998    return TRUE;
[db83bf]3999  if(a->i + a->j > b->i + b->j)
[410ea0f]4000    return FALSE;
[db83bf]4001  if(a->i < b->i)
[410ea0f]4002    return TRUE;
[db83bf]4003  if(a->i > b->i)
[410ea0f]4004    return FALSE;
[4f858ce]4005  return TRUE;
4006}
4007
[db83bf]4008static int tgb_pair_better_gen (const void *ap, const void *bp)
[410ea0f]4009{
4010  sorted_pair_node *a = *((sorted_pair_node **) ap);
4011  sorted_pair_node *b = *((sorted_pair_node **) bp);
4012  assume ((a->i > a->j) || (a->i < 0));
4013  assume ((b->i > b->j) || (b->i < 0));
[db83bf]4014  if(a->deg < b->deg)
[410ea0f]4015    return -1;
[db83bf]4016  if(a->deg > b->deg)
[410ea0f]4017    return 1;
4018
4019  int comp = pLmCmp (a->lcm_of_lm, b->lcm_of_lm);
4020
[db83bf]4021  if(comp == 1)
[410ea0f]4022    return 1;
[db83bf]4023  if(-1 == comp)
[410ea0f]4024    return -1;
[db83bf]4025  if(a->expected_length < b->expected_length)
[410ea0f]4026    return -1;
[db83bf]4027  if(a->expected_length > b->expected_length)
[410ea0f]4028    return 1;
[db83bf]4029  if(a->i + a->j < b->i + b->j)
[410ea0f]4030    return -1;
[db83bf]4031  if(a->i + a->j > b->i + b->j)
[410ea0f]4032    return 1;
[db83bf]4033  if(a->i < b->i)
[410ea0f]4034    return -1;
[db83bf]4035  if(a->i > b->i)
[410ea0f]4036    return 1;
[4f858ce]4037  return 0;
4038}
4039
[db83bf]4040static poly gcd_of_terms (poly p, ring r)
[d231ed]4041{
[410ea0f]4042  int max_g_0 = 0;
4043  assume (p != NULL);
[4f858ce]4044  int i;
[410ea0f]4045  poly m = pOne ();
[4f858ce]4046  poly t;
[1f637e]4047  for(i = (currRing->N); i; i--)
[4f858ce]4048  {
[410ea0f]4049    pSetExp (m, i, pGetExp (p, i));
[db83bf]4050    if(max_g_0 == 0)
4051      if(pGetExp (m, i) > 0)
4052        max_g_0 = i;
[4f858ce]4053  }
[2fc974]4054
[410ea0f]4055  t = p->next;
[db83bf]4056  while(t != NULL)
[d231ed]4057  {
[db83bf]4058    if(max_g_0 == 0)
[410ea0f]4059      break;
[db83bf]4060    for(i = max_g_0; i; i--)
[4f858ce]4061    {
[410ea0f]4062      pSetExp (m, i, si_min (pGetExp (t, i), pGetExp (m, i)));
[db83bf]4063      if(max_g_0 == i)
4064        if(pGetExp (m, i) == 0)
4065          max_g_0 = 0;
4066      if((max_g_0 == 0) && (pGetExp (m, i) > 0))
[d231ed]4067      {
[db83bf]4068        max_g_0 = i;
[4f858ce]4069      }
4070    }
[410ea0f]4071    t = t->next;
[4f858ce]4072  }
[410ea0f]4073  p_Setm (m, r);
[db83bf]4074  if(max_g_0 > 0)
[4f858ce]4075    return m;
[410ea0f]4076  pDelete (&m);
[4f858ce]4077  return NULL;
4078}
[2fc974]4079
[db83bf]4080static inline BOOLEAN pHasNotCFExtended (poly p1, poly p2, poly m)
[4f858ce]4081{
[2fc974]4082
[db83bf]4083  if(pGetComp (p1) > 0 || pGetComp (p2) > 0)
[4f858ce]4084    return FALSE;
4085  int i = 1;
4086  loop
4087  {
[db83bf]4088    if((pGetExp (p1, i) - pGetExp (m, i) > 0)
4089       && (pGetExp (p2, i) - pGetExp (m, i) > 0))
[410ea0f]4090      return FALSE;
[1f637e]4091    if(i == (currRing->N))
[410ea0f]4092      return TRUE;
[4f858ce]4093    i++;
4094  }
4095}
4096
4097//for impl reasons may return false if the the normal product criterion matches
[410ea0f]4098static inline BOOLEAN
4099extended_product_criterion (poly p1, poly gcd1, poly p2, poly gcd2,
[db83bf]4100                            slimgb_alg * c)
[d231ed]4101{
[db83bf]4102  if(c->nc)
[d491e3]4103    return FALSE;
[db83bf]4104  if(gcd1 == NULL)
[410ea0f]4105    return FALSE;
[db83bf]4106  if(gcd2 == NULL)
[410ea0f]4107    return FALSE;
[db83bf]4108  gcd1->next = gcd2;            //may ordered incorrect
[410ea0f]4109  poly m = gcd_of_terms (gcd1, c->r);
4110  gcd1->next = NULL;
[db83bf]4111  if(m == NULL)
[410ea0f]4112    return FALSE;
4113
4114  BOOLEAN erg = pHasNotCFExtended (p1, p2, m);
4115  pDelete (&m);
4116  return erg;
[4f858ce]4117}
[2fc974]4118
[db83bf]4119#if 0                           //currently unused
4120static poly kBucketGcd (kBucket * b, ring r)
[4f858ce]4121{
[410ea0f]4122  int s = 0;
[4f858ce]4123  int i;
4124  poly m, n;
[410ea0f]4125  BOOLEAN initialized = FALSE;
[db83bf]4126  for(i = MAX_BUCKET - 1; i >= 0; i--)
[31279e]4127  {
[db83bf]4128    if(b->buckets[i] != NULL)
[d231ed]4129    {
[db83bf]4130      if(!initialized)
[d231ed]4131      {
[db83bf]4132        m = gcd_of_terms (b->buckets[i], r);
4133        initialized = TRUE;
4134        if(m == NULL)
4135          return NULL;
[4f858ce]4136      }
4137      else
[410ea0f]4138      {
[db83bf]4139        n = gcd_of_terms (b->buckets[i], r);
4140        if(n == NULL)
4141        {
4142          pDelete (&m);
4143          return NULL;
4144        }
4145        n->next = m;
4146        poly t = gcd_of_terms (n, r);
4147        n->next = NULL;
4148        pDelete (&m);
4149        pDelete (&n);
4150        m = t;
4151        if(m == NULL)
4152          return NULL;
[2fc974]4153
[410ea0f]4154      }
[4f858ce]4155    }
4156  }
4157  return m;
4158}
[a41623]4159#endif
[4f858ce]4160
[db83bf]4161static inline wlen_type quality_of_pos_in_strat_S (int pos, slimgb_alg * c)
[d231ed]4162{
[db83bf]4163  if(c->strat->lenSw != NULL)
[410ea0f]4164    return c->strat->lenSw[pos];
[4f858ce]4165  return c->strat->lenS[pos];
4166}
[2fc974]4167
[1daae71]4168#ifdef HAVE_PLURAL
[410ea0f]4169static inline wlen_type
4170quality_of_pos_in_strat_S_mult_high (int pos, poly high, slimgb_alg * c)
[54e883b]4171  //meant only for nc
4172{
[410ea0f]4173  poly m = pOne ();
4174  pExpVectorDiff (m, high, c->strat->S[pos]);
4175  poly product = nc_mm_Mult_pp (m, c->strat->S[pos], c->r);
4176  wlen_type erg = pQuality (product, c);
4177  pDelete (&m);
4178  pDelete (&product);
[54e883b]4179  return erg;
4180}
[1daae71]4181#endif
[4f858ce]4182
[410ea0f]4183static void
4184multi_reduction_lls_trick (red_object * los, int losl, slimgb_alg * c,
[db83bf]4185                           find_erg & erg)
[d231ed]4186{
[410ea0f]4187  erg.expand = NULL;
[db83bf]4188  BOOLEAN swap_roles;           //from reduce_by, to_reduce_u if fromS
4189  if(erg.fromS)
[d231ed]4190  {
[db83bf]4191    if(pLmEqual (c->strat->S[erg.reduce_by], los[erg.to_reduce_u].p))
[4f858ce]4192    {
[410ea0f]4193      wlen_type quality_a = quality_of_pos_in_strat_S (erg.reduce_by, c);
4194      int best = erg.to_reduce_u + 1;
[4f858ce]4195/*
[2fc974]4196      for (i=erg.to_reduce_u;i>=erg.to_reduce_l;i--)
4197      {
[e4e1c2a]4198  int qc=los[i].guess_quality(c);
[2fc974]4199  if (qc<quality_a)
4200  {
[e4e1c2a]4201    best=i;
4202    quality_a=qc;
4203  }
[4f858ce]4204      }
[2fc974]4205      if(best!=erg.to_reduce_u+1)
4206      {*/
[ca4a891]4207      wlen_type qc;
[410ea0f]4208      best = find_best (los, erg.to_reduce_l, erg.to_reduce_u, qc, c);
[db83bf]4209      if(qc < quality_a)
[d231ed]4210      {
[db83bf]4211        los[best].flatten ();
4212        int b_pos = kBucketCanonicalize (los[best].bucket);
4213        los[best].p = los[best].bucket->buckets[b_pos];
4214        qc = pQuality (los[best].bucket->buckets[b_pos], c);
4215        if(qc < quality_a)
4216        {
4217          red_object h = los[erg.to_reduce_u];
4218          los[erg.to_reduce_u] = los[best];
4219          los[best] = h;
4220          swap_roles = TRUE;
4221        }
4222        else
4223          swap_roles = FALSE;
[4f858ce]4224      }
[31279e]4225      else
[4f858ce]4226      {
[db83bf]4227        swap_roles = FALSE;
[e4e1c2a]4228      }
[4f858ce]4229    }
[410ea0f]4230    else
[2fc974]4231    {
[db83bf]4232      if(erg.to_reduce_u > erg.to_reduce_l)
[2fc974]4233      {
[db83bf]4234        wlen_type quality_a = quality_of_pos_in_strat_S (erg.reduce_by, c);
[410ea0f]4235#ifdef HAVE_PLURAL
[db83bf]4236        if((c->nc) && (!(rIsSCA (c->r))))
4237          quality_a =
4238            quality_of_pos_in_strat_S_mult_high (erg.reduce_by,
4239                                                 los[erg.to_reduce_u].p, c);
[410ea0f]4240#endif
[db83bf]4241        int best = erg.to_reduce_u + 1;
4242        wlen_type qc;
4243        best = find_best (los, erg.to_reduce_l, erg.to_reduce_u, qc, c);
4244        assume (qc == los[best].guess_quality (c));
4245        if(qc < quality_a)
4246        {
4247          los[best].flatten ();
4248          int b_pos = kBucketCanonicalize (los[best].bucket);
4249          los[best].p = los[best].bucket->buckets[b_pos];
4250          qc = pQuality (los[best].bucket->buckets[b_pos], c);
4251          //(best!=erg.to_reduce_u+1)
4252          if(qc < quality_a)
4253          {
4254            red_object h = los[erg.to_reduce_u];
4255            los[erg.to_reduce_u] = los[best];
4256            los[best] = h;
4257            erg.reduce_by = erg.to_reduce_u;
4258            erg.fromS = FALSE;
4259            erg.to_reduce_u--;
4260          }
4261        }
[2fc974]4262      }
4263      else
4264      {
[db83bf]4265        assume (erg.to_reduce_u == erg.to_reduce_l);
4266        wlen_type quality_a = quality_of_pos_in_strat_S (erg.reduce_by, c);
4267        wlen_type qc = los[erg.to_reduce_u].guess_quality (c);
4268        if(qc < 0)
4269          PrintS ("Wrong wlen_type");
4270        if(qc < quality_a)
4271        {
4272          int best = erg.to_reduce_u;
4273          los[best].flatten ();
4274          int b_pos = kBucketCanonicalize (los[best].bucket);
4275          los[best].p = los[best].bucket->buckets[b_pos];
4276          qc = pQuality (los[best].bucket->buckets[b_pos], c);
4277          assume (qc >= 0);
4278          if(qc < quality_a)
4279          {
4280            BOOLEAN exp = FALSE;
4281            if(qc <= 2)
4282            {
4283              //Print("\n qc is %lld \n",qc);
4284              exp = TRUE;
4285            }
4286            else
4287            {
4288              if(qc < quality_a / 2)
4289                exp = TRUE;
4290              else if(erg.reduce_by < c->n / 4)
4291                exp = TRUE;
4292            }
4293            if(exp)
4294            {
4295              poly clear_into;
4296              los[erg.to_reduce_u].flatten ();
4297              kBucketClear (los[erg.to_reduce_u].bucket, &clear_into,
4298                            &erg.expand_length);
4299              erg.expand = pCopy (clear_into);
4300              kBucketInit (los[erg.to_reduce_u].bucket, clear_into,
4301                           erg.expand_length);
4302              if(TEST_OPT_PROT)
4303                PrintS ("e");
4304            }
4305          }
4306        }
[2fc974]4307      }
4308
[410ea0f]4309      swap_roles = FALSE;
[2fc974]4310      return;
[410ea0f]4311    }
[2fc974]4312  }
4313  else
4314  {
[db83bf]4315    if(erg.reduce_by > erg.to_reduce_u)
[2fc974]4316    {
4317      //then lm(rb)>= lm(tru) so =
[410ea0f]4318      assume (erg.reduce_by == erg.to_reduce_u + 1);
4319      int best = erg.reduce_by;
4320      wlen_type quality_a = los[erg.reduce_by].guess_quality (c);
[2fc974]4321      wlen_type qc;
[410ea0f]4322      best = find_best (los, erg.to_reduce_l, erg.to_reduce_u, qc, c);
[2fc974]4323
[db83bf]4324      if(qc < quality_a)
[2fc974]4325      {
[db83bf]4326        red_object h = los[erg.reduce_by];
4327        los[erg.reduce_by] = los[best];
4328        los[best] = h;
[410ea0f]4329      }
4330      swap_roles = FALSE;
4331      return;
[2fc974]4332    }
4333    else
4334    {
[410ea0f]4335      assume (!pLmEqual (los[erg.reduce_by].p, los[erg.to_reduce_l].p));
4336      assume (erg.to_reduce_u == erg.to_reduce_l);
[2fc974]4337      //further assume, that reduce_by is the above all other polys
4338      //with same leading term
[410ea0f]4339      int il = erg.reduce_by;
4340      wlen_type quality_a = los[erg.reduce_by].guess_quality (c);
[2fc974]4341      wlen_type qc;
[db83bf]4342      while((il > 0) && pLmEqual (los[il - 1].p, los[il].p))
[2fc974]4343      {
[db83bf]4344        il--;
4345        qc = los[il].guess_quality (c);
4346        if(qc < quality_a)
4347        {
4348          quality_a = qc;
4349          erg.reduce_by = il;
4350        }
[2fc974]4351      }
[410ea0f]4352      swap_roles = FALSE;
[2fc974]4353    }
4354  }
[db83bf]4355  if(swap_roles)
[2fc974]4356  {
[db83bf]4357    if(TEST_OPT_PROT)
[410ea0f]4358      PrintS ("b");
[2fc974]4359    poly clear_into;
4360    int new_length;
[db83bf]4361    int bp = erg.to_reduce_u;   //bucket_positon
[2fc974]4362    //kBucketClear(los[bp].bucket,&clear_into,&new_length);
[410ea0f]4363    new_length = los[bp].clear_to_poly ();
4364    clear_into = los[bp].p;
4365    poly p = c->strat->S[erg.reduce_by];
4366    int j = erg.reduce_by;
[db83bf]4367    int old_length = c->strat->lenS[j]; // in view of S
[410ea0f]4368    los[bp].p = p;
[db83bf]4369    if(c->eliminationProblem)
[2fc974]4370    {
[410ea0f]4371      los[bp].sugar = c->pTotaldegree_full (p);
[2fc974]4372    }
[410ea0f]4373    kBucketInit (los[bp].bucket, p, old_length);
4374    wlen_type qal = pQuality (clear_into, c, new_length);
4375    int pos_in_c = -1;
[2fc974]4376    int z;
4377    int new_pos;
[410ea0f]4378    new_pos = simple_posInS (c->strat, clear_into, new_length, qal);
4379    assume (new_pos <= j);
[db83bf]4380    for(z = c->n; z; z--)
[2fc974]4381    {
[db83bf]4382      if(p == c->S->m[z - 1])
[2fc974]4383      {
[db83bf]4384        pos_in_c = z - 1;
4385        break;
[2fc974]4386      }
4387    }
[5a9e7b]4388
[410ea0f]4389    int tdeg_full = -1;
4390    int tdeg = -1;
[db83bf]4391    if(pos_in_c >= 0)
[2fc974]4392    {
[410ea0f]4393#ifdef TGB_RESORT_PAIRS
4394      c->used_b = TRUE;
4395      c->replaced[pos_in_c] = TRUE;
4396#endif
4397      tdeg = c->T_deg[pos_in_c];
4398      c->S->m[pos_in_c] = clear_into;
4399      c->lengths[pos_in_c] = new_length;
4400      c->weighted_lengths[pos_in_c] = qal;
[db83bf]4401      if(c->gcd_of_terms[pos_in_c] == NULL)
4402        c->gcd_of_terms[pos_in_c] = gcd_of_terms (clear_into, c->r);
4403      if(c->T_deg_full)
4404        tdeg_full = c->T_deg_full[pos_in_c] =
4405          c->pTotaldegree_full (clear_into);
[410ea0f]4406      else
[db83bf]4407        tdeg_full = tdeg;
[410ea0f]4408      c_S_element_changed_hook (pos_in_c, c);
[2fc974]4409    }
4410    else
4411    {
[db83bf]4412      if(c->eliminationProblem)
[2fc974]4413      {
[db83bf]4414        tdeg_full = c->pTotaldegree_full (clear_into);
4415        tdeg = c->pTotaldegree (clear_into);
[2fc974]4416      }
4417    }
[410ea0f]4418    c->strat->S[j] = clear_into;
4419    c->strat->lenS[j] = new_length;
[31279e]4420
[410ea0f]4421    assume (pLength (clear_into) == new_length);
[db83bf]4422    if(c->strat->lenSw != NULL)
[410ea0f]4423      c->strat->lenSw[j] = qal;
[db83bf]4424    if(!rField_is_Zp (c->r))
[2fc974]4425    {
[db83bf]4426      p_Cleardenom (clear_into, c->r);  //should be unnecessary
[2fc974]4427      //p_Content(clear_into, c->r);
4428    }
4429    else
[410ea0f]4430      pNorm (clear_into);
[4f858ce]4431#ifdef FIND_DETERMINISTIC
[410ea0f]4432    erg.reduce_by = j;
[2fc974]4433    //resort later see diploma thesis, find_in_S must be deterministic
4434    //during multireduction if spolys are only in the span of the
4435    //input polys
[4f858ce]4436#else
[db83bf]4437    if(new_pos < j)
[2fc974]4438    {
[db83bf]4439      if(c->strat->honey)
4440        c->strat->ecartS[j] = tdeg_full - tdeg;
[410ea0f]4441      move_forward_in_S (j, new_pos, c->strat);
4442      erg.reduce_by = new_pos;
[2fc974]4443    }
[4f858ce]4444#endif
[2fc974]4445  }
[4f858ce]4446}
[2fc974]4447
[db83bf]4448static int fwbw (red_object * los, int i)
[2fc974]4449{
[410ea0f]4450  int i2 = i;
4451  int step = 1;
[31279e]4452
[410ea0f]4453  BOOLEAN bw = FALSE;
4454  BOOLEAN incr = TRUE;
[31279e]4455
[db83bf]4456  while(1)
[410ea0f]4457  {
[db83bf]4458    if(!bw)
[410ea0f]4459    {
4460      step = si_min (i2, step);
[db83bf]4461      if(step == 0)
4462        break;
[410ea0f]4463      i2 -= step;
[31279e]4464
[db83bf]4465      if(!pLmEqual (los[i].p, los[i2].p))
[410ea0f]4466      {
[db83bf]4467        bw = TRUE;
4468        incr = FALSE;
[410ea0f]4469      }
4470      else
4471      {
[db83bf]4472        if((!incr) && (step == 1))
4473          break;
[410ea0f]4474      }
4475    }
4476    else
4477    {
4478      step = si_min (i - i2, step);
[db83bf]4479      if(step == 0)
4480        break;
[410ea0f]4481      i2 += step;
[db83bf]4482      if(pLmEqual (los[i].p, los[i2].p))
[410ea0f]4483      {
[db83bf]4484        if(step == 1)
4485          break;
4486        else
4487        {
4488          bw = FALSE;
4489        }
[410ea0f]4490      }
4491    }
[db83bf]4492    if(incr)
[410ea0f]4493      step *= 2;
4494    else
4495    {
[db83bf]4496      if(step % 2 == 1)
4497        step = (step + 1) / 2;
[410ea0f]4498      else
[db83bf]4499        step /= 2;
[410ea0f]4500    }
4501  }
4502  return i2;
[4f858ce]4503}
[2fc974]4504
[410ea0f]4505static void
4506canonicalize_region (red_object * los, int l, int u, slimgb_alg * c)
[2fc974]4507{
[410ea0f]4508  assume (l <= u + 1);
4509  int i;
[db83bf]4510  for(i = l; i <= u; i++)
[410ea0f]4511  {
4512    kBucketCanonicalize (los[i].bucket);
4513  }
[03f3269]4514}
[410ea0f]4515
4516static void
4517multi_reduction_find (red_object * los, int losl, slimgb_alg * c, int startf,
[db83bf]4518                      find_erg & erg)
[2fc974]4519{
[410ea0f]4520  kStrategy strat = c->strat;
[4f858ce]4521
[410ea0f]4522  assume (startf <= losl);
4523  assume ((startf == losl - 1)
[db83bf]4524          || (pLmCmp (los[startf].p, los[startf + 1].p) == -1));
[410ea0f]4525  int i = startf;
[31279e]4526
[4f858ce]4527  int j;
[db83bf]4528  while(i >= 0)
[410ea0f]4529  {
4530    assume ((i == losl - 1) || (pLmCmp (los[i].p, los[i + 1].p) <= 0));
4531    assume (is_valid_ro (los[i]));
4532    assume ((!(c->eliminationProblem))
[db83bf]4533            || (los[i].sugar >= c->pTotaldegree (los[i].p)));
[410ea0f]4534    j = kFindDivisibleByInS_easy (strat, los[i]);
[db83bf]4535    if(j >= 0)
[2fc974]4536    {
[410ea0f]4537      erg.to_reduce_u = i;
4538      erg.reduce_by = j;
4539      erg.fromS = TRUE;
4540      int i2 = fwbw (los, i);
4541      assume (pLmEqual (los[i].p, los[i2].p));
4542      assume ((i2 == 0) || (!pLmEqual (los[i2].p, los[i2 - 1].p)));
4543      assume (i >= i2);
4544
4545      erg.to_reduce_l = i2;
4546      assume ((i == losl - 1) || (pLmCmp (los[i].p, los[i + 1].p) == -1));
4547      canonicalize_region (los, erg.to_reduce_u + 1, startf, c);
[4f858ce]4548      return;
4549    }
[db83bf]4550    if(j < 0)
[2fc974]4551    {
[4f858ce]4552      //not reduceable, try to use this for reducing higher terms
[410ea0f]4553      int i2 = fwbw (los, i);
4554      assume (pLmEqual (los[i].p, los[i2].p));
4555      assume ((i2 == 0) || (!pLmEqual (los[i2].p, los[i2 - 1].p)));
4556      assume (i >= i2);
[db83bf]4557      if(i2 != i)
[2fc974]4558      {
[db83bf]4559        erg.to_reduce_u = i - 1;
4560        erg.to_reduce_l = i2;
4561        erg.reduce_by = i;
4562        erg.fromS = FALSE;
4563        assume ((i == losl - 1) || (pLmCmp (los[i].p, los[i + 1].p) == -1));
4564        canonicalize_region (los, erg.to_reduce_u + 1, startf, c);
4565        return;
[4f858ce]4566      }
4567      i--;
4568    }
4569  }
[db83bf]4570  erg.reduce_by = -1;           //error code
[4f858ce]4571  return;
4572}
4573
4574 //  nicht reduzierbare eintraege in ergebnisliste schreiben
4575//   nullen loeschen
[2fc974]4576//   while(finde_groessten leitterm reduzierbar(c,erg))
4577//   {
[31279e]4578
[410ea0f]4579static int
4580multi_reduction_clear_zeroes (red_object * los, int losl, int l, int u)
[4f858ce]4581{
[410ea0f]4582  int deleted = 0;
4583  int i = l;
4584  int last = -1;
[db83bf]4585  while(i <= u)
[4f858ce]4586  {
[db83bf]4587    if(los[i].p == NULL)
[2fc974]4588    {
[410ea0f]4589      kBucketDestroy (&los[i].bucket);
[4f858ce]4590//      delete los[i];//here we assume los are constructed with new
[31279e]4591      //destroy resources, must be added here
[db83bf]4592      if(last >= 0)
[410ea0f]4593      {
[db83bf]4594        memmove (los + (int) (last + 1 - deleted), los + (last + 1),
4595                 sizeof (red_object) * (i - 1 - last));
[410ea0f]4596      }
4597      last = i;
4598      deleted++;
[4f858ce]4599    }
4600    i++;
4601  }
[db83bf]4602  if((last >= 0) && (last != losl - 1))
[410ea0f]4603    memmove (los + (int) (last + 1 - deleted), los + last + 1,
[db83bf]4604             sizeof (red_object) * (losl - 1 - last));
[4f858ce]4605  return deleted;
4606}
[6a2e9c]4607
[db83bf]4608int search_red_object_pos (red_object * a, int top, red_object * key)
[2fc974]4609{
[410ea0f]4610  int an = 0;
4611  int en = top;
[db83bf]4612  if(top == -1)
[410ea0f]4613    return 0;
[db83bf]4614  if(pLmCmp (key->p, a[top].p) == 1)
[410ea0f]4615    return top + 1;
4616  int i;
4617  loop
4618  {
[db83bf]4619    if(an >= en - 1)
[08cd81]4620    {
[db83bf]4621      if(pLmCmp (key->p, a[an].p) == -1)
4622        return an;
[410ea0f]4623      return en;
[08cd81]4624    }
[410ea0f]4625    i = (an + en) / 2;
[db83bf]4626    if(pLmCmp (key->p, a[i].p) == -1)
[410ea0f]4627      en = i;
4628    else
4629      an = i;
4630  }
[08cd81]4631}
[2fc974]4632
[db83bf]4633static void sort_region_down (red_object * los, int l, int u, slimgb_alg * c)
[4f858ce]4634{
[410ea0f]4635  int r_size = u - l + 1;
4636  qsort (los + l, r_size, sizeof (red_object), red_object_better_gen);
[4f858ce]4637  int i;
[410ea0f]4638  int *new_indices = (int *) omalloc ((r_size) * sizeof (int));
4639  int bound = 0;
4640  BOOLEAN at_end = FALSE;
[db83bf]4641  for(i = l; i <= u; i++)
[2fc974]4642  {
[db83bf]4643    if(!(at_end))
[2fc974]4644    {
[410ea0f]4645      bound = new_indices[i - l] =
[db83bf]4646        bound + search_red_object_pos (los + bound, l - bound - 1, los + i);
4647      if(bound == l)
4648        at_end = TRUE;
[08cd81]4649    }
[2fc974]4650    else
4651    {
[410ea0f]4652      new_indices[i - l] = l;
[08cd81]4653    }
4654  }
[410ea0f]4655  red_object *los_region =
4656    (red_object *) omalloc (sizeof (red_object) * (u - l + 1));
[db83bf]4657  for(int i = 0; i < r_size; i++)
[2fc974]4658  {
[410ea0f]4659    new_indices[i] += i;
4660    los_region[i] = los[l + i];
4661    assume ((i == 0) || (new_indices[i] > new_indices[i - 1]));
[08cd81]4662  }
[4f858ce]4663
[410ea0f]4664  i = r_size - 1;
4665  int j = u;
4666  int j2 = l - 1;
[db83bf]4667  while(i >= 0)
[2fc974]4668  {
[db83bf]4669    if(new_indices[i] == j)
[2fc974]4670    {
[410ea0f]4671      los[j] = los_region[i];
[08cd81]4672      i--;
4673      j--;
[2fc974]4674    }
4675    else
4676    {
[410ea0f]4677      assume (new_indices[i] < j);
4678      los[j] = los[j2];
4679      assume (j2 >= 0);
[08cd81]4680      j2--;
4681      j--;
[4f858ce]4682    }
4683  }
[410ea0f]4684  omfree (los_region);
4685  omfree (new_indices);
[4f858ce]4686}
4687
4688//assume that los is ordered ascending by leading term, all non zero
[db83bf]4689static void multi_reduction (red_object * los, int &losl, slimgb_alg * c)
[4f858ce]4690{
[410ea0f]4691  poly *delay = (poly *) omalloc (losl * sizeof (poly));
4692  int delay_s = 0;
[4f858ce]4693  //initialize;
[410ea0f]4694  assume (c->strat->sl >= 0);
4695  assume (losl > 0);
[4f858ce]4696  int i;
[410ea0f]4697  wlen_type max_initial_quality = 0;
[31279e]4698
[db83bf]4699  for(i = 0; i < losl; i++)
[2fc974]4700  {
[410ea0f]4701    los[i].sev = pGetShortExpVector (los[i].p);
[4f858ce]4702//SetShortExpVector();
[410ea0f]4703    los[i].p = kBucketGetLm (los[i].bucket);
[db83bf]4704    if(los[i].initial_quality > max_initial_quality)
[410ea0f]4705      max_initial_quality = los[i].initial_quality;
[44c2b1]4706    // else
4707//         Print("init2_qal=%lld;", los[i].initial_quality);
4708//     Print("initial_quality=%lld;",max_initial_quality);
[4f858ce]4709  }
4710
[410ea0f]4711  int curr_pos = losl - 1;
[4f858ce]4712
[5a9e7b]4713//  nicht reduzierbare eintrï¿œe in ergebnisliste schreiben
[4f858ce]4714  // nullen loeschen
[db83bf]4715  while(curr_pos >= 0)
[2fc974]4716  {
[db83bf]4717    if((c->use_noro_last_block)
4718       && (lies_in_last_dp_block (los[curr_pos].p, c)))
[2fc974]4719    {
[410ea0f]4720      int pn_noro = curr_pos + 1;
4721      poly *p_noro = (poly *) omalloc (pn_noro * sizeof (poly));
[db83bf]4722      for(i = 0; i < pn_noro; i++)
[410ea0f]4723      {
[db83bf]4724        int dummy_len;
4725        poly p;
4726        los[i].p = NULL;
4727        kBucketClear (los[i].bucket, &p, &dummy_len);
4728        p_noro[i] = p;
[410ea0f]4729      }
[47e836b]4730      if(n_GetChar(currRing->cf) < 255)
[410ea0f]4731      {
[db83bf]4732        noro_step < tgb_uint8 > (p_noro, pn_noro, c);
[410ea0f]4733      }
4734      else
4735      {
[47e836b]4736        if(n_GetChar(currRing->cf) < 65000)
[db83bf]4737        {
4738          noro_step < tgb_uint16 > (p_noro, pn_noro, c);
4739        }
4740        else
4741        {
4742          noro_step < tgb_uint32 > (p_noro, pn_noro, c);
4743        }
[410ea0f]4744      }
[db83bf]4745      for(i = 0; i < pn_noro; i++)
[410ea0f]4746      {
[db83bf]4747        los[i].p = p_noro[i];
4748        los[i].sev = pGetShortExpVector (los[i].p);
4749        //ignore quality
4750        kBucketInit (los[i].bucket, los[i].p, pLength (los[i].p));
[410ea0f]4751      }
4752      qsort (los, pn_noro, sizeof (red_object), red_object_better_gen);
4753      int deleted =
[db83bf]4754        multi_reduction_clear_zeroes (los, losl, pn_noro, curr_pos);
[410ea0f]4755      losl -= deleted;
4756      curr_pos -= deleted;
4757      break;
[f2b5839]4758    }
[4f858ce]4759    find_erg erg;
[6a2e9c]4760
[db83bf]4761    multi_reduction_find (los, losl, c, curr_pos, erg); //last argument should be curr_pos
4762    if(erg.reduce_by < 0)
[410ea0f]4763      break;
[4f858ce]4764
[410ea0f]4765    erg.expand = NULL;
[31279e]4766
[410ea0f]4767    multi_reduction_lls_trick (los, losl, c, erg);
[31279e]4768
[4f858ce]4769    int i;
4770    //    wrp(los[erg.to_reduce_u].p);
[a610ee]4771    //PrintLn();
[410ea0f]4772    multi_reduce_step (erg, los, c);
[31279e]4773
[e4e1c2a]4774
[db83bf]4775    if(!TEST_OPT_REDTHROUGH)
[228b631]4776    {
[db83bf]4777      for(i = erg.to_reduce_l; i <= erg.to_reduce_u; i++)
[410ea0f]4778      {
[db83bf]4779        if(los[i].p != NULL)    //the check (los[i].p!=NULL) might be invalid
4780        {
4781          //
4782          assume (los[i].initial_quality > 0);
4783          if(los[i].guess_quality (c)
4784             > 1.5 * delay_factor * max_initial_quality)
4785          {
4786            if(TEST_OPT_PROT)
4787              PrintS ("v");
4788            los[i].canonicalize ();
4789            if(los[i].guess_quality (c) > delay_factor * max_initial_quality)
4790            {
4791              if(TEST_OPT_PROT)
4792                PrintS (".");
4793              los[i].clear_to_poly ();
4794              //delay.push_back(los[i].p);
4795              delay[delay_s] = los[i].p;
4796              delay_s++;
4797              los[i].p = NULL;
4798            }
4799          }
4800        }
[410ea0f]4801      }
4802    }
[db83bf]4803    int deleted = multi_reduction_clear_zeroes (los, losl, erg.to_reduce_l,
4804                                                erg.to_reduce_u);
4805    if(erg.fromS == FALSE)
[410ea0f]4806      curr_pos = si_max (erg.to_reduce_u, erg.reduce_by);
[4f858ce]4807    else
[410ea0f]4808      curr_pos = erg.to_reduce_u;
[4f858ce]4809    losl -= deleted;
4810    curr_pos -= deleted;
4811
4812    //Print("deleted %i \n",deleted);
[db83bf]4813    if((TEST_V_UPTORADICAL) && (!(erg.fromS)))
[410ea0f]4814      sort_region_down (los, si_min (erg.to_reduce_l, erg.reduce_by),
[db83bf]4815                        (si_max (erg.to_reduce_u, erg.reduce_by)) - deleted,
4816                        c);
[31279e]4817    else
[410ea0f]4818      sort_region_down (los, erg.to_reduce_l, erg.to_reduce_u - deleted, c);
[03f3269]4819
[db83bf]4820    if(erg.expand)
[4f858ce]4821    {
4822#ifdef FIND_DETERMINISTIC
4823      int i;
[db83bf]4824      for(i = 0; c->expandS[i]; i++) ;
[410ea0f]4825      c->expandS = (poly *) omrealloc (c->expandS, (i + 2) * sizeof (poly));
4826      c->expandS[i] = erg.expand;
4827      c->expandS[i + 1] = NULL;
[4f858ce]4828#else
[410ea0f]4829      int ecart = 0;
[db83bf]4830      if(c->eliminationProblem)
[2fc974]4831      {
[db83bf]4832        ecart =
4833          c->pTotaldegree_full (erg.expand) - c->pTotaldegree (erg.expand);
[321283]4834      }
[410ea0f]4835      add_to_reductors (c, erg.expand, erg.expand_length, ecart);
[4f858ce]4836#endif
4837    }
4838  }
[31279e]4839
[6e08ad]4840  //sorted_pair_node** pairs=(sorted_pair_node**)
4841  //  omalloc(delay_s*sizeof(sorted_pair_node*));
[410ea0f]4842  c->introduceDelayedPairs (delay, delay_s);
[6e08ad]4843  /*
[410ea0f]4844     for(i=0;i<delay_s;i++)
4845     {
4846     poly p=delay[i];
4847     //if (rPar(c->r)==0)
4848     simplify_poly(p,c->r);
4849     sorted_pair_node* si=(sorted_pair_node*) omalloc(sizeof(sorted_pair_node));
4850     si->i=-1;
4851     si->j=-1;
4852     if (!rField_is_Zp(c->r))
4853     {
4854     if (!c->nc)
4855     p=redTailShort(p, c->strat);
4856     p_Cleardenom(p, c->r);
4857     p_Content(p, c->r);
4858     }
4859     si->expected_length=pQuality(p,c,pLength(p));
4860     si->deg=pTotaldegree(p);
4861     si->lcm_of_lm=p;
4862     pairs[i]=si;
4863     }
4864     qsort(pairs,delay_s,sizeof(sorted_pair_node*),tgb_pair_better_gen2);
4865     c->apairs=spn_merge(c->apairs,c->pair_top+1,pairs,delay_s,c);
4866     c->pair_top+=delay_s; */
4867  omfree (delay);
[6e08ad]4868  //omfree(pairs);
[4f858ce]4869  return;
4870}
[2fc974]4871
[db83bf]4872void red_object::flatten ()
[2fc974]4873{
[410ea0f]4874  assume (p == kBucketGetLm (bucket));
[4f858ce]4875}
[2fc974]4876
[db83bf]4877void red_object::validate ()
[2fc974]4878{
[410ea0f]4879  p = kBucketGetLm (bucket);
[db83bf]4880  if(p)
[410ea0f]4881    sev = pGetShortExpVector (p);
[4f858ce]4882}
[2fc974]4883
[db83bf]4884int red_object::clear_to_poly ()
[2fc974]4885{
[410ea0f]4886  flatten ();
[4f858ce]4887  int l;
[410ea0f]4888  kBucketClear (bucket, &p, &l);
[4f858ce]4889  return l;
4890}
4891
[db83bf]4892void reduction_step::reduce (red_object * r, int l, int u)
[410ea0f]4893{
4894}
[2fc974]4895
[db83bf]4896void simple_reducer::do_reduce (red_object & ro)
[1daae71]4897{
[d491e3]4898  number coef;
[1daae71]4899#ifdef HAVE_PLURAL
[db83bf]4900  if(c->nc)
[410ea0f]4901    nc_BucketPolyRed_Z (ro.bucket, p, &coef);
[1daae71]4902  else
4903#endif
[410ea0f]4904    coef = kBucketPolyRed (ro.bucket, p, p_len, c->strat->kNoether);
4905  nDelete (&coef);
[4f858ce]4906}
4907
[db83bf]4908void simple_reducer::reduce (red_object * r, int l, int u)
[2fc974]4909{
[410ea0f]4910  this->pre_reduce (r, l, u);
[4f858ce]4911  int i;
4912//debug start
[5a9e7b]4913
[db83bf]4914  if(c->eliminationProblem)
[2fc974]4915  {
[410ea0f]4916    assume (p_LmEqual (r[l].p, r[u].p, c->r));
[321283]4917    /*int lm_deg=pTotaldegree(r[l].p);
[410ea0f]4918       reducer_deg=lm_deg+pTotaldegree_full(p)-pTotaldegree(p); */
[d64382]4919  }
[4f858ce]4920
[db83bf]4921  for(i = l; i <= u; i++)
[2fc974]4922  {
[410ea0f]4923    this->do_reduce (r[i]);
[db83bf]4924    if(c->eliminationProblem)
[2fc974]4925    {
[410ea0f]4926      r[i].sugar = si_max (r[i].sugar, reducer_deg);
[d64382]4927    }
[4f858ce]4928  }
[db83bf]4929  for(i = l; i <= u; i++)
[2fc974]4930  {
[410ea0f]4931    kBucketSimpleContent (r[i].bucket);
4932    r[i].validate ();
4933#ifdef TGB_DEBUG
4934#endif
[bddc9d]4935  }
[4f858ce]4936}
[2fc974]4937
[410ea0f]4938reduction_step::~reduction_step ()
4939{
4940}
[2fc974]4941
[410ea0f]4942simple_reducer::~simple_reducer ()
[2fc974]4943{
[db83bf]4944  if(fill_back != NULL)
[4f858ce]4945  {
[410ea0f]4946    kBucketInit (fill_back, p, p_len);
[4f858ce]4947  }
[410ea0f]4948  fill_back = NULL;
[4f858ce]4949}
[31279e]4950
[db83bf]4951void multi_reduce_step (find_erg & erg, red_object * r, slimgb_alg * c)
[2fc974]4952{
[410ea0f]4953  static int id = 0;
[4f858ce]4954  id++;
[03f3269]4955  unsigned long sev;
[410ea0f]4956  BOOLEAN lt_changed = FALSE;
4957  int rn = erg.reduce_by;
[4f858ce]4958  poly red;
4959  int red_len;
[410ea0f]4960  simple_reducer *pointer;
4961  BOOLEAN work_on_copy = FALSE;
[db83bf]4962  if(erg.fromS)
[2fc974]4963  {
[410ea0f]4964    red = c->strat->S[rn];
4965    red_len = c->strat->lenS[rn];
4966    assume (red_len == pLength (red));
[4f858ce]4967  }
4968  else
4969  {
[410ea0f]4970    r[rn].flatten ();
4971    kBucketClear (r[rn].bucket, &red, &red_len);
[31279e]4972
[db83bf]4973    if(!rField_is_Zp (c->r))
[4f858ce]4974    {
[db83bf]4975      p_Cleardenom (red, c->r); //should be unnecessary
[a0d9be]4976      //p_Content(red, c->r);
[4f858ce]4977    }
[410ea0f]4978    pNormalize (red);
[db83bf]4979    if(c->eliminationProblem)
[a0d9be]4980    {
[410ea0f]4981      r[rn].sugar = c->pTotaldegree_full (red);
[d64382]4982    }
[03f3269]4983
[db83bf]4984    if((!(erg.fromS)) && (TEST_V_UPTORADICAL))
[a0d9be]4985    {
[db83bf]4986      if(polynomial_root (red, c->r))
4987        lt_changed = TRUE;
[410ea0f]4988      sev = p_GetShortExpVector (red, c->r);
[a0d9be]4989    }
[410ea0f]4990    red_len = pLength (red);
[4f858ce]4991  }
[db83bf]4992  if(((TEST_V_MODPSOLVSB) && (red_len > 1))
4993     || ((c->nc) || (erg.to_reduce_u - erg.to_reduce_l > 5)))
[2fc974]4994  {
[410ea0f]4995    work_on_copy = TRUE;
[4f858ce]4996    // poly m=pOne();
[410ea0f]4997    poly m = c->tmp_lm;
4998    pSetCoeff (m, nInit (1));
4999    pSetComp (m, 0);
[1f637e]5000    for(int i = 1; i <= (currRing->N); i++)
[410ea0f]5001      pSetExp (m, i, (pGetExp (r[erg.to_reduce_l].p, i) - pGetExp (red, i)));
5002    pSetm (m);
[d491e3]5003    poly red_cp;
[410ea0f]5004#ifdef HAVE_PLURAL
[db83bf]5005    if(c->nc)
[410ea0f]5006      red_cp = nc_mm_Mult_pp (m, red, c->r);
[d491e3]5007    else
[410ea0f]5008#endif
5009      red_cp = ppMult_mm (red, m);
[db83bf]5010    if(!erg.fromS)
[2fc974]5011    {
[410ea0f]5012      kBucketInit (r[rn].bucket, red, red_len);
[4f858ce]5013    }
5014    //now reduce the copy
[9cbb7a3]5015    //static poly redNF2 (poly h,slimgb_alg* c , int &len, number&  m,int n)
[03f3269]5016
[db83bf]5017    if(!c->nc)
[410ea0f]5018      redTailShort (red_cp, c->strat);
[4f858ce]5019    //number mul;
5020    // red_len--;
5021//     red_cp->next=redNF2(red_cp->next,c,red_len,mul,c->average_length);
5022//     pSetCoeff(red_cp,nMult(red_cp->coef,mul));
5023//     nDelete(&mul);
5024//     red_len++;
[410ea0f]5025    red = red_cp;
5026    red_len = pLength (red);
[4f858ce]5027    // pDelete(&m);
5028  }
5029
[410ea0f]5030  assume (red_len == pLength (red));
[5a9e7b]5031
[410ea0f]5032  int reducer_deg = 0;
[db83bf]5033  if(c->eliminationProblem)
[2fc974]5034  {
[410ea0f]5035    int lm_deg = c->pTotaldegree (r[erg.to_reduce_l].p);
5036    int ecart;
[db83bf]5037    if(erg.fromS)
[410ea0f]5038    {
5039      ecart = c->strat->ecartS[erg.reduce_by];
5040    }
5041    else
5042    {
5043      ecart = c->pTotaldegree_full (red) - lm_deg;
5044    }
5045    reducer_deg = lm_deg + ecart;
[321283]5046  }
[410ea0f]5047  pointer = new simple_reducer (red, red_len, reducer_deg, c);
[4f858ce]5048
[db83bf]5049  if((!work_on_copy) && (!erg.fromS))
[410ea0f]5050    pointer->fill_back = r[rn].bucket;
[4f858ce]5051  else
[410ea0f]5052    pointer->fill_back = NULL;
5053  pointer->reduction_id = id;
5054  pointer->c = c;
[4f858ce]5055
[410ea0f]5056  pointer->reduce (r, erg.to_reduce_l, erg.to_reduce_u);
[db83bf]5057  if(work_on_copy)
[410ea0f]5058    pDelete (&pointer->p);
[4f858ce]5059  delete pointer;
[db83bf]5060  if(lt_changed)
[2fc974]5061  {
[410ea0f]5062    assume (!erg.fromS);
5063    r[erg.reduce_by].sev = sev;
[03f3269]5064  }
[2fc974]5065}
[31279e]5066
[db83bf]5067void simple_reducer::pre_reduce (red_object * r, int l, int u)
[410ea0f]5068{
5069}
Note: See TracBrowser for help on using the repository browser.