source: git/libpolys/polys/nc/sca.cc @ f7a975

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