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