source: git/dyn_modules/syzextra/syzextra.cc @ 204092

spielwiese
Last change on this file since 204092 was 204092, checked in by Oleksandr Motsak <motsak@…>, 12 years ago
moved/separated new functions related to Schreyer Syzygy computation chg: prefixed corresponding wrappers with underscore due to interpreter registratrar' general expectation
  • Property mode set to 100644
File size: 17.1 KB
Line 
1// -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2/*****************************************************************************\
3 * Computer Algebra System SINGULAR   
4\*****************************************************************************/
5/** @file syzextra.cc
6 *
7 * Here we implement the Computation of Syzygies
8 *
9 * ABSTRACT: Computation of Syzygies due to Schreyer
10 *
11 * @author Oleksandr Motsak
12 *
13 **/
14/*****************************************************************************/
15
16// include header file
17#include <kernel/mod2.h>
18
19#include "syzextra.h"
20
21#include "DebugPrint.h"
22
23#include <omalloc/omalloc.h>
24
25#include <misc/intvec.h>
26#include <misc/options.h>
27
28#include <coeffs/coeffs.h>
29
30#include <polys/monomials/p_polys.h>
31#include <polys/monomials/ring.h>
32
33#include <kernel/kstd1.h>
34#include <kernel/polys.h>
35#include <kernel/syz.h>
36#include <kernel/ideals.h>
37
38
39
40#include <Singular/tok.h>
41#include <Singular/ipid.h>
42#include <Singular/lists.h>
43#include <Singular/attrib.h>
44
45#include <Singular/ipid.h> 
46#include <Singular/ipshell.h> // For iiAddCproc
47
48#include <stdio.h>
49#include <stdlib.h>
50#include <string.h>
51
52// USING_NAMESPACE_SINGULARXX;
53USING_NAMESPACE( SINGULARXXNAME :: DEBUG )
54
55
56BEGIN_NAMESPACE_SINGULARXX     BEGIN_NAMESPACE(SYZEXTRA)
57
58BEGIN_NAMESPACE(SORT_c_ds)
59
60
61#ifdef _GNU_SOURCE
62static int cmp_c_ds(const void *p1, const void *p2, void *R)
63{
64#else
65static int cmp_c_ds(const void *p1, const void *p2)
66{
67  void *R = currRing; 
68#endif
69
70  const int YES = 1;
71  const int NO = -1;
72
73  const ring r =  (const ring) R; // TODO/NOTE: the structure is known: C, lp!!!
74
75  assume( r == currRing );
76
77  const poly a = *(const poly*)p1;
78  const poly b = *(const poly*)p2;
79
80  assume( a != NULL );
81  assume( b != NULL );
82
83  assume( p_LmTest(a, r) );
84  assume( p_LmTest(b, r) );
85
86
87  const signed long iCompDiff = p_GetComp(a, r) - p_GetComp(b, r);
88
89  // TODO: test this!!!!!!!!!!!!!!!!
90
91  //return -( compare (c, qsorts) )
92
93  const int __DEBUG__ = 0;
94
95#ifndef NDEBUG
96  if( __DEBUG__ )
97  {
98    PrintS("cmp_c_ds: a, b: \np1: "); dPrint(a, r, r, 2);
99    PrintS("b: "); dPrint(b, r, r, 2);
100    PrintLn();
101  }
102#endif
103
104
105  if( iCompDiff > 0 )
106    return YES;
107
108  if( iCompDiff < 0 )
109    return  NO;
110
111  assume( iCompDiff == 0 );
112
113  const signed long iDegDiff = p_Totaldegree(a, r) - p_Totaldegree(b, r);
114
115  if( iDegDiff > 0 )
116    return YES;
117
118  if( iDegDiff < 0 )
119    return  NO;
120
121  assume( iDegDiff == 0 );
122
123#ifndef NDEBUG
124  if( __DEBUG__ )
125  {
126    PrintS("cmp_c_ds: a & b have the same comp & deg! "); PrintLn();
127  }
128#endif
129
130  for (int v = rVar(r); v > 0; v--)
131  {
132    assume( v > 0 );
133    assume( v <= rVar(r) );
134
135    const signed int d = p_GetExp(a, v, r) - p_GetExp(b, v, r);
136
137    if( d > 0 )
138      return YES;
139
140    if( d < 0 )
141      return NO;
142
143    assume( d == 0 );
144  }
145
146  return 0; 
147}
148
149END_NAMESPACE
150/* namespace SORT_c_ds */
151
152/// return a new term: leading coeff * leading monomial of p
153/// with 0 leading component!
154poly leadmonom(const poly p, const ring r)
155{
156  poly m = NULL;
157
158  if( p != NULL )
159  {
160    assume( p != NULL );
161    assume( p_LmTest(p, r) );
162
163    m = p_LmInit(p, r);
164    p_SetCoeff0(m, n_Copy(p_GetCoeff(p, r), r), r);
165
166    p_SetComp(m, 0, r);
167    p_Setm(m, r);
168
169    assume( p_GetComp(m, r) == 0 );
170    assume( m != NULL );
171    assume( pNext(m) == NULL );
172    assume( p_LmTest(m, r) );
173  }
174
175  return m;
176}
177
178
179   
180poly p_Tail(const poly p, const ring r)
181{
182  if( p == NULL)
183    return NULL;
184  else
185    return p_Copy( pNext(p), r );
186}
187
188
189ideal id_Tail(const ideal id, const ring r)
190{
191  if( id == NULL)
192    return NULL;
193
194  const ideal newid = idInit(IDELEMS(id),id->rank);
195 
196  for (int i=IDELEMS(id) - 1; i >= 0; i--)
197    newid->m[i] = p_Tail( id->m[i], r );
198
199  newid->rank = id_RankFreeModule(newid, currRing);
200
201  return newid; 
202}
203
204
205
206void Sort_c_ds(const ideal id, const ring r)
207{
208  const int sizeNew = IDELEMS(id);
209
210#ifdef _GNU_SOURCE
211#define qsort_my(m, s, ss, r, cmp) qsort_r(m, s, ss, cmp, r)
212#else
213#define qsort_my(m, s, ss, r, cmp) qsort_r(m, s, ss, cmp)
214#endif
215 
216  if( sizeNew >= 2 )
217    qsort_my(id->m, sizeNew, sizeof(poly), r, SORT_c_ds::cmp_c_ds);
218
219#undef qsort_my
220
221  id->rank = id_RankFreeModule(id, r);
222}
223
224
225
226ideal ComputeLeadingSyzygyTerms(const ideal& id, const ring r)
227{
228  // 1. set of components S?
229  // 2. for each component c from S: set of indices of leading terms
230  // with this component?
231  // 3. short exp. vectors for each leading term?
232
233  const int size = IDELEMS(id);
234
235  if( size < 2 )
236  {
237    const ideal newid = idInit(1, 0); newid->m[0] = NULL; // zero ideal...       
238    return newid;
239  }
240
241
242  // TODO/NOTE: input is supposed to be (reverse-) sorted wrt "(c,ds)"!??
243
244  // components should come in groups: count elements in each group
245  // && estimate the real size!!!
246
247
248  // use just a vector instead???
249  const ideal newid = idInit( (size * (size-1))/2, size); // maximal size: ideal case!
250
251  int k = 0;
252
253  for (int j = 0; j < size; j++)
254  {
255    const poly p = id->m[j];
256    assume( p != NULL );
257    const int  c = p_GetComp(p, r);
258
259    for (int i = j - 1; i >= 0; i--)
260    {
261      const poly pp = id->m[i];
262      assume( pp != NULL );
263      const int  cc = p_GetComp(pp, r);
264
265      if( c != cc )
266        continue;
267
268      const poly m = p_Init(r); // p_New???
269
270      // m = LCM(p, pp) / p! // TODO: optimize: knowing the ring structure: (C/lp)!
271      for (int v = rVar(r); v > 0; v--)
272      {
273        assume( v > 0 );
274        assume( v <= rVar(r) );
275
276        const short e1 = p_GetExp(p , v, r);
277        const short e2 = p_GetExp(pp, v, r);
278
279        if( e1 >= e2 )
280          p_SetExp(m, v, 0, r);
281        else
282          p_SetExp(m, v, e2 - e1, r);
283
284      }
285
286      assume( (j > i) && (i >= 0) );
287
288      p_SetComp(m, j + 1, r);
289      pNext(m) = NULL;
290      p_SetCoeff0(m, n_Init(1, r->cf), r); // for later...
291
292      p_Setm(m, r); // should not do anything!!!
293
294      newid->m[k++] = m;
295    }
296  }
297
298//   if( __DEBUG__ && FALSE )
299//   {
300//     PrintS("ComputeLeadingSyzygyTerms::Temp0: \n");
301//     dPrint(newid, r, r, 1);
302//   }
303
304  // the rest of newid is assumed to be zeroes...
305
306  // simplify(newid, 2 + 32)??
307  // sort(newid, "C,ds")[1]???
308  id_DelDiv(newid, r); // #define SIMPL_LMDIV 32
309
310//   if( __DEBUG__ && FALSE )
311//   {
312//     PrintS("ComputeLeadingSyzygyTerms::Temp1: \n");
313//     dPrint(newid, r, r, 1);
314//   }
315
316  idSkipZeroes(newid); // #define SIMPL_NULL 2
317
318//   if( __DEBUG__ )
319//   {
320//     PrintS("ComputeLeadingSyzygyTerms::Output: \n");
321//     dPrint(newid, r, r, 1);
322//   }
323
324  Sort_c_ds(newid, r);
325
326  return newid;
327}
328
329
330
331
332ideal Compute2LeadingSyzygyTerms(const ideal& id, const ring r)
333{
334#ifndef NDEBUG
335  const BOOLEAN __DEBUG__ = (BOOLEAN)((long)(atGet(currRingHdl,"DEBUG",INT_CMD, (void*)TRUE)));
336#else
337  const BOOLEAN __DEBUG__ = (BOOLEAN)((long)(atGet(currRingHdl,"DEBUG",INT_CMD, (void*)FALSE)));
338#endif
339
340  const BOOLEAN __TAILREDSYZ__ = (BOOLEAN)((long)(atGet(currRingHdl,"TAILREDSYZ",INT_CMD, (void*)0)));
341  const BOOLEAN __SYZCHECK__ = (BOOLEAN)((long)(atGet(currRingHdl,"SYZCHECK",INT_CMD, (void*)0)));   
342
343
344
345  // 1. set of components S?
346  // 2. for each component c from S: set of indices of leading terms
347  // with this component?
348  // 3. short exp. vectors for each leading term?
349
350  const int size = IDELEMS(id);
351
352  if( size < 2 )
353  {
354    const ideal newid = idInit(1, 1); newid->m[0] = NULL; // zero module...   
355    return newid;
356  }
357
358
359    // TODO/NOTE: input is supposed to be sorted wrt "C,ds"!??
360
361    // components should come in groups: count elements in each group
362    // && estimate the real size!!!
363
364
365    // use just a vector instead???
366  ideal newid = idInit( (size * (size-1))/2, size); // maximal size: ideal case!
367
368  int k = 0;
369
370  for (int j = 0; j < size; j++)
371  {
372    const poly p = id->m[j];
373    assume( p != NULL );
374    const int  c = p_GetComp(p, r);
375
376    for (int i = j - 1; i >= 0; i--)
377    {
378      const poly pp = id->m[i];
379      assume( pp != NULL );
380      const int  cc = p_GetComp(pp, r);
381
382      if( c != cc )
383        continue;
384
385        // allocate memory & zero it out!
386      const poly m = p_Init(r); const poly mm = p_Init(r);
387
388
389        // m = LCM(p, pp) / p! mm = LCM(p, pp) / pp!
390        // TODO: optimize: knowing the ring structure: (C/lp)!
391
392      for (int v = rVar(r); v > 0; v--)
393      {
394        assume( v > 0 );
395        assume( v <= rVar(r) );
396
397        const short e1 = p_GetExp(p , v, r);
398        const short e2 = p_GetExp(pp, v, r);
399
400        if( e1 >= e2 )
401          p_SetExp(mm, v, e1 - e2, r); //            p_SetExp(m, v, 0, r);
402        else
403          p_SetExp(m, v, e2 - e1, r); //            p_SetExp(mm, v, 0, r);
404
405      }
406
407      assume( (j > i) && (i >= 0) );
408
409      p_SetComp(m, j + 1, r);
410      p_SetComp(mm, i + 1, r);
411
412      const number& lc1 = p_GetCoeff(p , r);
413      const number& lc2 = p_GetCoeff(pp, r);
414
415      number g = n_Lcm( lc1, lc2, r );
416
417      p_SetCoeff0(m ,       n_Div(g, lc1, r), r);
418      p_SetCoeff0(mm, n_Neg(n_Div(g, lc2, r), r), r);
419
420      n_Delete(&g, r);
421
422      p_Setm(m, r); // should not do anything!!!
423      p_Setm(mm, r); // should not do anything!!!
424
425      pNext(m) = mm; //        pNext(mm) = NULL;
426
427      newid->m[k++] = m;
428    }
429  }
430
431//   if( __DEBUG__ && FALSE )
432//   {
433//     PrintS("Compute2LeadingSyzygyTerms::Temp0: \n");
434//     dPrint(newid, r, r, 1);
435//   }
436
437  if( !__TAILREDSYZ__ )
438  {
439      // simplify(newid, 2 + 32)??
440      // sort(newid, "C,ds")[1]???
441    id_DelDiv(newid, r); // #define SIMPL_LMDIV 32
442
443//     if( __DEBUG__ && FALSE )
444//     {
445//       PrintS("Compute2LeadingSyzygyTerms::Temp1 (deldiv): \n");
446//       dPrint(newid, r, r, 1);
447//     }
448  }
449  else
450  {
451      //      option(redSB); option(redTail);
452      //      TEST_OPT_REDSB
453      //      TEST_OPT_REDTAIL
454    assume( r == currRing );
455    BITSET _save_test = test;
456    test |= (Sy_bit(OPT_REDTAIL) | Sy_bit(OPT_REDSB));
457
458    intvec* w=new intvec(IDELEMS(newid));
459    ideal tmp = kStd(newid, currQuotient, isHomog, &w);
460    delete w;
461
462    test = _save_test;
463
464    id_Delete(&newid, r);
465    newid = tmp;
466
467//     if( __DEBUG__ && FALSE )
468//     {
469//       PrintS("Compute2LeadingSyzygyTerms::Temp1 (std): \n");
470//       dPrint(newid, r, r, 1);
471//     }
472
473  }
474
475  idSkipZeroes(newid);
476
477  Sort_c_ds(newid, r);
478 
479  return newid;
480}
481
482poly FindReducer(poly product, poly syzterm,
483                        ideal L, ideal LS,
484                        const ring r)
485{
486  assume( product != NULL );
487  assume( L != NULL );
488
489  int c = 0;
490
491  if (syzterm != NULL)
492    c = p_GetComp(syzterm, r) - 1;
493
494  assume( c >= 0 && c < IDELEMS(L) );
495
496#ifndef NDEBUG
497  const BOOLEAN __DEBUG__ = (BOOLEAN)((long)(atGet(currRingHdl,"DEBUG",INT_CMD, (void*)TRUE)));
498#else
499  const BOOLEAN __DEBUG__ = (BOOLEAN)((long)(atGet(currRingHdl,"DEBUG",INT_CMD, (void*)FALSE)));
500#endif
501
502  long debug = __DEBUG__;
503  const BOOLEAN __SYZCHECK__ = (BOOLEAN)((long)(atGet(currRingHdl,"SYZCHECK",INT_CMD, (void*)debug)));   
504
505  if (__SYZCHECK__ && syzterm != NULL)
506  {
507    const poly m = L->m[c];
508
509    assume( m != NULL ); assume( pNext(m) == NULL );
510
511    poly lm = p_Mult_mm(leadmonom(syzterm, r), m, r);
512    assume( p_EqualPolys(lm, product, r) );
513
514    //  def @@c = leadcomp(syzterm); int @@r = int(@@c);
515    //  def @@product = leadmonomial(syzterm) * L[@@r];
516
517    p_Delete(&lm, r);   
518  }
519
520  // looking for an appropriate diviser q = L[k]...
521  for( int k = IDELEMS(L)-1; k>= 0; k-- )
522  {
523    const poly p = L->m[k];   
524
525    // ... which divides the product, looking for the _1st_ appropriate one!
526    if( !p_LmDivisibleBy(p, product, r) )
527      continue;
528
529
530    const poly q = p_New(r);
531    pNext(q) = NULL;
532    p_ExpVectorDiff(q, product, p, r); // (LM(product) / LM(L[k]))
533    p_SetComp(q, k + 1, r);
534    p_Setm(q, r);
535
536    // cannot allow something like: a*gen(i) - a*gen(i)
537    if (syzterm != NULL && (k == c))
538      if (p_ExpVectorEqual(syzterm, q, r))
539      {
540        if( __DEBUG__ )
541        {
542          Print("FindReducer::Test SYZTERM: q == syzterm !:((, syzterm is: ");
543          dPrint(syzterm, r, r, 1);
544        }   
545
546        p_LmFree(q, r);
547        continue;
548      }
549
550    // while the complement (the fraction) is not reducible by leading syzygies
551    if( LS != NULL )
552    {
553      BOOLEAN ok = TRUE;
554
555      for(int kk = IDELEMS(LS)-1; kk>= 0; kk-- )
556      {
557        const poly pp = LS->m[kk];
558
559        if( p_LmDivisibleBy(pp, q, r) )
560        {
561
562          if( __DEBUG__ )
563          {
564            Print("FindReducer::Test LS: q is divisible by LS[%d] !:((, diviser is: ", kk+1);
565            dPrint(pp, r, r, 1);
566          }   
567
568          ok = FALSE; // q in <LS> :((
569          break;                 
570        }
571      }
572
573      if(!ok)
574      {
575        p_LmFree(q, r);
576        continue;
577      }
578    }
579
580    p_SetCoeff0(q, n_Neg( n_Div( p_GetCoeff(product, r), p_GetCoeff(p, r), r), r), r);
581    return q;
582
583  }
584
585
586  return NULL;
587}
588
589poly TraverseTail(poly multiplier, poly tail, 
590                         ideal L, ideal T, ideal LS,
591                         const ring r)
592{
593  assume( multiplier != NULL );
594
595  assume( L != NULL );
596  assume( T != NULL );
597
598  poly s = NULL;
599
600  // iterate over the tail
601  for(poly p = tail; p != NULL; p = pNext(p))
602    s = p_Add_q(s, ReduceTerm(multiplier, p, NULL, L, T, LS, r), r); 
603
604  return s;
605}
606
607
608poly ReduceTerm(poly multiplier, poly term4reduction, poly syztermCheck,
609                       ideal L, ideal T, ideal LS, const ring r)
610{
611  assume( multiplier != NULL );
612  assume( term4reduction != NULL );
613
614
615  assume( L != NULL );
616  assume( T != NULL );
617
618  // assume(r == currRing); // ?
619
620  // simple implementation with FindReducer:
621  poly s = NULL;
622
623  if(1)
624  {
625    // NOTE: only LT(term4reduction) should be used in the following:
626    poly product = pp_Mult_mm(multiplier, term4reduction, r);
627    s = FindReducer(product, syztermCheck, L, LS, r);
628    p_Delete(&product, r);
629  }
630
631  if( s == NULL ) // No Reducer?
632    return s;
633
634  poly b = leadmonom(s, r);
635
636  const int c = p_GetComp(s, r) - 1;
637  assume( c >= 0 && c < IDELEMS(T) );
638
639  const poly tail = T->m[c];
640
641  if( tail != NULL )
642    s = p_Add_q(s, TraverseTail(b, tail, L, T, LS, r), r); 
643
644  return s;
645}
646
647
648poly SchreyerSyzygyNF(poly syz_lead, poly syz_2, ideal L, ideal T, ideal LS, const ring r)
649{
650  assume( syz_lead != NULL );
651  assume( syz_2 != NULL );
652
653  assume( L != NULL );
654  assume( T != NULL );
655
656  assume( IDELEMS(L) == IDELEMS(T) );
657
658  int  c = p_GetComp(syz_lead, r) - 1;
659
660  assume( c >= 0 && c < IDELEMS(T) );
661
662  poly p = leadmonom(syz_lead, r); // :( 
663  poly spoly = pp_Mult_qq(p, T->m[c], r);
664  p_Delete(&p, r);
665
666
667  c = p_GetComp(syz_2, r) - 1;
668  assume( c >= 0 && c < IDELEMS(T) );
669
670  p = leadmonom(syz_2, r); // :(
671  spoly = p_Add_q(spoly, pp_Mult_qq(p, T->m[c], r), r);
672  p_Delete(&p, r);
673
674  poly tail = p_Copy(syz_2, r); // TODO: use bucket!?
675
676  while (spoly != NULL)
677  {
678    poly t = FindReducer(spoly, NULL, L, LS, r);
679
680    p_LmDelete(&spoly, r);
681
682    if( t != NULL )
683    {
684      p = leadmonom(t, r); // :(
685      c = p_GetComp(t, r) - 1;
686
687      assume( c >= 0 && c < IDELEMS(T) );
688
689      spoly = p_Add_q(spoly, pp_Mult_qq(p, T->m[c], r), r);
690
691      p_Delete(&p, r);
692
693      tail = p_Add_q(tail, t, r);
694    }   
695  }
696
697  return tail;
698}
699
700
701void ComputeSyzygy(const ideal L, const ideal T, ideal& LL, ideal& TT, const ring R)
702{
703  assume( R == currRing ); // For attributes :-/
704
705  assume( IDELEMS(L) == IDELEMS(T) );
706
707#ifndef NDEBUG
708  const BOOLEAN __DEBUG__ = (BOOLEAN)((long)(atGet(currRingHdl,"DEBUG",INT_CMD, (void*)TRUE)));
709#else
710  const BOOLEAN __DEBUG__ = (BOOLEAN)((long)(atGet(currRingHdl,"DEBUG",INT_CMD, (void*)FALSE)));
711#endif
712
713  const BOOLEAN __LEAD2SYZ__ = (BOOLEAN)((long)(atGet(currRingHdl,"LEAD2SYZ",INT_CMD, (void*)1)));
714  const BOOLEAN __TAILREDSYZ__ = (BOOLEAN)((long)(atGet(currRingHdl,"TAILREDSYZ",INT_CMD, (void*)1)));
715  const BOOLEAN __SYZCHECK__ = (BOOLEAN)((long)(atGet(currRingHdl,"SYZCHECK",INT_CMD, (void*)__DEBUG__)));
716
717  const BOOLEAN __HYBRIDNF__ = (BOOLEAN)((long)(atGet(currRingHdl,"HYBRIDNF",INT_CMD, (void*)0)));
718
719
720  if( __LEAD2SYZ__ )
721    LL = Compute2LeadingSyzygyTerms(L, R); // 2 terms!
722  else
723    LL = ComputeLeadingSyzygyTerms(L, R); // 1 term!
724
725  const int size = IDELEMS(LL);
726
727  TT = idInit(size, 0);
728
729  if( size == 1 && LL->m[0] == NULL )
730    return;
731
732
733  ideal LS = NULL;
734
735  if( __TAILREDSYZ__ )
736    LS = LL;
737
738  for( int k = size - 1; k >= 0; k-- )
739  {
740    const poly a = LL->m[k]; assume( a != NULL );
741
742    const int r = p_GetComp(a, R) - 1; 
743
744    assume( r >= 0 && r < IDELEMS(T) );
745    assume( r >= 0 && r < IDELEMS(L) );
746
747    poly aa = leadmonom(a, R); assume( aa != NULL); // :(   
748
749    poly a2 = pNext(a);   
750
751    if( a2 != NULL )
752    {
753      TT->m[k] = a2; pNext(a) = NULL;
754    }
755
756    if( ! __HYBRIDNF__ )
757    {
758      poly t = TraverseTail(aa, T->m[r], L, T, LS, R);
759
760      if( a2 != NULL )
761      {
762        assume( __LEAD2SYZ__ );
763
764        const int r2 = p_GetComp(a2, R) - 1; poly aa2 = leadmonom(a2, R); // :(
765
766        assume( r2 >= 0 && r2 < IDELEMS(T) );
767
768        TT->m[k] = p_Add_q(a2, p_Add_q(t, TraverseTail(aa2, T->m[r2], L, T, LS, R), R), R);
769
770        p_Delete(&aa2, R);
771      } else
772        TT->m[k] = p_Add_q(t, ReduceTerm(aa, L->m[r], a, L, T, LS, R), R);
773
774    } else
775    {
776      if( a2 == NULL )
777      {
778        aa = p_Mult_mm(aa, L->m[r], R);
779        a2 = FindReducer(aa, a, L, LS, R); 
780      }
781      assume( a2 != NULL );
782
783      TT->m[k] = SchreyerSyzygyNF(a, a2, L, T, LS, R); // will copy a2 :(
784
785      p_Delete(&a2, R);
786    }
787    p_Delete(&aa, R);   
788  }
789
790  TT->rank = id_RankFreeModule(TT, R);
791}
792
793
794
795
796
797
798
799
800END_NAMESPACE               END_NAMESPACE_SINGULARXX
801
802
803// Vi-modeline: vim: filetype=c:syntax:shiftwidth=2:tabstop=8:textwidth=0:expandtab
Note: See TracBrowser for help on using the repository browser.