source: git/Singular/dyn_modules/syzextra/mod_main.cc @ eb55f8a

spielwiese
Last change on this file since eb55f8a was eb55f8a, checked in by Oleksandr Motsak <motsak@…>, 10 years ago
There should be no *Test in assume call (and no assume in *Test definition)
  • Property mode set to 100644
File size: 44.6 KB
Line 
1#include <kernel/mod2.h>
2
3#include <omalloc/omalloc.h>
4
5#include <misc/intvec.h>
6#include <misc/options.h>
7
8#include <coeffs/coeffs.h>
9
10#include <polys/PolyEnumerator.h>
11
12#include <polys/monomials/p_polys.h>
13#include <polys/monomials/ring.h>
14#include <polys/simpleideals.h>
15
16// #include <kernel/longrat.h>
17#include <kernel/GBEngine/kstd1.h>
18
19#include <kernel/polys.h>
20
21#include <kernel/GBEngine/syz.h>
22
23#include <Singular/tok.h>
24#include <Singular/ipid.h>
25#include <Singular/lists.h>
26#include <Singular/attrib.h>
27
28#include <Singular/ipid.h>
29#include <Singular/ipshell.h> // For iiAddCproc
30
31// extern coeffs coeffs_BIGINT
32
33#include "singularxx_defs.h"
34
35#include "DebugPrint.h"
36#include "myNF.h"
37#include "syzextra.h"
38
39
40#include <Singular/mod_lib.h>
41
42
43#if GOOGLE_PROFILE_ENABLED
44#include <google/profiler.h>
45#endif // #if GOOGLE_PROFILE_ENABLED
46
47
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51
52
53
54
55extern void pISUpdateComponents(ideal F, const intvec *const V, const int MIN, const ring r);
56// extern ring rCurrRingAssure_SyzComp();
57extern ring rAssure_InducedSchreyerOrdering(const ring r, BOOLEAN complete, int sign);
58extern int rGetISPos(const int p, const ring r);
59
60// USING_NAMESPACE_SINGULARXX;
61
62USING_NAMESPACE( SINGULARXXNAME :: DEBUG )
63USING_NAMESPACE( SINGULARXXNAME :: NF )
64USING_NAMESPACE( SINGULARXXNAME :: SYZEXTRA )
65
66
67BEGIN_NAMESPACE_NONAME
68
69
70static inline void NoReturn(leftv& res)
71{
72  res->rtyp = NONE;
73  res->data = NULL;
74}
75
76/// wrapper around n_ClearContent
77static BOOLEAN _ClearContent(leftv res, leftv h)
78{
79  NoReturn(res);
80
81  const char *usage = "'ClearContent' needs a (non-zero!) poly or vector argument...";
82
83  if( h == NULL )
84  {
85    WarnS(usage);
86    return TRUE;
87  }
88
89  assume( h != NULL );
90
91  if( !( h->Typ() == POLY_CMD || h->Typ() == VECTOR_CMD) )
92  {
93    WarnS(usage);
94    return TRUE;
95  }
96
97  assume (h->Next() == NULL);
98
99  poly ph = reinterpret_cast<poly>(h->Data());
100
101  if( ph == NULL )
102  {
103    WarnS(usage);
104    return TRUE;
105  }
106
107  const ring r =  currRing;
108  assume( r != NULL ); assume( r->cf != NULL ); const coeffs C = r->cf;
109
110  number n;
111
112  // experimentall (recursive enumerator treatment) of alg. ext
113  CPolyCoeffsEnumerator itr(ph);
114  n_ClearContent(itr, n, C);
115
116  res->data = n;
117  res->rtyp = NUMBER_CMD;
118
119  return FALSE;
120}
121
122/// wrapper around n_ClearDenominators
123static BOOLEAN _ClearDenominators(leftv res, leftv h)
124{
125  NoReturn(res);
126
127  const char *usage = "'ClearDenominators' needs a (non-zero!) poly or vector argument...";
128
129  if( h == NULL )
130  {
131    WarnS(usage);
132    return TRUE;
133  }
134
135  assume( h != NULL );
136
137  if( !( h->Typ() == POLY_CMD || h->Typ() == VECTOR_CMD) )
138  {
139    WarnS(usage);
140    return TRUE;
141  }
142
143  assume (h->Next() == NULL);
144
145  poly ph = reinterpret_cast<poly>(h->Data());
146
147  if( ph == NULL )
148  {
149    WarnS(usage);
150    return TRUE;
151  }
152
153  const ring r =  currRing;
154  assume( r != NULL ); assume( r->cf != NULL ); const coeffs C = r->cf;
155
156  number n;
157
158  // experimentall (recursive enumerator treatment) of alg. ext.
159  CPolyCoeffsEnumerator itr(ph);
160  n_ClearDenominators(itr, n, C);
161
162  res->data = n;
163  res->rtyp = NUMBER_CMD;
164
165  return FALSE;
166}
167
168
169/// try to get an optional (simple) integer argument out of h
170/// or return the default value
171static int getOptionalInteger(const leftv& h, const int _n)
172{
173  if( h!= NULL && h->Typ() == INT_CMD )
174  {
175    int n = (int)(long)(h->Data());
176
177    if( n < 0 )
178      Warn("Negative (%d) optional integer argument", n);
179
180    return (n);
181  }
182
183  return (_n);
184}
185
186static BOOLEAN noop(leftv __res, leftv /*__v*/)
187{
188  NoReturn(__res);
189  return FALSE;
190}
191
192static BOOLEAN _ProfilerStart(leftv __res, leftv h)
193{
194  NoReturn(__res);
195#if GOOGLE_PROFILE_ENABLED
196  if( h!= NULL && h->Typ() == STRING_CMD )
197  {
198    const char* name = (char*)(h->Data());
199    assume( name != NULL );
200    ProfilerStart(name);
201  } else
202    WerrorS("ProfilerStart requires a string [name] argument");
203#else
204  WarnS("Sorry no google profiler support (GOOGLE_PROFILE_ENABLE!=1)...");
205//  return TRUE; // ?
206#endif // #if GOOGLE_PROFILE_ENABLED
207  return FALSE;
208  (void)h;
209}
210static BOOLEAN _ProfilerStop(leftv __res, leftv /*__v*/)
211{
212  NoReturn(__res);
213#if GOOGLE_PROFILE_ENABLED
214  ProfilerStop();
215#else
216  WarnS("Sorry no google profiler support (GOOGLE_PROFILE_ENABLED!=1)...");
217//  return TRUE; // ?
218#endif // #if GOOGLE_PROFILE_ENABLED
219  return FALSE;
220}
221
222static inline number jjLONG2N(long d)
223{
224  return n_Init(d, coeffs_BIGINT);
225}
226
227static inline void view(const intvec* v)
228{
229#ifndef SING_NDEBUG
230  v->view();
231#else
232  // This code duplication is only due to Hannes's #ifndef SING_NDEBUG!
233  Print ("intvec: {rows: %d, cols: %d, length: %d, Values: \n", v->rows(), v->cols(), v->length());
234
235  for (int i = 0; i < v->rows(); i++)
236  {
237    Print ("Row[%3d]:", i);
238    for (int j = 0; j < v->cols(); j++)
239      Print (" %5d", (*v)[j + i * (v->cols())] );
240    PrintLn ();
241  }
242  PrintS ("}\n");
243#endif
244
245}
246
247
248
249static BOOLEAN DetailedPrint(leftv __res, leftv h)
250{
251  NoReturn(__res);
252
253  if( h == NULL )
254  {
255    WarnS("DetailedPrint needs an argument...");
256    return TRUE;
257  }
258
259  if( h->Typ() == NUMBER_CMD)
260  {
261    number n = (number)h->Data();
262
263    const ring r = currRing;
264
265#ifdef LDEBUG
266    r->cf->cfDBTest(n,__FILE__,__LINE__,r->cf);
267#endif
268
269    StringSetS("");
270    n_Write(n, r->cf);
271    PrintS(StringEndS());
272    PrintLn();
273
274    return FALSE;
275  }
276
277  if( h->Typ() == RING_CMD)
278  {
279    const ring r = (const ring)h->Data();
280    rWrite(r, TRUE);
281    PrintLn();
282#ifdef RDEBUG
283    //rDebugPrint(r);
284#endif
285    return FALSE;
286  }
287
288  if( h->Typ() == POLY_CMD || h->Typ() == VECTOR_CMD)
289  {
290    const poly p = (const poly)h->Data(); h = h->Next();
291
292    dPrint(p, currRing, currRing, getOptionalInteger(h, 3));
293
294    return FALSE;
295  }
296
297  if( h->Typ() == IDEAL_CMD || h->Typ() == MODUL_CMD)
298  {
299    const ideal id = (const ideal)h->Data(); h = h->Next();
300
301    dPrint(id, currRing, currRing, getOptionalInteger(h, 3));
302
303    return FALSE;
304  }
305
306  if( h->Typ() == RESOLUTION_CMD )
307  {
308    const syStrategy syzstr = reinterpret_cast<const syStrategy>(h->Data());
309
310    h = h->Next();
311
312    int nTerms = getOptionalInteger(h, 1);
313
314
315    Print("RESOLUTION_CMD(%p): ", reinterpret_cast<const void*>(syzstr)); PrintLn();
316
317    const ring save = currRing;
318    const ring r = syzstr->syRing;
319    const ring rr = (r != NULL) ? r: save;
320
321
322    const int iLength = syzstr->length;
323
324    Print("int 'length': %d", iLength); PrintLn();
325    Print("int 'regularity': %d", syzstr->regularity); PrintLn();
326    Print("short 'list_length': %hd", syzstr->list_length); PrintLn();
327    Print("short 'references': %hd", syzstr->references); PrintLn();
328
329
330#define PRINT_pINTVECTOR(s, v) Print("intvec '%10s'(%p)", #v, reinterpret_cast<const void*>((s)->v)); \
331if( (s)->v != NULL ){ PrintS(": "); view((s)->v); }; \
332PrintLn();
333
334    PRINT_pINTVECTOR(syzstr, resolution);
335    PRINT_pINTVECTOR(syzstr, betti);
336    PRINT_pINTVECTOR(syzstr, Tl);
337    PRINT_pINTVECTOR(syzstr, cw);
338#undef PRINT_pINTVECTOR
339
340    if (r == NULL)
341      Print("ring '%10s': NULL", "syRing");
342    else
343      if (r == currRing)
344        Print("ring '%10s': currRing", "syRing");
345      else
346        if (r != NULL && r != save)
347        {
348          Print("ring '%10s': ", "syRing");
349          rWrite(r);
350#ifdef RDEBUG
351          //              rDebugPrint(r);
352#endif
353          // rChangeCurrRing(r);
354        }
355    PrintLn();
356
357    const SRes rP = syzstr->resPairs;
358    Print("SRes 'resPairs': %p", reinterpret_cast<const void*>(rP)); PrintLn();
359
360    if (rP != NULL)
361      for (int iLevel = 0; (iLevel < iLength) && (rP[iLevel] != NULL) && ((*syzstr->Tl)[iLevel] >= 0); iLevel++)
362      {
363        int n = 0;
364        const int iTl = (*syzstr->Tl)[iLevel];
365        for (int j = 0; (j < iTl) && ((rP[iLevel][j].lcm!=NULL) || (rP[iLevel][j].syz!=NULL)); j++)
366        {
367          if (rP[iLevel][j].isNotMinimal==NULL)
368            n++;
369        }
370        Print("minimal-resPairs-Size[1+%d]: %d", iLevel, n); PrintLn();
371      }
372
373
374    //  const ring rrr = (iLevel > 0) ? rr : save; ?
375#define PRINT_RESOLUTION(s, v) Print("resolution '%12s': %p", #v, reinterpret_cast<const void*>((s)->v)); PrintLn(); \
376if ((s)->v != NULL) \
377  for (int iLevel = 0; (iLevel < iLength) && ( ((s)->v)[iLevel] != NULL ); iLevel++) \
378  { \
379    /* const ring rrr = (iLevel > 0) ? save : save; */ \
380    Print("id '%10s'[%d]: (%p) ncols = %d / size: %d; nrows = %d, rank = %ld / rk: %ld", #v, iLevel, reinterpret_cast<const void*>(((s)->v)[iLevel]), ((s)->v)[iLevel]->ncols, idSize(((s)->v)[iLevel]), ((s)->v)[iLevel]->nrows, ((s)->v)[iLevel]->rank, -1L/*id_RankFreeModule(((s)->v)[iLevel], rrr)*/ ); \
381    PrintLn(); \
382  } \
383  PrintLn();
384
385    // resolvente:
386    PRINT_RESOLUTION(syzstr, minres);
387    PRINT_RESOLUTION(syzstr, fullres);
388
389//    assume (id_RankFreeModule (syzstr->res[1], rr) == syzstr->res[1]->rank);
390
391    PRINT_RESOLUTION(syzstr, res);
392    PRINT_RESOLUTION(syzstr, orderedRes);
393#undef PRINT_RESOLUTION
394
395#define PRINT_POINTER(s, v) Print("pointer '%17s': %p", #v, reinterpret_cast<const void*>((s)->v)); PrintLn();
396    // 2d arrays:
397    PRINT_POINTER(syzstr, truecomponents);
398    PRINT_POINTER(syzstr, ShiftedComponents);
399    PRINT_POINTER(syzstr, backcomponents);
400    PRINT_POINTER(syzstr, Howmuch);
401    PRINT_POINTER(syzstr, Firstelem);
402    PRINT_POINTER(syzstr, elemLength);
403    PRINT_POINTER(syzstr, sev);
404
405    // arrays of intvects:
406    PRINT_POINTER(syzstr, weights);
407    PRINT_POINTER(syzstr, hilb_coeffs);
408#undef PRINT_POINTER
409
410
411    if (syzstr->fullres==NULL)
412    {
413      PrintS("resolution 'fullres': (NULL) => resolution not computed yet");
414      PrintLn();
415    } else
416    {
417      Print("resolution 'fullres': (%p) => resolution seems to be computed already", reinterpret_cast<const void*>(syzstr->fullres));
418      PrintLn();
419      dPrint(*syzstr->fullres, save, save, nTerms);
420    }
421
422
423
424
425    if (syzstr->minres==NULL)
426    {
427      PrintS("resolution 'minres': (NULL) => resolution not minimized yet");
428      PrintLn();
429    } else
430    {
431      Print("resolution 'minres': (%p) => resolution seems to be minimized already", reinterpret_cast<const void*>(syzstr->minres));
432      PrintLn();
433      dPrint(*syzstr->minres, save, save, nTerms);
434    }
435
436
437
438
439    /*
440    int ** truecomponents;
441    long** ShiftedComponents;
442    int ** backcomponents;
443    int ** Howmuch;
444    int ** Firstelem;
445    int ** elemLength;
446    unsigned long ** sev;
447
448    intvec ** weights;
449    intvec ** hilb_coeffs;
450
451    SRes resPairs;               //polynomial data for internal use only
452
453    resolvente fullres;
454    resolvente minres;
455    resolvente res;              //polynomial data for internal use only
456    resolvente orderedRes;       //polynomial data for internal use only
457*/
458
459    //            if( currRing != save ) rChangeCurrRing(save);
460  }
461
462
463  return FALSE;
464}
465
466/// wrapper around p_Tail and id_Tail
467static BOOLEAN Tail(leftv res, leftv h)
468{
469  NoReturn(res);
470
471  if( h == NULL )
472  {
473    WarnS("Tail needs a poly/vector/ideal/module argument...");
474    return TRUE;
475  }
476
477  assume( h != NULL );
478
479  const ring r =  currRing;
480
481  if( h->Typ() == POLY_CMD || h->Typ() == VECTOR_CMD)
482  {
483    res->data = p_Tail( (const poly)h->Data(), r );
484    res->rtyp = h->Typ();
485
486    h = h->Next(); assume (h == NULL);
487
488    return FALSE;
489  }
490
491  if( h->Typ() == IDEAL_CMD || h->Typ() == MODUL_CMD)
492  {
493    res->data = id_Tail( (const ideal)h->Data(), r );
494    res->rtyp = h->Typ();
495
496    h = h->Next(); assume (h == NULL);
497
498    return FALSE;
499  }
500
501  WarnS("Tail needs a single poly/vector/ideal/module argument...");
502  return TRUE;
503}
504
505
506
507static BOOLEAN _ComputeLeadingSyzygyTerms(leftv res, leftv h)
508{
509  const SchreyerSyzygyComputationFlags attributes(currRingHdl);
510
511  const BOOLEAN __DEBUG__      = attributes.__DEBUG__;
512//  const BOOLEAN __SYZCHECK__   = attributes.__SYZCHECK__;
513  const BOOLEAN __LEAD2SYZ__   = attributes.__LEAD2SYZ__;
514//  const BOOLEAN __HYBRIDNF__   = attributes.__HYBRIDNF__;
515//  const BOOLEAN __TAILREDSYZ__ = attributes.__TAILREDSYZ__;
516
517  const ring r = attributes.m_rBaseRing;
518  NoReturn(res);
519
520  if( h == NULL )
521  {
522    WarnS("ComputeLeadingSyzygyTerms needs an argument...");
523    return TRUE;
524  }
525
526  assume( h != NULL );
527
528  if( h->Typ() == IDEAL_CMD || h->Typ() == MODUL_CMD)
529  {
530    const ideal id = (const ideal)h->Data();
531
532    assume(id != NULL);
533
534    if( __DEBUG__ )
535    {
536      PrintS("ComputeLeadingSyzygyTerms::Input: \n");
537      dPrint(id, r, r, 1);
538    }
539
540    assume( !__LEAD2SYZ__ );
541
542    h = h->Next(); assume (h == NULL);
543
544    const ideal newid = ComputeLeadingSyzygyTerms(id,  attributes);
545
546    res->data = newid; res->rtyp = MODUL_CMD;
547    return FALSE;
548  }
549
550  WarnS("ComputeLeadingSyzygyTerms needs a single ideal/module argument...");
551  return TRUE;
552}
553
554///  sorting wrt <c,ds> & reversing...
555/// change the input inplace!!!
556// TODO: use a ring with >_{c, ds}!???
557static BOOLEAN _Sort_c_ds(leftv res, leftv h)
558{
559  const SchreyerSyzygyComputationFlags attributes(currRingHdl);
560
561  const BOOLEAN __DEBUG__      = FALSE; // attributes.__DEBUG__;
562//  const BOOLEAN __SYZCHECK__   = attributes.__SYZCHECK__;
563//  const BOOLEAN __LEAD2SYZ__   = attributes.__LEAD2SYZ__;
564//  const BOOLEAN __HYBRIDNF__   = attributes.__HYBRIDNF__;
565//  const BOOLEAN __TAILREDSYZ__ = attributes.__TAILREDSYZ__;
566
567  NoReturn(res);
568
569  const ring r = attributes.m_rBaseRing;
570  NoReturn(res);
571
572  if( h == NULL )
573  {
574    WarnS("Sort_c_ds needs an argument...");
575    return TRUE;
576  }
577
578  assume( h != NULL );
579
580  if(    (h->Typ() == IDEAL_CMD || h->Typ() == MODUL_CMD)
581      && (h->rtyp  == IDHDL) // must be a variable!
582      && (h->e == NULL) // not a list element
583      )
584  {
585    const ideal id = (const ideal)h->Data();
586
587    assume(id != NULL);
588
589    if( __DEBUG__ )
590    {
591      PrintS("Sort_c_ds::Input: \n");
592      dPrint(id, r, r, 1);
593    }
594
595    assume (h->Next() == NULL);
596
597    id_Test(id, r);
598
599    Sort_c_ds(id, r); // NOT A COPY! inplace sorting!!!
600
601//    res->data = id;
602//    res->rtyp = h->Typ();
603
604    if( __DEBUG__ )
605    {
606      PrintS("Sort_c_ds::Output: \n");
607      dPrint(id, r, r, 1);
608    }
609
610    // NOTE: nothing is to be returned!!!
611    return FALSE;
612  }
613
614  WarnS("ComputeLeadingSyzygyTerms needs a single ideal/module argument (must be a variable!)...");
615  return TRUE;
616}
617
618
619static BOOLEAN _Compute2LeadingSyzygyTerms(leftv res, leftv h)
620{
621  const SchreyerSyzygyComputationFlags attributes(currRingHdl);
622
623  const BOOLEAN __DEBUG__      = attributes.__DEBUG__;
624//  const BOOLEAN __SYZCHECK__   = attributes.__SYZCHECK__;
625  const BOOLEAN __LEAD2SYZ__   = attributes.__LEAD2SYZ__;
626//  const BOOLEAN __HYBRIDNF__   = attributes.__HYBRIDNF__;
627//  const BOOLEAN __TAILREDSYZ__ = attributes.__TAILREDSYZ__;
628
629  const ring r = attributes.m_rBaseRing;
630  NoReturn(res);
631
632  if( h == NULL )
633  {
634    WarnS("Compute2LeadingSyzygyTerms needs an argument...");
635    return TRUE;
636  }
637
638  assume( h != NULL );
639
640  assume( __LEAD2SYZ__ ); // ???
641
642  if( h->Typ() == IDEAL_CMD || h->Typ() == MODUL_CMD)
643  {
644    const ideal id = (const ideal)h->Data();
645
646    assume(id != NULL);
647
648    if( __DEBUG__ )
649    {
650      PrintS("Compute2LeadingSyzygyTerms::Input: \n");
651      dPrint(id, r, r, 0);
652    }
653
654    h = h->Next(); assume (h == NULL);
655
656    res->data = Compute2LeadingSyzygyTerms(id, attributes);
657    res->rtyp = MODUL_CMD;
658
659    return FALSE;
660  }
661
662  WarnS("Compute2LeadingSyzygyTerms needs a single ideal/module argument...");
663  return TRUE;
664}
665
666
667
668/// proc SSFindReducer(def product, def syzterm, def L, def T, list #)
669static BOOLEAN _FindReducer(leftv res, leftv h)
670{
671  const SchreyerSyzygyComputationFlags attributes(currRingHdl);
672
673  const BOOLEAN __DEBUG__      = attributes.__DEBUG__;
674//   const BOOLEAN __SYZCHECK__   = attributes.__SYZCHECK__;
675//   const BOOLEAN __LEAD2SYZ__   = attributes.__LEAD2SYZ__;
676//   const BOOLEAN __HYBRIDNF__   = attributes.__HYBRIDNF__;
677  const BOOLEAN __TAILREDSYZ__ = attributes.__TAILREDSYZ__;
678
679  const char* usage = "`FindReducer(<poly/vector>, <vector/0>, <ideal/module>[,<module>])` expected";
680  const ring r = attributes.m_rBaseRing;
681
682  NoReturn(res);
683
684
685  if ((h==NULL) || (h->Typ()!=VECTOR_CMD && h->Typ() !=POLY_CMD) || (h->Data() == NULL))
686  {
687    WerrorS(usage);
688    return TRUE;
689  }
690
691  const poly product = (poly) h->Data(); assume (product != NULL);
692
693
694  h = h->Next();
695  if ((h==NULL) || !((h->Typ()==VECTOR_CMD) || (h->Data() == NULL)) )
696  {
697    WerrorS(usage);
698    return TRUE;
699  }
700
701  poly syzterm = NULL;
702
703  if(h->Typ()==VECTOR_CMD)
704    syzterm = (poly) h->Data();
705
706
707
708  h = h->Next();
709  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
710  {
711    WerrorS(usage);
712    return TRUE;
713  }
714
715  const ideal L = (ideal) h->Data(); h = h->Next();
716
717  assume( IDELEMS(L) > 0 );
718
719  ideal LS = NULL;
720
721  if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))
722  {
723    LS = (ideal)h->Data();
724    h = h->Next();
725  }
726
727  if( __TAILREDSYZ__ )
728    assume (LS != NULL);
729
730  assume( h == NULL );
731
732  if( __DEBUG__ )
733  {
734    PrintS("FindReducer(product, syzterm, L, T, #)::Input: \n");
735
736    PrintS("product: "); dPrint(product, r, r, 2);
737    PrintS("syzterm: "); dPrint(syzterm, r, r, 2);
738    PrintS("L: "); dPrint(L, r, r, 0);
739//    PrintS("T: "); dPrint(T, r, r, 4);
740
741    if( LS == NULL )
742      PrintS("LS: NULL\n");
743    else
744    {
745      PrintS("LS: "); dPrint(LS, r, r, 0);
746    }
747  }
748
749  res->rtyp = VECTOR_CMD;
750  res->data = FindReducer(product, syzterm, L, LS, attributes);
751
752  if( __DEBUG__ )
753  {
754    PrintS("FindReducer::Output: \n");
755    dPrint((poly)res->data, r, r, 2);
756  }
757
758  return FALSE;
759
760}
761
762// proc SchreyerSyzygyNF(vector syz_lead, vector syz_2, def L, def T, list #)
763static BOOLEAN _SchreyerSyzygyNF(leftv res, leftv h)
764{
765  const SchreyerSyzygyComputationFlags attributes(currRingHdl);
766
767  const BOOLEAN __DEBUG__      = attributes.__DEBUG__;
768//   const BOOLEAN __SYZCHECK__   = attributes.__SYZCHECK__;
769//   const BOOLEAN __LEAD2SYZ__   = attributes.__LEAD2SYZ__;
770  const BOOLEAN __HYBRIDNF__   = attributes.__HYBRIDNF__;
771  const BOOLEAN __TAILREDSYZ__ = attributes.__TAILREDSYZ__;
772
773  const char* usage = "`SchreyerSyzygyNF(<vector>, <vector>, <ideal/module>, <ideal/module>[,<module>])` expected";
774  const ring r = attributes.m_rBaseRing;
775
776  NoReturn(res);
777
778  assume( __HYBRIDNF__ ); // ???
779
780  if ((h==NULL) || (h->Typ() != VECTOR_CMD) || (h->Data() == NULL))
781  {
782    WerrorS(usage);
783    return TRUE;
784  }
785
786  const poly syz_lead = (poly) h->Data(); assume (syz_lead != NULL);
787
788
789  h = h->Next();
790  if ((h==NULL) || (h->Typ() != VECTOR_CMD) || (h->Data() == NULL))
791  {
792    WerrorS(usage);
793    return TRUE;
794  }
795
796  const poly syz_2 = (poly) h->Data(); assume (syz_2 != NULL);
797
798  h = h->Next();
799  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
800  {
801    WerrorS(usage);
802    return TRUE;
803  }
804
805  const ideal L = (ideal) h->Data(); assume( IDELEMS(L) > 0 );
806
807
808  h = h->Next();
809  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
810  {
811    WerrorS(usage);
812    return TRUE;
813  }
814
815  const ideal T = (ideal) h->Data();
816
817  assume( IDELEMS(L) == IDELEMS(T) );
818
819  ideal LS = NULL;
820
821  h = h->Next();
822  if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))
823  {
824    LS = (ideal)h->Data();
825    h = h->Next();
826  }
827
828  if( __TAILREDSYZ__ )
829    assume (LS != NULL);
830
831  assume( h == NULL );
832
833  if( __DEBUG__ )
834  {
835    PrintS("SchreyerSyzygyNF(syz_lead, syz_2, L, T, #)::Input: \n");
836
837    PrintS("syz_lead: "); dPrint(syz_lead, r, r, 2);
838    PrintS("syz_2: "); dPrint(syz_2, r, r, 2);
839
840    PrintS("L: "); dPrint(L, r, r, 0);
841    PrintS("T: "); dPrint(T, r, r, 0);
842
843    if( LS == NULL )
844      PrintS("LS: NULL\n");
845    else
846    {
847      PrintS("LS: "); dPrint(LS, r, r, 0);
848    }
849  }
850
851  res->rtyp = VECTOR_CMD;
852  res->data = SchreyerSyzygyNF(syz_lead,
853                               (syz_2!=NULL)? p_Copy(syz_2, r): syz_2, L, T, LS, attributes);
854
855  if( __DEBUG__ )
856  {
857    PrintS("SchreyerSyzygyNF::Output: ");
858
859    dPrint((poly)res->data, r, r, 2);
860  }
861
862
863  return FALSE;
864}
865
866
867
868/// proc SSReduceTerm(poly m, def t, def syzterm, def L, def T, list #)
869static BOOLEAN _ReduceTerm(leftv res, leftv h)
870{
871  const SchreyerSyzygyComputationFlags attributes(currRingHdl);
872
873  const BOOLEAN __DEBUG__      = attributes.__DEBUG__;
874//  const BOOLEAN __SYZCHECK__   = attributes.__SYZCHECK__;
875//   const BOOLEAN __LEAD2SYZ__   = attributes.__LEAD2SYZ__;
876//   const BOOLEAN __HYBRIDNF__   = attributes.__HYBRIDNF__;
877  const BOOLEAN __TAILREDSYZ__ = attributes.__TAILREDSYZ__;
878
879  const char* usage = "`ReduceTerm(<poly>, <poly/vector>, <vector/0>, <ideal/module>, <ideal/module>[,<module>])` expected";
880  const ring r = attributes.m_rBaseRing;
881
882  NoReturn(res);
883
884  if ((h==NULL) || (h->Typ() !=POLY_CMD) || (h->Data() == NULL))
885  {
886    WerrorS(usage);
887    return TRUE;
888  }
889
890  const poly multiplier = (poly) h->Data(); assume (multiplier != NULL);
891
892
893  h = h->Next();
894  if ((h==NULL) || (h->Typ()!=VECTOR_CMD && h->Typ() !=POLY_CMD) || (h->Data() == NULL))
895  {
896    WerrorS(usage);
897    return TRUE;
898  }
899
900  const poly term4reduction = (poly) h->Data(); assume( term4reduction != NULL );
901
902
903  poly syztermCheck = NULL;
904
905  h = h->Next();
906  if ((h==NULL) || !((h->Typ()==VECTOR_CMD) || (h->Data() == NULL)) )
907  {
908    WerrorS(usage);
909    return TRUE;
910  }
911
912  if(h->Typ()==VECTOR_CMD)
913    syztermCheck = (poly) h->Data();
914
915
916  h = h->Next();
917  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
918  {
919    WerrorS(usage);
920    return TRUE;
921  }
922
923  const ideal L = (ideal) h->Data(); assume( IDELEMS(L) > 0 );
924
925
926  h = h->Next();
927  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
928  {
929    WerrorS(usage);
930    return TRUE;
931  }
932
933  const ideal T = (ideal) h->Data();
934
935  assume( IDELEMS(L) == IDELEMS(T) );
936
937  ideal LS = NULL;
938
939  h = h->Next();
940  if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))
941  {
942    LS = (ideal)h->Data();
943    h = h->Next();
944  }
945
946  if( __TAILREDSYZ__ )
947    assume (LS != NULL);
948
949  assume( h == NULL );
950
951  if( __DEBUG__ )
952  {
953    PrintS("ReduceTerm(m, t, syzterm, L, T, #)::Input: \n");
954
955    PrintS("m: "); dPrint(multiplier, r, r, 2);
956    PrintS("t: "); dPrint(term4reduction, r, r, 2);
957    PrintS("syzterm: "); dPrint(syztermCheck, r, r, 2);
958
959    PrintS("L: "); dPrint(L, r, r, 0);
960    PrintS("T: "); dPrint(T, r, r, 0);
961
962    if( LS == NULL )
963      PrintS("LS: NULL\n");
964    else
965    {
966      PrintS("LS: "); dPrint(LS, r, r, 0);
967    }
968  }
969
970
971  if (__DEBUG__ && syztermCheck != NULL)
972  {
973    const int c = p_GetComp(syztermCheck, r) - 1;
974    assume( c >= 0 && c < IDELEMS(L) );
975
976    const poly p = L->m[c];
977    assume( p != NULL ); assume( pNext(p) == NULL );
978
979    assume( p_EqualPolys(term4reduction, p, r) ); // assume? TODO
980
981
982    poly m = leadmonom(syztermCheck, r);
983    assume( m != NULL ); assume( pNext(m) == NULL );
984
985    assume( p_EqualPolys(multiplier, m, r) ); // assume? TODO
986
987    p_Delete(&m, r);
988
989// NOTE:   leadmonomial(syzterm) == m &&  L[leadcomp(syzterm)] == t
990  }
991
992  res->rtyp = VECTOR_CMD;
993  res->data = ReduceTerm(multiplier, term4reduction, syztermCheck, L, T, LS, attributes);
994
995
996  if( __DEBUG__ )
997  {
998    PrintS("ReduceTerm::Output: ");
999
1000    dPrint((poly)res->data, r, r, 2);
1001  }
1002
1003
1004  return FALSE;
1005}
1006
1007
1008
1009
1010// proc SSTraverseTail(poly m, def @tail, def L, def T, list #)
1011static BOOLEAN _TraverseTail(leftv res, leftv h)
1012{
1013  const SchreyerSyzygyComputationFlags attributes(currRingHdl);
1014
1015  const BOOLEAN __DEBUG__      = attributes.__DEBUG__;
1016//   const BOOLEAN __SYZCHECK__   = attributes.__SYZCHECK__;
1017//   const BOOLEAN __LEAD2SYZ__   = attributes.__LEAD2SYZ__;
1018//   const BOOLEAN __HYBRIDNF__   = attributes.__HYBRIDNF__;
1019  const BOOLEAN __TAILREDSYZ__ = attributes.__TAILREDSYZ__;
1020
1021  const char* usage = "`TraverseTail(<poly>, <poly/vector>, <ideal/module>, <ideal/module>[,<module>])` expected";
1022  const ring r = attributes.m_rBaseRing;
1023
1024  NoReturn(res);
1025
1026  if ((h==NULL) || (h->Typ() !=POLY_CMD) || (h->Data() == NULL))
1027  {
1028    WerrorS(usage);
1029    return TRUE;
1030  }
1031
1032  const poly multiplier = (poly) h->Data(); assume (multiplier != NULL);
1033
1034  h = h->Next();
1035  if ((h==NULL) || (h->Typ()!=VECTOR_CMD && h->Typ() !=POLY_CMD))
1036  {
1037    WerrorS(usage);
1038    return TRUE;
1039  }
1040
1041  const poly tail = (poly) h->Data();
1042
1043  h = h->Next();
1044
1045  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
1046  {
1047    WerrorS(usage);
1048    return TRUE;
1049  }
1050
1051  const ideal L = (ideal) h->Data();
1052
1053  assume( IDELEMS(L) > 0 );
1054
1055  h = h->Next();
1056  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
1057  {
1058    WerrorS(usage);
1059    return TRUE;
1060  }
1061
1062  const ideal T = (ideal) h->Data();
1063
1064  assume( IDELEMS(L) == IDELEMS(T) );
1065
1066  h = h->Next();
1067
1068  ideal LS = NULL;
1069
1070  if ((h != NULL) && (h->Typ() ==MODUL_CMD) && (h->Data() != NULL))
1071  {
1072    LS = (ideal)h->Data();
1073    h = h->Next();
1074  }
1075
1076  if( __TAILREDSYZ__ )
1077    assume (LS != NULL);
1078
1079  assume( h == NULL );
1080
1081  if( __DEBUG__ )
1082  {
1083    PrintS("TraverseTail(m, t, L, T, #)::Input: \n");
1084
1085    PrintS("m: "); dPrint(multiplier, r, r, 2);
1086    PrintS("t: "); dPrint(tail, r, r, 10);
1087
1088    PrintS("L: "); dPrint(L, r, r, 0);
1089    PrintS("T: "); dPrint(T, r, r, 0);
1090
1091    if( LS == NULL )
1092      PrintS("LS: NULL\n");
1093    else
1094    {
1095      PrintS("LS: "); dPrint(LS, r, r, 0);
1096    }
1097  }
1098
1099  res->rtyp = VECTOR_CMD;
1100  res->data = TraverseTail(multiplier, tail, L, T, LS, attributes);
1101
1102
1103  if( __DEBUG__ )
1104  {
1105    PrintS("TraverseTail::Output: ");
1106    dPrint((poly)res->data, r, r, 2);
1107  }
1108
1109  return FALSE;
1110}
1111
1112
1113static BOOLEAN _ComputeResolution(leftv res, leftv h)
1114{
1115  const SchreyerSyzygyComputationFlags attributes(currRingHdl);
1116
1117  const BOOLEAN __DEBUG__      = attributes.__DEBUG__;
1118
1119  const char* usage = "`ComputeResolution(<ideal/module>[,int])` expected";
1120  const ring r = attributes.m_rBaseRing;
1121
1122  NoReturn(res);
1123
1124  // input
1125  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
1126  {
1127    WerrorS(usage);
1128    return TRUE;
1129  }
1130
1131  ideal M = (ideal)(h->CopyD()); // copy for resolution...!???
1132  int size = IDELEMS(M);
1133
1134  assume( size >= 0 );
1135
1136  h = h->Next();
1137
1138  // lead
1139  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
1140  {
1141    WerrorS(usage);
1142    return TRUE;
1143  }
1144
1145  ideal L = (ideal)(h->CopyD()); // no copy!
1146  assume( IDELEMS(L) == size );
1147
1148  h = h->Next();
1149  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
1150  {
1151    WerrorS(usage);
1152    return TRUE;
1153  }
1154
1155  ideal T = (ideal)(h->CopyD()); // no copy!
1156  assume( IDELEMS(T) == size );
1157
1158  h = h->Next();
1159
1160  // length..?
1161  long length = 0;
1162
1163  if ((h!=NULL) && (h->Typ()==INT_CMD))
1164  {
1165    length = (long)(h->Data());
1166    h = h->Next();
1167  }
1168
1169  assume( h == NULL );
1170
1171  if( length <= 0 )
1172    length = 1 + rVar(r);
1173
1174  if( __DEBUG__ )
1175  {
1176    PrintS("ComputeResolution(M, length)::Input: \n");
1177    Print( "starting length: %ld\n", length);
1178    PrintS("M: \n"); dPrint(M, r, r, 0);
1179    PrintS("L=LEAD(M): \n"); dPrint(L, r, r, 1);
1180    PrintS("T=TAIL(M): \n"); dPrint(T, r, r, 0);
1181  }
1182
1183
1184  syStrategy _res=(syStrategy)omAlloc0(sizeof(ssyStrategy));
1185
1186//  class ssyStrategy; typedef ssyStrategy * syStrategy;
1187//  typedef ideal *            resolvente;
1188
1189  _res->length = length + 1; // index + 1;
1190  _res->fullres = (resolvente)omAlloc0((_res->length)*sizeof(ideal));
1191  int index = 0;
1192  _res->fullres[index++] = M;
1193
1194//  if (attributes.__TREEOUTPUT__)
1195//    Print("{ \"RESOLUTION: HYBRIDNF:%d, TAILREDSYZ: %d, LEAD2SYZ: %d, IGNORETAILS: %d\": [\n", attributes.__HYBRIDNF__, attributes.__TAILREDSYZ__, attributes.__LEAD2SYZ__, attributes.__IGNORETAILS__);
1196
1197  while( (!idIs0(L)) && (index < length))
1198  {
1199    attributes.nextSyzygyLayer();
1200    ideal LL, TT;
1201
1202    ComputeSyzygy(L, T, LL, TT, attributes);
1203
1204    if( __DEBUG__ )
1205    {
1206      Print("ComputeResolution()::Separated Syzygy[%d]: \n", index);
1207      PrintS("LL: \n"); dPrint(LL, r, r, 1);
1208      PrintS("TT: \n"); dPrint(TT, r, r, 2);
1209    }
1210    size = IDELEMS(LL);
1211
1212    assume( size == IDELEMS(TT) );
1213
1214    id_Delete(&L, r); id_Delete(&T, r);
1215
1216    L = LL; T = TT;
1217
1218    // id_Add(T, L, r);
1219    M = idInit(size, 0);
1220    for( int i = size-1; i >= 0; i-- )
1221    {
1222      M->m[i] = p_Add_q(p_Copy(T->m[i], r), p_Copy(L->m[i], r), r); // TODO: :(((
1223    }
1224    M->rank = id_RankFreeModule(M, r);
1225
1226    if( __DEBUG__ )
1227    {
1228      Print("ComputeResolution()::Restored Syzygy[%d]: \n", index);
1229      PrintS("M = LL + TT: \n"); dPrint(M, r, r, 0);
1230    }
1231
1232    _res->fullres[index++] = M; // ???
1233  }
1234//  if (attributes.__TREEOUTPUT__)
1235//    PrintS("] }\n");
1236
1237  id_Delete(&L, r); id_Delete(&T, r);
1238
1239  res->data = _res;
1240  res->rtyp = RESOLUTION_CMD;
1241
1242  if( __DEBUG__ )
1243  {
1244    Print("ComputeResolution::Output (index: %d): ", index);
1245//    class sleftv; typedef sleftv * leftv;
1246    sleftv _h;
1247    DetailedPrint(&_h, res);
1248  }
1249
1250//  omFreeSize(_res, sizeof(ssyStrategy));
1251
1252  return FALSE;
1253
1254}
1255
1256
1257/// module (LL, TT) = SSComputeSyzygy(L, T);
1258/// Compute Syz(L ++ T) = N = LL ++ TT
1259// proc SSComputeSyzygy(def L, def T)
1260static BOOLEAN _ComputeSyzygy(leftv res, leftv h)
1261{
1262  const SchreyerSyzygyComputationFlags attributes(currRingHdl);
1263
1264  const BOOLEAN __DEBUG__      = attributes.__DEBUG__;
1265//   const BOOLEAN __SYZCHECK__   = attributes.__SYZCHECK__;
1266//   const BOOLEAN __LEAD2SYZ__   = attributes.__LEAD2SYZ__;
1267//   const BOOLEAN __HYBRIDNF__   = attributes.__HYBRIDNF__;
1268//   const BOOLEAN __TAILREDSYZ__ = attributes.__TAILREDSYZ__;
1269
1270  const char* usage = "`ComputeSyzygy(<ideal/module>, <ideal/module>)` expected";
1271  const ring r = attributes.m_rBaseRing;
1272
1273  NoReturn(res);
1274
1275  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
1276  {
1277    WerrorS(usage);
1278    return TRUE;
1279  }
1280
1281  const ideal L = (ideal) h->Data();
1282
1283  assume( IDELEMS(L) > 0 );
1284
1285  h = h->Next();
1286  if ((h==NULL) || (h->Typ()!=IDEAL_CMD && h->Typ() !=MODUL_CMD) || (h->Data() == NULL))
1287  {
1288    WerrorS(usage);
1289    return TRUE;
1290  }
1291
1292  const ideal T = (ideal) h->Data();
1293  assume( IDELEMS(L) == IDELEMS(T) );
1294
1295
1296  h = h->Next(); assume( h == NULL );
1297
1298  if( __DEBUG__ )
1299  {
1300    PrintS("ComputeSyzygy(L, T)::Input: \n");
1301
1302    PrintS("L: "); dPrint(L, r, r, 0);
1303    PrintS("T: "); dPrint(T, r, r, 0);
1304  }
1305
1306  ideal LL, TT;
1307
1308  ComputeSyzygy(L, T, LL, TT, attributes);
1309
1310  lists l = (lists)omAllocBin(slists_bin); l->Init(2);
1311
1312  l->m[0].rtyp = MODUL_CMD; l->m[0].data = reinterpret_cast<void *>(LL);
1313
1314  l->m[1].rtyp = MODUL_CMD; l->m[1].data = reinterpret_cast<void *>(TT);
1315
1316  res->data = l; res->rtyp = LIST_CMD;
1317
1318  if( __DEBUG__ )
1319  {
1320    PrintS("ComputeSyzygy::Output: ");
1321    dPrint(LL, r, r, 0);
1322    dPrint(TT, r, r, 0);
1323  }
1324
1325  return FALSE;
1326
1327}
1328
1329/// Get leading term without a module component
1330static BOOLEAN _leadmonom(leftv res, leftv h)
1331{
1332  NoReturn(res);
1333
1334  if ((h!=NULL) && (h->Typ()==VECTOR_CMD || h->Typ()==POLY_CMD) && (h->Data() != NULL))
1335  {
1336    const ring r = currRing;
1337    const poly p = (poly)(h->Data());
1338
1339    res->data = reinterpret_cast<void *>(  leadmonom(p, r) );
1340    res->rtyp = POLY_CMD;
1341
1342    return FALSE;
1343  }
1344
1345  WerrorS("`leadmonom(<poly/vector>)` expected");
1346  return TRUE;
1347}
1348
1349/// Get leading component
1350static BOOLEAN leadcomp(leftv res, leftv h)
1351{
1352  NoReturn(res);
1353
1354  if ((h!=NULL) && (h->Typ()==VECTOR_CMD || h->Typ()==POLY_CMD))
1355  {
1356    const ring r = currRing;
1357
1358    const poly p = (poly)(h->Data());
1359
1360    if (p != NULL )
1361    {
1362      assume( p != NULL );
1363      p_LmTest(p, r);
1364
1365      const unsigned long iComp = p_GetComp(p, r);
1366
1367  //    assume( iComp > 0 ); // p is a vector
1368
1369      res->data = reinterpret_cast<void *>(jjLONG2N(iComp));
1370    } else
1371      res->data = reinterpret_cast<void *>(jjLONG2N(0));
1372
1373
1374    res->rtyp = BIGINT_CMD;
1375    return FALSE;
1376  }
1377
1378  WerrorS("`leadcomp(<poly/vector>)` expected");
1379  return TRUE;
1380}
1381
1382
1383
1384
1385/// Get raw leading exponent vector
1386static BOOLEAN leadrawexp(leftv res, leftv h)
1387{
1388  NoReturn(res);
1389
1390  if ((h!=NULL) && (h->Typ()==VECTOR_CMD || h->Typ()==POLY_CMD) && (h->Data() != NULL))
1391  {
1392    const ring r = currRing;
1393    const poly p = (poly)(h->Data());
1394
1395    assume( p != NULL );
1396    p_LmTest(p, r);
1397
1398    const int iExpSize = r->ExpL_Size;
1399
1400//    intvec *iv = new intvec(iExpSize);
1401
1402    lists l=(lists)omAllocBin(slists_bin);
1403    l->Init(iExpSize);
1404
1405    for(int i = iExpSize-1; i >= 0; i--)
1406    {
1407      l->m[i].rtyp = BIGINT_CMD;
1408      l->m[i].data = reinterpret_cast<void *>(jjLONG2N(p->exp[i])); // longs...
1409    }
1410
1411    res->rtyp = LIST_CMD; // list of bigints
1412    res->data = reinterpret_cast<void *>(l);
1413    return FALSE;
1414  }
1415
1416  WerrorS("`leadrawexp(<poly/vector>)` expected");
1417  return TRUE;
1418}
1419
1420
1421/// Endowe the current ring with additional (leading) Syz-component ordering
1422static BOOLEAN MakeSyzCompOrdering(leftv res, leftv /*h*/)
1423{
1424
1425  NoReturn(res);
1426
1427  //    res->data = rCurrRingAssure_SyzComp(); // changes current ring! :(
1428  res->data = reinterpret_cast<void *>(rAssure_SyzComp(currRing, TRUE));
1429  res->rtyp = RING_CMD; // return new ring!
1430  // QRING_CMD?
1431
1432  return FALSE;
1433}
1434
1435
1436/// Same for Induced Schreyer ordering (ordering on components is defined by sign!)
1437static BOOLEAN MakeInducedSchreyerOrdering(leftv res, leftv h)
1438{
1439
1440  NoReturn(res);
1441
1442  int sign = 1;
1443  if ((h!=NULL) && (h->Typ()==INT_CMD))
1444  {
1445    const int s = (int)((long)(h->Data()));
1446
1447    if( s != -1 && s != 1 )
1448    {
1449      WerrorS("`MakeInducedSchreyerOrdering(<int>)` called with wrong integer argument (must be +-1)!");
1450      return TRUE;
1451    }
1452
1453    sign = s;
1454  }
1455
1456  assume( sign == 1 || sign == -1 );
1457  res->data = reinterpret_cast<void *>(rAssure_InducedSchreyerOrdering(currRing, TRUE, sign));
1458  res->rtyp = RING_CMD; // return new ring!
1459  // QRING_CMD?
1460  return FALSE;
1461}
1462
1463
1464/// Returns old SyzCompLimit, can set new limit
1465static BOOLEAN SetSyzComp(leftv res, leftv h)
1466{
1467  NoReturn(res);
1468
1469  const ring r = currRing;
1470
1471  if( !rIsSyzIndexRing(r) )
1472  {
1473    WerrorS("`SetSyzComp(<int>)` called on incompatible ring (not created by 'MakeSyzCompOrdering'!)");
1474    return TRUE;
1475  }
1476
1477  res->rtyp = INT_CMD;
1478  res->data = reinterpret_cast<void *>(rGetCurrSyzLimit(r)); // return old syz limit
1479
1480  if ((h!=NULL) && (h->Typ()==INT_CMD))
1481  {
1482    const int iSyzComp = (int)reinterpret_cast<long>(h->Data());
1483    assume( iSyzComp > 0 );
1484    rSetSyzComp(iSyzComp, currRing);
1485  }
1486
1487  return FALSE;
1488}
1489
1490/// ?
1491static BOOLEAN GetInducedData(leftv res, leftv h)
1492{
1493  NoReturn(res);
1494
1495  const ring r = currRing;
1496
1497  int p = 0; // which IS-block? p^th!
1498
1499  if ((h!=NULL) && (h->Typ()==INT_CMD))
1500  {
1501    p = (int)((long)(h->Data())); h=h->next;
1502    assume(p >= 0);
1503  }
1504
1505  const int pos = rGetISPos(p, r);
1506
1507  if(  /*(*/ -1 == pos /*)*/  )
1508  {
1509    WerrorS("`GetInducedData([int])` called on incompatible ring (not created by 'MakeInducedSchreyerOrdering'!)");
1510    return TRUE;
1511  }
1512
1513
1514  const int iLimit = r->typ[pos].data.is.limit;
1515  const ideal F = r->typ[pos].data.is.F;
1516  ideal FF = id_Copy(F, r);
1517
1518
1519
1520  lists l=(lists)omAllocBin(slists_bin);
1521  l->Init(2);
1522
1523  l->m[0].rtyp = INT_CMD;
1524  l->m[0].data = reinterpret_cast<void *>(iLimit);
1525
1526
1527  //        l->m[1].rtyp = MODUL_CMD;
1528
1529  if( idIsModule(FF, r) )
1530  {
1531    l->m[1].rtyp = MODUL_CMD;
1532
1533    //          Print("before: %d\n", FF->nrows);
1534    //          FF->nrows = id_RankFreeModule(FF, r); // ???
1535    //          Print("after: %d\n", FF->nrows);
1536  }
1537  else
1538    l->m[1].rtyp = IDEAL_CMD;
1539
1540  l->m[1].data = reinterpret_cast<void *>(FF);
1541
1542  res->rtyp = LIST_CMD; // list of int/module
1543  res->data = reinterpret_cast<void *>(l);
1544
1545  return FALSE;
1546
1547}
1548
1549
1550/* // the following turned out to be unnecessary...
1551/// Finds p^th AM ordering, and returns its position in r->typ[] AND
1552/// corresponding &r->wvhdl[]
1553/// returns FALSE if something went wrong!
1554/// p - starts with 0!
1555BOOLEAN rGetAMPos(const ring r, const int p, int &typ_pos, int &wvhdl_pos, const BOOLEAN bSearchWvhdl = FALSE)
1556{
1557#if MYTEST
1558  Print("rGetAMPos(p: %d...)\nF:", p);
1559  PrintLn();
1560#endif
1561  typ_pos = -1;
1562  wvhdl_pos = -1;
1563
1564  if (r->typ==NULL)
1565    return FALSE;
1566
1567
1568  int j = p; // Which IS record to use...
1569  for( int pos = 0; pos < r->OrdSize; pos++ )
1570    if( r->typ[pos].ord_typ == ro_am)
1571      if( j-- == 0 )
1572      {
1573        typ_pos = pos;
1574
1575        if( bSearchWvhdl )
1576        {
1577          const int nblocks = rBlocks(r) - 1;
1578          const int* w = r->typ[pos].data.am.weights; // ?
1579
1580          for( pos = 0; pos <= nblocks; pos ++ )
1581            if (r->order[pos] == ringorder_am)
1582              if( r->wvhdl[pos] == w )
1583              {
1584                wvhdl_pos = pos;
1585                break;
1586              }
1587          if (wvhdl_pos < 0)
1588            return FALSE;
1589
1590          assume(wvhdl_pos >= 0);
1591        }
1592        assume(typ_pos >= 0);
1593        return TRUE;
1594      }
1595
1596  return FALSE;
1597}
1598
1599// // ?
1600// static BOOLEAN GetAMData(leftv res, leftv h)
1601// {
1602//   NoReturn(res);
1603//
1604//   const ring r = currRing;
1605//
1606//   int p = 0; // which IS-block? p^th!
1607//
1608//   if ((h!=NULL) && (h->Typ()==INT_CMD))
1609//     p = (int)((long)(h->Data())); h=h->next;
1610//
1611//   assume(p >= 0);
1612//
1613//   int d, w;
1614//
1615//   if( !rGetAMPos(r, p, d, w, TRUE) )
1616//   {
1617//     Werror("`GetAMData([int])`: no %d^th _am block-ordering!", p);
1618//     return TRUE;
1619//   }
1620//
1621//   assume( r->typ[d].ord_typ == ro_am );
1622//   assume( r->order[w] == ringorder_am );
1623//
1624//
1625//   const short start = r->typ[d].data.am.start;  // bounds of ordering (in E)
1626//   const short end = r->typ[d].data.am.end;
1627//   const short len_gen = r->typ[d].data.am.len_gen; // i>len_gen: weight(gen(i)):=0
1628//   const int *weights = r->typ[d].data.am.weights; // pointers into wvhdl field of length (end-start+1) + len_gen
1629//   // contents w_1,... w_n, len, mod_w_1, .. mod_w_len, 0
1630//
1631//   assume( weights == r->wvhdl[w] );
1632//
1633//
1634//   lists l=(lists)omAllocBin(slists_bin);
1635//   l->Init(2);
1636//
1637//   const short V = end-start+1;
1638//   intvec* ww_vars = new intvec(V);
1639//   intvec* ww_gens = new intvec(len_gen);
1640//
1641//   for (int i = 0; i < V; i++ )
1642//     (*ww_vars)[i] = weights[i];
1643//
1644//   assume( weights[V] == len_gen );
1645//
1646//   for (int i = 0; i < len_gen; i++ )
1647//     (*ww_gens)[i] = weights[i - V - 1];
1648//
1649//
1650//   l->m[0].rtyp = INTVEC_CMD;
1651//   l->m[0].data = reinterpret_cast<void *>(ww_vars);
1652//
1653//   l->m[1].rtyp = INTVEC_CMD;
1654//   l->m[1].data = reinterpret_cast<void *>(ww_gens);
1655//
1656//
1657//   return FALSE;
1658//
1659// }
1660*/
1661
1662/// Returns old SyzCompLimit, can set new limit
1663static BOOLEAN SetInducedReferrence(leftv res, leftv h)
1664{
1665  NoReturn(res);
1666
1667  const ring r = currRing;
1668
1669  if( !( (h!=NULL) && ( (h->Typ()==IDEAL_CMD) || (h->Typ()==MODUL_CMD))) )
1670  {
1671    WerrorS("`SetInducedReferrence(<ideal/module>, [int[, int]])` expected");
1672    return TRUE;
1673  }
1674
1675  const ideal F = (ideal)h->Data(); ; // No copy!
1676  h=h->next;
1677
1678  int rank = 0;
1679
1680  if ((h!=NULL) && (h->Typ()==INT_CMD))
1681  {
1682    rank = (int)((long)(h->Data())); h=h->next;
1683    assume(rank >= 0);
1684  } else
1685    rank = id_RankFreeModule(F, r); // Starting syz-comp (1st: i+1)
1686
1687  int p = 0; // which IS-block? p^th!
1688
1689  if ((h!=NULL) && (h->Typ()==INT_CMD))
1690  {
1691    p = (int)((long)(h->Data())); h=h->next;
1692    assume(p >= 0);
1693  }
1694
1695  const int posIS = rGetISPos(p, r);
1696
1697  if(  /*(*/ -1 == posIS /*)*/  )
1698  {
1699    WerrorS("`SetInducedReferrence(<ideal/module>, [int[, int]])` called on incompatible ring (not created by 'MakeInducedSchreyerOrdering'!)");
1700    return TRUE;
1701  }
1702
1703
1704
1705  // F & componentWeights belong to that ordering block of currRing now:
1706  rSetISReference(r, F, rank, p); // F will be copied!
1707  return FALSE;
1708}
1709
1710
1711//    F = ISUpdateComponents( F, V, MIN );
1712//    // replace gen(i) -> gen(MIN + V[i-MIN]) for all i > MIN in all terms from F!
1713static BOOLEAN ISUpdateComponents(leftv res, leftv h)
1714{
1715  NoReturn(res);
1716
1717  PrintS("ISUpdateComponents:.... \n");
1718
1719  if ((h!=NULL) && (h->Typ()==MODUL_CMD))
1720  {
1721    ideal F = (ideal)h->Data(); ; // No copy!
1722    h=h->next;
1723
1724    if ((h!=NULL) && (h->Typ()==INTVEC_CMD))
1725    {
1726      const intvec* const V = (const intvec* const) h->Data();
1727      h=h->next;
1728
1729      if ((h!=NULL) && (h->Typ()==INT_CMD))
1730      {
1731        const int MIN = (int)((long)(h->Data()));
1732
1733        pISUpdateComponents(F, V, MIN, currRing);
1734        return FALSE;
1735      }
1736    }
1737  }
1738
1739  WerrorS("`ISUpdateComponents(<module>, intvec, int)` expected");
1740  return TRUE;
1741}
1742
1743
1744/// NF using length
1745static BOOLEAN reduce_syz(leftv res, leftv h)
1746{
1747  // const ring r = currRing;
1748
1749  if ( !( (h!=NULL) && (h->Typ()==VECTOR_CMD || h->Typ()==POLY_CMD) ) )
1750  {
1751    WerrorS("`reduce_syz(<poly/vector>!, <ideal/module>, <int>, [int])` expected");
1752    return TRUE;
1753  }
1754
1755  res->rtyp = h->Typ();
1756  const poly v = reinterpret_cast<poly>(h->Data());
1757  h=h->next;
1758
1759  if ( !( (h!=NULL) && (h->Typ()==MODUL_CMD || h->Typ()==IDEAL_CMD ) ) )
1760  {
1761    WerrorS("`reduce_syz(<poly/vector>, <ideal/module>!, <int>, [int])` expected");
1762    return TRUE;
1763  }
1764
1765  assumeStdFlag(h);
1766  const ideal M = reinterpret_cast<ideal>(h->Data()); h=h->next;
1767
1768
1769  if ( !( (h!=NULL) && (h->Typ()== INT_CMD)  ) )
1770  {
1771    WerrorS("`reduce_syz(<poly/vector>, <ideal/module>, <int>!, [int])` expected");
1772    return TRUE;
1773  }
1774
1775  const int iSyzComp = (int)((long)(h->Data())); h=h->next;
1776
1777  int iLazyReduce = 0;
1778
1779  if ( ( (h!=NULL) && (h->Typ()== INT_CMD)  ) )
1780    iLazyReduce = (int)((long)(h->Data()));
1781
1782  res->data = (void *)kNFLength(M, currRing->qideal, v, iSyzComp, iLazyReduce); // NOTE: currRing :(
1783  return FALSE;
1784}
1785
1786
1787/// Get raw syzygies (idPrepare)
1788static BOOLEAN idPrepare(leftv res, leftv h)
1789{
1790  //        extern int rGetISPos(const int p, const ring r);
1791
1792  const ring r = currRing;
1793
1794  const bool isSyz = rIsSyzIndexRing(r);
1795  const int posIS = rGetISPos(0, r);
1796
1797
1798  if ( !( (h!=NULL) && (h->Typ()==MODUL_CMD) && (h->Data() != NULL) ) )
1799  {
1800    WerrorS("`idPrepare(<module>)` expected");
1801    return TRUE;
1802  }
1803
1804  const ideal I = reinterpret_cast<ideal>(h->Data());
1805
1806  assume( I != NULL );
1807  idTest(I);
1808
1809  int iComp = -1;
1810
1811  h=h->next;
1812  if ( (h!=NULL) && (h->Typ()==INT_CMD) )
1813  {
1814    iComp = (int)((long)(h->Data()));
1815  } else
1816  {
1817      if( (!isSyz) && (-1 == posIS) )
1818      {
1819        WerrorS("`idPrepare(<...>)` called on incompatible ring (not created by 'MakeSyzCompOrdering' or 'MakeInducedSchreyerOrdering'!)");
1820        return TRUE;
1821      }
1822
1823    if( isSyz )
1824      iComp = rGetCurrSyzLimit(r);
1825    else
1826      iComp = id_RankFreeModule(r->typ[posIS].data.is.F, r); // ;
1827  }
1828
1829  assume(iComp >= 0);
1830
1831
1832  intvec* w = reinterpret_cast<intvec *>(atGet(h, "isHomog", INTVEC_CMD));
1833  tHomog hom = testHomog;
1834
1835  //           int add_row_shift = 0;
1836  //
1837  if (w!=NULL)
1838  {
1839    w = ivCopy(w);
1840  //             add_row_shift = ww->min_in();
1841  //
1842  //             (*ww) -= add_row_shift;
1843  //
1844  //             if (idTestHomModule(I, currRing->qideal, ww))
1845  //             {
1846    hom = isHomog;
1847  //               w = ww;
1848  //             }
1849  //             else
1850  //             {
1851  //               //WarnS("wrong weights");
1852  //               delete ww;
1853  //               w = NULL;
1854  //               hom=testHomog;
1855  //             }
1856  }
1857
1858
1859  // computes syzygies of h1,
1860  // works always in a ring with ringorder_s
1861  // NOTE: rSetSyzComp(syzcomp) should better be called beforehand
1862  //        ideal idPrepare (ideal  h1, tHomog hom, int syzcomp, intvec **w);
1863
1864  ideal J = // idPrepare( I, hom, iComp, &w);
1865           kStd(I, currRing->qideal, hom, &w, NULL, iComp);
1866
1867  idTest(J);
1868
1869  if (w!=NULL)
1870    atSet(res, omStrDup("isHomog"), w, INTVEC_CMD);
1871  //             if (w!=NULL) delete w;
1872
1873  res->rtyp = MODUL_CMD;
1874  res->data = reinterpret_cast<void *>(J);
1875  return FALSE;
1876}
1877
1878/// Get raw syzygies (idPrepare)
1879static BOOLEAN _p_Content(leftv res, leftv h)
1880{
1881  if ( !( (h!=NULL) && (h->Typ()==POLY_CMD) && (h->Data() != NULL) ) )
1882  {
1883    WerrorS("`p_Content(<poly-var>)` expected");
1884    return TRUE;
1885  }
1886
1887
1888  const poly p = reinterpret_cast<poly>(h->Data());
1889
1890
1891  pTest(p);  pWrite(p); PrintLn();
1892
1893
1894  p_Content( p, currRing);
1895
1896  pTest(p);
1897  pWrite(p); PrintLn();
1898
1899  NoReturn(res);
1900  return FALSE;
1901}
1902
1903static BOOLEAN _m2_end(leftv res, leftv h)
1904{
1905  int ret = 0;
1906
1907  if ( (h!=NULL) && (h->Typ()!=INT_CMD) )
1908  {
1909    WerrorS("`m2_end([<int>])` expected");
1910    return TRUE;
1911  }
1912  ret = (int)(long)(h->Data());
1913
1914  m2_end( ret );
1915
1916  NoReturn(res);
1917  return FALSE;
1918}
1919
1920
1921
1922END_NAMESPACE
1923
1924extern "C" int SI_MOD_INIT(syzextra)(SModulFunctions* psModulFunctions) 
1925{
1926
1927#define ADD(C,D,E) \
1928  psModulFunctions->iiAddCproc((currPack->libname? currPack->libname: ""), (char*)C, D, E);
1929
1930
1931// #define ADD(A,B,C,D,E) ADD0(iiAddCproc, "", C, D, E)
1932
1933//#define ADD0(A,B,C,D,E) A(B, (char*)C, D, E)
1934// #define ADD(A,B,C,D,E) ADD0(A->iiAddCproc, B, C, D, E)
1935  ADD("ClearContent", FALSE, _ClearContent);
1936  ADD("ClearDenominators", FALSE, _ClearDenominators);
1937
1938  ADD("m2_end", FALSE, _m2_end);
1939
1940  ADD("DetailedPrint", FALSE, DetailedPrint);
1941  ADD("leadmonomial", FALSE, _leadmonom);
1942  ADD("leadcomp", FALSE, leadcomp);
1943  ADD("leadrawexp", FALSE, leadrawexp);
1944
1945  ADD("ISUpdateComponents", FALSE, ISUpdateComponents);
1946  ADD("SetInducedReferrence", FALSE, SetInducedReferrence);
1947  ADD("GetInducedData", FALSE, GetInducedData);
1948  ADD("SetSyzComp", FALSE, SetSyzComp);
1949  ADD("MakeInducedSchreyerOrdering", FALSE, MakeInducedSchreyerOrdering);
1950  ADD("MakeSyzCompOrdering", FALSE, MakeSyzCompOrdering);
1951
1952  ADD("ProfilerStart", FALSE, _ProfilerStart);
1953  ADD("ProfilerStop",  FALSE, _ProfilerStop );
1954
1955  ADD("noop", FALSE, noop);
1956  ADD("idPrepare", FALSE, idPrepare);
1957  ADD("reduce_syz", FALSE, reduce_syz);
1958
1959  ADD("p_Content", FALSE, _p_Content);
1960
1961  ADD("Tail", FALSE, Tail);
1962
1963  ADD("ComputeLeadingSyzygyTerms", FALSE, _ComputeLeadingSyzygyTerms);
1964  ADD("Compute2LeadingSyzygyTerms", FALSE, _Compute2LeadingSyzygyTerms);
1965
1966  ADD("Sort_c_ds", FALSE, _Sort_c_ds);
1967  ADD("FindReducer", FALSE, _FindReducer);
1968
1969
1970  ADD("ReduceTerm", FALSE, _ReduceTerm);
1971  ADD("TraverseTail", FALSE, _TraverseTail);
1972
1973
1974  ADD("SchreyerSyzygyNF", FALSE, _SchreyerSyzygyNF);
1975  ADD("ComputeSyzygy", FALSE, _ComputeSyzygy);
1976
1977  ADD("ComputeResolution", FALSE, _ComputeResolution);
1978//  ADD("GetAMData", FALSE, GetAMData);
1979
1980  //  ADD("", FALSE, );
1981
1982#undef ADD
1983  return MAX_TOK;
1984}
Note: See TracBrowser for help on using the repository browser.