source: git/kernel/sca.cc @ e6f7da9

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