source: git/kernel/sca.cc @ 6dbc96

spielwiese
Last change on this file since 6dbc96 was 6dbc96, checked in by Motsak Oleksandr <motsak@…>, 17 years ago
*motsak: adding suppercommutative algebras git-svn-id: file:///usr/local/Singular/svn/trunk@9619 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 49.5 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/***************************************************************
5 *  File:    sca.cc
6 *  Purpose: supercommutative kernel procedures
7 *  Author:  motsak (Oleksandr Motsak)
8 *  Created: 2006/12/18
9 *  Version: $Id: sca.cc,v 1.1 2007-01-03 00:04:00 motsak Exp $
10 *******************************************************************/
11
12// #define PDEBUG 2
13#include "mod2.h"
14
15// for
16#define PLURAL_INTERNAL_DECLARATIONS
17#include "sca.h"
18
19
20#include "febase.h"
21
22#include "p_polys.h"
23#include "kutil.h"
24#include "ideals.h"
25#include "intvec.h"
26#include "polys.h"
27
28#include "ring.h"
29#include "numbers.h"
30#include "matpol.h"
31#include "kbuckets.h"
32#include "kstd1.h"
33#include "sbuckets.h"
34#include "prCopy.h"
35#include "p_Mult_q.h"
36#include "p_MemAdd.h"
37
38#include "kutil.h"
39#include "kstd1.h"
40
41#include "weight.h"
42
43
44//   scaFirstAltVar( r, 0 );
45//   scaLastAltVar( r, 0 );
46
47
48
49////////////////////////////////////////////////////////////////////////////////////////////////////
50// Super Commutative Algabra extension by Motsak
51////////////////////////////////////////////////////////////////////////////////////////////////////
52
53
54
55
56
57// returns the sign of: lm(pMonomM) * lm(pMonomMM),
58// preserves input, may return +/-1, 0
59inline int sca_Sign_mm_Mult_mm( const poly pMonomM, const poly pMonomMM, const ring rRing )
60{
61#ifdef PDEBUG
62    p_Test(pMonomM,  rRing);
63    p_Test(pMonomMM, rRing);
64#endif
65
66    const unsigned int iFirstAltVar = scaFirstAltVar(rRing);
67    const unsigned int iLastAltVar  = scaLastAltVar(rRing);
68
69    unsigned int tpower = 0;
70    unsigned int cpower = 0;
71
72    for( unsigned int j = iLastAltVar; j >= iFirstAltVar; j-- )
73    {
74      const unsigned int iExpM  = p_GetExp(pMonomM,  j, rRing);
75      const unsigned int iExpMM = p_GetExp(pMonomMM, j, rRing);
76
77      if( iExpMM != 0 )
78      {
79        if( iExpM != 0 )
80        {
81          return 0; // lm(pMonomM) * lm(pMonomMM) == 0
82        }
83        tpower += cpower; // compute degree of (-1).
84      }
85
86      cpower += iExpM;
87    }
88
89    if( (tpower&1) != 0 ) // degree is odd => negate coeff.
90      return -1;
91
92    return(1);
93}
94
95
96
97
98// returns and changes pMonomM: lt(pMonomM) = lt(pMonomM) * lt(pMonomMM),
99// preserves pMonomMM. may return NULL!
100// if result != NULL => next(result) = next(pMonomM), lt(result) = lt(pMonomM) * lt(pMonomMM)
101// if result == NULL => pMonomM MUST BE deleted manually!
102inline poly sca_m_Mult_mm( poly pMonomM, const poly pMonomMM, const ring rRing )
103{
104#ifdef PDEBUG
105    p_Test(pMonomM,  rRing);
106    p_Test(pMonomMM, rRing);
107#endif
108
109    const unsigned int iFirstAltVar = scaFirstAltVar(rRing);
110    const unsigned int iLastAltVar = scaLastAltVar(rRing);
111
112    unsigned int tpower = 0;
113    unsigned int cpower = 0;
114
115    for( unsigned int j = iLastAltVar; j >= iFirstAltVar; j-- )
116    {
117      const unsigned int iExpM  = p_GetExp(pMonomM,  j, rRing);
118      const unsigned int iExpMM = p_GetExp(pMonomMM, j, rRing);
119
120      if( iExpMM != 0 )
121      {
122        if( iExpM != 0 ) // result is zero!
123        {
124          return NULL; // we do nothing with pMonomM in this case!
125        }
126
127        tpower += cpower; // compute degree of (-1).
128      }
129
130      cpower += iExpM;
131    }
132
133    p_ExpVectorAdd(pMonomM, pMonomMM, rRing); // "exponents" are additive!!!
134
135    number nCoeffM = p_GetCoeff(pMonomM, rRing); // no new copy! should be deleted!
136
137    if( (tpower&1) != 0 ) // degree is odd => negate coeff.
138      nCoeffM = n_Neg(nCoeffM, rRing); // negate nCoeff (will destroy the original number)
139
140    const number nCoeffMM = p_GetCoeff(pMonomMM, rRing); // no new copy!
141
142    number nCoeff = n_Mult(nCoeffM, nCoeffMM, rRing); // new number!
143
144    p_SetCoeff(pMonomM, nCoeff, rRing); // delete lc(pMonomM) and set lc(pMonomM) = nCoeff
145
146#ifdef PDEBUG
147    p_Test(pMonomM, rRing);
148#endif
149
150    return(pMonomM);
151}
152
153// returns and changes pMonomM: lt(pMonomM) = lt(pMonomMM) * lt(pMonomM),
154// preserves pMonomMM. may return NULL!
155// if result != NULL => next(result) = next(pMonomM), lt(result) = lt(pMonomMM) * lt(pMonomM)
156// if result == NULL => pMonomM MUST BE deleted manually!
157inline poly sca_mm_Mult_m( const poly pMonomMM, poly pMonomM, const ring rRing )
158{
159#ifdef PDEBUG
160    p_Test(pMonomM,  rRing);
161    p_Test(pMonomMM, rRing);
162#endif
163
164    const unsigned int iFirstAltVar = scaFirstAltVar(rRing);
165    const unsigned int iLastAltVar = scaLastAltVar(rRing);
166
167    unsigned int tpower = 0;
168    unsigned int cpower = 0;
169
170    for( unsigned int j = iLastAltVar; j >= iFirstAltVar; j-- )
171    {
172      const unsigned int iExpMM = p_GetExp(pMonomMM, j, rRing);
173      const unsigned int iExpM  = p_GetExp(pMonomM,  j, rRing);
174
175      if( iExpM != 0 )
176      {
177        if( iExpMM != 0 ) // result is zero!
178        {
179          return NULL; // we do nothing with pMonomM in this case!
180        }
181
182        tpower += cpower; // compute degree of (-1).
183      }
184
185      cpower += iExpMM;
186    }
187
188    p_ExpVectorAdd(pMonomM, pMonomMM, rRing); // "exponents" are additive!!!
189
190    number nCoeffM = p_GetCoeff(pMonomM, rRing); // no new copy! should be deleted!
191
192    if( (tpower&1) != 0 ) // degree is odd => negate coeff.
193      nCoeffM = n_Neg(nCoeffM, rRing); // negate nCoeff (will destroy the original number), creates new number!
194
195    const number nCoeffMM = p_GetCoeff(pMonomMM, rRing); // no new copy!
196
197    number nCoeff = n_Mult(nCoeffM, nCoeffMM, rRing); // new number!
198
199    p_SetCoeff(pMonomM, nCoeff, rRing); // delete lc(pMonomM) and set lc(pMonomM) = nCoeff
200
201#ifdef PDEBUG
202    p_Test(pMonomM, rRing);
203#endif
204
205    return(pMonomM);
206}
207
208
209
210// returns: result = lt(pMonom1) * lt(pMonom2),
211// preserves pMonom1, pMonom2. may return NULL!
212// if result != NULL => next(result) = NULL, lt(result) = lt(pMonom1) * lt(pMonom2)
213inline poly sca_mm_Mult_mm( poly pMonom1, const poly pMonom2, const ring rRing )
214{
215#ifdef PDEBUG
216    p_Test(pMonom1, rRing);
217    p_Test(pMonom2, rRing);
218#endif
219
220    const unsigned int iFirstAltVar = scaFirstAltVar(rRing);
221    const unsigned int iLastAltVar = scaLastAltVar(rRing);
222
223    unsigned int tpower = 0;
224    unsigned int cpower = 0;
225
226    for( unsigned int j = iLastAltVar; j >= iFirstAltVar; j-- )
227    {
228      const unsigned int iExp1 = p_GetExp(pMonom1, j, rRing);
229      const unsigned int iExp2 = p_GetExp(pMonom2, j, rRing);
230
231      if( iExp2 != 0 )
232      {
233        if( iExp1 != 0 ) // result is zero!
234        {
235          return NULL;
236        }
237
238        tpower += cpower; // compute degree of (-1).
239      }
240
241      cpower += iExp1;
242    }
243
244    poly pResult;
245    omTypeAllocBin(poly, pResult, rRing->PolyBin);
246    p_SetRingOfLm(pResult, rRing);
247
248    p_ExpVectorSum(pResult, pMonom1, pMonom2, rRing); // "exponents" are additive!!!
249
250    pNext(pResult) = NULL;
251
252    const number nCoeff1 = p_GetCoeff(pMonom1, rRing); // no new copy!
253    const number nCoeff2 = p_GetCoeff(pMonom2, rRing); // no new copy!
254
255    number nCoeff = n_Mult(nCoeff1, nCoeff2, rRing); // new number!
256
257    if( (tpower&1) != 0 ) // degree is odd => negate coeff.
258      nCoeff = n_Neg(nCoeff, rRing); // negate nCoeff (will destroy the original number)
259
260    p_SetCoeff0(pResult, nCoeff, rRing); // set lc(pResult) = nCoeff, no destruction!
261
262#ifdef PDEBUG
263    p_Test(pResult, rRing);
264#endif
265
266    return(pResult);
267}
268
269// returns: result =  x_i * lt(pMonom),
270// preserves pMonom. may return NULL!
271// if result != NULL => next(result) = NULL, lt(result) = x_i * lt(pMonom)
272inline poly sca_xi_Mult_mm(unsigned int i, const poly pMonom, const ring rRing)
273{
274#ifdef PDEBUG
275    p_Test(pMonom, rRing);
276#endif
277
278    assume( i <= scaLastAltVar(rRing));
279    assume( scaFirstAltVar(rRing) <= i );
280
281    if( p_GetExp(pMonom, i, rRing) ) // result is zero!
282      return NULL;
283
284    const unsigned int iFirstAltVar = scaFirstAltVar(rRing);
285
286    unsigned int cpower = 0;
287
288    for( unsigned int j = iFirstAltVar; j < i ; j++ )
289      cpower += p_GetExp(pMonom, j, rRing);
290
291    poly pResult = p_LmInit(pMonom, rRing);
292
293    p_SetExp(pResult, i, 1, rRing); // pResult*=X_i &&
294    p_Setm(pResult, rRing);         // addjust degree after previous step!
295
296    number nCoeff = n_Copy(p_GetCoeff(pMonom, rRing), rRing); // new number!
297
298    if( (cpower&1) != 0 ) // degree is odd => negate coeff.
299      nCoeff = n_Neg(nCoeff, rRing); // negate nCoeff (will destroy the original number)
300
301    p_SetCoeff0(pResult, nCoeff, rRing); // set lc(pResult) = nCoeff, no destruction!
302
303#ifdef PDEBUG
304    p_Test(pResult, rRing);
305#endif
306
307    return(pResult);
308}
309
310//-----------------------------------------------------------------------------------//
311
312// return poly = pPoly * pMonom; preserve pMonom, destroy or reuse pPoly.
313poly sca_p_Mult_mm(poly pPoly, const poly pMonom, const ring rRing)
314{
315  assume( rIsSCA(rRing) );
316
317#ifdef PDEBUG
318//  Print("sca_p_Mult_mm\n"); // !
319
320  p_Test(pPoly, rRing);
321  p_Test(pMonom, rRing);
322#endif
323
324  if( pPoly == NULL )
325    return NULL;
326
327  if( pMonom == NULL )
328  {
329    // pPoly != NULL =>
330    p_Delete( &pPoly, rRing );
331
332    return NULL;
333  }
334
335  const int iComponentMonomM = p_GetComp(pMonom, rRing);
336
337  poly p = pPoly; poly* ppPrev = &pPoly;
338
339  loop
340  {
341#ifdef PDEBUG
342    p_Test(p, rRing);
343#endif
344    const int iComponent = p_GetComp(p, rRing);
345
346    if( iComponent!=0 )
347    {
348      if( iComponentMonomM!=0 ) // TODO: make global if on iComponentMonomM =?= 0
349      {
350        // REPORT_ERROR
351        Werror("sca_p_Mult_mm: exponent mismatch %d and %d\n", iComponent, iComponentMonomM);
352        // what should we do further?!?
353
354        p_Delete( &pPoly, rRing); // delete the result AND rest
355        return NULL;
356      }
357#ifdef PDEBUG
358      if(iComponentMonomM==0 )
359      {
360        Print("Multiplication in the left module from the right");
361      }
362#endif
363    }
364
365    // terms will be in the same order because of quasi-ordering!
366    poly v = sca_m_Mult_mm(p, pMonom, rRing);
367
368    if( v != NULL )
369    {
370      ppPrev = &pNext(p); // fixed!
371
372    // *p is changed if v != NULL ( p == v )
373      pIter(p);
374
375      if( p == NULL )
376        break;
377    }
378    else
379    { // Upps! Zero!!! we must kill this term!
380
381      //
382      p = p_LmDeleteAndNext(p, rRing);
383
384      *ppPrev = p;
385
386      if( p == NULL )
387        break;
388    }
389
390
391  }
392
393#ifdef PDEBUG
394  p_Test(pPoly,rRing);
395#endif
396
397  return(pPoly);
398}
399
400// return new poly = pPoly * pMonom; preserve pPoly and pMonom.
401poly sca_pp_Mult_mm(const poly pPoly, const poly pMonom, const ring rRing, poly &)
402{
403  assume( rIsSCA(rRing) );
404
405#ifdef PDEBUG
406//  Print("sca_pp_Mult_mm\n"); // !
407
408  p_Test(pPoly, rRing);
409  p_Test(pMonom, rRing);
410#endif
411
412  if( ( pPoly == NULL ) || ( pMonom == NULL ) )
413    return NULL;
414
415  const int iComponentMonomM = p_GetComp(pMonom, rRing);
416
417  poly pResult = NULL;
418  poly* ppPrev = &pResult;
419
420  for( poly p = pPoly; p!= NULL; pIter(p) )
421  {
422#ifdef PDEBUG
423    p_Test(p, rRing);
424#endif
425    const int iComponent = p_GetComp(p, rRing);
426
427    if( iComponent!=0 )
428    {
429      if( iComponentMonomM!=0 ) // TODO: make global if on iComponentMonomM =?= 0
430      {
431        // REPORT_ERROR
432        Werror("sca_pp_Mult_mm: exponent mismatch %d and %d\n", iComponent, iComponentMonomM);
433        // what should we do further?!?
434
435        p_Delete( &pResult, rRing); // delete the result
436        return NULL;
437      }
438
439#ifdef PDEBUG
440      if(iComponentMonomM==0 )
441      {
442        Print("Multiplication in the left module from the right");
443      }
444#endif
445    }
446
447    // terms will be in the same order because of quasi-ordering!
448    poly v = sca_mm_Mult_mm(p, pMonom, rRing);
449
450    if( v != NULL )
451    {
452      *ppPrev = v;
453      ppPrev = &pNext(v);
454    }
455
456  }
457
458#ifdef PDEBUG
459  p_Test(pResult,rRing);
460#endif
461
462  return(pResult);
463}
464
465//-----------------------------------------------------------------------------------//
466
467// return x_i * pPoly; preserve pPoly.
468inline poly sca_xi_Mult_pp(unsigned int i, const poly pPoly, const ring rRing)
469{
470  assume( rIsSCA(rRing) );
471
472#ifdef PDEBUG
473  p_Test(pPoly, rRing);
474#endif
475
476  assume(i <= scaLastAltVar(rRing));
477  assume(scaFirstAltVar(rRing) <= i);
478
479  if( pPoly == NULL )
480    return NULL;
481
482  poly pResult = NULL;
483  poly* ppPrev = &pResult;
484
485  for( poly p = pPoly; p!= NULL; pIter(p) )
486  {
487
488    // terms will be in the same order because of quasi-ordering!
489    poly v = sca_xi_Mult_mm(i, p, rRing);
490
491#ifdef PDEBUG
492    p_Test(v, rRing);
493#endif
494
495    if( v != NULL )
496    {
497      *ppPrev = v;
498      ppPrev = &pNext(*ppPrev);
499    }
500  }
501
502
503#ifdef PDEBUG
504  p_Test(pResult, rRing);
505#endif
506
507  return(pResult);
508}
509
510
511// return new poly = pMonom * pPoly; preserve pPoly and pMonom.
512poly sca_mm_Mult_pp(const poly pMonom, const poly pPoly, const ring rRing)
513{
514  assume( rIsSCA(rRing) );
515
516#ifdef PDEBUG
517//  Print("sca_mm_Mult_pp\n"); // !
518
519  p_Test(pPoly, rRing);
520  p_Test(pMonom, rRing);
521#endif
522
523  if( ( pPoly == NULL ) || ( pMonom == NULL ) )
524    return NULL;
525
526  const int iComponentMonomM = p_GetComp(pMonom, rRing);
527
528  poly pResult = NULL;
529  poly* ppPrev = &pResult;
530
531  for( poly p = pPoly; p!= NULL; pIter(p) )
532  {
533#ifdef PDEBUG
534    p_Test(p, rRing);
535#endif
536    const int iComponent = p_GetComp(p, rRing);
537
538    if( iComponentMonomM!=0 )
539    {
540      if( iComponent!=0 ) // TODO: make global if on iComponentMonomM =?= 0
541      {
542        // REPORT_ERROR
543        Werror("sca_mm_Mult_pp: exponent mismatch %d and %d\n", iComponent, iComponentMonomM);
544        // what should we do further?!?
545
546        p_Delete( &pResult, rRing); // delete the result
547        return NULL;
548      }
549#ifdef PDEBUG
550      if(iComponent==0 )
551      {
552        Print("Multiplication in the left module from the right");
553      }
554#endif
555    }
556
557    // terms will be in the same order because of quasi-ordering!
558    poly v = sca_mm_Mult_mm(pMonom, p, rRing);
559
560    if( v != NULL )
561    {
562      *ppPrev = v;
563      ppPrev = &pNext(*ppPrev); // nice line ;-)
564    }
565  }
566
567#ifdef PDEBUG
568  p_Test(pResult,rRing);
569#endif
570
571  return(pResult);
572}
573
574
575// return poly = pMonom * pPoly; preserve pMonom, destroy or reuse pPoly.
576poly sca_mm_Mult_p(const poly pMonom, poly pPoly, const ring rRing) // !!!!! the MOST used procedure !!!!!
577{
578  assume( rIsSCA(rRing) );
579
580#ifdef PDEBUG
581  p_Test(pPoly, rRing);
582  p_Test(pMonom, rRing);
583#endif
584
585  if( pPoly == NULL )
586    return NULL;
587
588  if( pMonom == NULL )
589  {
590    // pPoly != NULL =>
591    p_Delete( &pPoly, rRing );
592    return NULL;
593  }
594
595  const int iComponentMonomM = p_GetComp(pMonom, rRing);
596
597  poly p = pPoly; poly* ppPrev = &pPoly;
598
599  loop
600  {
601#ifdef PDEBUG
602    if( !p_Test(p, rRing) )
603    {
604      Print("p is wrong!");
605      p_Write(p,rRing);
606    }
607#endif
608
609    const int iComponent = p_GetComp(p, rRing);
610
611    if( iComponentMonomM!=0 )
612    {
613      if( iComponent!=0 ) // TODO: make global if on iComponentMonomM =?= 0
614      {
615        // REPORT_ERROR
616        Werror("sca_mm_Mult_p: exponent mismatch %d and %d\n", iComponent, iComponentMonomM);
617        // what should we do further?!?
618
619        p_Delete( &pPoly, rRing); // delete the result
620        return NULL;
621      }
622#ifdef PDEBUG
623      if(iComponent==0 )
624      {
625        Print("Multiplication in the left module from the right");
626      }
627#endif
628    }
629
630    // terms will be in the same order because of quasi-ordering!
631    poly v = sca_mm_Mult_m(pMonom, p, rRing);
632
633    if( v != NULL )
634    {
635      ppPrev = &pNext(p);
636
637    // *p is changed if v != NULL ( p == v )
638      pIter(p);
639
640      if( p == NULL )
641        break;
642    }
643    else
644    { // Upps! Zero!!! we must kill this term!
645      p = p_LmDeleteAndNext(p, rRing);
646
647      *ppPrev = p;
648
649      if( p == NULL )
650        break;
651    }
652  }
653
654#ifdef PDEBUG
655    if( !p_Test(pPoly, rRing) )
656    {
657      Print("pPoly is wrong!");
658      p_Write(pPoly, rRing);
659    }
660#endif
661
662  return(pPoly);
663}
664
665//-----------------------------------------------------------------------------------//
666
667#ifdef PDEBUG
668#endif
669
670
671
672
673//-----------------------------------------------------------------------------------//
674
675// GB computation routines:
676
677/*2
678* returns the LCM of the head terms of a and b
679*/
680inline poly p_Lcm(const poly a, const poly b, const long lCompM, const ring r)
681{
682  poly m = p_ISet(1, r);
683
684  const int pVariables = r->N;
685
686  for (int i = pVariables; i; i--)
687  {
688    const int lExpA = p_GetExp (a, i, r);
689    const int lExpB = p_GetExp (b, i, r);
690
691    p_SetExp (m, i, si_max(lExpA, lExpB), r);
692  }
693
694  p_SetComp (m, lCompM, r);
695
696  p_Setm(m,r);
697
698#ifdef PDEBUG
699  p_Test(m,r);
700#endif
701
702  return(m);
703}
704
705/*4
706* creates the S-polynomial of p1 and p2
707* does not destroy p1 and p2
708*/
709poly sca_SPoly( const poly p1, const poly p2, const ring r )
710{
711  assume( rIsSCA(r) );
712
713  const long lCompP1 = p_GetComp(p1,r);
714  const long lCompP2 = p_GetComp(p2,r);
715
716  if ((lCompP1!=lCompP2) && (lCompP1!=0) && (lCompP2!=0))
717  {
718#ifdef PDEBUG
719    Print("sca_SPoly: different non-zero components!\n");
720#endif
721    return(NULL);
722  }
723
724  poly pL = p_Lcm(p1, p2, si_max(lCompP1, lCompP2), r);       // pL = lcm( lm(p1), lm(p2) )
725
726  poly m1 = p_ISet(1, r);
727  p_ExpVectorDiff(m1, pL, p1, r);                  // m1 = pL / lm(p1)
728  //p_SetComp(m1,0,r);
729  //p_Setm(m1,r);
730#ifdef PDEBUG
731  p_Test(m1,r);
732#endif
733
734
735  poly m2 = p_ISet(1, r);
736  p_ExpVectorDiff (m2, pL, p2, r);                  // m2 = pL / lm(p2)
737
738  //p_SetComp(m2,0,r);
739  //p_Setm(m2,r);
740#ifdef PDEBUG
741  p_Test(m2,r);
742#endif
743
744  p_Delete(&pL,r);
745
746  number C1  = n_Copy(p_GetCoeff(p1,r),r);      // C1 = lc(p1)
747  number C2  = n_Copy(p_GetCoeff(p2,r),r);      // C2 = lc(p2)
748
749  number C = nGcd(C1,C2,r);                     // C = gcd(C1, C2)
750
751  if (!n_IsOne(C, r))                              // if C != 1
752  {
753    C1=n_Div(C1, C, r);                              // C1 = C1 / C
754    C2=n_Div(C2, C, r);                              // C2 = C2 / C
755  }
756
757  n_Delete(&C,r); // destroy the number C
758
759  const int iSignSum = sca_Sign_mm_Mult_mm (m1, p1, r) + sca_Sign_mm_Mult_mm (m2, p2, r);
760  // zero if different signs
761
762  assume( (iSignSum*iSignSum == 0) || (iSignSum*iSignSum == 4) );
763
764  if( iSignSum != 0 ) // the same sign!
765    C2=n_Neg (C2, r);
766
767  p_SetCoeff(m1, C2, r);                           // lc(m1) = C2!!!
768  p_SetCoeff(m2, C1, r);                           // lc(m2) = C1!!!
769
770  poly tmp1 = mm_Mult_pp (m1, pNext(p1), r);    // tmp1 = m1 * tail(p1),
771  p_Delete(&m1,r);  //  => n_Delete(&C1,r);
772
773  poly tmp2 = mm_Mult_pp (m2, pNext(p2), r);    // tmp1 = m2 * tail(p2),
774  p_Delete(&m2,r);  //  => n_Delete(&C1,r);
775
776  poly spoly = p_Add_q (tmp1, tmp2, r); // spoly = spoly(lt(p1), lt(p2)) + m1 * tail(p1), delete tmp1,2
777
778  if (spoly!=NULL) pCleardenom (spoly); // r?
779//  if (spoly!=NULL) pContent (spoly); // r?
780
781#ifdef PDEBUG
782  p_Test (spoly, r);
783#endif
784
785  return(spoly);
786}
787
788
789
790
791/*2
792* reduction of p2 with p1
793* do not destroy p1, but p2
794* p1 divides p2 -> for use in NF algorithm
795*/
796poly sca_ReduceSpoly(const poly p1, poly p2, const ring r)
797{
798  assume( rIsSCA(r) );
799
800  assume( p1 != NULL );
801
802  const long lCompP1 = p_GetComp (p1, r);
803  const long lCompP2 = p_GetComp (p2, r);
804
805  if ((lCompP1!=lCompP2) && (lCompP1!=0) && (lCompP2!=0))
806  {
807#ifdef PDEBUG
808    Print("sca_ReduceSpoly: different non-zero components!");
809#endif
810    return(NULL);
811  }
812
813  poly m = p_ISet (1, r);
814  p_ExpVectorDiff (m, p2, p1, r);                      // m = lm(p2) / lm(p1)
815  //p_Setm(m,r);
816#ifdef PDEBUG
817  p_Test (m,r);
818#endif
819
820  number C1 = n_Copy( p_GetCoeff(p1, r), r);
821  number C2 = n_Copy( p_GetCoeff(p2, r), r);
822
823  /* GCD stuff */
824  number C = nGcd(C1, C2, r);
825
826  if (!n_IsOne(C, r))
827  {
828    C1 = n_Div(C1, C, r);
829    C2 = n_Div(C2, C, r);
830  }
831  n_Delete(&C,r);
832
833  const int iSign = sca_Sign_mm_Mult_mm( m, p1, r );
834
835  if(iSign == 1)
836    C2 = n_Neg(C2,r);
837
838  p_SetCoeff(m, C2, r);
839
840#ifdef PDEBUG
841  p_Test(m,r);
842#endif
843
844  p2 = p_LmDeleteAndNext( p2, r );
845
846  p2 = p_Mult_nn(p2, C1, r); // p2 !!!
847  n_Delete(&C1,r);
848
849  poly T = mm_Mult_pp(m, pNext(p1), r);
850  p_Delete(&m, r);
851
852  p2 = p_Add_q(p2, T, r);
853
854  if ( p2!=NULL ) pContent(p2); // r?
855
856#ifdef PDEBUG
857  p_Test(p2,r);
858#endif
859
860  return(p2);
861}
862
863
864void addLObject(LObject& h, kStrategy& strat)
865{
866  if(h.IsNull()) return;
867
868  strat->initEcart(&h);
869  h.sev=0; // pGetShortExpVector(h.p);
870
871  // add h into S and L
872  int pos=posInS(strat, strat->sl, h.p, h.ecart);
873
874  if ( (pos <= strat->sl) && (pComparePolys(h.p, strat->S[pos])) )
875  {
876    if (TEST_OPT_PROT)
877      PrintS("d\n");
878  }
879  else
880  {
881    if (TEST_OPT_INTSTRATEGY)
882    {
883      pCleardenom(h.p);
884    }
885    else
886    {
887      pNorm(h.p);
888      pContent(h.p);
889    }
890
891    if ((strat->syzComp==0)||(!strat->homog))
892    {
893      h.p = redtailBba(h.p,pos-1,strat);
894
895      if (TEST_OPT_INTSTRATEGY)
896      {
897//        pCleardenom(h.p);
898        pContent(h.p);
899      }
900      else
901      {
902        pNorm(h.p);
903      }
904    }
905
906    if(h.IsNull()) return;
907
908    /* statistic */
909    if (TEST_OPT_PROT)
910    {
911      PrintS("s\n");
912    }
913
914    if (TEST_OPT_DEBUG)
915    {
916      PrintS("new s:");
917      wrp(h.p);
918      PrintLn();
919    }
920
921    enterpairs(h.p, strat->sl, h.ecart, 0, strat);
922
923    pos=0;
924
925    if (strat->sl!=-1) pos = posInS(strat, strat->sl, h.p, h.ecart);
926
927    strat->enterS(h, pos, strat, -1);
928
929    if (h.lcm!=NULL) pLmFree(h.lcm);
930  }
931
932
933}
934
935
936ideal sca_gr_bba(const ideal F, const ideal Q, const intvec *, const intvec *, kStrategy strat)
937{
938  assume(rIsSCA(currRing));
939
940  BOOLEAN bIdHomog = id_IsYHomogeneous(F, currRing);
941
942  strat->homog = strat->homog && bIdHomog;
943
944#ifdef PDEBUG
945  assume( strat->homog == bIdHomog );
946#endif /*PDEBUG*/
947
948
949#if 0
950   PrintS("<sca::bba>\n");
951  {
952    Print("ideal F: \n");
953    for (int i = 0; i < F->idelems(); i++)
954    {
955      Print("; F[%d] = ", i+1);
956      p_Write(F->m[i], currRing);
957    }
958    Print(";\n");
959    PrintLn();
960  }
961#endif
962
963
964#ifdef PDEBUG
965//   PrintS("sca_gr_bba\n");
966#endif /*PDEBUG*/
967
968
969
970  int srmax, lrmax;
971  int olddeg, reduc;
972  int red_result = 1;
973  int hilbeledeg = 1, hilbcount = 0, minimcnt = 0;
974
975  initBuchMoraCrit(strat); // set Gebauer, honey, sugarCrit
976
977  gr_initBba(F,strat); // set enterS, red, initEcart, initEcartPair
978
979  initBuchMoraPos(strat);
980
981
982  // ?? set spSpolyShort, reduce ???
983
984  initBuchMora(F, NULL, strat); // Q  = squares!!!!!!!
985
986  strat->posInT=posInT110; // !!!
987
988  srmax = strat->sl;
989  reduc = olddeg = lrmax = 0;
990
991
992  const unsigned int m_iFirstAltVar = scaFirstAltVar(currRing);
993  const unsigned int m_iLastAltVar  = scaLastAltVar(currRing);
994
995
996
997
998  /* compute------------------------------------------------------- */
999  for(; strat->Ll >= 0;
1000#ifdef KDEBUG
1001    strat->P.lcm = NULL,
1002#endif
1003    kTest(strat)
1004    )
1005  {
1006    if (strat->Ll > lrmax) lrmax =strat->Ll;/*stat.*/
1007
1008    if (TEST_OPT_DEBUG) messageSets(strat);
1009
1010    if (strat->Ll== 0) strat->interpt=TRUE;
1011
1012    if (TEST_OPT_DEGBOUND
1013    && ((strat->honey
1014    && (strat->L[strat->Ll].ecart+pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
1015       || ((!strat->honey) && (pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))))
1016    {
1017      /*
1018      *stops computation if
1019      * 24 IN test and the degree +ecart of L[strat->Ll] is bigger then
1020      *a predefined number Kstd1_deg
1021      */
1022      while (strat->Ll >= 0) deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
1023      break;
1024    }
1025
1026    /* picks the last element from the lazyset L */
1027    strat->P = strat->L[strat->Ll];
1028    strat->Ll--;
1029
1030    //kTest(strat);
1031
1032    assume(pNext(strat->P.p) != strat->tail);
1033
1034//     if( pNext(strat->P.p) == strat->tail )
1035//     {
1036//       // deletes the int spoly and computes SPoly
1037//       pLmFree(strat->P.p); // ???
1038//       strat->P.p = sca_SPoly(strat->P.p1, strat->P.p2, currRing);
1039//     }
1040
1041    if(strat->P.IsNull()) continue;
1042
1043//     poly save = NULL;
1044//
1045//     if(pNext(strat->P.p) != NULL)
1046//       save = p_Copy(strat->P.p, currRing);
1047
1048    strat->initEcart(&strat->P); // remove it?
1049
1050    if (TEST_OPT_PROT)
1051      message((strat->honey ? strat->P.ecart : 0) + strat->P.pFDeg(), &olddeg,&reduc,strat, red_result);
1052
1053    // reduction of the element chosen from L wrt S
1054    strat->red(&strat->P,strat);
1055
1056    if(strat->P.IsNull()) continue;
1057
1058    addLObject(strat->P, strat);
1059
1060    if (strat->sl > srmax) srmax = strat->sl;
1061
1062    ////////////// children !!!!!!!!!!!!!
1063
1064    const poly save = strat->P.p;
1065
1066//     if( save != NULL )
1067    {
1068
1069#ifdef PDEBUG
1070      p_Test(save, currRing);
1071#endif
1072
1073      const poly pNext = pNext(save);
1074
1075      for( unsigned int i = m_iFirstAltVar; i <= m_iLastAltVar; i++ )
1076      if( p_GetExp(save, i, currRing) )
1077      {
1078        const poly tt = xi_Mult_pp(i, pNext, currRing);
1079
1080#ifdef PDEBUG
1081        p_Test(tt, currRing);
1082#endif
1083
1084        if( tt == NULL) continue;
1085
1086        LObject h(tt); // h = x_i * P
1087
1088        if (TEST_OPT_INTSTRATEGY)
1089        {
1090//           h.pCleardenom(); // also does a pContent
1091          pContent(h.p);
1092        }
1093        else
1094        {
1095          h.pNorm();
1096        }
1097
1098        strat->initEcart(&h);
1099
1100
1101//         if (pOrdSgn==-1)
1102//         {
1103//           cancelunit(&h);  // tries to cancel a unit
1104//           deleteHC(&h, strat);
1105//         }
1106
1107//         if(h.IsNull()) continue;
1108
1109//         if (TEST_OPT_PROT)
1110//           message((strat->honey ? h.ecart : 0) + h.pFDeg(), &olddeg, &reduc, strat, red_result);
1111
1112//         strat->red(&h, strat); // wrt S
1113//         if(h.IsNull()) continue;
1114
1115
1116  //       poly save = p_Copy(h.p, currRing);
1117
1118        int pos;
1119
1120        if (strat->Ll==-1)
1121          pos =0;
1122        else
1123          pos = strat->posInL(strat->L,strat->Ll,&h,strat);
1124
1125        h.sev = pGetShortExpVector(h.p);
1126        enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
1127
1128  //       h.p = save;
1129  //       addLObject(h, strat);
1130
1131//         if (strat->sl > srmax) srmax = strat->sl;
1132      }
1133
1134      // p_Delete( &save, currRing );
1135    }
1136
1137
1138  } // for(;;)
1139
1140
1141  if (TEST_OPT_DEBUG) messageSets(strat);
1142
1143  /* release temp data-------------------------------- */
1144  exitBuchMora(strat);
1145
1146  if (TEST_OPT_WEIGHTM)
1147  {
1148    pFDeg=pFDegOld;
1149    pLDeg=pLDegOld;
1150    if (ecartWeights)
1151    {
1152      omFreeSize((ADDRESS)ecartWeights,(pVariables+1)*sizeof(int));
1153      ecartWeights=NULL;
1154    }
1155  }
1156
1157  if (TEST_OPT_PROT) messageStat(srmax,lrmax,hilbcount,strat);
1158
1159//  if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
1160
1161
1162  /* complete reduction of the standard basis--------- */
1163  if (TEST_OPT_REDSB){
1164//     completeReduce(strat); // ???
1165
1166    ideal I = strat->Shdl;
1167    ideal erg = kInterRed(I,NULL);
1168    assume(I!=erg);
1169    id_Delete(&I, currRing);
1170    strat->Shdl = erg;
1171  }
1172
1173
1174#if 0
1175  {
1176    Print("ideal S: \n");
1177    for (int i = 0; i < F->idelems(); i++)
1178    {
1179      Print("; S[%d] = ", 1+i);
1180      p_Write(F->m[i], currRing);
1181    }
1182    Print(";\n");
1183    PrintLn();
1184  }
1185
1186   PrintS("</sca::bba>\n");
1187#endif
1188
1189  return (strat->Shdl);
1190}
1191
1192
1193// is this an exterior algebra or a commuunative polynomial ring \otimes exterior algebra?
1194// we should check whether qr->qideal is of the form: y_i^2, y_{i+1}^2, \ldots, y_j^2 (j > i)
1195//.if yes, setup qr->nc->type, etc.
1196bool SetupSCA(ring& rGR, const ring rG)
1197{
1198//   return false; // test Plural
1199
1200  //////////////////////////////////////////////////////////////////////////
1201  // checks...
1202  //////////////////////////////////////////////////////////////////////////
1203  assume(rGR != NULL);
1204  assume(rG  != NULL);
1205
1206  assume(rIsPluralRing(rG));
1207
1208  const int N = rG->N;
1209  if(N < 2)
1210    return false;
1211
1212  // skew-commutative + constant skew? => no tensor products at the moment!!! Only exterior algebras are supported!
1213
1214//   if( rG->nc->D != NULL )
1215//     return false;
1216
1217  if(ncRingType(rG) != nc_skew)
1218    return false;
1219
1220  if(rG->nc->IsSkewConstant != 1)
1221    return false;
1222
1223  if(!n_IsMOne(p_GetCoeff(MATELEM(rG->nc->COM,1,2),rG->nc->basering), rG->nc->basering)) // COM live in basering!
1224    return false;
1225
1226  assume(rGR->qideal != NULL);
1227
1228  // sort qr->qideal:
1229
1230  // for sanity
1231  ring rSaveRing = currRing;
1232
1233  bool bWeChangeRing = false;
1234  if(currRing != rG)
1235  {
1236    rChangeCurrRing(rG);
1237    bWeChangeRing = true;
1238  }
1239
1240  const ideal idQuotient = rGR->qideal;
1241  const int   iQSize = idQuotient->idelems();
1242
1243  intvec *iv = idSort(idQuotient, FALSE); // by lex, currRing dependent!!! :(
1244  assume(iv != NULL);
1245
1246  // check for y_{iAltVarStart}^2, y_{iAltVarStart+1}^2, \ldots, y_{iAltVarEnd}^2 (iAltVarEnd > iAltVarStart)
1247  bool bSCA = true;
1248
1249  int iAltVarStart = -1;
1250  int iAltVarEnd   = -1;
1251
1252  for(int i = 0; i < iQSize; i++)
1253  {
1254    const poly t = idQuotient->m[(*iv)[i]-1];
1255
1256    if( pNext(t) != NULL )
1257    {
1258      bSCA = false;
1259      break;
1260    }
1261
1262    const int iComp = p_GetComp(t, rG);
1263
1264    if( iComp > 0 )
1265    {
1266      bSCA = false;
1267      break;
1268    }
1269
1270    int iV = -1;
1271
1272    for (int j = N; j; j--)
1273    {
1274      const int e = p_GetExp (t, j, rGR);
1275
1276      if( e > 0 )
1277      {
1278        if( (e != 2) || (iV != -1) )
1279        {
1280          bSCA = false;
1281          break;
1282        }
1283
1284        iV = j;
1285      }
1286    }
1287
1288    if(!bSCA) break;
1289
1290    if(iV == -1)
1291    {
1292      bSCA = false;
1293      break;
1294    }
1295
1296    if(iAltVarStart == -1)
1297    {
1298      iAltVarStart = iV;
1299      iAltVarEnd   = iV;
1300    } else
1301    {
1302      if((iAltVarStart-1) == iV)
1303      {
1304        iAltVarStart = iV;
1305      } else
1306      if((iAltVarEnd+1) == iV)
1307      {
1308        iAltVarEnd = iV;
1309      } else
1310      {
1311        bSCA = false;
1312        break;
1313      }
1314    }
1315  }
1316
1317  // cleanup:
1318  delete iv;
1319
1320  if (bWeChangeRing)
1321  {
1322    rChangeCurrRing(rSaveRing);
1323  }
1324
1325
1326  if(!bSCA) return false;
1327
1328  assume( 1            <= iAltVarStart );
1329  assume( iAltVarStart <= iAltVarEnd   );
1330  assume( iAltVarEnd   <= N            );
1331
1332
1333/*
1334  // Anti-commutative (c_{ij} = -1)?
1335  for( int i = iAltVarStart; i < iAltVarEnd; i++ )
1336    for( int j = i + 1; i <= iAltVarEnd; j++ )
1337      if(!n_IsMOne(p_GetCoeff(MATELEM(rG->nc->COM,i,j),rG->nc->basering), rG->nc->basering)) // COM live in basering!
1338        return false;
1339
1340
1341  for( int i = 1; i < iAltVarStart-1; i++ )
1342    for( int j = i + 1; i < iAltVarStart; j++ )
1343      if(!n_IsOne(p_GetCoeff(MATELEM(rG->nc->COM,i,j),rG->nc->basering), rG->nc->basering)) // COM live in basering!
1344        return false;
1345
1346
1347  for( int i = iAltVarEnd+1; i < N; i++ )
1348    for( int j = i + 1; i <= N; j++ )
1349      if(!n_IsOne(p_GetCoeff(MATELEM(rG->nc->COM,i,j),rG->nc->basering), rG->nc->basering)) // COM live in basering!
1350        return false;
1351*/
1352
1353  //////////////////////////////////////////////////////////////////////////
1354  // ok... let's setup it!!!
1355  //////////////////////////////////////////////////////////////////////////
1356
1357  ncRingType( rGR, nc_exterior );
1358
1359  scaFirstAltVar( rGR, iAltVarStart );
1360  scaLastAltVar( rGR, iAltVarEnd );
1361
1362  // ????????????????????????????????????????????????????????????????????????????????
1363  // check ordering!!! alternating variables must be bigger than all other variables?
1364
1365  SetProcsSCA(rGR, rGR->p_Procs);
1366
1367  return true;
1368}
1369
1370// return x_i * pPoly; preserve pPoly.
1371poly xi_Mult_pp(unsigned int i, const poly pPoly, const ring rRing)
1372{
1373  assume(1 <= i);
1374  assume(i <= rRing->N);
1375
1376  if(rIsSCA(rRing))
1377    return sca_xi_Mult_pp(i, pPoly, rRing);
1378
1379
1380
1381  poly xi =  p_ISet(1, rRing);
1382  p_SetExp(xi, i, 1, rRing);
1383  p_Setm(xi, rRing);
1384
1385  poly pResult = pp_Mult_qq(xi, pPoly, rRing);
1386
1387  p_Delete( &xi, rRing);
1388
1389  return pResult;
1390
1391}
1392
1393
1394///////////////////////////////////////////////////////////////////////////////////////
1395//************* SCA BBA *************************************************************//
1396///////////////////////////////////////////////////////////////////////////////////////
1397
1398// Under development!!!
1399ideal sca_bba (const ideal F, const ideal Q, const intvec *w, const intvec *hilb, kStrategy strat)
1400{
1401  assume(rIsSCA(currRing));
1402
1403  BOOLEAN bIdHomog = id_IsYHomogeneous(F, currRing);
1404
1405  strat->homog = strat->homog && bIdHomog;
1406
1407#ifdef PDEBUG
1408  assume( strat->homog == bIdHomog );
1409#endif /*PDEBUG*/
1410
1411
1412//    PrintS("<sca>\n");
1413
1414  om_Opts.MinTrack = 5; // ???
1415
1416  int   srmax, lrmax, red_result = 1;
1417  int   olddeg, reduc;
1418  int hilbeledeg=1, hilbcount=0, minimcnt=0;
1419
1420  BOOLEAN withT = FALSE;
1421
1422  initBuchMoraCrit(strat); // sets Gebauer, honey, sugarCrit // sca - ok???
1423  initBuchMoraPos(strat); // sets strat->posInL, strat->posInT // check!! (Plural's: )
1424
1425//   initHilbCrit(F, Q, &hilb, strat);
1426
1427//  gr_initBba(F,strat);
1428  initBba(F, strat); // set enterS, red, initEcart, initEcartPair
1429
1430  /*set enterS, spSpolyShort, reduce, red, initEcart, initEcartPair*/
1431  // ?? set spSpolyShort, reduce ???
1432  initBuchMora(F, NULL, strat); // Q = squares!!!
1433
1434//   if (strat->minim>0) strat->M = idInit(IDELEMS(F),F->rank);
1435
1436  srmax = strat->sl;
1437  reduc = olddeg = lrmax = 0;
1438
1439#define NO_BUCKETS
1440
1441#ifndef NO_BUCKETS
1442  if (!TEST_OPT_NOT_BUCKETS)
1443    strat->use_buckets = 1;
1444#endif
1445
1446  // redtailBBa against T for inhomogenous input
1447  if (!K_TEST_OPT_OLDSTD)
1448    withT = ! strat->homog;
1449
1450  // strat->posInT = posInT_pLength;
1451  kTest_TS(strat);
1452
1453#undef HAVE_TAIL_RING
1454
1455#ifdef HAVE_TAIL_RING
1456  kStratInitChangeTailRing(strat);
1457#endif
1458
1459  ///////////////////////////////////////////////////////////////
1460  // SCA:
1461  const unsigned short m_iFirstAltVar = scaFirstAltVar(currRing);
1462  const unsigned short m_iLastAltVar  = scaLastAltVar(currRing);
1463
1464
1465
1466  /* compute------------------------------------------------------- */
1467  while (strat->Ll >= 0)
1468  {
1469    if (strat->Ll > lrmax) lrmax =strat->Ll;/*stat.*/
1470
1471#ifdef KDEBUG
1472//     loop_count++;
1473    if (TEST_OPT_DEBUG) messageSets(strat);
1474#endif
1475
1476    if (strat->Ll== 0) strat->interpt=TRUE;
1477
1478    if (TEST_OPT_DEGBOUND
1479        && ((strat->honey && (strat->L[strat->Ll].ecart+pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
1480            || ((!strat->honey) && (pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))))
1481    {
1482      /*
1483       *stops computation if
1484       * 24 IN test and the degree +ecart of L[strat->Ll] is bigger then
1485       *a predefined number Kstd1_deg
1486       */
1487      while ((strat->Ll >= 0)
1488  && (strat->L[strat->Ll].p1!=NULL) && (strat->L[strat->Ll].p2!=NULL)
1489        && ((strat->honey && (strat->L[strat->Ll].ecart+pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg))
1490            || ((!strat->honey) && (pFDeg(strat->L[strat->Ll].p,currRing)>Kstd1_deg)))
1491  )
1492        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
1493      if (strat->Ll<0) break;
1494      else strat->noClearS=TRUE;
1495    }
1496
1497    /* picks the last element from the lazyset L */
1498    strat->P = strat->L[strat->Ll];
1499    strat->Ll--;
1500
1501
1502    assume(pNext(strat->P.p) != strat->tail);
1503
1504/*    if (pNext(strat->P.p) == strat->tail)
1505    {
1506      // deletes the short spoly
1507      pLmFree(strat->P.p);
1508      strat->P.p = NULL;
1509      poly m1 = NULL, m2 = NULL;
1510
1511      // check that spoly creation is ok
1512      while (strat->tailRing != currRing &&
1513             !kCheckSpolyCreation(&(strat->P), strat, m1, m2))
1514      {
1515        assume(m1 == NULL && m2 == NULL);
1516        // if not, change to a ring where exponents are at least
1517        // large enough
1518        kStratChangeTailRing(strat);
1519      }
1520
1521#ifdef PDEBUG
1522      Print("ksCreateSpoly!#?");
1523#endif
1524
1525      // create the real one
1526      ksCreateSpoly(&(strat->P), NULL, strat->use_buckets,
1527                    strat->tailRing, m1, m2, strat->R); //?????????
1528    }
1529    else */
1530
1531    if (strat->P.p1 == NULL)
1532    {
1533//       if (strat->minim > 0)
1534//         strat->P.p2=p_Copy(strat->P.p, currRing, strat->tailRing);
1535
1536
1537      // for input polys, prepare reduction
1538      strat->P.PrepareRed(strat->use_buckets);
1539    }
1540
1541    if (TEST_OPT_PROT)
1542      message((strat->honey ? strat->P.ecart : 0) + strat->P.pFDeg(),
1543              &olddeg,&reduc,strat, red_result);
1544
1545    /* reduction of the element choosen from L */
1546    red_result = strat->red(&strat->P,strat);
1547
1548
1549    // reduction to non-zero new poly
1550    if (red_result == 1)
1551    {
1552      /* statistic */
1553      if (TEST_OPT_PROT) PrintS("s");
1554
1555      // get the polynomial (canonicalize bucket, make sure P.p is set)
1556      strat->P.GetP(strat->lmBin);
1557
1558      int pos = posInS(strat,strat->sl,strat->P.p,strat->P.ecart);
1559
1560      // reduce the tail and normalize poly
1561      if (TEST_OPT_INTSTRATEGY)
1562      {
1563        strat->P.pCleardenom();
1564        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
1565        {
1566          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT); // !!!
1567          strat->P.pCleardenom();
1568
1569        }
1570      }
1571      else
1572      {
1573
1574        strat->P.pNorm();
1575        if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
1576          strat->P.p = redtailBba(&(strat->P),pos-1,strat, withT);
1577      }
1578
1579
1580#ifdef KDEBUG
1581      if (TEST_OPT_DEBUG){PrintS(" ns:");strat->P.wrp();PrintLn();}
1582#endif
1583
1584//       // min_std stuff
1585//       if ((strat->P.p1==NULL) && (strat->minim>0))
1586//       {
1587//         if (strat->minim==1)
1588//         {
1589//           strat->M->m[minimcnt]=p_Copy(strat->P.p,currRing,strat->tailRing);
1590//           p_Delete(&strat->P.p2, currRing, strat->tailRing);
1591//         }
1592//         else
1593//         {
1594//           strat->M->m[minimcnt]=strat->P.p2;
1595//           strat->P.p2=NULL;
1596//         }
1597//         if (strat->tailRing!=currRing && pNext(strat->M->m[minimcnt])!=NULL)
1598//           pNext(strat->M->m[minimcnt])
1599//             = strat->p_shallow_copy_delete(pNext(strat->M->m[minimcnt]),
1600//                                            strat->tailRing, currRing,
1601//                                            currRing->PolyBin);
1602//         minimcnt++;
1603//       }
1604
1605      // enter into S, L, and T
1606      if(withT)
1607        enterT(strat->P, strat);
1608
1609      // L
1610      enterpairs(strat->P.p,strat->sl,strat->P.ecart,pos,strat, strat->tl);
1611
1612      // posInS only depends on the leading term
1613      strat->enterS(strat->P, pos, strat, strat->tl);
1614
1615//       if (hilb!=NULL) khCheck(Q,w,hilb,hilbeledeg,hilbcount,strat);
1616
1617//      Print("[%d]",hilbeledeg);
1618      if (strat->P.lcm!=NULL) pLmFree(strat->P.lcm);
1619
1620      if (strat->sl>srmax) srmax = strat->sl;
1621
1622      // //////////////////////////////////////////////////////////
1623      // SCA:
1624      const poly pSave = strat->P.p;
1625      const poly pNext = pNext(pSave);
1626
1627//       if(0)
1628      for( unsigned short i = m_iFirstAltVar; i <= m_iLastAltVar; i++ )
1629      if( p_GetExp(pSave, i, currRing) )
1630      {
1631        const poly pNew = xi_Mult_pp(i, pNext, currRing);
1632
1633#ifdef PDEBUG
1634        p_Test(pNew, currRing);
1635#endif
1636
1637        if( pNew == NULL) continue;
1638
1639        LObject h(pNew); // h = x_i * strat->P
1640
1641        if (TEST_OPT_INTSTRATEGY)
1642        {
1643//           h.pCleardenom(); // also does a pContent
1644          pContent(h.p);
1645        }
1646        else
1647        {
1648          h.pNorm();
1649        }
1650
1651        strat->initEcart(&h);
1652        h.sev = pGetShortExpVector(h.p);
1653
1654        int pos;
1655
1656        if (strat->Ll==-1)
1657          pos =0;
1658        else
1659          pos = strat->posInL(strat->L,strat->Ll,&h,strat);
1660
1661        enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
1662
1663
1664/*
1665        h.sev = pGetShortExpVector(h.p);
1666        strat->initEcart(&h);
1667
1668        h.PrepareRed(strat->use_buckets);
1669
1670        // reduction of the element choosen from L(?)
1671        red_result = strat->red(&h,strat);
1672
1673        // reduction to non-zero new poly
1674        if (red_result != 1) continue;
1675
1676
1677        int pos = posInS(strat,strat->sl,h.p,h.ecart);
1678
1679        // reduce the tail and normalize poly
1680        if (TEST_OPT_INTSTRATEGY)
1681        {
1682          h.pCleardenom();
1683          if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
1684          {
1685            h.p = redtailBba(&(h),pos-1,strat, withT); // !!!
1686            h.pCleardenom();
1687          }
1688        }
1689        else
1690        {
1691
1692          h.pNorm();
1693          if ((TEST_OPT_REDSB)||(TEST_OPT_REDTAIL))
1694            h.p = redtailBba(&(h),pos-1,strat, withT);
1695        }
1696
1697
1698  #ifdef KDEBUG
1699        if (TEST_OPT_DEBUG){PrintS(" N:");h.wrp();PrintLn();}
1700  #endif
1701
1702//         h.PrepareRed(strat->use_buckets); // ???
1703
1704        h.sev = pGetShortExpVector(h.p);
1705        strat->initEcart(&h);
1706
1707        if (strat->Ll==-1)
1708          pos = 0;
1709        else
1710          pos = strat->posInL(strat->L,strat->Ll,&h,strat);
1711
1712         enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);*/
1713
1714      } // for all x_i \in Ann(lm(P))
1715
1716
1717
1718
1719
1720    } // if red(P) != NULL
1721
1722//     else if (strat->P.p1 == NULL && strat->minim > 0)
1723//     {
1724//       p_Delete(&strat->P.p2, currRing, strat->tailRing);
1725//     }
1726
1727// #ifdef KDEBUG
1728    memset(&(strat->P), 0, sizeof(strat->P));
1729// #endif
1730
1731    kTest_TS(strat);
1732
1733//     Print("\n$\n");
1734
1735  }
1736
1737#ifdef KDEBUG
1738  if (TEST_OPT_DEBUG) messageSets(strat);
1739#endif
1740
1741  /* complete reduction of the standard basis--------- */
1742  if (TEST_OPT_REDSB) completeReduce(strat);
1743
1744  /* release temp data-------------------------------- */
1745
1746  exitBuchMora(strat);
1747
1748  if (TEST_OPT_WEIGHTM)
1749  {
1750    pRestoreDegProcs(pFDegOld, pLDegOld);
1751    if (ecartWeights)
1752    {
1753      omFreeSize((ADDRESS)ecartWeights,(pVariables+1)*sizeof(short));
1754      ecartWeights=NULL;
1755    }
1756  }
1757
1758  if (TEST_OPT_PROT) messageStat(srmax,lrmax,hilbcount,strat);
1759
1760//   if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
1761
1762//    PrintS("</sca>\n");
1763
1764  return (strat->Shdl);
1765}
1766
1767
1768
1769// y-Degree
1770inline long p_yDegree(const poly p, const ring r)
1771{
1772  assume(rIsSCA(r));
1773
1774  const unsigned short m_iFirstAltVar = scaFirstAltVar(r);
1775  const unsigned short m_iLastAltVar  = scaLastAltVar(r);
1776
1777  long sum = 0;
1778
1779  for(int i = m_iFirstAltVar; i <= m_iLastAltVar; i++)
1780    sum += p_GetExp(p, i, r);
1781
1782  return sum;
1783}
1784
1785
1786
1787
1788/**2
1789 * tests whether p is sca-homogeneous without respect to the actual weigths(=>all ones)
1790 */
1791BOOLEAN p_IsYHomogeneous(const poly p, const ring r)
1792{
1793  assume(rIsSCA(r));
1794
1795  if( p == NULL ) return TRUE;
1796
1797  poly q = p;
1798
1799  const long o = p_yDegree(q, r);
1800  pIter(q);
1801
1802  while( q != NULL )
1803  {
1804    if (p_yDegree(q,r) != o) return FALSE;
1805    pIter(q);
1806  }
1807
1808  return TRUE;
1809}
1810
1811
1812/*2
1813*returns true if id is y-homogenous without respect to the aktual weights(=> all ones)
1814*/
1815BOOLEAN id_IsYHomogeneous(const ideal id, const ring r)
1816{
1817  if (id == NULL) return TRUE;
1818
1819  const int iSize = IDELEMS(id);
1820
1821  if (iSize == 0) return TRUE;
1822
1823  BOOLEAN b = TRUE;
1824
1825  for(int i = iSize - 1; (i >= 0 ) && b; i--)
1826    b = p_IsYHomogeneous(id->m[i], r);
1827
1828  return b;
1829}
1830
1831// //////////////////////////////////////////////////////////////////////////////
1832// sca mora...
1833
1834// returns TRUE if mora should use buckets, false otherwise
1835static BOOLEAN kMoraUseBucket(kStrategy strat)
1836{
1837#ifdef MORA_USE_BUCKETS
1838  if (TEST_OPT_NOT_BUCKETS)
1839    return FALSE;
1840  if (strat->red == redFirst)
1841  {
1842#ifdef NO_LDEG
1843    if (!strat->syzComp)
1844      return TRUE;
1845#else
1846    if ((strat->homog || strat->honey) && !strat->syzComp)
1847      return TRUE;
1848#endif
1849  }
1850  else
1851  {
1852    assume(strat->red == redEcart);
1853    if (strat->honey && !strat->syzComp)
1854      return TRUE;
1855  }
1856#endif
1857  return FALSE;
1858}
1859
1860
1861#ifdef HAVE_ASSUME
1862static int sca_mora_count = 0;
1863static int sca_mora_loop_count;
1864#endif
1865
1866// ideal sca_mora (ideal F, ideal Q, intvec *w, intvec *, kStrategy strat)
1867ideal sca_mora(const ideal F, const ideal Q, const intvec *w, const intvec *, kStrategy strat)
1868{
1869  BOOLEAN bIdHomog = id_IsYHomogeneous(F, currRing);
1870
1871  strat->homog = strat->homog && bIdHomog;
1872
1873#ifdef PDEBUG
1874  assume( strat->homog == bIdHomog );
1875#endif /*PDEBUG*/
1876
1877
1878#ifdef HAVE_ASSUME
1879  sca_mora_count++;
1880  sca_mora_loop_count = 0;
1881#endif
1882#ifdef KDEBUG
1883  om_Opts.MinTrack = 5;
1884#endif
1885  int srmax;
1886  int lrmax = 0;
1887  int olddeg = 0;
1888  int reduc = 0;
1889  int red_result = 1;
1890  int hilbeledeg=1,hilbcount=0;
1891
1892  strat->update = TRUE;
1893  /*- setting global variables ------------------- -*/
1894  initBuchMoraCrit(strat);
1895//   initHilbCrit(F,NULL,&hilb,strat); // no Q!
1896  initMora(F,strat);
1897  initBuchMoraPos(strat);
1898  /*Shdl=*/initBuchMora(F,NULL,strat); // no Q!
1899//   if (TEST_OPT_FASTHC) missingAxis(&strat->lastAxis,strat);
1900  /*updateS in initBuchMora has Hecketest
1901  * and could have put strat->kHEdgdeFound FALSE*/
1902#if 0
1903  if (ppNoether!=NULL)
1904  {
1905    strat->kHEdgeFound = TRUE;
1906  }
1907  if (strat->kHEdgeFound && strat->update)
1908  {
1909    firstUpdate(strat);
1910    updateLHC(strat);
1911    reorderL(strat);
1912  }
1913  if (TEST_OPT_FASTHC && (strat->lastAxis) && strat->posInLOldFlag)
1914  {
1915    strat->posInLOld = strat->posInL;
1916    strat->posInLOldFlag = FALSE;
1917    strat->posInL = posInL10;
1918    updateL(strat);
1919    reorderL(strat);
1920  }
1921#endif
1922
1923  srmax = strat->sl;
1924  kTest_TS(strat);
1925
1926  strat->use_buckets = kMoraUseBucket(strat);
1927  /*- compute-------------------------------------------*/
1928
1929#undef HAVE_TAIL_RING
1930
1931#ifdef HAVE_TAIL_RING
1932//  if (strat->homog && strat->red == redFirst)
1933//     kStratInitChangeTailRing(strat);
1934#endif
1935
1936
1937  // 4SCA:
1938  const unsigned short m_iFirstAltVar = scaFirstAltVar(currRing);
1939  const unsigned short m_iLastAltVar  = scaLastAltVar(currRing);
1940
1941  while (strat->Ll >= 0)
1942  {
1943#ifdef HAVE_ASSUME
1944    sca_mora_loop_count++;
1945#endif
1946    if (lrmax< strat->Ll) lrmax=strat->Ll; /*stat*/
1947    //test_int_std(strat->kIdeal);
1948    if (TEST_OPT_DEBUG) messageSets(strat);
1949    if (TEST_OPT_DEGBOUND
1950    && (strat->L[strat->Ll].ecart+strat->L[strat->Ll].GetpFDeg()> Kstd1_deg))
1951    {
1952      /*
1953      * stops computation if
1954      * - 24 (degBound)
1955      *   && upper degree is bigger than Kstd1_deg
1956      */
1957      while ((strat->Ll >= 0)
1958        && (strat->L[strat->Ll].p1!=NULL) && (strat->L[strat->Ll].p2!=NULL)
1959        && (strat->L[strat->Ll].ecart+strat->L[strat->Ll].GetpFDeg()> Kstd1_deg)
1960      )
1961      {
1962        deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
1963        //if (TEST_OPT_PROT)
1964        //{
1965        //   PrintS("D"); mflush();
1966        //}
1967      }
1968      if (strat->Ll<0) break;
1969      else strat->noClearS=TRUE;
1970    }
1971    strat->P = strat->L[strat->Ll];/*- picks the last element from the lazyset L -*/
1972    if (strat->Ll==0) strat->interpt=TRUE;
1973    strat->Ll--;
1974
1975    // create the real Spoly
1976    assume(pNext(strat->P.p) != strat->tail);
1977
1978    if (strat->P.p1 == NULL)
1979    {
1980      // for input polys, prepare reduction (buckets !)
1981      strat->P.SetLength(strat->length_pLength);
1982      strat->P.PrepareRed(strat->use_buckets);
1983    }
1984
1985    if (!strat->P.IsNull())
1986    {
1987      // might be NULL from noether !!!
1988      if (TEST_OPT_PROT)
1989        message(strat->P.ecart+strat->P.GetpFDeg(),&olddeg,&reduc,strat, red_result);
1990      // reduce
1991      red_result = strat->red(&strat->P,strat);
1992    }
1993
1994    if (! strat->P.IsNull())
1995    {
1996      strat->P.GetP();
1997      // statistics
1998      if (TEST_OPT_PROT) PrintS("s");
1999      // normalization
2000      if (!TEST_OPT_INTSTRATEGY)
2001        strat->P.pNorm();
2002      // tailreduction
2003      strat->P.p = redtail(&(strat->P),strat->sl,strat);
2004      // set ecart -- might have changed because of tail reductions
2005      if ((!strat->noTailReduction) && (!strat->honey))
2006        strat->initEcart(&strat->P);
2007      // cancel unit
2008      cancelunit(&strat->P);
2009      // for char 0, clear denominators
2010      if (TEST_OPT_INTSTRATEGY)
2011        strat->P.pCleardenom();
2012
2013      // put in T
2014      enterT(strat->P,strat);
2015      // build new pairs
2016      enterpairs(strat->P.p,strat->sl,strat->P.ecart,0,strat, strat->tl);
2017      // put in S
2018      strat->enterS(strat->P,
2019                    posInS(strat,strat->sl,strat->P.p, strat->P.ecart),
2020                    strat, strat->tl);
2021
2022
2023      // clear strat->P
2024      if (strat->P.lcm!=NULL) pLmFree(strat->P.lcm);
2025      strat->P.lcm=NULL;
2026
2027      if (strat->sl>srmax) srmax = strat->sl; /*stat.*/
2028      if (strat->Ll>lrmax) lrmax = strat->Ll;
2029
2030
2031
2032      // //////////////////////////////////////////////////////////
2033      // SCA:
2034      const poly pSave = strat->P.p;
2035      const poly pNext = pNext(pSave);
2036
2037//       if(0)
2038      for( unsigned short i = m_iFirstAltVar; i <= m_iLastAltVar; i++ )
2039      if( p_GetExp(pSave, i, currRing) )
2040      {
2041
2042        assume(p_GetExp(pSave, i, currRing) == 1);
2043
2044        const poly pNew = xi_Mult_pp(i, pNext, currRing);
2045
2046#ifdef PDEBUG
2047        p_Test(pNew, currRing);
2048#endif
2049
2050        if( pNew == NULL) continue;
2051
2052        LObject h(pNew); // h = x_i * strat->P
2053
2054        if (TEST_OPT_INTSTRATEGY)
2055           h.pCleardenom(); // also does a pContent
2056        else
2057          h.pNorm();
2058
2059        strat->initEcart(&h);
2060        h.sev = pGetShortExpVector(h.p);
2061
2062        int pos;
2063
2064        if (strat->Ll==-1)
2065          pos = 0;
2066        else
2067          pos = strat->posInL(strat->L,strat->Ll,&h,strat);
2068
2069        enterL(&strat->L,&strat->Ll,&strat->Lmax,h,pos);
2070
2071        if (strat->Ll>lrmax) lrmax = strat->Ll;
2072      }
2073
2074#ifdef KDEBUG
2075      // make sure kTest_TS does not complain about strat->P
2076      memset(&strat->P,0,sizeof(strat->P));
2077#endif
2078    }
2079#if 0
2080    if (strat->kHEdgeFound)
2081    {
2082      if ((BTEST1(27))
2083      || ((TEST_OPT_MULTBOUND) && (scMult0Int((strat->Shdl)) < mu)))
2084      {
2085        // obachman: is this still used ???
2086        /*
2087        * stops computation if strat->kHEdgeFound and
2088        * - 27 (finiteDeterminacyTest)
2089        * or
2090        * - 23
2091        *   (multBound)
2092        *   && multiplicity of the ideal is smaller then a predefined number mu
2093        */
2094        while (strat->Ll >= 0) deleteInL(strat->L,&strat->Ll,strat->Ll,strat);
2095      }
2096    }
2097#endif
2098    kTest_TS(strat);
2099  }
2100  /*- complete reduction of the standard basis------------------------ -*/
2101  if (TEST_OPT_REDSB) completeReduce(strat);
2102  /*- release temp data------------------------------- -*/
2103  exitBuchMora(strat);
2104  /*- polynomials used for HECKE: HC, noether -*/
2105  if (BTEST1(27))
2106  {
2107    if (strat->kHEdge!=NULL)
2108      Kstd1_mu=pFDeg(strat->kHEdge,currRing);
2109    else
2110      Kstd1_mu=-1;
2111  }
2112  pDelete(&strat->kHEdge);
2113  strat->update = TRUE; //???
2114  strat->lastAxis = 0; //???
2115  pDelete(&strat->kNoether);
2116  omFreeSize((ADDRESS)strat->NotUsedAxis,(pVariables+1)*sizeof(BOOLEAN));
2117  if (TEST_OPT_PROT) messageStat(srmax,lrmax,hilbcount,strat);
2118  if (TEST_OPT_WEIGHTM)
2119  {
2120    pRestoreDegProcs(pFDegOld, pLDegOld);
2121    if (ecartWeights)
2122    {
2123      omFreeSize((ADDRESS)ecartWeights,(pVariables+1)*sizeof(short));
2124      ecartWeights=NULL;
2125    }
2126  }
2127//   if (Q!=NULL) updateResult(strat->Shdl,Q,strat);
2128  idTest(strat->Shdl);
2129  return (strat->Shdl);
2130}
2131
2132
2133
2134
2135
2136
2137void SetProcsSCA(ring& rGR, p_Procs_s* p_Procs)
2138{
2139
2140  // "commutative" procedures:
2141  rGR->p_Procs->p_Mult_mm     = sca_p_Mult_mm;
2142  rGR->p_Procs->pp_Mult_mm    = sca_pp_Mult_mm;
2143
2144  p_Procs->p_Mult_mm          = sca_p_Mult_mm;
2145  p_Procs->pp_Mult_mm         = sca_pp_Mult_mm;
2146
2147  // non-commutaitve
2148  rGR->nc->p_Procs.mm_Mult_p   = sca_mm_Mult_p;
2149  rGR->nc->p_Procs.mm_Mult_pp  = sca_mm_Mult_pp;
2150
2151
2152  if (pOrdSgn==-1)
2153    rGR->nc->p_Procs.GB          = sca_mora; // local ordering => Mora, otherwise - Buchberger!
2154  else
2155    rGR->nc->p_Procs.GB          = sca_gr_bba; // sca_bba?
2156
2157
2158//   rGR->nc->p_Procs.GlobalGB    = sca_gr_bba;
2159//   rGR->nc->p_Procs.LocalGB     = sca_mora;
2160
2161
2162//   rGR->nc->p_Procs.SPoly         = sca_SPoly;
2163//   rGR->nc->p_Procs.ReduceSPoly   = sca_ReduceSpoly;
2164
2165#if 0
2166
2167        // Multiplication procedures:
2168
2169        p_Procs->p_Mult_mm   = sca_p_Mult_mm;
2170        _p_procs->p_Mult_mm  = sca_p_Mult_mm;
2171
2172        p_Procs->pp_Mult_mm  = sca_pp_Mult_mm;
2173        _p_procs->pp_Mult_mm = sca_pp_Mult_mm;
2174
2175        r->nc->mmMultP()     = sca_mm_Mult_p;
2176        r->nc->mmMultPP()    = sca_mm_Mult_pp;
2177
2178        r->nc->GB()            = sca_gr_bba;
2179/*
2180        // ??????????????????????????????????????? coefficients swell...
2181        r->nc->SPoly()         = sca_SPoly;
2182        r->nc->ReduceSPoly()   = sca_ReduceSpoly;
2183*/
2184//         r->nc->BucketPolyRed() = gnc_kBucketPolyRed;
2185//         r->nc->BucketPolyRed_Z()= gnc_kBucketPolyRed_Z;
2186
2187#endif
2188}
Note: See TracBrowser for help on using the repository browser.