source: git/kernel/tgb.cc @ 20e3062

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