Changeset 9fa5ff in git


Ignore:
Timestamp:
Apr 26, 2018, 5:16:38 PM (5 years ago)
Author:
Hans Schoenemann <hannes@…>
Branches:
(u'spielwiese', '8e0ad00ce244dfd0756200662572aef8402f13d5')
Children:
945000cb5ab9a7e19901cbd2d68659fde7c7b939
Parents:
cbd574852be7b5156dd605a13e277523b6c99045
Message:
removed more code from syzextra
Location:
Singular/dyn_modules/syzextra
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • Singular/dyn_modules/syzextra/mod_main.cc

    rcbd574 r9fa5ff  
    3636
    3737#include "Singular/mod_lib.h"
    38 
    39 
    40 #if GOOGLE_PROFILE_ENABLED
    41 #include <google/profiler.h>
    42 #endif // #if GOOGLE_PROFILE_ENABLED
    4338
    4439
     
    258253}
    259254
    260 // proc SchreyerSyzygyNF(vector syz_lead, vector syz_2, def L, def T, list #)
    261 static BOOLEAN _SchreyerSyzygyNF(leftv res, leftv h)
    262 {
    263   const SchreyerSyzygyComputationFlags attributes(currRingHdl);
    264 
    265 //   const BOOLEAN OPT__SYZCHECK   = attributes.OPT__SYZCHECK;
    266 //   const BOOLEAN OPT__LEAD2SYZ   = attributes.OPT__LEAD2SYZ;
    267   const BOOLEAN OPT__HYBRIDNF   = attributes.OPT__HYBRIDNF;
    268   const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;
    269 
    270   const char* usage = "`SchreyerSyzygyNF(<vector>, <vector>, <ideal/module>, <ideal/module>[,<module>])` expected";
    271   const ring r = attributes.m_rBaseRing;
    272 
    273   NoReturn(res);
    274 
    275   assume( OPT__HYBRIDNF ); // ???
    276 
    277   if ((h==NULL) || (h->Typ() != VECTOR_CMD) || (h->Data() == NULL))
    278   {
    279     WerrorS(usage);
    280     return TRUE;
    281   }
    282 
    283   const poly syz_lead = (poly) h->Data(); assume (syz_lead != NULL);
    284 
    285 
    286   h = h->Next();
    287   if ((h==NULL) || (h->Typ() != VECTOR_CMD) || (h->Data() == NULL))
    288   {
    289     WerrorS(usage);
    290     return TRUE;
    291   }
    292 
    293   const poly syz_2 = (poly) h->Data(); assume (syz_2 != NULL);
    294 
    295   h = h->Next();
    296   if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
    297   {
    298     WerrorS(usage);
    299     return TRUE;
    300   }
    301 
    302   const ideal L = (ideal) h->Data(); assume( IDELEMS(L) > 0 );
    303 
    304 
    305   h = h->Next();
    306   if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
    307   {
    308     WerrorS(usage);
    309     return TRUE;
    310   }
    311 
    312   const ideal T = (ideal) h->Data();
    313 
    314   assume( IDELEMS(L) == IDELEMS(T) );
    315 
    316   ideal LS = NULL;
    317 
    318   h = h->Next();
    319   if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))
    320   {
    321     LS = (ideal)h->Data();
    322     h = h->Next();
    323   }
    324 
    325 #ifndef SING_NDEBUG
    326   if( LIKELY( OPT__TAILREDSYZ) )
    327     assume (LS != NULL);
    328 #endif
    329 
    330   assume( h == NULL );
    331 
    332   res->rtyp = VECTOR_CMD;
    333   res->data = SchreyerSyzygyNF(syz_lead,
    334                                (syz_2!=NULL)? p_Copy(syz_2, r): syz_2, L, T, LS, attributes);
    335 
    336   return FALSE;
    337 }
    338 
    339 
    340 
    341 /// proc SSReduceTerm(poly m, def t, def syzterm, def L, def T, list #)
    342 static BOOLEAN _ReduceTerm(leftv res, leftv h)
    343 {
    344   const SchreyerSyzygyComputationFlags attributes(currRingHdl);
    345 
    346 //  const BOOLEAN OPT__SYZCHECK   = attributes.OPT__SYZCHECK;
    347 //   const BOOLEAN OPT__LEAD2SYZ   = attributes.OPT__LEAD2SYZ;
    348 //   const BOOLEAN OPT__HYBRIDNF   = attributes.OPT__HYBRIDNF;
    349   const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;
    350 
    351   const char* usage = "`ReduceTerm(<poly>, <poly/vector>, <vector/0>, <ideal/module>, <ideal/module>[,<module>])` expected";
    352   const ring r = attributes.m_rBaseRing;
    353 
    354   NoReturn(res);
    355 
    356   if ((h==NULL) || (h->Typ() !=POLY_CMD) || (h->Data() == NULL))
    357   {
    358     WerrorS(usage);
    359     return TRUE;
    360   }
    361 
    362   const poly multiplier = (poly) h->Data(); assume (multiplier != NULL);
    363 
    364 
    365   h = h->Next();
    366   if ((h==NULL) || (h->Typ()!=VECTOR_CMD && h->Typ() !=POLY_CMD) || (h->Data() == NULL))
    367   {
    368     WerrorS(usage);
    369     return TRUE;
    370   }
    371 
    372   const poly term4reduction = (poly) h->Data(); assume( term4reduction != NULL );
    373 
    374 
    375   poly syztermCheck = NULL;
    376 
    377   h = h->Next();
    378   if ((h==NULL) || !((h->Typ()==VECTOR_CMD) || (h->Data() == NULL)) )
    379   {
    380     WerrorS(usage);
    381     return TRUE;
    382   }
    383 
    384   if(h->Typ()==VECTOR_CMD)
    385     syztermCheck = (poly) h->Data();
    386 
    387 
    388   h = h->Next();
    389   if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
    390   {
    391     WerrorS(usage);
    392     return TRUE;
    393   }
    394 
    395   const ideal L = (ideal) h->Data(); assume( IDELEMS(L) > 0 );
    396 
    397 
    398   h = h->Next();
    399   if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
    400   {
    401     WerrorS(usage);
    402     return TRUE;
    403   }
    404 
    405   const ideal T = (ideal) h->Data();
    406 
    407   assume( IDELEMS(L) == IDELEMS(T) );
    408 
    409   ideal LS = NULL;
    410 
    411   h = h->Next();
    412   if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))
    413   {
    414     LS = (ideal)h->Data();
    415     h = h->Next();
    416   }
    417 
    418 #ifndef SING_NDEBUG
    419   if( LIKELY( OPT__TAILREDSYZ) )
    420     assume (LS != NULL);
    421 #endif
    422 
    423   assume( h == NULL );
    424 
    425   res->rtyp = VECTOR_CMD;
    426   res->data = ReduceTerm(multiplier, term4reduction, syztermCheck, L, T, LS, attributes);
    427 
    428   return FALSE;
    429 }
    430 
    431 
    432 
    433 
    434 // proc SSTraverseTail(poly m, def @tail, def L, def T, list #)
    435 static BOOLEAN _TraverseTail(leftv res, leftv h)
    436 {
    437   const SchreyerSyzygyComputationFlags attributes(currRingHdl);
    438 
    439 //   const BOOLEAN OPT__SYZCHECK   = attributes.OPT__SYZCHECK;
    440 //   const BOOLEAN OPT__LEAD2SYZ   = attributes.OPT__LEAD2SYZ;
    441 //   const BOOLEAN OPT__HYBRIDNF   = attributes.OPT__HYBRIDNF;
    442   const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;
    443 
    444   const char* usage = "`TraverseTail(<poly>, <poly/vector>, <ideal/module>, <ideal/module>[,<module>])` expected";
    445   const ring r = attributes.m_rBaseRing;
    446 
    447   NoReturn(res);
    448 
    449   if ((h==NULL) || (h->Typ() !=POLY_CMD) || (h->Data() == NULL))
    450   {
    451     WerrorS(usage);
    452     return TRUE;
    453   }
    454 
    455   const poly multiplier = (poly) h->Data(); assume (multiplier != NULL);
    456 
    457   h = h->Next();
    458   if ((h==NULL) || (h->Typ()!=VECTOR_CMD && h->Typ() !=POLY_CMD))
    459   {
    460     WerrorS(usage);
    461     return TRUE;
    462   }
    463 
    464   const poly tail = (poly) h->Data();
    465 
    466   h = h->Next();
    467 
    468   if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
    469   {
    470     WerrorS(usage);
    471     return TRUE;
    472   }
    473 
    474   const ideal L = (ideal) h->Data();
    475 
    476   assume( IDELEMS(L) > 0 );
    477 
    478   h = h->Next();
    479   if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
    480   {
    481     WerrorS(usage);
    482     return TRUE;
    483   }
    484 
    485   const ideal T = (ideal) h->Data();
    486 
    487   assume( IDELEMS(L) == IDELEMS(T) );
    488 
    489   h = h->Next();
    490 
    491   ideal LS = NULL;
    492 
    493   if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))
    494   {
    495     LS = (ideal)h->Data();
    496     h = h->Next();
    497   }
    498 
    499 #ifndef SING_NDEBUG
    500   if( LIKELY( OPT__TAILREDSYZ) )
    501     assume (LS != NULL);
    502 #endif
    503 
    504   assume( h == NULL );
    505 
    506   res->rtyp = VECTOR_CMD;
    507   res->data = TraverseTail(multiplier, tail, L, T, LS, attributes);
    508 
    509   return FALSE;
    510 }
    511 
    512 
    513 static BOOLEAN _ComputeResolution(leftv res, leftv h)
    514 {
    515   const SchreyerSyzygyComputationFlags attributes(currRingHdl);
    516 
    517   const char* usage = "`ComputeResolution(<ideal/module>, <same as before>, <same as before>[,int])` expected";
    518   const ring r = attributes.m_rBaseRing;
    519 
    520   NoReturn(res);
    521 
    522   // input
    523   if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
    524   {
    525     WerrorS(usage);
    526     return TRUE;
    527   }
    528 
    529   const int type = h->Typ();
    530   ideal M = (ideal)(h->CopyD()); // copy for resolution...!???
    531   int size = IDELEMS(M);
    532 
    533   assume( size >= 0 );
    534 
    535   h = h->Next();
    536 
    537   // lead
    538   if ((h==NULL) || (h->Typ()!=type) || (h->Data() == NULL))
    539   {
    540     WerrorS(usage);
    541     return TRUE;
    542   }
    543 
    544   ideal L = (ideal)(h->CopyD()); // no copy!
    545   assume( IDELEMS(L) == size );
    546 
    547   h = h->Next();
    548   if ((h==NULL) || (h->Typ()!=type) || (h->Data() == NULL))
    549   {
    550     WerrorS(usage);
    551     return TRUE;
    552   }
    553 
    554   ideal T = (ideal)(h->CopyD()); // no copy!
    555   assume( IDELEMS(T) == size );
    556 
    557   h = h->Next();
    558 
    559   // length..?
    560   long length = 0;
    561 
    562   if ((h!=NULL) && (h->Typ()==INT_CMD))
    563   {
    564     length = (long)(h->Data());
    565     h = h->Next();
    566   }
    567 
    568   assume( h == NULL );
    569 
    570   if( length <= 0 )
    571     length = 1 + rVar(r);
    572 
    573   syStrategy _res=(syStrategy)omAlloc0(sizeof(ssyStrategy));
    574 
    575 //  class ssyStrategy; typedef ssyStrategy * syStrategy;
    576 //  typedef ideal *            resolvente;
    577 
    578   _res->length = length + 1; // index + 1;
    579   _res->fullres = (resolvente)omAlloc0((_res->length+1)*sizeof(ideal));
    580   int index = 0;
    581   _res->fullres[index++] = M;
    582 
    583 //  if (UNLIKELY(attributes.OPT__TREEOUTPUT))
    584 //    Print("{ \"RESOLUTION: HYBRIDNF:%d, TAILREDSYZ: %d, LEAD2SYZ: %d, IGNORETAILS: %d\": [\n", attributes.OPT__HYBRIDNF, attributes.OPT__TAILREDSYZ, attributes.OPT__LEAD2SYZ, attributes.OPT__IGNORETAILS);
    585 
    586   while( (!idIs0(L)) && (index < length))
    587   {
    588     attributes.nextSyzygyLayer();
    589     ideal LL, TT;
    590 
    591     ComputeSyzygy(L, T, LL, TT, attributes);
    592 
    593     size = IDELEMS(LL);
    594 
    595     assume( size == IDELEMS(TT) );
    596 
    597     id_Delete(&L, r); id_Delete(&T, r);
    598 
    599     L = LL; T = TT;
    600 
    601     // id_Add(T, L, r);
    602     M = idInit(size, 0);
    603     for( int i = size-1; i >= 0; i-- )
    604     {
    605       M->m[i] = p_Add_q(p_Copy(T->m[i], r), p_Copy(L->m[i], r), r); // TODO: :(((
    606     }
    607     M->rank = id_RankFreeModule(M, r);
    608 
    609     _res->fullres[index++] = M; // ???
    610   }
    611 //  if ( UNLIKELY(attributes.OPT__TREEOUTPUT) )
    612 //    PrintS("] }\n");
    613 
    614   id_Delete(&L, r); id_Delete(&T, r);
    615 
    616   res->data = _res;
    617   res->rtyp = RESOLUTION_CMD;
    618 
    619 //  omFreeSize(_res, sizeof(ssyStrategy));
    620 
    621   return FALSE;
    622 
    623 }
    624 
    625 
    626 /// module (LL, TT) = SSComputeSyzygy(L, T);
    627 /// Compute Syz(L ++ T) = N = LL ++ TT
    628 // proc SSComputeSyzygy(def L, def T)
    629 static BOOLEAN _ComputeSyzygy(leftv res, leftv h)
    630 {
    631   const SchreyerSyzygyComputationFlags attributes(currRingHdl);
    632 
    633 //   const BOOLEAN OPT__SYZCHECK   = attributes.OPT__SYZCHECK;
    634 //   const BOOLEAN OPT__LEAD2SYZ   = attributes.OPT__LEAD2SYZ;
    635 //   const BOOLEAN OPT__HYBRIDNF   = attributes.OPT__HYBRIDNF;
    636 //   const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;
    637 
    638   const char* usage = "`ComputeSyzygy(<ideal/module>, <ideal/module>)` expected";
    639   const ring r = attributes.m_rBaseRing;
    640 
    641   NoReturn(res);
    642 
    643   if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
    644   {
    645     WerrorS(usage);
    646     return TRUE;
    647   }
    648 
    649   const ideal L = (ideal) h->Data();
    650 
    651   assume( IDELEMS(L) > 0 );
    652 
    653   h = h->Next();
    654   if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
    655   {
    656     WerrorS(usage);
    657     return TRUE;
    658   }
    659 
    660   const ideal T = (ideal) h->Data();
    661   assume( IDELEMS(L) == IDELEMS(T) );
    662 
    663 
    664   h = h->Next(); assume( h == NULL );
    665 
    666   ideal LL, TT;
    667 
    668   ComputeSyzygy(L, T, LL, TT, attributes);
    669 
    670   lists l = (lists)omAllocBin(slists_bin); l->Init(2);
    671 
    672   l->m[0].rtyp = MODUL_CMD; l->m[0].data = reinterpret_cast<void *>(LL);
    673 
    674   l->m[1].rtyp = MODUL_CMD; l->m[1].data = reinterpret_cast<void *>(TT);
    675 
    676   res->data = l; res->rtyp = LIST_CMD;
    677 
    678   return FALSE;
    679 
    680 }
    681 
    682255/// Get leading component
    683256static BOOLEAN leadcomp(leftv res, leftv h)
    684257{
    685   NoReturn(res);
    686 
    687258  if ((h!=NULL) && (h->Typ()==VECTOR_CMD || h->Typ()==POLY_CMD))
    688259  {
     
    701272
    702273      res->data = reinterpret_cast<void *>(jjLONG2N(iComp));
    703     } else
     274    }
     275    else
    704276      res->data = reinterpret_cast<void *>(jjLONG2N(0));
    705277
     
    716288static BOOLEAN MakeInducedSchreyerOrdering(leftv res, leftv h)
    717289{
    718 
    719   NoReturn(res);
    720 
    721290  int sign = 1;
    722291  if ((h!=NULL) && (h->Typ()==INT_CMD))
     
    744313static BOOLEAN GetInducedData(leftv res, leftv h)
    745314{
    746   NoReturn(res);
    747 
    748315  const ring r = currRing;
    749316
     
    802369static BOOLEAN SetInducedReferrence(leftv res, leftv h)
    803370{
     371  res->Init();
    804372  NoReturn(res);
    805373
     
    839407    return TRUE;
    840408  }
    841 
    842 
    843409
    844410  // F & componentWeights belong to that ordering block of currRing now:
     
    947513
    948514
    949 // #define ADD(A,B,C,D,E) ADD0(iiAddCproc, "", C, D, E)
    950 
    951 //#define ADD0(A,B,C,D,E) A(B, (char*)C, D, E)
    952 // #define ADD(A,B,C,D,E) ADD0(A->iiAddCproc, B, C, D, E)
    953515  ADD("ClearContent", FALSE, _ClearContent);
    954516  ADD("ClearDenominators", FALSE, _ClearDenominators);
     
    964526  ADD("Tail", FALSE, Tail);
    965527
    966   ADD("ReduceTerm", FALSE, _ReduceTerm);
    967   ADD("TraverseTail", FALSE, _TraverseTail);
    968 
    969 
    970   ADD("SchreyerSyzygyNF", FALSE, _SchreyerSyzygyNF);
    971   ADD("ComputeSyzygy", FALSE, _ComputeSyzygy);
    972 
    973   ADD("ComputeResolution", FALSE, _ComputeResolution);
    974 
    975   //  ADD("", FALSE, );
    976 
    977528#undef ADD
    978529  return MAX_TOK;
  • Singular/dyn_modules/syzextra/syzextra.cc

    rcbd574 r9fa5ff  
    2727
    2828#include "misc/intvec.h"
    29 #include "misc/options.h"
    3029
    3130#include "coeffs/coeffs.h"
     
    3534#include "polys/simpleideals.h"
    3635
    37 #include "polys/kbuckets.h" // for kBucket*
    38 #include "polys/sbuckets.h" // for sBucket*
    39 //#include "polys/nc/summator.h" // for CPolynomialSummator
    40 #include "polys/operations/p_Mult_q.h" // for MIN_LENGTH_BUCKET
    41 
    42 #include "kernel/GBEngine/kstd1.h"
    4336#include "kernel/polys.h"
    44 #include "kernel/GBEngine/syz.h"
    4537#include "kernel/ideals.h"
    46 
    47 #include "kernel/oswrapper/timer.h"
    48 
    49 #include "Singular/tok.h"
    50 #include "Singular/ipid.h"
    51 #include "Singular/lists.h"
    52 #include "Singular/attrib.h"
    53 
    54 #include "Singular/ipid.h"
    55 #include "Singular/ipshell.h" // For iiAddCproc
    5638
    5739#include <stdio.h>
    5840#include <stdlib.h>
    59 
    60 #ifndef RTIMER_BENCHMARKING
    61 # define RTIMER_BENCHMARKING 0
    62 #endif
    63 
    64 SBucketFactory::Bucket SBucketFactory::_CreateBucket(const ring r)
    65 {
    66   const Bucket bt = sBucketCreate(r);
    67 
    68   assume( bt != NULL );
    69   return bt;
    70 }
    71 
    72 void SBucketFactory::_DestroyBucket(SBucketFactory::Bucket & bt)
    73 {
    74   if( bt != NULL )
    75   {
    76     sBucketDestroy( &bt );
    77     bt = NULL;
    78   }
    79 }
    80 
    81 class SBucketWrapper
    82 {
    83   typedef SBucketFactory::Bucket Bucket;
    84 
    85   private:
    86     Bucket m_bucket;
    87 
    88     SBucketFactory& m_factory;
    89   public:
    90     SBucketWrapper(const ring r, SBucketFactory& factory):
    91         m_bucket( factory.getBucket(r) ),
    92         m_factory( factory )
    93     {}
    94 
    95     ~SBucketWrapper()
    96     {
    97       m_factory.putBucket( m_bucket );
    98     }
    99 
    100   public:
    101 
    102     /// adds p to the internal bucket
    103     /// destroys p, l == length(p)
    104     inline void Add( poly p, const int l )
    105     {
    106       assume( pLength(p) == l );
    107       sBucket_Add_p( m_bucket, p, l );
    108     }
    109 
    110     /// adds p to the internal bucket
    111     /// destroys p
    112     inline void Add( poly p ){ Add(p, pLength(p)); }
    113 
    114     poly ClearAdd()
    115     {
    116       poly p; int l;
    117       sBucketClearAdd(m_bucket, &p, &l);
    118       assume( pLength(p) == l );
    119       return p;
    120     }
    121 };
    122 
    123 static FORCE_INLINE poly pp_Add_qq( const poly a, const poly b, const ring R)
    124 {
    125   return p_Add_q( p_Copy(a, R), p_Copy(b, R), R );
    126 }
    127 
    128 static FORCE_INLINE poly p_VectorProductLT( poly s,  const ideal& L, const ideal& T, const ring& R)
    129 {
    130   assume( IDELEMS(L) == IDELEMS(T) );
    131   poly vp = NULL; // resulting vector product
    132 
    133   while( s != NULL )
    134   {
    135     const poly nxt = pNext(s);
    136     pNext(s) = NULL;
    137 
    138     if( !n_IsZero( pGetCoeff(s), R->cf) )
    139     {
    140       const int i = p_GetComp(s, R) - 1;
    141       assume( i >= 0 ); assume( i < IDELEMS(L) );
    142       p_SetComp(s, 0, R); p_SetmComp(s, R);
    143 
    144       vp = p_Add_q( vp, pp_Mult_qq( s, L->m[i], R ), R);
    145       vp = p_Add_q( vp, pp_Mult_qq( s, T->m[i], R ), R);
    146     }
    147 
    148     p_Delete(&s, R);
    149 
    150     s = nxt;
    151   };
    152 
    153   assume( s == NULL );
    154 
    155   return vp;
    156 }
    157 
    158 static FORCE_INLINE int atGetInt(idhdl rootRingHdl, const char* attribute, long def)
    159 {
    160   return ((int)(long)(atGet(rootRingHdl, attribute, INT_CMD, (void*)def)));
    161 }
    162 
    163 #if (defined(HAVE_QSORT_R) && (defined __APPLE__ || defined __MACH__ || defined __DARWIN__ || defined __FreeBSD__ || defined __BSD__ || defined OpenBSD3_1 || defined OpenBSD3_9))
    164 static int cmp_c_ds(void *R, const void *p1, const void *p2){
    165 #elif (defined(HAVE_QSORT_R) && (defined _GNU_SOURCE || defined __GNU__ || defined __linux__))
    166 static int cmp_c_ds(const void *p1, const void *p2, void *R){
    167 #else
    168 static int cmp_c_ds(const void *p1, const void *p2){ void *R = currRing;
    169 #endif
    170   assume(R != NULL);
    171   const int YES = 1;
    172   const int NO = -1;
    173 
    174   const ring r =  (const ring) R; // TODO/NOTE: the structure is known: C, lp!!!
    175 
    176   assume( r == currRing ); // for now...
    177 
    178   const poly a = *(const poly*)p1;
    179   const poly b = *(const poly*)p2;
    180 
    181   assume( a != NULL );
    182   assume( b != NULL );
    183 
    184   p_LmTest(a, r);
    185   p_LmTest(b, r);
    186 
    187 
    188   const signed long iCompDiff = p_GetComp(a, r) - p_GetComp(b, r);
    189 
    190   // TODO: test this!!!!!!!!!!!!!!!!
    191 
    192   //return -( compare (c, qsorts) )
    193 
    194   if( iCompDiff > 0 )
    195     return YES;
    196 
    197   if( iCompDiff < 0 )
    198     return  NO;
    199 
    200   assume( iCompDiff == 0 );
    201 
    202   const signed long iDegDiff = p_Totaldegree(a, r) - p_Totaldegree(b, r);
    203 
    204   if( iDegDiff > 0 )
    205     return YES;
    206 
    207   if( iDegDiff < 0 )
    208     return  NO;
    209 
    210   assume( iDegDiff == 0 );
    211 
    212   for (int v = rVar(r); v > 0; v--)
    213   {
    214     assume( v > 0 );
    215     assume( v <= rVar(r) );
    216 
    217     const signed int d = p_GetExp(a, v, r) - p_GetExp(b, v, r);
    218 
    219     if( d > 0 )
    220       return YES;
    221 
    222     if( d < 0 )
    223       return NO;
    224 
    225     assume( d == 0 );
    226   }
    227 
    228   return 0;
    229 }
    230 
    231 /*
    232 static int cmp_poly(const poly &a, const poly &b)
    233 {
    234   const int YES = 1;
    235   const int NO = -1;
    236 
    237   const ring r =  (const ring) currRing; // TODO/NOTE: the structure is known: C, lp!!!
    238 
    239   assume( r == currRing );
    240 
    241   assume( a != NULL );
    242   assume( b != NULL );
    243 
    244   p_LmTest(a, r);
    245   p_LmTest(b, r);
    246   assume( p_GetComp(a, r) == 0 );
    247   assume( p_GetComp(b, r) == 0 );
    248 
    249   for (int v = rVar(r); v > 0; v--)
    250   {
    251     assume( v > 0 );
    252     assume( v <= rVar(r) );
    253 
    254     const signed int d = p_GetExp(a, v, r) - p_GetExp(b, v, r);
    255 
    256     if( d > 0 )
    257       return YES;
    258 
    259     if( d < 0 )
    260       return NO;
    261 
    262     assume( d == 0 );
    263   }
    264 
    265   return 0;
    266 }
    267 */
    268 
    269 /* namespace SORT_c_ds */
    270 
    271 static FORCE_INLINE poly myp_Head(const poly p, const bool bIgnoreCoeff, const ring r)
    272 {
    273   assume( p != NULL ); p_LmCheckPolyRing1(p, r);
    274 
    275   poly np; omTypeAllocBin(poly, np, r->PolyBin);
    276   p_SetRingOfLm(np, r);
    277   memcpy(np->exp, p->exp, r->ExpL_Size*sizeof(long));
    278   pNext(np) = NULL;
    279   pSetCoeff0(np, (bIgnoreCoeff)? NULL : n_Copy(pGetCoeff(p), r->cf));
    280 
    281   p_LmCheckPolyRing1(np, r);
    282   return np;
    283 }
    284 
    285 
    286 /// return a new term: leading coeff * leading monomial of p
    287 /// with 0 leading component!
    288 poly leadmonom(const poly p, const ring r, const bool bSetZeroComp)
    289 {
    290   if( UNLIKELY(p == NULL ) )
    291      return NULL;
    292 
    293     assume( p != NULL );
    294     p_LmTest(p, r);
    295 
    296     poly m = p_LmInit(p, r);
    297     p_SetCoeff0(m, n_Copy(pGetCoeff(p), r->cf), r);
    298 
    299     if( bSetZeroComp )
    300       p_SetComp(m, 0, r);
    301 
    302     p_Setm(m, r);
    303 
    304     assume( m != NULL );
    305     assume( pNext(m) == NULL );
    306     p_LmTest(m, r);
    307 
    308     if( bSetZeroComp )
    309       assume( p_GetComp(m, r) == 0 );
    310 
    311   return m;
    312 }
    313 
    314 
    31541
    31642poly p_Tail(const poly p, const ring r)
     
    32147    return p_Copy( pNext(p), r );
    32248}
    323 
    32449
    32550ideal id_Tail(const ideal id, const ring r)
     
    33863}
    33964
    340 
    341 
    342 void Sort_c_ds(const ideal id, const ring r)
    343 {
    344   const int sizeNew = IDELEMS(id);
    345 
    346 #if ( (defined(HAVE_QSORT_R)) && (defined __APPLE__ || defined __MACH__ || defined __DARWIN__ || defined __FreeBSD__ || defined __BSD__ || defined OpenBSD3_1 || defined OpenBSD3_9) )
    347 #define qsort_my(m, s, ss, r, cmp) qsort_r(m, s, ss, r, cmp)
    348 #elif ( (defined(HAVE_QSORT_R)) && (defined _GNU_SOURCE || defined __GNU__ || defined __linux__))
    349 #define qsort_my(m, s, ss, r, cmp) qsort_r(m, s, ss, cmp, r)
    350 #else
    351 #define qsort_my(m, s, ss, r, cmp) qsort(m, s, ss, cmp)
    352 #endif
    353 
    354   if( sizeNew >= 2 )
    355     qsort_my(id->m, sizeNew, sizeof(poly), r, FROM_NAMESPACE(SORT_c_ds, cmp_c_ds));
    356 
    357 #undef qsort_my
    358 
    359   id->rank = id_RankFreeModule(id, r);
    360 }
    361 
    362 /// Clean up all the accumulated data
    363 void SchreyerSyzygyComputation::CleanUp()
    364 {
    365   id_Delete(const_cast<ideal*>(&m_idTails), m_rBaseRing); // TODO!!!
    366 
    367 /*if( m_sum_bucket != NULL )
    368   {
    369     assume ( sIsEmpty(m_sum_bucket) );
    370     sBucketDestroy(&m_sum_bucket);
    371     m_sum_bucket = NULL;
    372   }*/
    373 
    374   if( m_spoly_bucket != NULL )
    375   {
    376     kBucketDestroy(&m_spoly_bucket);
    377     m_spoly_bucket = NULL;
    378   }
    379 
    380   for( TCache::iterator it = m_cache.begin(); it != m_cache.end(); it++ )
    381   {
    382     TP2PCache& T = it->second;
    383 
    384     for(TP2PCache::iterator vit = T.begin(); vit != T.end(); vit++ )
    385     {
    386       p_Delete( (&(vit->second)), m_rBaseRing);
    387       p_Delete( const_cast<poly*>(&(vit->first)), m_rBaseRing);
    388     }
    389   }
    390 }
    391   /*
    392   for( TTailTerms::const_iterator it = m_idTailTerms.begin(); it != m_idTailTerms.end(); it++ )
    393   {
    394     const TTail& v = *it;
    395     for(TTail::const_iterator vit = v.begin(); vit != v.end(); vit++ )
    396       delete const_cast<CTailTerm*>(*vit);
    397   }
    398   */
    399 
    400 
    401 
    402 int CReducerFinder::PreProcessTerm(const poly t, CReducerFinder& syzChecker) const
    403 {
    404   assume( t != NULL );
    405 
    406   const ring r = m_rBaseRing;
    407 
    408 
    409   if( LIKELY(OPT__TAILREDSYZ) )
    410     if( p_LmIsConstant(t, r) ) // most basic case of baing coprime with L, whatever that is...
    411       return 1; // TODO: prove this...?
    412 
    413   //   return false; // appears to be fine
    414 
    415   const long comp = p_GetComp(t, r);
    416 
    417   CReducersHash::const_iterator itr = m_hash.find(comp);
    418 
    419   if ( itr == m_hash.end() )
    420     return 2; // no such leading component!!!
    421 
    422   assume( itr->first == comp );
    423 
    424   const bool bIdealCase = (comp == 0);
    425   const bool bSyzCheck = syzChecker.IsNonempty(); // need to check even in ideal case????? proof?  "&& !bIdealCase"
    426 
    427   if( LIKELY(OPT__TAILREDSYZ && (bIdealCase || bSyzCheck)) )
    428   {
    429     const TReducers& v = itr->second;
    430     const int N = rVar(r);
    431     // TODO: extract exps of t beforehand?!
    432     bool coprime = true;
    433     for(TReducers::const_iterator vit = v.begin(); (vit != v.end()) && coprime; ++vit )
    434     {
    435       assume( (*vit)->CheckLT( m_L ) );
    436 
    437       const poly p = (*vit)->lt();
    438 
    439       assume( p_GetComp(p, r) == comp );
    440 
    441       // TODO: check if coprime with Leads... if OPT__TAILREDSYZ !
    442       for( int var = N; var > 0; --var )
    443         if( (p_GetExp(p, var, r) != 0) && (p_GetExp(t, var, r) != 0) )
    444         {
    445           coprime = false; // t not coprime with p!
    446           break;
    447         }
    448 
    449       if( bSyzCheck && coprime )
    450       {
    451         poly ss = p_LmInit(t, r);
    452         p_SetCoeff0(ss, n_Init(1, r->cf), r); // for delete & printout only!...
    453         p_SetComp(ss, (*vit)->label() + 1, r); // coeff?
    454         p_Setm(ss, r);
    455 
    456         coprime = ( syzChecker.IsDivisible(ss) );
    457 
    458         p_LmDelete(&ss, r); // deletes coeff as well???
    459       }
    460 
    461       assume( p == (*vit)->lt() );
    462       assume( (*vit)->CheckLT( m_L ) );
    463     }
    464 
    465     return coprime? 3: 0; // t was coprime with all of leading terms!!!
    466 
    467   }
    468   //   return true; // delete the term
    469 
    470   return 0;
    471 }
    472 
    473 
    474 void SchreyerSyzygyComputation::SetUpTailTerms()
    475 {
    476   const ideal idTails = m_idTails;
    477   assume( idTails != NULL );
    478   assume( idTails->m != NULL );
    479   const ring r = m_rBaseRing;
    480 
    481   unsigned long pp[4] = {0,0,0,0}; // count preprocessed terms...
    482 
    483   for( int p = IDELEMS(idTails) - 1; p >= 0; --p )
    484     for( poly* tt = &(idTails->m[p]); (*tt) != NULL;  )
    485     {
    486       const poly t = *tt;
    487       const int k = m_div.PreProcessTerm(t, m_checker); // 0..3
    488       assume( 0 <= k && k <= 3 );
    489 
    490       pp[k]++; // collect stats
    491 
    492       if( k )
    493       {
    494         (*tt) = p_LmDeleteAndNext(t, r); // delete the lead and next...
    495       }
    496       else
    497         tt = &pNext(t); // go next?
    498 
    499     }
    500 
    501   if( UNLIKELY(OPT__PROT) )
    502   {
    503     Print("(PP/ST: {c: %lu, C: %lu, P: %lu} + %lu)", pp[1], pp[2], pp[3], pp[0]);
    504     m_stat[0] += pp [0]; m_stat[1] += pp [1]; m_stat[2] += pp [2]; m_stat[3] += pp [3];
    505   }
    506 }
    507 
    508 /*
    509   m_idTailTerms.resize( IDELEMS(idTails) );
    510 
    511   for( unsigned int p = IDELEMS(idTails) - 1; p >= 0; p -- )
    512   {
    513     TTail& v = m_idTailTerms[p];
    514     poly t = idTails->m[p];
    515     v.resize( pLength(t) );
    516 
    517     unsigned int pp = 0;
    518 
    519     while( t != NULL )
    520     {
    521       assume( t != NULL );
    522       // TODO: compute L:t!
    523 //      ideal reducers;
    524 //      CReducerFinder m_reducers
    525 
    526       CTailTerm* d = v[pp] = new CTailTerm();
    527 
    528       ++pp; pIter(t);
    529     }
    530   }
    531 */
    532 
    533 void SchreyerSyzygyComputation::PrintStats() const
    534 {
    535   Print("SchreyerSyzygyComputation Stats: (PP/ST: {c: %lu, C: %lu, P: %lu} + %lu, LOT: %lu, LCM: %lu, ST:%lu, LK: %lu {*: %lu})\n",
    536         m_stat[1], m_stat[2], m_stat[3], m_stat[0],
    537         m_stat[4], m_stat[5],
    538         m_stat[8],
    539         m_stat[6] + m_stat[7], m_stat[7]
    540        );
    541 }
    542 
    543 
    544 ideal SchreyerSyzygyComputation::Compute1LeadingSyzygyTerms()
    545 {
    546   const ideal& id = m_idLeads;
    547   const ring& r = m_rBaseRing;
    548 //  const SchreyerSyzygyComputationFlags& attributes = m_atttributes;
    549 
    550   assume(!OPT__LEAD2SYZ);
    551 
    552   // 1. set of components S?
    553   // 2. for each component c from S: set of indices of leading terms
    554   // with this component?
    555   // 3. short exp. vectors for each leading term?
    556 
    557   const int size = IDELEMS(id);
    558 
    559   if( size < 2 )
    560   {
    561     const ideal newid = idInit(1, 0); newid->m[0] = NULL; // zero ideal...
    562     return newid;
    563   }
    564 
    565   // TODO/NOTE: input is supposed to be (reverse-) sorted wrt "(c,ds)"!??
    566 
    567   // components should come in groups: count elements in each group
    568   // && estimate the real size!!!
    569 
    570 
    571   // use just a vector instead???
    572   const ideal newid = idInit( (size * (size-1))/2, size); // maximal size: ideal case!
    573 
    574   int k = 0;
    575 
    576   for (int j = 0; j < size; j++)
    577   {
    578     const poly p = id->m[j];
    579     assume( p != NULL );
    580     const int  c = p_GetComp(p, r);
    581 
    582     for (int i = j - 1; i >= 0; i--)
    583     {
    584       const poly pp = id->m[i];
    585       assume( pp != NULL );
    586       const int  cc = p_GetComp(pp, r);
    587 
    588       if( c != cc )
    589         continue;
    590 
    591       const poly m = p_Init(r); // p_New???
    592 
    593       // m = LCM(p, pp) / p! // TODO: optimize: knowing the ring structure: (C/lp)!
    594       for (int v = rVar(r); v > 0; v--)
    595       {
    596         assume( v > 0 );
    597         assume( v <= rVar(r) );
    598 
    599         const short e1 = p_GetExp(p , v, r);
    600         const short e2 = p_GetExp(pp, v, r);
    601 
    602         if( e1 >= e2 )
    603           p_SetExp(m, v, 0, r);
    604         else
    605           p_SetExp(m, v, e2 - e1, r);
    606 
    607       }
    608 
    609       assume( (j > i) && (i >= 0) );
    610 
    611       p_SetComp(m, j + 1, r);
    612       pNext(m) = NULL;
    613       p_SetCoeff0(m, n_Init(1, r->cf), r); // for later...
    614 
    615       p_Setm(m, r); // should not do anything!!!
    616 
    617       newid->m[k++] = m;
    618     }
    619   }
    620 
    621   // the rest of newid is assumed to be zeroes...
    622 
    623   // simplify(newid, 2 + 32)??
    624   // sort(newid, "C,ds")[1]???
    625   id_DelDiv(newid, r); // #define SIMPL_LMDIV 32
    626 
    627   idSkipZeroes(newid); // #define SIMPL_NULL 2
    628 
    629   Sort_c_ds(newid, r);
    630 
    631   return newid;
    632 }
    633 
    634 ideal SchreyerSyzygyComputation::Compute2LeadingSyzygyTerms()
    635 {
    636   const ideal& id = m_idLeads;
    637   const ring& r = m_rBaseRing;
    638 //  const SchreyerSyzygyComputationFlags& attributes = m_atttributes;
    639 
    640   // 1. set of components S?
    641   // 2. for each component c from S: set of indices of leading terms
    642   // with this component?
    643   // 3. short exp. vectors for each leading term?
    644 
    645   const int size = IDELEMS(id);
    646 
    647   if( size < 2 )
    648   {
    649     const ideal newid = idInit(1, 1); newid->m[0] = NULL; // zero module...
    650     return newid;
    651   }
    652 
    653 
    654   // TODO/NOTE: input is supposed to be sorted wrt "C,ds"!??
    655 
    656   // components should come in groups: count elements in each group
    657   // && estimate the real size!!!
    658 
    659 
    660   // use just a vector instead???
    661   ideal newid = idInit( (size * (size-1))/2, size); // maximal size: ideal case!
    662 
    663   int k = 0;
    664 
    665   for (int j = 0; j < size; j++)
    666   {
    667     const poly p = id->m[j];
    668     assume( p != NULL );
    669     const int  c = p_GetComp(p, r);
    670 
    671     for (int i = j - 1; i >= 0; i--)
    672     {
    673       const poly pp = id->m[i];
    674       assume( pp != NULL );
    675       const int  cc = p_GetComp(pp, r);
    676 
    677       if( c != cc )
    678         continue;
    679 
    680         // allocate memory & zero it out!
    681       const poly m = p_Init(r); const poly mm = p_Init(r);
    682 
    683 
    684         // m = LCM(p, pp) / p! mm = LCM(p, pp) / pp!
    685         // TODO: optimize: knowing the ring structure: (C/lp)!
    686 
    687       for (int v = rVar(r); v > 0; v--)
    688       {
    689         assume( v > 0 );
    690         assume( v <= rVar(r) );
    691 
    692         const short e1 = p_GetExp(p , v, r);
    693         const short e2 = p_GetExp(pp, v, r);
    694 
    695         if( e1 >= e2 )
    696           p_SetExp(mm, v, e1 - e2, r); //            p_SetExp(m, v, 0, r);
    697         else
    698           p_SetExp(m, v, e2 - e1, r); //            p_SetExp(mm, v, 0, r);
    699 
    700       }
    701 
    702       assume( (j > i) && (i >= 0) );
    703 
    704       p_SetComp(m, j + 1, r);
    705       p_SetComp(mm, i + 1, r);
    706 
    707       const number& lc1 = p_GetCoeff(p , r);
    708       const number& lc2 = p_GetCoeff(pp, r);
    709 
    710 #if NODIVISION
    711       assume( n_IsOne(lc1, r->cf) );
    712       assume( n_IsOne(lc2, r->cf) );
    713 
    714       p_SetCoeff0( m, n_Init( 1, r->cf), r );
    715       p_SetCoeff0(mm, n_Init(-1, r->cf), r );
    716 #else
    717       number g = n_Lcm( lc1, lc2, r->cf );
    718       p_SetCoeff0(m ,       n_Div(g, lc1, r), r);
    719       p_SetCoeff0(mm, n_InpNeg(n_Div(g, lc2, r), r), r);
    720       n_Delete(&g, r);
    721 #endif
    722 
    723       p_Setm(m, r); // should not do anything!!!
    724       p_Setm(mm, r); // should not do anything!!!
    725 
    726       pNext(m) = mm; //        pNext(mm) = NULL;
    727 
    728       newid->m[k++] = m;
    729     }
    730   }
    731 
    732   if( UNLIKELY(!OPT__TAILREDSYZ) )
    733   {
    734       // simplify(newid, 2 + 32)??
    735       // sort(newid, "C,ds")[1]???
    736     id_DelDiv(newid, r); // #define SIMPL_LMDIV 32
    737   }
    738   else
    739   {
    740       //      option(redSB); option(redTail);
    741       //      TEST_OPT_REDSB
    742       //      TEST_OPT_REDTAIL
    743     assume( r == currRing );
    744 
    745     BITSET _save_test; SI_SAVE_OPT1(_save_test);
    746     SI_RESTORE_OPT1(Sy_bit(OPT_REDTAIL) | Sy_bit(OPT_REDSB) | _save_test);
    747 
    748     intvec* w=new intvec(IDELEMS(newid));
    749     ideal tmp = kStd(newid, currRing->qideal, isHomog, &w);
    750     delete w;
    751 
    752     SI_RESTORE_OPT1(_save_test)
    753 
    754     id_Delete(&newid, r);
    755     newid = tmp;
    756   }
    757 
    758   idSkipZeroes(newid);
    759 
    760   Sort_c_ds(newid, r);
    761 
    762   return newid;
    763 }
    764 
    765 poly SchreyerSyzygyComputation::TraverseNF(const poly a, const poly a2) const
    766 {
    767   const ideal& L = m_idLeads;
    768   const ideal& T = m_idTails;
    769 
    770   const ring& R = m_rBaseRing;
    771 
    772   const int r = p_GetComp(a, R) - 1;
    773 
    774   assume( r >= 0 && r < IDELEMS(T) );
    775   assume( r >= 0 && r < IDELEMS(L) );
    776 
    777   assume( a != NULL );
    778 
    779   poly aa = leadmonom(a, R); assume( aa != NULL); // :(
    780 
    781   poly t = TraverseTail(aa, r);
    782 
    783   if( a2 != NULL )
    784   {
    785     assume( OPT__LEAD2SYZ );
    786 
    787     // replace the following... ?
    788     const int r2 = p_GetComp(a2, R) - 1; poly aa2 = leadmonom(a2, R); // :(
    789 
    790     assume( r2 >= 0 && r2 < IDELEMS(T) );
    791 
    792     poly s =  TraverseTail(aa2, r2);
    793 
    794     p_Delete(&aa2, R);
    795 
    796     t = p_Add_q(a2, p_Add_q(t, s, R), R);
    797 
    798   } else
    799     t = p_Add_q(t, ReduceTerm(aa, L->m[r], a), R); // should be identical to bove with a2
    800 
    801   p_Delete(&aa, R);
    802 
    803   return t;
    804 }
    805 
    806 void SchreyerSyzygyComputation::ComputeSyzygy()
    807 {
    808   assume( m_idLeads != NULL );
    809   assume( m_idTails != NULL );
    810 
    811   const ideal& L = m_idLeads;
    812   const ideal& T = m_idTails;
    813 
    814   ideal& TT = m_syzTails;
    815   const ring& R = m_rBaseRing;
    816 
    817 //  if( m_sum_bucket == NULL )
    818 //    m_sum_bucket = sBucketCreate(R);
    819 //  assume ( sIsEmpty(m_sum_bucket) );
    820 
    821   if( m_spoly_bucket == NULL )
    822     m_spoly_bucket = kBucketCreate(R);
    823 
    824 
    825   assume( IDELEMS(L) == IDELEMS(T) );
    826 
    827 #ifdef SING_NDEBUG
    828   int t, r; // for rtimer benchmarking in prot realease mode
    829 #endif
    830 
    831   if( UNLIKELY(OPT__TREEOUTPUT) )
    832     Print("\n{ \"syzygylayer\": \"%d\", \"hybridnf\": \"%d\", \"diagrams\": \n[", OPT__SYZNUMBER, OPT__HYBRIDNF );
    833 
    834   if( UNLIKELY(OPT__PROT) ) Print("\n[%d]", OPT__SYZNUMBER );
    835 
    836   if( m_syzLeads == NULL )
    837   {
    838 #ifdef SING_NDEBUG
    839     if( UNLIKELY(OPT__PROT & RTIMER_BENCHMARKING) )
    840     {
    841       t = getTimer(); r = getRTimer();
    842       Print("\n%% %5d **!TIME4!** SchreyerSyzygyComputation::ComputeSyzygy::ComputeLeadingSyzygyTerms: t: %d, r: %d\n", r, t, r);
    843     }
    844 #endif
    845 
    846     ComputeLeadingSyzygyTerms( OPT__LEAD2SYZ && !OPT__IGNORETAILS ); // 2 terms OR 1 term!
    847 
    848 #ifdef SING_NDEBUG
    849     if( UNLIKELY(OPT__PROT & RTIMER_BENCHMARKING) )
    850     {
    851       t = getTimer() - t; r = getRTimer() - r;
    852       Print("\n%% %5d **!TIME4!** SchreyerSyzygyComputation::ComputeSyzygy::ComputeLeadingSyzygyTerms: dt: %d, dr: %d\n", getRTimer(), t, r);
    853     }
    854 #endif
    855 
    856   }
    857 
    858   assume( m_syzLeads != NULL );
    859   ideal& LL = m_syzLeads;
    860   const int size = IDELEMS(LL);
    861 
    862   TT = idInit(size, 0);
    863 
    864   if( size == 1 && LL->m[0] == NULL )
    865   {
    866      if( UNLIKELY(OPT__TREEOUTPUT) )
    867        PrintS("]},");
    868      return;
    869   }
    870 
    871 
    872   // use hybrid (Schreyer NF) method?
    873   const bool method = (OPT__HYBRIDNF  == 1); //  || (OPT__HYBRIDNF == 2 && OPT__SYZNUMBER < 3);
    874 
    875   if( UNLIKELY(OPT__PROT) ) Print("[%s NF|%s]",(method) ? "PR" : "TT", (NOPRODUCT == 1)? "_,_": "^*^" );
    876 
    877 
    878   if(  LIKELY(!OPT__IGNORETAILS) )
    879   {
    880     if( T != NULL )
    881     {
    882 #ifdef SING_NDEBUG
    883       if( UNLIKELY(OPT__PROT & RTIMER_BENCHMARKING) )
    884       {
    885         t = getTimer(); r = getRTimer();
    886         Print("\n%% %5d **!TIME4!** SchreyerSyzygyComputation::ComputeSyzygy::SetUpTailTerms(): t: %d, r: %d\n", r, t, r);
    887       }
    888 #endif
    889 
    890       SetUpTailTerms();
    891 
    892 #ifdef SING_NDEBUG
    893       if( UNLIKELY(OPT__PROT & RTIMER_BENCHMARKING) )
    894       {
    895         t = getTimer() - t; r = getRTimer() - r;
    896         Print("\n%% %5d **!TIME4!** SchreyerSyzygyComputation::ComputeSyzygy::SetUpTailTerms(): dt: %d, dr: %d\n", getRTimer(), t, r);
    897       }
    898 #endif
    899     }
    900   }
    901 
    902 #ifdef SING_NDEBUG
    903   if( UNLIKELY(OPT__PROT & RTIMER_BENCHMARKING) )
    904   {
    905     t = getTimer(); r = getRTimer();
    906     Print("\n%% %5d **!TIME4!** SchreyerSyzygyComputation::ComputeSyzygy::SyzygyLift: t: %d, r: %d\n", r, t, r);
    907   }
    908 #endif
    909 
    910 //  for( int k = 0; k < size; ++k ) // TODO: should be fine now!
    911   for( int k = size - 1; k >= 0; --k )
    912   {
    913     const poly a = LL->m[k]; assume( a != NULL );
    914 
    915     poly a2 = pNext(a);
    916 
    917     // Splitting 2-terms Leading syzygy module
    918     if( a2 != NULL )
    919       pNext(a) = NULL;
    920 
    921     if( UNLIKELY(OPT__IGNORETAILS) )
    922     {
    923       TT->m[k] = NULL;
    924 
    925       assume( a2 != NULL );
    926 
    927       if( a2 != NULL )
    928         p_Delete(&a2, R);
    929 
    930       continue;
    931     }
    932 
    933     //    TT->m[k] = a2;
    934 
    935     poly nf;
    936 
    937     if( method )
    938       nf = SchreyerSyzygyNF(a, a2);
    939     else
    940       nf = TraverseNF(a, a2);
    941 
    942     TT->m[k] = nf;
    943 
    944     if( UNLIKELY(OPT__SYZCHECK) )
    945     {
    946       // TODO: check the correctness (syzygy property): a + TT->m[k] should be a syzygy!!!
    947 
    948       poly s = pp_Add_qq( a, TT->m[k], R); // current syzygy
    949 
    950       poly vp = p_VectorProductLT(s, L, T, R);
    951 
    952       assume( vp == NULL );
    953 
    954       if( UNLIKELY( OPT__PROT && (vp != NULL) ) ) Warn("ERROR: SyzCheck failed, wrong tail: [%d]\n\n", k); // check k'th syzygy failed
    955 
    956       p_Delete(&vp, R);
    957     }
    958   }
    959 
    960 #ifdef SING_NDEBUG
    961   if( UNLIKELY( OPT__PROT & RTIMER_BENCHMARKING ) )
    962   {
    963     t = getTimer() - t; r = getRTimer() - r;
    964     Print("\n%% %5d **!TIME4!** SchreyerSyzygyComputation::ComputeSyzygy::SyzygyLift: dt: %d, dr: %d\n", getRTimer(), t, r);
    965   }
    966 #endif
    967 
    968   TT->rank = id_RankFreeModule(TT, R);
    969 
    970   if( UNLIKELY(OPT__TREEOUTPUT) )
    971     PrintS("\n]},");
    972 
    973   if( UNLIKELY(OPT__PROT) ) PrintLn();
    974 }
    975 
    976 void SchreyerSyzygyComputation::ComputeLeadingSyzygyTerms(bool bComputeSecondTerms)
    977 {
    978 //  const SchreyerSyzygyComputationFlags& attributes = m_atttributes;
    979 
    980 //  const BOOLEAN OPT__LEAD2SYZ   = attributes.OPT__LEAD2SYZ;
    981 //  const BOOLEAN OPT__TAILREDSYZ = attributes.OPT__TAILREDSYZ;
    982 
    983   assume( m_syzLeads == NULL );
    984 
    985   if( UNLIKELY(bComputeSecondTerms) )
    986   {
    987     assume( OPT__LEAD2SYZ );
    988 //    m_syzLeads = FROM_NAMESPACE(INTERNAL, _Compute2LeadingSyzygyTerms(m_idLeads, m_rBaseRing, m_atttributes));
    989     m_syzLeads = Compute2LeadingSyzygyTerms();
    990   }
    991   else
    992   {
    993     assume( !OPT__LEAD2SYZ );
    994 
    995     m_syzLeads = Compute1LeadingSyzygyTerms();
    996   }
    997 //    m_syzLeads = FROM_NAMESPACE(INTERNAL, _ComputeLeadingSyzygyTerms(m_idLeads, m_rBaseRing, m_atttributes));
    998 
    999   // NOTE: set m_LS if tails are to be reduced!
    1000   assume( m_syzLeads!= NULL );
    1001 
    1002   if ( LIKELY( OPT__TAILREDSYZ && !OPT__IGNORETAILS && (IDELEMS(m_syzLeads) > 0) && !((IDELEMS(m_syzLeads) == 1) && (m_syzLeads->m[0] == NULL)) ) )
    1003   {
    1004     m_LS = m_syzLeads;
    1005     m_checker.Initialize(m_syzLeads);
    1006     assume( m_checker.IsNonempty() ); // TODO: this always fails... BUG????
    1007   }
    1008 
    1009   if( UNLIKELY( OPT__PROT ) ) Print("(L%dS:%d)", bComputeSecondTerms ? 2 : 1, IDELEMS(m_syzLeads));
    1010 
    1011 }
    1012 
    1013 poly SchreyerSyzygyComputation::SchreyerSyzygyNF(const poly syz_lead, poly syz_2) const
    1014 {
    1015   assume( !OPT__IGNORETAILS );
    1016 
    1017   const ideal& L = m_idLeads;
    1018   const ideal& T = m_idTails;
    1019   const ring& r = m_rBaseRing;
    1020 
    1021   assume( syz_lead != NULL );
    1022 
    1023   if( syz_2 == NULL )
    1024   {
    1025     const int rr = p_GetComp(syz_lead, r) - 1;
    1026 
    1027     assume( rr >= 0 && rr < IDELEMS(T) );
    1028     assume( rr >= 0 && rr < IDELEMS(L) );
    1029 
    1030 #if NOPRODUCT
    1031     syz_2 = m_div.FindReducer(syz_lead, L->m[rr], syz_lead, m_checker);
    1032     p_Test(syz_2, r);
    1033 
    1034 #else
    1035     poly aa = leadmonom(syz_lead, r); assume( aa != NULL); // :(
    1036     aa = p_Mult_mm(aa, L->m[rr], r);
    1037 
    1038     syz_2 = m_div.FindReducer(aa, syz_lead, m_checker);
    1039     p_Test(syz_2, r);
    1040 
    1041     p_Delete(&aa, r);
    1042 #endif
    1043 
    1044   }
    1045 
    1046   assume( syz_2 != NULL ); // by construction of S-Polynomial
    1047 
    1048   assume( L != NULL );
    1049   assume( T != NULL );
    1050 
    1051   assume( IDELEMS(L) == IDELEMS(T) );
    1052 
    1053   int  c = p_GetComp(syz_lead, r) - 1;
    1054 
    1055   assume( c >= 0 && c < IDELEMS(T) );
    1056 
    1057   if( m_spoly_bucket == NULL )
    1058     m_spoly_bucket = kBucketCreate(r);
    1059 
    1060   SBucketWrapper tail(r, m_sum_bucket_factory);
    1061 
    1062 
    1063   kBucket_pt bucket = m_spoly_bucket; assume( bucket != NULL ); kbTest(bucket); m_spoly_bucket = NULL;
    1064 
    1065 //  kBucketInit(bucket, NULL, 0); // not needed!?
    1066 
    1067   poly p = leadmonom(syz_lead, r); // :(
    1068 //  poly spoly = pp_Mult_qq(p, T->m[c], r);
    1069   kBucket_Plus_mm_Mult_pp(bucket, p, T->m[c], 0); // TODO: store pLength(T->m[c]) separately!?
    1070   p_Delete(&p, r);
    1071 
    1072   kbTest(bucket);
    1073 
    1074   c = p_GetComp(syz_2, r) - 1;
    1075   assume( c >= 0 && c < IDELEMS(T) );
    1076 
    1077   p = leadmonom(syz_2, r); // :(
    1078 //  spoly = p_Add_q(spoly, pp_Mult_qq(p, T->m[c], r), r);
    1079   kBucket_Plus_mm_Mult_pp(bucket, p, T->m[c], 0); // pLength(T->m[c])?!
    1080   kbTest(bucket);
    1081   p_Delete(&p, r);
    1082 
    1083 //  const bool bUsePolynomial = TEST_OPT_NOT_BUCKETS; //  || (pLength(spoly) < MIN_LENGTH_BUCKET);
    1084 //  CPolynomialSummator tail(r, bUsePolynomial);
    1085   tail.Add(syz_2, 1);
    1086 
    1087   kbTest(bucket);
    1088   for( poly spoly = kBucketExtractLm(bucket); spoly != NULL; p_LmDelete(&spoly, r), spoly = kBucketExtractLm(bucket))
    1089   {
    1090     kbTest(bucket);
    1091     poly t = m_div.FindReducer(spoly, NULL, m_checker);
    1092     p_Test(t, r);
    1093 
    1094     if( t != NULL )
    1095     {
    1096       p = leadmonom(t, r); // :(
    1097       c = p_GetComp(t, r) - 1;
    1098 
    1099       assume( c >= 0 && c < IDELEMS(T) );
    1100 
    1101       kBucket_Plus_mm_Mult_pp(bucket, p, T->m[c], 0); // pLength(T->m[c])?
    1102 //      spoly = p_Add_q(spoly, pp_Mult_qq(p, T->m[c], r), r);
    1103 
    1104       p_Delete(&p, r);
    1105 
    1106       tail.Add(t, 1);
    1107     } // otherwise discard that leading term altogether!
    1108     else
    1109       if( UNLIKELY(OPT__PROT) ) ++ m_stat[4]; // PrintS("$"); // LOT
    1110 
    1111     kbTest(bucket);
    1112   }
    1113 
    1114   kbTest(bucket);
    1115 
    1116   // now bucket must be empty!
    1117   assume( kBucketClear(bucket) == NULL );
    1118 
    1119   const poly result = tail.ClearAdd(); // TODO: use Merge with sBucket???
    1120 
    1121 
    1122   if( m_spoly_bucket == NULL )
    1123     m_spoly_bucket = bucket;
    1124   else
    1125     kBucketDestroy(&bucket);
    1126 
    1127 
    1128   if( UNLIKELY(OPT__TREEOUTPUT) )
    1129   {
    1130     PrintS("]},");
    1131   }
    1132   return result;
    1133 }
    1134 
    1135 // namespace     {
    1136 
    1137 // };
    1138 
    1139 
    1140 bool my_p_LmCmp (poly a, poly b, const ring r) { return p_LmCmp(a, b, r) == -1; } // TODO: change to simple lex. memory compare!
    1141 
    1142 // NOTE: need p_Copy?????? for image + multiplier!!???
    1143 // NOTE: better store complete syz. terms!!?
    1144 poly SchreyerSyzygyComputation::TraverseTail(poly multiplier, const int tail) const
    1145 {
    1146   const ring& r = m_rBaseRing;
    1147 
    1148   assume(m_idTails !=  NULL && m_idTails->m != NULL);
    1149   assume( tail >= 0 && tail < IDELEMS(m_idTails) );
    1150 
    1151   p_Test(multiplier, r);
    1152 
    1153   if( UNLIKELY(OPT__NOCACHING) )
    1154     return ComputeImage(multiplier, tail);
    1155 
    1156   // TODO: store (multiplier, tail) -.-^-.-^-.--> !
    1157   TCache::iterator top_itr = m_cache.find(tail);
    1158 
    1159   if ( top_itr != m_cache.end() )
    1160   {
    1161      assume( top_itr->first == tail );
    1162 
    1163      TP2PCache& T = top_itr->second;
    1164 
    1165      TP2PCache::iterator itr = T.find(multiplier);
    1166 
    1167      if( itr != T.end() ) // Yey - Reuse!!!
    1168      {
    1169        assume( p_LmEqual(itr->first, multiplier, r) );
    1170 
    1171        if( itr->second == NULL ) // leadcoeff plays no role if value is NULL!
    1172          return (NULL);
    1173 
    1174        poly p = p_Copy(itr->second, r); // COPY!!!
    1175 
    1176        p_Test(multiplier, r);
    1177 
    1178        if( !n_Equal( pGetCoeff(multiplier), pGetCoeff(itr->first), r->cf) ) // normalize coeffs!?
    1179        {
    1180          number n = n_Div( pGetCoeff(multiplier), pGetCoeff(itr->first), r->cf); // new number
    1181 
    1182          if( UNLIKELY( OPT__TREEOUTPUT ) )
    1183          {
    1184            StringSetS("");
    1185            n_Write(n, r->cf);
    1186            char* s = StringEndS();
    1187            Print("\"recale\": \"%s\", ", s);
    1188            omFree(s);
    1189          }
    1190 
    1191          if( UNLIKELY( OPT__PROT ) ) ++ m_stat[7]; // PrintS("l*"); // lookup & rescale
    1192 
    1193          p = p_Mult_nn(p, n, r); // !
    1194          n_Delete(&n, r->cf);
    1195        } else
    1196          if( UNLIKELY( OPT__PROT ) ) ++ m_stat[6]; // PrintS("l"); // lookup no rescale
    1197 
    1198        p_Test(multiplier, r);
    1199 
    1200        return p;
    1201      }
    1202 
    1203 
    1204      p_Test(multiplier, r);
    1205 
    1206      const poly p = ComputeImage(multiplier, tail);
    1207 
    1208      if( UNLIKELY(OPT__PROT) ) ++ m_stat[8]; // PrintS("S"); // store
    1209 
    1210      p_Test(multiplier, r);
    1211 
    1212      T.insert( TP2PCache::value_type(myp_Head(multiplier, (p==NULL), r), p) ); //     T[ multiplier ] = p;
    1213 
    1214      p_Test(multiplier, r);
    1215 
    1216 //     if( p == NULL )
    1217 //        return (NULL);
    1218 
    1219      return p_Copy(p, r);
    1220   }
    1221 
    1222   CCacheCompare o(r); TP2PCache T(o);
    1223 
    1224   const poly p = ComputeImage(multiplier, tail);
    1225 
    1226   if( UNLIKELY( OPT__PROT ) ) ++ m_stat[8]; // PrintS("S"); // store // %d", tail + 1);
    1227 
    1228   T.insert( TP2PCache::value_type(myp_Head(multiplier, (p==NULL), r), p) );
    1229 
    1230   m_cache.insert( TCache::value_type(tail, T) );
    1231 
    1232 //  if( p == NULL )
    1233 //    return (NULL);
    1234 
    1235   return p_Copy(p, r);
    1236 }
    1237 
    1238 poly SchreyerSyzygyComputation::ComputeImage(poly multiplier, const int tail) const
    1239 {
    1240   const ring& r = m_rBaseRing;
    1241 
    1242   assume(m_idTails !=  NULL && m_idTails->m != NULL);
    1243   assume( tail >= 0 && tail < IDELEMS(m_idTails) );
    1244 
    1245   p_Test(multiplier, r);
    1246 
    1247   const poly t = m_idTails->m[tail]; // !!!
    1248 
    1249   if(t != NULL)
    1250   {
    1251     const poly p = TraverseTail(multiplier, t);
    1252 
    1253     p_Test(multiplier, r);
    1254     return p;
    1255   }
    1256 
    1257   return NULL;
    1258 }
    1259 
    1260 
    1261 poly SchreyerSyzygyComputation::TraverseTail(poly multiplier, poly tail) const
    1262 {
    1263   assume( !OPT__IGNORETAILS );
    1264 
    1265   const ideal& L = m_idLeads;
    1266   const ideal& T = m_idTails;
    1267   const ring& r = m_rBaseRing;
    1268 
    1269   assume( multiplier != NULL );
    1270 
    1271   assume( L != NULL );
    1272   assume( T != NULL );
    1273 
    1274   p_Test(multiplier, r);
    1275 
    1276   if( UNLIKELY( !(  (!OPT__TAILREDSYZ)   ||   m_lcm.Check(multiplier)     )) )
    1277   {
    1278     if( UNLIKELY(OPT__TAILREDSYZ && OPT__PROT) )
    1279     {
    1280       ++ m_stat[5]; // PrintS("%"); // check LCM !
    1281     }
    1282     return NULL;
    1283   }
    1284 
    1285   //    const bool bUsePolynomial = TEST_OPT_NOT_BUCKETS; //  || (pLength(tail) < MIN_LENGTH_BUCKET);
    1286 
    1287   SBucketWrapper sum(r, m_sum_bucket_factory);
    1288 /*
    1289   sBucket_pt sum;
    1290 
    1291   if( m_sum_bucket == NULL )
    1292     sum = sBucketCreate(r);
    1293   else
    1294   {
    1295     if( !sIsEmpty(m_sum_bucket) )
    1296       sum = sBucketCreate(r);
    1297     else
    1298     {
    1299       sum = m_sum_bucket;
    1300       m_sum_bucket = NULL;
    1301     }
    1302   }
    1303 
    1304 
    1305   assume( sum != NULL ); assume ( sIsEmpty(sum) );
    1306   assume( r == sBucketGetRing(sum) );
    1307 */
    1308 
    1309 //  poly s; int len;
    1310 
    1311   //    CPolynomialSummator sum(r, bUsePolynomial);
    1312   //    poly s = NULL;
    1313 
    1314   // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    1315   // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    1316   for(poly p = tail; p != NULL; p = pNext(p))   // iterate over the tail
    1317   {
    1318     // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    1319     const poly rt = ReduceTerm(multiplier, p, NULL); // TODO: also return/store length?
    1320     sum.Add(rt);
    1321     // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    1322     // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    1323     // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    1324 
    1325 //    const int lp = pLength(rt);
    1326 //    if( rt != NULL && lp != 0 )
    1327 //      sBucket_Add_p(sum, rt, lp);
    1328   }
    1329   // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    1330   // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    1331 
    1332 //  sBucketClearAdd(sum, &s, &len); // Will Not Clear?!?
    1333   const poly s = sum.ClearAdd();
    1334 
    1335 //  assume( sum != NULL ); assume ( sIsEmpty(sum) );
    1336 /*
    1337   if( m_sum_bucket == NULL )
    1338     m_sum_bucket = sum;
    1339   else
    1340     sBucketDestroy(&sum);
    1341 
    1342   assume( pLength(s) == len );
    1343 */
    1344 
    1345   p_Test(multiplier, r);
    1346 
    1347   return s;
    1348 }
    1349 
    1350 
    1351 
    1352 
    1353 poly SchreyerSyzygyComputation::ReduceTerm(poly multiplier, poly term4reduction, poly syztermCheck) const
    1354 {
    1355   assume( !OPT__IGNORETAILS );
    1356 
    1357   const ideal& L = m_idLeads;
    1358   const ideal& T = m_idTails;
    1359   const ring& r = m_rBaseRing;
    1360 
    1361   assume( multiplier != NULL );
    1362   assume( term4reduction != NULL );
    1363 
    1364 
    1365   assume( L != NULL );
    1366   assume( T != NULL );
    1367 
    1368   p_Test(multiplier, r);
    1369 
    1370   // simple implementation with FindReducer:
    1371   poly s = NULL;
    1372 
    1373   if( (!OPT__TAILREDSYZ) || m_lcm.Check(multiplier) ) // TODO: UNLIKELY / LIKELY ????
    1374   {
    1375 #if NOPRODUCT
    1376     s = m_div.FindReducer(multiplier, term4reduction, syztermCheck, m_checker); // s ????
    1377     p_Test(s, r);
    1378 
    1379     p_Test(multiplier, r);
    1380 
    1381     if( s == NULL ) // No Reducer?
    1382     {
    1383       if( UNLIKELY(OPT__PROT) ) ++ m_stat[4]; // PrintS("$"); // LOT
    1384       return NULL;
    1385     }
    1386 
    1387 #else
    1388     // NOTE: only LT(term4reduction) should be used in the following:
    1389     poly product = pp_Mult_mm(multiplier, term4reduction, r);
    1390     p_Test(product, r);
    1391 
    1392     s = m_div.FindReducer(product, syztermCheck, m_checker); // ??
    1393     p_Test(s, r);
    1394 
    1395     p_Test(multiplier, r);
    1396 
    1397     if( s == NULL ) // No Reducer?
    1398     {
    1399       if( UNLIKELY(OPT__PROT) ) ++ m_stat[4]; // PrintS("$"); // LOT
    1400       return NULL;
    1401     }
    1402 
    1403     p_Delete(&product, r);
    1404 #endif
    1405   }
    1406 
    1407   if( s == NULL ) // No Reducer?
    1408   {
    1409     if( UNLIKELY( OPT__TAILREDSYZ && OPT__PROT) )
    1410     {
    1411       ++ m_stat[5]; // PrintS("%"); // check LCM !
    1412     }
    1413     return NULL;
    1414   }
    1415 
    1416   p_Test(multiplier, r);
    1417   p_Test(s, r);
    1418 
    1419   poly b = leadmonom(s, r);
    1420 
    1421   p_Test(b, r);
    1422 
    1423   const int c = p_GetComp(s, r) - 1;
    1424   assume( c >= 0 && c < IDELEMS(T) );
    1425 
    1426 
    1427   if( UNLIKELY( OPT__TREEOUTPUT ) )
    1428      PrintS("\", \"children\": [");
    1429 
    1430   const poly t = TraverseTail(b, c); // T->m[c];
    1431 
    1432   p_Test(multiplier, r);
    1433 
    1434   if( t != NULL )
    1435     s = p_Add_q(s, t, r);
    1436 
    1437   p_Test(multiplier, r);
    1438 
    1439   return s;
    1440 }
    1441 
    1442 SchreyerSyzygyComputationFlags::SchreyerSyzygyComputationFlags(idhdl rootRingHdl):
    1443     OPT__DEBUG( atGetInt(rootRingHdl,"DEBUG", 0) ),
    1444     OPT__LEAD2SYZ( atGetInt(rootRingHdl, "LEAD2SYZ", 0) ),
    1445     OPT__TAILREDSYZ( atGetInt(rootRingHdl, "TAILREDSYZ", 1) ),
    1446     OPT__HYBRIDNF( atGetInt(rootRingHdl, "HYBRIDNF", 0) ),
    1447     OPT__IGNORETAILS( atGetInt(rootRingHdl, "IGNORETAILS", 0) ),
    1448     OPT__SYZNUMBER( atGetInt(rootRingHdl, "SYZNUMBER", 0) ),
    1449     OPT__TREEOUTPUT( atGetInt(rootRingHdl, "TREEOUTPUT", 0) ),
    1450     OPT__SYZCHECK( atGetInt(rootRingHdl, "SYZCHECK", 0) ),
    1451     OPT__PROT(TEST_OPT_PROT),
    1452     OPT__NOCACHING( atGetInt(rootRingHdl, "NOCACHING", 0) ),
    1453     m_rBaseRing( rootRingHdl->data.uring )
    1454 {
    1455   // TODO: just current setting!
    1456   assume( rootRingHdl == currRingHdl );
    1457   assume( rootRingHdl->typ == RING_CMD );
    1458   assume( m_rBaseRing == currRing );
    1459   // move the global ring here inside???
    1460 }
    1461 
    1462 
    1463 
    1464 CLeadingTerm::CLeadingTerm(unsigned int _label,  const poly _lt, const ring R):
    1465     m_sev( p_GetShortExpVector(_lt, R) ),  m_label( _label ),  m_lt( _lt )
    1466 {
    1467   assume( sev() == p_GetShortExpVector(lt(), R) );
    1468 }
    1469 
    1470 CReducerFinder::~CReducerFinder()
    1471 {
    1472   for( CReducersHash::const_iterator it = m_hash.begin(); it != m_hash.end(); it++ )
    1473   {
    1474     const TReducers& v = it->second;
    1475     for(TReducers::const_iterator vit = v.begin(); vit != v.end(); vit++ )
    1476       delete const_cast<CLeadingTerm*>(*vit);
    1477   }
    1478 }
    1479 
    1480 
    1481 void CReducerFinder::Initialize(const ideal L)
    1482 {
    1483   assume( m_L == NULL || m_L == L );
    1484   if( m_L == NULL )
    1485     m_L = L;
    1486 
    1487   assume( m_L == L );
    1488 
    1489   if( L != NULL )
    1490   {
    1491     const ring& R = m_rBaseRing;
    1492     assume( R != NULL );
    1493 
    1494     for( int k = IDELEMS(L) - 1; k >= 0; k-- )
    1495     {
    1496       const poly a = L->m[k]; // assume( a != NULL );
    1497 
    1498       // NOTE: label is k \in 0 ... |L|-1!!!
    1499       if( a != NULL )
    1500         m_hash[p_GetComp(a, R)].push_back( new CLeadingTerm(k, a, R) );
    1501     }
    1502   }
    1503 }
    1504 
    1505 CReducerFinder::CReducerFinder(const ideal L, const SchreyerSyzygyComputationFlags& flags):
    1506     SchreyerSyzygyComputationFlags(flags),
    1507     m_L(const_cast<ideal>(L)), // for debug anyway
    1508     m_hash()
    1509 {
    1510   assume( flags.m_rBaseRing == m_rBaseRing );
    1511   if( L != NULL )
    1512     Initialize(L);
    1513 }
    1514 
    1515 /// _p_LmDivisibleByNoComp for a | b*c
    1516 static inline BOOLEAN _p_LmDivisibleByNoComp(const poly a, const poly b, const poly c, const ring r)
    1517 {
    1518   int i=r->VarL_Size - 1;
    1519   unsigned long divmask = r->divmask;
    1520   unsigned long la, lb;
    1521 
    1522   if (r->VarL_LowIndex >= 0)
    1523   {
    1524     i += r->VarL_LowIndex;
    1525     do
    1526     {
    1527       la = a->exp[i];
    1528       lb = b->exp[i] + c->exp[i];
    1529       if ((la > lb) ||
    1530           (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask)))
    1531       {
    1532         pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == FALSE);
    1533         return FALSE;
    1534       }
    1535       i--;
    1536     }
    1537     while (i>=r->VarL_LowIndex);
    1538   }
    1539   else
    1540   {
    1541     do
    1542     {
    1543       la = a->exp[r->VarL_Offset[i]];
    1544       lb = b->exp[r->VarL_Offset[i]] + c->exp[r->VarL_Offset[i]];
    1545       if ((la > lb) ||
    1546           (((la & divmask) ^ (lb & divmask)) != ((lb - la) & divmask)))
    1547       {
    1548         pDivAssume(p_DebugLmDivisibleByNoComp(a, b, r) == FALSE);
    1549         return FALSE;
    1550       }
    1551       i--;
    1552     }
    1553     while (i>=0);
    1554   }
    1555 #ifdef HAVE_RINGS
    1556   assume( !rField_is_Ring(r) ); // not implemented for rings...!
    1557 #endif
    1558   return TRUE;
    1559 }
    1560 
    1561 
    1562 bool CLeadingTerm::CheckLT( const ideal & L ) const
    1563 {
    1564 //  for( int i = IDELEMS(L); i >= 0; --i) assume( pNext(L->m[i]) == NULL ); // ???
    1565   return ( L->m[label()] == lt() );
    1566 }
    1567 
    1568 bool CLeadingTerm::DivisibilityCheck(const poly product, const unsigned long not_sev, const ring r) const
    1569 {
    1570   // may have no coeff yet
    1571 //  assume ( !n_IsZero( p_GetCoeff(product, r), r ) );
    1572 
    1573   assume ( !n_IsZero( pGetCoeff(lt()), r->cf ) );
    1574   assume( sev() == p_GetShortExpVector(lt(), r) );
    1575 
    1576   assume( product != NULL );
    1577   assume( (p_GetComp(lt(), r) == p_GetComp(product, r)) || (p_GetComp(lt(), r) == 0) );
    1578 
    1579 //  const int k = label();
    1580 //  assume( m_L->m[k] == p );
    1581 
    1582   return p_LmShortDivisibleByNoComp(lt(), sev(), product, not_sev, r);
    1583 
    1584 }
    1585 
    1586 #if NOPRODUCT
    1587 /// as DivisibilityCheck(multiplier * t, ...) for monomial 'm'
    1588 /// and a module term 't'
    1589 bool CLeadingTerm::DivisibilityCheck(const poly m, const poly t, const unsigned long not_sev, const ring r) const
    1590 {
    1591   assume ( !n_IsZero( pGetCoeff(lt()), r->cf ) );
    1592   assume( sev() == p_GetShortExpVector(lt(), r) );
    1593 
    1594   assume( m != NULL );
    1595   assume( t != NULL );
    1596   assume ( !n_IsZero( pGetCoeff(m), r->cf ) );
    1597   assume ( !n_IsZero( pGetCoeff(t), r->cf ) );
    1598 
    1599 // assume( p_GetComp(m, r) == 0 );
    1600   assume( (p_GetComp(lt(), r) == p_GetComp(t, r))  || (p_GetComp(lt(), r) == 0)  );
    1601 
    1602   p_Test(m, r);
    1603   p_Test(t, r);
    1604 //  const int k = label();
    1605 //  assume( m_L->m[k] == p );
    1606 
    1607   if (sev() & not_sev)
    1608     return false;
    1609 
    1610   return _p_LmDivisibleByNoComp(lt(), m, t, r);
    1611 //  return p_LmShortDivisibleByNoComp(p, p_sev, product, not_sev, r);
    1612 }
    1613 #endif
    1614 
    1615 
    1616 /// TODO:
    1617 class CDivisorEnumerator: public SchreyerSyzygyComputationFlags
    1618 {
    1619   private:
    1620     const CReducerFinder& m_reds;
    1621     const poly m_product;
    1622     const unsigned long m_not_sev;
    1623     const long m_comp;
    1624 
    1625     CReducerFinder::CReducersHash::const_iterator m_itr;
    1626     CReducerFinder::TReducers::const_iterator m_current, m_finish;
    1627 
    1628     bool m_active;
    1629 
    1630   public:
    1631     CDivisorEnumerator(const CReducerFinder& self, const poly product):
    1632         SchreyerSyzygyComputationFlags(self),
    1633         m_reds(self),
    1634         m_product(product),
    1635         m_not_sev(~p_GetShortExpVector(product, m_rBaseRing)),
    1636         m_comp(p_GetComp(product, m_rBaseRing)),
    1637         m_itr(), m_current(), m_finish(),
    1638         m_active(false)
    1639     {
    1640       assume( m_comp >= 0 );
    1641       assume( m_reds.m_L != NULL ); /// TODO: m_L should stay the same!!!
    1642 
    1643       assume( product != NULL ); // may have no coeff yet :(
    1644 //      assume ( !n_IsZero( p_GetCoeff(product, m_rBaseRing), m_rBaseRing ) );
    1645     }
    1646 
    1647     inline bool Reset()
    1648     {
    1649       m_active = false;
    1650 
    1651       m_itr = m_reds.m_hash.find(m_comp);
    1652 
    1653       if( m_itr == m_reds.m_hash.end() )
    1654         return false;
    1655 
    1656       assume( m_itr->first == m_comp );
    1657 
    1658       m_current = (m_itr->second).begin();
    1659       m_finish = (m_itr->second).end();
    1660 
    1661       if (m_current == m_finish)
    1662         return false;
    1663 
    1664 //      m_active = true;
    1665       return true;
    1666     }
    1667 
    1668     const CLeadingTerm& Current() const
    1669     {
    1670       assume( m_active );
    1671       assume( m_current != m_finish );
    1672 
    1673       return *(*m_current);
    1674     }
    1675 
    1676     inline bool MoveNext()
    1677     {
    1678       assume( m_current != m_finish );
    1679 
    1680       if( m_active )
    1681         ++m_current;
    1682       else
    1683         m_active = true; // for Current()
    1684 
    1685       // looking for the next good entry
    1686       for( ; m_current != m_finish; ++m_current )
    1687       {
    1688         assume( Current().CheckLT( m_reds.m_L ) );
    1689 
    1690         if( Current().DivisibilityCheck(m_product, m_not_sev, m_rBaseRing) )
    1691         {
    1692 //          m_active = true;
    1693           assume( Current().CheckLT( m_reds.m_L ) );
    1694           return true;
    1695         }
    1696         assume( Current().CheckLT( m_reds.m_L ) );
    1697       }
    1698 
    1699       // the end... :(
    1700       assume( m_current == m_finish );
    1701 
    1702       m_active = false;
    1703       return false;
    1704     }
    1705 };
    1706 
    1707 
    1708 bool CReducerFinder::IsDivisible(const poly product) const
    1709 {
    1710   assume( product != NULL );
    1711 
    1712   // NOTE: q may have no coeff!!!
    1713 
    1714   CDivisorEnumerator itr(*this, product);
    1715   if( !itr.Reset() )
    1716     return false;
    1717 
    1718   return itr.MoveNext();
    1719 
    1720 }
    1721 
    1722 #if NOPRODUCT
    1723 
    1724 /// TODO:
    1725 class CDivisorEnumerator2: public SchreyerSyzygyComputationFlags
    1726 {
    1727   private:
    1728     const CReducerFinder& m_reds;
    1729     const poly m_multiplier, m_term;
    1730     const unsigned long m_not_sev;
    1731     const long m_comp;
    1732 
    1733     CReducerFinder::CReducersHash::const_iterator m_itr;
    1734     CReducerFinder::TReducers::const_iterator m_current, m_finish;
    1735 
    1736     bool m_active;
    1737 
    1738   public:
    1739     CDivisorEnumerator2(const CReducerFinder& self, const poly m, const poly t):
    1740         SchreyerSyzygyComputationFlags(self),
    1741         m_reds(self),
    1742         m_multiplier(m), m_term(t),
    1743         m_not_sev(~p_GetShortExpVector(m, t, m_rBaseRing)),
    1744         m_comp(p_GetComp(t, m_rBaseRing)),
    1745         m_itr(), m_current(), m_finish(),
    1746         m_active(false)
    1747     {
    1748       assume( m_comp >= 0 );
    1749       assume( m_reds.m_L != NULL );
    1750       assume( m_multiplier != NULL );
    1751       assume( m_term != NULL );
    1752 
    1753       assume( m != NULL );
    1754       assume( t != NULL );
    1755       assume ( !n_IsZero( pGetCoeff(m), m_rBaseRing->cf ) );
    1756       assume ( !n_IsZero( pGetCoeff(t), m_rBaseRing->cf ) );
    1757 
    1758       p_Test(m, m_rBaseRing);
    1759 
    1760     }
    1761 
    1762     inline bool Reset()
    1763     {
    1764       m_active = false;
    1765 
    1766       m_itr = m_reds.m_hash.find(m_comp);
    1767 
    1768       if( m_itr == m_reds.m_hash.end() )
    1769         return false;
    1770 
    1771       assume( m_itr->first == m_comp );
    1772 
    1773       m_current = (m_itr->second).begin();
    1774       m_finish = (m_itr->second).end();
    1775 
    1776       if (m_current == m_finish)
    1777         return false;
    1778 
    1779       return true;
    1780     }
    1781 
    1782     const CLeadingTerm& Current() const
    1783     {
    1784       assume( m_active );
    1785       assume( m_current != m_finish );
    1786 
    1787       return *(*m_current);
    1788     }
    1789 
    1790     inline bool MoveNext()
    1791     {
    1792       assume( m_current != m_finish );
    1793 
    1794       if( m_active )
    1795         ++m_current;
    1796       else
    1797         m_active = true;
    1798 
    1799 
    1800       // looking for the next good entry
    1801       for( ; m_current != m_finish; ++m_current )
    1802       {
    1803         assume( Current().CheckLT( m_reds.m_L ) );
    1804 
    1805         if( Current().DivisibilityCheck(m_multiplier, m_term, m_not_sev, m_rBaseRing) )
    1806         {
    1807 //          m_active = true;
    1808           assume( Current().CheckLT( m_reds.m_L ) );
    1809           return true;
    1810 
    1811         }
    1812         assume( Current().CheckLT( m_reds.m_L ) );
    1813       }
    1814 
    1815       // the end... :(
    1816       assume( m_current == m_finish );
    1817 
    1818       m_active = false;
    1819       return false;
    1820     }
    1821 };
    1822 
    1823 poly CReducerFinder::FindReducer(const poly multiplier, const poly t,
    1824                                  const poly syzterm,
    1825                                  const CReducerFinder& syz_checker) const
    1826 {
    1827   const ring& r = m_rBaseRing;
    1828 
    1829   p_Test(multiplier, r);
    1830 
    1831   CDivisorEnumerator2 itr(*this, multiplier, t);
    1832   if( !itr.Reset() )
    1833     return NULL;
    1834 
    1835   // don't care about the module component of multiplier (as it may be the syzygy term)
    1836   // product = multiplier * t?
    1837 
    1838   assume( multiplier != NULL ); assume( t != NULL );
    1839 
    1840   const ideal& L = m_L; assume( L != NULL ); // for debug/testing only!
    1841 
    1842   long c = 0;
    1843 
    1844   if (syzterm != NULL)
    1845     c = p_GetComp(syzterm, r) - 1;
    1846 
    1847   assume( c >= 0 && c < IDELEMS(L) );
    1848 
    1849   p_Test(multiplier, r);
    1850 
    1851   const BOOLEAN to_check = (syz_checker.IsNonempty()); // OPT__TAILREDSYZ &&
    1852 
    1853 //  const poly q = p_One(r);
    1854   const poly q = p_New(r); pNext(q) = NULL;
    1855 
    1856   assume( pNext(q) == NULL );
    1857 
    1858   p_Test(multiplier, r);
    1859   while( itr.MoveNext() )
    1860   {
    1861     assume( itr.Current().CheckLT( L ) ); // ???
    1862 
    1863     const poly p = itr.Current().lt(); // ???
    1864     const int k  = itr.Current().label();
    1865 
    1866     p_ExpVectorSum(q, multiplier, t, r); // q == product == multiplier * t // TODO: do it once?
    1867     p_ExpVectorDiff(q, q, p, r); // (LM(product) / LM(L[k]))
    1868 
    1869     p_SetComp(q, k + 1, r);
    1870     p_Setm(q, r);
    1871 
    1872     p_Test(multiplier, r);
    1873 
    1874     // cannot allow something like: a*gen(i) - a*gen(i)
    1875     if (syzterm != NULL && (k == c))
    1876       if (p_ExpVectorEqual(syzterm, q, r))
    1877       {
    1878         assume( itr.Current().CheckLT( L ) ); // ???
    1879         continue;
    1880       }
    1881 
    1882     // while the complement (the fraction) is not reducible by leading syzygies
    1883     if( to_check && syz_checker.IsDivisible(q) )
    1884     {
    1885       assume( itr.Current().CheckLT( L ) ); // ???
    1886       continue;
    1887     }
    1888 
    1889     number n = n_Mult( pGetCoeff(multiplier), pGetCoeff(t), r->cf);
    1890 
    1891 #if NODIVISION
    1892     // we assume all leading coeffs to be 1!
    1893     assume( n_IsOne(pGetCoeff(p), r->cf) );
    1894 #else
    1895     if( !n_IsOne( pGetCoeff(p), r ) )
    1896       n = n_Div(n, pGetCoeff(p), r->cf);
    1897 #endif
    1898 
    1899     p_SetCoeff0(q, n_InpNeg(n, r->cf), r);
    1900 //    n_Delete(&n, r);
    1901 
    1902     p_Test(multiplier, r);
    1903     p_Test(q, r);
    1904 
    1905     assume( itr.Current().CheckLT( L ) ); // ???
    1906     return q;
    1907   }
    1908 
    1909   p_LmFree(q, r);
    1910 
    1911   p_Test(multiplier, r);
    1912 
    1913   return NULL;
    1914 
    1915 }
    1916 #endif
    1917 
    1918 
    1919 poly CReducerFinder::FindReducer(const poly product, const poly syzterm, const CReducerFinder& syz_checker) const
    1920 {
    1921   CDivisorEnumerator itr(*this, product);
    1922   if( !itr.Reset() )
    1923     return NULL;
    1924 
    1925 
    1926 
    1927   const ring& r = m_rBaseRing;
    1928 
    1929   assume( product != NULL );
    1930 
    1931   const ideal& L = m_L; assume( L != NULL ); // for debug/testing only!
    1932 
    1933   long c = 0;
    1934 
    1935   if (syzterm != NULL)
    1936     c = p_GetComp(syzterm, r) - 1;
    1937 
    1938   assume( c >= 0 && c < IDELEMS(L) );
    1939 
    1940   const BOOLEAN to_check = (syz_checker.IsNonempty()); // OPT__TAILREDSYZ &&
    1941 
    1942   const poly q = p_New(r); pNext(q) = NULL;
    1943 
    1944   while( itr.MoveNext() )
    1945   {
    1946     assume( itr.Current().CheckLT( L ) ); // ???
    1947 
    1948     const poly p = itr.Current().lt(); // ??
    1949     const int k  = itr.Current().label();
    1950 
    1951     p_ExpVectorDiff(q, product, p, r); // (LM(product) / LM(L[k]))
    1952     p_SetComp(q, k + 1, r);
    1953     p_Setm(q, r);
    1954 
    1955     // cannot allow something like: a*gen(i) - a*gen(i)
    1956     if (syzterm != NULL && (k == c))
    1957       if (p_ExpVectorEqual(syzterm, q, r))
    1958       {
    1959         assume( itr.Current().CheckLT( L ) ); // ???
    1960         continue;
    1961       }
    1962 
    1963     // while the complement (the fraction) is not reducible by leading syzygies
    1964     if( to_check && syz_checker.IsDivisible(q) ) // ?????
    1965     {
    1966       assume( itr.Current().CheckLT( L ) ); // ???
    1967       continue;
    1968     }
    1969 
    1970 
    1971 #if NODIVISION
    1972     assume( n_IsOne(p_GetCoeff(p, r), r->cf) );
    1973     p_SetCoeff0(q, n_InpNeg( n_Copy(pGetCoeff(product), r->cf), r->cf), r);
    1974 #else
    1975     p_SetCoeff0(q, n_InpNeg( n_Div( pGetCoeff(product), p_GetCoeff(p), r->cf), r->cf), r);
    1976 #endif
    1977 
    1978     assume( itr.Current().CheckLT( L ) ); // ???
    1979     return q;
    1980   }
    1981 
    1982 
    1983 
    1984 /*
    1985   const long comp = p_GetComp(product, r);
    1986   const unsigned long not_sev = ~p_GetShortExpVector(product, r);
    1987 
    1988   assume( comp >= 0 );
    1989 
    1990 //   for( int k = IDELEMS(L)-1; k>= 0; k-- )
    1991 //   {
    1992 //     const poly p = L->m[k];
    1993 //
    1994 //     if ( p_GetComp(p, r) != comp )
    1995 //       continue;
    1996 //
    1997 //     const unsigned long p_sev = p_GetShortExpVector(p, r); // to be stored in m_hash!!!
    1998 
    1999    // looking for an appropriate diviser p = L[k]...
    2000   CReducersHash::const_iterator it = m_hash.find(comp); // same module component
    2001 
    2002   if( it == m_hash.end() )
    2003     return NULL;
    2004 
    2005   assume( m_L != NULL );
    2006 
    2007   const TReducers& reducers = it->second;
    2008 
    2009   const BOOLEAN to_check = (syz_checker.IsNonempty()); // OPT__TAILREDSYZ &&
    2010 
    2011   const poly q = p_New(r); pNext(q) = NULL;
    2012 
    2013   for(TReducers::const_iterator vit = reducers.begin(); vit != reducers.end(); vit++ )
    2014   {
    2015     const poly p = (*vit)->lt(); // ???
    2016 
    2017     assume( p_GetComp(p, r) == comp );
    2018 
    2019     const int k = (*vit)->label();
    2020 
    2021     assume( L->m[k] == p ); // CheckLT
    2022 
    2023     const unsigned long p_sev = (*vit)->sev();
    2024 
    2025     assume( p_sev == p_GetShortExpVector(p, r) );
    2026 
    2027     if( !p_LmShortDivisibleByNoComp(p, p_sev, product, not_sev, r) )
    2028       continue;
    2029 
    2030 //     // ... which divides the product, looking for the _1st_ appropriate one!
    2031 //     if( !p_LmDivisibleByNoComp(p, product, r) ) // included inside  p_LmShortDivisibleBy!
    2032 //       continue;
    2033 
    2034     p_ExpVectorDiff(q, product, p, r); // (LM(product) / LM(L[k]))
    2035     p_SetComp(q, k + 1, r);
    2036     p_Setm(q, r);
    2037 
    2038     // cannot allow something like: a*gen(i) - a*gen(i)
    2039     if (syzterm != NULL && (k == c))
    2040       if (p_ExpVectorEqual(syzterm, q, r))
    2041       {
    2042         continue;
    2043       }
    2044 
    2045     // while the complement (the fraction) is not reducible by leading syzygies
    2046     if( to_check && syz_checker.IsDivisible(q) )
    2047     {
    2048       continue;
    2049     }
    2050 
    2051     p_SetCoeff0(q, n_InpNeg( n_Div( p_GetCoeff(product, r), p_GetCoeff(p, r), r), r), r);
    2052     return q;
    2053   }
    2054 */
    2055 
    2056   p_LmFree(q, r);
    2057   return NULL;
    2058 }
    2059 
    2060 
    2061 CLCM::CLCM(const ideal& L, const SchreyerSyzygyComputationFlags& flags):
    2062     SchreyerSyzygyComputationFlags(flags), std::vector<bool>(),
    2063     m_compute(false), m_N(rVar(flags.m_rBaseRing))
    2064 {
    2065   const ring& R = m_rBaseRing;
    2066   assume( flags.m_rBaseRing == R );
    2067   assume( R != NULL );
    2068 
    2069   assume( L != NULL );
    2070 
    2071   if( LIKELY( OPT__TAILREDSYZ && !OPT__HYBRIDNF && (L != NULL) )) // TODO: not hybrid!?
    2072   {
    2073     const int l = IDELEMS(L);
    2074 
    2075     assume( l > 0 );
    2076 
    2077     resize(l, false);
    2078 
    2079     for( int k = l - 1; k >= 0; k-- )
    2080     {
    2081       const poly a = L->m[k]; assume( a != NULL );
    2082 
    2083       for (unsigned int j = m_N; j > 0; j--)
    2084         if ( !(*this)[j] )
    2085           (*this)[j] = (p_GetExp(a, j, R) > 0);
    2086     }
    2087 
    2088     m_compute = true;
    2089   }
    2090 }
    2091 
    2092 
    2093 bool CLCM::Check(const poly m) const
    2094 {
    2095   assume( m != NULL );
    2096   if( m_compute && (m != NULL))
    2097   {
    2098     const ring& R = m_rBaseRing;
    2099 
    2100     assume( OPT__TAILREDSYZ && !OPT__HYBRIDNF );
    2101 
    2102     for (unsigned int j = m_N; j > 0; j--)
    2103       if ( (*this)[j] )
    2104         if(p_GetExp(m, j, R) > 0)
    2105           return true;
    2106 
    2107     return false;
    2108 
    2109   } else return true;
    2110 }
    2111 
    2112 
    2113 
    2114 
    2115 
    2116 // Vi-modeline: vim: filetype=c:syntax:shiftwidth=2:tabstop=8:textwidth=0:expandtab
  • Singular/dyn_modules/syzextra/syzextra.h

    rcbd574 r9fa5ff  
    153153};
    154154
    155 
    156 
    157 
    158 
    159 
    160 
    161155/// Computation attribute storage
    162156struct SchreyerSyzygyComputationFlags
     
    437431    poly ComputeImage(poly multiplier, const int tail) const;
    438432
    439 
    440 
    441433  public:
    442434    /// just for testing via the wrapper below
Note: See TracChangeset for help on using the changeset viewer.