source: git/kernel/GBEngine/tgb.cc @ 4f8fd1d

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