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