My Project
ring.cc
Go to the documentation of this file.
1/****************************************
2* Computer Algebra System SINGULAR *
3****************************************/
4/*
5* ABSTRACT - the interpreter related ring operations
6*/
7
8/* includes */
9#include <cmath>
10
11#include "misc/auxiliary.h"
12#include "misc/mylimits.h"
13#include "misc/options.h"
14#include "misc/int64vec.h"
15
16#include "coeffs/numbers.h"
17#include "coeffs/coeffs.h"
18
20#include "polys/simpleideals.h"
23#include "polys/prCopy.h"
25
26#include "polys/matpol.h"
27
29
30#ifdef HAVE_PLURAL
31#include "polys/nc/nc.h"
32#include "polys/nc/sca.h"
33#endif
34
35
36#include "ext_fields/algext.h"
37#include "ext_fields/transext.h"
38
39
40#define BITS_PER_LONG 8*SIZEOF_LONG
41
42typedef char * char_ptr;
45
46
47static const char * const ringorder_name[] =
48{
49 " ?", ///< ringorder_no = 0,
50 "a", ///< ringorder_a,
51 "A", ///< ringorder_a64,
52 "c", ///< ringorder_c,
53 "C", ///< ringorder_C,
54 "M", ///< ringorder_M,
55 "S", ///< ringorder_S,
56 "s", ///< ringorder_s,
57 "lp", ///< ringorder_lp,
58 "dp", ///< ringorder_dp,
59 "rp", ///< ringorder_rp,
60 "Dp", ///< ringorder_Dp,
61 "wp", ///< ringorder_wp,
62 "Wp", ///< ringorder_Wp,
63 "ls", ///< ringorder_ls,
64 "ds", ///< ringorder_ds,
65 "Ds", ///< ringorder_Ds,
66 "ws", ///< ringorder_ws,
67 "Ws", ///< ringorder_Ws,
68 "am", ///< ringorder_am,
69 "L", ///< ringorder_L,
70 "aa", ///< ringorder_aa
71 "rs", ///< ringorder_rs,
72 "IS", ///< ringorder_IS
73 " _" ///< ringorder_unspec
74};
75
76
77const char * rSimpleOrdStr(int ord)
78{
79 return ringorder_name[ord];
80}
81
82/// unconditionally deletes fields in r
83void rDelete(ring r);
84/// set r->VarL_Size, r->VarL_Offset, r->VarL_LowIndex
85static void rSetVarL(ring r);
86/// get r->divmask depending on bits per exponent
87static unsigned long rGetDivMask(int bits);
88/// right-adjust r->VarOffset
89static void rRightAdjustVarOffset(ring r);
90static void rOptimizeLDeg(ring r);
91
92/*0 implementation*/
93//BOOLEAN rField_is_R(ring r)
94//{
95// if (r->cf->ch== -1)
96// {
97// if (r->float_len==(short)0) return TRUE;
98// }
99// return FALSE;
100//}
101
102ring rDefault(const coeffs cf, int N, char **n,int ord_size, rRingOrder_t *ord, int *block0, int *block1, int** wvhdl, unsigned long bitmask)
103{
104 assume( cf != NULL);
105 ring r=(ring) omAlloc0Bin(sip_sring_bin);
106 r->N = N;
107 r->cf = cf;
108 /*rPar(r) = 0; Alloc0 */
109 /*names*/
110 r->names = (char **) omAlloc0(N * sizeof(char *));
111 int i;
112 for(i=0;i<N;i++)
113 {
114 r->names[i] = omStrDup(n[i]);
115 }
116 /*weights: entries for 2 blocks: NULL*/
117 if (wvhdl==NULL)
118 r->wvhdl = (int **)omAlloc0((ord_size+1) * sizeof(int *));
119 else
120 r->wvhdl=wvhdl;
121 r->order = ord;
122 r->block0 = block0;
123 r->block1 = block1;
124 if (bitmask!=0) r->wanted_maxExp=bitmask;
125
126 /* complete ring intializations */
127 rComplete(r);
128 return r;
129}
130ring rDefault(int ch, int N, char **n,int ord_size, rRingOrder_t *ord, int *block0, int *block1,int ** wvhdl)
131{
132 coeffs cf;
133 if (ch==0) cf=nInitChar(n_Q,NULL);
134 else cf=nInitChar(n_Zp,(void*)(long)ch);
135 assume( cf != NULL);
136 return rDefault(cf,N,n,ord_size,ord,block0,block1,wvhdl);
137}
138ring rDefault(const coeffs cf, int N, char **n, const rRingOrder_t o)
139{
140 assume( cf != NULL);
141 /*order: o=lp,0*/
142 rRingOrder_t *order = (rRingOrder_t *) omAlloc(2* sizeof(rRingOrder_t));
143 int *block0 = (int *)omAlloc0(2 * sizeof(int));
144 int *block1 = (int *)omAlloc0(2 * sizeof(int));
145 /* ringorder o=lp for the first block: var 1..N */
146 order[0] = o;
147 block0[0] = 1;
148 block1[0] = N;
149 /* the last block: everything is 0 */
150 order[1] = (rRingOrder_t)0;
151
152 return rDefault(cf,N,n,2,order,block0,block1);
153}
154
155ring rDefault(int ch, int N, char **n)
156{
157 coeffs cf;
158 if (ch==0) cf=nInitChar(n_Q,NULL);
159 else cf=nInitChar(n_Zp,(void*)(long)ch);
160 assume( cf != NULL);
161 return rDefault(cf,N,n);
162}
163
164///////////////////////////////////////////////////////////////////////////
165//
166// rInit: define a new ring from sleftv's
167//
168//-> ipshell.cc
169
170/////////////////////////////
171// Auxillary functions
172//
173
174// check intvec, describing the ordering
176{
177 if ((iv->length()!=2)&&(iv->length()!=3))
178 {
179 WerrorS("weights only for orderings wp,ws,Wp,Ws,a,M");
180 return TRUE;
181 }
182 return FALSE;
183}
184
185int rTypeOfMatrixOrder(const intvec* order)
186{
187 int i=0,j,typ=1;
188 int sz = (int)sqrt((double)(order->length()-2));
189 if ((sz*sz)!=(order->length()-2))
190 {
191 WerrorS("Matrix order is not a square matrix");
192 typ=0;
193 }
194 while ((i<sz) && (typ==1))
195 {
196 j=0;
197 while ((j<sz) && ((*order)[j*sz+i+2]==0)) j++;
198 if (j>=sz)
199 {
200 typ = 0;
201 WerrorS("Matrix order not complete");
202 }
203 else if ((*order)[j*sz+i+2]<0)
204 typ = -1;
205 else
206 i++;
207 }
208 return typ;
209}
210
211
212int r_IsRingVar(const char *n, char**names,int N)
213{
214 if (names!=NULL)
215 {
216 for (int i=0; i<N; i++)
217 {
218 if (names[i]==NULL) return -1;
219 if (strcmp(n,names[i]) == 0) return (int)i;
220 }
221 }
222 return -1;
223}
224
225
226void rWrite(ring r, BOOLEAN details)
227{
228 if ((r==NULL)||(r->order==NULL))
229 return; /*to avoid printing after errors....*/
230
231 assume(r != NULL);
232 const coeffs C = r->cf;
233 assume(C != NULL);
234
235 int nblocks=rBlocks(r);
236
237 // omCheckAddrSize(r,sizeof(ip_sring));
238 omCheckAddrSize(r->order,nblocks*sizeof(int));
239 omCheckAddrSize(r->block0,nblocks*sizeof(int));
240 omCheckAddrSize(r->block1,nblocks*sizeof(int));
241 omCheckAddrSize(r->wvhdl,nblocks*sizeof(int *));
242 omCheckAddrSize(r->names,r->N*sizeof(char *));
243
244 nblocks--;
245
246
247 //Print("ref:%d, C->ref:%d\n",r->ref,C->ref);
248 PrintS("// coefficients: ");
249 if( nCoeff_is_algExt(C) )
250 {
251 // NOTE: the following (non-thread-safe!) UGLYNESS
252 // (changing naRing->ShortOut for a while) is due to Hans!
253 // Just think of other ring using the VERY SAME naRing and possible
254 // side-effects...
255 ring R = C->extRing;
256 const BOOLEAN bSaveShortOut = rShortOut(R); R->ShortOut = rShortOut(r) & rCanShortOut(R);
257
258 n_CoeffWrite(C, details); // for correct printing of minpoly... WHAT AN UGLYNESS!!!
259
260 R->ShortOut = bSaveShortOut;
261 }
262 else
263 n_CoeffWrite(C, details);
264 PrintLn();
265// {
266// PrintS("// characteristic : ");
267//
268// char const * const * const params = rParameter(r);
269//
270// if (params!=NULL)
271// {
272// Print ("// %d parameter : ",rPar(r));
273//
274// char const * const * sp= params;
275// int nop=0;
276// while (nop<rPar(r))
277// {
278// PrintS(*sp);
279// PrintS(" ");
280// sp++; nop++;
281// }
282// PrintS("\n// minpoly : ");
283// if ( rField_is_long_C(r) )
284// {
285// // i^2+1:
286// Print("(%s^2+1)\n", params[0]);
287// }
288// else if (rMinpolyIsNULL(r))
289// {
290// PrintS("0\n");
291// }
292// else
293// {
294// StringSetS(""); n_Write(r->cf->minpoly, r); PrintS(StringEndS("\n")); // NOTE/TODO: use StringAppendS("\n"); omFree(s);
295// }
296// //if (r->qideal!=NULL)
297// //{
298// // iiWriteMatrix((matrix)r->qideal,"// minpolys",1,r,0);
299// // PrintLn();
300// //}
301// }
302// }
303 Print("// number of vars : %d",r->N);
304
305 //for (nblocks=0; r->order[nblocks]; nblocks++);
306 nblocks=rBlocks(r)-1;
307
308 for (int l=0, nlen=0 ; l<nblocks; l++)
309 {
310 int i;
311 Print("\n// block %3d : ",l+1);
312
313 Print("ordering %s", rSimpleOrdStr(r->order[l]));
314
315
316 if (r->order[l] == ringorder_IS)
317 {
318 assume( r->block0[l] == r->block1[l] );
319 const int s = r->block0[l];
320 assume( (-2 < s) && (s < 2) );
321 Print("(%d)", s); // 0 => prefix! +/-1 => suffix!
322 continue;
323 }
324 else if (r->order[l]==ringorder_s)
325 {
326 assume( l == 0 );
327 Print(" syz_comp: %d",r->block0[l]);
328 continue;
329 }
330 else if (
331 ( (r->order[l] >= ringorder_lp)
332 ||(r->order[l] == ringorder_M)
333 ||(r->order[l] == ringorder_a)
334 ||(r->order[l] == ringorder_am)
335 ||(r->order[l] == ringorder_a64)
336 ||(r->order[l] == ringorder_aa) ) && (r->order[l] < ringorder_IS) )
337 {
338 PrintS("\n// : names ");
339 for (i = r->block0[l]-1; i<r->block1[l]; i++)
340 {
341 nlen = strlen(r->names[i]);
342 Print(" %s",r->names[i]);
343 }
344 }
345
346 if (r->wvhdl[l]!=NULL)
347 {
348 #ifndef SING_NDEBUG
349 if((r->order[l] != ringorder_wp)
350 &&(r->order[l] != ringorder_Wp)
351 &&(r->order[l] != ringorder_ws)
352 &&(r->order[l] != ringorder_Ws)
353 &&(r->order[l] != ringorder_a)
354 &&(r->order[l] != ringorder_a64)
355 &&(r->order[l] != ringorder_am)
356 &&(r->order[l] != ringorder_M))
357 {
358 Warn("should not have wvhdl entry at pos. %d",l);
359 }
360 #endif
361 for (int j= 0;
362 j<(r->block1[l]-r->block0[l]+1)*(r->block1[l]-r->block0[l]+1);
363 j+=i)
364 {
365 PrintS("\n// : weights ");
366 for (i = 0; i<=r->block1[l]-r->block0[l]; i++)
367 {
368 if (r->order[l] == ringorder_a64)
369 {
370 int64 *w=(int64 *)r->wvhdl[l];
371 #if SIZEOF_LONG == 4
372 Print("%*lld " ,nlen,w[i+j]);
373 #else
374 Print(" %*ld" ,nlen,w[i+j]);
375 #endif
376 }
377 else
378 Print(" %*d" ,nlen,r->wvhdl[l][i+j]);
379 }
380 if (r->order[l]!=ringorder_M) break;
381 }
382 if (r->order[l]==ringorder_am)
383 {
384 int m=r->wvhdl[l][i];
385 Print("\n// : %d module weights ",m);
386 m+=i;i++;
387 for(;i<=m;i++) Print(" %*d" ,nlen,r->wvhdl[l][i]);
388 }
389 }
390 }
391#ifdef HAVE_PLURAL
392 if(rIsPluralRing(r))
393 {
394 PrintS("\n// noncommutative relations:");
395 if( details )
396 {
397 poly pl=NULL;
398 int nl;
399 int i,j;
400 for (i = 1; i<r->N; i++)
401 {
402 for (j = i+1; j<=r->N; j++)
403 {
404 nl = n_IsOne(p_GetCoeff(MATELEM(r->GetNC()->C,i,j),r), r->cf);
405 if ( (MATELEM(r->GetNC()->D,i,j)!=NULL) || (!nl) )
406 {
407 Print("\n// %s%s=",r->names[j-1],r->names[i-1]);
408 pl = MATELEM(r->GetNC()->MT[UPMATELEM(i,j,r->N)],1,1);
409 p_Write0(pl, r, r);
410 }
411 }
412 }
413 } else
414 PrintS(" ...");
415
416#if MYTEST /*Singularg should not differ from Singular except in error case*/
417 Print("\n// noncommutative type:%d", (int)ncRingType(r));
418 Print("\n// is skew constant:%d",r->GetNC()->IsSkewConstant);
419 if( rIsSCA(r) )
420 {
421 Print("\n// alternating variables: [%d, %d]", scaFirstAltVar(r), scaLastAltVar(r));
422 const ideal Q = SCAQuotient(r); // resides within r!
423 PrintS("\n// quotient of sca by ideal");
424
425 if (Q!=NULL)
426 {
427 iiWriteMatrix((matrix)Q,"scaQ",1,r,0);
428 }
429 else
430 PrintS(" (NULL)");
431 }
432#endif
433 }
434 if (rIsLPRing(r))
435 {
436 Print("\n// letterplace ring (block size %d, ncgen count %d)",r->isLPring, r->LPncGenCount);
437 }
438#endif
439 if (r->qideal!=NULL)
440 {
441 PrintS("\n// quotient ring from ideal");
442 if( details )
443 {
444 PrintLn();
445 iiWriteMatrix((matrix)r->qideal,"_",1,r,0);
446 } else PrintS(" ...");
447 }
448}
449
450void rDelete(ring r)
451{
452 int i, j;
453
454 if (r == NULL) return;
455 if( r->ref > 0 ) // ->ref means the number of Interpreter objects referring to the ring...
456 return;
457
458 if( r->qideal != NULL )
459 {
460 ideal q = r->qideal;
461 r->qideal = NULL;
462 id_Delete(&q, r);
463 }
464
465#ifdef HAVE_PLURAL
466 if (rIsPluralRing(r))
467 nc_rKill(r);
468#endif
469
470 rUnComplete(r); // may need r->cf for p_Delete
471 nKillChar(r->cf); r->cf = NULL;
472 // delete order stuff
473 if (r->order != NULL)
474 {
475 i=rBlocks(r);
476 assume(r->block0 != NULL && r->block1 != NULL && r->wvhdl != NULL);
477 // delete order
478 omFreeSize((ADDRESS)r->order,i*sizeof(rRingOrder_t));
479 omFreeSize((ADDRESS)r->block0,i*sizeof(int));
480 omFreeSize((ADDRESS)r->block1,i*sizeof(int));
481 // delete weights
482 for (j=0; j<i; j++)
483 {
484 if (r->wvhdl[j]!=NULL)
485 omFree(r->wvhdl[j]);
486 }
487 omFreeSize((ADDRESS)r->wvhdl,i*sizeof(int *));
488 }
489 else
490 {
491 assume(r->block0 == NULL && r->block1 == NULL && r->wvhdl == NULL);
492 }
493
494 // delete varnames
495 if(r->names!=NULL)
496 {
497 for (i=0; i<r->N; i++)
498 {
499 if (r->names[i] != NULL) omFree((ADDRESS)r->names[i]);
500 }
501 omFreeSize((ADDRESS)r->names,r->N*sizeof(char *));
502 }
503
505}
506
507rRingOrder_t rOrderName(char * ordername)
508{
509 int order=ringorder_unspec;
510 while (order!= 0)
511 {
512 if (strcmp(ordername,rSimpleOrdStr(order))==0)
513 break;
514 order--;
515 }
516 if (order==0) Werror("wrong ring order `%s`",ordername);
517 omFree((ADDRESS)ordername);
518 return (rRingOrder_t)order;
519}
520
521char * rOrdStr(ring r)
522{
523 if ((r==NULL)||(r->order==NULL)) return omStrDup("");
524 int nblocks,l,i;
525
526 for (nblocks=0; r->order[nblocks]; nblocks++);
527 nblocks--;
528
529 StringSetS("");
530 for (l=0; ; l++)
531 {
532 StringAppendS((char *)rSimpleOrdStr(r->order[l]));
533 if (r->order[l] == ringorder_s)
534 {
535 StringAppend("(%d)",r->block0[l]);
536 }
537 else if (
538 (r->order[l] != ringorder_c)
539 && (r->order[l] != ringorder_C)
540 && (r->order[l] != ringorder_s)
541 && (r->order[l] != ringorder_S)
542 && (r->order[l] != ringorder_IS)
543 )
544 {
545 if (r->wvhdl[l]!=NULL)
546 {
547 #ifndef SING_NDEBUG
548 if((r->order[l] != ringorder_wp)
549 &&(r->order[l] != ringorder_Wp)
550 &&(r->order[l] != ringorder_ws)
551 &&(r->order[l] != ringorder_Ws)
552 &&(r->order[l] != ringorder_a)
553 &&(r->order[l] != ringorder_a64)
554 &&(r->order[l] != ringorder_am)
555 &&(r->order[l] != ringorder_M))
556 {
557 Warn("should not have wvhdl entry at pos. %d",l);
558 StringAppend("(%d)",r->block1[l]-r->block0[l]+1);
559 }
560 else
561 #endif
562 {
563 StringAppendS("(");
564 for (int j= 0;
565 j<(r->block1[l]-r->block0[l]+1)*(r->block1[l]-r->block0[l]+1);
566 j+=i+1)
567 {
568 char c=',';
569 if(r->order[l]==ringorder_a64)
570 {
571 int64 * w=(int64 *)r->wvhdl[l];
572 for (i = 0; i<r->block1[l]-r->block0[l]; i++)
573 {
574 StringAppend("%lld," ,w[i]);
575 }
576 StringAppend("%lld)" ,w[i]);
577 break;
578 }
579 else
580 {
581 for (i = 0; i<r->block1[l]-r->block0[l]; i++)
582 {
583 StringAppend("%d," ,r->wvhdl[l][i+j]);
584 }
585 }
586 if (r->order[l]!=ringorder_M)
587 {
588 StringAppend("%d)" ,r->wvhdl[l][i+j]);
589 break;
590 }
591 if (j+i+1==(r->block1[l]-r->block0[l]+1)*(r->block1[l]-r->block0[l]+1))
592 c=')';
593 StringAppend("%d%c" ,r->wvhdl[l][i+j],c);
594 }
595 }
596 }
597 else
598 StringAppend("(%d)",r->block1[l]-r->block0[l]+1);
599 }
600 else if (r->order[l] == ringorder_IS)
601 {
602 assume( r->block0[l] == r->block1[l] );
603 const int s = r->block0[l];
604 assume( (-2 < s) && (s < 2) );
605
606 StringAppend("(%d)", s);
607 }
608
609 if (l==nblocks)
610 {
611 if (r->wanted_maxExp!=0)
612 {
613 long mm=r->wanted_maxExp;
614 if (mm>MAX_INT_VAL) mm=MAX_INT_VAL;
615 StringAppend(",L(%ld)",mm);
616 }
617 return StringEndS();
618 }
619 StringAppendS(",");
620 }
621}
622
623char * rVarStr(ring r)
624{
625 if ((r==NULL)||(r->names==NULL)) return omStrDup("");
626 int i;
627 int l=2;
628 char *s;
629
630 for (i=0; i<r->N; i++)
631 {
632 l+=strlen(r->names[i])+1;
633 }
634 s=(char *)omAlloc((long)l);
635 s[0]='\0';
636 for (i=0; i<r->N-1; i++)
637 {
638 strcat(s,r->names[i]);
639 strcat(s,",");
640 }
641 strcat(s,r->names[i]);
642 return s;
643}
644
645/// TODO: make it a virtual method of coeffs, together with:
646/// Decompose & Compose, rParameter & rPar
647char * rCharStr(const ring r){ assume( r != NULL ); return nCoeffString(r->cf); }
648
649char * rParStr(ring r)
650{
651 if ((r==NULL)||(rParameter(r)==NULL)) return omStrDup("");
652
653 char const * const * const params = rParameter(r);
654
655 int i;
656 int l=2;
657
658 for (i=0; i<rPar(r); i++)
659 {
660 l+=strlen(params[i])+1;
661 }
662 char *s=(char *)omAlloc((long)l);
663 s[0]='\0';
664 for (i=0; i<rPar(r)-1; i++)
665 {
666 strcat(s, params[i]);
667 strcat(s,",");
668 }
669 strcat(s, params[i]);
670 return s;
671}
672
673char * rString(ring r)
674{
675 if ((r!=NULL)&&(r->cf!=NULL))
676 {
677 char *ch=rCharStr(r);
678 char *var=rVarStr(r);
679 char *ord=rOrdStr(r);
680 char *res=(char *)omAlloc(strlen(ch)+strlen(var)+strlen(ord)+9);
681 sprintf(res,"(%s),(%s),(%s)",ch,var,ord);
682 omFree((ADDRESS)ch);
683 omFree((ADDRESS)var);
684 omFree((ADDRESS)ord);
685 return res;
686 }
687 else
688 return omStrDup("undefined");
689}
690
691
692/*
693// The fowolling function seems to be never used. Remove?
694static int binaryPower (const int a, const int b)
695{
696 // computes a^b according to the binary representation of b,
697 // i.e., a^7 = a^4 * a^2 * a^1. This saves some multiplications.
698 int result = 1;
699 int factor = a;
700 int bb = b;
701 while (bb != 0)
702 {
703 if (bb % 2 != 0) result = result * factor;
704 bb = bb / 2;
705 factor = factor * factor;
706 }
707 return result;
708}
709*/
710
711/* we keep this otherwise superfluous method for compatibility reasons
712 towards the SINGULAR svn trunk */
713int rChar(ring r) { return r->cf->ch; }
714
715
716
717// creates a commutative nc extension; "converts" comm.ring to a Plural ring
718#ifdef HAVE_PLURAL
720{
721 r = rCopy(r);
722 if (rIsPluralRing(r))
723 return r;
724
725 matrix C = mpNew(r->N,r->N); // ring-independent!?!
726 matrix D = mpNew(r->N,r->N);
727
728 for(int i=1; i<r->N; i++)
729 for(int j=i+1; j<=r->N; j++)
730 MATELEM(C,i,j) = p_One( r);
731
732 if (nc_CallPlural(C, D, NULL, NULL, r, false, true, false, r/*??currRing??*/, TRUE)) // TODO: what about quotient ideal?
733 WarnS("Error initializing multiplication!"); // No reaction!???
734
735 return r;
736}
737#endif
738
739
740/*2
741 *returns -1 for not compatible, (sum is undefined)
742 * 1 for compatible (and sum)
743 */
744/* vartest: test for variable/paramter names
745* dp_dp: 0:block ordering
746* 1:for comm. rings: use block order dp + dp/ds/wp
747* 2:order aa(..),dp
748*/
749int rSumInternal(ring r1, ring r2, ring &sum, BOOLEAN vartest, BOOLEAN dp_dp)
750{
751
752 ip_sring tmpR;
753 memset(&tmpR,0,sizeof(tmpR));
754 /* check coeff. field =====================================================*/
755
756 if (r1->cf==r2->cf)
757 {
758 tmpR.cf=nCopyCoeff(r1->cf);
759 }
760 else /* different type */
761 {
762 if (getCoeffType(r1->cf)==n_Zp)
763 {
764 if (getCoeffType(r2->cf)==n_Q)
765 {
766 tmpR.cf=nCopyCoeff(r1->cf);
767 }
768 else if (nCoeff_is_Extension(r2->cf) && rChar(r2) == rChar(r1))
769 {
770 /*AlgExtInfo extParam;
771 extParam.r = r2->cf->extRing;
772 extParam.i = r2->cf->extRing->qideal;*/
773 tmpR.cf=nCopyCoeff(r2->cf);
774 }
775 else
776 {
777 WerrorS("Z/p+...");
778 return -1;
779 }
780 }
781 else if ((getCoeffType(r1->cf)==n_Zn)||(getCoeffType(r1->cf)==n_Znm))
782 {
783 if (getCoeffType(r2->cf)==n_Q)
784 {
785 tmpR.cf=nCopyCoeff(r1->cf);
786 }
787 else if (nCoeff_is_Extension(r2->cf)
788 && (mpz_cmp(r1->cf->modNumber,r2->cf->extRing->cf->modNumber)==0))
789 { // covers transext.cc and algext.cc
790 tmpR.cf=nCopyCoeff(r2->cf);
791 }
792 else
793 {
794 WerrorS("Z/n+...");
795 return -1;
796 }
797 }
798 else if (getCoeffType(r1->cf)==n_R)
799 {
800 WerrorS("R+..");
801 return -1;
802 }
803 else if (getCoeffType(r1->cf)==n_Q)
804 {
805 if (getCoeffType(r2->cf)==n_Zp)
806 {
807 tmpR.cf=nCopyCoeff(r2->cf);
808 }
809 else if (nCoeff_is_Extension(r2->cf))
810 {
811 tmpR.cf=nCopyCoeff(r2->cf);
812 }
813 else
814 {
815 WerrorS("Q+...");
816 return -1;
817 }
818 }
819 else if (nCoeff_is_Extension(r1->cf))
820 {
821 if (r1->cf->extRing->cf==r2->cf)
822 {
823 tmpR.cf=nCopyCoeff(r1->cf);
824 }
825 else if (getCoeffType(r1->cf->extRing->cf)==n_Zp && getCoeffType(r2->cf)==n_Q) //r2->cf == n_Zp should have been handled above
826 {
827 tmpR.cf=nCopyCoeff(r1->cf);
828 }
829 else
830 {
831 WerrorS ("coeff sum of two extension fields not implemented");
832 return -1;
833 }
834 }
835 else
836 {
837 WerrorS("coeff sum not yet implemented");
838 return -1;
839 }
840 }
841 /* variable names ========================================================*/
842 int i,j,k;
843 int l=r1->N+r2->N;
844 char **names=(char **)omAlloc0(l*sizeof(char *));
845 k=0;
846
847 // collect all varnames from r1, except those which are parameters
848 // of r2, or those which are the empty string
849 for (i=0;i<r1->N;i++)
850 {
851 BOOLEAN b=TRUE;
852
853 if (*(r1->names[i]) == '\0')
854 b = FALSE;
855 else if ((rParameter(r2)!=NULL) && (strlen(r1->names[i])==1))
856 {
857 if (vartest)
858 {
859 for(j=0;j<rPar(r2);j++)
860 {
861 if (strcmp(r1->names[i],rParameter(r2)[j])==0)
862 {
863 b=FALSE;
864 break;
865 }
866 }
867 }
868 }
869
870 if (b)
871 {
872 //Print("name : %d: %s\n",k,r1->names[i]);
873 names[k]=omStrDup(r1->names[i]);
874 k++;
875 }
876 //else
877 // Print("no name (par1) %s\n",r1->names[i]);
878 }
879 // Add variables from r2, except those which are parameters of r1
880 // those which are empty strings, and those which equal a var of r1
881 for(i=0;i<r2->N;i++)
882 {
883 BOOLEAN b=TRUE;
884
885 if (*(r2->names[i]) == '\0')
886 b = FALSE;
887 else if ((rParameter(r1)!=NULL) && (strlen(r2->names[i])==1))
888 {
889 if (vartest)
890 {
891 for(j=0;j<rPar(r1);j++)
892 {
893 if (strcmp(r2->names[i],rParameter(r1)[j])==0)
894 {
895 b=FALSE;
896 break;
897 }
898 }
899 }
900 }
901
902 if (b)
903 {
904 if (vartest)
905 {
906 for(j=0;j<r1->N;j++)
907 {
908 if (strcmp(r1->names[j],r2->names[i])==0)
909 {
910 b=FALSE;
911 break;
912 }
913 }
914 }
915 if (b)
916 {
917 //Print("name : %d : %s\n",k,r2->names[i]);
918 names[k]=omStrDup(r2->names[i]);
919 k++;
920 }
921 //else
922 // Print("no name (var): %s\n",r2->names[i]);
923 }
924 //else
925 // Print("no name (par): %s\n",r2->names[i]);
926 }
927 // check whether we found any vars at all
928 if (k == 0)
929 {
930 names[k]=omStrDup("");
931 k=1;
932 }
933 tmpR.N=k;
934 tmpR.names=names;
935 /* ordering *======================================================== */
936 tmpR.OrdSgn=0;
937 if ((dp_dp==2)
938 && (r1->OrdSgn==1)
939 && (r2->OrdSgn==1)
940#ifdef HAVE_PLURAL
941 && !rIsPluralRing(r1) && !rIsPluralRing(r2)
942#endif
943 )
944 {
945 tmpR.order=(rRingOrder_t*)omAlloc0(4*sizeof(rRingOrder_t));
946 tmpR.block0=(int*)omAlloc0(4*sizeof(int));
947 tmpR.block1=(int*)omAlloc0(4*sizeof(int));
948 tmpR.wvhdl=(int**) omAlloc0(4*sizeof(int**));
949 // ----
950 tmpR.block0[0] = 1;
951 tmpR.block1[0] = rVar(r1)+rVar(r2);
952 tmpR.order[0] = ringorder_aa;
953 tmpR.wvhdl[0]=(int*)omAlloc0((rVar(r1)+rVar(r2) + 1)*sizeof(int));
954 for(int i=0;i<rVar(r1);i++) tmpR.wvhdl[0][i]=1;
955 // ----
956 tmpR.block0[1] = 1;
957 tmpR.block1[1] = rVar(r1)+rVar(r2);
958 tmpR.order[1] = ringorder_dp;
959 // ----
960 tmpR.order[2] = ringorder_C;
961 }
962 else if (dp_dp
963#ifdef HAVE_PLURAL
964 && !rIsPluralRing(r1) && !rIsPluralRing(r2)
965#endif
966 )
967 {
968 tmpR.order=(rRingOrder_t*)omAlloc(4*sizeof(rRingOrder_t));
969 tmpR.block0=(int*)omAlloc0(4*sizeof(int));
970 tmpR.block1=(int*)omAlloc0(4*sizeof(int));
971 tmpR.wvhdl=(int**)omAlloc0(4*sizeof(int *));
972 tmpR.order[0]=ringorder_dp;
973 tmpR.block0[0]=1;
974 tmpR.block1[0]=rVar(r1);
975 if (r2->OrdSgn==1)
976 {
977 if ((r2->block0[0]==1)
978 && (r2->block1[0]==rVar(r2))
979 && ((r2->order[0]==ringorder_wp)
980 || (r2->order[0]==ringorder_Wp)
981 || (r2->order[0]==ringorder_Dp))
982 )
983 {
984 tmpR.order[1]=r2->order[0];
985 if (r2->wvhdl[0]!=NULL)
986 #ifdef HAVE_OMALLOC
987 tmpR.wvhdl[1]=(int *)omMemDup(r2->wvhdl[0]);
988 #else
989 {
990 int l=r2->block1[0]-r2->block0[0]+1;
991 if (r2->order[0]==ringorder_a64) l*=2;
992 else if (r2->order[0]==ringorder_M) l=l*l;
993 else if (r2->order[0]==ringorder_am)
994 {
995 l+=r2->wvhdl[1][r2->block1[0]-r2->block0[0]+1]+1;
996 }
997 tmpR.wvhdl[1]=(int*)omalloc(l*sizeof(int));
998 memcpy(tmpR.wvhdl[1],r2->wvhdl[0],l*sizeof(int));
999 }
1000 #endif
1001 }
1002 else
1003 tmpR.order[1]=ringorder_dp;
1004 }
1005 else
1006 {
1007 tmpR.order[1]=ringorder_ds;
1008 tmpR.OrdSgn=-1;
1009 }
1010 tmpR.block0[1]=rVar(r1)+1;
1011 tmpR.block1[1]=rVar(r1)+rVar(r2);
1012 tmpR.order[2]=ringorder_C;
1013 tmpR.order[3]=(rRingOrder_t)0;
1014 }
1015 else
1016 {
1017 if ((r1->order[0]==ringorder_unspec)
1018 && (r2->order[0]==ringorder_unspec))
1019 {
1020 tmpR.order=(rRingOrder_t*)omAlloc(3*sizeof(rRingOrder_t));
1021 tmpR.block0=(int*)omAlloc(3*sizeof(int));
1022 tmpR.block1=(int*)omAlloc(3*sizeof(int));
1023 tmpR.wvhdl=(int**)omAlloc0(3*sizeof(int *));
1024 tmpR.order[0]=ringorder_unspec;
1025 tmpR.order[1]=ringorder_C;
1026 tmpR.order[2]=(rRingOrder_t)0;
1027 tmpR.block0[0]=1;
1028 tmpR.block1[0]=tmpR.N;
1029 }
1030 else if (l==k) /* r3=r1+r2 */
1031 {
1032 int b;
1033 ring rb;
1034 if (r1->order[0]==ringorder_unspec)
1035 {
1036 /* extend order of r2 to r3 */
1037 b=rBlocks(r2);
1038 rb=r2;
1039 tmpR.OrdSgn=r2->OrdSgn;
1040 }
1041 else if (r2->order[0]==ringorder_unspec)
1042 {
1043 /* extend order of r1 to r3 */
1044 b=rBlocks(r1);
1045 rb=r1;
1046 tmpR.OrdSgn=r1->OrdSgn;
1047 }
1048 else
1049 {
1050 b=rBlocks(r1)+rBlocks(r2)-2; /* for only one order C, only one 0 */
1051 rb=NULL;
1052 }
1053 tmpR.order=(rRingOrder_t*)omAlloc0(b*sizeof(rRingOrder_t));
1054 tmpR.block0=(int*)omAlloc0(b*sizeof(int));
1055 tmpR.block1=(int*)omAlloc0(b*sizeof(int));
1056 tmpR.wvhdl=(int**)omAlloc0(b*sizeof(int *));
1057 /* weights not implemented yet ...*/
1058 if (rb!=NULL)
1059 {
1060 for (i=0;i<b;i++)
1061 {
1062 tmpR.order[i]=rb->order[i];
1063 tmpR.block0[i]=rb->block0[i];
1064 tmpR.block1[i]=rb->block1[i];
1065 if (rb->wvhdl[i]!=NULL)
1066 WarnS("rSum: weights not implemented");
1067 }
1068 tmpR.block0[0]=1;
1069 }
1070 else /* ring sum for complete rings */
1071 {
1072 for (i=0;r1->order[i]!=0;i++)
1073 {
1074 tmpR.order[i]=r1->order[i];
1075 tmpR.block0[i]=r1->block0[i];
1076 tmpR.block1[i]=r1->block1[i];
1077 if (r1->wvhdl[i]!=NULL)
1078 #ifdef HAVE_OMALLOC
1079 tmpR.wvhdl[i] = (int*) omMemDup(r1->wvhdl[i]);
1080 #else
1081 {
1082 int l=r1->block1[i]-r1->block0[i]+1;
1083 if (r1->order[i]==ringorder_a64) l*=2;
1084 else if (r1->order[i]==ringorder_M) l=l*l;
1085 else if (r1->order[i]==ringorder_am)
1086 {
1087 l+=r1->wvhdl[i][r1->block1[i]-r1->block0[i]+1]+1;
1088 }
1089 tmpR.wvhdl[i]=(int*)omalloc(l*sizeof(int));
1090 memcpy(tmpR.wvhdl[i],r1->wvhdl[i],l*sizeof(int));
1091 }
1092 #endif
1093 }
1094 j=i;
1095 i--;
1096 if ((r1->order[i]==ringorder_c)
1097 ||(r1->order[i]==ringorder_C))
1098 {
1099 j--;
1100 tmpR.order[b-2]=r1->order[i];
1101 }
1102 for (i=0;r2->order[i]!=0;i++)
1103 {
1104 if ((r2->order[i]!=ringorder_c)
1105 &&(r2->order[i]!=ringorder_C))
1106 {
1107 tmpR.order[j]=r2->order[i];
1108 tmpR.block0[j]=r2->block0[i]+rVar(r1);
1109 tmpR.block1[j]=r2->block1[i]+rVar(r1);
1110 if (r2->wvhdl[i]!=NULL)
1111 {
1112 #ifdef HAVE_OMALLOC
1113 tmpR.wvhdl[j] = (int*) omMemDup(r2->wvhdl[i]);
1114 #else
1115 {
1116 int l=r2->block1[i]-r2->block0[i]+1;
1117 if (r2->order[i]==ringorder_a64) l*=2;
1118 else if (r2->order[i]==ringorder_M) l=l*l;
1119 else if (r2->order[i]==ringorder_am)
1120 {
1121 l+=r2->wvhdl[i][r2->block1[i]-r2->block0[i]+1]+1;
1122 }
1123 tmpR.wvhdl[j]=(int*)omalloc(l*sizeof(int));
1124 memcpy(tmpR.wvhdl[j],r2->wvhdl[i],l*sizeof(int));
1125 }
1126 #endif
1127 }
1128 j++;
1129 }
1130 }
1131 if((r1->OrdSgn==-1)||(r2->OrdSgn==-1))
1132 tmpR.OrdSgn=-1;
1133 }
1134 }
1135 else if ((k==rVar(r1)) && (k==rVar(r2))) /* r1 and r2 are "quite"
1136 the same ring */
1137 /* copy r1, because we have the variables from r1 */
1138 {
1139 int b=rBlocks(r1);
1140
1141 tmpR.order=(rRingOrder_t*)omAlloc0(b*sizeof(rRingOrder_t));
1142 tmpR.block0=(int*)omAlloc0(b*sizeof(int));
1143 tmpR.block1=(int*)omAlloc0(b*sizeof(int));
1144 tmpR.wvhdl=(int**)omAlloc0(b*sizeof(int *));
1145 /* weights not implemented yet ...*/
1146 for (i=0;i<b;i++)
1147 {
1148 tmpR.order[i]=r1->order[i];
1149 tmpR.block0[i]=r1->block0[i];
1150 tmpR.block1[i]=r1->block1[i];
1151 if (r1->wvhdl[i]!=NULL)
1152 {
1153 #ifdef HAVE_OMALLOC
1154 tmpR.wvhdl[i] = (int*) omMemDup(r1->wvhdl[i]);
1155 #else
1156 {
1157 int l=r1->block1[i]-r1->block0[i]+1;
1158 if (r1->order[i]==ringorder_a64) l*=2;
1159 else if (r1->order[i]==ringorder_M) l=l*l;
1160 else if (r1->order[i]==ringorder_am)
1161 {
1162 l+=r1->wvhdl[i][r1->block1[i]-r1->block0[i]+1]+1;
1163 }
1164 tmpR.wvhdl[i]=(int*)omalloc(l*sizeof(int));
1165 memcpy(tmpR.wvhdl[i],r1->wvhdl[i],l*sizeof(int));
1166 }
1167 #endif
1168 }
1169 }
1170 tmpR.OrdSgn=r1->OrdSgn;
1171 }
1172 else
1173 {
1174 for(i=0;i<k;i++) omFree((ADDRESS)tmpR.names[i]);
1175 omFreeSize((ADDRESS)names,tmpR.N*sizeof(char *));
1176 Werror("variables must not overlap (# of vars: %d,%d -> %d)",rVar(r1),rVar(r2),k);
1177 return -1;
1178 }
1179 }
1180 tmpR.bitmask=si_max(r1->bitmask,r2->bitmask);
1181 sum=(ring)omAllocBin(sip_sring_bin);
1182 memcpy(sum,&tmpR,sizeof(ip_sring));
1183 rComplete(sum);
1184
1185//#ifdef RDEBUG
1186// rDebugPrint(sum);
1187//#endif
1188
1189
1190
1191#ifdef HAVE_PLURAL
1192 if(1)
1193 {
1194// ring old_ring = currRing;
1195
1196 BOOLEAN R1_is_nc = rIsPluralRing(r1);
1197 BOOLEAN R2_is_nc = rIsPluralRing(r2);
1198
1199 if ( (R1_is_nc) || (R2_is_nc))
1200 {
1201 ring R1 = nc_rCreateNCcomm_rCopy(r1);
1202 assume( rIsPluralRing(R1) );
1203
1204#if 0
1205#ifdef RDEBUG
1206 rWrite(R1);
1207 rDebugPrint(R1);
1208#endif
1209#endif
1210 ring R2 = nc_rCreateNCcomm_rCopy(r2);
1211#if 0
1212#ifdef RDEBUG
1213 rWrite(R2);
1214 rDebugPrint(R2);
1215#endif
1216#endif
1217
1218// rChangeCurrRing(sum); // ?
1219
1220 // Projections from R_i into Sum:
1221 /* multiplication matrices business: */
1222 /* find permutations of vars and pars */
1223 int *perm1 = (int *)omAlloc0((rVar(R1)+1)*sizeof(int));
1224 int *par_perm1 = NULL;
1225 if (rPar(R1)!=0) par_perm1=(int *)omAlloc0((rPar(R1)+1)*sizeof(int));
1226
1227 int *perm2 = (int *)omAlloc0((rVar(R2)+1)*sizeof(int));
1228 int *par_perm2 = NULL;
1229 if (rPar(R2)!=0) par_perm2=(int *)omAlloc0((rPar(R2)+1)*sizeof(int));
1230
1231 maFindPerm(R1->names, rVar(R1), rParameter(R1), rPar(R1),
1232 sum->names, rVar(sum), rParameter(sum), rPar(sum),
1233 perm1, par_perm1, sum->cf->type);
1234
1235 maFindPerm(R2->names, rVar(R2), rParameter(R2), rPar(R2),
1236 sum->names, rVar(sum), rParameter(sum), rPar(sum),
1237 perm2, par_perm2, sum->cf->type);
1238
1239
1240 matrix C1 = R1->GetNC()->C, C2 = R2->GetNC()->C;
1241 matrix D1 = R1->GetNC()->D, D2 = R2->GetNC()->D;
1242
1243 // !!!! BUG? C1 and C2 might live in different baserings!!!
1244
1245 int l = rVar(R1) + rVar(R2);
1246
1247 matrix C = mpNew(l,l);
1248 matrix D = mpNew(l,l);
1249
1250 for (i = 1; i <= rVar(R1); i++)
1251 for (j= rVar(R1)+1; j <= l; j++)
1252 MATELEM(C,i,j) = p_One(sum); // in 'sum'
1253
1254 id_Test((ideal)C, sum);
1255
1256 nMapFunc nMap1 = n_SetMap(R1->cf,sum->cf); /* can change something global: not usable
1257 after the next nSetMap call :( */
1258 // Create blocked C and D matrices:
1259 for (i=1; i<= rVar(R1); i++)
1260 for (j=i+1; j<=rVar(R1); j++)
1261 {
1262 assume(MATELEM(C1,i,j) != NULL);
1263 MATELEM(C,i,j) = p_PermPoly(MATELEM(C1,i,j), perm1, R1, sum, nMap1, par_perm1, rPar(R1)); // need ADD + CMP ops.
1264
1265 if (MATELEM(D1,i,j) != NULL)
1266 MATELEM(D,i,j) = p_PermPoly(MATELEM(D1,i,j), perm1, R1, sum, nMap1, par_perm1, rPar(R1));
1267 }
1268
1269 id_Test((ideal)C, sum);
1270 id_Test((ideal)D, sum);
1271
1272
1273 nMapFunc nMap2 = n_SetMap(R2->cf,sum->cf); /* can change something global: not usable
1274 after the next nSetMap call :( */
1275 for (i=1; i<= rVar(R2); i++)
1276 for (j=i+1; j<=rVar(R2); j++)
1277 {
1278 assume(MATELEM(C2,i,j) != NULL);
1279 MATELEM(C,rVar(R1)+i,rVar(R1)+j) = p_PermPoly(MATELEM(C2,i,j),perm2,R2,sum, nMap2,par_perm2,rPar(R2));
1280
1281 if (MATELEM(D2,i,j) != NULL)
1282 MATELEM(D,rVar(R1)+i,rVar(R1)+j) = p_PermPoly(MATELEM(D2,i,j),perm2,R2,sum, nMap2,par_perm2,rPar(R2));
1283 }
1284
1285 id_Test((ideal)C, sum);
1286 id_Test((ideal)D, sum);
1287
1288 // Now sum is non-commutative with blocked structure constants!
1289 if (nc_CallPlural(C, D, NULL, NULL, sum, false, false, true, sum))
1290 WarnS("Error initializing non-commutative multiplication!");
1291
1292 /* delete R1, R2*/
1293
1294#if 0
1295#ifdef RDEBUG
1296 rWrite(sum);
1297 rDebugPrint(sum);
1298
1299 Print("\nRefs: R1: %d, R2: %d\n", R1->GetNC()->ref, R2->GetNC()->ref);
1300
1301#endif
1302#endif
1303
1304
1305 rDelete(R1);
1306 rDelete(R2);
1307
1308 /* delete perm arrays */
1309 if (perm1!=NULL) omFree((ADDRESS)perm1);
1310 if (perm2!=NULL) omFree((ADDRESS)perm2);
1311 if (par_perm1!=NULL) omFree((ADDRESS)par_perm1);
1312 if (par_perm2!=NULL) omFree((ADDRESS)par_perm2);
1313
1314// rChangeCurrRing(old_ring);
1315 }
1316
1317 }
1318#endif
1319
1320 ideal Q=NULL;
1321 ideal Q1=NULL, Q2=NULL;
1322 if (r1->qideal!=NULL)
1323 {
1324// rChangeCurrRing(sum);
1325// if (r2->qideal!=NULL)
1326// {
1327// WerrorS("todo: qring+qring");
1328// return -1;
1329// }
1330// else
1331// {}
1332 /* these were defined in the Plural Part above... */
1333 int *perm1 = (int *)omAlloc0((rVar(r1)+1)*sizeof(int));
1334 int *par_perm1 = NULL;
1335 if (rPar(r1)!=0) par_perm1=(int *)omAlloc0((rPar(r1)+1)*sizeof(int));
1336 maFindPerm(r1->names, rVar(r1), rParameter(r1), rPar(r1),
1337 sum->names, rVar(sum), rParameter(sum), rPar(sum),
1338 perm1, par_perm1, sum->cf->type);
1339 nMapFunc nMap1 = n_SetMap(r1->cf,sum->cf);
1340 Q1 = idInit(IDELEMS(r1->qideal),1);
1341
1342 for (int for_i=0;for_i<IDELEMS(r1->qideal);for_i++)
1343 Q1->m[for_i] = p_PermPoly(
1344 r1->qideal->m[for_i], perm1,
1345 r1, sum,
1346 nMap1,
1347 par_perm1, rPar(r1));
1348
1349 omFree((ADDRESS)perm1);
1350 }
1351
1352 if (r2->qideal!=NULL)
1353 {
1354 //if (currRing!=sum)
1355 // rChangeCurrRing(sum);
1356 int *perm2 = (int *)omAlloc0((rVar(r2)+1)*sizeof(int));
1357 int *par_perm2 = NULL;
1358 if (rPar(r2)!=0) par_perm2=(int *)omAlloc0((rPar(r2)+1)*sizeof(int));
1359 maFindPerm(r2->names, rVar(r2), rParameter(r2), rPar(r2),
1360 sum->names, rVar(sum), rParameter(sum), rPar(sum),
1361 perm2, par_perm2, sum->cf->type);
1362 nMapFunc nMap2 = n_SetMap(r2->cf,sum->cf);
1363 Q2 = idInit(IDELEMS(r2->qideal),1);
1364
1365 for (int for_i=0;for_i<IDELEMS(r2->qideal);for_i++)
1366 Q2->m[for_i] = p_PermPoly(
1367 r2->qideal->m[for_i], perm2,
1368 r2, sum,
1369 nMap2,
1370 par_perm2, rPar(r2));
1371
1372 omFree((ADDRESS)perm2);
1373 }
1374 if (Q1!=NULL)
1375 {
1376 if ( Q2!=NULL)
1377 Q = id_SimpleAdd(Q1,Q2,sum);
1378 else
1379 Q=id_Copy(Q1,sum);
1380 }
1381 else
1382 {
1383 if ( Q2!=NULL)
1384 Q = id_Copy(Q2,sum);
1385 else
1386 Q=NULL;
1387 }
1388 sum->qideal = Q;
1389
1390#ifdef HAVE_PLURAL
1391 if( rIsPluralRing(sum) )
1392 nc_SetupQuotient( sum );
1393#endif
1394 return 1;
1395}
1396
1397/*2
1398 *returns -1 for not compatible, (sum is undefined)
1399 * 0 for equal, (and sum)
1400 * 1 for compatible (and sum)
1401 */
1402int rSum(ring r1, ring r2, ring &sum)
1403{
1404 if ((r1==NULL)||(r2==NULL)
1405 ||(r1->cf==NULL)||(r2->cf==NULL))
1406 return -1;
1407 if (r1==r2)
1408 {
1409 sum=r1;
1410 rIncRefCnt(r1);
1411 return 0;
1412 }
1413 return rSumInternal(r1,r2,sum,TRUE,FALSE);
1414}
1415
1416/*2
1417 * create a copy of the ring r
1418 * used for qring definition,..
1419 * DOES NOT CALL rComplete
1420 */
1421ring rCopy0(const ring r, BOOLEAN copy_qideal, BOOLEAN copy_ordering)
1422{
1423 if (r == NULL) return NULL;
1424 int i,j;
1425 ring res=(ring)omAlloc0Bin(sip_sring_bin);
1426 //memset: res->idroot=NULL; /* local objects */
1427 //ideal minideal;
1428 res->options=r->options; /* ring dependent options */
1429
1430 //memset: res->ordsgn=NULL;
1431 //memset: res->typ=NULL;
1432 //memset: res->VarOffset=NULL;
1433 //memset: res->firstwv=NULL;
1434
1435 //struct omBin PolyBin; /* Bin from where monoms are allocated */
1436 //memset: res->PolyBin=NULL; // rComplete
1437 res->cf=nCopyCoeff(r->cf); /* coeffs */
1438
1439 //memset: res->ref=0; /* reference counter to the ring */
1440
1441 res->N=rVar(r); /* number of vars */
1442
1443 res->firstBlockEnds=r->firstBlockEnds;
1444#ifdef HAVE_PLURAL
1445 res->real_var_start=r->real_var_start;
1446 res->real_var_end=r->real_var_end;
1447#endif
1448
1449#ifdef HAVE_SHIFTBBA
1450 res->isLPring=r->isLPring; /* 0 for non-letterplace rings, otherwise the number of LP blocks, at least 1, known also as lV */
1451 res->LPncGenCount=r->LPncGenCount;
1452#endif
1453
1454 res->VectorOut=r->VectorOut;
1455 res->ShortOut=r->ShortOut;
1456 res->CanShortOut=r->CanShortOut;
1457
1458 //memset: res->ExpL_Size=0;
1459 //memset: res->CmpL_Size=0;
1460 //memset: res->VarL_Size=0;
1461 //memset: res->pCompIndex=0;
1462 //memset: res->pOrdIndex=0;
1463 //memset: res->OrdSize=0;
1464 //memset: res->VarL_LowIndex=0;
1465 //memset: res->NegWeightL_Size=0;
1466 //memset: res->NegWeightL_Offset=NULL;
1467 //memset: res->VarL_Offset=NULL;
1468
1469 // the following are set by rComplete unless predefined
1470 // therefore, we copy these values: maybe they are non-standard
1471 /* mask for getting single exponents */
1472 res->bitmask=r->bitmask;
1473 res->divmask=r->divmask;
1474 res->BitsPerExp = r->BitsPerExp;
1475 res->ExpPerLong = r->ExpPerLong;
1476
1477 //memset: res->p_Procs=NULL;
1478 //memset: res->pFDeg=NULL;
1479 //memset: res->pLDeg=NULL;
1480 //memset: res->pFDegOrig=NULL;
1481 //memset: res->pLDegOrig=NULL;
1482 //memset: res->p_Setm=NULL;
1483 //memset: res->cf=NULL;
1484
1485/*
1486 if (r->extRing!=NULL)
1487 r->extRing->ref++;
1488
1489 res->extRing=r->extRing;
1490 //memset: res->qideal=NULL;
1491*/
1492
1493
1494 if (copy_ordering == TRUE)
1495 {
1496 res->LexOrder=r->LexOrder; // TRUE if the monomial ordering has polynomial and power series blocks
1497 res->MixedOrder=r->MixedOrder; // TRUE for mixed (global/local) ordering, FALSE otherwise,
1498 i=rBlocks(r);
1499 res->wvhdl = (int **)omAlloc(i * sizeof(int *));
1500 res->order = (rRingOrder_t *) omAlloc(i * sizeof(rRingOrder_t));
1501 res->block0 = (int *) omAlloc(i * sizeof(int));
1502 res->block1 = (int *) omAlloc(i * sizeof(int));
1503 for (j=0; j<i; j++)
1504 {
1505 if (r->wvhdl[j]!=NULL)
1506 {
1507 #ifdef HAVE_OMALLOC
1508 res->wvhdl[j] = (int*) omMemDup(r->wvhdl[j]);
1509 #else
1510 {
1511 int l=r->block1[j]-r->block0[j]+1;
1512 if (r->order[j]==ringorder_a64) l*=2;
1513 else if (r->order[j]==ringorder_M) l=l*l;
1514 else if (r->order[j]==ringorder_am)
1515 {
1516 l+=r->wvhdl[j][r->block1[j]-r->block0[j]+1]+1;
1517 }
1518 res->wvhdl[j]=(int*)omalloc(l*sizeof(int));
1519 memcpy(res->wvhdl[j],r->wvhdl[j],l*sizeof(int));
1520 }
1521 #endif
1522 }
1523 else
1524 res->wvhdl[j]=NULL;
1525 }
1526 memcpy(res->order,r->order,i * sizeof(rRingOrder_t));
1527 memcpy(res->block0,r->block0,i * sizeof(int));
1528 memcpy(res->block1,r->block1,i * sizeof(int));
1529 }
1530 //memset: else
1531 //memset: {
1532 //memset: res->wvhdl = NULL;
1533 //memset: res->order = NULL;
1534 //memset: res->block0 = NULL;
1535 //memset: res->block1 = NULL;
1536 //memset: }
1537
1538 res->names = (char **)omAlloc0(rVar(r) * sizeof(char *));
1539 for (i=0; i<rVar(res); i++)
1540 {
1541 res->names[i] = omStrDup(r->names[i]);
1542 }
1543 if (r->qideal!=NULL)
1544 {
1545 if (copy_qideal)
1546 {
1547 assume(copy_ordering);
1548 rComplete(res);
1549 res->qideal= idrCopyR_NoSort(r->qideal, r, res);
1551 }
1552 //memset: else res->qideal = NULL;
1553 }
1554 //memset: else res->qideal = NULL;
1555 //memset: res->GetNC() = NULL; // copy is purely commutative!!!
1556 return res;
1557}
1558
1559/*2
1560 * create a copy of the ring r
1561 * used for qring definition,..
1562 * DOES NOT CALL rComplete
1563 */
1564ring rCopy0AndAddA(const ring r, int64vec *wv64, BOOLEAN copy_qideal, BOOLEAN copy_ordering)
1565{
1566 if (r == NULL) return NULL;
1567 int i,j;
1568 ring res=(ring)omAlloc0Bin(sip_sring_bin);
1569 //memcpy(res,r,sizeof(ip_sring));
1570 //memset: res->idroot=NULL; /* local objects */
1571 //ideal minideal;
1572 res->options=r->options; /* ring dependent options */
1573
1574 //memset: res->ordsgn=NULL;
1575 //memset: res->typ=NULL;
1576 //memset: res->VarOffset=NULL;
1577 //memset: res->firstwv=NULL;
1578
1579 //struct omBin PolyBin; /* Bin from where monoms are allocated */
1580 //memset: res->PolyBin=NULL; // rComplete
1581 res->cf=nCopyCoeff(r->cf); /* coeffs */
1582
1583 //memset: res->ref=0; /* reference counter to the ring */
1584
1585 res->N=rVar(r); /* number of vars */
1586
1587 res->firstBlockEnds=r->firstBlockEnds;
1588#ifdef HAVE_PLURAL
1589 res->real_var_start=r->real_var_start;
1590 res->real_var_end=r->real_var_end;
1591#endif
1592
1593#ifdef HAVE_SHIFTBBA
1594 res->isLPring=r->isLPring; /* 0 for non-letterplace rings, otherwise the number of LP blocks, at least 1, known also as lV */
1595 res->LPncGenCount=r->LPncGenCount;
1596#endif
1597
1598 res->VectorOut=r->VectorOut;
1599 res->ShortOut=r->ShortOut;
1600 res->CanShortOut=r->CanShortOut;
1601 res->LexOrder=r->LexOrder; // TRUE if the monomial ordering has polynomial and power series blocks
1602 res->MixedOrder=r->MixedOrder; // TRUE for mixed (global/local) ordering, FALSE otherwise,
1603
1604 //memset: res->ExpL_Size=0;
1605 //memset: res->CmpL_Size=0;
1606 //memset: res->VarL_Size=0;
1607 //memset: res->pCompIndex=0;
1608 //memset: res->pOrdIndex=0;
1609 //memset: res->OrdSize=0;
1610 //memset: res->VarL_LowIndex=0;
1611 //memset: res->NegWeightL_Size=0;
1612 //memset: res->NegWeightL_Offset=NULL;
1613 //memset: res->VarL_Offset=NULL;
1614
1615 // the following are set by rComplete unless predefined
1616 // therefore, we copy these values: maybe they are non-standard
1617 /* mask for getting single exponents */
1618 res->bitmask=r->bitmask;
1619 res->divmask=r->divmask;
1620 res->BitsPerExp = r->BitsPerExp;
1621 res->ExpPerLong = r->ExpPerLong;
1622
1623 //memset: res->p_Procs=NULL;
1624 //memset: res->pFDeg=NULL;
1625 //memset: res->pLDeg=NULL;
1626 //memset: res->pFDegOrig=NULL;
1627 //memset: res->pLDegOrig=NULL;
1628 //memset: res->p_Setm=NULL;
1629 //memset: res->cf=NULL;
1630
1631/*
1632 if (r->extRing!=NULL)
1633 r->extRing->ref++;
1634
1635 res->extRing=r->extRing;
1636 //memset: res->qideal=NULL;
1637*/
1638
1639
1640 if (copy_ordering == TRUE)
1641 {
1642 i=rBlocks(r)+1; // DIFF to rCopy0
1643 res->wvhdl = (int **)omAlloc(i * sizeof(int *));
1644 res->order = (rRingOrder_t *) omAlloc(i * sizeof(rRingOrder_t));
1645 res->block0 = (int *) omAlloc(i * sizeof(int));
1646 res->block1 = (int *) omAlloc(i * sizeof(int));
1647 for (j=0; j<i-1; j++)
1648 {
1649 if (r->wvhdl[j]!=NULL)
1650 {
1651 #ifdef HAVE_OMALLOC
1652 res->wvhdl[j+1] = (int*) omMemDup(r->wvhdl[j]); //DIFF
1653 #else
1654 {
1655 int l=r->block1[j]-r->block0[j]+1;
1656 if (r->order[j]==ringorder_a64) l*=2;
1657 else if (r->order[j]==ringorder_M) l=l*l;
1658 else if (r->order[j]==ringorder_am)
1659 {
1660 l+=r->wvhdl[j][r->block1[j]-r->block0[j]+1]+1;
1661 }
1662 res->wvhdl[j+1]=(int*)omalloc(l*sizeof(int));
1663 memcpy(res->wvhdl[j+1],r->wvhdl[j],l*sizeof(int));
1664 }
1665 #endif
1666 }
1667 else
1668 res->wvhdl[j+1]=NULL; //DIFF
1669 }
1670 memcpy(&(res->order[1]),r->order,(i-1) * sizeof(rRingOrder_t)); //DIFF
1671 memcpy(&(res->block0[1]),r->block0,(i-1) * sizeof(int)); //DIFF
1672 memcpy(&(res->block1[1]),r->block1,(i-1) * sizeof(int)); //DIFF
1673 }
1674 //memset: else
1675 //memset: {
1676 //memset: res->wvhdl = NULL;
1677 //memset: res->order = NULL;
1678 //memset: res->block0 = NULL;
1679 //memset: res->block1 = NULL;
1680 //memset: }
1681
1682 //the added A
1683 res->order[0]=ringorder_a64;
1684 int length=wv64->rows();
1685 int64 *A=(int64 *)omAlloc(length*sizeof(int64));
1686 for(j=length-1;j>=0;j--)
1687 {
1688 A[j]=(*wv64)[j];
1689 }
1690 res->wvhdl[0]=(int *)A;
1691 res->block0[0]=1;
1692 res->block1[0]=length;
1693 //
1694
1695 res->names = (char **)omAlloc0(rVar(r) * sizeof(char *));
1696 for (i=0; i<rVar(res); i++)
1697 {
1698 res->names[i] = omStrDup(r->names[i]);
1699 }
1700 if (r->qideal!=NULL)
1701 {
1702 if (copy_qideal)
1703 {
1704 #ifndef SING_NDEBUG
1705 if (!copy_ordering)
1706 WerrorS("internal error: rCopy0(Q,TRUE,FALSE)");
1707 else
1708 #endif
1709 {
1710 #ifndef SING_NDEBUG
1711 WarnS("internal bad stuff: rCopy0(Q,TRUE,TRUE)");
1712 #endif
1713 rComplete(res);
1714 res->qideal= idrCopyR_NoSort(r->qideal, r, res);
1716 }
1717 }
1718 //memset: else res->qideal = NULL;
1719 }
1720 //memset: else res->qideal = NULL;
1721 //memset: res->GetNC() = NULL; // copy is purely commutative!!!
1722 return res;
1723}
1724
1725/*2
1726 * create a copy of the ring r, which must be equivalent to currRing
1727 * used for qring definition,..
1728 * (i.e.: normal rings: same nCopy as currRing;
1729 * qring: same nCopy, same idCopy as currRing)
1730 */
1731ring rCopy(ring r)
1732{
1733 if (r == NULL) return NULL;
1734 ring res=rCopy0(r,FALSE,TRUE);
1735 rComplete(res, 1); // res is purely commutative so far
1736 if (r->qideal!=NULL) res->qideal=idrCopyR_NoSort(r->qideal, r, res);
1737
1738#ifdef HAVE_PLURAL
1739 if (rIsPluralRing(r))
1740 if( nc_rCopy(res, r, true) ) {}
1741#endif
1742
1743 return res;
1744}
1745
1746BOOLEAN rEqual(ring r1, ring r2, BOOLEAN qr)
1747{
1748 if (r1 == r2) return TRUE;
1749 if (r1 == NULL || r2 == NULL) return FALSE;
1750 if (r1->cf!=r2->cf) return FALSE;
1751 if (rVar(r1)!=rVar(r2)) return FALSE;
1752 if (r1->bitmask!=r2->bitmask) return FALSE;
1753 #ifdef HAVE_SHIFTBBA
1754 if (r1->isLPring!=r2->isLPring) return FALSE;
1755 if (r1->LPncGenCount!=r2->LPncGenCount) return FALSE;
1756 #endif
1757
1758 if( !rSamePolyRep(r1, r2) )
1759 return FALSE;
1760
1761 int i/*, j*/;
1762
1763 for (i=0; i<rVar(r1); i++)
1764 {
1765 if ((r1->names[i] != NULL) && (r2->names[i] != NULL))
1766 {
1767 if (strcmp(r1->names[i], r2->names[i])) return FALSE;
1768 }
1769 else if ((r1->names[i] != NULL) ^ (r2->names[i] != NULL))
1770 {
1771 return FALSE;
1772 }
1773 }
1774
1775 if (qr)
1776 {
1777 if (r1->qideal != NULL)
1778 {
1779 ideal id1 = r1->qideal, id2 = r2->qideal;
1780 int i, n;
1781 poly *m1, *m2;
1782
1783 if (id2 == NULL) return FALSE;
1784 if ((n = IDELEMS(id1)) != IDELEMS(id2)) return FALSE;
1785
1786 {
1787 m1 = id1->m;
1788 m2 = id2->m;
1789 for (i=0; i<n; i++)
1790 if (! p_EqualPolys(m1[i],m2[i], r1, r2)) return FALSE;
1791 }
1792 }
1793 else if (r2->qideal != NULL) return FALSE;
1794 }
1795
1796 return TRUE;
1797}
1798
1799BOOLEAN rSamePolyRep(ring r1, ring r2)
1800{
1801 int i, j;
1802
1803 if (r1 == r2) return TRUE;
1804
1805 if (r1 == NULL || r2 == NULL) return FALSE;
1806
1807 if ((r1->cf != r2->cf)
1808 || (rVar(r1) != rVar(r2))
1809 || (r1->OrdSgn != r2->OrdSgn))
1810 return FALSE;
1811
1812 i=0;
1813 while (r1->order[i] != 0)
1814 {
1815 if (r2->order[i] == 0) return FALSE;
1816 if ((r1->order[i] != r2->order[i])
1817 || (r1->block0[i] != r2->block0[i])
1818 || (r1->block1[i] != r2->block1[i]))
1819 return FALSE;
1820 if (r1->wvhdl[i] != NULL)
1821 {
1822 if (r2->wvhdl[i] == NULL)
1823 return FALSE;
1824 for (j=0; j<r1->block1[i]-r1->block0[i]+1; j++)
1825 if (r2->wvhdl[i][j] != r1->wvhdl[i][j])
1826 return FALSE;
1827 }
1828 else if (r2->wvhdl[i] != NULL) return FALSE;
1829 i++;
1830 }
1831 if (r2->order[i] != 0) return FALSE;
1832
1833 // we do not check variable names
1834 // we do not check minpoly/minideal
1835 // we do not check qideal
1836
1837 return TRUE;
1838}
1839
1841{
1842 // check for simple ordering
1843 if (rHasSimpleOrder(r))
1844 {
1845 if ((r->order[1] == ringorder_c)
1846 || (r->order[1] == ringorder_C))
1847 {
1848 switch(r->order[0])
1849 {
1850 case ringorder_dp:
1851 case ringorder_wp:
1852 case ringorder_ds:
1853 case ringorder_ws:
1854 case ringorder_ls:
1855 case ringorder_unspec:
1856 if (r->order[1] == ringorder_C
1857 || r->order[0] == ringorder_unspec)
1858 return rOrderType_ExpComp;
1859 return rOrderType_Exp;
1860
1861 default:
1862 assume(r->order[0] == ringorder_lp ||
1863 r->order[0] == ringorder_rs ||
1864 r->order[0] == ringorder_Dp ||
1865 r->order[0] == ringorder_Wp ||
1866 r->order[0] == ringorder_Ds ||
1867 r->order[0] == ringorder_Ws);
1868
1869 if (r->order[1] == ringorder_c) return rOrderType_ExpComp;
1870 return rOrderType_Exp;
1871 }
1872 }
1873 else
1874 {
1875 assume((r->order[0]==ringorder_c)||(r->order[0]==ringorder_C));
1876 return rOrderType_CompExp;
1877 }
1878 }
1879 else
1880 return rOrderType_General;
1881}
1882
1884{
1885 return (r->order[0] == ringorder_c);
1886}
1888{
1889 if (r->order[0] == ringorder_unspec) return TRUE;
1890 int blocks = rBlocks(r) - 1;
1891 assume(blocks >= 1);
1892 if (blocks == 1) return TRUE;
1893
1894 int s = 0;
1895 while( (s < blocks) && (r->order[s] == ringorder_IS) && (r->order[blocks-1] == ringorder_IS) )
1896 {
1897 s++;
1898 blocks--;
1899 }
1900
1901 if ((blocks - s) > 2) return FALSE;
1902
1903 assume( blocks == s + 2 );
1904
1905 if (
1906 (r->order[s] != ringorder_c)
1907 && (r->order[s] != ringorder_C)
1908 && (r->order[s+1] != ringorder_c)
1909 && (r->order[s+1] != ringorder_C)
1910 )
1911 return FALSE;
1912 if ((r->order[s+1] == ringorder_M)
1913 || (r->order[s] == ringorder_M))
1914 return FALSE;
1915 return TRUE;
1916}
1917
1918// returns TRUE, if simple lp or ls ordering
1920{
1921 return rHasSimpleOrder(r) &&
1922 (r->order[0] == ringorder_ls ||
1923 r->order[0] == ringorder_lp ||
1924 r->order[1] == ringorder_ls ||
1925 r->order[1] == ringorder_lp);
1926}
1927
1929{
1930 switch(order)
1931 {
1932 case ringorder_dp:
1933 case ringorder_Dp:
1934 case ringorder_ds:
1935 case ringorder_Ds:
1936 case ringorder_Ws:
1937 case ringorder_Wp:
1938 case ringorder_ws:
1939 case ringorder_wp:
1940 return TRUE;
1941
1942 default:
1943 return FALSE;
1944 }
1945}
1946
1948{
1949 switch(order)
1950 {
1951 case ringorder_Ws:
1952 case ringorder_Wp:
1953 case ringorder_ws:
1954 case ringorder_wp:
1955 return TRUE;
1956
1957 default:
1958 return FALSE;
1959 }
1960}
1961
1963{
1964 if (r->order[0] == ringorder_unspec) return TRUE;
1965 int blocks = rBlocks(r) - 1;
1966 assume(blocks >= 1);
1967 if (blocks == 1) return TRUE;
1968
1969 int s = 0;
1970 while( (s < blocks) && (r->order[s] == ringorder_IS) && (r->order[blocks-1] == ringorder_IS) )
1971 {
1972 s++;
1973 blocks--;
1974 }
1975
1976 if ((blocks - s) > 3) return FALSE;
1977
1978// if ((blocks > 3) || (blocks < 2)) return FALSE;
1979 if ((blocks - s) == 3)
1980 {
1981 return (((r->order[s] == ringorder_aa) && (r->order[s+1] != ringorder_M) &&
1982 ((r->order[s+2] == ringorder_c) || (r->order[s+2] == ringorder_C))) ||
1983 (((r->order[s] == ringorder_c) || (r->order[s] == ringorder_C)) &&
1984 (r->order[s+1] == ringorder_aa) && (r->order[s+2] != ringorder_M)));
1985 }
1986 else
1987 {
1988 return ((r->order[s] == ringorder_aa) && (r->order[s+1] != ringorder_M));
1989 }
1990}
1991
1992// return TRUE if p_SetComp requires p_Setm
1994{
1995 if (r->typ != NULL)
1996 {
1997 int pos;
1998 for (pos=0;pos<r->OrdSize;pos++)
1999 {
2000 sro_ord* o=&(r->typ[pos]);
2001 if ( (o->ord_typ == ro_syzcomp)
2002 || (o->ord_typ == ro_syz)
2003 || (o->ord_typ == ro_is)
2004 || (o->ord_typ == ro_am)
2005 || (o->ord_typ == ro_isTemp))
2006 return TRUE;
2007 }
2008 }
2009 return FALSE;
2010}
2011
2012// return TRUE if p->exp[r->pOrdIndex] holds total degree of p */
2014{
2015 // Hmm.... what about Syz orderings?
2016 return (rVar(r) > 1 &&
2017 ((rHasSimpleOrder(r) &&
2018 (rOrder_is_DegOrdering((rRingOrder_t)r->order[0]) ||
2019 rOrder_is_DegOrdering(( rRingOrder_t)r->order[1]))) ||
2020 (rHasSimpleOrderAA(r) &&
2021 (rOrder_is_DegOrdering((rRingOrder_t)r->order[1]) ||
2022 ((r->order[1]!=0) &&
2023 rOrder_is_DegOrdering((rRingOrder_t)r->order[2]))))));
2024}
2025
2026// return TRUE if p->exp[r->pOrdIndex] holds a weighted degree of p */
2028{
2029 // Hmm.... what about Syz orderings?
2030 return ((rVar(r) > 1) &&
2031 rHasSimpleOrder(r) &&
2034}
2035
2036BOOLEAN rIsPolyVar(int v,const ring r)
2037{
2038 int i=0;
2039 while(r->order[i]!=0)
2040 {
2041 if((r->block0[i]<=v)
2042 && (r->block1[i]>=v))
2043 {
2044 switch(r->order[i])
2045 {
2046 case ringorder_a:
2047 return (r->wvhdl[i][v-r->block0[i]]>0);
2048 case ringorder_M:
2049 return 2; /*don't know*/
2050 case ringorder_a64: /* assume: all weight are non-negative!*/
2051 case ringorder_lp:
2052 case ringorder_rs:
2053 case ringorder_dp:
2054 case ringorder_Dp:
2055 case ringorder_wp:
2056 case ringorder_Wp:
2057 return TRUE;
2058 case ringorder_ls:
2059 case ringorder_ds:
2060 case ringorder_Ds:
2061 case ringorder_ws:
2062 case ringorder_Ws:
2063 return FALSE;
2064 default:
2065 break;
2066 }
2067 }
2068 i++;
2069 }
2070 return 3; /* could not find var v*/
2071}
2072
2073#ifdef RDEBUG
2074// This should eventually become a full-fledge ring check, like pTest
2075BOOLEAN rDBTest(ring r, const char* fn, const int l)
2076{
2077 int i,j;
2078
2079 if (r == NULL)
2080 {
2081 dReportError("Null ring in %s:%d", fn, l);
2082 return FALSE;
2083 }
2084
2085
2086 if (r->N == 0) return TRUE;
2087
2088 if ((r->OrdSgn!=1) && (r->OrdSgn!= -1))
2089 {
2090 dReportError("missing OrdSgn in %s:%d", fn, l);
2091 return FALSE;
2092 }
2093
2094// omCheckAddrSize(r,sizeof(ip_sring));
2095#if OM_CHECK > 0
2096 i=rBlocks(r);
2097 omCheckAddrSize(r->order,i*sizeof(int));
2098 omCheckAddrSize(r->block0,i*sizeof(int));
2099 omCheckAddrSize(r->block1,i*sizeof(int));
2100 for(int j=0;j<=i;j++)
2101 {
2102 if((r->order[j]<0)||(r->order[j]>ringorder_unspec))
2103 dError("wrong order in r->order");
2104 }
2105 if (r->wvhdl!=NULL)
2106 {
2107 omCheckAddrSize(r->wvhdl,i*sizeof(int *));
2108 for (j=0;j<i; j++)
2109 {
2110 if (r->wvhdl[j] != NULL) omCheckAddr(r->wvhdl[j]);
2111 }
2112 }
2113#endif
2114 if (r->VarOffset == NULL)
2115 {
2116 dReportError("Null ring VarOffset -- no rComplete (?) in n %s:%d", fn, l);
2117 return FALSE;
2118 }
2119 omCheckAddrSize(r->VarOffset,(r->N+1)*sizeof(int));
2120
2121 if ((r->OrdSize==0)!=(r->typ==NULL))
2122 {
2123 dReportError("mismatch OrdSize and typ-pointer in %s:%d");
2124 return FALSE;
2125 }
2126 omcheckAddrSize(r->typ,r->OrdSize*sizeof(*(r->typ)));
2127 omCheckAddrSize(r->VarOffset,(r->N+1)*sizeof(*(r->VarOffset)));
2128 // test assumptions:
2129 for(i=0;i<=r->N;i++) // for all variables (i = 0..N)
2130 {
2131 if(r->typ!=NULL)
2132 {
2133 for(j=0;j<r->OrdSize;j++) // for all ordering blocks (j =0..OrdSize-1)
2134 {
2135 if(r->typ[j].ord_typ == ro_isTemp)
2136 {
2137 const int p = r->typ[j].data.isTemp.suffixpos;
2138
2139 if(p <= j)
2140 dReportError("ordrec prefix %d is unmatched",j);
2141
2142 assume( p < r->OrdSize );
2143
2144 if(r->typ[p].ord_typ != ro_is)
2145 dReportError("ordrec prefix %d is unmatched (suffix: %d is wrong!!!)",j, p);
2146
2147 // Skip all intermediate blocks for undone variables:
2148 if(r->typ[j].data.isTemp.pVarOffset[i] != -1) // Check i^th variable
2149 {
2150 j = p - 1; // SKIP ALL INTERNAL BLOCKS...???
2151 continue; // To make for check OrdSize bound...
2152 }
2153 }
2154 else if (r->typ[j].ord_typ == ro_is)
2155 {
2156 // Skip all intermediate blocks for undone variables:
2157 if(r->typ[j].data.is.pVarOffset[i] != -1)
2158 {
2159 // TODO???
2160 }
2161
2162 }
2163 else
2164 {
2165 if (r->typ[j].ord_typ==ro_cp)
2166 {
2167 if(((short)r->VarOffset[i]) == r->typ[j].data.cp.place)
2168 dReportError("ordrec %d conflicts with var %d",j,i);
2169 }
2170 else
2171 if ((r->typ[j].ord_typ!=ro_syzcomp)
2172 && (r->VarOffset[i] == r->typ[j].data.dp.place))
2173 dReportError("ordrec %d conflicts with var %d",j,i);
2174 }
2175 }
2176 }
2177 int tmp;
2178 tmp=r->VarOffset[i] & 0xffffff;
2179 #if SIZEOF_LONG == 8
2180 if ((r->VarOffset[i] >> 24) >63)
2181 #else
2182 if ((r->VarOffset[i] >> 24) >31)
2183 #endif
2184 dReportError("bit_start out of range:%d",r->VarOffset[i] >> 24);
2185 if (i > 0 && ((tmp<0) ||(tmp>r->ExpL_Size-1)))
2186 {
2187 dReportError("varoffset out of range for var %d: %d",i,tmp);
2188 }
2189 }
2190 if(r->typ!=NULL)
2191 {
2192 for(j=0;j<r->OrdSize;j++)
2193 {
2194 if ((r->typ[j].ord_typ==ro_dp)
2195 || (r->typ[j].ord_typ==ro_wp)
2196 || (r->typ[j].ord_typ==ro_wp_neg))
2197 {
2198 if (r->typ[j].data.dp.start > r->typ[j].data.dp.end)
2199 dReportError("in ordrec %d: start(%d) > end(%d)",j,
2200 r->typ[j].data.dp.start, r->typ[j].data.dp.end);
2201 if ((r->typ[j].data.dp.start < 1)
2202 || (r->typ[j].data.dp.end > r->N))
2203 dReportError("in ordrec %d: start(%d)<1 or end(%d)>vars(%d)",j,
2204 r->typ[j].data.dp.start, r->typ[j].data.dp.end,r->N);
2205 }
2206 }
2207 }
2208
2209 assume(r != NULL);
2210 assume(r->cf != NULL);
2211
2212 if (nCoeff_is_algExt(r->cf))
2213 {
2214 assume(r->cf->extRing != NULL);
2215 assume(r->cf->extRing->qideal != NULL);
2216 omCheckAddr(r->cf->extRing->qideal->m[0]);
2217 }
2218
2219 //assume(r->cf!=NULL);
2220
2221 return TRUE;
2222}
2223#endif
2224
2225static void rO_Align(int &place, int &bitplace)
2226{
2227 // increment place to the next aligned one
2228 // (count as Exponent_t,align as longs)
2229 if (bitplace!=BITS_PER_LONG)
2230 {
2231 place++;
2232 bitplace=BITS_PER_LONG;
2233 }
2234}
2235
2236static void rO_TDegree(int &place, int &bitplace, int start, int end,
2237 long *o, sro_ord &ord_struct)
2238{
2239 // degree (aligned) of variables v_start..v_end, ordsgn 1
2240 rO_Align(place,bitplace);
2241 ord_struct.ord_typ=ro_dp;
2242 ord_struct.data.dp.start=start;
2243 ord_struct.data.dp.end=end;
2244 ord_struct.data.dp.place=place;
2245 o[place]=1;
2246 place++;
2247 rO_Align(place,bitplace);
2248}
2249
2250static void rO_TDegree_neg(int &place, int &bitplace, int start, int end,
2251 long *o, sro_ord &ord_struct)
2252{
2253 // degree (aligned) of variables v_start..v_end, ordsgn -1
2254 rO_Align(place,bitplace);
2255 ord_struct.ord_typ=ro_dp;
2256 ord_struct.data.dp.start=start;
2257 ord_struct.data.dp.end=end;
2258 ord_struct.data.dp.place=place;
2259 o[place]=-1;
2260 place++;
2261 rO_Align(place,bitplace);
2262}
2263
2264static void rO_WDegree(int &place, int &bitplace, int start, int end,
2265 long *o, sro_ord &ord_struct, int *weights)
2266{
2267 // weighted degree (aligned) of variables v_start..v_end, ordsgn 1
2268 while((start<end) && (weights[0]==0)) { start++; weights++; }
2269 while((start<end) && (weights[end-start]==0)) { end--; }
2270 int i;
2271 int pure_tdeg=1;
2272 for(i=start;i<=end;i++)
2273 {
2274 if(weights[i-start]!=1)
2275 {
2276 pure_tdeg=0;
2277 break;
2278 }
2279 }
2280 if (pure_tdeg)
2281 {
2282 rO_TDegree(place,bitplace,start,end,o,ord_struct);
2283 return;
2284 }
2285 rO_Align(place,bitplace);
2286 ord_struct.ord_typ=ro_wp;
2287 ord_struct.data.wp.start=start;
2288 ord_struct.data.wp.end=end;
2289 ord_struct.data.wp.place=place;
2290 ord_struct.data.wp.weights=weights;
2291 o[place]=1;
2292 place++;
2293 rO_Align(place,bitplace);
2294 for(i=start;i<=end;i++)
2295 {
2296 if(weights[i-start]<0)
2297 {
2298 ord_struct.ord_typ=ro_wp_neg;
2299 break;
2300 }
2301 }
2302}
2303
2304static void rO_WMDegree(int &place, int &bitplace, int start, int end,
2305 long *o, sro_ord &ord_struct, int *weights)
2306{
2307 assume(weights != NULL);
2308
2309 // weighted degree (aligned) of variables v_start..v_end, ordsgn 1
2310// while((start<end) && (weights[0]==0)) { start++; weights++; }
2311// while((start<end) && (weights[end-start]==0)) { end--; }
2312 rO_Align(place,bitplace);
2313 ord_struct.ord_typ=ro_am;
2314 ord_struct.data.am.start=start;
2315 ord_struct.data.am.end=end;
2316 ord_struct.data.am.place=place;
2317 ord_struct.data.am.weights=weights;
2318 ord_struct.data.am.weights_m = weights + (end-start+1);
2319 ord_struct.data.am.len_gen=weights[end-start+1];
2320 assume( ord_struct.data.am.weights_m[0] == ord_struct.data.am.len_gen );
2321 o[place]=1;
2322 place++;
2323 rO_Align(place,bitplace);
2324}
2325
2326static void rO_WDegree64(int &place, int &bitplace, int start, int end,
2327 long *o, sro_ord &ord_struct, int64 *weights)
2328{
2329 // weighted degree (aligned) of variables v_start..v_end, ordsgn 1,
2330 // reserved 2 places
2331 rO_Align(place,bitplace);
2332 ord_struct.ord_typ=ro_wp64;
2333 ord_struct.data.wp64.start=start;
2334 ord_struct.data.wp64.end=end;
2335 ord_struct.data.wp64.place=place;
2336 #ifdef HAVE_OMALLOC
2337 ord_struct.data.wp64.weights64=weights;
2338 #else
2339 int l=end-start+1;
2340 ord_struct.data.wp64.weights64=(int64*)omAlloc(l*sizeof(int64));
2341 for(int i=0;i<l;i++) ord_struct.data.wp64.weights64[i]=weights[i];
2342 #endif
2343 o[place]=1;
2344 place++;
2345 o[place]=1;
2346 place++;
2347 rO_Align(place,bitplace);
2348}
2349
2350static void rO_WDegree_neg(int &place, int &bitplace, int start, int end,
2351 long *o, sro_ord &ord_struct, int *weights)
2352{
2353 // weighted degree (aligned) of variables v_start..v_end, ordsgn -1
2354 while((start<end) && (weights[0]==0)) { start++; weights++; }
2355 while((start<end) && (weights[end-start]==0)) { end--; }
2356 rO_Align(place,bitplace);
2357 ord_struct.ord_typ=ro_wp;
2358 ord_struct.data.wp.start=start;
2359 ord_struct.data.wp.end=end;
2360 ord_struct.data.wp.place=place;
2361 ord_struct.data.wp.weights=weights;
2362 o[place]=-1;
2363 place++;
2364 rO_Align(place,bitplace);
2365 int i;
2366 for(i=start;i<=end;i++)
2367 {
2368 if(weights[i-start]<0)
2369 {
2370 ord_struct.ord_typ=ro_wp_neg;
2371 break;
2372 }
2373 }
2374}
2375
2376static void rO_LexVars(int &place, int &bitplace, int start, int end,
2377 int &prev_ord, long *o,int *v, int bits, int opt_var)
2378{
2379 // a block of variables v_start..v_end with lex order, ordsgn 1
2380 int k;
2381 int incr=1;
2382 if(prev_ord==-1) rO_Align(place,bitplace);
2383
2384 if (start>end)
2385 {
2386 incr=-1;
2387 }
2388 for(k=start;;k+=incr)
2389 {
2390 bitplace-=bits;
2391 if (bitplace < 0) { bitplace=BITS_PER_LONG-bits; place++; }
2392 o[place]=1;
2393 v[k]= place | (bitplace << 24);
2394 if (k==end) break;
2395 }
2396 prev_ord=1;
2397 if (opt_var!= -1)
2398 {
2399 assume((opt_var == end+1) ||(opt_var == end-1));
2400 if((opt_var != end+1) &&(opt_var != end-1)) WarnS("hier-2");
2401 int save_bitplace=bitplace;
2402 bitplace-=bits;
2403 if (bitplace < 0)
2404 {
2405 bitplace=save_bitplace;
2406 return;
2407 }
2408 // there is enough space for the optional var
2409 v[opt_var]=place | (bitplace << 24);
2410 }
2411}
2412
2413static void rO_LexVars_neg(int &place, int &bitplace, int start, int end,
2414 int &prev_ord, long *o,int *v, int bits, int opt_var)
2415{
2416 // a block of variables v_start..v_end with lex order, ordsgn -1
2417 int k;
2418 int incr=1;
2419 if(prev_ord==1) rO_Align(place,bitplace);
2420
2421 if (start>end)
2422 {
2423 incr=-1;
2424 }
2425 for(k=start;;k+=incr)
2426 {
2427 bitplace-=bits;
2428 if (bitplace < 0) { bitplace=BITS_PER_LONG-bits; place++; }
2429 o[place]=-1;
2430 v[k]=place | (bitplace << 24);
2431 if (k==end) break;
2432 }
2433 prev_ord=-1;
2434// #if 0
2435 if (opt_var!= -1)
2436 {
2437 assume((opt_var == end+1) ||(opt_var == end-1));
2438 if((opt_var != end+1) &&(opt_var != end-1)) WarnS("hier-1");
2439 int save_bitplace=bitplace;
2440 bitplace-=bits;
2441 if (bitplace < 0)
2442 {
2443 bitplace=save_bitplace;
2444 return;
2445 }
2446 // there is enough space for the optional var
2447 v[opt_var]=place | (bitplace << 24);
2448 }
2449// #endif
2450}
2451
2452static void rO_Syzcomp(int &place, int &bitplace, int &prev_ord,
2453 long *o, sro_ord &ord_struct)
2454{
2455 // ordering is derived from component number
2456 rO_Align(place,bitplace);
2457 ord_struct.ord_typ=ro_syzcomp;
2458 ord_struct.data.syzcomp.place=place;
2459 ord_struct.data.syzcomp.Components=NULL;
2460 ord_struct.data.syzcomp.ShiftedComponents=NULL;
2461 o[place]=1;
2462 prev_ord=1;
2463 place++;
2464 rO_Align(place,bitplace);
2465}
2466
2467static void rO_Syz(int &place, int &bitplace, int &prev_ord,
2468 int syz_comp, long *o, sro_ord &ord_struct)
2469{
2470 // ordering is derived from component number
2471 // let's reserve one Exponent_t for it
2472 if ((prev_ord== 1) || (bitplace!=BITS_PER_LONG))
2473 rO_Align(place,bitplace);
2474 ord_struct.ord_typ=ro_syz;
2475 ord_struct.data.syz.place=place;
2476 ord_struct.data.syz.limit=syz_comp;
2477 if (syz_comp>0)
2478 ord_struct.data.syz.syz_index = (int*) omAlloc0((syz_comp+1)*sizeof(int));
2479 else
2480 ord_struct.data.syz.syz_index = NULL;
2481 ord_struct.data.syz.curr_index = 1;
2482 o[place]= -1;
2483 prev_ord=-1;
2484 place++;
2485}
2486
2487#ifndef SING_NDEBUG
2488# define MYTEST 0
2489#else /* ifndef SING_NDEBUG */
2490# define MYTEST 0
2491#endif /* ifndef SING_NDEBUG */
2492
2493static void rO_ISPrefix(int &place, int &bitplace, int &prev_ord,
2494 long *o, int N, int *v, sro_ord &ord_struct)
2495{
2496 if ((prev_ord== 1) || (bitplace!=BITS_PER_LONG))
2497 rO_Align(place,bitplace);
2498 // since we add something afterwards - it's better to start with anew!?
2499
2500 ord_struct.ord_typ = ro_isTemp;
2501 ord_struct.data.isTemp.start = place;
2502 #ifdef HAVE_OMALLOC
2503 ord_struct.data.isTemp.pVarOffset = (int *)omMemDup(v);
2504 #else
2505 ord_struct.data.isTemp.pVarOffset = (int *)omAlloc((N+1)*sizeof(int));
2506 memcpy(ord_struct.data.isTemp.pVarOffset,v,(N+1)*sizeof(int));
2507 #endif
2508 ord_struct.data.isTemp.suffixpos = -1;
2509
2510 // We will act as rO_Syz on our own!!!
2511 // Here we allocate an exponent as a level placeholder
2512 o[place]= -1;
2513 prev_ord=-1;
2514 place++;
2515}
2516static void rO_ISSuffix(int &place, int &bitplace, int &prev_ord, long *o,
2517 int N, int *v, sro_ord *tmp_typ, int &typ_i, int sgn)
2518{
2519
2520 // Let's find previous prefix:
2521 int typ_j = typ_i - 1;
2522 while(typ_j >= 0)
2523 {
2524 if( tmp_typ[typ_j].ord_typ == ro_isTemp)
2525 break;
2526 typ_j --;
2527 }
2528
2529 assume( typ_j >= 0 );
2530
2531 if( typ_j < 0 ) // Found NO prefix!!! :(
2532 return;
2533
2534 assume( tmp_typ[typ_j].ord_typ == ro_isTemp );
2535
2536 // Get saved state:
2537 const int start = tmp_typ[typ_j].data.isTemp.start;
2538 int *pVarOffset = tmp_typ[typ_j].data.isTemp.pVarOffset;
2539
2540/*
2541 // shift up all blocks
2542 while(typ_j < (typ_i-1))
2543 {
2544 tmp_typ[typ_j] = tmp_typ[typ_j+1];
2545 typ_j++;
2546 }
2547 typ_j = typ_i - 1; // No increment for typ_i
2548*/
2549 tmp_typ[typ_j].data.isTemp.suffixpos = typ_i;
2550
2551 // Let's keep that dummy for now...
2552 typ_j = typ_i; // the typ to change!
2553 typ_i++; // Just for now...
2554
2555
2556 for( int i = 0; i <= N; i++ ) // Note [0] == component !!! No Skip?
2557 {
2558 // Was i-th variable allocated inbetween?
2559 if( v[i] != pVarOffset[i] )
2560 {
2561 pVarOffset[i] = v[i]; // Save for later...
2562 v[i] = -1; // Undo!
2563 assume( pVarOffset[i] != -1 );
2564 }
2565 else
2566 pVarOffset[i] = -1; // No change here...
2567 }
2568
2569 if( pVarOffset[0] != -1 )
2570 pVarOffset[0] &= 0x0fff;
2571
2572 sro_ord &ord_struct = tmp_typ[typ_j];
2573
2574
2575 ord_struct.ord_typ = ro_is;
2576 ord_struct.data.is.start = start;
2577 ord_struct.data.is.end = place;
2578 ord_struct.data.is.pVarOffset = pVarOffset;
2579
2580
2581 // What about component???
2582// if( v[0] != -1 ) // There is a component already...???
2583// if( o[ v[0] & 0x0fff ] == sgn )
2584// {
2585// pVarOffset[0] = -1; // NEVER USED Afterwards...
2586// return;
2587// }
2588
2589
2590 // Moreover: we need to allocate the module component (v[0]) here!
2591 if( v[0] == -1) // It's possible that there was module component v0 at the begining (before prefix)!
2592 {
2593 // Start with a whole long exponent
2594 if( bitplace != BITS_PER_LONG )
2595 rO_Align(place, bitplace);
2596
2597 assume( bitplace == BITS_PER_LONG );
2598 bitplace -= BITS_PER_LONG;
2599 assume(bitplace == 0);
2600 v[0] = place | (bitplace << 24); // Never mind whether pVarOffset[0] > 0!!!
2601 o[place] = sgn; // Singnum for component ordering
2602 prev_ord = sgn;
2603 }
2604}
2605
2606
2607static unsigned long rGetExpSize(unsigned long bitmask, int & bits)
2608{
2609 if (bitmask == 0)
2610 {
2611 bits=16; bitmask=0xffff;
2612 }
2613 else if (bitmask <= 1L)
2614 {
2615 bits=1; bitmask = 1L;
2616 }
2617 else if (bitmask <= 3L)
2618 {
2619 bits=2; bitmask = 3L;
2620 }
2621 else if (bitmask <= 7L)
2622 {
2623 bits=3; bitmask=7L;
2624 }
2625 else if (bitmask <= 0xfL)
2626 {
2627 bits=4; bitmask=0xfL;
2628 }
2629 else if (bitmask <= 0x1fL)
2630 {
2631 bits=5; bitmask=0x1fL;
2632 }
2633 else if (bitmask <= 0x3fL)
2634 {
2635 bits=6; bitmask=0x3fL;
2636 }
2637#if SIZEOF_LONG == 8
2638 else if (bitmask <= 0x7fL)
2639 {
2640 bits=7; bitmask=0x7fL; /* 64 bit longs only */
2641 }
2642#endif
2643 else if (bitmask <= 0xffL)
2644 {
2645 bits=8; bitmask=0xffL;
2646 }
2647#if SIZEOF_LONG == 8
2648 else if (bitmask <= 0x1ffL)
2649 {
2650 bits=9; bitmask=0x1ffL; /* 64 bit longs only */
2651 }
2652#endif
2653 else if (bitmask <= 0x3ffL)
2654 {
2655 bits=10; bitmask=0x3ffL;
2656 }
2657#if SIZEOF_LONG == 8
2658 else if (bitmask <= 0xfffL)
2659 {
2660 bits=12; bitmask=0xfff; /* 64 bit longs only */
2661 }
2662#endif
2663 else if (bitmask <= 0xffffL)
2664 {
2665 bits=16; bitmask=0xffffL;
2666 }
2667#if SIZEOF_LONG == 8
2668 else if (bitmask <= 0xfffffL)
2669 {
2670 bits=20; bitmask=0xfffffL; /* 64 bit longs only */
2671 }
2672 else if (bitmask <= 0xffffffffL)
2673 {
2674 bits=32; bitmask=0xffffffffL;
2675 }
2676 else if (bitmask <= 0x7fffffffffffffffL)
2677 {
2678 bits=63; bitmask=0x7fffffffffffffffL; /* for overflow tests*/
2679 }
2680 else
2681 {
2682 bits=63; bitmask=0x7fffffffffffffffL; /* for overflow tests*/
2683 }
2684#else
2685 else if (bitmask <= 0x7fffffff)
2686 {
2687 bits=31; bitmask=0x7fffffff; /* for overflow tests*/
2688 }
2689 else
2690 {
2691 bits=31; bitmask=0x7fffffffL; /* for overflow tests*/
2692 }
2693#endif
2694 return bitmask;
2695}
2696
2697/*2
2698* optimize rGetExpSize for a block of N variables, exp <=bitmask
2699*/
2700unsigned long rGetExpSize(unsigned long bitmask, int & bits, int N)
2701{
2702#if SIZEOF_LONG == 8
2703 if (N<4) N=4;
2704#else
2705 if (N<2) N=2;
2706#endif
2707 bitmask =rGetExpSize(bitmask, bits);
2708 int vars_per_long=BIT_SIZEOF_LONG/bits;
2709 int bits1;
2710 loop
2711 {
2712 if (bits == BIT_SIZEOF_LONG-1)
2713 {
2714 bits = BIT_SIZEOF_LONG - 1;
2715 return LONG_MAX;
2716 }
2717 unsigned long bitmask1 =rGetExpSize(bitmask+1, bits1);
2718 int vars_per_long1=BIT_SIZEOF_LONG/bits1;
2719 if ((((N+vars_per_long-1)/vars_per_long) ==
2720 ((N+vars_per_long1-1)/vars_per_long1)))
2721 {
2722 vars_per_long=vars_per_long1;
2723 bits=bits1;
2724 bitmask=bitmask1;
2725 }
2726 else
2727 {
2728 return bitmask; /* and bits */
2729 }
2730 }
2731}
2732
2733
2734/*2
2735 * create a copy of the ring r, which must be equivalent to currRing
2736 * used for std computations
2737 * may share data structures with currRing
2738 * DOES CALL rComplete
2739 */
2740ring rModifyRing(ring r, BOOLEAN omit_degree,
2741 BOOLEAN try_omit_comp,
2742 unsigned long exp_limit)
2743{
2744 assume (r != NULL );
2745 assume (exp_limit > 1);
2746 BOOLEAN omitted_degree = FALSE;
2747
2748 int bits;
2749 exp_limit=rGetExpSize(exp_limit, bits, r->N);
2750 BOOLEAN need_other_ring = (exp_limit != r->bitmask);
2751
2752 int iNeedInducedOrderingSetup = 0; ///< How many induced ordering block do we have?
2753
2754 int nblocks=rBlocks(r);
2755 rRingOrder_t *order=(rRingOrder_t*)omAlloc0((nblocks+1)*sizeof(rRingOrder_t));
2756 int *block0=(int*)omAlloc0((nblocks+1)*sizeof(int));
2757 int *block1=(int*)omAlloc0((nblocks+1)*sizeof(int));
2758 int **wvhdl=(int**)omAlloc0((nblocks+1)*sizeof(int *));
2759
2760 int i=0;
2761 int j=0; /* i index in r, j index in res */
2762
2763 for( rRingOrder_t r_ord=r->order[i]; (r_ord != (rRingOrder_t)0) && (i < nblocks); j++, r_ord=r->order[++i])
2764 {
2765 BOOLEAN copy_block_index=TRUE;
2766
2767 if (r->block0[i]==r->block1[i])
2768 {
2769 switch(r_ord)
2770 {
2771 case ringorder_wp:
2772 case ringorder_dp:
2773 case ringorder_Wp:
2774 case ringorder_Dp:
2775 r_ord=ringorder_lp;
2776 break;
2777 case ringorder_Ws:
2778 case ringorder_Ds:
2779 case ringorder_ws:
2780 case ringorder_ds:
2781 r_ord=ringorder_ls;
2782 break;
2783 default:
2784 break;
2785 }
2786 }
2787 switch(r_ord)
2788 {
2789 case ringorder_S:
2790 {
2791#ifndef SING_NDEBUG
2792 Warn("Error: unhandled ordering in rModifyRing: ringorder_S = [%d]", r_ord);
2793#endif
2794 order[j]=r_ord; /*r->order[i];*/
2795 break;
2796 }
2797 case ringorder_C:
2798 case ringorder_c:
2799 if (!try_omit_comp)
2800 {
2801 order[j]=r_ord; /*r->order[i]*/;
2802 }
2803 else
2804 {
2805 j--;
2806 need_other_ring=TRUE;
2807 try_omit_comp=FALSE;
2808 copy_block_index=FALSE;
2809 }
2810 break;
2811 case ringorder_wp:
2812 case ringorder_dp:
2813 case ringorder_ws:
2814 case ringorder_ds:
2815 if(!omit_degree)
2816 {
2817 order[j]=r_ord; /*r->order[i]*/;
2818 }
2819 else
2820 {
2821 order[j]=ringorder_rs;
2822 need_other_ring=TRUE;
2823 omit_degree=FALSE;
2824 omitted_degree = TRUE;
2825 }
2826 break;
2827 case ringorder_Wp:
2828 case ringorder_Dp:
2829 case ringorder_Ws:
2830 case ringorder_Ds:
2831 if(!omit_degree)
2832 {
2833 order[j]=r_ord; /*r->order[i];*/
2834 }
2835 else
2836 {
2837 order[j]=ringorder_lp;
2838 need_other_ring=TRUE;
2839 omit_degree=FALSE;
2840 omitted_degree = TRUE;
2841 }
2842 break;
2843 case ringorder_IS:
2844 {
2845 if (try_omit_comp)
2846 {
2847 // tried, but cannot omit component due to the ordering block [%d]: %d (ringorder_IS)", i, r_ord
2848 try_omit_comp = FALSE;
2849 }
2850 order[j]=r_ord; /*r->order[i];*/
2851 iNeedInducedOrderingSetup++;
2852 break;
2853 }
2854 case ringorder_s:
2855 {
2856 assume((i == 0) && (j == 0));
2857 if (try_omit_comp)
2858 {
2859 // tried, but cannot omit component due to the ordering block [%d]: %d (ringorder_s)", i, r_ord
2860 try_omit_comp = FALSE;
2861 }
2862 order[j]=r_ord; /*r->order[i];*/
2863 break;
2864 }
2865 default:
2866 order[j]=r_ord; /*r->order[i];*/
2867 break;
2868 }
2869 if (copy_block_index)
2870 {
2871 block0[j]=r->block0[i];
2872 block1[j]=r->block1[i];
2873 wvhdl[j]=r->wvhdl[i];
2874 }
2875
2876 // order[j]=ringorder_no; // done by omAlloc0
2877 }
2878 if(!need_other_ring)
2879 {
2880 omFreeSize(order,(nblocks+1)*sizeof(rRingOrder_t));
2881 omFreeSize(block0,(nblocks+1)*sizeof(int));
2882 omFreeSize(block1,(nblocks+1)*sizeof(int));
2883 omFreeSize(wvhdl,(nblocks+1)*sizeof(int *));
2884 return r;
2885 }
2886 ring res=(ring)omAlloc0Bin(sip_sring_bin);
2887 *res = *r;
2888
2889#ifdef HAVE_PLURAL
2890 res->GetNC() = NULL;
2891#endif
2892
2893 // res->qideal, res->idroot ???
2894 res->wvhdl=wvhdl;
2895 res->order=order;
2896 res->block0=block0;
2897 res->block1=block1;
2898 res->bitmask=exp_limit;
2899 res->wanted_maxExp=r->wanted_maxExp;
2900 //int tmpref=r->cf->ref0;
2901 rComplete(res, 1);
2902 //r->cf->ref=tmpref;
2903
2904 // adjust res->pFDeg: if it was changed globally, then
2905 // it must also be changed for new ring
2906 if (r->pFDegOrig != res->pFDegOrig &&
2908 {
2909 // still might need adjustment for weighted orderings
2910 // and omit_degree
2911 res->firstwv = r->firstwv;
2912 res->firstBlockEnds = r->firstBlockEnds;
2913 res->pFDeg = res->pFDegOrig = p_WFirstTotalDegree;
2914 }
2915 if (omitted_degree)
2916 res->pLDeg = r->pLDegOrig;
2917
2918 rOptimizeLDeg(res); // also sets res->pLDegOrig
2919
2920 // set syzcomp
2921 if (res->typ != NULL)
2922 {
2923 if( res->typ[0].ord_typ == ro_syz) // "s" Always on [0] place!
2924 {
2925 res->typ[0] = r->typ[0]; // Copy struct!? + setup the same limit!
2926
2927 if (r->typ[0].data.syz.limit > 0)
2928 {
2929 res->typ[0].data.syz.syz_index
2930 = (int*) omAlloc((r->typ[0].data.syz.limit +1)*sizeof(int));
2931 memcpy(res->typ[0].data.syz.syz_index, r->typ[0].data.syz.syz_index,
2932 (r->typ[0].data.syz.limit +1)*sizeof(int));
2933 }
2934 }
2935
2936 if( iNeedInducedOrderingSetup > 0 )
2937 {
2938 for(j = 0, i = 0; (i < nblocks) && (iNeedInducedOrderingSetup > 0); i++)
2939 if( res->typ[i].ord_typ == ro_is ) // Search for suffixes!
2940 {
2941 ideal F = idrHeadR(r->typ[i].data.is.F, r, res); // Copy F from r into res!
2942 assume(
2944 F, // WILL BE COPIED!
2945 r->typ[i].data.is.limit,
2946 j++
2947 )
2948 );
2949 id_Delete(&F, res);
2950 iNeedInducedOrderingSetup--;
2951 }
2952 } // Process all induced Ordering blocks! ...
2953 }
2954 // the special case: homog (omit_degree) and 1 block rs: that is global:
2955 // it comes from dp
2956 res->OrdSgn=r->OrdSgn;
2957
2958
2959#ifdef HAVE_PLURAL
2960 if (rIsPluralRing(r))
2961 {
2962 if ( nc_rComplete(r, res, false) ) // no qideal!
2963 {
2964#ifndef SING_NDEBUG
2965 WarnS("error in nc_rComplete");
2966#endif
2967 // cleanup?
2968
2969// rDelete(res);
2970// return r;
2971
2972 // just go on..
2973 }
2974
2975 if( rIsSCA(r) )
2976 {
2978 WarnS("error in sca_Force!");
2979 }
2980 }
2981#endif
2982
2983 return res;
2984}
2985
2986// construct Wp,C ring
2987ring rModifyRing_Wp(ring r, int* weights)
2988{
2989 ring res=(ring)omAlloc0Bin(sip_sring_bin);
2990 *res = *r;
2991#ifdef HAVE_PLURAL
2992 res->GetNC() = NULL;
2993#endif
2994
2995 /*weights: entries for 3 blocks: NULL*/
2996 res->wvhdl = (int **)omAlloc0(3 * sizeof(int *));
2997 /*order: Wp,C,0*/
2998 res->order = (rRingOrder_t *) omAlloc(3 * sizeof(rRingOrder_t *));
2999 res->block0 = (int *)omAlloc0(3 * sizeof(int *));
3000 res->block1 = (int *)omAlloc0(3 * sizeof(int *));
3001 /* ringorder Wp for the first block: var 1..r->N */
3002 res->order[0] = ringorder_Wp;
3003 res->block0[0] = 1;
3004 res->block1[0] = r->N;
3005 res->wvhdl[0] = weights;
3006 /* ringorder C for the second block: no vars */
3007 res->order[1] = ringorder_C;
3008 /* the last block: everything is 0 */
3009 res->order[2] = (rRingOrder_t)0;
3010
3011 //int tmpref=r->cf->ref;
3012 rComplete(res, 1);
3013 //r->cf->ref=tmpref;
3014#ifdef HAVE_PLURAL
3015 if (rIsPluralRing(r))
3016 {
3017 if ( nc_rComplete(r, res, false) ) // no qideal!
3018 {
3019#ifndef SING_NDEBUG
3020 WarnS("error in nc_rComplete");
3021#endif
3022 // cleanup?
3023
3024// rDelete(res);
3025// return r;
3026
3027 // just go on..
3028 }
3029 }
3030#endif
3031 return res;
3032}
3033
3034// construct lp, C ring with r->N variables, r->names vars....
3035ring rModifyRing_Simple(ring r, BOOLEAN ommit_degree, BOOLEAN ommit_comp, unsigned long exp_limit, BOOLEAN &simple)
3036{
3037 simple=TRUE;
3038 if (!rHasSimpleOrder(r))
3039 {
3040 simple=FALSE; // sorting needed
3041 assume (r != NULL );
3042 assume (exp_limit > 1);
3043 int bits;
3044
3045 exp_limit=rGetExpSize(exp_limit, bits, r->N);
3046
3047 int nblocks=1+(ommit_comp!=0);
3048 rRingOrder_t *order=(rRingOrder_t*)omAlloc0((nblocks+1)*sizeof(rRingOrder_t));
3049 int *block0=(int*)omAlloc0((nblocks+1)*sizeof(int));
3050 int *block1=(int*)omAlloc0((nblocks+1)*sizeof(int));
3051 int **wvhdl=(int**)omAlloc0((nblocks+1)*sizeof(int *));
3052
3053 order[0]=ringorder_lp;
3054 block0[0]=1;
3055 block1[0]=r->N;
3056 if (!ommit_comp)
3057 {
3058 order[1]=ringorder_C;
3059 }
3060 ring res=(ring)omAlloc0Bin(sip_sring_bin);
3061 *res = *r;
3062#ifdef HAVE_PLURAL
3063 res->GetNC() = NULL;
3064#endif
3065 // res->qideal, res->idroot ???
3066 res->wvhdl=wvhdl;
3067 res->order=order;
3068 res->block0=block0;
3069 res->block1=block1;
3070 res->bitmask=exp_limit;
3071 res->wanted_maxExp=r->wanted_maxExp;
3072 //int tmpref=r->cf->ref;
3073 rComplete(res, 1);
3074 //r->cf->ref=tmpref;
3075
3076#ifdef HAVE_PLURAL
3077 if (rIsPluralRing(r))
3078 {
3079 if ( nc_rComplete(r, res, false) ) // no qideal!
3080 {
3081#ifndef SING_NDEBUG
3082 WarnS("error in nc_rComplete");
3083#endif
3084 // cleanup?
3085
3086// rDelete(res);
3087// return r;
3088
3089 // just go on..
3090 }
3091 }
3092#endif
3093
3095
3096 return res;
3097 }
3098 return rModifyRing(r, ommit_degree, ommit_comp, exp_limit);
3099}
3100
3102{
3103 rUnComplete(r);
3104 omFree(r->order);
3105 omFree(r->block0);
3106 omFree(r->block1);
3107 omFree(r->wvhdl);
3109}
3110
3112{
3113 rUnComplete(r);
3114 omFree(r->order);
3115 omFree(r->block0);
3116 omFree(r->block1);
3117 omFree(r->wvhdl[0]);
3118 omFree(r->wvhdl);
3120}
3121
3122static void rSetOutParams(ring r)
3123{
3124 r->VectorOut = (r->order[0] == ringorder_c);
3125 if (rIsNCRing(r))
3126 r->CanShortOut=FALSE;
3127 else
3128 {
3129 r->CanShortOut = TRUE;
3130 int i;
3131 if (rParameter(r)!=NULL)
3132 {
3133 for (i=0;i<rPar(r);i++)
3134 {
3135 if(strlen(rParameter(r)[i])>1)
3136 {
3137 r->CanShortOut=FALSE;
3138 break;
3139 }
3140 }
3141 }
3142 if (r->CanShortOut)
3143 {
3144 int N = r->N;
3145 for (i=(N-1);i>=0;i--)
3146 {
3147 if(r->names[i] != NULL && strlen(r->names[i])>1)
3148 {
3149 r->CanShortOut=FALSE;
3150 break;
3151 }
3152 }
3153 }
3154 }
3155 r->ShortOut = r->CanShortOut;
3156
3157 assume( !( !r->CanShortOut && r->ShortOut ) );
3158}
3159
3160static void rSetFirstWv(ring r, int i, rRingOrder_t* order, int* block0, int* block1, int** wvhdl)
3161{
3162 // cheat for ringorder_aa
3163 if (order[i] == ringorder_aa)
3164 i++;
3165 if(block1[i]!=r->N) r->LexOrder=TRUE;
3166 r->firstBlockEnds=block1[i];
3167 r->firstwv = wvhdl[i];
3168 if ((order[i]== ringorder_ws)
3169 || (order[i]==ringorder_Ws)
3170 || (order[i]== ringorder_wp)
3171 || (order[i]==ringorder_Wp)
3172 || (order[i]== ringorder_a)
3173 /*|| (order[i]==ringorder_A)*/)
3174 {
3175 int j;
3176 for(j=block1[i]-block0[i];j>=0;j--)
3177 {
3178 if (r->firstwv[j]==0) r->LexOrder=TRUE;
3179 }
3180 }
3181 else if (order[i]==ringorder_a64)
3182 {
3183 int j;
3184 int64 *w=rGetWeightVec(r);
3185 for(j=block1[i]-block0[i];j>=0;j--)
3186 {
3187 if (w[j]==0) r->LexOrder=TRUE;
3188 }
3189 }
3190}
3191
3192static void rOptimizeLDeg(ring r)
3193{
3194 if (r->pFDeg == p_Deg)
3195 {
3196 if (r->pLDeg == pLDeg1)
3197 r->pLDeg = pLDeg1_Deg;
3198 if (r->pLDeg == pLDeg1c)
3199 r->pLDeg = pLDeg1c_Deg;
3200 }
3201 else if (r->pFDeg == p_Totaldegree)
3202 {
3203 if (r->pLDeg == pLDeg1)
3204 r->pLDeg = pLDeg1_Totaldegree;
3205 if (r->pLDeg == pLDeg1c)
3206 r->pLDeg = pLDeg1c_Totaldegree;
3207 }
3208 else if (r->pFDeg == p_WFirstTotalDegree)
3209 {
3210 if (r->pLDeg == pLDeg1)
3211 r->pLDeg = pLDeg1_WFirstTotalDegree;
3212 if (r->pLDeg == pLDeg1c)
3213 r->pLDeg = pLDeg1c_WFirstTotalDegree;
3214 }
3215 r->pLDegOrig = r->pLDeg;
3216}
3217
3218// set pFDeg, pLDeg, requires OrdSgn already set
3219static void rSetDegStuff(ring r)
3220{
3221 rRingOrder_t* order = r->order;
3222 int* block0 = r->block0;
3223 int* block1 = r->block1;
3224 int** wvhdl = r->wvhdl;
3225
3226 if (order[0]==ringorder_S ||order[0]==ringorder_s || order[0]==ringorder_IS)
3227 {
3228 order++;
3229 block0++;
3230 block1++;
3231 wvhdl++;
3232 }
3233 r->LexOrder = FALSE;
3234 r->pFDeg = p_Totaldegree;
3235 r->pLDeg = (r->OrdSgn == 1 ? pLDegb : pLDeg0);
3236
3237 /*======== ordering type is (am,_) ==================*/
3238 if (order[0]==ringorder_am)
3239 {
3240 for(int ii=block0[0];ii<=block1[0];ii++)
3241 if (wvhdl[0][ii-1]<0) { r->MixedOrder=2;break;}
3242 r->LexOrder=FALSE;
3243 for(int ii=block0[0];ii<=block1[0];ii++)
3244 if (wvhdl[0][ii-1]==0) { r->LexOrder=TRUE;break;}
3245 if ((block0[0]==1)&&(block1[0]==r->N))
3246 {
3247 r->pFDeg = p_Deg;
3248 r->pLDeg = pLDeg1c_Deg;
3249 }
3250 else
3251 {
3252 r->pFDeg = p_WTotaldegree;
3253 r->LexOrder=TRUE;
3254 r->pLDeg = pLDeg1c_WFirstTotalDegree;
3255 }
3256 r->firstwv = wvhdl[0];
3257 }
3258 /*======== ordering type is (_,c) =========================*/
3259 else if ((order[0]==ringorder_unspec) || (order[1] == 0)
3260 ||(
3261 ((order[1]==ringorder_c)||(order[1]==ringorder_C)
3262 ||(order[1]==ringorder_S)
3263 ||(order[1]==ringorder_s))
3264 && (order[0]!=ringorder_M)
3265 && (order[2]==0))
3266 )
3267 {
3268 if (r->OrdSgn == -1) r->pLDeg = pLDeg0c;
3269 if ((order[0] == ringorder_lp)
3270 || (order[0] == ringorder_ls)
3271 || (order[0] == ringorder_rp)
3272 || (order[0] == ringorder_rs))
3273 {
3274 r->LexOrder=TRUE;
3275 r->pLDeg = pLDeg1c;
3276 r->pFDeg = p_Totaldegree;
3277 }
3278 else if ((order[0] == ringorder_a)
3279 || (order[0] == ringorder_wp)
3280 || (order[0] == ringorder_Wp))
3281 {
3282 r->pFDeg = p_WFirstTotalDegree;
3283 }
3284 else if ((order[0] == ringorder_ws)
3285 || (order[0] == ringorder_Ws))
3286 {
3287 for(int ii=block0[0];ii<=block1[0];ii++)
3288 {
3289 if (wvhdl[0][ii-1]<0) { r->MixedOrder=2;break;}
3290 }
3291 if (r->MixedOrder==0)
3292 {
3293 if ((block0[0]==1)&&(block1[0]==r->N))
3294 r->pFDeg = p_WTotaldegree;
3295 else
3296 r->pFDeg = p_WFirstTotalDegree;
3297 }
3298 else
3299 r->pFDeg = p_Totaldegree;
3300 }
3301 r->firstBlockEnds=block1[0];
3302 r->firstwv = wvhdl[0];
3303 }
3304 /*======== ordering type is (c,_) =========================*/
3305 else if (((order[0]==ringorder_c)
3306 ||(order[0]==ringorder_C)
3307 ||(order[0]==ringorder_S)
3308 ||(order[0]==ringorder_s))
3309 && (order[1]!=ringorder_M)
3310 && (order[2]==0))
3311 {
3312 if ((order[1] == ringorder_lp)
3313 || (order[1] == ringorder_ls)
3314 || (order[1] == ringorder_rp)
3315 || order[1] == ringorder_rs)
3316 {
3317 r->LexOrder=TRUE;
3318 r->pLDeg = pLDeg1c;
3319 r->pFDeg = p_Totaldegree;
3320 }
3321 r->firstBlockEnds=block1[1];
3322 if (wvhdl!=NULL) r->firstwv = wvhdl[1];
3323 if ((order[1] == ringorder_a)
3324 || (order[1] == ringorder_wp)
3325 || (order[1] == ringorder_Wp))
3326 r->pFDeg = p_WFirstTotalDegree;
3327 else if ((order[1] == ringorder_ws)
3328 || (order[1] == ringorder_Ws))
3329 {
3330 for(int ii=block0[1];ii<=block1[1];ii++)
3331 if (wvhdl[1][ii-1]<0) { r->MixedOrder=2;break;}
3332 if (r->MixedOrder==FALSE)
3333 r->pFDeg = p_WFirstTotalDegree;
3334 else
3335 r->pFDeg = p_Totaldegree;
3336 }
3337 }
3338 /*------- more than one block ----------------------*/
3339 else
3340 {
3341 if ((r->VectorOut)||(order[0]==ringorder_C)||(order[0]==ringorder_S)||(order[0]==ringorder_s))
3342 {
3343 rSetFirstWv(r, 1, order, block0, block1, wvhdl);
3344 }
3345 else
3346 rSetFirstWv(r, 0, order, block0, block1, wvhdl);
3347
3348 if ((order[0]!=ringorder_c)
3349 && (order[0]!=ringorder_C)
3350 && (order[0]!=ringorder_S)
3351 && (order[0]!=ringorder_s))
3352 {
3353 r->pLDeg = pLDeg1c;
3354 }
3355 else
3356 {
3357 r->pLDeg = pLDeg1;
3358 }
3359 r->pFDeg = p_WTotaldegree; // may be improved: p_Totaldegree for lp/dp/ls/.. blocks
3360 }
3361
3364 {
3365 if(r->MixedOrder==FALSE)
3366 r->pFDeg = p_Deg;
3367 else
3368 r->pFDeg = p_Totaldegree;
3369 }
3370
3371 if( rGetISPos(0, r) != -1 ) // Are there Schreyer induced blocks?
3372 {
3373#ifndef SING_NDEBUG
3374 assume( r->pFDeg == p_Deg || r->pFDeg == p_WTotaldegree || r->pFDeg == p_Totaldegree);
3375#endif
3376
3377 r->pLDeg = pLDeg1; // ?
3378 }
3379
3380 r->pFDegOrig = r->pFDeg;
3381 // NOTE: this leads to wrong ecart during std
3382 // in Old/sre.tst
3383 rOptimizeLDeg(r); // also sets r->pLDegOrig
3384}
3385
3386/*2
3387* set NegWeightL_Size, NegWeightL_Offset
3388*/
3389static void rSetNegWeight(ring r)
3390{
3391 int i,l;
3392 if (r->typ!=NULL)
3393 {
3394 l=0;
3395 for(i=0;i<r->OrdSize;i++)
3396 {
3397 if((r->typ[i].ord_typ==ro_wp_neg)
3398 ||(r->typ[i].ord_typ==ro_am))
3399 l++;
3400 }
3401 if (l>0)
3402 {
3403 r->NegWeightL_Size=l;
3404 r->NegWeightL_Offset=(int *) omAlloc(l*sizeof(int));
3405 l=0;
3406 for(i=0;i<r->OrdSize;i++)
3407 {
3408 if(r->typ[i].ord_typ==ro_wp_neg)
3409 {
3410 r->NegWeightL_Offset[l]=r->typ[i].data.wp.place;
3411 l++;
3412 }
3413 else if(r->typ[i].ord_typ==ro_am)
3414 {
3415 r->NegWeightL_Offset[l]=r->typ[i].data.am.place;
3416 l++;
3417 }
3418 }
3419 return;
3420 }
3421 }
3422 r->NegWeightL_Size = 0;
3423 r->NegWeightL_Offset = NULL;
3424}
3425
3426static void rSetOption(ring r)
3427{
3428 // set redthrough
3429 if (!TEST_OPT_OLDSTD && r->OrdSgn == 1 && ! r->LexOrder)
3430 r->options |= Sy_bit(OPT_REDTHROUGH);
3431 else
3432 r->options &= ~Sy_bit(OPT_REDTHROUGH);
3433
3434 // set intStrategy
3435 if ( (r->cf->extRing!=NULL)
3436 || rField_is_Q(r)
3437 || rField_is_Ring(r)
3438 )
3439 r->options |= Sy_bit(OPT_INTSTRATEGY);
3440 else
3441 r->options &= ~Sy_bit(OPT_INTSTRATEGY);
3442
3443 // set redTail
3444 if (r->LexOrder || r->OrdSgn == -1 || (r->cf->extRing!=NULL))
3445 r->options &= ~Sy_bit(OPT_REDTAIL);
3446 else
3447 r->options |= Sy_bit(OPT_REDTAIL);
3448}
3449
3450static void rCheckOrdSgn(ring r,int i/*last block*/);
3451
3452/* -------------------------------------------------------- */
3453/*2
3454* change all global variables to fit the description of the new ring
3455*/
3456
3457void p_SetGlobals(const ring r, BOOLEAN complete)
3458{
3459// // // if (r->ppNoether!=NULL) p_Delete(&r->ppNoether,r); // ???
3460
3461 r->pLexOrder=r->LexOrder;
3462 if (complete)
3463 {
3464 si_opt_1 &= ~ TEST_RINGDEP_OPTS;
3465 si_opt_1 |= r->options;
3466 }
3467}
3468
3469static inline int sign(int x) { return (x > 0) - (x < 0);}
3471{
3472 int i;
3473 poly p=p_One(r);
3474 p_SetExp(p,1,1,r);
3475 p_Setm(p,r);
3476 int vz=sign(p_FDeg(p,r));
3477 for(i=2;i<=rVar(r);i++)
3478 {
3479 p_SetExp(p,i-1,0,r);
3480 p_SetExp(p,i,1,r);
3481 p_Setm(p,r);
3482 if (sign(p_FDeg(p,r))!=vz)
3483 {
3484 p_Delete(&p,r);
3485 return TRUE;
3486 }
3487 }
3488 p_Delete(&p,r);
3489 return FALSE;
3490}
3491
3492BOOLEAN rComplete(ring r, int force)
3493{
3494 if (r->VarOffset!=NULL && force == 0) return FALSE;
3495 rSetOutParams(r);
3496 int n=rBlocks(r)-1;
3497 int i;
3498 int bits;
3499 r->bitmask=rGetExpSize(r->wanted_maxExp,bits,r->N);
3500 r->BitsPerExp = bits;
3501 r->ExpPerLong = BIT_SIZEOF_LONG / bits;
3502 r->divmask=rGetDivMask(bits);
3503
3504 // will be used for ordsgn:
3505 long *tmp_ordsgn=(long *)omAlloc0(3*(n+r->N)*sizeof(long));
3506 // will be used for VarOffset:
3507 int *v=(int *)omAlloc((r->N+1)*sizeof(int));
3508 for(i=r->N; i>=0 ; i--)
3509 {
3510 v[i]=-1;
3511 }
3512 sro_ord *tmp_typ=(sro_ord *)omAlloc0(3*(n+r->N)*sizeof(sro_ord));
3513 int typ_i=0;
3514 int prev_ordsgn=0;
3515
3516 // fill in v, tmp_typ, tmp_ordsgn, determine typ_i (== ordSize)
3517 int j=0;
3518 int j_bits=BITS_PER_LONG;
3519
3520 BOOLEAN need_to_add_comp=FALSE; // Only for ringorder_s and ringorder_S!
3521
3522 for(i=0;i<n;i++)
3523 {
3524 tmp_typ[typ_i].order_index=i;
3525 switch (r->order[i])
3526 {
3527 case ringorder_a:
3528 case ringorder_aa:
3529 rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,tmp_typ[typ_i],
3530 r->wvhdl[i]);
3531 typ_i++;
3532 break;
3533
3534 case ringorder_am:
3535 rO_WMDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,tmp_typ[typ_i],
3536 r->wvhdl[i]);
3537 typ_i++;
3538 break;
3539
3540 case ringorder_a64:
3541 rO_WDegree64(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3542 tmp_typ[typ_i], (int64 *)(r->wvhdl[i]));
3543 typ_i++;
3544 break;
3545
3546 case ringorder_c:
3547 rO_Align(j, j_bits);
3548 rO_LexVars_neg(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
3549 r->ComponentOrder=1;
3550 break;
3551
3552 case ringorder_C:
3553 rO_Align(j, j_bits);
3554 rO_LexVars(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
3555 r->ComponentOrder=-1;
3556 break;
3557
3558 case ringorder_M:
3559 {
3560 int k,l;
3561 k=r->block1[i]-r->block0[i]+1; // number of vars
3562 for(l=0;l<k;l++)
3563 {
3564 rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3565 tmp_typ[typ_i],
3566 r->wvhdl[i]+(r->block1[i]-r->block0[i]+1)*l);
3567 typ_i++;
3568 }
3569 break;
3570 }
3571
3572 case ringorder_lp:
3573 rO_LexVars(j, j_bits, r->block0[i],r->block1[i], prev_ordsgn,
3574 tmp_ordsgn,v,bits, -1);
3575 break;
3576
3577 case ringorder_ls:
3578 rO_LexVars_neg(j, j_bits, r->block0[i],r->block1[i], prev_ordsgn,
3579 tmp_ordsgn,v, bits, -1);
3580 break;
3581
3582 case ringorder_rs:
3583 rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i], prev_ordsgn,
3584 tmp_ordsgn,v, bits, -1);
3585 break;
3586
3587 case ringorder_rp:
3588 rO_LexVars(j, j_bits, r->block1[i],r->block0[i], prev_ordsgn,
3589 tmp_ordsgn,v, bits, -1);
3590 break;
3591
3592 case ringorder_dp:
3593 if (r->block0[i]==r->block1[i])
3594 {
3595 rO_LexVars(j, j_bits, r->block0[i],r->block0[i], prev_ordsgn,
3596 tmp_ordsgn,v, bits, -1);
3597 }
3598 else
3599 {
3600 rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3601 tmp_typ[typ_i]);
3602 typ_i++;
3603 rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i]+1,
3604 prev_ordsgn,tmp_ordsgn,v,bits, r->block0[i]);
3605 }
3606 break;
3607
3608 case ringorder_Dp:
3609 if (r->block0[i]==r->block1[i])
3610 {
3611 rO_LexVars(j, j_bits, r->block0[i],r->block0[i], prev_ordsgn,
3612 tmp_ordsgn,v, bits, -1);
3613 }
3614 else
3615 {
3616 rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3617 tmp_typ[typ_i]);
3618 typ_i++;
3619 rO_LexVars(j, j_bits, r->block0[i],r->block1[i]-1, prev_ordsgn,
3620 tmp_ordsgn,v, bits, r->block1[i]);
3621 }
3622 break;
3623
3624 case ringorder_ds:
3625 if (r->block0[i]==r->block1[i])
3626 {
3627 rO_LexVars_neg(j, j_bits,r->block0[i],r->block1[i],prev_ordsgn,
3628 tmp_ordsgn,v,bits, -1);
3629 }
3630 else
3631 {
3632 rO_TDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3633 tmp_typ[typ_i]);
3634 typ_i++;
3635 rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i]+1,
3636 prev_ordsgn,tmp_ordsgn,v,bits, r->block0[i]);
3637 }
3638 break;
3639
3640 case ringorder_Ds:
3641 if (r->block0[i]==r->block1[i])
3642 {
3643 rO_LexVars_neg(j, j_bits, r->block0[i],r->block0[i],prev_ordsgn,
3644 tmp_ordsgn,v, bits, -1);
3645 }
3646 else
3647 {
3648 rO_TDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3649 tmp_typ[typ_i]);
3650 typ_i++;
3651 rO_LexVars(j, j_bits, r->block0[i],r->block1[i]-1, prev_ordsgn,
3652 tmp_ordsgn,v, bits, r->block1[i]);
3653 }
3654 break;
3655
3656 case ringorder_wp:
3657 rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3658 tmp_typ[typ_i], r->wvhdl[i]);
3659 typ_i++;
3660 { // check for weights <=0
3661 int jj;
3662 BOOLEAN have_bad_weights=FALSE;
3663 for(jj=r->block1[i]-r->block0[i];jj>=0; jj--)
3664 {
3665 if (r->wvhdl[i][jj]<=0) have_bad_weights=TRUE;
3666 }
3667 if (have_bad_weights)
3668 {
3669 rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3670 tmp_typ[typ_i]);
3671 typ_i++;
3672 }
3673 }
3674 if (r->block1[i]!=r->block0[i])
3675 {
3676 rO_LexVars_neg(j, j_bits,r->block1[i],r->block0[i]+1, prev_ordsgn,
3677 tmp_ordsgn, v,bits, r->block0[i]);
3678 }
3679 break;
3680
3681 case ringorder_Wp:
3682 rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3683 tmp_typ[typ_i], r->wvhdl[i]);
3684 typ_i++;
3685 { // check for weights <=0
3686 int jj;
3687 BOOLEAN have_bad_weights=FALSE;
3688 for(jj=r->block1[i]-r->block0[i];jj>=0; jj--)
3689 {
3690 if (r->wvhdl[i][jj]<=0) have_bad_weights=TRUE;
3691 }
3692 if (have_bad_weights)
3693 {
3694 rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3695 tmp_typ[typ_i]);
3696 typ_i++;
3697 }
3698 }
3699 if (r->block1[i]!=r->block0[i])
3700 {
3701 rO_LexVars(j, j_bits,r->block0[i],r->block1[i]-1, prev_ordsgn,
3702 tmp_ordsgn,v, bits, r->block1[i]);
3703 }
3704 break;
3705
3706 case ringorder_ws:
3707 rO_WDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3708 tmp_typ[typ_i], r->wvhdl[i]);
3709 typ_i++;
3710 if (r->block1[i]!=r->block0[i])
3711 {
3712 rO_LexVars_neg(j, j_bits,r->block1[i],r->block0[i]+1, prev_ordsgn,
3713 tmp_ordsgn, v,bits, r->block0[i]);
3714 }
3715 break;
3716
3717 case ringorder_Ws:
3718 rO_WDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3719 tmp_typ[typ_i], r->wvhdl[i]);
3720 typ_i++;
3721 if (r->block1[i]!=r->block0[i])
3722 {
3723 rO_LexVars(j, j_bits,r->block0[i],r->block1[i]-1, prev_ordsgn,
3724 tmp_ordsgn,v, bits, r->block1[i]);
3725 }
3726 break;
3727
3728 case ringorder_S:
3729 assume(typ_i == 1); // For LaScala3 only: on the 2nd place ([1])!
3730 // TODO: for K[x]: it is 0...?!
3731 rO_Syzcomp(j, j_bits,prev_ordsgn, tmp_ordsgn,tmp_typ[typ_i]);
3732 need_to_add_comp=TRUE;
3733 r->ComponentOrder=-1;
3734 typ_i++;
3735 break;
3736
3737 case ringorder_s:
3738 assume(typ_i == 0 && j == 0);
3739 rO_Syz(j, j_bits, prev_ordsgn, r->block0[i], tmp_ordsgn, tmp_typ[typ_i]); // set syz-limit?
3740 need_to_add_comp=TRUE;
3741 r->ComponentOrder=-1;
3742 typ_i++;
3743 break;
3744
3745 case ringorder_IS:
3746 {
3747
3748 assume( r->block0[i] == r->block1[i] );
3749 const int s = r->block0[i];
3750 assume( -2 < s && s < 2);
3751
3752 if(s == 0) // Prefix IS
3753 rO_ISPrefix(j, j_bits, prev_ordsgn, tmp_ordsgn, r->N, v, tmp_typ[typ_i++]); // What about prev_ordsgn?
3754 else // s = +1 or -1 // Note: typ_i might be incrimented here inside!
3755 {
3756 rO_ISSuffix(j, j_bits, prev_ordsgn, tmp_ordsgn, r->N, v, tmp_typ, typ_i, s); // Suffix.
3757 need_to_add_comp=FALSE;
3758 }
3759
3760 break;
3761 }
3762 case ringorder_unspec:
3763 case ringorder_no:
3764 default:
3765 dReportError("undef. ringorder used\n");
3766 break;
3767 }
3768 }
3769 rCheckOrdSgn(r,n-1);
3770
3771 int j0=j; // save j
3772 int j_bits0=j_bits; // save jbits
3773 rO_Align(j,j_bits);
3774 r->CmpL_Size = j;
3775
3776 j_bits=j_bits0; j=j0;
3777
3778 // fill in some empty slots with variables not already covered
3779 // v0 is special, is therefore normally already covered
3780 // now we do have rings without comp...
3781 if((need_to_add_comp) && (v[0]== -1))
3782 {
3783 if (prev_ordsgn==1)
3784 {
3785 rO_Align(j, j_bits);
3786 rO_LexVars(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
3787 }
3788 else
3789 {
3790 rO_Align(j, j_bits);
3791 rO_LexVars_neg(j, j_bits, 0,0, prev_ordsgn,tmp_ordsgn,v,BITS_PER_LONG, -1);
3792 }
3793 }
3794 // the variables
3795 for(i=1 ; i<=r->N ; i++)
3796 {
3797 if(v[i]==(-1))
3798 {
3799 if (prev_ordsgn==1)
3800 {
3801 rO_LexVars(j, j_bits, i,i, prev_ordsgn,tmp_ordsgn,v,bits, -1);
3802 }
3803 else
3804 {
3805 rO_LexVars_neg(j,j_bits,i,i, prev_ordsgn,tmp_ordsgn,v,bits, -1);
3806 }
3807 }
3808 }
3809
3810 rO_Align(j,j_bits);
3811 // ----------------------------
3812 // finished with constructing the monomial, computing sizes:
3813
3814 r->ExpL_Size=j;
3815 r->PolyBin = omGetSpecBin(POLYSIZE + (r->ExpL_Size)*sizeof(long));
3816 assume(r->PolyBin != NULL);
3817
3818 // ----------------------------
3819 // indices and ordsgn vector for comparison
3820 //
3821 // r->pCompHighIndex already set
3822 r->ordsgn=(long *)omAlloc0(r->ExpL_Size*sizeof(long));
3823
3824 for(j=0;j<r->CmpL_Size;j++)
3825 {
3826 r->ordsgn[j] = tmp_ordsgn[j];
3827 }
3828
3829 omFreeSize((ADDRESS)tmp_ordsgn,(3*(n+r->N)*sizeof(long)));
3830
3831 // ----------------------------
3832 // description of orderings for setm:
3833 //
3834 r->OrdSize=typ_i;
3835 if (typ_i==0) r->typ=NULL;
3836 else
3837 {
3838 r->typ=(sro_ord*)omAlloc(typ_i*sizeof(sro_ord));
3839 memcpy(r->typ,tmp_typ,typ_i*sizeof(sro_ord));
3840 }
3841 omFreeSize((ADDRESS)tmp_typ,(3*(n+r->N)*sizeof(sro_ord)));
3842
3843 // ----------------------------
3844 // indices for (first copy of ) variable entries in exp.e vector (VarOffset):
3845 r->VarOffset=v;
3846
3847 // ----------------------------
3848 // other indicies
3849 r->pCompIndex=(r->VarOffset[0] & 0xffff); //r->VarOffset[0];
3850 i=0; // position
3851 j=0; // index in r->typ
3852 if (i==r->pCompIndex) i++; // IS???
3853 while ((j < r->OrdSize)
3854 && ((r->typ[j].ord_typ==ro_syzcomp) ||
3855 (r->typ[j].ord_typ==ro_syz) || (r->typ[j].ord_typ==ro_isTemp) || (r->typ[j].ord_typ==ro_is) ||
3856 (r->order[r->typ[j].order_index] == ringorder_aa)))
3857 {
3858 i++; j++;
3859 }
3860
3861 if (i==r->pCompIndex) i++;
3862 r->pOrdIndex=i;
3863
3864 // ----------------------------
3865 rSetDegStuff(r); // OrdSgn etc already set
3866 rSetOption(r);
3867 // ----------------------------
3868 // r->p_Setm
3869 r->p_Setm = p_GetSetmProc(r);
3870
3871 // ----------------------------
3872 // set VarL_*
3873 rSetVarL(r);
3874
3875 // ----------------------------
3876 // right-adjust VarOffset
3878
3879 // ----------------------------
3880 // set NegWeightL*
3881 rSetNegWeight(r);
3882
3883 // ----------------------------
3884 // p_Procs: call AFTER NegWeightL
3885 r->p_Procs = (p_Procs_s*)omAlloc(sizeof(p_Procs_s));
3886 p_ProcsSet(r, r->p_Procs);
3887
3888 // use totaldegree on crazy oderings:
3889 if ((r->pFDeg==p_WTotaldegree) && rOrd_is_MixedDegree_Ordering(r))
3890 r->pFDeg = p_Totaldegree;
3891 return FALSE;
3892}
3893
3894static void rCheckOrdSgn(ring r,int b/*last block*/)
3895{ // set r->OrdSgn, r->MixedOrder
3896 // for each variable:
3897 int nonpos=0;
3898 int nonneg=0;
3899 for(int i=1;i<=r->N;i++)
3900 {
3901 int found=0;
3902 // for all blocks:
3903 for(int j=0;(j<=b) && (found==0);j++)
3904 {
3905 // search the first block containing var(i)
3906 if ((r->block0[j]<=i)&&(r->block1[j]>=i))
3907 {
3908 // what kind if block is it?
3909 if ((r->order[j]==ringorder_ls)
3910 || (r->order[j]==ringorder_ds)
3911 || (r->order[j]==ringorder_Ds)
3912 || (r->order[j]==ringorder_ws)
3913 || (r->order[j]==ringorder_Ws)
3914 || (r->order[j]==ringorder_rs))
3915 {
3916 r->OrdSgn=-1;
3917 nonpos++;
3918 found=1;
3919 }
3920 else if((r->order[j]==ringorder_a)
3921 ||(r->order[j]==ringorder_aa))
3922 {
3923 // <0: local/mixed ordering
3924 // >0: var(i) is okay, look at other vars
3925 // ==0: look at other blocks for var(i)
3926 if(r->wvhdl[j][i-r->block0[j]]<0)
3927 {
3928 r->OrdSgn=-1;
3929 nonpos++;
3930 found=1;
3931 }
3932 else if(r->wvhdl[j][i-r->block0[j]]>0)
3933 {
3934 nonneg++;
3935 found=1;
3936 }
3937 }
3938 else if(r->order[j]==ringorder_M)
3939 {
3940 // <0: local/mixed ordering
3941 // >0: var(i) is okay, look at other vars
3942 // ==0: look at other blocks for var(i)
3943 if(r->wvhdl[j][i-r->block0[j]]<0)
3944 {
3945 r->OrdSgn=-1;
3946 nonpos++;
3947 found=1;
3948 }
3949 else if(r->wvhdl[j][i-r->block0[j]]>0)
3950 {
3951 nonneg++;
3952 found=1;
3953 }
3954 else
3955 {
3956 // very bad: try next row(s)
3957 int add=r->block1[j]-r->block0[j]+1;
3958 int max_i=r->block0[j]+add*add-add-1;
3959 while(found==0)
3960 {
3961 i+=add;
3962 if (r->wvhdl[j][i-r->block0[j]]<0)
3963 {
3964 r->OrdSgn=-1;
3965 nonpos++;
3966 found=1;
3967 }
3968 else if(r->wvhdl[j][i-r->block0[j]]>0)
3969 {
3970 nonneg++;
3971 found=1;
3972 }
3973 else if(i>max_i)
3974 {
3975 nonpos++;
3976 nonneg++;
3977 found=1;
3978 }
3979 }
3980 }
3981 }
3982 else if ((r->order[j]==ringorder_lp)
3983 || (r->order[j]==ringorder_dp)
3984 || (r->order[j]==ringorder_Dp)
3985 || (r->order[j]==ringorder_wp)
3986 || (r->order[j]==ringorder_Wp)
3987 || (r->order[j]==ringorder_rp))
3988 {
3989 found=1;
3990 nonneg++;
3991 }
3992 }
3993 }
3994 }
3995 if (nonpos>0)
3996 {
3997 r->OrdSgn=-1;
3998 if (nonneg>0) r->MixedOrder=1;
3999 }
4000 else
4001 {
4002 r->OrdSgn=1;
4003 r->MixedOrder=0;
4004 }
4005}
4006
4007void rUnComplete(ring r)
4008{
4009 if (r == NULL) return;
4010 if (r->VarOffset != NULL)
4011 {
4012 if (r->OrdSize!=0 && r->typ != NULL)
4013 {
4014 for(int i = 0; i < r->OrdSize; i++)
4015 if( r->typ[i].ord_typ == ro_is) // Search for suffixes! (prefix have the same VarOffset)
4016 {
4017 id_Delete(&r->typ[i].data.is.F, r);
4018
4019 if( r->typ[i].data.is.pVarOffset != NULL )
4020 {
4021 omFreeSize((ADDRESS)r->typ[i].data.is.pVarOffset, (r->N +1)*sizeof(int));
4022 }
4023 }
4024 else if (r->typ[i].ord_typ == ro_syz)
4025 {
4026 if(r->typ[i].data.syz.limit > 0)
4027 omFreeSize(r->typ[i].data.syz.syz_index, ((r->typ[i].data.syz.limit) +1)*sizeof(int));
4028 }
4029 else if (r->typ[i].ord_typ == ro_syzcomp)
4030 {
4031 assume( r->typ[i].data.syzcomp.ShiftedComponents == NULL );
4032 assume( r->typ[i].data.syzcomp.Components == NULL );
4033// WarnS( "rUnComplete : ord_typ == ro_syzcomp was unhandled!!! Possibly memory leak!!!" );
4034#ifndef SING_NDEBUG
4035// assume(0);
4036#endif
4037 }
4038
4039 omFreeSize((ADDRESS)r->typ,r->OrdSize*sizeof(sro_ord)); r->typ = NULL;
4040 }
4041
4042 if (r->PolyBin != NULL)
4043 omUnGetSpecBin(&(r->PolyBin));
4044
4045 omFreeSize((ADDRESS)r->VarOffset, (r->N +1)*sizeof(int));
4046 r->VarOffset=NULL;
4047
4048 if (r->ordsgn != NULL && r->CmpL_Size != 0)
4049 {
4050 omFreeSize((ADDRESS)r->ordsgn,r->ExpL_Size*sizeof(long));
4051 r->ordsgn=NULL;
4052 }
4053 if (r->p_Procs != NULL)
4054 {
4055 omFreeSize(r->p_Procs, sizeof(p_Procs_s));
4056 r->p_Procs=NULL;
4057 }
4058 omfreeSize(r->VarL_Offset, r->VarL_Size*sizeof(int));
4059 r->VarL_Offset=NULL;
4060 }
4061 if (r->NegWeightL_Offset!=NULL)
4062 {
4063 omFreeSize(r->NegWeightL_Offset, r->NegWeightL_Size*sizeof(int));
4064 r->NegWeightL_Offset=NULL;
4065 }
4066}
4067
4068// set r->VarL_Size, r->VarL_Offset, r->VarL_LowIndex
4069static void rSetVarL(ring r)
4070{
4071 int min = MAX_INT_VAL, min_j = -1;
4072 int* VarL_Number = (int*) omAlloc0(r->ExpL_Size*sizeof(int));
4073
4074 int i,j;
4075
4076 // count how often a var long is occupied by an exponent
4077 for (i=1; i<=r->N; i++)
4078 {
4079 VarL_Number[r->VarOffset[i] & 0xffffff]++;
4080 }
4081
4082 // determine how many and min
4083 for (i=0, j=0; i<r->ExpL_Size; i++)
4084 {
4085 if (VarL_Number[i] != 0)
4086 {
4087 if (min > VarL_Number[i])
4088 {
4089 min = VarL_Number[i];
4090 min_j = j;
4091 }
4092 j++;
4093 }
4094 }
4095
4096 r->VarL_Size = j; // number of long with exp. entries in
4097 // in p->exp
4098 r->VarL_Offset = (int*) omAlloc(r->VarL_Size*sizeof(int));
4099 r->VarL_LowIndex = 0;
4100
4101 // set VarL_Offset
4102 for (i=0, j=0; i<r->ExpL_Size; i++)
4103 {
4104 if (VarL_Number[i] != 0)
4105 {
4106 r->VarL_Offset[j] = i;
4107 if (j > 0 && r->VarL_Offset[j-1] != r->VarL_Offset[j] - 1)
4108 r->VarL_LowIndex = -1;
4109 j++;
4110 }
4111 }
4112 if (r->VarL_LowIndex >= 0)
4113 r->VarL_LowIndex = r->VarL_Offset[0];
4114
4115 if (min_j != 0)
4116 {
4117 j = r->VarL_Offset[min_j];
4118 r->VarL_Offset[min_j] = r->VarL_Offset[0];
4119 r->VarL_Offset[0] = j;
4120 }
4121 omFree(VarL_Number);
4122}
4123
4124static void rRightAdjustVarOffset(ring r)
4125{
4126 int* shifts = (int*) omAlloc(r->ExpL_Size*sizeof(int));
4127 int i;
4128 // initialize shifts
4129 for (i=0;i<r->ExpL_Size;i++)
4130 shifts[i] = BIT_SIZEOF_LONG;
4131
4132 // find minimal bit shift in each long exp entry
4133 for (i=1;i<=r->N;i++)
4134 {
4135 if (shifts[r->VarOffset[i] & 0xffffff] > r->VarOffset[i] >> 24)
4136 shifts[r->VarOffset[i] & 0xffffff] = r->VarOffset[i] >> 24;
4137 }
4138 // reset r->VarOffset: set the minimal shift to 0
4139 for (i=1;i<=r->N;i++)
4140 {
4141 if (shifts[r->VarOffset[i] & 0xffffff] != 0)
4142 r->VarOffset[i]
4143 = (r->VarOffset[i] & 0xffffff) |
4144 (((r->VarOffset[i] >> 24) - shifts[r->VarOffset[i] & 0xffffff]) << 24);
4145 }
4146 omFree(shifts);
4147}
4148
4149// get r->divmask depending on bits per exponent
4150static unsigned long rGetDivMask(int bits)
4151{
4152 unsigned long divmask = 1;
4153 int i = bits;
4154
4155 while (i < BIT_SIZEOF_LONG)
4156 {
4157 divmask |= (((unsigned long) 1) << (unsigned long) i);
4158 i += bits;
4159 }
4160 return divmask;
4161}
4162
4163#ifdef RDEBUG
4164void rDebugPrint(const ring r)
4165{
4166 if (r==NULL)
4167 {
4168 PrintS("NULL ?\n");
4169 return;
4170 }
4171 // corresponds to ro_typ from ring.h:
4172 const char *TYP[]={"ro_dp","ro_wp","ro_am","ro_wp64","ro_wp_neg","ro_cp",
4173 "ro_syzcomp", "ro_syz", "ro_isTemp", "ro_is", "ro_none"};
4174 int i,j;
4175
4176 Print("ExpL_Size:%d ",r->ExpL_Size);
4177 Print("CmpL_Size:%d ",r->CmpL_Size);
4178 Print("VarL_Size:%d\n",r->VarL_Size);
4179 Print("bitmask=0x%lx (expbound=%ld) \n",r->bitmask, r->bitmask);
4180 Print("divmask=%lx\n", r->divmask);
4181 Print("BitsPerExp=%d ExpPerLong=%d at L[%d]\n", r->BitsPerExp, r->ExpPerLong, r->VarL_Offset[0]);
4182
4183 Print("VarL_LowIndex: %d\n", r->VarL_LowIndex);
4184 PrintS("VarL_Offset:\n");
4185 if (r->VarL_Offset==NULL) PrintS(" NULL");
4186 else
4187 for(j = 0; j < r->VarL_Size; j++)
4188 Print(" VarL_Offset[%d]: %d ", j, r->VarL_Offset[j]);
4189 PrintLn();
4190
4191
4192 PrintS("VarOffset:\n");
4193 if (r->VarOffset==NULL) PrintS(" NULL\n");
4194 else
4195 for(j=0;j<=r->N;j++)
4196 Print(" v%d at e-pos %d, bit %d\n",
4197 j,r->VarOffset[j] & 0xffffff, r->VarOffset[j] >>24);
4198 PrintS("ordsgn:\n");
4199 for(j=0;j<r->CmpL_Size;j++)
4200 Print(" ordsgn %ld at pos %d\n",r->ordsgn[j],j);
4201 Print("OrdSgn:%d\n",r->OrdSgn);
4202 PrintS("ordrec:\n");
4203 for(j=0;j<r->OrdSize;j++)
4204 {
4205 Print(" typ %s", TYP[r->typ[j].ord_typ]);
4206 if (r->typ[j].ord_typ==ro_syz)
4207 {
4208 const short place = r->typ[j].data.syz.place;
4209 const int limit = r->typ[j].data.syz.limit;
4210 const int curr_index = r->typ[j].data.syz.curr_index;
4211 const int* syz_index = r->typ[j].data.syz.syz_index;
4212
4213 Print(" limit %d (place: %d, curr_index: %d), syz_index: ", limit, place, curr_index);
4214
4215 if( syz_index == NULL )
4216 PrintS("(NULL)");
4217 else
4218 {
4219 PrintS("{");
4220 for( i=0; i <= limit; i++ )
4221 Print("%d ", syz_index[i]);
4222 PrintS("}");
4223 }
4224
4225 }
4226 else if (r->typ[j].ord_typ==ro_isTemp)
4227 {
4228 Print(" start (level) %d, suffixpos: %d, VO: ",r->typ[j].data.isTemp.start, r->typ[j].data.isTemp.suffixpos);
4229
4230 }
4231 else if (r->typ[j].ord_typ==ro_is)
4232 {
4233 Print(" start %d, end: %d: ",r->typ[j].data.is.start, r->typ[j].data.is.end);
4234
4235// for( int k = 0; k <= r->N; k++) if (r->typ[j].data.is.pVarOffset[k] != -1) Print("[%2d]: %04x; ", k, r->typ[j].data.is.pVarOffset[k]);
4236
4237 Print(" limit %d",r->typ[j].data.is.limit);
4238#ifndef SING_NDEBUG
4239 //PrintS(" F: ");idShow(r->typ[j].data.is.F, r, r, 1);
4240#endif
4241
4242 PrintLn();
4243 }
4244 else if (r->typ[j].ord_typ==ro_am)
4245 {
4246 Print(" place %d",r->typ[j].data.am.place);
4247 Print(" start %d",r->typ[j].data.am.start);
4248 Print(" end %d",r->typ[j].data.am.end);
4249 Print(" len_gen %d",r->typ[j].data.am.len_gen);
4250 PrintS(" w:");
4251 int l=0;
4252 for(l=r->typ[j].data.am.start;l<=r->typ[j].data.am.end;l++)
4253 Print(" %d",r->typ[j].data.am.weights[l-r->typ[j].data.am.start]);
4254 l=r->typ[j].data.am.end+1;
4255 int ll=r->typ[j].data.am.weights[l-r->typ[j].data.am.start];
4256 PrintS(" m:");
4257 for(int lll=l+1;lll<l+ll+1;lll++)
4258 Print(" %d",r->typ[j].data.am.weights[lll-r->typ[j].data.am.start]);
4259 }
4260 else
4261 {
4262 Print(" place %d",r->typ[j].data.dp.place);
4263
4264 if (r->typ[j].ord_typ!=ro_syzcomp && r->typ[j].ord_typ!=ro_syz)
4265 {
4266 Print(" start %d",r->typ[j].data.dp.start);
4267 Print(" end %d",r->typ[j].data.dp.end);
4268 if ((r->typ[j].ord_typ==ro_wp)
4269 || (r->typ[j].ord_typ==ro_wp_neg))
4270 {
4271 PrintS(" w:");
4272 for(int l=r->typ[j].data.wp.start;l<=r->typ[j].data.wp.end;l++)
4273 Print(" %d",r->typ[j].data.wp.weights[l-r->typ[j].data.wp.start]);
4274 }
4275 else if (r->typ[j].ord_typ==ro_wp64)
4276 {
4277 PrintS(" w64:");
4278 int l;
4279 for(l=r->typ[j].data.wp64.start;l<=r->typ[j].data.wp64.end;l++)
4280 Print(" %ld",(long)(r->typ[j].data.wp64.weights64+l-r->typ[j].data.wp64.start));
4281 }
4282 }
4283 }
4284 PrintLn();
4285 }
4286 Print("pOrdIndex:%d pCompIndex:%d\n", r->pOrdIndex, r->pCompIndex);
4287 Print("OrdSize:%d\n",r->OrdSize);
4288 PrintS("--------------------\n");
4289 for(j=0;j<r->ExpL_Size;j++)
4290 {
4291 Print("L[%d]: ",j);
4292 if (j< r->CmpL_Size)
4293 Print("ordsgn %ld ", r->ordsgn[j]);
4294 else
4295 PrintS("no comp ");
4296 i=1;
4297 for(;i<=r->N;i++)
4298 {
4299 if( (r->VarOffset[i] & 0xffffff) == j )
4300 { Print("v%d at e[%d], bit %d; ", i,r->VarOffset[i] & 0xffffff,
4301 r->VarOffset[i] >>24 ); }
4302 }
4303 if( r->pCompIndex==j ) PrintS("v0; ");
4304 for(i=0;i<r->OrdSize;i++)
4305 {
4306 if (r->typ[i].data.dp.place == j)
4307 {
4308 Print("ordrec:%s (start:%d, end:%d) ",TYP[r->typ[i].ord_typ],
4309 r->typ[i].data.dp.start, r->typ[i].data.dp.end);
4310 }
4311 }
4312
4313 if (j==r->pOrdIndex)
4314 PrintS("pOrdIndex\n");
4315 else
4316 PrintLn();
4317 }
4318 Print("LexOrder:%d, MixedOrder:%d\n",r->LexOrder, r->MixedOrder);
4319
4320 Print("NegWeightL_Size: %d, NegWeightL_Offset: ", r->NegWeightL_Size);
4321 if (r->NegWeightL_Offset==NULL) PrintS(" NULL");
4322 else
4323 for(j = 0; j < r->NegWeightL_Size; j++)
4324 Print(" [%d]: %d ", j, r->NegWeightL_Offset[j]);
4325 PrintLn();
4326
4327 // p_Procs stuff
4328 p_Procs_s proc_names;
4329 const char* field;
4330 const char* length;
4331 const char* ord;
4332 p_Debug_GetProcNames(r, &proc_names); // changes p_Procs!!!
4333 p_Debug_GetSpecNames(r, field, length, ord);
4334
4335 Print("p_Spec : %s, %s, %s\n", field, length, ord);
4336 PrintS("p_Procs :\n");
4337 for (i=0; i<(int) (sizeof(p_Procs_s)/sizeof(void*)); i++)
4338 {
4339 Print(" %s,\n", ((char**) &proc_names)[i]);
4340 }
4341
4342 {
4343 PrintLn();
4344 PrintS("pFDeg : ");
4345#define pFDeg_CASE(A) if(r->pFDeg == A) PrintS( "" #A "" )
4349 pFDeg_CASE(p_Deg); else
4350#undef pFDeg_CASE
4351 Print("(%p)", r->pFDeg); // default case
4352
4353 PrintLn();
4354 Print("pLDeg : (%p)", r->pLDeg);
4355 PrintLn();
4356 }
4357 PrintS("pSetm:");
4358 void p_Setm_Dummy(poly p, const ring r);
4359 void p_Setm_TotalDegree(poly p, const ring r);
4360 void p_Setm_WFirstTotalDegree(poly p, const ring r);
4361 void p_Setm_General(poly p, const ring r);
4362 if (r->p_Setm==p_Setm_General) PrintS("p_Setm_General\n");
4363 else if (r->p_Setm==p_Setm_Dummy) PrintS("p_Setm_Dummy\n");
4364 else if (r->p_Setm==p_Setm_TotalDegree) PrintS("p_Setm_Totaldegree\n");
4365 else if (r->p_Setm==p_Setm_WFirstTotalDegree) PrintS("p_Setm_WFirstTotalDegree\n");
4366 else Print("%p\n",r->p_Setm);
4367}
4368
4369void p_DebugPrint(poly p, const ring r)
4370{
4371 int i,j;
4372 p_Write(p,r);
4373 j=2;
4374 while(p!=NULL)
4375 {
4376 Print("\nexp[0..%d]\n",r->ExpL_Size-1);
4377 for(i=0;i<r->ExpL_Size;i++)
4378 Print("%ld ",p->exp[i]);
4379 PrintLn();
4380 Print("v0:%ld ",p_GetComp(p, r));
4381 for(i=1;i<=r->N;i++) Print(" v%d:%ld",i,p_GetExp(p,i, r));
4382 PrintLn();
4383 pIter(p);
4384 j--;
4385 if (j==0) { PrintS("...\n"); break; }
4386 }
4387}
4388
4389#endif // RDEBUG
4390
4391/// debug-print monomial poly/vector p, assuming that it lives in the ring R
4392static inline void m_DebugPrint(const poly p, const ring R)
4393{
4394 Print("\nexp[0..%d]\n", R->ExpL_Size - 1);
4395 for(int i = 0; i < R->ExpL_Size; i++)
4396 Print("%09lx ", p->exp[i]);
4397 PrintLn();
4398 Print("v0:%9ld ", p_GetComp(p, R));
4399 for(int i = 1; i <= R->N; i++) Print(" v%d:%5ld",i, p_GetExp(p, i, R));
4400 PrintLn();
4401}
4402
4403
4404// F = system("ISUpdateComponents", F, V, MIN );
4405// // replace gen(i) -> gen(MIN + V[i-MIN]) for all i > MIN in all terms from F!
4406void pISUpdateComponents(ideal F, const intvec *const V, const int MIN, const ring r )
4407{
4408 assume( V != NULL );
4409 assume( MIN >= 0 );
4410
4411 if( F == NULL )
4412 return;
4413
4414 for( int j = (F->ncols*F->nrows) - 1; j >= 0; j-- )
4415 {
4416#ifdef PDEBUG
4417 Print("F[%d]:", j);
4418 p_wrp(F->m[j], r);
4419#endif
4420
4421 for( poly p = F->m[j]; p != NULL; pIter(p) )
4422 {
4423 int c = p_GetComp(p, r);
4424
4425 if( c > MIN )
4426 {
4427#ifdef PDEBUG
4428 Print("gen[%d] -> gen(%d)\n", c, MIN + (*V)[ c - MIN - 1 ]);
4429#endif
4430
4431 p_SetComp( p, MIN + (*V)[ c - MIN - 1 ], r );
4432 }
4433 }
4434#ifdef PDEBUG
4435 Print("new F[%d]:", j);
4436 p_Test(F->m[j], r);
4437 p_wrp(F->m[j], r);
4438#endif
4439 }
4440}
4441
4442/*2
4443* asssume that rComplete was called with r
4444* assume that the first block ist ringorder_S
4445* change the block to reflect the sequence given by appending v
4446*/
4447static inline void rNChangeSComps(int* currComponents, long* currShiftedComponents, ring r)
4448{
4449 assume(r->typ[1].ord_typ == ro_syzcomp);
4450
4451 r->typ[1].data.syzcomp.ShiftedComponents = currShiftedComponents;
4452 r->typ[1].data.syzcomp.Components = currComponents;
4453}
4454
4455static inline void rNGetSComps(int** currComponents, long** currShiftedComponents, ring r)
4456{
4457 assume(r->typ[1].ord_typ == ro_syzcomp);
4458
4459 *currShiftedComponents = r->typ[1].data.syzcomp.ShiftedComponents;
4460 *currComponents = r->typ[1].data.syzcomp.Components;
4461}
4462#ifdef PDEBUG
4463static inline void rDBChangeSComps(int* currComponents,
4465 int length,
4466 ring r)
4467{
4468 assume(r->typ[1].ord_typ == ro_syzcomp);
4469
4470 r->typ[1].data.syzcomp.length = length;
4471 rNChangeSComps( currComponents, currShiftedComponents, r);
4472}
4473static inline void rDBGetSComps(int** currComponents,
4474 long** currShiftedComponents,
4475 int *length,
4476 ring r)
4477{
4478 assume(r->typ[1].ord_typ == ro_syzcomp);
4479
4480 *length = r->typ[1].data.syzcomp.length;
4481 rNGetSComps( currComponents, currShiftedComponents, r);
4482}
4483#endif
4484
4485void rChangeSComps(int* currComponents, long* currShiftedComponents, int length, ring r)
4486{
4487#ifdef PDEBUG
4488 rDBChangeSComps(currComponents, currShiftedComponents, length, r);
4489#else
4490 rNChangeSComps(currComponents, currShiftedComponents, r);
4491#endif
4492}
4493
4494void rGetSComps(int** currComponents, long** currShiftedComponents, int *length, ring r)
4495{
4496#ifdef PDEBUG
4497 rDBGetSComps(currComponents, currShiftedComponents, length, r);
4498#else
4499 rNGetSComps(currComponents, currShiftedComponents, r);
4500#endif
4501}
4502
4503
4504/////////////////////////////////////////////////////////////////////////////
4505//
4506// The following routines all take as input a ring r, and return R
4507// where R has a certain property. R might be equal r in which case r
4508// had already this property
4509//
4510ring rAssure_SyzOrder(const ring r, BOOLEAN complete)
4511{
4512 if ( r->order[0] == ringorder_c ) return r;
4513 return rAssure_SyzComp(r,complete);
4514}
4515ring rAssure_SyzComp(const ring r, BOOLEAN complete)
4516{
4517 if ( r->order[0] == ringorder_s ) return r;
4518
4519 if ( r->order[0] == ringorder_IS )
4520 {
4521#ifndef SING_NDEBUG
4522 WarnS("rAssure_SyzComp: input ring has an IS-ordering!");
4523#endif
4524// return r;
4525 }
4526 ring res=rCopy0(r, FALSE, FALSE);
4527 int i=rBlocks(r);
4528 int j;
4529
4530 res->order=(rRingOrder_t *)omAlloc((i+1)*sizeof(rRingOrder_t));
4531 res->block0=(int *)omAlloc0((i+1)*sizeof(int));
4532 res->block1=(int *)omAlloc0((i+1)*sizeof(int));
4533 int ** wvhdl =(int **)omAlloc0((i+1)*sizeof(int**));
4534 for(j=i;j>0;j--)
4535 {
4536 res->order[j]=r->order[j-1];
4537 res->block0[j]=r->block0[j-1];
4538 res->block1[j]=r->block1[j-1];
4539 if (r->wvhdl[j-1] != NULL)
4540 {
4541 #ifdef HAVE_OMALLOC
4542 wvhdl[j] = (int*) omMemDup(r->wvhdl[j-1]);
4543 #else
4544 {
4545 int l=r->block1[j-1]-r->block0[j-1]+1;
4546 if (r->order[j-1]==ringorder_a64) l*=2;
4547 else if (r->order[j-1]==ringorder_M) l=l*l;
4548 else if (r->order[j-1]==ringorder_am)
4549 {
4550 l+=r->wvhdl[j-1][r->block1[j-1]-r->block0[j-1]+1]+1;
4551 }
4552 wvhdl[j]=(int*)omalloc(l*sizeof(int));
4553 memcpy(wvhdl[j],r->wvhdl[j-1],l*sizeof(int));
4554 }
4555 #endif
4556 }
4557 }
4558 res->order[0]=ringorder_s;
4559
4560 res->wvhdl = wvhdl;
4561
4562 if (complete)
4563 {
4564 rComplete(res, 1);
4565#ifdef HAVE_PLURAL
4566 if (rIsPluralRing(r))
4567 {
4568 if ( nc_rComplete(r, res, false) ) // no qideal!
4569 {
4570#ifndef SING_NDEBUG
4571 WarnS("error in nc_rComplete"); // cleanup?// rDelete(res);// return r; // just go on..
4572#endif
4573 }
4574 }
4576#endif
4577
4578#ifdef HAVE_PLURAL
4579 ring old_ring = r;
4580#endif
4581 if (r->qideal!=NULL)
4582 {
4583 res->qideal= idrCopyR_NoSort(r->qideal, r, res);
4584 assume(id_RankFreeModule(res->qideal, res) == 0);
4585#ifdef HAVE_PLURAL
4586 if( rIsPluralRing(res) )
4587 {
4588 if( nc_SetupQuotient(res, r, true) )
4589 {
4590// WarnS("error in nc_SetupQuotient"); // cleanup? rDelete(res); return r; // just go on...?
4591 }
4592 assume(id_RankFreeModule(res->qideal, res) == 0);
4593 }
4594#endif
4595 }
4596
4597#ifdef HAVE_PLURAL
4598 assume((res->qideal==NULL) == (old_ring->qideal==NULL));
4599 assume(rIsPluralRing(res) == rIsPluralRing(old_ring));
4600 assume(rIsSCA(res) == rIsSCA(old_ring));
4601 assume(ncRingType(res) == ncRingType(old_ring));
4602#endif
4603 }
4604 return res;
4605}
4606
4607ring rAssure_TDeg(ring r, int &pos)
4608{
4609 if (r->N==1) // special: dp(1)==lp(1)== no entry in typ
4610 {
4611 pos=r->VarL_LowIndex;
4612 return r;
4613 }
4614 if (r->typ!=NULL)
4615 {
4616 for(int i=r->OrdSize-1;i>=0;i--)
4617 {
4618 if ((r->typ[i].ord_typ==ro_dp)
4619 && (r->typ[i].data.dp.start==1)
4620 && (r->typ[i].data.dp.end==r->N))
4621 {
4622 pos=r->typ[i].data.dp.place;
4623 //printf("no change, pos=%d\n",pos);
4624 return r;
4625 }
4626 }
4627 }
4628
4629#ifdef HAVE_PLURAL
4630 nc_struct* save=r->GetNC();
4631 r->GetNC()=NULL;
4632#endif
4633 ring res=rCopy(r);
4634 if (res->qideal!=NULL)
4635 {
4636 id_Delete(&res->qideal,r);
4637 }
4638
4639 int j;
4640
4641 res->ExpL_Size=r->ExpL_Size+1; // one word more in each monom
4642 res->PolyBin=omGetSpecBin(POLYSIZE + (res->ExpL_Size)*sizeof(long));
4643 omFree((ADDRESS)res->ordsgn);
4644 res->ordsgn=(long *)omAlloc0(res->ExpL_Size*sizeof(long));
4645 for(j=0;j<r->CmpL_Size;j++)
4646 {
4647 res->ordsgn[j] = r->ordsgn[j];
4648 }
4649 res->OrdSize=r->OrdSize+1; // one block more for pSetm
4650 if (r->typ!=NULL)
4651 omFree((ADDRESS)res->typ);
4652 res->typ=(sro_ord*)omAlloc0(res->OrdSize*sizeof(sro_ord));
4653 if (r->typ!=NULL)
4654 memcpy(res->typ,r->typ,r->OrdSize*sizeof(sro_ord));
4655 // the additional block for pSetm: total degree at the last word
4656 // but not included in the compare part
4657 res->typ[res->OrdSize-1].ord_typ=ro_dp;
4658 res->typ[res->OrdSize-1].data.dp.start=1;
4659 res->typ[res->OrdSize-1].data.dp.end=res->N;
4660 res->typ[res->OrdSize-1].data.dp.place=res->ExpL_Size-1;
4661 pos=res->ExpL_Size-1;
4662 //res->pOrdIndex=pos; //NO: think of a(1,0),dp !
4663 extern void p_Setm_General(poly p, ring r);
4664 res->p_Setm=p_Setm_General;
4665 // ----------------------------
4666 omFree((ADDRESS)res->p_Procs);
4667 res->p_Procs = (p_Procs_s*)omAlloc(sizeof(p_Procs_s));
4668
4669 p_ProcsSet(res, res->p_Procs);
4670#ifdef HAVE_PLURAL
4671 r->GetNC()=save;
4672 if (rIsPluralRing(r))
4673 {
4674 if ( nc_rComplete(r, res, false) ) // no qideal!
4675 {
4676#ifndef SING_NDEBUG
4677 WarnS("error in nc_rComplete");
4678#endif
4679 // just go on..
4680 }
4681 }
4682#endif
4683 if (r->qideal!=NULL)
4684 {
4685 res->qideal=idrCopyR_NoSort(r->qideal,r, res);
4686#ifdef HAVE_PLURAL
4687 if (rIsPluralRing(res))
4688 {
4689// nc_SetupQuotient(res, currRing);
4690 nc_SetupQuotient(res, r); // ?
4691 }
4692 assume((res->qideal==NULL) == (r->qideal==NULL));
4693#endif
4694 }
4695
4696#ifdef HAVE_PLURAL
4698 assume(rIsSCA(res) == rIsSCA(r));
4700#endif
4701
4702 return res;
4703}
4704
4705ring rAssure_HasComp(const ring r)
4706{
4707 int last_block;
4708 int i=0;
4709 do
4710 {
4711 if (r->order[i] == ringorder_c ||
4712 r->order[i] == ringorder_C) return r;
4713 if (r->order[i] == 0)
4714 break;
4715 i++;
4716 } while (1);
4717 //WarnS("re-creating ring with comps");
4718 last_block=i-1;
4719
4720 ring new_r = rCopy0(r, FALSE, FALSE);
4721 i+=2;
4722 new_r->wvhdl=(int **)omAlloc0(i * sizeof(int *));
4723 new_r->order = (rRingOrder_t *) omAlloc0(i * sizeof(rRingOrder_t));
4724 new_r->block0 = (int *) omAlloc0(i * sizeof(int));
4725 new_r->block1 = (int *) omAlloc0(i * sizeof(int));
4726 memcpy(new_r->order,r->order,(i-1) * sizeof(rRingOrder_t));
4727 memcpy(new_r->block0,r->block0,(i-1) * sizeof(int));
4728 memcpy(new_r->block1,r->block1,(i-1) * sizeof(int));
4729 for (int j=0; j<=last_block; j++)
4730 {
4731 if (r->wvhdl[j]!=NULL)
4732 {
4733 #ifdef HAVE_OMALLOC
4734 new_r->wvhdl[j] = (int*) omMemDup(r->wvhdl[j]);
4735 #else
4736 {
4737 int l=r->block1[j]-r->block0[j]+1;
4738 if (r->order[j]==ringorder_a64) l*=2;
4739 else if (r->order[j]==ringorder_M) l=l*l;
4740 else if (r->order[j]==ringorder_am)
4741 {
4742 l+=r->wvhdl[j][r->block1[j]-r->block0[j]+1]+1;
4743 }
4744 new_r->wvhdl[j]=(int*)omalloc(l*sizeof(int));
4745 memcpy(new_r->wvhdl[j],r->wvhdl[j],l*sizeof(int));
4746 }
4747 #endif
4748 }
4749 }
4750 last_block++;
4751 new_r->order[last_block]=ringorder_C;
4752 //new_r->block0[last_block]=0;
4753 //new_r->block1[last_block]=0;
4754 //new_r->wvhdl[last_block]=NULL;
4755
4756 rComplete(new_r, 1);
4757
4758#ifdef HAVE_PLURAL
4759 if (rIsPluralRing(r))
4760 {
4761 if ( nc_rComplete(r, new_r, false) ) // no qideal!
4762 {
4763#ifndef SING_NDEBUG
4764 WarnS("error in nc_rComplete"); // cleanup?// rDelete(res);// return r; // just go on..
4765#endif
4766 }
4767 }
4768 assume(rIsPluralRing(r) == rIsPluralRing(new_r));
4769#endif
4770
4771 return new_r;
4772}
4773
4774ring rAssure_CompLastBlock(ring r, BOOLEAN complete)
4775{
4776 int last_block = rBlocks(r) - 2;
4777 if (r->order[last_block] != ringorder_c &&
4778 r->order[last_block] != ringorder_C)
4779 {
4780 int c_pos = 0;
4781 int i;
4782
4783 for (i=0; i< last_block; i++)
4784 {
4785 if (r->order[i] == ringorder_c || r->order[i] == ringorder_C)
4786 {
4787 c_pos = i;
4788 break;
4789 }
4790 }
4791 if (c_pos != -1)
4792 {
4793 ring new_r = rCopy0(r, FALSE, TRUE);
4794 for (i=c_pos+1; i<=last_block; i++)
4795 {
4796 new_r->order[i-1] = new_r->order[i];
4797 new_r->block0[i-1] = new_r->block0[i];
4798 new_r->block1[i-1] = new_r->block1[i];
4799 new_r->wvhdl[i-1] = new_r->wvhdl[i];
4800 }
4801 new_r->order[last_block] = r->order[c_pos];
4802 new_r->block0[last_block] = r->block0[c_pos];
4803 new_r->block1[last_block] = r->block1[c_pos];
4804 new_r->wvhdl[last_block] = r->wvhdl[c_pos];
4805 if (complete)
4806 {
4807 rComplete(new_r, 1);
4808
4809#ifdef HAVE_PLURAL
4810 if (rIsPluralRing(r))
4811 {
4812 if ( nc_rComplete(r, new_r, false) ) // no qideal!
4813 {
4814#ifndef SING_NDEBUG
4815 WarnS("error in nc_rComplete"); // cleanup?// rDelete(res);// return r; // just go on..
4816#endif
4817 }
4818 }
4819 assume(rIsPluralRing(r) == rIsPluralRing(new_r));
4820#endif
4821 }
4822 return new_r;
4823 }
4824 }
4825 return r;
4826}
4827
4828// Moves _c or _C ordering to the last place AND adds _s on the 1st place
4830{
4831 rTest(r);
4832
4833 ring new_r_1 = rAssure_CompLastBlock(r, FALSE); // due to this FALSE - no completion!
4834 ring new_r = rAssure_SyzComp(new_r_1, FALSE); // new_r_1 is used only here!!!
4835
4836 if (new_r == r)
4837 return r;
4838
4839 ring old_r = r;
4840 if (new_r_1 != new_r && new_r_1 != old_r) rDelete(new_r_1);
4841
4842 rComplete(new_r, TRUE);
4843#ifdef HAVE_PLURAL
4844 if (rIsPluralRing(old_r))
4845 {
4846 if ( nc_rComplete(old_r, new_r, false) ) // no qideal!
4847 {
4848# ifndef SING_NDEBUG
4849 WarnS("error in nc_rComplete"); // cleanup? rDelete(res); return r; // just go on...?
4850# endif
4851 }
4852 }
4853#endif
4854
4855///? rChangeCurrRing(new_r);
4856 if (old_r->qideal != NULL)
4857 {
4858 new_r->qideal = idrCopyR(old_r->qideal, old_r, new_r);
4859 }
4860
4861#ifdef HAVE_PLURAL
4862 if( rIsPluralRing(old_r) )
4863 if( nc_SetupQuotient(new_r, old_r, true) )
4864 {
4865#ifndef SING_NDEBUG
4866 WarnS("error in nc_SetupQuotient"); // cleanup? rDelete(res); return r; // just go on...?
4867#endif
4868 }
4869#endif
4870
4871#ifdef HAVE_PLURAL
4872 assume((new_r->qideal==NULL) == (old_r->qideal==NULL));
4873 assume(rIsPluralRing(new_r) == rIsPluralRing(old_r));
4874 assume(rIsSCA(new_r) == rIsSCA(old_r));
4875 assume(ncRingType(new_r) == ncRingType(old_r));
4876#endif
4877
4878 rTest(new_r);
4879 rTest(old_r);
4880 return new_r;
4881}
4882
4883// use this for global orderings consisting of two blocks
4884static ring rAssure_Global(rRingOrder_t b1, rRingOrder_t b2, const ring r)
4885{
4886 int r_blocks = rBlocks(r);
4887
4888 assume(b1 == ringorder_c || b1 == ringorder_C ||
4889 b2 == ringorder_c || b2 == ringorder_C ||
4890 b2 == ringorder_S);
4891 if ((r_blocks == 3) &&
4892 (r->order[0] == b1) &&
4893 (r->order[1] == b2) &&
4894 (r->order[2] == 0))
4895 return r;
4896 ring res = rCopy0(r, FALSE, FALSE);
4897 res->order = (rRingOrder_t*)omAlloc0(3*sizeof(rRingOrder_t));
4898 res->block0 = (int*)omAlloc0(3*sizeof(int));
4899 res->block1 = (int*)omAlloc0(3*sizeof(int));
4900 res->wvhdl = (int**)omAlloc0(3*sizeof(int*));
4901 res->order[0] = b1;
4902 res->order[1] = b2;
4903 if (b1 == ringorder_c || b1 == ringorder_C)
4904 {
4905 res->block0[1] = 1;
4906 res->block1[1] = r->N;
4907 }
4908 else
4909 {
4910 res->block0[0] = 1;
4911 res->block1[0] = r->N;
4912 }
4913 rComplete(res, 1);
4914 if (r->qideal!=NULL) res->qideal= idrCopyR_NoSort(r->qideal, r, res);
4915#ifdef HAVE_PLURAL
4916 if (rIsPluralRing(r))
4917 {
4918 if ( nc_rComplete(r, res, false) ) // no qideal!
4919 {
4920#ifndef SING_NDEBUG
4921 WarnS("error in nc_rComplete");
4922#endif
4923 }
4924 }
4925#endif
4926// rChangeCurrRing(res);
4927 return res;
4928}
4929
4930ring rAssure_InducedSchreyerOrdering(const ring r, BOOLEAN complete/* = TRUE*/, int sgn/* = 1*/)
4931{ // TODO: ???? Add leading Syz-comp ordering here...????
4932
4933#if MYTEST
4934 Print("rAssure_InducedSchreyerOrdering(r, complete = %d, sgn = %d): r: \n", complete, sgn);
4935 rWrite(r);
4936#ifdef RDEBUG
4937 rDebugPrint(r);
4938#endif
4939 PrintLn();
4940#endif
4941 assume((sgn == 1) || (sgn == -1));
4942
4943 ring res=rCopy0(r, FALSE, FALSE); // No qideal & ordering copy.
4944
4945 int n = rBlocks(r); // Including trailing zero!
4946
4947 // Create 2 more blocks for prefix/suffix:
4948 res->order=(rRingOrder_t *)omAlloc0((n+2)*sizeof(rRingOrder_t)); // 0 .. n+1
4949 res->block0=(int *)omAlloc0((n+2)*sizeof(int));
4950 res->block1=(int *)omAlloc0((n+2)*sizeof(int));
4951 int ** wvhdl =(int **)omAlloc0((n+2)*sizeof(int**));
4952
4953 // Encapsulate all existing blocks between induced Schreyer ordering markers: prefix and suffix!
4954 // Note that prefix and suffix have the same ringorder marker and only differ in block[] parameters!
4955
4956 // new 1st block
4957 int j = 0;
4958 res->order[j] = ringorder_IS; // Prefix
4959 res->block0[j] = res->block1[j] = 0;
4960 // wvhdl[j] = NULL;
4961 j++;
4962
4963 for(int i = 0; (i <= n) && (r->order[i] != 0); i++, j++) // i = [0 .. n-1] <- non-zero old blocks
4964 {
4965 res->order [j] = r->order [i];
4966 res->block0[j] = r->block0[i];
4967 res->block1[j] = r->block1[i];
4968
4969 if (r->wvhdl[i] != NULL)
4970 {
4971 #ifdef HAVE_OMALLOC
4972 wvhdl[j] = (int*) omMemDup(r->wvhdl[i]);
4973 #else
4974 {
4975 int l=(r->block1[i]-r->block0[i]+1);
4976 if (r->order[i]==ringorder_a64) l*=2;
4977 else if (r->order[i]==ringorder_M) l=l*l;
4978 else if (r->order[i]==ringorder_am)
4979 {
4980 l+=r->wvhdl[i][r->block1[i]-r->block0[i]+1]+1;
4981 }
4982 wvhdl[j]=(int*)omalloc(l*sizeof(int));
4983 memcpy(wvhdl[j],r->wvhdl[i],l*sizeof(int));
4984 }
4985 #endif
4986 } // else wvhdl[j] = NULL;
4987 }
4988
4989 // new last block
4990 res->order [j] = ringorder_IS; // Suffix
4991 res->block0[j] = res->block1[j] = sgn; // Sign of v[o]: 1 for C, -1 for c
4992 // wvhdl[j] = NULL;
4993 j++;
4994
4995 // res->order [j] = 0; // The End!
4996 res->wvhdl = wvhdl;
4997
4998 // j == the last zero block now!
4999 assume(j == (n+1));
5000 assume(res->order[0]==ringorder_IS);
5001 assume(res->order[j-1]==ringorder_IS);
5002 assume(res->order[j]==0);
5003
5004
5005 if (complete)
5006 {
5007 rComplete(res, 1);
5008
5009#ifdef HAVE_PLURAL
5010 if (rIsPluralRing(r))
5011 {
5012 if ( nc_rComplete(r, res, false) ) // no qideal!
5013 {
5014#ifndef SING_NDEBUG
5015 WarnS("error in nc_rComplete"); // cleanup?// rDelete(res);// return r; // just go on..
5016#endif
5017 }
5018 }
5020#endif
5021
5022
5023#ifdef HAVE_PLURAL
5024 ring old_ring = r;
5025#endif
5026
5027 if (r->qideal!=NULL)
5028 {
5029 res->qideal= idrCopyR_NoSort(r->qideal, r, res);
5030
5031 assume(id_RankFreeModule(res->qideal, res) == 0);
5032
5033#ifdef HAVE_PLURAL
5034 if( rIsPluralRing(res) )
5035 if( nc_SetupQuotient(res, r, true) )
5036 {
5037// WarnS("error in nc_SetupQuotient"); // cleanup? rDelete(res); return r; // just go on...?
5038 }
5039
5040#endif
5041 assume(id_RankFreeModule(res->qideal, res) == 0);
5042 }
5043
5044#ifdef HAVE_PLURAL
5045 assume((res->qideal==NULL) == (old_ring->qideal==NULL));
5046 assume(rIsPluralRing(res) == rIsPluralRing(old_ring));
5047 assume(rIsSCA(res) == rIsSCA(old_ring));
5048 assume(ncRingType(res) == ncRingType(old_ring));
5049#endif
5050 }
5051
5052 return res;
5053}
5054
5055ring rAssure_dp_S(const ring r)
5056{
5058}
5059
5060ring rAssure_dp_C(const ring r)
5061{
5063}
5064
5065ring rAssure_C_dp(const ring r)
5066{
5068}
5069
5070ring rAssure_c_dp(const ring r)
5071{
5073}
5074
5075
5076
5077/// Finds p^th IS ordering, and returns its position in r->typ[]
5078/// returns -1 if something went wrong!
5079/// p - starts with 0!
5080int rGetISPos(const int p, const ring r)
5081{
5082 // Put the reference set F into the ring -ordering -recor
5083#if MYTEST
5084 Print("rIsIS(p: %d)\nF:", p);
5085 PrintLn();
5086#endif
5087
5088 if (r->typ==NULL)
5089 {
5090// dReportError("'rIsIS:' Error: wrong ring! (typ == NULL)");
5091 return -1;
5092 }
5093
5094 int j = p; // Which IS record to use...
5095 for( int pos = 0; pos < r->OrdSize; pos++ )
5096 if( r->typ[pos].ord_typ == ro_is)
5097 if( j-- == 0 )
5098 return pos;
5099
5100 return -1;
5101}
5102
5103
5104
5105
5106
5107
5108/// Changes r by setting induced ordering parameters: limit and reference leading terms
5109/// F belong to r, we will DO a copy!
5110/// We will use it AS IS!
5111/// returns true is everything was allright!
5112BOOLEAN rSetISReference(const ring r, const ideal F, const int i, const int p)
5113{
5114 // Put the reference set F into the ring -ordering -recor
5115
5116 if (r->typ==NULL)
5117 {
5118 dReportError("Error: WRONG USE of rSetISReference: wrong ring! (typ == NULL)");
5119 return FALSE;
5120 }
5121
5122
5123 int pos = rGetISPos(p, r);
5124
5125 if( pos == -1 )
5126 {
5127 dReportError("Error: WRONG USE of rSetISReference: specified ordering block was not found!!!" );
5128 return FALSE;
5129 }
5130
5131#if MYTEST
5132 if( i != r->typ[pos].data.is.limit )
5133 Print("Changing record on pos: %d\nOld limit: %d --->> New Limit: %d\n", pos, r->typ[pos].data.is.limit, i);
5134#endif
5135
5136 const ideal FF = idrHeadR(F, r, r); // id_Copy(F, r); // ???
5137
5138
5139 if( r->typ[pos].data.is.F != NULL)
5140 {
5141#if MYTEST
5142 PrintS("Deleting old reference set F... \n"); // idShow(r->typ[pos].data.is.F, r); PrintLn();
5143#endif
5144 id_Delete(&r->typ[pos].data.is.F, r);
5145 r->typ[pos].data.is.F = NULL;
5146 }
5147
5148 assume(r->typ[pos].data.is.F == NULL);
5149
5150 r->typ[pos].data.is.F = FF; // F is owened by ring now! TODO: delete at the end!
5151
5152 r->typ[pos].data.is.limit = i; // First induced component
5153
5154#if MYTEST
5155 PrintS("New reference set FF : \n"); idShow(FF, r, r, 1); PrintLn();
5156#endif
5157
5158 return TRUE;
5159}
5160
5161#ifdef PDEBUG
5163#endif
5164
5165
5166void rSetSyzComp(int k, const ring r)
5167{
5168 if(k < 0)
5169 {
5170 dReportError("rSetSyzComp with negative limit!");
5171 return;
5172 }
5173
5174 assume( k >= 0 );
5175 if (TEST_OPT_PROT) Print("{%d}", k);
5176 if ((r->typ!=NULL) && (r->typ[0].ord_typ==ro_syz))
5177 {
5178 r->block0[0]=r->block1[0] = k;
5179 if( k == r->typ[0].data.syz.limit )
5180 return; // nothing to do
5181
5182 int i;
5183 if (r->typ[0].data.syz.limit == 0)
5184 {
5185 r->typ[0].data.syz.syz_index = (int*) omAlloc0((k+1)*sizeof(int));
5186 r->typ[0].data.syz.syz_index[0] = 0;
5187 r->typ[0].data.syz.curr_index = 1;
5188 }
5189 else
5190 {
5191 r->typ[0].data.syz.syz_index = (int*)
5192 omReallocSize(r->typ[0].data.syz.syz_index,
5193 (r->typ[0].data.syz.limit+1)*sizeof(int),
5194 (k+1)*sizeof(int));
5195 }
5196 for (i=r->typ[0].data.syz.limit + 1; i<= k; i++)
5197 {
5198 r->typ[0].data.syz.syz_index[i] =
5199 r->typ[0].data.syz.curr_index;
5200 }
5201 if(k < r->typ[0].data.syz.limit) // ?
5202 {
5203#ifndef SING_NDEBUG
5204 Warn("rSetSyzComp called with smaller limit (%d) as before (%d)", k, r->typ[0].data.syz.limit);
5205#endif
5206 r->typ[0].data.syz.curr_index = 1 + r->typ[0].data.syz.syz_index[k];
5207 }
5208
5209
5210 r->typ[0].data.syz.limit = k;
5211 r->typ[0].data.syz.curr_index++;
5212 }
5213 else if(
5214 (r->typ!=NULL) &&
5215 (r->typ[0].ord_typ==ro_isTemp)
5216 )
5217 {
5218// (r->typ[currRing->typ[0].data.isTemp.suffixpos].data.is.limit == k)
5219#ifndef SING_NDEBUG
5220 Warn("rSetSyzComp(%d) in an IS ring! Be careful!", k);
5221#endif
5222 }
5223 else if (r->order[0]==ringorder_s)
5224 {
5225 r->block0[0] = r->block1[0] = k;
5226 }
5227 else if (r->order[0]!=ringorder_c)
5228 {
5229 dReportError("syzcomp in incompatible ring");
5230 }
5231#ifdef PDEBUG
5233 pDBsyzComp=k;
5234#endif
5235}
5236
5237// return the max-comonent wchich has syzIndex i
5238int rGetMaxSyzComp(int i, const ring r)
5239{
5240 if ((r->typ!=NULL) && (r->typ[0].ord_typ==ro_syz) &&
5241 r->typ[0].data.syz.limit > 0 && i > 0)
5242 {
5243 assume(i <= r->typ[0].data.syz.limit);
5244 int j;
5245 for (j=0; j<r->typ[0].data.syz.limit; j++)
5246 {
5247 if (r->typ[0].data.syz.syz_index[j] == i &&
5248 r->typ[0].data.syz.syz_index[j+1] != i)
5249 {
5250 assume(r->typ[0].data.syz.syz_index[j+1] == i+1);
5251 return j;
5252 }
5253 }
5254 return r->typ[0].data.syz.limit;
5255 }
5256 else
5257 {
5258 #ifndef SING_NDEBUG
5259 WarnS("rGetMaxSyzComp: order c");
5260 #endif
5261 return 0;
5262 }
5263}
5264
5266{
5267 if (r == NULL) return FALSE;
5268 int i, j, nb = rBlocks(r);
5269 for (i=0; i<nb; i++)
5270 {
5271 if (r->wvhdl[i] != NULL)
5272 {
5273 int length = r->block1[i] - r->block0[i]+1;
5274 int* wvhdl = r->wvhdl[i];
5275 if (r->order[i] == ringorder_M) length *= length;
5276
5277 for (j=0; j< length; j++)
5278 {
5279 if (wvhdl[j] != 0 && wvhdl[j] != 1) return FALSE;
5280 }
5281 }
5282 }
5283 return TRUE;
5284}
5285
5287{
5288 assume(r != NULL);
5289 int lb = rBlocks(r) - 2;
5290 return (r->order[lb] == ringorder_c || r->order[lb] == ringorder_C);
5291}
5292
5294{
5295 if ((r->order[0]==ringorder_dp) &&(r->block0[0]==1) &&(r->block1[0]==r->N))
5296 return TRUE;
5297 if (((r->order[0]==ringorder_c)||(r->order[0]==ringorder_C))
5298 && ((r->order[1]==ringorder_dp) &&(r->block0[1]==1) &&(r->block1[1]==r->N)))
5299 return TRUE;
5300 return FALSE;
5301}
5302
5304{
5305 if ((r->order[0]==ringorder_Dp) &&(r->block0[0]==1) &&(r->block1[0]==r->N))
5306 return TRUE;
5307 if (((r->order[0]==ringorder_c)||(r->order[0]==ringorder_C))
5308 && ((r->order[1]==ringorder_Dp) &&(r->block0[1]==1) &&(r->block1[1]==r->N)))
5309 return TRUE;
5310 return FALSE;
5311}
5312
5314{
5315 if ((r->order[0]==ringorder_lp) &&(r->block0[0]==1) &&(r->block1[0]==r->N))
5316 return TRUE;
5317 if (((r->order[0]==ringorder_c)||(r->order[0]==ringorder_C))
5318 && ((r->order[1]==ringorder_lp) &&(r->block0[1]==1) &&(r->block1[1]==r->N)))
5319 return TRUE;
5320 return FALSE;
5321}
5322
5323int64 * rGetWeightVec(const ring r)
5324{
5325 assume(r!=NULL);
5326 assume(r->OrdSize>0);
5327 int i=0;
5328 while((r->typ[i].ord_typ!=ro_wp64) && (r->typ[i].ord_typ>0)) i++;
5329 if (r->typ[i].ord_typ!=ro_wp64) return NULL; /* should not happen*/
5330 return r->typ[i].data.wp64.weights64;
5331}
5332
5333void rSetWeightVec(ring r, int64 *wv)
5334{
5335 assume(r!=NULL);
5336 assume(r->OrdSize>0);
5337 assume(r->typ[0].ord_typ==ro_wp64);
5338 memcpy(r->typ[0].data.wp64.weights64,wv,r->N*sizeof(int64));
5339}
5340
5341#include <ctype.h>
5342
5343static int rRealloc1(ring r, int size, int pos)
5344{
5345 r->order=(rRingOrder_t*)omReallocSize(r->order, size*sizeof(rRingOrder_t), (size+1)*sizeof(rRingOrder_t));
5346 r->block0=(int*)omReallocSize(r->block0, size*sizeof(int), (size+1)*sizeof(int));
5347 r->block1=(int*)omReallocSize(r->block1, size*sizeof(int), (size+1)*sizeof(int));
5348 r->wvhdl=(int **)omReallocSize(r->wvhdl,size*sizeof(int *), (size+1)*sizeof(int *));
5349 for(int k=size; k>pos; k--) r->wvhdl[k]=r->wvhdl[k-1];
5350 r->order[size]=(rRingOrder_t)0;
5351 size++;
5352 return size;
5353}
5354#if 0 // currently unused
5355static int rReallocM1(ring r, int size, int pos)
5356{
5357 r->order=(int*)omReallocSize(r->order, size*sizeof(int), (size-1)*sizeof(int));
5358 r->block0=(int*)omReallocSize(r->block0, size*sizeof(int), (size-1)*sizeof(int));
5359 r->block1=(int*)omReallocSize(r->block1, size*sizeof(int), (size-1)*sizeof(int));
5360 r->wvhdl=(int **)omReallocSize(r->wvhdl,size*sizeof(int *), (size-1)*sizeof(int *));
5361 for(int k=pos+1; k<size; k++) r->wvhdl[k]=r->wvhdl[k+1];
5362 size--;
5363 return size;
5364}
5365#endif
5366static void rOppWeight(int *w, int l)
5367{
5368 /* works for commutative/Plural; need to be changed for Letterplace */
5369 /* Letterpace: each block of vars needs to be reverted on it own */
5370 int i2=(l+1)/2;
5371 for(int j=0; j<=i2; j++)
5372 {
5373 int t=w[j];
5374 w[j]=w[l-j];
5375 w[l-j]=t;
5376 }
5377}
5378
5379#define rOppVar(R,I) (rVar(R)+1-I)
5380/* nice for Plural, need to be changed for Letterplace: requires also the length of a monomial */
5381
5382ring rOpposite(ring src)
5383 /* creates an opposite algebra of R */
5384 /* that is R^opp, where f (*^opp) g = g*f */
5385 /* treats the case of qring */
5386{
5387 if (src == NULL) return(NULL);
5388
5389 //rChangeCurrRing(src);
5390#ifdef RDEBUG
5391 rTest(src);
5392// rWrite(src);
5393// rDebugPrint(src);
5394#endif
5395
5396 ring r = rCopy0(src,FALSE);
5397 if (src->qideal != NULL)
5398 {
5399 id_Delete(&(r->qideal), src);
5400 }
5401
5402 // change vars v1..vN -> vN..v1
5403 int i;
5404 int i2 = (rVar(r)-1)/2;
5405 for(i=i2; i>=0; i--)
5406 {
5407 // index: 0..N-1
5408 //Print("ex var names: %d <-> %d\n",i,rOppVar(r,i));
5409 // exchange names
5410 char *p;
5411 p = r->names[rVar(r)-1-i];
5412 r->names[rVar(r)-1-i] = r->names[i];
5413 r->names[i] = p;
5414 }
5415// i2=(rVar(r)+1)/2;
5416// for(int i=i2; i>0; i--)
5417// {
5418// // index: 1..N
5419// //Print("ex var places: %d <-> %d\n",i,rVar(r)+1-i);
5420// // exchange VarOffset
5421// int t;
5422// t=r->VarOffset[i];
5423// r->VarOffset[i]=r->VarOffset[rOppVar(r,i)];
5424// r->VarOffset[rOppVar(r,i)]=t;
5425// }
5426 // change names:
5427 // TODO: does this work the same way for Letterplace?
5428 for (i=rVar(r)-1; i>=0; i--)
5429 {
5430 char *p=r->names[i];
5431 if(isupper(*p)) *p = tolower(*p);
5432 else *p = toupper(*p);
5433 }
5434 // change ordering: listing
5435 // change ordering: compare
5436// for(i=0; i<r->OrdSize; i++)
5437// {
5438// int t,tt;
5439// switch(r->typ[i].ord_typ)
5440// {
5441// case ro_dp:
5442// //
5443// t=r->typ[i].data.dp.start;
5444// r->typ[i].data.dp.start=rOppVar(r,r->typ[i].data.dp.end);
5445// r->typ[i].data.dp.end=rOppVar(r,t);
5446// break;
5447// case ro_wp:
5448// case ro_wp_neg:
5449// {
5450// t=r->typ[i].data.wp.start;
5451// r->typ[i].data.wp.start=rOppVar(r,r->typ[i].data.wp.end);
5452// r->typ[i].data.wp.end=rOppVar(r,t);
5453// // invert r->typ[i].data.wp.weights
5454// rOppWeight(r->typ[i].data.wp.weights,
5455// r->typ[i].data.wp.end-r->typ[i].data.wp.start);
5456// break;
5457// }
5458// //case ro_wp64:
5459// case ro_syzcomp:
5460// case ro_syz:
5461// WerrorS("not implemented in rOpposite");
5462// // should not happen
5463// break;
5464//
5465// case ro_cp:
5466// t=r->typ[i].data.cp.start;
5467// r->typ[i].data.cp.start=rOppVar(r,r->typ[i].data.cp.end);
5468// r->typ[i].data.cp.end=rOppVar(r,t);
5469// break;
5470// case ro_none:
5471// default:
5472// Werror("unknown type in rOpposite(%d)",r->typ[i].ord_typ);
5473// break;
5474// }
5475// }
5476 // Change order/block structures (needed for rPrint, rAdd etc.)
5477
5478 int j=0;
5479 int l=rBlocks(src);
5480 if ( ! rIsLPRing(src) )
5481 {
5482 // ie Plural or commutative
5483 for(i=0; src->order[i]!=0; i++)
5484 {
5485 switch (src->order[i])
5486 {
5487 case ringorder_c: /* c-> c */
5488 case ringorder_C: /* C-> C */
5489 case ringorder_no /*=0*/: /* end-of-block */
5490 r->order[j]=src->order[i];
5491 j++; break;
5492 case ringorder_lp: /* lp -> rp */
5493 r->order[j]=ringorder_rp;
5494 r->block0[j]=rOppVar(r, src->block1[i]);
5495 r->block1[j]=rOppVar(r, src->block0[i]);
5496 j++;break;
5497 case ringorder_rp: /* rp -> lp */
5498 r->order[j]=ringorder_lp;
5499 r->block0[j]=rOppVar(r, src->block1[i]);
5500 r->block1[j]=rOppVar(r, src->block0[i]);
5501 j++;break;
5502 case ringorder_dp: /* dp -> a(1..1),ls */
5503 {
5504 l=rRealloc1(r,l,j);
5505 r->order[j]=ringorder_a;
5506 r->block0[j]=rOppVar(r, src->block1[i]);
5507 r->block1[j]=rOppVar(r, src->block0[i]);
5508 r->wvhdl[j]=(int*)omAlloc((r->block1[j]-r->block0[j]+1)*sizeof(int));
5509 for(int k=r->block0[j]; k<=r->block1[j]; k++)
5510 r->wvhdl[j][k-r->block0[j]]=1;
5511 j++;
5512 r->order[j]=ringorder_ls;
5513 r->block0[j]=rOppVar(r, src->block1[i]);
5514 r->block1[j]=rOppVar(r, src->block0[i]);
5515 j++;
5516 break;
5517 }
5518 case ringorder_Dp: /* Dp -> a(1..1),rp */
5519 {
5520 l=rRealloc1(r,l,j);
5521 r->order[j]=ringorder_a;
5522 r->block0[j]=rOppVar(r, src->block1[i]);
5523 r->block1[j]=rOppVar(r, src->block0[i]);
5524 r->wvhdl[j]=(int*)omAlloc((r->block1[j]-r->block0[j]+1)*sizeof(int));
5525 for(int k=r->block0[j]; k<=r->block1[j]; k++)
5526 r->wvhdl[j][k-r->block0[j]]=1;
5527 j++;
5528 r->order[j]=ringorder_rp;
5529 r->block0[j]=rOppVar(r, src->block1[i]);
5530 r->block1[j]=rOppVar(r, src->block0[i]);
5531 j++;
5532 break;
5533 }
5534 case ringorder_wp: /* wp -> a(...),ls */
5535 {
5536 l=rRealloc1(r,l,j);
5537 r->order[j]=ringorder_a;
5538 r->block0[j]=rOppVar(r, src->block1[i]);
5539 r->block1[j]=rOppVar(r, src->block0[i]);
5540 r->wvhdl[j]=r->wvhdl[j+1]; r->wvhdl[j+1]=NULL;
5541 rOppWeight(r->wvhdl[j], r->block1[j]-r->block0[j]);
5542 j++;
5543 r->order[j]=ringorder_ls;
5544 r->block0[j]=rOppVar(r, src->block1[i]);
5545 r->block1[j]=rOppVar(r, src->block0[i]);
5546 j++;
5547 break;
5548 }
5549 case ringorder_Wp: /* Wp -> a(...),rp */
5550 {
5551 l=rRealloc1(r,l,j);
5552 r->order[j]=ringorder_a;
5553 r->block0[j]=rOppVar(r, src->block1[i]);
5554 r->block1[j]=rOppVar(r, src->block0[i]);
5555 r->wvhdl[j]=r->wvhdl[j+1]; r->wvhdl[j+1]=NULL;
5556 rOppWeight(r->wvhdl[j], r->block1[j]-r->block0[j]);
5557 j++;
5558 r->order[j]=ringorder_rp;
5559 r->block0[j]=rOppVar(r, src->block1[i]);
5560 r->block1[j]=rOppVar(r, src->block0[i]);
5561 j++;
5562 break;
5563 }
5564 case ringorder_M: /* M -> M */
5565 {
5566 r->order[j]=ringorder_M;
5567 r->block0[j]=rOppVar(r, src->block1[i]);
5568 r->block1[j]=rOppVar(r, src->block0[i]);
5569 int n=r->block1[j]-r->block0[j];
5570 /* M is a (n+1)x(n+1) matrix */
5571 for (int nn=0; nn<=n; nn++)
5572 {
5573 rOppWeight(&(r->wvhdl[j][nn*(n+1)]), n /*r->block1[j]-r->block0[j]*/);
5574 }
5575 j++;
5576 break;
5577 }
5578 case ringorder_a: /* a(...),ls -> wp/dp */
5579 {
5580 r->block0[j]=rOppVar(r, src->block1[i]);
5581 r->block1[j]=rOppVar(r, src->block0[i]);
5582 rOppWeight(r->wvhdl[j], r->block1[j]-r->block0[j]);
5583 if (src->order[i+1]==ringorder_ls)
5584 {
5585 r->order[j]=ringorder_wp;
5586 i++;
5587 //l=rReallocM1(r,l,j);
5588 }
5589 else
5590 {
5591 r->order[j]=ringorder_a;
5592 }
5593 j++;
5594 break;
5595 }
5596 // not yet done:
5597 case ringorder_ls:
5598 case ringorder_rs:
5599 case ringorder_ds:
5600 case ringorder_Ds:
5601 case ringorder_ws:
5602 case ringorder_Ws:
5603 case ringorder_am:
5604 case ringorder_a64:
5605 // should not occur:
5606 case ringorder_S:
5607 case ringorder_IS:
5608 case ringorder_s:
5609 case ringorder_aa:
5610 case ringorder_L:
5611 case ringorder_unspec:
5612 Werror("order %s not (yet) supported", rSimpleOrdStr(src->order[i]));
5613 break;
5614 }
5615 }
5616 } /* end if (!rIsLPRing(src)) */
5617 if (rIsLPRing(src))
5618 {
5619 // applies to Letterplace only
5620 // Letterplace conventions: dp<->Dp, lp<->rp
5621 // Wp(v) cannot be converted since wp(v) does not encode a monomial ordering
5622 // (a(w),<) is troublesome and thus postponed
5623 for(i=0; src->order[i]!=0; i++)
5624 {
5625 switch (src->order[i])
5626 {
5627 case ringorder_c: /* c-> c */
5628 case ringorder_C: /* C-> C */
5629 case ringorder_no /*=0*/: /* end-of-block */
5630 r->order[j]=src->order[i];
5631 j++; break;
5632 case ringorder_lp: /* lp -> rp */
5633 r->order[j]=ringorder_rp;
5634 r->block0[j]=rOppVar(r, src->block1[i]);
5635 r->block1[j]=rOppVar(r, src->block0[i]);
5636 j++;break;
5637 case ringorder_rp: /* rp -> lp */
5638 r->order[j]=ringorder_lp;
5639 r->block0[j]=rOppVar(r, src->block1[i]);
5640 r->block1[j]=rOppVar(r, src->block0[i]);
5641 j++;break;
5642 case ringorder_dp: /* dp -> Dp */
5643 {
5644 r->order[j]=ringorder_Dp;
5645 r->block0[j]=rOppVar(r, src->block1[i]);
5646 r->block1[j]=rOppVar(r, src->block0[i]);
5647 j++;break;
5648 }
5649 case ringorder_Dp: /* Dp -> dp*/
5650 {
5651 r->order[j]=ringorder_dp;
5652 r->block0[j]=rOppVar(r, src->block1[i]);
5653 r->block1[j]=rOppVar(r, src->block0[i]);
5654 j++;break;
5655 }
5656 // not clear how to do:
5657 case ringorder_wp:
5658 case ringorder_Wp:
5659 case ringorder_M:
5660 case ringorder_a:
5661 // not yet done:
5662 case ringorder_ls:
5663 case ringorder_rs:
5664 case ringorder_ds:
5665 case ringorder_Ds:
5666 case ringorder_ws:
5667 case ringorder_Ws:
5668 case ringorder_am:
5669 case ringorder_a64:
5670 // should not occur:
5671 case ringorder_S:
5672 case ringorder_IS:
5673 case ringorder_s:
5674 case ringorder_aa:
5675 case ringorder_L:
5676 case ringorder_unspec:
5677 Werror("order %s not (yet) supported", rSimpleOrdStr(src->order[i]));
5678 break;
5679 }
5680 }
5681 } /* end if (rIsLPRing(src)) */
5682 rComplete(r);
5683
5684 //rChangeCurrRing(r);
5685#ifdef RDEBUG
5686 rTest(r);
5687// rWrite(r);
5688// rDebugPrint(r);
5689#endif
5690
5691#ifdef HAVE_PLURAL
5692 // now, we initialize a non-comm structure on r
5693 if (rIsPluralRing(src))
5694 {
5695// assume( currRing == r);
5696
5697 int *perm = (int *)omAlloc0((rVar(r)+1)*sizeof(int));
5698 int *par_perm = NULL;
5699 nMapFunc nMap = n_SetMap(src->cf,r->cf);
5700 int ni,nj;
5701 for(i=1; i<=r->N; i++)
5702 {
5703 perm[i] = rOppVar(r,i);
5704 }
5705
5706 matrix C = mpNew(rVar(r),rVar(r));
5707 matrix D = mpNew(rVar(r),rVar(r));
5708
5709 for (i=1; i< rVar(r); i++)
5710 {
5711 for (j=i+1; j<=rVar(r); j++)
5712 {
5713 ni = r->N +1 - i;
5714 nj = r->N +1 - j; /* i<j ==> nj < ni */
5715
5716 assume(MATELEM(src->GetNC()->C,i,j) != NULL);
5717 MATELEM(C,nj,ni) = p_PermPoly(MATELEM(src->GetNC()->C,i,j),perm,src,r, nMap,par_perm,rPar(src));
5718
5719 if(MATELEM(src->GetNC()->D,i,j) != NULL)
5720 MATELEM(D,nj,ni) = p_PermPoly(MATELEM(src->GetNC()->D,i,j),perm,src,r, nMap,par_perm,rPar(src));
5721 }
5722 }
5723
5724 id_Test((ideal)C, r);
5725 id_Test((ideal)D, r);
5726
5727 if (nc_CallPlural(C, D, NULL, NULL, r, false, false, true, r)) // no qring setup!
5728 WarnS("Error initializing non-commutative multiplication!");
5729
5730#ifdef RDEBUG
5731 rTest(r);
5732// rWrite(r);
5733// rDebugPrint(r);
5734#endif
5735
5736 assume( r->GetNC()->IsSkewConstant == src->GetNC()->IsSkewConstant);
5737
5738 omFreeSize((ADDRESS)perm,(rVar(r)+1)*sizeof(int));
5739 }
5740#endif /* HAVE_PLURAL */
5741
5742 /* now oppose the qideal for qrings */
5743 if (src->qideal != NULL)
5744 {
5745#ifdef HAVE_PLURAL
5746 r->qideal = idOppose(src, src->qideal, r); // into the currRing: r
5747#else
5748 r->qideal = id_Copy(src->qideal, r); // ?
5749#endif
5750
5751#ifdef HAVE_PLURAL
5752 if( rIsPluralRing(r) )
5753 {
5755#ifdef RDEBUG
5756 rTest(r);
5757// rWrite(r);
5758// rDebugPrint(r);
5759#endif
5760 }
5761#endif
5762 }
5763#ifdef HAVE_PLURAL
5764 if( rIsPluralRing(r) )
5765 assume( ncRingType(r) == ncRingType(src) );
5766#endif
5767 rTest(r);
5768
5769 return r;
5770}
5771
5772ring rEnvelope(ring R)
5773 /* creates an enveloping algebra of R */
5774 /* that is R^e = R \tensor_K R^opp */
5775{
5776 ring Ropp = rOpposite(R);
5777 ring Renv = NULL;
5778 int stat = rSum(R, Ropp, Renv); /* takes care of qideals */
5779 if ( stat <=0 )
5780 WarnS("Error in rEnvelope at rSum");
5781 rTest(Renv);
5782 return Renv;
5783}
5784
5785#ifdef HAVE_PLURAL
5786BOOLEAN nc_rComplete(const ring src, ring dest, bool bSetupQuotient)
5787/* returns TRUE is there were errors */
5788/* dest is actualy equals src with the different ordering */
5789/* we map src->nc correctly to dest->src */
5790/* to be executed after rComplete, before rChangeCurrRing */
5791{
5792// NOTE: Originally used only by idElimination to transfer NC structure to dest
5793// ring created by dirty hack (without nc_CallPlural)
5794 rTest(src);
5795
5796 assume(!rIsPluralRing(dest)); // destination must be a newly constructed commutative ring
5797
5798 if (!rIsPluralRing(src))
5799 {
5800 return FALSE;
5801 }
5802
5803 const int N = dest->N;
5804
5805 assume(src->N == N);
5806
5807// ring save = currRing;
5808
5809// if (dest != save)
5810// rChangeCurrRing(dest);
5811
5812 const ring srcBase = src;
5813
5814 assume( n_SetMap(srcBase->cf,dest->cf) == n_SetMap(dest->cf,dest->cf) ); // currRing is important here!
5815
5816 matrix C = mpNew(N,N); // ring independent
5817 matrix D = mpNew(N,N);
5818
5819 matrix C0 = src->GetNC()->C;
5820 matrix D0 = src->GetNC()->D;
5821
5822 // map C and D into dest
5823 for (int i = 1; i < N; i++)
5824 {
5825 for (int j = i + 1; j <= N; j++)
5826 {
5827 const number n = n_Copy(p_GetCoeff(MATELEM(C0,i,j), srcBase), srcBase->cf); // src, mapping for coeffs into currRing = dest!
5828 const poly p = p_NSet(n, dest);
5829 MATELEM(C,i,j) = p;
5830 if (MATELEM(D0,i,j) != NULL)
5831 MATELEM(D,i,j) = prCopyR(MATELEM(D0,i,j), srcBase, dest); // ?
5832 }
5833 }
5834 /* One must test C and D _only_ in r->GetNC()->basering!!! not in r!!! */
5835
5836 id_Test((ideal)C, dest);
5837 id_Test((ideal)D, dest);
5838
5839 if (nc_CallPlural(C, D, NULL, NULL, dest, bSetupQuotient, false, true, dest)) // also takes care about quotient ideal
5840 {
5841 //WarnS("Error transferring non-commutative structure");
5842 // error message should be in the interpreter interface
5843
5844 mp_Delete(&C, dest);
5845 mp_Delete(&D, dest);
5846
5847// if (currRing != save)
5848// rChangeCurrRing(save);
5849
5850 return TRUE;
5851 }
5852
5853// mp_Delete(&C, dest); // used by nc_CallPlural!
5854// mp_Delete(&D, dest);
5855
5856// if (dest != save)
5857// rChangeCurrRing(save);
5858
5859 assume(rIsPluralRing(dest));
5860 return FALSE;
5861}
5862#endif
5863
5864void rModify_a_to_A(ring r)
5865// to be called BEFORE rComplete:
5866// changes every Block with a(...) to A(...)
5867{
5868 int i=0;
5869 int j;
5870 while(r->order[i]!=0)
5871 {
5872 if (r->order[i]==ringorder_a)
5873 {
5874 r->order[i]=ringorder_a64;
5875 int *w=r->wvhdl[i];
5876 int64 *w64=(int64 *)omAlloc((r->block1[i]-r->block0[i]+1)*sizeof(int64));
5877 for(j=r->block1[i]-r->block0[i];j>=0;j--)
5878 w64[j]=(int64)w[j];
5879 r->wvhdl[i]=(int*)w64;
5880 omFreeSize(w,(r->block1[i]-r->block0[i]+1)*sizeof(int));
5881 }
5882 i++;
5883 }
5884}
5885
5886
5887poly rGetVar(const int varIndex, const ring r)
5888{
5889 poly p = p_ISet(1, r);
5890 p_SetExp(p, varIndex, 1, r);
5891 p_Setm(p, r);
5892 return p;
5893}
5894
5895
5896/// TODO: rewrite somehow...
5897int n_IsParam(const number m, const ring r)
5898{
5899 assume(r != NULL);
5900 const coeffs C = r->cf;
5901 assume(C != NULL);
5902
5904
5905 const n_coeffType _filed_type = getCoeffType(C);
5906
5907 if(( _filed_type == n_algExt )||( _filed_type == n_polyExt ))
5908 return naIsParam(m, C);
5909
5910 if( _filed_type == n_transExt )
5911 return ntIsParam(m, C);
5912
5913 Werror("n_IsParam: IsParam is not to be used for (coeff_type = %d)",getCoeffType(C));
5914
5915 return 0;
5916}
5917
5918ring rPlusVar(const ring r, char *v,int left)
5919{
5920 if (r->order[2]!=0)
5921 {
5922 WerrorS("only for rings with an ordering of one block");
5923 return NULL;
5924 }
5925 int p;
5926 if((r->order[0]==ringorder_C)
5927 ||(r->order[0]==ringorder_c))
5928 p=1;
5929 else
5930 p=0;
5931 if((r->order[p]!=ringorder_dp)
5932 && (r->order[p]!=ringorder_Dp)
5933 && (r->order[p]!=ringorder_lp)
5934 && (r->order[p]!=ringorder_rp)
5935 && (r->order[p]!=ringorder_ds)
5936 && (r->order[p]!=ringorder_Ds)
5937 && (r->order[p]!=ringorder_ls))
5938 {
5939 WerrorS("ordering must be dp,Dp,lp,rp,ds,Ds or ls");
5940 return NULL;
5941 }
5942 for(int i=r->N-1;i>=0;i--)
5943 {
5944 if (strcmp(r->names[i],v)==0)
5945 {
5946 Werror("duplicate variable name >>%s<<",v);
5947 return NULL;
5948 }
5949 }
5950 ring R=rCopy0(r);
5951 char **names;
5952 #ifdef HAVE_SHIFTBBA
5953 if (rIsLPRing(r))
5954 {
5955 R->isLPring=r->isLPring+1;
5956 R->N=((r->N)/r->isLPring)+r->N;
5957 names=(char**)omAlloc(R->N*sizeof(char_ptr));
5958 if (left)
5959 {
5960 for(int b=0;b<((r->N)/r->isLPring);b++)
5961 {
5962 names[b*R->isLPring]=omStrDup(v);
5963 for(int i=R->isLPring-1;i>0;i--)
5964 names[i+b*R->isLPring]=R->names[i-1+b*r->isLPring];
5965 }
5966 }
5967 else
5968 {
5969 for(int b=0;b<((r->N)/r->isLPring);b++)
5970 {
5971 names[(b+1)*R->isLPring-1]=omStrDup(v);
5972 for(int i=R->isLPring-2;i>=0;i--)
5973 names[i+b*R->isLPring]=R->names[i+b*r->isLPring];
5974 }
5975 }
5976 }
5977 else
5978 #endif
5979 {
5980 R->N++;
5981 names=(char**)omAlloc(R->N*sizeof(char_ptr));
5982 if (left)
5983 {
5984 names[0]=omStrDup(v);
5985 for(int i=R->N-1;i>0;i--) names[i]=R->names[i-1];
5986 }
5987 else
5988 {
5989 names[R->N-1]=omStrDup(v);
5990 for(int i=R->N-2;i>=0;i--) names[i]=R->names[i];
5991 }
5992 }
5993 omFreeSize(R->names,r->N*sizeof(char_ptr));
5994 R->names=names;
5995 R->block1[p]=R->N;
5996 rComplete(R);
5997 return R;
5998}
5999
6000ring rMinusVar(const ring r, char *v)
6001{
6002 if (r->order[2]!=0)
6003 {
6004 WerrorS("only for rings with an ordering of one block");
6005 return NULL;
6006 }
6007 int p;
6008 if((r->order[0]==ringorder_C)
6009 ||(r->order[0]==ringorder_c))
6010 p=1;
6011 else
6012 p=0;
6013 if((r->order[p]!=ringorder_dp)
6014 && (r->order[p]!=ringorder_Dp)
6015 && (r->order[p]!=ringorder_lp)
6016 && (r->order[p]!=ringorder_rp)
6017 && (r->order[p]!=ringorder_ds)
6018 && (r->order[p]!=ringorder_Ds)
6019 && (r->order[p]!=ringorder_ls))
6020 {
6021 WerrorS("ordering must be dp,Dp,lp,rp,ds,Ds or ls");
6022 return NULL;
6023 }
6024 ring R=rCopy0(r);
6025 int i=R->N-1;
6026 while(i>=0)
6027 {
6028 if (strcmp(R->names[i],v)==0)
6029 {
6030 R->N--;
6031 omFree(R->names[i]);
6032 for(int j=i;j<R->N;j++) R->names[j]=R->names[j+1];
6033 R->names=(char**)omReallocSize(R->names,r->N*sizeof(char_ptr),R->N*sizeof(char_ptr));
6034 }
6035 i--;
6036 }
6037 R->block1[p]=R->N;
6038 rComplete(R,1);
6039 return R;
6040}
int sgn(const Rational &a)
Definition: GMPrat.cc:430
int naIsParam(number m, const coeffs cf)
if m == var(i)/1 => return i,
Definition: algext.cc:1096
All the auxiliary stuff.
long int64
Definition: auxiliary.h:68
static int si_max(const int a, const int b)
Definition: auxiliary.h:124
#define BIT_SIZEOF_LONG
Definition: auxiliary.h:80
int BOOLEAN
Definition: auxiliary.h:87
#define TRUE
Definition: auxiliary.h:100
#define FALSE
Definition: auxiliary.h:96
void * ADDRESS
Definition: auxiliary.h:119
int size(const CanonicalForm &f, const Variable &v)
int size ( const CanonicalForm & f, const Variable & v )
Definition: cf_ops.cc:600
const CanonicalForm CFMap CFMap & N
Definition: cfEzgcd.cc:56
int l
Definition: cfEzgcd.cc:100
int m
Definition: cfEzgcd.cc:128
for(int i=0;i<=n;i++) degsf[i]
Definition: cfEzgcd.cc:72
int i
Definition: cfEzgcd.cc:132
int k
Definition: cfEzgcd.cc:99
Variable x
Definition: cfModGcd.cc:4082
int p
Definition: cfModGcd.cc:4078
CanonicalForm cf
Definition: cfModGcd.cc:4083
CanonicalForm b
Definition: cfModGcd.cc:4103
int rows() const
Definition: int64vec.h:66
Definition: intvec.h:23
int length() const
Definition: intvec.h:94
Coefficient rings, fields and other domains suitable for Singular polynomials.
static FORCE_INLINE number n_Copy(number n, const coeffs r)
return a copy of 'n'
Definition: coeffs.h:451
static FORCE_INLINE void n_CoeffWrite(const coeffs r, BOOLEAN details=TRUE)
output the coeff description
Definition: coeffs.h:719
static FORCE_INLINE BOOLEAN nCoeff_is_Extension(const coeffs r)
Definition: coeffs.h:846
n_coeffType
Definition: coeffs.h:27
@ n_R
single prescision (6,6) real numbers
Definition: coeffs.h:31
@ n_polyExt
used to represent polys as coeffcients
Definition: coeffs.h:34
@ n_Q
rational (GMP) numbers
Definition: coeffs.h:30
@ n_Znm
only used if HAVE_RINGS is defined
Definition: coeffs.h:45
@ n_algExt
used for all algebraic extensions, i.e., the top-most extension in an extension tower is algebraic
Definition: coeffs.h:35
@ n_Zn
only used if HAVE_RINGS is defined
Definition: coeffs.h:44
@ n_Zp
\F{p < 2^31}
Definition: coeffs.h:29
@ n_transExt
used for all transcendental extensions, i.e., the top-most extension in an extension tower is transce...
Definition: coeffs.h:38
static FORCE_INLINE char * nCoeffString(const coeffs cf)
TODO: make it a virtual method of coeffs, together with: Decompose & Compose, rParameter & rPar.
Definition: coeffs.h:959
static FORCE_INLINE nMapFunc n_SetMap(const coeffs src, const coeffs dst)
set the mapping function pointers for translating numbers from src to dst
Definition: coeffs.h:700
coeffs nInitChar(n_coeffType t, void *parameter)
one-time initialisations for new coeffs in case of an error return NULL
Definition: numbers.cc:354
static FORCE_INLINE n_coeffType getCoeffType(const coeffs r)
Returns the type of coeffs domain.
Definition: coeffs.h:421
static FORCE_INLINE coeffs nCopyCoeff(const coeffs r)
"copy" coeffs, i.e. increment ref
Definition: coeffs.h:429
static FORCE_INLINE BOOLEAN nCoeff_is_algExt(const coeffs r)
TRUE iff r represents an algebraic extension field.
Definition: coeffs.h:910
number(* nMapFunc)(number a, const coeffs src, const coeffs dst)
maps "a", which lives in src, into dst
Definition: coeffs.h:73
void nKillChar(coeffs r)
undo all initialisations
Definition: numbers.cc:522
static FORCE_INLINE BOOLEAN n_IsOne(number n, const coeffs r)
TRUE iff 'n' represents the one element.
Definition: coeffs.h:468
#define Print
Definition: emacs.cc:80
#define Warn
Definition: emacs.cc:77
#define WarnS
Definition: emacs.cc:78
#define StringAppend
Definition: emacs.cc:79
const CanonicalForm int s
Definition: facAbsFact.cc:51
CanonicalForm res
Definition: facAbsFact.cc:60
const CanonicalForm & w
Definition: facAbsFact.cc:51
const Variable & v
< [in] a sqrfree bivariate poly
Definition: facBivar.h:39
bool found
Definition: facFactorize.cc:55
int j
Definition: facHensel.cc:110
static int min(int a, int b)
Definition: fast_mult.cc:268
void WerrorS(const char *s)
Definition: feFopen.cc:24
#define D(A)
Definition: gentable.cc:131
#define EXTERN_VAR
Definition: globaldefs.h:6
#define VAR
Definition: globaldefs.h:5
ideal id_Copy(ideal h1, const ring r)
copy an ideal
static BOOLEAN length(leftv result, leftv arg)
Definition: interval.cc:257
STATIC_VAR jList * Q
Definition: janet.cc:30
if(yy_init)
Definition: libparse.cc:1420
static bool rIsSCA(const ring r)
Definition: nc.h:190
ideal idOppose(ring Rop_src, ideal I, const ring Rop_dst)
opposes a module I from Rop to currRing(dst)
Definition: old.gring.cc:3381
bool nc_rCopy(ring res, const ring r, bool bSetupQuotient)
Definition: old.gring.cc:3003
bool nc_SetupQuotient(ring rGR, const ring rG=NULL, bool bCopy=false)
Definition: old.gring.cc:3403
static nc_type & ncRingType(nc_struct *p)
Definition: nc.h:159
BOOLEAN nc_CallPlural(matrix cc, matrix dd, poly cn, poly dn, ring r, bool bSetupQuotient, bool bCopyInput, bool bBeQuiet, ring curr, bool dummy_ring=false)
returns TRUE if there were errors analyze inputs, check them for consistency detects nc_type,...
Definition: old.gring.cc:2682
void nc_rKill(ring r)
complete destructor
Definition: old.gring.cc:2475
#define UPMATELEM(i, j, nVar)
Definition: nc.h:36
bool sca_Force(ring rGR, int b, int e)
Definition: sca.cc:1161
void maFindPerm(char const *const *const preim_names, int preim_n, char const *const *const preim_par, int preim_p, char const *const *const names, int n, char const *const *const par, int nop, int *perm, int *par_perm, n_coeffType ch)
Definition: maps.cc:163
void mp_Delete(matrix *a, const ring r)
Definition: matpol.cc:880
matrix mpNew(int r, int c)
create a r x c zero-matrix
Definition: matpol.cc:37
void iiWriteMatrix(matrix im, const char *n, int dim, const ring r, int spaces)
set spaces to zero by default
Definition: matpol.cc:834
#define MATELEM(mat, i, j)
1-based access to matrix
Definition: matpol.h:29
STATIC_VAR unsigned add[]
Definition: misc_ip.cc:107
#define assume(x)
Definition: mod2.h:387
int dReportError(const char *fmt,...)
Definition: dError.cc:43
#define p_GetComp(p, r)
Definition: monomials.h:64
#define pIter(p)
Definition: monomials.h:37
#define POLYSIZE
Definition: monomials.h:233
#define p_GetCoeff(p, r)
Definition: monomials.h:50
gmp_float sqrt(const gmp_float &a)
Definition: mpr_complex.cc:327
const int MAX_INT_VAL
Definition: mylimits.h:12
The main handler for Singular numbers which are suitable for Singular polynomials.
Definition: qr.h:46
#define omStrDup(s)
Definition: omAllocDecl.h:263
#define omFreeSize(addr, size)
Definition: omAllocDecl.h:260
#define omCheckAddr(addr)
Definition: omAllocDecl.h:328
#define omAlloc(size)
Definition: omAllocDecl.h:210
#define omReallocSize(addr, o_size, size)
Definition: omAllocDecl.h:220
#define omAllocBin(bin)
Definition: omAllocDecl.h:205
#define omCheckAddrSize(addr, size)
Definition: omAllocDecl.h:327
#define omAlloc0Bin(bin)
Definition: omAllocDecl.h:206
#define omalloc(size)
Definition: omAllocDecl.h:228
#define omFree(addr)
Definition: omAllocDecl.h:261
#define omAlloc0(size)
Definition: omAllocDecl.h:211
#define omFreeBin(addr, bin)
Definition: omAllocDecl.h:259
#define omMemDup(s)
Definition: omAllocDecl.h:264
#define omcheckAddrSize(addr, size)
Definition: omAllocDecl.h:329
#define omfreeSize(addr, size)
Definition: omAllocDecl.h:236
#define omGetSpecBin(size)
Definition: omBin.h:11
#define omUnGetSpecBin(bin_ptr)
Definition: omBin.h:14
#define MIN(a, b)
Definition: omDebug.c:102
#define NULL
Definition: omList.c:12
omBin_t * omBin
Definition: omStructs.h:12
VAR unsigned si_opt_1
Definition: options.c:5
#define OPT_INTSTRATEGY
Definition: options.h:92
#define OPT_REDTAIL
Definition: options.h:91
#define TEST_OPT_OLDSTD
Definition: options.h:123
#define OPT_REDTHROUGH
Definition: options.h:82
#define Sy_bit(x)
Definition: options.h:31
#define TEST_OPT_PROT
Definition: options.h:103
void p_ProcsSet(ring r, p_Procs_s *p_Procs)
Definition: p_Procs_Set.h:141
void p_Debug_GetProcNames(const ring r, p_Procs_s *p_Procs)
Definition: p_Procs_Set.h:232
void p_Debug_GetSpecNames(const ring r, const char *&field, const char *&length, const char *&ord)
Definition: p_Procs_Set.h:221
void p_Setm_WFirstTotalDegree(poly p, const ring r)
Definition: p_polys.cc:554
long pLDegb(poly p, int *l, const ring r)
Definition: p_polys.cc:811
long pLDeg1_Totaldegree(poly p, int *l, const ring r)
Definition: p_polys.cc:975
long p_WFirstTotalDegree(poly p, const ring r)
Definition: p_polys.cc:596
long pLDeg1_WFirstTotalDegree(poly p, int *l, const ring r)
Definition: p_polys.cc:1038
long pLDeg1c_WFirstTotalDegree(poly p, int *l, const ring r)
Definition: p_polys.cc:1068
void p_Setm_Dummy(poly p, const ring r)
Definition: p_polys.cc:541
void p_Setm_TotalDegree(poly p, const ring r)
Definition: p_polys.cc:547
poly p_ISet(long i, const ring r)
returns the poly representing the integer i
Definition: p_polys.cc:1297
long pLDeg1c_Deg(poly p, int *l, const ring r)
Definition: p_polys.cc:941
long pLDeg1(poly p, int *l, const ring r)
Definition: p_polys.cc:841
poly p_PermPoly(poly p, const int *perm, const ring oldRing, const ring dst, nMapFunc nMap, const int *par_perm, int OldPar, BOOLEAN use_mult)
Definition: p_polys.cc:4195
long pLDeg1_Deg(poly p, int *l, const ring r)
Definition: p_polys.cc:910
long p_WTotaldegree(poly p, const ring r)
Definition: p_polys.cc:613
p_SetmProc p_GetSetmProc(const ring r)
Definition: p_polys.cc:560
void p_Setm_General(poly p, const ring r)
Definition: p_polys.cc:158
long pLDeg1c(poly p, int *l, const ring r)
Definition: p_polys.cc:877
long pLDeg1c_Totaldegree(poly p, int *l, const ring r)
Definition: p_polys.cc:1005
long pLDeg0c(poly p, int *l, const ring r)
Definition: p_polys.cc:770
long pLDeg0(poly p, int *l, const ring r)
Definition: p_polys.cc:739
poly p_One(const ring r)
Definition: p_polys.cc:1313
poly p_NSet(number n, const ring r)
returns the poly representing the number n, destroys n
Definition: p_polys.cc:1469
long p_Deg(poly a, const ring r)
Definition: p_polys.cc:587
BOOLEAN p_EqualPolys(poly p1, poly p2, const ring r)
Definition: p_polys.cc:4577
static long p_FDeg(const poly p, const ring r)
Definition: p_polys.h:380
void p_Write(poly p, ring lmRing, ring tailRing)
Definition: polys0.cc:342
static unsigned long p_SetExp(poly p, const unsigned long e, const unsigned long iBitmask, const int VarOffset)
set a single variable exponent @Note: VarOffset encodes the position in p->exp
Definition: p_polys.h:488
static unsigned long p_SetComp(poly p, unsigned long c, ring r)
Definition: p_polys.h:247
static void p_Setm(poly p, const ring r)
Definition: p_polys.h:233
static long p_GetExp(const poly p, const unsigned long iBitmask, const int VarOffset)
get a single variable exponent @Note: the integer VarOffset encodes:
Definition: p_polys.h:469
static void p_Delete(poly *p, const ring r)
Definition: p_polys.h:901
void p_Write0(poly p, ring lmRing, ring tailRing)
Definition: polys0.cc:332
static long p_Totaldegree(poly p, const ring r)
Definition: p_polys.h:1507
#define p_Test(p, r)
Definition: p_polys.h:162
void p_wrp(poly p, ring lmRing, ring tailRing)
Definition: polys0.cc:373
poly prCopyR(poly p, ring src_r, ring dest_r)
Definition: prCopy.cc:34
ideal idrCopyR(ideal id, ring src_r, ring dest_r)
Definition: prCopy.cc:192
ideal idrCopyR_NoSort(ideal id, ring src_r, ring dest_r)
Definition: prCopy.cc:205
ideal idrHeadR(ideal id, ring r, ring dest_r)
Copy leading terms of id[i] via prHeeadR into dest_r.
Definition: prCopy.cc:156
void StringSetS(const char *st)
Definition: reporter.cc:128
void StringAppendS(const char *st)
Definition: reporter.cc:107
void PrintS(const char *s)
Definition: reporter.cc:284
char * StringEndS()
Definition: reporter.cc:151
void PrintLn()
Definition: reporter.cc:310
void Werror(const char *fmt,...)
Definition: reporter.cc:189
static void rSetNegWeight(ring r)
Definition: ring.cc:3389
BOOLEAN rOrd_SetCompRequiresSetm(const ring r)
return TRUE if p_SetComp requires p_Setm
Definition: ring.cc:1993
static void rO_ISSuffix(int &place, int &bitplace, int &prev_ord, long *o, int N, int *v, sro_ord *tmp_typ, int &typ_i, int sgn)
Definition: ring.cc:2516
int rSum(ring r1, ring r2, ring &sum)
Definition: ring.cc:1402
ring rAssure_TDeg(ring r, int &pos)
Definition: ring.cc:4607
void rWrite(ring r, BOOLEAN details)
Definition: ring.cc:226
ring rAssure_InducedSchreyerOrdering(const ring r, BOOLEAN complete, int sgn)
Definition: ring.cc:4930
static ring rAssure_Global(rRingOrder_t b1, rRingOrder_t b2, const ring r)
Definition: ring.cc:4884
BOOLEAN rOrder_is_WeightedOrdering(rRingOrder_t order)
Definition: ring.cc:1947
void rGetSComps(int **currComponents, long **currShiftedComponents, int *length, ring r)
Definition: ring.cc:4494
BOOLEAN rRing_ord_pure_Dp(const ring r)
Definition: ring.cc:5303
static void rNChangeSComps(int *currComponents, long *currShiftedComponents, ring r)
Definition: ring.cc:4447
ring rModifyRing_Wp(ring r, int *weights)
construct Wp, C ring
Definition: ring.cc:2987
BOOLEAN rOrder_is_DegOrdering(const rRingOrder_t order)
Definition: ring.cc:1928
void pISUpdateComponents(ideal F, const intvec *const V, const int MIN, const ring r)
Definition: ring.cc:4406
BOOLEAN rHasSimpleOrderAA(ring r)
Definition: ring.cc:1962
void rSetWeightVec(ring r, int64 *wv)
Definition: ring.cc:5333
static void rSetOption(ring r)
Definition: ring.cc:3426
BOOLEAN rComplete(ring r, int force)
this needs to be called whenever a new ring is created: new fields in ring are created (like VarOffse...
Definition: ring.cc:3492
int r_IsRingVar(const char *n, char **names, int N)
Definition: ring.cc:212
#define rOppVar(R, I)
Definition: ring.cc:5379
int rGetISPos(const int p, const ring r)
Finds p^th IS ordering, and returns its position in r->typ[] returns -1 if something went wrong!...
Definition: ring.cc:5080
static void rNGetSComps(int **currComponents, long **currShiftedComponents, ring r)
Definition: ring.cc:4455
#define BITS_PER_LONG
Definition: ring.cc:40
static void rO_WDegree64(int &place, int &bitplace, int start, int end, long *o, sro_ord &ord_struct, int64 *weights)
Definition: ring.cc:2326
BOOLEAN rHasSimpleLexOrder(const ring r)
returns TRUE, if simple lp or ls ordering
Definition: ring.cc:1919
void p_SetGlobals(const ring r, BOOLEAN complete)
set all properties of a new ring - also called by rComplete
Definition: ring.cc:3457
ring rAssure_SyzComp(const ring r, BOOLEAN complete)
Definition: ring.cc:4515
BOOLEAN nc_rComplete(const ring src, ring dest, bool bSetupQuotient)
Definition: ring.cc:5786
void p_DebugPrint(poly p, const ring r)
Definition: ring.cc:4369
void rKillModifiedRing(ring r)
Definition: ring.cc:3101
BOOLEAN rRing_ord_pure_dp(const ring r)
Definition: ring.cc:5293
static void rSetVarL(ring r)
set r->VarL_Size, r->VarL_Offset, r->VarL_LowIndex
Definition: ring.cc:4069
static void rO_LexVars(int &place, int &bitplace, int start, int end, int &prev_ord, long *o, int *v, int bits, int opt_var)
Definition: ring.cc:2376
const char * rSimpleOrdStr(int ord)
Definition: ring.cc:77
BOOLEAN rOrd_is_MixedDegree_Ordering(ring r)
Definition: ring.cc:3470
static void rDBChangeSComps(int *currComponents, long *currShiftedComponents, int length, ring r)
Definition: ring.cc:4463
ring rAssure_c_dp(const ring r)
Definition: ring.cc:5070
static void rSetOutParams(ring r)
Definition: ring.cc:3122
static void rSetDegStuff(ring r)
Definition: ring.cc:3219
static void rDBGetSComps(int **currComponents, long **currShiftedComponents, int *length, ring r)
Definition: ring.cc:4473
rOrderType_t rGetOrderType(ring r)
Definition: ring.cc:1840
int rChar(ring r)
Definition: ring.cc:713
int rTypeOfMatrixOrder(const intvec *order)
Definition: ring.cc:185
VAR omBin sip_sring_bin
Definition: ring.cc:43
void rUnComplete(ring r)
Definition: ring.cc:4007
ring nc_rCreateNCcomm_rCopy(ring r)
Definition: ring.cc:719
char * char_ptr
Definition: ring.cc:42
static void rOppWeight(int *w, int l)
Definition: ring.cc:5366
static void rO_WDegree_neg(int &place, int &bitplace, int start, int end, long *o, sro_ord &ord_struct, int *weights)
Definition: ring.cc:2350
void rKillModified_Wp_Ring(ring r)
Definition: ring.cc:3111
ring rMinusVar(const ring r, char *v)
undo rPlusVar
Definition: ring.cc:6000
BOOLEAN rRing_has_CompLastBlock(const ring r)
Definition: ring.cc:5286
ring rCopy0AndAddA(const ring r, int64vec *wv64, BOOLEAN copy_qideal, BOOLEAN copy_ordering)
Definition: ring.cc:1564
static void rO_Syzcomp(int &place, int &bitplace, int &prev_ord, long *o, sro_ord &ord_struct)
Definition: ring.cc:2452
BOOLEAN rOrd_is_Totaldegree_Ordering(const ring r)
Definition: ring.cc:2013
ring rModifyRing(ring r, BOOLEAN omit_degree, BOOLEAN try_omit_comp, unsigned long exp_limit)
Definition: ring.cc:2740
ring rAssure_SyzOrder(const ring r, BOOLEAN complete)
Definition: ring.cc:4510
static void rO_TDegree(int &place, int &bitplace, int start, int end, long *o, sro_ord &ord_struct)
Definition: ring.cc:2236
ring rAssure_C_dp(const ring r)
Definition: ring.cc:5065
BOOLEAN rHasSimpleOrder(const ring r)
Definition: ring.cc:1887
int rGetMaxSyzComp(int i, const ring r)
return the max-comonent wchich has syzIndex i Assume: i<= syzIndex_limit
Definition: ring.cc:5238
BOOLEAN rSetISReference(const ring r, const ideal F, const int i, const int p)
Changes r by setting induced ordering parameters: limit and reference leading terms F belong to r,...
Definition: ring.cc:5112
char * rString(ring r)
Definition: ring.cc:673
ring rAssure_HasComp(const ring r)
Definition: ring.cc:4705
ring rCopy0(const ring r, BOOLEAN copy_qideal, BOOLEAN copy_ordering)
Definition: ring.cc:1421
static void rO_WMDegree(int &place, int &bitplace, int start, int end, long *o, sro_ord &ord_struct, int *weights)
Definition: ring.cc:2304
static void rO_Syz(int &place, int &bitplace, int &prev_ord, int syz_comp, long *o, sro_ord &ord_struct)
Definition: ring.cc:2467
BOOLEAN rHas_c_Ordering(const ring r)
Definition: ring.cc:1883
static int rRealloc1(ring r, int size, int pos)
Definition: ring.cc:5343
#define pFDeg_CASE(A)
static unsigned long rGetExpSize(unsigned long bitmask, int &bits)
Definition: ring.cc:2607
void rDebugPrint(const ring r)
Definition: ring.cc:4164
static void rCheckOrdSgn(ring r, int i)
Definition: ring.cc:3894
BOOLEAN rRing_ord_pure_lp(const ring r)
Definition: ring.cc:5313
poly rGetVar(const int varIndex, const ring r)
Definition: ring.cc:5887
ring rModifyRing_Simple(ring r, BOOLEAN ommit_degree, BOOLEAN ommit_comp, unsigned long exp_limit, BOOLEAN &simple)
Definition: ring.cc:3035
void rChangeSComps(int *currComponents, long *currShiftedComponents, int length, ring r)
Definition: ring.cc:4485
static void m_DebugPrint(const poly p, const ring R)
debug-print monomial poly/vector p, assuming that it lives in the ring R
Definition: ring.cc:4392
static unsigned long rGetDivMask(int bits)
get r->divmask depending on bits per exponent
Definition: ring.cc:4150
BOOLEAN rSamePolyRep(ring r1, ring r2)
returns TRUE, if r1 and r2 represents the monomials in the same way FALSE, otherwise this is an analo...
Definition: ring.cc:1799
ring rAssure_SyzComp_CompLastBlock(const ring r)
makes sure that c/C ordering is last ordering and SyzIndex is first
Definition: ring.cc:4829
char * rParStr(ring r)
Definition: ring.cc:649
char * rCharStr(const ring r)
TODO: make it a virtual method of coeffs, together with: Decompose & Compose, rParameter & rPar.
Definition: ring.cc:647
static void rOptimizeLDeg(ring r)
Definition: ring.cc:3192
BOOLEAN rCheckIV(const intvec *iv)
Definition: ring.cc:175
rRingOrder_t rOrderName(char *ordername)
Definition: ring.cc:507
ring rOpposite(ring src)
Definition: ring.cc:5382
void rModify_a_to_A(ring r)
Definition: ring.cc:5864
char * rOrdStr(ring r)
Definition: ring.cc:521
void rDelete(ring r)
unconditionally deletes fields in r
Definition: ring.cc:450
ring rDefault(const coeffs cf, int N, char **n, int ord_size, rRingOrder_t *ord, int *block0, int *block1, int **wvhdl, unsigned long bitmask)
Definition: ring.cc:102
static void rRightAdjustVarOffset(ring r)
right-adjust r->VarOffset
Definition: ring.cc:4124
VAR omBin char_ptr_bin
Definition: ring.cc:44
char * rVarStr(ring r)
Definition: ring.cc:623
ring rPlusVar(const ring r, char *v, int left)
K[x],"y" -> K[x,y] resp. K[y,x].
Definition: ring.cc:5918
BOOLEAN rIsPolyVar(int v, const ring r)
returns TRUE if var(i) belongs to p-block
Definition: ring.cc:2036
ring rAssure_CompLastBlock(ring r, BOOLEAN complete)
makes sure that c/C ordering is last ordering
Definition: ring.cc:4774
static void rO_ISPrefix(int &place, int &bitplace, int &prev_ord, long *o, int N, int *v, sro_ord &ord_struct)
Definition: ring.cc:2493
static void rO_Align(int &place, int &bitplace)
Definition: ring.cc:2225
ring rAssure_dp_S(const ring r)
Definition: ring.cc:5055
static void rO_TDegree_neg(int &place, int &bitplace, int start, int end, long *o, sro_ord &ord_struct)
Definition: ring.cc:2250
static void rSetFirstWv(ring r, int i, rRingOrder_t *order, int *block0, int *block1, int **wvhdl)
Definition: ring.cc:3160
ring rEnvelope(ring R)
Definition: ring.cc:5772
BOOLEAN rEqual(ring r1, ring r2, BOOLEAN qr)
returns TRUE, if r1 equals r2 FALSE, otherwise Equality is determined componentwise,...
Definition: ring.cc:1746
int rSumInternal(ring r1, ring r2, ring &sum, BOOLEAN vartest, BOOLEAN dp_dp)
returns -1 for not compatible, 1 for compatible (and sum) dp_dp:0: block ordering,...
Definition: ring.cc:749
void rSetSyzComp(int k, const ring r)
Definition: ring.cc:5166
static const char *const ringorder_name[]
Definition: ring.cc:47
BOOLEAN rRing_is_Homog(const ring r)
Definition: ring.cc:5265
static int sign(int x)
Definition: ring.cc:3469
static void rO_WDegree(int &place, int &bitplace, int start, int end, long *o, sro_ord &ord_struct, int *weights)
Definition: ring.cc:2264
BOOLEAN rOrd_is_WeightedDegree_Ordering(const ring r)
Definition: ring.cc:2027
int n_IsParam(const number m, const ring r)
TODO: rewrite somehow...
Definition: ring.cc:5897
int64 * rGetWeightVec(const ring r)
Definition: ring.cc:5323
static void rO_LexVars_neg(int &place, int &bitplace, int start, int end, int &prev_ord, long *o, int *v, int bits, int opt_var)
Definition: ring.cc:2413
ring rAssure_dp_C(const ring r)
Definition: ring.cc:5060
ring rCopy(ring r)
Definition: ring.cc:1731
VAR int pDBsyzComp
Definition: ring.cc:5162
BOOLEAN rDBTest(ring r, const char *fn, const int l)
Definition: ring.cc:2075
static int rBlocks(ring r)
Definition: ring.h:569
struct p_Procs_s p_Procs_s
Definition: ring.h:23
static BOOLEAN rIsPluralRing(const ring r)
we must always have this test!
Definition: ring.h:400
ro_typ ord_typ
Definition: ring.h:220
static ring rIncRefCnt(ring r)
Definition: ring.h:843
static int rPar(const ring r)
(r->cf->P)
Definition: ring.h:600
@ ro_wp64
Definition: ring.h:55
@ ro_syz
Definition: ring.h:60
@ ro_cp
Definition: ring.h:58
@ ro_dp
Definition: ring.h:52
@ ro_is
Definition: ring.h:61
@ ro_wp_neg
Definition: ring.h:56
@ ro_wp
Definition: ring.h:53
@ ro_isTemp
Definition: ring.h:61
@ ro_am
Definition: ring.h:54
@ ro_syzcomp
Definition: ring.h:59
static BOOLEAN rIsLPRing(const ring r)
Definition: ring.h:411
rRingOrder_t
order stuff
Definition: ring.h:68
@ ringorder_lp
Definition: ring.h:77
@ ringorder_a
Definition: ring.h:70
@ ringorder_am
Definition: ring.h:88
@ ringorder_a64
for int64 weights
Definition: ring.h:71
@ ringorder_rs
opposite of ls
Definition: ring.h:92
@ ringorder_C
Definition: ring.h:73
@ ringorder_S
S?
Definition: ring.h:75
@ ringorder_ds
Definition: ring.h:84
@ ringorder_Dp
Definition: ring.h:80
@ ringorder_unspec
Definition: ring.h:94
@ ringorder_L
Definition: ring.h:89
@ ringorder_Ds
Definition: ring.h:85
@ ringorder_dp
Definition: ring.h:78
@ ringorder_c
Definition: ring.h:72
@ ringorder_rp
Definition: ring.h:79
@ ringorder_aa
for idElimination, like a, except pFDeg, pWeigths ignore it
Definition: ring.h:91
@ ringorder_no
Definition: ring.h:69
@ ringorder_Wp
Definition: ring.h:82
@ ringorder_ws
Definition: ring.h:86
@ ringorder_Ws
Definition: ring.h:87
@ ringorder_IS
Induced (Schreyer) ordering.
Definition: ring.h:93
@ ringorder_ls
Definition: ring.h:83
@ ringorder_s
s?
Definition: ring.h:76
@ ringorder_wp
Definition: ring.h:81
@ ringorder_M
Definition: ring.h:74
static BOOLEAN rField_is_Q(const ring r)
Definition: ring.h:507
static BOOLEAN rShortOut(const ring r)
Definition: ring.h:582
rOrderType_t
Definition: ring.h:98
@ rOrderType_CompExp
simple ordering, component has priority
Definition: ring.h:100
@ rOrderType_Exp
simple ordering, exponent vector has priority component is compatible with exp-vector order
Definition: ring.h:103
@ rOrderType_General
non-simple ordering as specified by currRing
Definition: ring.h:99
@ rOrderType_ExpComp
simple ordering, exponent vector has priority component not compatible with exp-vector order
Definition: ring.h:101
static BOOLEAN rIsNCRing(const ring r)
Definition: ring.h:421
static char const ** rParameter(const ring r)
(r->cf->parameter)
Definition: ring.h:626
int order_index
Definition: ring.h:221
static BOOLEAN rCanShortOut(const ring r)
Definition: ring.h:587
static short rVar(const ring r)
#define rVar(r) (r->N)
Definition: ring.h:593
union sro_ord::@1 data
#define rTest(r)
Definition: ring.h:786
#define rField_is_Ring(R)
Definition: ring.h:486
Definition: ring.h:219
ideal SCAQuotient(const ring r)
Definition: sca.h:10
static short scaLastAltVar(ring r)
Definition: sca.h:25
static short scaFirstAltVar(ring r)
Definition: sca.h:18
ideal idInit(int idsize, int rank)
initialise an ideal / module
Definition: simpleideals.cc:35
void id_Delete(ideal *h, ring r)
deletes an ideal/module/matrix
long id_RankFreeModule(ideal s, ring lmRing, ring tailRing)
return the maximal component number found in any polynomial in s
void idShow(const ideal id, const ring lmRing, const ring tailRing, const int debugPrint)
Definition: simpleideals.cc:57
ideal id_SimpleAdd(ideal h1, ideal h2, const ring R)
concat the lists h1 and h2 without zeros
#define IDELEMS(i)
Definition: simpleideals.h:23
#define id_Test(A, lR)
Definition: simpleideals.h:78
#define R
Definition: sirandom.c:27
#define A
Definition: sirandom.c:24
Definition: ring.h:248
n_Procs_s * cf
Definition: ring.h:368
int * block0
Definition: ring.h:254
short N
Definition: ring.h:303
int * block1
Definition: ring.h:255
rRingOrder_t * order
Definition: ring.h:253
int ** wvhdl
Definition: ring.h:257
unsigned long bitmask
Definition: ring.h:350
char ** names
Definition: ring.h:258
short OrdSgn
Definition: ring.h:305
Definition: nc.h:68
char * char_ptr
Definition: structs.h:53
#define loop
Definition: structs.h:75
EXTERN_VAR long * currShiftedComponents
Definition: syz.h:118
int ntIsParam(number m, const coeffs cf)
if m == var(i)/1 => return i,
Definition: transext.cc:2216