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