My Project
Loading...
Searching...
No Matches
ring.cc
Go to the documentation of this file.
1/****************************************
2* Computer Algebra System SINGULAR *
3****************************************/
4/*
5* ABSTRACT - the interpreter related ring operations
6*/
7
8/* includes */
9#include <cmath>
10
11#include "misc/auxiliary.h"
12#include "misc/mylimits.h"
13#include "misc/options.h"
14#include "misc/int64vec.h"
15
16#include "coeffs/numbers.h"
17#include "coeffs/coeffs.h"
18
20#include "polys/simpleideals.h"
23#include "polys/prCopy.h"
25
26#include "polys/matpol.h"
27
29
30#ifdef HAVE_PLURAL
31#include "polys/nc/nc.h"
32#include "polys/nc/sca.h"
33#endif
34
35
36#include "ext_fields/algext.h"
37#include "ext_fields/transext.h"
38
39
40#define BITS_PER_LONG 8*SIZEOF_LONG
41
42typedef char * char_ptr;
45
46
47static const char * const ringorder_name[] =
48{
49 " ?", ///< ringorder_no = 0,
50 "a", ///< ringorder_a,
51 "A", ///< ringorder_a64,
52 "c", ///< ringorder_c,
53 "C", ///< ringorder_C,
54 "M", ///< ringorder_M,
55 "S", ///< ringorder_S,
56 "s", ///< ringorder_s,
57 "lp", ///< ringorder_lp,
58 "dp", ///< ringorder_dp,
59 "ip", ///< ringorder_ip,
60 "Dp", ///< ringorder_Dp,
61 "wp", ///< ringorder_wp,
62 "Wp", ///< ringorder_Wp,
63 "Ip", ///< ringorder_Ip,
64 "ls", ///< ringorder_ls,
65 "ds", ///< ringorder_ds,
66 "Ds", ///< ringorder_Ds,
67 "ws", ///< ringorder_ws,
68 "Ws", ///< ringorder_Ws,
69 "am", ///< ringorder_am,
70 "L", ///< ringorder_L,
71 "aa", ///< ringorder_aa
72 "is", ///< ringorder_is,
73 "IS", ///< ringorder_IS
74 " _" ///< ringorder_unspec
75};
76
77
78const char * rSimpleOrdStr(int ord)
79{
80 return ringorder_name[ord];
81}
82
83/// unconditionally deletes fields in r
84void rDelete(ring r);
85/// set r->VarL_Size, r->VarL_Offset, r->VarL_LowIndex
86static void rSetVarL(ring r);
87/// get r->divmask depending on bits per exponent
88static unsigned long rGetDivMask(int bits);
89/// right-adjust r->VarOffset
90static void rRightAdjustVarOffset(ring r);
91static void rOptimizeLDeg(ring r);
92
93/*0 implementation*/
94//BOOLEAN rField_is_R(ring r)
95//{
96// if (r->cf->ch== -1)
97// {
98// if (r->float_len==(short)0) return TRUE;
99// }
100// return FALSE;
101//}
102
103ring rDefault(const coeffs cf, int N, char **n,int ord_size, rRingOrder_t *ord, int *block0, int *block1, int** wvhdl, unsigned long bitmask)
104{
105 assume( cf != NULL);
107 r->N = N;
108 r->cf = cf;
109 /*rPar(r) = 0; Alloc0 */
110 /*names*/
111 r->names = (char **) omAlloc0(N * sizeof(char *));
112 int i;
113 for(i=0;i<N;i++)
114 {
115 r->names[i] = omStrDup(n[i]);
116 }
117 /*weights: entries for 2 blocks: NULL*/
118 if (wvhdl==NULL)
119 r->wvhdl = (int **)omAlloc0((ord_size+1) * sizeof(int *));
120 else
121 r->wvhdl=wvhdl;
122 r->order = ord;
123 r->block0 = block0;
124 r->block1 = block1;
125 if (bitmask!=0) r->wanted_maxExp=bitmask;
126
127 /* complete ring intializations */
128 rComplete(r);
129 return r;
130}
131ring rDefault(int ch, int N, char **n,int ord_size, rRingOrder_t *ord, int *block0, int *block1,int ** wvhdl)
132{
133 coeffs cf;
134 if (ch==0) cf=nInitChar(n_Q,NULL);
135 else cf=nInitChar(n_Zp,(void*)(long)ch);
136 assume( cf != NULL);
137 return rDefault(cf,N,n,ord_size,ord,block0,block1,wvhdl);
138}
139ring rDefault(const coeffs cf, int N, char **n, const rRingOrder_t o)
140{
141 assume( cf != NULL);
142 /*order: o=lp,0*/
143 rRingOrder_t *order = (rRingOrder_t *) omAlloc(2* sizeof(rRingOrder_t));
144 int *block0 = (int *)omAlloc0(2 * sizeof(int));
145 int *block1 = (int *)omAlloc0(2 * sizeof(int));
146 /* ringorder o=lp for the first block: var 1..N */
147 order[0] = o;
148 block0[0] = 1;
149 block1[0] = N;
150 /* the last block: everything is 0 */
151 order[1] = (rRingOrder_t)0;
152
153 return rDefault(cf,N,n,2,order,block0,block1);
154}
155
156ring rDefault(int ch, int N, char **n)
157{
158 coeffs cf;
159 if (ch==0) cf=nInitChar(n_Q,NULL);
160 else cf=nInitChar(n_Zp,(void*)(long)ch);
161 assume( cf != NULL);
162 return rDefault(cf,N,n);
163}
164
165///////////////////////////////////////////////////////////////////////////
166//
167// rInit: define a new ring from sleftv's
168//
169//-> ipshell.cc
170
171/////////////////////////////
172// Auxillary functions
173//
174
175// check intvec, describing the ordering
177{
178 if ((iv->length()!=2)&&(iv->length()!=3))
179 {
180 WerrorS("weights only for orderings wp,ws,Wp,Ws,a,M");
181 return TRUE;
182 }
183 return FALSE;
184}
185
186int rTypeOfMatrixOrder(const intvec* order)
187{
188 int i=0,j,typ=1;
189 int sz = (int)sqrt((double)(order->length()-2));
190 if ((sz*sz)!=(order->length()-2))
191 {
192 WerrorS("Matrix order is not a square matrix");
193 typ=0;
194 }
195 while ((i<sz) && (typ==1))
196 {
197 j=0;
198 while ((j<sz) && ((*order)[j*sz+i+2]==0)) j++;
199 if (j>=sz)
200 {
201 typ = 0;
202 WerrorS("Matrix order not complete");
203 }
204 else if ((*order)[j*sz+i+2]<0)
205 typ = -1;
206 else
207 i++;
208 }
209 return typ;
210}
211
212
213int r_IsRingVar(const char *n, char**names,int N)
214{
215 if (names!=NULL)
216 {
217 for (int i=0; i<N; i++)
218 {
219 if (names[i]==NULL) return -1;
220 if (strcmp(n,names[i]) == 0) return (int)i;
221 }
222 }
223 return -1;
224}
225
226
228{
229 if ((r==NULL)||(r->order==NULL))
230 return; /*to avoid printing after errors....*/
231
232 assume(r != NULL);
233 const coeffs C = r->cf;
234 assume(C != NULL);
235
236 int nblocks=rBlocks(r);
237
238 // omCheckAddrSize(r,sizeof(ip_sring));
239 omCheckAddrSize(r->order,nblocks*sizeof(int));
240 omCheckAddrSize(r->block0,nblocks*sizeof(int));
241 omCheckAddrSize(r->block1,nblocks*sizeof(int));
242 omCheckAddrSize(r->wvhdl,nblocks*sizeof(int *));
243 omCheckAddrSize(r->names,r->N*sizeof(char *));
244
245 nblocks--;
246
247
248 //Print("ref:%d, C->ref:%d\n",r->ref,C->ref);
249 PrintS("// coefficients: ");
250 if( nCoeff_is_algExt(C) )
251 {
252 // NOTE: the following (non-thread-safe!) UGLYNESS
253 // (changing naRing->ShortOut for a while) is due to Hans!
254 // Just think of other ring using the VERY SAME naRing and possible
255 // side-effects...
256 ring R = C->extRing;
257 const BOOLEAN bSaveShortOut = rShortOut(R); R->ShortOut = rShortOut(r) & rCanShortOut(R);
258
259 n_CoeffWrite(C, details); // for correct printing of minpoly... WHAT AN UGLYNESS!!!
260
261 R->ShortOut = bSaveShortOut;
262 }
263 else
265 PrintLn();
266// {
267// PrintS("// characteristic : ");
268//
269// char const * const * const params = rParameter(r);
270//
271// if (params!=NULL)
272// {
273// Print ("// %d parameter : ",rPar(r));
274//
275// char const * const * sp= params;
276// int nop=0;
277// while (nop<rPar(r))
278// {
279// PrintS(*sp);
280// PrintS(" ");
281// sp++; nop++;
282// }
283// PrintS("\n// minpoly : ");
284// if ( rField_is_long_C(r) )
285// {
286// // i^2+1:
287// Print("(%s^2+1)\n", params[0]);
288// }
289// else if (rMinpolyIsNULL(r))
290// {
291// PrintS("0\n");
292// }
293// else
294// {
295// StringSetS(""); n_Write(r->cf->minpoly, r); PrintS(StringEndS("\n")); // NOTE/TODO: use StringAppendS("\n"); omFree(s);
296// }
297// //if (r->qideal!=NULL)
298// //{
299// // iiWriteMatrix((matrix)r->qideal,"// minpolys",1,r,0);
300// // PrintLn();
301// //}
302// }
303// }
304 Print("// number of vars : %d",r->N);
305
306 //for (nblocks=0; r->order[nblocks]; nblocks++);
307 nblocks=rBlocks(r)-1;
308
309 for (int l=0, nlen=0 ; l<nblocks; l++)
310 {
311 int i=0;
312 Print("\n// block %3d : ",l+1);
313
314 Print("ordering %s", rSimpleOrdStr(r->order[l]));
315
316
317 if (r->order[l] == ringorder_IS)
318 {
319 assume( r->block0[l] == r->block1[l] );
320 const int s = r->block0[l];
321 assume( (-2 < s) && (s < 2) );
322 Print("(%d)", s); // 0 => prefix! +/-1 => suffix!
323 continue;
324 }
325 else if (r->order[l]==ringorder_s)
326 {
327 assume( l == 0 );
328 Print(" syz_comp: %d",r->block0[l]);
329 continue;
330 }
331 else if (
332 ( (r->order[l] >= ringorder_lp)
333 ||(r->order[l] == ringorder_M)
334 ||(r->order[l] == ringorder_a)
335 ||(r->order[l] == ringorder_am)
336 ||(r->order[l] == ringorder_a64)
337 ||(r->order[l] == ringorder_aa) ) && (r->order[l] < ringorder_IS) )
338 {
339 PrintS("\n// : names ");
340 for (i = r->block0[l]-1; i<r->block1[l]; i++)
341 {
342 nlen = strlen(r->names[i]);
343 Print(" %s",r->names[i]);
344 }
345 }
346
347 if (r->wvhdl[l]!=NULL)
348 {
349 #ifndef SING_NDEBUG
350 if((r->order[l] != ringorder_wp)
351 &&(r->order[l] != ringorder_Wp)
352 &&(r->order[l] != ringorder_ws)
353 &&(r->order[l] != ringorder_Ws)
354 &&(r->order[l] != ringorder_a)
355 &&(r->order[l] != ringorder_a64)
356 &&(r->order[l] != ringorder_am)
357 &&(r->order[l] != ringorder_M))
358 {
359 Warn("should not have wvhdl entry at pos. %d",l);
360 }
361 #endif
362 int bl=r->block1[l]-r->block0[l]+1;
363 for (int j= 0;
364 j<(r->block1[l]-r->block0[l]+1)*(r->block1[l]-r->block0[l]+1);
365 j+=bl)
366 {
367 PrintS("\n// : weights ");
368 for (i = 0; i<=r->block1[l]-r->block0[l]; i++)
369 {
370 if (r->order[l] == ringorder_a64)
371 {
372 int64 *w=(int64 *)r->wvhdl[l];
373 #if SIZEOF_LONG == 4
374 Print("%*lld " ,nlen,w[i+j]);
375 #else
376 Print(" %*ld" ,nlen,w[i+j]);
377 #endif
378 }
379 else
380 Print(" %*d" ,nlen,r->wvhdl[l][i+j]);
381 }
382 if (r->order[l]!=ringorder_M) break;
383 }
384 if (r->order[l]==ringorder_am)
385 {
386 int m=r->wvhdl[l][bl];
387 Print("\n// : %d module weights ",m);
388 m+=bl;i=bl+1;
389 for(;i<=m;i++) Print(" %*d" ,nlen,r->wvhdl[l][i]);
390 }
391 }
392 }
393#ifdef HAVE_PLURAL
394 if(rIsPluralRing(r))
395 {
396 PrintS("\n// noncommutative relations:");
397 if( details )
398 {
399 poly pl=NULL;
400 int nl;
401 int i,j;
402 for (i = 1; i<r->N; i++)
403 {
404 for (j = i+1; j<=r->N; j++)
405 {
406 nl = n_IsOne(p_GetCoeff(MATELEM(r->GetNC()->C,i,j),r), r->cf);
407 if ( (MATELEM(r->GetNC()->D,i,j)!=NULL) || (!nl) )
408 {
409 Print("\n// %s%s=",r->names[j-1],r->names[i-1]);
410 pl = MATELEM(r->GetNC()->MT[UPMATELEM(i,j,r->N)],1,1);
411 p_Write0(pl, r, r);
412 }
413 }
414 }
415 } else
416 PrintS(" ...");
417
418#if MYTEST /*Singularg should not differ from Singular except in error case*/
419 Print("\n// noncommutative type:%d", (int)ncRingType(r));
420 Print("\n// is skew constant:%d",r->GetNC()->IsSkewConstant);
421 if( rIsSCA(r) )
422 {
423 Print("\n// alternating variables: [%d, %d]", scaFirstAltVar(r), scaLastAltVar(r));
424 const ideal Q = SCAQuotient(r); // resides within r!
425 PrintS("\n// quotient of sca by ideal");
426
427 if (Q!=NULL)
428 {
429 iiWriteMatrix((matrix)Q,"scaQ",1,r,0);
430 }
431 else
432 PrintS(" (NULL)");
433 }
434#endif
435 }
436 if (rIsLPRing(r))
437 {
438 Print("\n// letterplace ring (block size %d, ncgen count %d)",r->isLPring, r->LPncGenCount);
439 }
440#endif
441 if (r->qideal!=NULL)
442 {
443 PrintS("\n// quotient ring from ideal");
444 if( details )
445 {
446 PrintLn();
447 iiWriteMatrix((matrix)r->qideal,"_",1,r,0);
448 } else PrintS(" ...");
449 }
450}
451
453{
454 int i, j;
455
456 if (r == NULL) return;
457 if( r->ref > 0 ) // ->ref means the number of Interpreter objects referring to the ring...
458 return;
459
460 if (r->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/paramter 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 return ((rVar(r) > 1) &&
2032 (((r->order[0]==ringorder_dp)&&(r->block1[0]==r->N)) ||
2033 ((r->order[1]==ringorder_dp)&&(r->block1[1]==r->N)&&((r->block0[1]==1)))));
2034}
2035
2037{
2038 return ((rVar(r) > 1) &&
2039 (((r->order[0]==ringorder_ds)&&(r->block1[0]==r->N)) ||
2040 ((r->order[1]==ringorder_ds)&&(r->block1[1]==r->N)&&((r->block0[1]==1)))));
2041}
2042
2043// return TRUE if p->exp[r->pOrdIndex] holds a weighted degree of p */
2045{
2046 // Hmm.... what about Syz orderings?
2047 return ((rVar(r) > 1) &&
2048 rHasSimpleOrder(r) &&
2051}
2052
2053#ifdef RDEBUG
2054// This should eventually become a full-fledge ring check, like pTest
2055BOOLEAN rDBTest(ring r, const char* fn, const int l)
2056{
2057 int i,j;
2058
2059 if (r == NULL)
2060 {
2061 dReportError("Null ring in %s:%d", fn, l);
2062 return FALSE;
2063 }
2064
2065
2066 if (r->N == 0) return TRUE;
2067
2068 if ((r->OrdSgn!=1) && (r->OrdSgn!= -1))
2069 {
2070 dReportError("missing OrdSgn in %s:%d", fn, l);
2071 return FALSE;
2072 }
2073
2074// omCheckAddrSize(r,sizeof(ip_sring));
2075#if OM_CHECK > 0
2076 i=rBlocks(r);
2077 omCheckAddrSize(r->order,i*sizeof(int));
2078 omCheckAddrSize(r->block0,i*sizeof(int));
2079 omCheckAddrSize(r->block1,i*sizeof(int));
2080 for(int j=0;j<=i;j++)
2081 {
2082 if((r->order[j]<0)||(r->order[j]>ringorder_unspec))
2083 dError("wrong order in r->order");
2084 }
2085 if (r->wvhdl!=NULL)
2086 {
2087 omCheckAddrSize(r->wvhdl,i*sizeof(int *));
2088 for (j=0;j<i; j++)
2089 {
2090 if (r->wvhdl[j] != NULL) omCheckAddr(r->wvhdl[j]);
2091 }
2092 }
2093#endif
2094 if (r->VarOffset == NULL)
2095 {
2096 dReportError("Null ring VarOffset -- no rComplete (?) in n %s:%d", fn, l);
2097 return FALSE;
2098 }
2099 omCheckAddrSize(r->VarOffset,(r->N+1)*sizeof(int));
2100
2101 if ((r->OrdSize==0)!=(r->typ==NULL))
2102 {
2103 dReportError("mismatch OrdSize and typ-pointer in %s:%d");
2104 return FALSE;
2105 }
2106 omcheckAddrSize(r->typ,r->OrdSize*sizeof(*(r->typ)));
2107 omCheckAddrSize(r->VarOffset,(r->N+1)*sizeof(*(r->VarOffset)));
2108 // test assumptions:
2109 for(i=0;i<=r->N;i++) // for all variables (i = 0..N)
2110 {
2111 if(r->typ!=NULL)
2112 {
2113 for(j=0;j<r->OrdSize;j++) // for all ordering blocks (j =0..OrdSize-1)
2114 {
2115 if(r->typ[j].ord_typ == ro_isTemp)
2116 {
2117 const int p = r->typ[j].data.isTemp.suffixpos;
2118
2119 if(p <= j)
2120 dReportError("ordrec prefix %d is unmatched",j);
2121
2122 assume( p < r->OrdSize );
2123
2124 if(r->typ[p].ord_typ != ro_is)
2125 dReportError("ordrec prefix %d is unmatched (suffix: %d is wrong!!!)",j, p);
2126
2127 // Skip all intermediate blocks for undone variables:
2128 if(r->typ[j].data.isTemp.pVarOffset[i] != -1) // Check i^th variable
2129 {
2130 j = p - 1; // SKIP ALL INTERNAL BLOCKS...???
2131 continue; // To make for check OrdSize bound...
2132 }
2133 }
2134 else if (r->typ[j].ord_typ == ro_is)
2135 {
2136 // Skip all intermediate blocks for undone variables:
2137 if(r->typ[j].data.is.pVarOffset[i] != -1)
2138 {
2139 // TODO???
2140 }
2141
2142 }
2143 else
2144 {
2145 if (r->typ[j].ord_typ==ro_cp)
2146 {
2147 if(((short)r->VarOffset[i]) == r->typ[j].data.cp.place)
2148 dReportError("ordrec %d conflicts with var %d",j,i);
2149 }
2150 else
2151 if ((r->typ[j].ord_typ!=ro_syzcomp)
2152 && (r->VarOffset[i] == r->typ[j].data.dp.place))
2153 dReportError("ordrec %d conflicts with var %d",j,i);
2154 }
2155 }
2156 }
2157 int tmp;
2158 tmp=r->VarOffset[i] & 0xffffff;
2159 #if SIZEOF_LONG == 8
2160 if ((r->VarOffset[i] >> 24) >63)
2161 #else
2162 if ((r->VarOffset[i] >> 24) >31)
2163 #endif
2164 dReportError("bit_start out of range:%d",r->VarOffset[i] >> 24);
2165 if (i > 0 && ((tmp<0) ||(tmp>r->ExpL_Size-1)))
2166 {
2167 dReportError("varoffset out of range for var %d: %d",i,tmp);
2168 }
2169 }
2170 if(r->typ!=NULL)
2171 {
2172 for(j=0;j<r->OrdSize;j++)
2173 {
2174 if ((r->typ[j].ord_typ==ro_dp)
2175 || (r->typ[j].ord_typ==ro_wp)
2176 || (r->typ[j].ord_typ==ro_wp_neg))
2177 {
2178 if (r->typ[j].data.dp.start > r->typ[j].data.dp.end)
2179 dReportError("in ordrec %d: start(%d) > end(%d)",j,
2180 r->typ[j].data.dp.start, r->typ[j].data.dp.end);
2181 if ((r->typ[j].data.dp.start < 1)
2182 || (r->typ[j].data.dp.end > r->N))
2183 dReportError("in ordrec %d: start(%d)<1 or end(%d)>vars(%d)",j,
2184 r->typ[j].data.dp.start, r->typ[j].data.dp.end,r->N);
2185 }
2186 }
2187 }
2188
2189 assume(r != NULL);
2190 assume(r->cf != NULL);
2191
2192 if (nCoeff_is_algExt(r->cf))
2193 {
2194 assume(r->cf->extRing != NULL);
2195 assume(r->cf->extRing->qideal != NULL);
2196 omCheckAddr(r->cf->extRing->qideal->m[0]);
2197 }
2198
2199 //assume(r->cf!=NULL);
2200
2201 return TRUE;
2202}
2203#endif
2204
2205static void rO_Align(int &place, int &bitplace)
2206{
2207 // increment place to the next aligned one
2208 // (count as Exponent_t,align as longs)
2210 {
2211 place++;
2213 }
2214}
2215
2216static void rO_TDegree(int &place, int &bitplace, int start, int end,
2217 long *o, sro_ord &ord_struct)
2218{
2219 // degree (aligned) of variables v_start..v_end, ordsgn 1
2220 rO_Align(place,bitplace);
2221 ord_struct.ord_typ=ro_dp;
2222 ord_struct.data.dp.start=start;
2223 ord_struct.data.dp.end=end;
2224 ord_struct.data.dp.place=place;
2225 o[place]=1;
2226 place++;
2227 rO_Align(place,bitplace);
2228}
2229
2230static void rO_TDegree_neg(int &place, int &bitplace, int start, int end,
2231 long *o, sro_ord &ord_struct)
2232{
2233 // degree (aligned) of variables v_start..v_end, ordsgn -1
2234 rO_Align(place,bitplace);
2235 ord_struct.ord_typ=ro_dp;
2236 ord_struct.data.dp.start=start;
2237 ord_struct.data.dp.end=end;
2238 ord_struct.data.dp.place=place;
2239 o[place]=-1;
2240 place++;
2241 rO_Align(place,bitplace);
2242}
2243
2244static void rO_WDegree(int &place, int &bitplace, int start, int end,
2245 long *o, sro_ord &ord_struct, int *weights)
2246{
2247 // weighted degree (aligned) of variables v_start..v_end, ordsgn 1
2248 while((start<end) && (weights[0]==0)) { start++; weights++; }
2249 while((start<end) && (weights[end-start]==0)) { end--; }
2250 int i;
2251 int pure_tdeg=1;
2252 for(i=start;i<=end;i++)
2253 {
2254 if(weights[i-start]!=1)
2255 {
2256 pure_tdeg=0;
2257 break;
2258 }
2259 }
2260 if (pure_tdeg)
2261 {
2262 rO_TDegree(place,bitplace,start,end,o,ord_struct);
2263 return;
2264 }
2265 rO_Align(place,bitplace);
2266 ord_struct.ord_typ=ro_wp;
2267 ord_struct.data.wp.start=start;
2268 ord_struct.data.wp.end=end;
2269 ord_struct.data.wp.place=place;
2270 ord_struct.data.wp.weights=weights;
2271 o[place]=1;
2272 place++;
2273 rO_Align(place,bitplace);
2274 for(i=start;i<=end;i++)
2275 {
2276 if(weights[i-start]<0)
2277 {
2278 ord_struct.ord_typ=ro_wp_neg;
2279 break;
2280 }
2281 }
2282}
2283
2284static void rO_WMDegree(int &place, int &bitplace, int start, int end,
2285 long *o, sro_ord &ord_struct, int *weights)
2286{
2287 assume(weights != NULL);
2288
2289 // weighted degree (aligned) of variables v_start..v_end, ordsgn 1
2290// while((start<end) && (weights[0]==0)) { start++; weights++; }
2291// while((start<end) && (weights[end-start]==0)) { end--; }
2292 rO_Align(place,bitplace);
2293 ord_struct.ord_typ=ro_am;
2294 ord_struct.data.am.start=start;
2295 ord_struct.data.am.end=end;
2296 ord_struct.data.am.place=place;
2297 ord_struct.data.am.weights=weights;
2298 ord_struct.data.am.weights_m = weights + (end-start+1);
2299 ord_struct.data.am.len_gen=weights[end-start+1];
2300 assume( ord_struct.data.am.weights_m[0] == ord_struct.data.am.len_gen );
2301 o[place]=1;
2302 place++;
2303 rO_Align(place,bitplace);
2304}
2305
2306static void rO_WDegree64(int &place, int &bitplace, int start, int end,
2307 long *o, sro_ord &ord_struct, int64 *weights)
2308{
2309 // weighted degree (aligned) of variables v_start..v_end, ordsgn 1,
2310 // reserved 2 places
2311 rO_Align(place,bitplace);
2312 ord_struct.ord_typ=ro_wp64;
2313 ord_struct.data.wp64.start=start;
2314 ord_struct.data.wp64.end=end;
2315 ord_struct.data.wp64.place=place;
2316 #ifdef HAVE_OMALLOC
2317 ord_struct.data.wp64.weights64=weights;
2318 #else
2319 int l=end-start+1;
2320 ord_struct.data.wp64.weights64=(int64*)omAlloc(l*sizeof(int64));
2321 for(int i=0;i<l;i++) ord_struct.data.wp64.weights64[i]=weights[i];
2322 #endif
2323 o[place]=1;
2324 place++;
2325 o[place]=1;
2326 place++;
2327 rO_Align(place,bitplace);
2328}
2329
2330static void rO_WDegree_neg(int &place, int &bitplace, int start, int end,
2331 long *o, sro_ord &ord_struct, int *weights)
2332{
2333 // weighted degree (aligned) of variables v_start..v_end, ordsgn -1
2334 while((start<end) && (weights[0]==0)) { start++; weights++; }
2335 while((start<end) && (weights[end-start]==0)) { end--; }
2336 rO_Align(place,bitplace);
2337 ord_struct.ord_typ=ro_wp;
2338 ord_struct.data.wp.start=start;
2339 ord_struct.data.wp.end=end;
2340 ord_struct.data.wp.place=place;
2341 ord_struct.data.wp.weights=weights;
2342 o[place]=-1;
2343 place++;
2344 rO_Align(place,bitplace);
2345 int i;
2346 for(i=start;i<=end;i++)
2347 {
2348 if(weights[i-start]<0)
2349 {
2350 ord_struct.ord_typ=ro_wp_neg;
2351 break;
2352 }
2353 }
2354}
2355
2356static void rO_LexVars(int &place, int &bitplace, int start, int end,
2357 int &prev_ord, long *o,int *v, int bits, int opt_var)
2358{
2359 // a block of variables v_start..v_end with lex order, ordsgn 1
2360 int k;
2361 int incr=1;
2362 if(prev_ord==-1) rO_Align(place,bitplace);
2363
2364 if (start>end)
2365 {
2366 incr=-1;
2367 }
2368 for(k=start;;k+=incr)
2369 {
2370 bitplace-=bits;
2371 if (bitplace < 0) { bitplace=BITS_PER_LONG-bits; place++; }
2372 o[place]=1;
2373 v[k]= place | (bitplace << 24);
2374 if (k==end) break;
2375 }
2376 prev_ord=1;
2377 if (opt_var!= -1)
2378 {
2379 assume((opt_var == end+1) ||(opt_var == end-1));
2380 if((opt_var != end+1) &&(opt_var != end-1)) WarnS("hier-2");
2382 bitplace-=bits;
2383 if (bitplace < 0)
2384 {
2386 return;
2387 }
2388 // there is enough space for the optional var
2389 v[opt_var]=place | (bitplace << 24);
2390 }
2391}
2392
2393static void rO_LexVars_neg(int &place, int &bitplace, int start, int end,
2394 int &prev_ord, long *o,int *v, int bits, int opt_var)
2395{
2396 // a block of variables v_start..v_end with lex order, ordsgn -1
2397 int k;
2398 int incr=1;
2399 if(prev_ord==1) rO_Align(place,bitplace);
2400
2401 if (start>end)
2402 {
2403 incr=-1;
2404 }
2405 for(k=start;;k+=incr)
2406 {
2407 bitplace-=bits;
2408 if (bitplace < 0) { bitplace=BITS_PER_LONG-bits; place++; }
2409 o[place]=-1;
2410 v[k]=place | (bitplace << 24);
2411 if (k==end) break;
2412 }
2413 prev_ord=-1;
2414// #if 0
2415 if (opt_var!= -1)
2416 {
2417 assume((opt_var == end+1) ||(opt_var == end-1));
2418 if((opt_var != end+1) &&(opt_var != end-1)) WarnS("hier-1");
2420 bitplace-=bits;
2421 if (bitplace < 0)
2422 {
2424 return;
2425 }
2426 // there is enough space for the optional var
2427 v[opt_var]=place | (bitplace << 24);
2428 }
2429// #endif
2430}
2431
2432static void rO_Syzcomp(int &place, int &bitplace, int &prev_ord,
2433 long *o, sro_ord &ord_struct)
2434{
2435 // ordering is derived from component number
2436 rO_Align(place,bitplace);
2437 ord_struct.ord_typ=ro_syzcomp;
2438 ord_struct.data.syzcomp.place=place;
2439 ord_struct.data.syzcomp.Components=NULL;
2440 ord_struct.data.syzcomp.ShiftedComponents=NULL;
2441 o[place]=1;
2442 prev_ord=1;
2443 place++;
2444 rO_Align(place,bitplace);
2445}
2446
2447static void rO_Syz(int &place, int &bitplace, int &prev_ord,
2448 int syz_comp, long *o, sro_ord &ord_struct)
2449{
2450 // ordering is derived from component number
2451 // let's reserve one Exponent_t for it
2452 if ((prev_ord== 1) || (bitplace!=BITS_PER_LONG))
2453 rO_Align(place,bitplace);
2454 ord_struct.ord_typ=ro_syz;
2455 ord_struct.data.syz.place=place;
2456 ord_struct.data.syz.limit=syz_comp;
2457 if (syz_comp>0)
2458 ord_struct.data.syz.syz_index = (int*) omAlloc0((syz_comp+1)*sizeof(int));
2459 else
2460 ord_struct.data.syz.syz_index = NULL;
2461 ord_struct.data.syz.curr_index = 1;
2462 o[place]= -1;
2463 prev_ord=-1;
2464 place++;
2465}
2466
2467#ifndef SING_NDEBUG
2468# define MYTEST 0
2469#else /* ifndef SING_NDEBUG */
2470# define MYTEST 0
2471#endif /* ifndef SING_NDEBUG */
2472
2473static void rO_ISPrefix(int &place, int &bitplace, int &prev_ord,
2474 long *o, int N, int *v, sro_ord &ord_struct)
2475{
2476 if ((prev_ord== 1) || (bitplace!=BITS_PER_LONG))
2477 rO_Align(place,bitplace);
2478 // since we add something afterwards - it's better to start with anew!?
2479
2480 ord_struct.ord_typ = ro_isTemp;
2481 ord_struct.data.isTemp.start = place;
2482 #ifdef HAVE_OMALLOC
2483 ord_struct.data.isTemp.pVarOffset = (int *)omMemDup(v);
2484 #else
2485 ord_struct.data.isTemp.pVarOffset = (int *)omAlloc((N+1)*sizeof(int));
2486 memcpy(ord_struct.data.isTemp.pVarOffset,v,(N+1)*sizeof(int));
2487 #endif
2488 ord_struct.data.isTemp.suffixpos = -1;
2489
2490 // We will act as rO_Syz on our own!!!
2491 // Here we allocate an exponent as a level placeholder
2492 o[place]= -1;
2493 prev_ord=-1;
2494 place++;
2495}
2496static void rO_ISSuffix(int &place, int &bitplace, int &prev_ord, long *o,
2497 int N, int *v, sro_ord *tmp_typ, int &typ_i, int sgn)
2498{
2499
2500 // Let's find previous prefix:
2501 int typ_j = typ_i - 1;
2502 while(typ_j >= 0)
2503 {
2504 if( tmp_typ[typ_j].ord_typ == ro_isTemp)
2505 break;
2506 typ_j --;
2507 }
2508
2509 assume( typ_j >= 0 );
2510
2511 if( typ_j < 0 ) // Found NO prefix!!! :(
2512 return;
2513
2514 assume( tmp_typ[typ_j].ord_typ == ro_isTemp );
2515
2516 // Get saved state:
2517 const int start = tmp_typ[typ_j].data.isTemp.start;
2518 int *pVarOffset = tmp_typ[typ_j].data.isTemp.pVarOffset;
2519
2520/*
2521 // shift up all blocks
2522 while(typ_j < (typ_i-1))
2523 {
2524 tmp_typ[typ_j] = tmp_typ[typ_j+1];
2525 typ_j++;
2526 }
2527 typ_j = typ_i - 1; // No increment for typ_i
2528*/
2529 tmp_typ[typ_j].data.isTemp.suffixpos = typ_i;
2530
2531 // Let's keep that dummy for now...
2532 typ_j = typ_i; // the typ to change!
2533 typ_i++; // Just for now...
2534
2535
2536 for( int i = 0; i <= N; i++ ) // Note [0] == component !!! No Skip?
2537 {
2538 // Was i-th variable allocated inbetween?
2539 if( v[i] != pVarOffset[i] )
2540 {
2541 pVarOffset[i] = v[i]; // Save for later...
2542 v[i] = -1; // Undo!
2543 assume( pVarOffset[i] != -1 );
2544 }
2545 else
2546 pVarOffset[i] = -1; // No change here...
2547 }
2548
2549 if( pVarOffset[0] != -1 )
2550 pVarOffset[0] &= 0x0fff;
2551
2553
2554
2555 ord_struct.ord_typ = ro_is;
2556 ord_struct.data.is.start = start;
2557 ord_struct.data.is.end = place;
2558 ord_struct.data.is.pVarOffset = pVarOffset;
2559
2560
2561 // What about component???
2562// if( v[0] != -1 ) // There is a component already...???
2563// if( o[ v[0] & 0x0fff ] == sgn )
2564// {
2565// pVarOffset[0] = -1; // NEVER USED Afterwards...
2566// return;
2567// }
2568
2569
2570 // Moreover: we need to allocate the module component (v[0]) here!
2571 if( v[0] == -1) // It's possible that there was module component v0 at the begining (before prefix)!
2572 {
2573 // Start with a whole long exponent
2574 if( bitplace != BITS_PER_LONG )
2575 rO_Align(place, bitplace);
2576
2579 assume(bitplace == 0);
2580 v[0] = place | (bitplace << 24); // Never mind whether pVarOffset[0] > 0!!!
2581 o[place] = sgn; // Singnum for component ordering
2582 prev_ord = sgn;
2583 }
2584}
2585
2586
2587static unsigned long rGetExpSize(unsigned long bitmask, int & bits)
2588{
2589 if (bitmask == 0)
2590 {
2591 bits=16; bitmask=0xffff;
2592 }
2593 else if (bitmask <= 1L)
2594 {
2595 bits=1; bitmask = 1L;
2596 }
2597 else if (bitmask <= 3L)
2598 {
2599 bits=2; bitmask = 3L;
2600 }
2601 else if (bitmask <= 7L)
2602 {
2603 bits=3; bitmask=7L;
2604 }
2605 else if (bitmask <= 0xfL)
2606 {
2607 bits=4; bitmask=0xfL;
2608 }
2609 else if (bitmask <= 0x1fL)
2610 {
2611 bits=5; bitmask=0x1fL;
2612 }
2613 else if (bitmask <= 0x3fL)
2614 {
2615 bits=6; bitmask=0x3fL;
2616 }
2617#if SIZEOF_LONG == 8
2618 else if (bitmask <= 0x7fL)
2619 {
2620 bits=7; bitmask=0x7fL; /* 64 bit longs only */
2621 }
2622#endif
2623 else if (bitmask <= 0xffL)
2624 {
2625 bits=8; bitmask=0xffL;
2626 }
2627#if SIZEOF_LONG == 8
2628 else if (bitmask <= 0x1ffL)
2629 {
2630 bits=9; bitmask=0x1ffL; /* 64 bit longs only */
2631 }
2632#endif
2633 else if (bitmask <= 0x3ffL)
2634 {
2635 bits=10; bitmask=0x3ffL;
2636 }
2637#if SIZEOF_LONG == 8
2638 else if (bitmask <= 0xfffL)
2639 {
2640 bits=12; bitmask=0xfff; /* 64 bit longs only */
2641 }
2642#endif
2643 else if (bitmask <= 0xffffL)
2644 {
2645 bits=16; bitmask=0xffffL;
2646 }
2647#if SIZEOF_LONG == 8
2648 else if (bitmask <= 0xfffffL)
2649 {
2650 bits=20; bitmask=0xfffffL; /* 64 bit longs only */
2651 }
2652 else if (bitmask <= 0xffffffffL)
2653 {
2654 bits=32; bitmask=0xffffffffL;
2655 }
2656 else if (bitmask <= 0x7fffffffffffffffL)
2657 {
2658 bits=63; bitmask=0x7fffffffffffffffL; /* for overflow tests*/
2659 }
2660 else
2661 {
2662 bits=63; bitmask=0x7fffffffffffffffL; /* for overflow tests*/
2663 }
2664#else
2665 else if (bitmask <= 0x7fffffff)
2666 {
2667 bits=31; bitmask=0x7fffffff; /* for overflow tests*/
2668 }
2669 else
2670 {
2671 bits=31; bitmask=0x7fffffffL; /* for overflow tests*/
2672 }
2673#endif
2674 return bitmask;
2675}
2676
2677/*2
2678* optimize rGetExpSize for a block of N variables, exp <=bitmask
2679*/
2680unsigned long rGetExpSize(unsigned long bitmask, int & bits, int N)
2681{
2682 bitmask =rGetExpSize(bitmask, bits);
2684 int bits1;
2685 loop
2686 {
2687 if (bits == BIT_SIZEOF_LONG-1)
2688 {
2689 bits = BIT_SIZEOF_LONG - 1;
2690 return LONG_MAX;
2691 }
2692 unsigned long bitmask1 =rGetExpSize(bitmask+1, bits1);
2694 if ((((N+vars_per_long-1)/vars_per_long) ==
2696 {
2698 bits=bits1;
2699 bitmask=bitmask1;
2700 }
2701 else
2702 {
2703 return bitmask; /* and bits */
2704 }
2705 }
2706}
2707
2708
2709/*2
2710 * create a copy of the ring r, which must be equivalent to currRing
2711 * used for std computations
2712 * may share data structures with currRing
2713 * DOES CALL rComplete
2714 */
2717 unsigned long exp_limit)
2718{
2719 assume (r != NULL );
2720 assume (exp_limit > 1);
2722
2723 int bits;
2725 BOOLEAN need_other_ring = (exp_limit != r->bitmask);
2726
2727 int iNeedInducedOrderingSetup = 0; ///< How many induced ordering block do we have?
2728
2729 int nblocks=rBlocks(r);
2731 int *block0=(int*)omAlloc0((nblocks+1)*sizeof(int));
2732 int *block1=(int*)omAlloc0((nblocks+1)*sizeof(int));
2733 int **wvhdl=(int**)omAlloc0((nblocks+1)*sizeof(int *));
2734
2735 int i=0;
2736 int j=0; /* i index in r, j index in res */
2737
2738 for( rRingOrder_t r_ord=r->order[i]; (r_ord != (rRingOrder_t)0) && (i < nblocks); j++, r_ord=r->order[++i])
2739 {
2741
2742 if (r->block0[i]==r->block1[i])
2743 {
2744 switch(r_ord)
2745 {
2746 case ringorder_wp:
2747 case ringorder_dp:
2748 case ringorder_Wp:
2749 case ringorder_Dp:
2751 break;
2752 case ringorder_Ws:
2753 case ringorder_Ds:
2754 case ringorder_ws:
2755 case ringorder_ds:
2757 break;
2758 default:
2759 break;
2760 }
2761 }
2762 switch(r_ord)
2763 {
2764 case ringorder_S:
2765 {
2766#ifndef SING_NDEBUG
2767 Warn("Error: unhandled ordering in rModifyRing: ringorder_S = [%d]", r_ord);
2768#endif
2769 order[j]=r_ord; /*r->order[i];*/
2770 break;
2771 }
2772 case ringorder_C:
2773 case ringorder_c:
2774 if (!try_omit_comp)
2775 {
2776 order[j]=r_ord; /*r->order[i]*/;
2777 }
2778 else
2779 {
2780 j--;
2784 }
2785 break;
2786 case ringorder_wp:
2787 case ringorder_dp:
2788 case ringorder_ws:
2789 case ringorder_ds:
2790 if(!omit_degree)
2791 {
2792 order[j]=r_ord; /*r->order[i]*/;
2793 }
2794 else
2795 {
2796 order[j]=ringorder_rs;
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_lp;
2816 }
2817 break;
2818 case ringorder_IS:
2819 {
2820 if (try_omit_comp)
2821 {
2822 // tried, but cannot omit component due to the ordering block [%d]: %d (ringorder_IS)", i, r_ord
2824 }
2825 order[j]=r_ord; /*r->order[i];*/
2827 break;
2828 }
2829 case ringorder_s:
2830 {
2831 assume((i == 0) && (j == 0));
2832 if (try_omit_comp)
2833 {
2834 // tried, but cannot omit component due to the ordering block [%d]: %d (ringorder_s)", i, r_ord
2836 }
2837 order[j]=r_ord; /*r->order[i];*/
2838 break;
2839 }
2840 default:
2841 order[j]=r_ord; /*r->order[i];*/
2842 break;
2843 }
2844 if (copy_block_index)
2845 {
2846 block0[j]=r->block0[i];
2847 block1[j]=r->block1[i];
2848 wvhdl[j]=r->wvhdl[i];
2849 }
2850
2851 // order[j]=ringorder_no; // done by omAlloc0
2852 }
2853 if(!need_other_ring)
2854 {
2855 omFreeSize(order,(nblocks+1)*sizeof(rRingOrder_t));
2856 omFreeSize(block0,(nblocks+1)*sizeof(int));
2857 omFreeSize(block1,(nblocks+1)*sizeof(int));
2858 omFreeSize(wvhdl,(nblocks+1)*sizeof(int *));
2859 return r;
2860 }
2862 *res = *r;
2863
2864#ifdef HAVE_PLURAL
2865 res->GetNC() = NULL;
2866#endif
2867
2868 // res->qideal, res->idroot ???
2869 res->wvhdl=wvhdl;
2870 res->order=order;
2871 res->block0=block0;
2872 res->block1=block1;
2873 res->bitmask=exp_limit;
2874 res->wanted_maxExp=r->wanted_maxExp;
2875 //int tmpref=r->cf->ref0;
2876 rComplete(res, 1);
2877 //r->cf->ref=tmpref;
2878
2879 // adjust res->pFDeg: if it was changed globally, then
2880 // it must also be changed for new ring
2881 if (r->pFDegOrig != res->pFDegOrig &&
2883 {
2884 // still might need adjustment for weighted orderings
2885 // and omit_degree
2886 res->firstwv = r->firstwv;
2887 res->firstBlockEnds = r->firstBlockEnds;
2888 res->pFDeg = res->pFDegOrig = p_WFirstTotalDegree;
2889 }
2890 if (omitted_degree)
2891 res->pLDeg = r->pLDegOrig;
2892
2893 rOptimizeLDeg(res); // also sets res->pLDegOrig
2894
2895 // set syzcomp
2896 if (res->typ != NULL)
2897 {
2898 if( res->typ[0].ord_typ == ro_syz) // "s" Always on [0] place!
2899 {
2900 res->typ[0] = r->typ[0]; // Copy struct!? + setup the same limit!
2901
2902 if (r->typ[0].data.syz.limit > 0)
2903 {
2904 res->typ[0].data.syz.syz_index
2905 = (int*) omAlloc((r->typ[0].data.syz.limit +1)*sizeof(int));
2906 memcpy(res->typ[0].data.syz.syz_index, r->typ[0].data.syz.syz_index,
2907 (r->typ[0].data.syz.limit +1)*sizeof(int));
2908 }
2909 }
2910
2912 {
2913 for(j = 0, i = 0; (i < nblocks) && (iNeedInducedOrderingSetup > 0); i++)
2914 if( res->typ[i].ord_typ == ro_is ) // Search for suffixes!
2915 {
2916 ideal F = idrHeadR(r->typ[i].data.is.F, r, res); // Copy F from r into res!
2917 assume(
2919 F, // WILL BE COPIED!
2920 r->typ[i].data.is.limit,
2921 j++
2922 )
2923 );
2924 id_Delete(&F, res);
2926 }
2927 } // Process all induced Ordering blocks! ...
2928 }
2929 // the special case: homog (omit_degree) and 1 block rs: that is global:
2930 // it comes from dp
2931 res->OrdSgn=r->OrdSgn;
2932
2933
2934#ifdef HAVE_PLURAL
2935 if (rIsPluralRing(r))
2936 {
2937 if ( nc_rComplete(r, res, false) ) // no qideal!
2938 {
2939#ifndef SING_NDEBUG
2940 WarnS("error in nc_rComplete");
2941#endif
2942 // cleanup?
2943
2944// rDelete(res);
2945// return r;
2946
2947 // just go on..
2948 }
2949
2950 if( rIsSCA(r) )
2951 {
2953 WarnS("error in sca_Force!");
2954 }
2955 }
2956#endif
2957
2958 return res;
2959}
2960
2961// construct Wp,C ring
2962ring rModifyRing_Wp(ring r, int* weights)
2963{
2965 *res = *r;
2966#ifdef HAVE_PLURAL
2967 res->GetNC() = NULL;
2968#endif
2969
2970 /*weights: entries for 3 blocks: NULL*/
2971 res->wvhdl = (int **)omAlloc0(3 * sizeof(int *));
2972 /*order: Wp,C,0*/
2973 res->order = (rRingOrder_t *) omAlloc(3 * sizeof(rRingOrder_t *));
2974 res->block0 = (int *)omAlloc0(3 * sizeof(int *));
2975 res->block1 = (int *)omAlloc0(3 * sizeof(int *));
2976 /* ringorder Wp for the first block: var 1..r->N */
2977 res->order[0] = ringorder_Wp;
2978 res->block0[0] = 1;
2979 res->block1[0] = r->N;
2980 res->wvhdl[0] = weights;
2981 /* ringorder C for the second block: no vars */
2982 res->order[1] = ringorder_C;
2983 /* the last block: everything is 0 */
2984 res->order[2] = (rRingOrder_t)0;
2985
2986 //int tmpref=r->cf->ref;
2987 rComplete(res, 1);
2988 //r->cf->ref=tmpref;
2989#ifdef HAVE_PLURAL
2990 if (rIsPluralRing(r))
2991 {
2992 if ( nc_rComplete(r, res, false) ) // no qideal!
2993 {
2994#ifndef SING_NDEBUG
2995 WarnS("error in nc_rComplete");
2996#endif
2997 // cleanup?
2998
2999// rDelete(res);
3000// return r;
3001
3002 // just go on..
3003 }
3004 }
3005#endif
3006 return res;
3007}
3008
3009// construct lp, C ring with r->N variables, r->names vars....
3011{
3012 simple=TRUE;
3013 if (!rHasSimpleOrder(r))
3014 {
3015 simple=FALSE; // sorting needed
3016 assume (r != NULL );
3017 assume (exp_limit > 1);
3018 int bits;
3019
3021
3022 int nblocks=1+(ommit_comp!=0);
3024 int *block0=(int*)omAlloc0((nblocks+1)*sizeof(int));
3025 int *block1=(int*)omAlloc0((nblocks+1)*sizeof(int));
3026 int **wvhdl=(int**)omAlloc0((nblocks+1)*sizeof(int *));
3027
3028 order[0]=ringorder_lp;
3029 block0[0]=1;
3030 block1[0]=r->N;
3031 if (!ommit_comp)
3032 {
3033 order[1]=ringorder_C;
3034 }
3036 *res = *r;
3037#ifdef HAVE_PLURAL
3038 res->GetNC() = NULL;
3039#endif
3040 // res->qideal, res->idroot ???
3041 res->wvhdl=wvhdl;
3042 res->order=order;
3043 res->block0=block0;
3044 res->block1=block1;
3045 res->bitmask=exp_limit;
3046 res->wanted_maxExp=r->wanted_maxExp;
3047 //int tmpref=r->cf->ref;
3048 rComplete(res, 1);
3049 //r->cf->ref=tmpref;
3050
3051#ifdef HAVE_PLURAL
3052 if (rIsPluralRing(r))
3053 {
3054 if ( nc_rComplete(r, res, false) ) // no qideal!
3055 {
3056#ifndef SING_NDEBUG
3057 WarnS("error in nc_rComplete");
3058#endif
3059 // cleanup?
3060
3061// rDelete(res);
3062// return r;
3063
3064 // just go on..
3065 }
3066 }
3067#endif
3068
3070
3071 return res;
3072 }
3074}
3075
3077{
3078 rUnComplete(r);
3079 omFree(r->order);
3080 omFree(r->block0);
3081 omFree(r->block1);
3082 omFree(r->wvhdl);
3084}
3085
3087{
3088 rUnComplete(r);
3089 omFree(r->order);
3090 omFree(r->block0);
3091 omFree(r->block1);
3092 omFree(r->wvhdl[0]);
3093 omFree(r->wvhdl);
3095}
3096
3097static void rSetOutParams(ring r)
3098{
3099 r->VectorOut = (r->order[0] == ringorder_c);
3100 if (rIsNCRing(r))
3101 r->CanShortOut=FALSE;
3102 else
3103 {
3104 r->CanShortOut = TRUE;
3105 int i;
3106 if (rParameter(r)!=NULL)
3107 {
3108 for (i=0;i<rPar(r);i++)
3109 {
3110 if(strlen(rParameter(r)[i])>1)
3111 {
3112 r->CanShortOut=FALSE;
3113 break;
3114 }
3115 }
3116 }
3117 if (r->CanShortOut)
3118 {
3119 int N = r->N;
3120 for (i=(N-1);i>=0;i--)
3121 {
3122 if(r->names[i] != NULL && strlen(r->names[i])>1)
3123 {
3124 r->CanShortOut=FALSE;
3125 break;
3126 }
3127 }
3128 }
3129 }
3130 r->ShortOut = r->CanShortOut;
3131
3132 assume( !( !r->CanShortOut && r->ShortOut ) );
3133}
3134
3135static void rSetFirstWv(ring r, int i, rRingOrder_t* order, int* block0, int* block1, int** wvhdl)
3136{
3137 // cheat for ringorder_aa
3138 if (order[i] == ringorder_aa)
3139 i++;
3140 if(block1[i]!=r->N) r->LexOrder=TRUE;
3141 r->firstBlockEnds=block1[i];
3142 r->firstwv = wvhdl[i];
3143 if ((order[i]== ringorder_ws)
3144 || (order[i]==ringorder_Ws)
3145 || (order[i]== ringorder_wp)
3146 || (order[i]==ringorder_Wp)
3147 || (order[i]== ringorder_a)
3148 /*|| (order[i]==ringorder_A)*/)
3149 {
3150 int j;
3151 for(j=block1[i]-block0[i];j>=0;j--)
3152 {
3153 if (r->firstwv[j]==0) r->LexOrder=TRUE;
3154 }
3155 }
3156 else if (order[i]==ringorder_a64)
3157 {
3158 int j;
3159 int64 *w=rGetWeightVec(r);
3160 for(j=block1[i]-block0[i];j>=0;j--)
3161 {
3162 if (w[j]==0) r->LexOrder=TRUE;
3163 }
3164 }
3165}
3166
3167static void rOptimizeLDeg(ring r)
3168{
3169 if (r->pFDeg == p_Deg)
3170 {
3171 if (r->pLDeg == pLDeg1)
3172 r->pLDeg = pLDeg1_Deg;
3173 if (r->pLDeg == pLDeg1c)
3174 r->pLDeg = pLDeg1c_Deg;
3175 }
3176 else if (r->pFDeg == p_Totaldegree)
3177 {
3178 if (r->pLDeg == pLDeg1)
3179 r->pLDeg = pLDeg1_Totaldegree;
3180 if (r->pLDeg == pLDeg1c)
3181 r->pLDeg = pLDeg1c_Totaldegree;
3182 }
3183 else if (r->pFDeg == p_WFirstTotalDegree)
3184 {
3185 if (r->pLDeg == pLDeg1)
3186 r->pLDeg = pLDeg1_WFirstTotalDegree;
3187 if (r->pLDeg == pLDeg1c)
3188 r->pLDeg = pLDeg1c_WFirstTotalDegree;
3189 }
3190 r->pLDegOrig = r->pLDeg;
3191}
3192
3193// set pFDeg, pLDeg, requires OrdSgn already set
3194static void rSetDegStuff(ring r)
3195{
3196 rRingOrder_t* order = r->order;
3197 int* block0 = r->block0;
3198 int* block1 = r->block1;
3199 int** wvhdl = r->wvhdl;
3200
3201 if (order[0]==ringorder_S ||order[0]==ringorder_s || order[0]==ringorder_IS)
3202 {
3203 order++;
3204 block0++;
3205 block1++;
3206 wvhdl++;
3207 }
3208 r->LexOrder = FALSE;
3209 r->pFDeg = p_Totaldegree;
3210 r->pLDeg = (r->OrdSgn == 1 ? pLDegb : pLDeg0);
3211
3212 /*======== ordering type is (am,_) ==================*/
3213 if (order[0]==ringorder_am)
3214 {
3215 for(int ii=block0[0];ii<=block1[0];ii++)
3216 if (wvhdl[0][ii-1]<0) { r->MixedOrder=2;break;}
3217 r->LexOrder=FALSE;
3218 for(int ii=block0[0];ii<=block1[0];ii++)
3219 if (wvhdl[0][ii-1]==0) { r->LexOrder=TRUE;break;}
3220 if ((block0[0]==1)&&(block1[0]==r->N))
3221 {
3222 r->pFDeg = p_Deg;
3223 r->pLDeg = pLDeg1c_Deg;
3224 }
3225 else
3226 {
3227 r->pFDeg = p_WTotaldegree;
3228 r->LexOrder=TRUE;
3229 r->pLDeg = pLDeg1c_WFirstTotalDegree;
3230 }
3231 r->firstwv = wvhdl[0];
3232 }
3233 /*======== ordering type is (_,c) =========================*/
3234 else if ((order[0]==ringorder_unspec) || (order[1] == 0)
3235 ||(
3236 ((order[1]==ringorder_c)||(order[1]==ringorder_C)
3237 ||(order[1]==ringorder_S)
3238 ||(order[1]==ringorder_s))
3239 && (order[0]!=ringorder_M)
3240 && (order[2]==0))
3241 )
3242 {
3243 if (r->OrdSgn == -1) r->pLDeg = pLDeg0c;
3244 if ((order[0] == ringorder_lp)
3245 || (order[0] == ringorder_ls)
3246 || (order[0] == ringorder_rp)
3247 || (order[0] == ringorder_rs))
3248 {
3249 r->LexOrder=TRUE;
3250 r->pLDeg = pLDeg1c;
3251 r->pFDeg = p_Totaldegree;
3252 }
3253 else if ((order[0] == ringorder_a)
3254 || (order[0] == ringorder_wp)
3255 || (order[0] == ringorder_Wp))
3256 {
3257 r->pFDeg = p_WFirstTotalDegree;
3258 }
3259 else if ((order[0] == ringorder_ws)
3260 || (order[0] == ringorder_Ws))
3261 {
3262 for(int ii=block0[0];ii<=block1[0];ii++)
3263 {
3264 if (wvhdl[0][ii-1]<0) { r->MixedOrder=2;break;}
3265 }
3266 if (r->MixedOrder==0)
3267 {
3268 if ((block0[0]==1)&&(block1[0]==r->N))
3269 r->pFDeg = p_WTotaldegree;
3270 else
3271 r->pFDeg = p_WFirstTotalDegree;
3272 }
3273 else
3274 r->pFDeg = p_Totaldegree;
3275 }
3276 r->firstBlockEnds=block1[0];
3277 r->firstwv = wvhdl[0];
3278 }
3279 /*======== ordering type is (c,_) =========================*/
3280 else if (((order[0]==ringorder_c)
3281 ||(order[0]==ringorder_C)
3282 ||(order[0]==ringorder_S)
3283 ||(order[0]==ringorder_s))
3284 && (order[1]!=ringorder_M)
3285 && (order[2]==0))
3286 {
3287 if ((order[1] == ringorder_lp)
3288 || (order[1] == ringorder_ls)
3289 || (order[1] == ringorder_rp)
3290 || order[1] == ringorder_rs)
3291 {
3292 r->LexOrder=TRUE;
3293 r->pLDeg = pLDeg1c;
3294 r->pFDeg = p_Totaldegree;
3295 }
3296 r->firstBlockEnds=block1[1];
3297 if (wvhdl!=NULL) r->firstwv = wvhdl[1];
3298 if ((order[1] == ringorder_a)
3299 || (order[1] == ringorder_wp)
3300 || (order[1] == ringorder_Wp))
3301 r->pFDeg = p_WFirstTotalDegree;
3302 else if ((order[1] == ringorder_ws)
3303 || (order[1] == ringorder_Ws))
3304 {
3305 for(int ii=block0[1];ii<=block1[1];ii++)
3306 if (wvhdl[1][ii-1]<0) { r->MixedOrder=2;break;}
3307 if (r->MixedOrder==FALSE)
3308 r->pFDeg = p_WFirstTotalDegree;
3309 else
3310 r->pFDeg = p_Totaldegree;
3311 }
3312 }
3313 /*------- more than one block ----------------------*/
3314 else
3315 {
3316 if ((r->VectorOut)||(order[0]==ringorder_C)||(order[0]==ringorder_S)||(order[0]==ringorder_s))
3317 {
3318 rSetFirstWv(r, 1, order, block0, block1, wvhdl);
3319 }
3320 else
3321 rSetFirstWv(r, 0, order, block0, block1, wvhdl);
3322
3323 if ((order[0]!=ringorder_c)
3324 && (order[0]!=ringorder_C)
3325 && (order[0]!=ringorder_S)
3326 && (order[0]!=ringorder_s))
3327 {
3328 r->pLDeg = pLDeg1c;
3329 }
3330 else
3331 {
3332 r->pLDeg = pLDeg1;
3333 }
3334 r->pFDeg = p_WTotaldegree; // may be improved: p_Totaldegree for lp/dp/ls/.. blocks
3335 }
3336
3339 {
3340 if(r->MixedOrder==FALSE)
3341 r->pFDeg = p_Deg;
3342 else
3343 r->pFDeg = p_Totaldegree;
3344 }
3345
3346 if( rGetISPos(0, r) != -1 ) // Are there Schreyer induced blocks?
3347 {
3348#ifndef SING_NDEBUG
3349 assume( r->pFDeg == p_Deg || r->pFDeg == p_WTotaldegree || r->pFDeg == p_Totaldegree);
3350#endif
3351
3352 r->pLDeg = pLDeg1; // ?
3353 }
3354
3355 r->pFDegOrig = r->pFDeg;
3356 // NOTE: this leads to wrong ecart during std
3357 // in Old/sre.tst
3358 rOptimizeLDeg(r); // also sets r->pLDegOrig
3359}
3360
3361/*2
3362* set NegWeightL_Size, NegWeightL_Offset
3363*/
3364static void rSetNegWeight(ring r)
3365{
3366 int i,l;
3367 if (r->typ!=NULL)
3368 {
3369 l=0;
3370 for(i=0;i<r->OrdSize;i++)
3371 {
3372 if((r->typ[i].ord_typ==ro_wp_neg)
3373 ||(r->typ[i].ord_typ==ro_am))
3374 l++;
3375 }
3376 if (l>0)
3377 {
3378 r->NegWeightL_Size=l;
3379 r->NegWeightL_Offset=(int *) omAlloc(l*sizeof(int));
3380 l=0;
3381 for(i=0;i<r->OrdSize;i++)
3382 {
3383 if(r->typ[i].ord_typ==ro_wp_neg)
3384 {
3385 r->NegWeightL_Offset[l]=r->typ[i].data.wp.place;
3386 l++;
3387 }
3388 else if(r->typ[i].ord_typ==ro_am)
3389 {
3390 r->NegWeightL_Offset[l]=r->typ[i].data.am.place;
3391 l++;
3392 }
3393 }
3394 return;
3395 }
3396 }
3397 r->NegWeightL_Size = 0;
3398 r->NegWeightL_Offset = NULL;
3399}
3400
3401static void rSetOption(ring r)
3402{
3403 // set redthrough
3404 if (!TEST_OPT_OLDSTD && r->OrdSgn == 1 && ! r->LexOrder)
3405 r->options |= Sy_bit(OPT_REDTHROUGH);
3406 else
3407 r->options &= ~Sy_bit(OPT_REDTHROUGH);
3408
3409 // set intStrategy
3410 if ( (r->cf->extRing!=NULL)
3411 || rField_is_Q(r)
3412 || rField_is_Ring(r)
3413 )
3414 r->options |= Sy_bit(OPT_INTSTRATEGY);
3415 else
3416 r->options &= ~Sy_bit(OPT_INTSTRATEGY);
3417
3418 // set redTail
3419 if (r->LexOrder || r->OrdSgn == -1 || (r->cf->extRing!=NULL))
3420 r->options &= ~Sy_bit(OPT_REDTAIL);
3421 else
3422 r->options |= Sy_bit(OPT_REDTAIL);
3423}
3424
3425static void rCheckOrdSgn(ring r,int i/*last block*/);
3426
3427/* -------------------------------------------------------- */
3428/*2
3429* change all global variables to fit the description of the new ring
3430*/
3431
3432void p_SetGlobals(const ring r, BOOLEAN complete)
3433{
3434 r->pLexOrder=r->LexOrder;
3435 if (complete)
3436 {
3438 si_opt_1 |= r->options;
3439 }
3440}
3441
3442static inline int sign(int x) { return (x > 0) - (x < 0);}
3444{
3445 int i;
3446 poly p=p_One(r);
3447 p_SetExp(p,1,1,r);
3448 p_Setm(p,r);
3449 int vz=sign(p_FDeg(p,r));
3450 for(i=2;i<=rVar(r);i++)
3451 {
3452 p_SetExp(p,i-1,0,r);
3453 p_SetExp(p,i,1,r);
3454 p_Setm(p,r);
3455 if (sign(p_FDeg(p,r))!=vz)
3456 {
3457 p_Delete(&p,r);
3458 return TRUE;
3459 }
3460 }
3461 p_Delete(&p,r);
3462 return FALSE;
3463}
3464
3466{
3467 if (r->VarOffset!=NULL && force == 0) return FALSE;
3468 rSetOutParams(r);
3469 int n=rBlocks(r)-1;
3470 int i;
3471 int bits;
3472 r->bitmask=rGetExpSize(r->wanted_maxExp,bits,r->N);
3473 r->BitsPerExp = bits;
3474 r->ExpPerLong = BIT_SIZEOF_LONG / bits;
3475 r->divmask=rGetDivMask(bits);
3476
3477 // will be used for ordsgn:
3478 long *tmp_ordsgn=(long *)omAlloc0(3*(n+r->N)*sizeof(long));
3479 // will be used for VarOffset:
3480 int *v=(int *)omAlloc((r->N+1)*sizeof(int));
3481 for(i=r->N; i>=0 ; i--)
3482 {
3483 v[i]=-1;
3484 }
3485 sro_ord *tmp_typ=(sro_ord *)omAlloc0(3*(n+r->N)*sizeof(sro_ord));
3486 int typ_i=0;
3487 int prev_ordsgn=0;
3488
3489 // fill in v, tmp_typ, tmp_ordsgn, determine typ_i (== ordSize)
3490 int j=0;
3492
3493 BOOLEAN need_to_add_comp=FALSE; // Only for ringorder_s and ringorder_S!
3494
3495 for(i=0;i<n;i++)
3496 {
3497 tmp_typ[typ_i].order_index=i;
3498 switch (r->order[i])
3499 {
3500 case ringorder_a:
3501 case ringorder_aa:
3502 rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,tmp_typ[typ_i],
3503 r->wvhdl[i]);
3504 typ_i++;
3505 break;
3506
3507 case ringorder_am:
3508 rO_WMDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,tmp_typ[typ_i],
3509 r->wvhdl[i]);
3510 typ_i++;
3511 break;
3512
3513 case ringorder_a64:
3514 rO_WDegree64(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3515 tmp_typ[typ_i], (int64 *)(r->wvhdl[i]));
3516 typ_i++;
3517 break;
3518
3519 case ringorder_c:
3520 rO_Align(j, j_bits);
3522 r->ComponentOrder=1;
3523 break;
3524
3525 case ringorder_C:
3526 rO_Align(j, j_bits);
3528 r->ComponentOrder=-1;
3529 break;
3530
3531 case ringorder_M:
3532 {
3533 int k,l;
3534 k=r->block1[i]-r->block0[i]+1; // number of vars
3535 for(l=0;l<k;l++)
3536 {
3537 rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3538 tmp_typ[typ_i],
3539 r->wvhdl[i]+(r->block1[i]-r->block0[i]+1)*l);
3540 typ_i++;
3541 }
3542 break;
3543 }
3544
3545 case ringorder_lp:
3546 rO_LexVars(j, j_bits, r->block0[i],r->block1[i], prev_ordsgn,
3547 tmp_ordsgn,v,bits, -1);
3548 break;
3549
3550 case ringorder_ls:
3551 rO_LexVars_neg(j, j_bits, r->block0[i],r->block1[i], prev_ordsgn,
3552 tmp_ordsgn,v, bits, -1);
3553 break;
3554
3555 case ringorder_is:
3556 rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i], prev_ordsgn,
3557 tmp_ordsgn,v, bits, -1);
3558 break;
3559
3560 case ringorder_ip:
3561 rO_LexVars(j, j_bits, r->block1[i],r->block0[i], prev_ordsgn,
3562 tmp_ordsgn,v, bits, -1);
3563 break;
3564
3565 case ringorder_dp:
3566 if (r->block0[i]==r->block1[i])
3567 {
3568 rO_LexVars(j, j_bits, r->block0[i],r->block0[i], prev_ordsgn,
3569 tmp_ordsgn,v, bits, -1);
3570 }
3571 else
3572 {
3573 rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3574 tmp_typ[typ_i]);
3575 typ_i++;
3576 rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i]+1,
3577 prev_ordsgn,tmp_ordsgn,v,bits, r->block0[i]);
3578 }
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(j, j_bits, r->block0[i],r->block1[i]-1, prev_ordsgn,
3593 tmp_ordsgn,v, bits, r->block1[i]);
3594 }
3595 break;
3596
3597 case ringorder_Ip:
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->block1[i],r->block0[i], prev_ordsgn,
3609 tmp_ordsgn,v, bits, -1);
3610 }
3611 break;
3612
3613 case ringorder_ds:
3614 if (r->block0[i]==r->block1[i])
3615 {
3616 rO_LexVars_neg(j, j_bits,r->block0[i],r->block1[i],prev_ordsgn,
3617 tmp_ordsgn,v,bits, -1);
3618 }
3619 else
3620 {
3621 rO_TDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3622 tmp_typ[typ_i]);
3623 typ_i++;
3624 rO_LexVars_neg(j, j_bits, r->block1[i],r->block0[i]+1,
3625 prev_ordsgn,tmp_ordsgn,v,bits, r->block0[i]);
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->block0[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(j, j_bits, r->block0[i],r->block1[i]-1, prev_ordsgn,
3641 tmp_ordsgn,v, bits, r->block1[i]);
3642 }
3643 break;
3644
3645 case ringorder_wp:
3646 rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3647 tmp_typ[typ_i], r->wvhdl[i]);
3648 typ_i++;
3649 { // check for weights <=0
3650 int jj;
3652 for(jj=r->block1[i]-r->block0[i];jj>=0; jj--)
3653 {
3654 if (r->wvhdl[i][jj]<=0) have_bad_weights=TRUE;
3655 }
3656 if (have_bad_weights)
3657 {
3658 rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3659 tmp_typ[typ_i]);
3660 typ_i++;
3661 }
3662 }
3663 if (r->block1[i]!=r->block0[i])
3664 {
3665 rO_LexVars_neg(j, j_bits,r->block1[i],r->block0[i]+1, prev_ordsgn,
3666 tmp_ordsgn, v,bits, r->block0[i]);
3667 }
3668 break;
3669
3670 case ringorder_Wp:
3671 rO_WDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3672 tmp_typ[typ_i], r->wvhdl[i]);
3673 typ_i++;
3674 { // check for weights <=0
3675 int jj;
3677 for(jj=r->block1[i]-r->block0[i];jj>=0; jj--)
3678 {
3679 if (r->wvhdl[i][jj]<=0) have_bad_weights=TRUE;
3680 }
3681 if (have_bad_weights)
3682 {
3683 rO_TDegree(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3684 tmp_typ[typ_i]);
3685 typ_i++;
3686 }
3687 }
3688 if (r->block1[i]!=r->block0[i])
3689 {
3690 rO_LexVars(j, j_bits,r->block0[i],r->block1[i]-1, prev_ordsgn,
3691 tmp_ordsgn,v, bits, r->block1[i]);
3692 }
3693 break;
3694
3695 case ringorder_ws:
3696 rO_WDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3697 tmp_typ[typ_i], r->wvhdl[i]);
3698 typ_i++;
3699 if (r->block1[i]!=r->block0[i])
3700 {
3701 rO_LexVars_neg(j, j_bits,r->block1[i],r->block0[i]+1, prev_ordsgn,
3702 tmp_ordsgn, v,bits, r->block0[i]);
3703 }
3704 break;
3705
3706 case ringorder_Ws:
3707 rO_WDegree_neg(j,j_bits,r->block0[i],r->block1[i],tmp_ordsgn,
3708 tmp_typ[typ_i], r->wvhdl[i]);
3709 typ_i++;
3710 if (r->block1[i]!=r->block0[i])
3711 {
3712 rO_LexVars(j, j_bits,r->block0[i],r->block1[i]-1, prev_ordsgn,
3713 tmp_ordsgn,v, bits, r->block1[i]);
3714 }
3715 break;
3716
3717 case ringorder_S:
3718 assume(typ_i == 1); // For LaScala3 only: on the 2nd place ([1])!
3719 // TODO: for K[x]: it is 0...?!
3722 r->ComponentOrder=-1;
3723 typ_i++;
3724 break;
3725
3726 case ringorder_s:
3727 assume(typ_i == 0 && j == 0);
3728 rO_Syz(j, j_bits, prev_ordsgn, r->block0[i], tmp_ordsgn, tmp_typ[typ_i]); // set syz-limit?
3730 r->ComponentOrder=-1;
3731 typ_i++;
3732 break;
3733
3734 case ringorder_IS:
3735 {
3736
3737 assume( r->block0[i] == r->block1[i] );
3738 const int s = r->block0[i];
3739 assume( -2 < s && s < 2);
3740
3741 if(s == 0) // Prefix IS
3742 rO_ISPrefix(j, j_bits, prev_ordsgn, tmp_ordsgn, r->N, v, tmp_typ[typ_i++]); // What about prev_ordsgn?
3743 else // s = +1 or -1 // Note: typ_i might be incremented here inside!
3744 {
3745 rO_ISSuffix(j, j_bits, prev_ordsgn, tmp_ordsgn, r->N, v, tmp_typ, typ_i, s); // Suffix.
3747 }
3748
3749 break;
3750 }
3751 case ringorder_unspec:
3752 case ringorder_no:
3753 default:
3754 dReportError("undef. ringorder used\n");
3755 break;
3756 }
3757 }
3758 rCheckOrdSgn(r,n-1);
3759
3760 int j0=j; // save j
3761 int j_bits0=j_bits; // save jbits
3762 rO_Align(j,j_bits);
3763 r->CmpL_Size = j;
3764
3765 j_bits=j_bits0; j=j0;
3766
3767 // fill in some empty slots with variables not already covered
3768 // v0 is special, is therefore normally already covered
3769 // now we do have rings without comp...
3770 if((need_to_add_comp) && (v[0]== -1))
3771 {
3772 if (prev_ordsgn==1)
3773 {
3774 rO_Align(j, j_bits);
3776 }
3777 else
3778 {
3779 rO_Align(j, j_bits);
3781 }
3782 }
3783 // the variables
3784 for(i=1 ; i<=r->N ; i++)
3785 {
3786 if(v[i]==(-1))
3787 {
3788 if (prev_ordsgn==1)
3789 {
3791 }
3792 else
3793 {
3795 }
3796 }
3797 }
3798
3799 rO_Align(j,j_bits);
3800 // ----------------------------
3801 // finished with constructing the monomial, computing sizes:
3802
3803 r->ExpL_Size=j;
3804 r->PolyBin = omGetSpecBin(POLYSIZE + (r->ExpL_Size)*sizeof(long));
3805 assume(r->PolyBin != NULL);
3806
3807 // ----------------------------
3808 // indices and ordsgn vector for comparison
3809 //
3810 // r->pCompHighIndex already set
3811 r->ordsgn=(long *)omAlloc0(r->ExpL_Size*sizeof(long));
3812
3813 for(j=0;j<r->CmpL_Size;j++)
3814 {
3815 r->ordsgn[j] = tmp_ordsgn[j];
3816 }
3817
3818 omFreeSize((ADDRESS)tmp_ordsgn,(3*(n+r->N)*sizeof(long)));
3819
3820 // ----------------------------
3821 // description of orderings for setm:
3822 //
3823 r->OrdSize=typ_i;
3824 if (typ_i==0) r->typ=NULL;
3825 else
3826 {
3827 r->typ=(sro_ord*)omAlloc(typ_i*sizeof(sro_ord));
3828 memcpy(r->typ,tmp_typ,typ_i*sizeof(sro_ord));
3829 }
3830 omFreeSize((ADDRESS)tmp_typ,(3*(n+r->N)*sizeof(sro_ord)));
3831
3832 // ----------------------------
3833 // indices for (first copy of ) variable entries in exp.e vector (VarOffset):
3834 r->VarOffset=v;
3835
3836 // ----------------------------
3837 // other indicies
3838 r->pCompIndex=(r->VarOffset[0] & 0xffff); //r->VarOffset[0];
3839 i=0; // position
3840 j=0; // index in r->typ
3841 if (i==r->pCompIndex) i++; // IS???
3842 while ((j < r->OrdSize)
3843 && ((r->typ[j].ord_typ==ro_syzcomp) ||
3844 (r->typ[j].ord_typ==ro_syz) || (r->typ[j].ord_typ==ro_isTemp) || (r->typ[j].ord_typ==ro_is) ||
3845 (r->order[r->typ[j].order_index] == ringorder_aa)))
3846 {
3847 i++; j++;
3848 }
3849
3850 if (i==r->pCompIndex) i++;
3851 r->pOrdIndex=i;
3852
3853 // ----------------------------
3854 rSetDegStuff(r); // OrdSgn etc already set
3855 rSetOption(r);
3856 // ----------------------------
3857 // r->p_Setm
3858 r->p_Setm = p_GetSetmProc(r);
3859
3860 // ----------------------------
3861 // set VarL_*
3862 rSetVarL(r);
3863
3864 // ----------------------------
3865 // right-adjust VarOffset
3867
3868 // ----------------------------
3869 // set NegWeightL*
3870 rSetNegWeight(r);
3871
3872 // ----------------------------
3873 // p_Procs: call AFTER NegWeightL
3874 r->p_Procs = (p_Procs_s*)omAlloc(sizeof(p_Procs_s));
3875 p_ProcsSet(r, r->p_Procs);
3876
3877 // use totaldegree on crazy oderings:
3878 if ((r->pFDeg==p_WTotaldegree) && rOrd_is_MixedDegree_Ordering(r))
3879 r->pFDeg = p_Totaldegree;
3880 return FALSE;
3881}
3882
3883static void rCheckOrdSgn(ring r,int b/*last block*/)
3884{ // set r->OrdSgn, r->MixedOrder
3885 // for each variable:
3886 int nonpos=0;
3887 int nonneg=0;
3888 for(int i=1;i<=r->N;i++)
3889 {
3890 int found=0;
3891 // for all blocks:
3892 for(int j=0;(j<=b) && (found==0);j++)
3893 {
3894 // search the first block containing var(i)
3895 if ((r->block0[j]<=i)&&(r->block1[j]>=i))
3896 {
3897 // what kind if block is it?
3898 if ((r->order[j]==ringorder_ls)
3899 || (r->order[j]==ringorder_ds)
3900 || (r->order[j]==ringorder_Ds)
3901 || (r->order[j]==ringorder_ws)
3902 || (r->order[j]==ringorder_Ws)
3903 || (r->order[j]==ringorder_rs))
3904 {
3905 r->OrdSgn=-1;
3906 nonpos++;
3907 found=1;
3908 }
3909 else if((r->order[j]==ringorder_a)
3910 ||(r->order[j]==ringorder_aa))
3911 {
3912 // <0: local/mixed ordering
3913 // >0: var(i) is okay, look at other vars
3914 // ==0: look at other blocks for var(i)
3915 if(r->wvhdl[j][i-r->block0[j]]<0)
3916 {
3917 r->OrdSgn=-1;
3918 nonpos++;
3919 found=1;
3920 }
3921 else if(r->wvhdl[j][i-r->block0[j]]>0)
3922 {
3923 nonneg++;
3924 found=1;
3925 }
3926 }
3927 else if(r->order[j]==ringorder_M)
3928 {
3929 // <0: local/mixed ordering
3930 // >0: var(i) is okay, look at other vars
3931 // ==0: look at other blocks for var(i)
3932 if(r->wvhdl[j][i-r->block0[j]]<0)
3933 {
3934 r->OrdSgn=-1;
3935 nonpos++;
3936 found=1;
3937 }
3938 else if(r->wvhdl[j][i-r->block0[j]]>0)
3939 {
3940 nonneg++;
3941 found=1;
3942 }
3943 else
3944 {
3945 // very bad: try next row(s)
3946 int add=r->block1[j]-r->block0[j]+1;
3947 int max_i=r->block0[j]+add*add-add-1;
3948 while(found==0)
3949 {
3950 i+=add;
3951 if (r->wvhdl[j][i-r->block0[j]]<0)
3952 {
3953 r->OrdSgn=-1;
3954 nonpos++;
3955 found=1;
3956 }
3957 else if(r->wvhdl[j][i-r->block0[j]]>0)
3958 {
3959 nonneg++;
3960 found=1;
3961 }
3962 else if(i>max_i)
3963 {
3964 nonpos++;
3965 nonneg++;
3966 found=1;
3967 }
3968 }
3969 }
3970 }
3971 else if ((r->order[j]==ringorder_lp)
3972 || (r->order[j]==ringorder_dp)
3973 || (r->order[j]==ringorder_Dp)
3974 || (r->order[j]==ringorder_wp)
3975 || (r->order[j]==ringorder_Wp)
3976 || (r->order[j]==ringorder_rp))
3977 {
3978 found=1;
3979 nonneg++;
3980 }
3981 }
3982 }
3983 }
3984 if (nonpos>0)
3985 {
3986 r->OrdSgn=-1;
3987 if (nonneg>0) r->MixedOrder=1;
3988 }
3989 else
3990 {
3991 r->OrdSgn=1;
3992 r->MixedOrder=0;
3993 }
3994}
3995
3997{
3998 if (r == NULL) return;
3999 if (r->VarOffset != NULL)
4000 {
4001 if (r->OrdSize!=0 && r->typ != NULL)
4002 {
4003 for(int i = 0; i < r->OrdSize; i++)
4004 if( r->typ[i].ord_typ == ro_is) // Search for suffixes! (prefix have the same VarOffset)
4005 {
4006 id_Delete(&r->typ[i].data.is.F, r);
4007
4008 if( r->typ[i].data.is.pVarOffset != NULL )
4009 {
4010 omFreeSize((ADDRESS)r->typ[i].data.is.pVarOffset, (r->N +1)*sizeof(int));
4011 }
4012 }
4013 else if (r->typ[i].ord_typ == ro_syz)
4014 {
4015 if(r->typ[i].data.syz.limit > 0)
4016 omFreeSize(r->typ[i].data.syz.syz_index, ((r->typ[i].data.syz.limit) +1)*sizeof(int));
4017 }
4018 else if (r->typ[i].ord_typ == ro_syzcomp)
4019 {
4020 assume( r->typ[i].data.syzcomp.ShiftedComponents == NULL );
4021 assume( r->typ[i].data.syzcomp.Components == NULL );
4022// WarnS( "rUnComplete : ord_typ == ro_syzcomp was unhandled!!! Possibly memory leak!!!" );
4023#ifndef SING_NDEBUG
4024// assume(0);
4025#endif
4026 }
4027
4028 omFreeSize((ADDRESS)r->typ,r->OrdSize*sizeof(sro_ord)); r->typ = NULL;
4029 }
4030
4031 if (r->PolyBin != NULL)
4032 omUnGetSpecBin(&(r->PolyBin));
4033
4034 omFreeSize((ADDRESS)r->VarOffset, (r->N +1)*sizeof(int));
4035 r->VarOffset=NULL;
4036
4037 if (r->ordsgn != NULL && r->CmpL_Size != 0)
4038 {
4039 omFreeSize((ADDRESS)r->ordsgn,r->ExpL_Size*sizeof(long));
4040 r->ordsgn=NULL;
4041 }
4042 if (r->p_Procs != NULL)
4043 {
4044 omFreeSize(r->p_Procs, sizeof(p_Procs_s));
4045 r->p_Procs=NULL;
4046 }
4047 omfreeSize(r->VarL_Offset, r->VarL_Size*sizeof(int));
4048 r->VarL_Offset=NULL;
4049 }
4050 if (r->NegWeightL_Offset!=NULL)
4051 {
4052 omFreeSize(r->NegWeightL_Offset, r->NegWeightL_Size*sizeof(int));
4053 r->NegWeightL_Offset=NULL;
4054 }
4055}
4056
4057// set r->VarL_Size, r->VarL_Offset, r->VarL_LowIndex
4058static void rSetVarL(ring r)
4059{
4060 int min = INT_MAX, min_j = -1;
4061 int* VarL_Number = (int*) omAlloc0(r->ExpL_Size*sizeof(int));
4062
4063 int i,j;
4064
4065 // count how often a var long is occupied by an exponent
4066 for (i=1; i<=r->N; i++)
4067 {
4068 VarL_Number[r->VarOffset[i] & 0xffffff]++;
4069 }
4070
4071 // determine how many and min
4072 for (i=0, j=0; i<r->ExpL_Size; i++)
4073 {
4074 if (VarL_Number[i] != 0)
4075 {
4076 if (min > VarL_Number[i])
4077 {
4078 min = VarL_Number[i];
4079 min_j = j;
4080 }
4081 j++;
4082 }
4083 }
4084
4085 r->VarL_Size = j; // number of long with exp. entries in
4086 // in p->exp
4087 r->VarL_Offset = (int*) omAlloc(r->VarL_Size*sizeof(int));
4088 r->VarL_LowIndex = 0;
4089
4090 // set VarL_Offset
4091 for (i=0, j=0; i<r->ExpL_Size; i++)
4092 {
4093 if (VarL_Number[i] != 0)
4094 {
4095 r->VarL_Offset[j] = i;
4096 if (j > 0 && r->VarL_Offset[j-1] != r->VarL_Offset[j] - 1)
4097 r->VarL_LowIndex = -1;
4098 j++;
4099 }
4100 }
4101 if (r->VarL_LowIndex >= 0)
4102 r->VarL_LowIndex = r->VarL_Offset[0];
4103
4104 if (min_j != 0)
4105 {
4106 j = r->VarL_Offset[min_j];
4107 r->VarL_Offset[min_j] = r->VarL_Offset[0];
4108 r->VarL_Offset[0] = j;
4109 }
4111}
4112
4114{
4115 int* shifts = (int*) omAlloc(r->ExpL_Size*sizeof(int));
4116 int i;
4117 // initialize shifts
4118 for (i=0;i<r->ExpL_Size;i++)
4120
4121 // find minimal bit shift in each long exp entry
4122 for (i=1;i<=r->N;i++)
4123 {
4124 if (shifts[r->VarOffset[i] & 0xffffff] > r->VarOffset[i] >> 24)
4125 shifts[r->VarOffset[i] & 0xffffff] = r->VarOffset[i] >> 24;
4126 }
4127 // reset r->VarOffset: set the minimal shift to 0
4128 for (i=1;i<=r->N;i++)
4129 {
4130 if (shifts[r->VarOffset[i] & 0xffffff] != 0)
4131 r->VarOffset[i]
4132 = (r->VarOffset[i] & 0xffffff) |
4133 (((r->VarOffset[i] >> 24) - shifts[r->VarOffset[i] & 0xffffff]) << 24);
4134 }
4135 omFree(shifts);
4136}
4137
4138// get r->divmask depending on bits per exponent
4139static unsigned long rGetDivMask(int bits)
4140{
4141 unsigned long divmask = 1;
4142 int i = bits;
4143
4144 while (i < BIT_SIZEOF_LONG)
4145 {
4146 divmask |= (((unsigned long) 1) << (unsigned long) i);
4147 i += bits;
4148 }
4149 return divmask;
4150}
4151
4152#ifdef RDEBUG
4153void rDebugPrint(const ring r)
4154{
4155 if (r==NULL)
4156 {
4157 PrintS("NULL ?\n");
4158 return;
4159 }
4160 // corresponds to ro_typ from ring.h:
4161 const char *TYP[]={"ro_dp","ro_wp","ro_am","ro_wp64","ro_wp_neg","ro_cp",
4162 "ro_syzcomp", "ro_syz", "ro_isTemp", "ro_is", "ro_none"};
4163 int i,j;
4164
4165 Print("ExpL_Size:%d ",r->ExpL_Size);
4166 Print("CmpL_Size:%d ",r->CmpL_Size);
4167 Print("VarL_Size:%d\n",r->VarL_Size);
4168 Print("bitmask=0x%lx (expbound=%ld) \n",r->bitmask, r->bitmask);
4169 Print("divmask=%lx\n", r->divmask);
4170 Print("BitsPerExp=%d ExpPerLong=%d at L[%d]\n", r->BitsPerExp, r->ExpPerLong, r->VarL_Offset[0]);
4171
4172 Print("VarL_LowIndex: %d\n", r->VarL_LowIndex);
4173 PrintS("VarL_Offset:\n");
4174 if (r->VarL_Offset==NULL) PrintS(" NULL");
4175 else
4176 for(j = 0; j < r->VarL_Size; j++)
4177 Print(" VarL_Offset[%d]: %d ", j, r->VarL_Offset[j]);
4178 PrintLn();
4179
4180
4181 PrintS("VarOffset:\n");
4182 if (r->VarOffset==NULL) PrintS(" NULL\n");
4183 else
4184 for(j=0;j<=r->N;j++)
4185 Print(" v%d at e-pos %d, bit %d\n",
4186 j,r->VarOffset[j] & 0xffffff, r->VarOffset[j] >>24);
4187 PrintS("ordsgn:\n");
4188 for(j=0;j<r->CmpL_Size;j++)
4189 Print(" ordsgn %ld at pos %d\n",r->ordsgn[j],j);
4190 Print("OrdSgn:%d\n",r->OrdSgn);
4191 PrintS("ordrec:\n");
4192 for(j=0;j<r->OrdSize;j++)
4193 {
4194 Print(" typ %s", TYP[r->typ[j].ord_typ]);
4195 if (r->typ[j].ord_typ==ro_syz)
4196 {
4197 const short place = r->typ[j].data.syz.place;
4198 const int limit = r->typ[j].data.syz.limit;
4199 const int curr_index = r->typ[j].data.syz.curr_index;
4200 const int* syz_index = r->typ[j].data.syz.syz_index;
4201
4202 Print(" limit %d (place: %d, curr_index: %d), syz_index: ", limit, place, curr_index);
4203
4204 if( syz_index == NULL )
4205 PrintS("(NULL)");
4206 else
4207 {
4208 PrintS("{");
4209 for( i=0; i <= limit; i++ )
4210 Print("%d ", syz_index[i]);
4211 PrintS("}");
4212 }
4213
4214 }
4215 else if (r->typ[j].ord_typ==ro_isTemp)
4216 {
4217 Print(" start (level) %d, suffixpos: %d, VO: ",r->typ[j].data.isTemp.start, r->typ[j].data.isTemp.suffixpos);
4218
4219 }
4220 else if (r->typ[j].ord_typ==ro_is)
4221 {
4222 Print(" start %d, end: %d: ",r->typ[j].data.is.start, r->typ[j].data.is.end);
4223
4224// 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]);
4225
4226 Print(" limit %d",r->typ[j].data.is.limit);
4227#ifndef SING_NDEBUG
4228 //PrintS(" F: ");idShow(r->typ[j].data.is.F, r, r, 1);
4229#endif
4230
4231 PrintLn();
4232 }
4233 else if (r->typ[j].ord_typ==ro_am)
4234 {
4235 Print(" place %d",r->typ[j].data.am.place);
4236 Print(" start %d",r->typ[j].data.am.start);
4237 Print(" end %d",r->typ[j].data.am.end);
4238 Print(" len_gen %d",r->typ[j].data.am.len_gen);
4239 PrintS(" w:");
4240 int l=0;
4241 for(l=r->typ[j].data.am.start;l<=r->typ[j].data.am.end;l++)
4242 Print(" %d",r->typ[j].data.am.weights[l-r->typ[j].data.am.start]);
4243 l=r->typ[j].data.am.end+1;
4244 int ll=r->typ[j].data.am.weights[l-r->typ[j].data.am.start];
4245 PrintS(" m:");
4246 for(int lll=l+1;lll<l+ll+1;lll++)
4247 Print(" %d",r->typ[j].data.am.weights[lll-r->typ[j].data.am.start]);
4248 }
4249 else
4250 {
4251 Print(" place %d",r->typ[j].data.dp.place);
4252
4253 if (r->typ[j].ord_typ!=ro_syzcomp && r->typ[j].ord_typ!=ro_syz)
4254 {
4255 Print(" start %d",r->typ[j].data.dp.start);
4256 Print(" end %d",r->typ[j].data.dp.end);
4257 if ((r->typ[j].ord_typ==ro_wp)
4258 || (r->typ[j].ord_typ==ro_wp_neg))
4259 {
4260 PrintS(" w:");
4261 for(int l=r->typ[j].data.wp.start;l<=r->typ[j].data.wp.end;l++)
4262 Print(" %d",r->typ[j].data.wp.weights[l-r->typ[j].data.wp.start]);
4263 }
4264 else if (r->typ[j].ord_typ==ro_wp64)
4265 {
4266 PrintS(" w64:");
4267 int l;
4268 for(l=r->typ[j].data.wp64.start;l<=r->typ[j].data.wp64.end;l++)
4269 Print(" %ld",(long)(r->typ[j].data.wp64.weights64+l-r->typ[j].data.wp64.start));
4270 }
4271 }
4272 }
4273 PrintLn();
4274 }
4275 Print("pOrdIndex:%d pCompIndex:%d\n", r->pOrdIndex, r->pCompIndex);
4276 Print("OrdSize:%d\n",r->OrdSize);
4277 PrintS("--------------------\n");
4278 for(j=0;j<r->ExpL_Size;j++)
4279 {
4280 Print("L[%d]: ",j);
4281 if (j< r->CmpL_Size)
4282 Print("ordsgn %ld ", r->ordsgn[j]);
4283 else
4284 PrintS("no comp ");
4285 i=1;
4286 for(;i<=r->N;i++)
4287 {
4288 if( (r->VarOffset[i] & 0xffffff) == j )
4289 { Print("v%d at e[%d], bit %d; ", i,r->VarOffset[i] & 0xffffff,
4290 r->VarOffset[i] >>24 ); }
4291 }
4292 if( r->pCompIndex==j ) PrintS("v0; ");
4293 for(i=0;i<r->OrdSize;i++)
4294 {
4295 if (r->typ[i].data.dp.place == j)
4296 {
4297 Print("ordrec:%s (start:%d, end:%d) ",TYP[r->typ[i].ord_typ],
4298 r->typ[i].data.dp.start, r->typ[i].data.dp.end);
4299 }
4300 }
4301
4302 if (j==r->pOrdIndex)
4303 PrintS("pOrdIndex\n");
4304 else
4305 PrintLn();
4306 }
4307 Print("LexOrder:%d, MixedOrder:%d\n",r->LexOrder, r->MixedOrder);
4308
4309 Print("NegWeightL_Size: %d, NegWeightL_Offset: ", r->NegWeightL_Size);
4310 if (r->NegWeightL_Offset==NULL) PrintS(" NULL");
4311 else
4312 for(j = 0; j < r->NegWeightL_Size; j++)
4313 Print(" [%d]: %d ", j, r->NegWeightL_Offset[j]);
4314 PrintLn();
4315
4316 // p_Procs stuff
4318 const char* field;
4319 const char* length;
4320 const char* ord;
4321 p_Debug_GetProcNames(r, &proc_names); // changes p_Procs!!!
4323
4324 Print("p_Spec : %s, %s, %s\n", field, length, ord);
4325 PrintS("p_Procs :\n");
4326 for (i=0; i<(int) (sizeof(p_Procs_s)/sizeof(void*)); i++)
4327 {
4328 Print(" %s,\n", ((char**) &proc_names)[i]);
4329 }
4330
4331 {
4332 PrintLn();
4333 PrintS("pFDeg : ");
4334#define pFDeg_CASE(A) if(r->pFDeg == A) PrintS( "" #A "" )
4338 pFDeg_CASE(p_Deg); else
4339#undef pFDeg_CASE
4340 Print("(%p)", r->pFDeg); // default case
4341
4342 PrintLn();
4343 Print("pLDeg : (%p)", r->pLDeg);
4344 PrintLn();
4345 }
4346 PrintS("pSetm:");
4347 void p_Setm_Dummy(poly p, const ring r);
4348 void p_Setm_TotalDegree(poly p, const ring r);
4349 void p_Setm_WFirstTotalDegree(poly p, const ring r);
4350 void p_Setm_General(poly p, const ring r);
4351 if (r->p_Setm==p_Setm_General) PrintS("p_Setm_General\n");
4352 else if (r->p_Setm==p_Setm_Dummy) PrintS("p_Setm_Dummy\n");
4353 else if (r->p_Setm==p_Setm_TotalDegree) PrintS("p_Setm_Totaldegree\n");
4354 else if (r->p_Setm==p_Setm_WFirstTotalDegree) PrintS("p_Setm_WFirstTotalDegree\n");
4355 else Print("%p\n",r->p_Setm);
4356}
4357
4358void p_DebugPrint(poly p, const ring r)
4359{
4360 int i,j;
4361 p_Write(p,r);
4362 j=2;
4363 while(p!=NULL)
4364 {
4365 Print("\nexp[0..%d]\n",r->ExpL_Size-1);
4366 for(i=0;i<r->ExpL_Size;i++)
4367 Print("%ld ",p->exp[i]);
4368 PrintLn();
4369 Print("v0:%ld ",p_GetComp(p, r));
4370 for(i=1;i<=r->N;i++) Print(" v%d:%ld",i,p_GetExp(p,i, r));
4371 PrintLn();
4372 pIter(p);
4373 j--;
4374 if (j==0) { PrintS("...\n"); break; }
4375 }
4376}
4377
4378#endif // RDEBUG
4379
4380/// debug-print monomial poly/vector p, assuming that it lives in the ring R
4381static inline void m_DebugPrint(const poly p, const ring R)
4382{
4383 Print("\nexp[0..%d]\n", R->ExpL_Size - 1);
4384 for(int i = 0; i < R->ExpL_Size; i++)
4385 Print("%09lx ", p->exp[i]);
4386 PrintLn();
4387 Print("v0:%9ld ", p_GetComp(p, R));
4388 for(int i = 1; i <= R->N; i++) Print(" v%d:%5ld",i, p_GetExp(p, i, R));
4389 PrintLn();
4390}
4391
4392
4393/*2
4394* asssume that rComplete was called with r
4395* assume that the first block ist ringorder_S
4396* change the block to reflect the sequence given by appending v
4397*/
4399{
4400 assume(r->typ[1].ord_typ == ro_syzcomp);
4401
4402 r->typ[1].data.syzcomp.ShiftedComponents = currShiftedComponents;
4403 r->typ[1].data.syzcomp.Components = currComponents;
4404}
4405
4406static inline void rNGetSComps(int** currComponents, long** currShiftedComponents, ring r)
4407{
4408 assume(r->typ[1].ord_typ == ro_syzcomp);
4409
4410 *currShiftedComponents = r->typ[1].data.syzcomp.ShiftedComponents;
4411 *currComponents = r->typ[1].data.syzcomp.Components;
4412}
4413#ifdef PDEBUG
4414static inline void rDBChangeSComps(int* currComponents,
4416 int length,
4417 ring r)
4418{
4419 assume(r->typ[1].ord_typ == ro_syzcomp);
4420
4421 r->typ[1].data.syzcomp.length = length;
4423}
4424static inline void rDBGetSComps(int** currComponents,
4425 long** currShiftedComponents,
4426 int *length,
4427 ring r)
4428{
4429 assume(r->typ[1].ord_typ == ro_syzcomp);
4430
4431 *length = r->typ[1].data.syzcomp.length;
4433}
4434#endif
4435
4437{
4438#ifdef PDEBUG
4440#else
4442#endif
4443}
4444
4446{
4447#ifdef PDEBUG
4449#else
4451#endif
4452}
4453
4454
4455/////////////////////////////////////////////////////////////////////////////
4456//
4457// The following routines all take as input a ring r, and return R
4458// where R has a certain property. R might be equal r in which case r
4459// had already this property
4460//
4462{
4463 if ( r->order[0] == ringorder_c ) return r;
4464 return rAssure_SyzComp(r,complete);
4465}
4467{
4468 if ( r->order[0] == ringorder_s ) return r;
4469
4470 if ( r->order[0] == ringorder_IS )
4471 {
4472#ifndef SING_NDEBUG
4473 WarnS("rAssure_SyzComp: input ring has an IS-ordering!");
4474#endif
4475// return r;
4476 }
4477 ring res=rCopy0(r, FALSE, FALSE);
4478 int i=rBlocks(r);
4479 int j;
4480
4481 res->order=(rRingOrder_t *)omAlloc((i+1)*sizeof(rRingOrder_t));
4482 res->block0=(int *)omAlloc0((i+1)*sizeof(int));
4483 res->block1=(int *)omAlloc0((i+1)*sizeof(int));
4484 int ** wvhdl =(int **)omAlloc0((i+1)*sizeof(int**));
4485 for(j=i;j>0;j--)
4486 {
4487 res->order[j]=r->order[j-1];
4488 res->block0[j]=r->block0[j-1];
4489 res->block1[j]=r->block1[j-1];
4490 if (r->wvhdl[j-1] != NULL)
4491 {
4492 #ifdef HAVE_OMALLOC
4493 wvhdl[j] = (int*) omMemDup(r->wvhdl[j-1]);
4494 #else
4495 {
4496 int l=r->block1[j-1]-r->block0[j-1]+1;
4497 if (r->order[j-1]==ringorder_a64) l*=2;
4498 else if (r->order[j-1]==ringorder_M) l=l*l;
4499 else if (r->order[j-1]==ringorder_am)
4500 {
4501 l+=r->wvhdl[j-1][r->block1[j-1]-r->block0[j-1]+1]+1;
4502 }
4503 wvhdl[j]=(int*)omalloc(l*sizeof(int));
4504 memcpy(wvhdl[j],r->wvhdl[j-1],l*sizeof(int));
4505 }
4506 #endif
4507 }
4508 }
4509 res->order[0]=ringorder_s;
4510
4511 res->wvhdl = wvhdl;
4512
4513 if (complete)
4514 {
4515 rComplete(res, 1);
4516#ifdef HAVE_PLURAL
4517 if (rIsPluralRing(r))
4518 {
4519 if ( nc_rComplete(r, res, false) ) // no qideal!
4520 {
4521#ifndef SING_NDEBUG
4522 WarnS("error in nc_rComplete"); // cleanup?// rDelete(res);// return r; // just go on..
4523#endif
4524 }
4525 }
4527#endif
4528
4529#ifdef HAVE_PLURAL
4530 ring old_ring = r;
4531#endif
4532 if (r->qideal!=NULL)
4533 {
4534 res->qideal= idrCopyR_NoSort(r->qideal, r, res);
4535 assume(id_RankFreeModule(res->qideal, res) == 0);
4536#ifdef HAVE_PLURAL
4537 if( rIsPluralRing(res) )
4538 {
4539 if( nc_SetupQuotient(res, r, true) )
4540 {
4541// WarnS("error in nc_SetupQuotient"); // cleanup? rDelete(res); return r; // just go on...?
4542 }
4543 assume(id_RankFreeModule(res->qideal, res) == 0);
4544 }
4545#endif
4546 }
4547
4548#ifdef HAVE_PLURAL
4549 assume((res->qideal==NULL) == (old_ring->qideal==NULL));
4553#endif
4554 }
4555 return res;
4556}
4557
4559{
4560 if (r->N==1) // special: dp(1)==lp(1)== no entry in typ
4561 {
4562 pos=r->VarL_LowIndex;
4563 return r;
4564 }
4565 if (r->typ!=NULL)
4566 {
4567 for(int i=r->OrdSize-1;i>=0;i--)
4568 {
4569 if ((r->typ[i].ord_typ==ro_dp)
4570 && (r->typ[i].data.dp.start==1)
4571 && (r->typ[i].data.dp.end==r->N))
4572 {
4573 pos=r->typ[i].data.dp.place;
4574 //printf("no change, pos=%d\n",pos);
4575 return r;
4576 }
4577 }
4578 }
4579
4580#ifdef HAVE_PLURAL
4581 nc_struct* save=r->GetNC();
4582 r->GetNC()=NULL;
4583#endif
4584 ring res=rCopy(r);
4585 if (res->qideal!=NULL)
4586 {
4587 id_Delete(&res->qideal,r);
4588 }
4589
4590 int j;
4591
4592 res->ExpL_Size=r->ExpL_Size+1; // one word more in each monom
4593 res->PolyBin=omGetSpecBin(POLYSIZE + (res->ExpL_Size)*sizeof(long));
4594 omFree((ADDRESS)res->ordsgn);
4595 res->ordsgn=(long *)omAlloc0(res->ExpL_Size*sizeof(long));
4596 for(j=0;j<r->CmpL_Size;j++)
4597 {
4598 res->ordsgn[j] = r->ordsgn[j];
4599 }
4600 res->OrdSize=r->OrdSize+1; // one block more for pSetm
4601 if (r->typ!=NULL)
4602 omFree((ADDRESS)res->typ);
4603 res->typ=(sro_ord*)omAlloc0(res->OrdSize*sizeof(sro_ord));
4604 if (r->typ!=NULL)
4605 memcpy(res->typ,r->typ,r->OrdSize*sizeof(sro_ord));
4606 // the additional block for pSetm: total degree at the last word
4607 // but not included in the compare part
4608 res->typ[res->OrdSize-1].ord_typ=ro_dp;
4609 res->typ[res->OrdSize-1].data.dp.start=1;
4610 res->typ[res->OrdSize-1].data.dp.end=res->N;
4611 res->typ[res->OrdSize-1].data.dp.place=res->ExpL_Size-1;
4612 pos=res->ExpL_Size-1;
4613 //res->pOrdIndex=pos; //NO: think of a(1,0),dp !
4614 extern void p_Setm_General(poly p, ring r);
4615 res->p_Setm=p_Setm_General;
4616 // ----------------------------
4617 omFree((ADDRESS)res->p_Procs);
4618 res->p_Procs = (p_Procs_s*)omAlloc(sizeof(p_Procs_s));
4619
4620 p_ProcsSet(res, res->p_Procs);
4621#ifdef HAVE_PLURAL
4622 r->GetNC()=save;
4623 if (rIsPluralRing(r))
4624 {
4625 if ( nc_rComplete(r, res, false) ) // no qideal!
4626 {
4627#ifndef SING_NDEBUG
4628 WarnS("error in nc_rComplete");
4629#endif
4630 // just go on..
4631 }
4632 }
4633#endif
4634 if (r->qideal!=NULL)
4635 {
4636 res->qideal=idrCopyR_NoSort(r->qideal,r, res);
4637#ifdef HAVE_PLURAL
4638 if (rIsPluralRing(res))
4639 {
4640// nc_SetupQuotient(res, currRing);
4641 nc_SetupQuotient(res, r); // ?
4642 }
4643 assume((res->qideal==NULL) == (r->qideal==NULL));
4644#endif
4645 }
4646
4647#ifdef HAVE_PLURAL
4649 assume(rIsSCA(res) == rIsSCA(r));
4651#endif
4652
4653 return res;
4654}
4655
4657{
4658 int last_block;
4659 int i=0;
4660 do
4661 {
4662 if (r->order[i] == ringorder_c ||
4663 r->order[i] == ringorder_C) return r;
4664 if (r->order[i] == 0)
4665 break;
4666 i++;
4667 } while (1);
4668 //WarnS("re-creating ring with comps");
4669 last_block=i-1;
4670
4671 ring new_r = rCopy0(r, FALSE, FALSE);
4672 i+=2;
4673 new_r->wvhdl=(int **)omAlloc0(i * sizeof(int *));
4674 new_r->order = (rRingOrder_t *) omAlloc0(i * sizeof(rRingOrder_t));
4675 new_r->block0 = (int *) omAlloc0(i * sizeof(int));
4676 new_r->block1 = (int *) omAlloc0(i * sizeof(int));
4677 memcpy(new_r->order,r->order,(i-1) * sizeof(rRingOrder_t));
4678 memcpy(new_r->block0,r->block0,(i-1) * sizeof(int));
4679 memcpy(new_r->block1,r->block1,(i-1) * sizeof(int));
4680 for (int j=0; j<=last_block; j++)
4681 {
4682 if (r->wvhdl[j]!=NULL)
4683 {
4684 #ifdef HAVE_OMALLOC
4685 new_r->wvhdl[j] = (int*) omMemDup(r->wvhdl[j]);
4686 #else
4687 {
4688 int l=r->block1[j]-r->block0[j]+1;
4689 if (r->order[j]==ringorder_a64) l*=2;
4690 else if (r->order[j]==ringorder_M) l=l*l;
4691 else if (r->order[j]==ringorder_am)
4692 {
4693 l+=r->wvhdl[j][r->block1[j]-r->block0[j]+1]+1;
4694 }
4695 new_r->wvhdl[j]=(int*)omalloc(l*sizeof(int));
4696 memcpy(new_r->wvhdl[j],r->wvhdl[j],l*sizeof(int));
4697 }
4698 #endif
4699 }
4700 }
4701 last_block++;
4703 //new_r->block0[last_block]=0;
4704 //new_r->block1[last_block]=0;
4705 //new_r->wvhdl[last_block]=NULL;
4706
4707 rComplete(new_r, 1);
4708
4709#ifdef HAVE_PLURAL
4710 if (rIsPluralRing(r))
4711 {
4712 if ( nc_rComplete(r, new_r, false) ) // no qideal!
4713 {
4714#ifndef SING_NDEBUG
4715 WarnS("error in nc_rComplete"); // cleanup?// rDelete(res);// return r; // just go on..
4716#endif
4717 }
4718 }
4720#endif
4721
4722 return new_r;
4723}
4724
4726{
4727 int last_block = rBlocks(r) - 2;
4728 if (r->order[last_block] != ringorder_c &&
4729 r->order[last_block] != ringorder_C)
4730 {
4731 int c_pos = 0;
4732 int i;
4733
4734 for (i=0; i< last_block; i++)
4735 {
4736 if (r->order[i] == ringorder_c || r->order[i] == ringorder_C)
4737 {
4738 c_pos = i;
4739 break;
4740 }
4741 }
4742 if (c_pos != -1)
4743 {
4744 ring new_r = rCopy0(r, FALSE, TRUE);
4745 for (i=c_pos+1; i<=last_block; i++)
4746 {
4747 new_r->order[i-1] = new_r->order[i];
4748 new_r->block0[i-1] = new_r->block0[i];
4749 new_r->block1[i-1] = new_r->block1[i];
4750 new_r->wvhdl[i-1] = new_r->wvhdl[i];
4751 }
4752 new_r->order[last_block] = r->order[c_pos];
4753 new_r->block0[last_block] = r->block0[c_pos];
4754 new_r->block1[last_block] = r->block1[c_pos];
4755 new_r->wvhdl[last_block] = r->wvhdl[c_pos];
4756 if (complete)
4757 {
4758 rComplete(new_r, 1);
4759
4760#ifdef HAVE_PLURAL
4761 if (rIsPluralRing(r))
4762 {
4763 if ( nc_rComplete(r, new_r, false) ) // no qideal!
4764 {
4765#ifndef SING_NDEBUG
4766 WarnS("error in nc_rComplete"); // cleanup?// rDelete(res);// return r; // just go on..
4767#endif
4768 }
4769 }
4771#endif
4772 }
4773 return new_r;
4774 }
4775 }
4776 return r;
4777}
4778
4779// Moves _c or _C ordering to the last place AND adds _s on the 1st place
4781{
4782 rTest(r);
4783
4784 ring new_r_1 = rAssure_CompLastBlock(r, FALSE); // due to this FALSE - no completion!
4785 ring new_r = rAssure_SyzComp(new_r_1, FALSE); // new_r_1 is used only here!!!
4786
4787 if (new_r == r)
4788 return r;
4789
4790 ring old_r = r;
4791 if (new_r_1 != new_r && new_r_1 != old_r) rDelete(new_r_1);
4792
4794#ifdef HAVE_PLURAL
4795 if (rIsPluralRing(old_r))
4796 {
4797 if ( nc_rComplete(old_r, new_r, false) ) // no qideal!
4798 {
4799# ifndef SING_NDEBUG
4800 WarnS("error in nc_rComplete"); // cleanup? rDelete(res); return r; // just go on...?
4801# endif
4802 }
4803 }
4804#endif
4805
4806///? rChangeCurrRing(new_r);
4807 if (old_r->qideal != NULL)
4808 {
4809 new_r->qideal = idrCopyR(old_r->qideal, old_r, new_r);
4810 }
4811
4812#ifdef HAVE_PLURAL
4813 if( rIsPluralRing(old_r) )
4814 if( nc_SetupQuotient(new_r, old_r, true) )
4815 {
4816#ifndef SING_NDEBUG
4817 WarnS("error in nc_SetupQuotient"); // cleanup? rDelete(res); return r; // just go on...?
4818#endif
4819 }
4820#endif
4821
4822#ifdef HAVE_PLURAL
4823 assume((new_r->qideal==NULL) == (old_r->qideal==NULL));
4827#endif
4828
4829 rTest(new_r);
4830 rTest(old_r);
4831 return new_r;
4832}
4833
4834// use this for global orderings consisting of two blocks
4836{
4837 int r_blocks = rBlocks(r);
4838
4839 assume(b1 == ringorder_c || b1 == ringorder_C ||
4840 b2 == ringorder_c || b2 == ringorder_C ||
4841 b2 == ringorder_S);
4842 if ((r_blocks == 3) &&
4843 (r->order[0] == b1) &&
4844 (r->order[1] == b2) &&
4845 (r->order[2] == 0))
4846 return r;
4847 ring res = rCopy0(r, FALSE, FALSE);
4848 res->order = (rRingOrder_t*)omAlloc0(3*sizeof(rRingOrder_t));
4849 res->block0 = (int*)omAlloc0(3*sizeof(int));
4850 res->block1 = (int*)omAlloc0(3*sizeof(int));
4851 res->wvhdl = (int**)omAlloc0(3*sizeof(int*));
4852 res->order[0] = b1;
4853 res->order[1] = b2;
4854 if (b1 == ringorder_c || b1 == ringorder_C)
4855 {
4856 res->block0[1] = 1;
4857 res->block1[1] = r->N;
4858 }
4859 else
4860 {
4861 res->block0[0] = 1;
4862 res->block1[0] = r->N;
4863 }
4864 rComplete(res, 1);
4865 if (r->qideal!=NULL) res->qideal= idrCopyR_NoSort(r->qideal, r, res);
4866#ifdef HAVE_PLURAL
4867 if (rIsPluralRing(r))
4868 {
4869 if ( nc_rComplete(r, res, false) ) // no qideal!
4870 {
4871#ifndef SING_NDEBUG
4872 WarnS("error in nc_rComplete");
4873#endif
4874 }
4875 }
4876#endif
4877// rChangeCurrRing(res);
4878 return res;
4879}
4880
4882{
4883 int r_blocks = rBlocks(r);
4884
4885 if ((r_blocks == 3) &&
4886 (r->order[0] == ringorder_Wp) &&
4887 (r->order[1] == ringorder_C) &&
4888 (r->order[2] == 0))
4889 {
4890 BOOLEAN ok=TRUE;
4891 for(int i=0;i<r->N;i++)
4892 {
4893 if ((*w)[i]!=r->wvhdl[0][i]) { ok=FALSE;break;}
4894 }
4895 if (ok) return r;
4896 }
4897 ring res = rCopy0(r, FALSE, FALSE);
4898 res->order = (rRingOrder_t*)omAlloc0(3*sizeof(rRingOrder_t));
4899 res->block0 = (int*)omAlloc0(3*sizeof(int));
4900 res->block1 = (int*)omAlloc0(3*sizeof(int));
4901 res->wvhdl = (int**)omAlloc0(3*sizeof(int*));
4902 res->order[0] = ringorder_Wp;
4903 res->order[1] = ringorder_C;
4904 res->block0[1] = 1;
4905 res->block1[1] = r->N;
4906 res->wvhdl[0]=(int*)omAlloc(r->N*sizeof(int));
4907 for(int i=0;i<r->N;i++)
4908 {
4909 r->wvhdl[0][i]=(*w)[i];
4910 }
4911 rComplete(res, 1);
4912 if (r->qideal!=NULL) res->qideal= idrCopyR_NoSort(r->qideal, r, res);
4913#ifdef HAVE_PLURAL
4914 if (rIsPluralRing(r))
4915 {
4916 if ( nc_rComplete(r, res, false) ) // no qideal!
4917 {
4918#ifndef SING_NDEBUG
4919 WarnS("error in nc_rComplete");
4920#endif
4921 }
4922 }
4923#endif
4924// rChangeCurrRing(res);
4925 return res;
4926}
4927
4928ring rAssure_InducedSchreyerOrdering(const ring r, BOOLEAN complete/* = TRUE*/, int sgn/* = 1*/)
4929{ // TODO: ???? Add leading Syz-comp ordering here...????
4930
4931#if MYTEST
4932 Print("rAssure_InducedSchreyerOrdering(r, complete = %d, sgn = %d): r: \n", complete, sgn);
4933 rWrite(r);
4934#ifdef RDEBUG
4935 rDebugPrint(r);
4936#endif
4937 PrintLn();
4938#endif
4939 assume((sgn == 1) || (sgn == -1));
4940
4941 ring res=rCopy0(r, FALSE, FALSE); // No qideal & ordering copy.
4942
4943 int n = rBlocks(r); // Including trailing zero!
4944
4945 // Create 2 more blocks for prefix/suffix:
4946 res->order=(rRingOrder_t *)omAlloc0((n+2)*sizeof(rRingOrder_t)); // 0 .. n+1
4947 res->block0=(int *)omAlloc0((n+2)*sizeof(int));
4948 res->block1=(int *)omAlloc0((n+2)*sizeof(int));
4949 int ** wvhdl =(int **)omAlloc0((n+2)*sizeof(int**));
4950
4951 // Encapsulate all existing blocks between induced Schreyer ordering markers: prefix and suffix!
4952 // Note that prefix and suffix have the same ringorder marker and only differ in block[] parameters!
4953
4954 // new 1st block
4955 int j = 0;
4956 res->order[j] = ringorder_IS; // Prefix
4957 res->block0[j] = res->block1[j] = 0;
4958 // wvhdl[j] = NULL;
4959 j++;
4960
4961 for(int i = 0; (i <= n) && (r->order[i] != 0); i++, j++) // i = [0 .. n-1] <- non-zero old blocks
4962 {
4963 res->order [j] = r->order [i];
4964 res->block0[j] = r->block0[i];
4965 res->block1[j] = r->block1[i];
4966
4967 if (r->wvhdl[i] != NULL)
4968 {
4969 #ifdef HAVE_OMALLOC
4970 wvhdl[j] = (int*) omMemDup(r->wvhdl[i]);
4971 #else
4972 {
4973 int l=(r->block1[i]-r->block0[i]+1);
4974 if (r->order[i]==ringorder_a64) l*=2;
4975 else if (r->order[i]==ringorder_M) l=l*l;
4976 else if (r->order[i]==ringorder_am)
4977 {
4978 l+=r->wvhdl[i][r->block1[i]-r->block0[i]+1]+1;
4979 }
4980 wvhdl[j]=(int*)omalloc(l*sizeof(int));
4981 memcpy(wvhdl[j],r->wvhdl[i],l*sizeof(int));
4982 }
4983 #endif
4984 } // else wvhdl[j] = NULL;
4985 }
4986
4987 // new last block
4988 res->order [j] = ringorder_IS; // Suffix
4989 res->block0[j] = res->block1[j] = sgn; // Sign of v[o]: 1 for C, -1 for c
4990 // wvhdl[j] = NULL;
4991 j++;
4992
4993 // res->order [j] = 0; // The End!
4994 res->wvhdl = wvhdl;
4995
4996 // j == the last zero block now!
4997 assume(j == (n+1));
4998 assume(res->order[0]==ringorder_IS);
4999 assume(res->order[j-1]==ringorder_IS);
5000 assume(res->order[j]==0);
5001
5002
5003 if (complete)
5004 {
5005 rComplete(res, 1);
5006
5007#ifdef HAVE_PLURAL
5008 if (rIsPluralRing(r))
5009 {
5010 if ( nc_rComplete(r, res, false) ) // no qideal!
5011 {
5012#ifndef SING_NDEBUG
5013 WarnS("error in nc_rComplete"); // cleanup?// rDelete(res);// return r; // just go on..
5014#endif
5015 }
5016 }
5018#endif
5019
5020
5021#ifdef HAVE_PLURAL
5022 ring old_ring = r;
5023#endif
5024
5025 if (r->qideal!=NULL)
5026 {
5027 res->qideal= idrCopyR_NoSort(r->qideal, r, res);
5028
5029 assume(id_RankFreeModule(res->qideal, res) == 0);
5030
5031#ifdef HAVE_PLURAL
5032 if( rIsPluralRing(res) )
5033 if( nc_SetupQuotient(res, r, true) )
5034 {
5035// WarnS("error in nc_SetupQuotient"); // cleanup? rDelete(res); return r; // just go on...?
5036 }
5037
5038#endif
5039 assume(id_RankFreeModule(res->qideal, res) == 0);
5040 }
5041
5042#ifdef HAVE_PLURAL
5043 assume((res->qideal==NULL) == (old_ring->qideal==NULL));
5047#endif
5048 }
5049
5050 return res;
5051}
5052
5054{
5056}
5057
5059{
5061}
5062
5064{
5066}
5067
5069{
5071}
5072
5074{
5076}
5077
5078
5079
5080/// Finds p^th IS ordering, and returns its position in r->typ[]
5081/// returns -1 if something went wrong!
5082/// p - starts with 0!
5083int rGetISPos(const int p, const ring r)
5084{
5085 // Put the reference set F into the ring -ordering -recor
5086#if MYTEST
5087 Print("rIsIS(p: %d)\nF:", p);
5088 PrintLn();
5089#endif
5090
5091 if (r->typ==NULL)
5092 {
5093// dReportError("'rIsIS:' Error: wrong ring! (typ == NULL)");
5094 return -1;
5095 }
5096
5097 int j = p; // Which IS record to use...
5098 for( int pos = 0; pos < r->OrdSize; pos++ )
5099 if( r->typ[pos].ord_typ == ro_is)
5100 if( j-- == 0 )
5101 return pos;
5102
5103 return -1;
5104}
5105
5106
5107
5108
5109
5110
5111/// Changes r by setting induced ordering parameters: limit and reference leading terms
5112/// F belong to r, we will DO a copy!
5113/// We will use it AS IS!
5114/// returns true is everything was allright!
5115BOOLEAN rSetISReference(const ring r, const ideal F, const int i, const int p)
5116{
5117 // Put the reference set F into the ring -ordering -recor
5118
5119 if (r->typ==NULL)
5120 {
5121 dReportError("Error: WRONG USE of rSetISReference: wrong ring! (typ == NULL)");
5122 return FALSE;
5123 }
5124
5125
5126 int pos = rGetISPos(p, r);
5127
5128 if( pos == -1 )
5129 {
5130 dReportError("Error: WRONG USE of rSetISReference: specified ordering block was not found!!!" );
5131 return FALSE;
5132 }
5133
5134#if MYTEST
5135 if( i != r->typ[pos].data.is.limit )
5136 Print("Changing record on pos: %d\nOld limit: %d --->> New Limit: %d\n", pos, r->typ[pos].data.is.limit, i);
5137#endif
5138
5139 const ideal FF = idrHeadR(F, r, r); // id_Copy(F, r); // ???
5140
5141
5142 if( r->typ[pos].data.is.F != NULL)
5143 {
5144#if MYTEST
5145 PrintS("Deleting old reference set F... \n"); // idShow(r->typ[pos].data.is.F, r); PrintLn();
5146#endif
5147 id_Delete(&r->typ[pos].data.is.F, r);
5148 r->typ[pos].data.is.F = NULL;
5149 }
5150
5151 assume(r->typ[pos].data.is.F == NULL);
5152
5153 r->typ[pos].data.is.F = FF; // F is owened by ring now! TODO: delete at the end!
5154
5155 r->typ[pos].data.is.limit = i; // First induced component
5156
5157#if MYTEST
5158 PrintS("New reference set FF : \n"); idShow(FF, r, r, 1); PrintLn();
5159#endif
5160
5161 return TRUE;
5162}
5163
5164#ifdef PDEBUG
5166#endif
5167
5168
5169void rSetSyzComp(int k, const ring r)
5170{
5171 if(k < 0)
5172 {
5173 dReportError("rSetSyzComp with negative limit!");
5174 return;
5175 }
5176
5177 assume( k >= 0 );
5178 if (TEST_OPT_PROT) Print("{%d}", k);
5179 if ((r->typ!=NULL) && (r->typ[0].ord_typ==ro_syz))
5180 {
5181 r->block0[0]=r->block1[0] = k;
5182 if( k == r->typ[0].data.syz.limit )
5183 return; // nothing to do
5184
5185 int i;
5186 if (r->typ[0].data.syz.limit == 0)
5187 {
5188 r->typ[0].data.syz.syz_index = (int*) omAlloc0((k+1)*sizeof(int));
5189 r->typ[0].data.syz.syz_index[0] = 0;
5190 r->typ[0].data.syz.curr_index = 1;
5191 }
5192 else
5193 {
5194 r->typ[0].data.syz.syz_index = (int*)
5195 omReallocSize(r->typ[0].data.syz.syz_index,
5196 (r->typ[0].data.syz.limit+1)*sizeof(int),
5197 (k+1)*sizeof(int));
5198 }
5199 for (i=r->typ[0].data.syz.limit + 1; i<= k; i++)
5200 {
5201 r->typ[0].data.syz.syz_index[i] =
5202 r->typ[0].data.syz.curr_index;
5203 }
5204 if(k < r->typ[0].data.syz.limit) // ?
5205 {
5206#ifndef SING_NDEBUG
5207 Warn("rSetSyzComp called with smaller limit (%d) as before (%d)", k, r->typ[0].data.syz.limit);
5208#endif
5209 r->typ[0].data.syz.curr_index = 1 + r->typ[0].data.syz.syz_index[k];
5210 }
5211
5212
5213 r->typ[0].data.syz.limit = k;
5214 r->typ[0].data.syz.curr_index++;
5215 }
5216 else if(
5217 (r->typ!=NULL) &&
5218 (r->typ[0].ord_typ==ro_isTemp)
5219 )
5220 {
5221// (r->typ[currRing->typ[0].data.isTemp.suffixpos].data.is.limit == k)
5222#ifndef SING_NDEBUG
5223 Warn("rSetSyzComp(%d) in an IS ring! Be careful!", k);
5224#endif
5225 }
5226 else if (r->order[0]==ringorder_s)
5227 {
5228 r->block0[0] = r->block1[0] = k;
5229 }
5230 else if (r->order[0]!=ringorder_c)
5231 {
5232 dReportError("syzcomp in incompatible ring");
5233 }
5234#ifdef PDEBUG
5236 pDBsyzComp=k;
5237#endif
5238}
5239
5240// return the max-comonent wchich has syzIndex i
5241int rGetMaxSyzComp(int i, const ring r)
5242{
5243 if ((r->typ!=NULL) && (r->typ[0].ord_typ==ro_syz) &&
5244 r->typ[0].data.syz.limit > 0 && i > 0)
5245 {
5246 assume(i <= r->typ[0].data.syz.limit);
5247 int j;
5248 for (j=0; j<r->typ[0].data.syz.limit; j++)
5249 {
5250 if (r->typ[0].data.syz.syz_index[j] == i &&
5251 r->typ[0].data.syz.syz_index[j+1] != i)
5252 {
5253 assume(r->typ[0].data.syz.syz_index[j+1] == i+1);
5254 return j;
5255 }
5256 }
5257 return r->typ[0].data.syz.limit;
5258 }
5259 else
5260 {
5261 #ifndef SING_NDEBUG
5262 WarnS("rGetMaxSyzComp: order c");
5263 #endif
5264 return 0;
5265 }
5266}
5267
5269{
5270 assume(r != NULL);
5271 int lb = rBlocks(r) - 2;
5272 return (r->order[lb] == ringorder_c || r->order[lb] == ringorder_C);
5273}
5274
5276{
5277 if ((r->order[0]==ringorder_dp) &&(r->block0[0]==1) &&(r->block1[0]==r->N))
5278 return TRUE;
5279 if (((r->order[0]==ringorder_c)||(r->order[0]==ringorder_C))
5280 && ((r->order[1]==ringorder_dp) &&(r->block0[1]==1) &&(r->block1[1]==r->N)))
5281 return TRUE;
5282 return FALSE;
5283}
5284
5286{
5287 if ((r->order[0]==ringorder_Dp) &&(r->block0[0]==1) &&(r->block1[0]==r->N))
5288 return TRUE;
5289 if (((r->order[0]==ringorder_c)||(r->order[0]==ringorder_C))
5290 && ((r->order[1]==ringorder_Dp) &&(r->block0[1]==1) &&(r->block1[1]==r->N)))
5291 return TRUE;
5292 return FALSE;
5293}
5294
5296{
5297 if ((r->order[0]==ringorder_lp) &&(r->block0[0]==1) &&(r->block1[0]==r->N))
5298 return TRUE;
5299 if (((r->order[0]==ringorder_c)||(r->order[0]==ringorder_C))
5300 && ((r->order[1]==ringorder_lp) &&(r->block0[1]==1) &&(r->block1[1]==r->N)))
5301 return TRUE;
5302 return FALSE;
5303}
5304
5306{
5307 assume(r!=NULL);
5308 assume(r->OrdSize>0);
5309 int i=0;
5310 while((r->typ[i].ord_typ!=ro_wp64) && (r->typ[i].ord_typ>0)) i++;
5311 if (r->typ[i].ord_typ!=ro_wp64) return NULL; /* should not happen*/
5312 return r->typ[i].data.wp64.weights64;
5313}
5314
5316{
5317 assume(r!=NULL);
5318 assume(r->OrdSize>0);
5319 assume(r->typ[0].ord_typ==ro_wp64);
5320 memcpy(r->typ[0].data.wp64.weights64,wv,r->N*sizeof(int64));
5321}
5322
5323#include <ctype.h>
5324
5325static int rRealloc1(ring r, int size, int pos)
5326{
5327 r->order=(rRingOrder_t*)omReallocSize(r->order, size*sizeof(rRingOrder_t), (size+1)*sizeof(rRingOrder_t));
5328 r->block0=(int*)omReallocSize(r->block0, size*sizeof(int), (size+1)*sizeof(int));
5329 r->block1=(int*)omReallocSize(r->block1, size*sizeof(int), (size+1)*sizeof(int));
5330 r->wvhdl=(int **)omReallocSize(r->wvhdl,size*sizeof(int *), (size+1)*sizeof(int *));
5331 for(int k=size; k>pos; k--) r->wvhdl[k]=r->wvhdl[k-1];
5332 r->order[size]=(rRingOrder_t)0;
5333 size++;
5334 return size;
5335}
5336#if 0 // currently unused
5337static int rReallocM1(ring r, int size, int pos)
5338{
5339 r->order=(int*)omReallocSize(r->order, size*sizeof(int), (size-1)*sizeof(int));
5340 r->block0=(int*)omReallocSize(r->block0, size*sizeof(int), (size-1)*sizeof(int));
5341 r->block1=(int*)omReallocSize(r->block1, size*sizeof(int), (size-1)*sizeof(int));
5342 r->wvhdl=(int **)omReallocSize(r->wvhdl,size*sizeof(int *), (size-1)*sizeof(int *));
5343 for(int k=pos+1; k<size; k++) r->wvhdl[k]=r->wvhdl[k+1];
5344 size--;
5345 return size;
5346}
5347#endif
5348static void rOppWeight(int *w, int l)
5349{
5350 /* works for commutative/Plural; need to be changed for Letterplace */
5351 /* Letterpace: each block of vars needs to be reverted on it own */
5352 int i2=(l+1)/2;
5353 for(int j=0; j<=i2; j++)
5354 {
5355 int t=w[j];
5356 w[j]=w[l-j];
5357 w[l-j]=t;
5358 }
5359}
5360
5361#define rOppVar(R,I) (rVar(R)+1-I)
5362/* nice for Plural, need to be changed for Letterplace: requires also the length of a monomial */
5363
5365 /* creates an opposite algebra of R */
5366 /* that is R^opp, where f (*^opp) g = g*f */
5367 /* treats the case of qring */
5368{
5369 if (src == NULL) return(NULL);
5370
5371 //rChangeCurrRing(src);
5372#ifdef RDEBUG
5373 rTest(src);
5374// rWrite(src);
5375// rDebugPrint(src);
5376#endif
5377
5378 ring r = rCopy0(src,FALSE);
5379 if (src->qideal != NULL)
5380 {
5381 id_Delete(&(r->qideal), src);
5382 }
5383
5384 // change vars v1..vN -> vN..v1
5385 int i;
5386 int i2 = (rVar(r)-1)/2;
5387 for(i=i2; i>=0; i--)
5388 {
5389 // index: 0..N-1
5390 //Print("ex var names: %d <-> %d\n",i,rOppVar(r,i));
5391 // exchange names
5392 char *p;
5393 p = r->names[rVar(r)-1-i];
5394 r->names[rVar(r)-1-i] = r->names[i];
5395 r->names[i] = p;
5396 }
5397// i2=(rVar(r)+1)/2;
5398// for(int i=i2; i>0; i--)
5399// {
5400// // index: 1..N
5401// //Print("ex var places: %d <-> %d\n",i,rVar(r)+1-i);
5402// // exchange VarOffset
5403// int t;
5404// t=r->VarOffset[i];
5405// r->VarOffset[i]=r->VarOffset[rOppVar(r,i)];
5406// r->VarOffset[rOppVar(r,i)]=t;
5407// }
5408 // change names:
5409 // TODO: does this work the same way for Letterplace?
5410 for (i=rVar(r)-1; i>=0; i--)
5411 {
5412 char *p=r->names[i];
5413 if(isupper(*p)) *p = tolower(*p);
5414 else *p = toupper(*p);
5415 }
5416 // change ordering: listing
5417 // change ordering: compare
5418// for(i=0; i<r->OrdSize; i++)
5419// {
5420// int t,tt;
5421// switch(r->typ[i].ord_typ)
5422// {
5423// case ro_dp:
5424// //
5425// t=r->typ[i].data.dp.start;
5426// r->typ[i].data.dp.start=rOppVar(r,r->typ[i].data.dp.end);
5427// r->typ[i].data.dp.end=rOppVar(r,t);
5428// break;
5429// case ro_wp:
5430// case ro_wp_neg:
5431// {
5432// t=r->typ[i].data.wp.start;
5433// r->typ[i].data.wp.start=rOppVar(r,r->typ[i].data.wp.end);
5434// r->typ[i].data.wp.end=rOppVar(r,t);
5435// // invert r->typ[i].data.wp.weights
5436// rOppWeight(r->typ[i].data.wp.weights,
5437// r->typ[i].data.wp.end-r->typ[i].data.wp.start);
5438// break;
5439// }
5440// //case ro_wp64:
5441// case ro_syzcomp:
5442// case ro_syz:
5443// WerrorS("not implemented in rOpposite");
5444// // should not happen
5445// break;
5446//
5447// case ro_cp:
5448// t=r->typ[i].data.cp.start;
5449// r->typ[i].data.cp.start=rOppVar(r,r->typ[i].data.cp.end);
5450// r->typ[i].data.cp.end=rOppVar(r,t);
5451// break;
5452// case ro_none:
5453// default:
5454// Werror("unknown type in rOpposite(%d)",r->typ[i].ord_typ);
5455// break;
5456// }
5457// }
5458 // Change order/block structures (needed for rPrint, rAdd etc.)
5459
5460 int j=0;
5461 int l=rBlocks(src);
5462 if ( ! rIsLPRing(src) )
5463 {
5464 // ie Plural or commutative
5465 for(i=0; src->order[i]!=0; i++)
5466 {
5467 switch (src->order[i])
5468 {
5469 case ringorder_c: /* c-> c */
5470 case ringorder_C: /* C-> C */
5471 case ringorder_no /*=0*/: /* end-of-block */
5472 r->order[j]=src->order[i];
5473 j++; break;
5474 case ringorder_lp: /* lp -> rp */
5475 r->order[j]=ringorder_rp;
5476 r->block0[j]=rOppVar(r, src->block1[i]);
5477 r->block1[j]=rOppVar(r, src->block0[i]);
5478 j++;break;
5479 case ringorder_rp: /* rp -> lp */
5480 r->order[j]=ringorder_lp;
5481 r->block0[j]=rOppVar(r, src->block1[i]);
5482 r->block1[j]=rOppVar(r, src->block0[i]);
5483 j++;break;
5484 case ringorder_dp: /* dp -> a(1..1),ls */
5485 {
5486 l=rRealloc1(r,l,j);
5487 r->order[j]=ringorder_a;
5488 r->block0[j]=rOppVar(r, src->block1[i]);
5489 r->block1[j]=rOppVar(r, src->block0[i]);
5490 r->wvhdl[j]=(int*)omAlloc((r->block1[j]-r->block0[j]+1)*sizeof(int));
5491 for(int k=r->block0[j]; k<=r->block1[j]; k++)
5492 r->wvhdl[j][k-r->block0[j]]=1;
5493 j++;
5494 r->order[j]=ringorder_ls;
5495 r->block0[j]=rOppVar(r, src->block1[i]);
5496 r->block1[j]=rOppVar(r, src->block0[i]);
5497 j++;
5498 break;
5499 }
5500 case ringorder_Dp: /* Dp -> a(1..1),rp */
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_rp;
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_wp: /* wp -> a(...),ls */
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]=r->wvhdl[j+1]; r->wvhdl[j+1]=NULL;
5523 rOppWeight(r->wvhdl[j], r->block1[j]-r->block0[j]);
5524 j++;
5525 r->order[j]=ringorder_ls;
5526 r->block0[j]=rOppVar(r, src->block1[i]);
5527 r->block1[j]=rOppVar(r, src->block0[i]);
5528 j++;
5529 break;
5530 }
5531 case ringorder_Wp: /* Wp -> a(...),rp */
5532 {
5533 l=rRealloc1(r,l,j);
5534 r->order[j]=ringorder_a;
5535 r->block0[j]=rOppVar(r, src->block1[i]);
5536 r->block1[j]=rOppVar(r, src->block0[i]);
5537 r->wvhdl[j]=r->wvhdl[j+1]; r->wvhdl[j+1]=NULL;
5538 rOppWeight(r->wvhdl[j], r->block1[j]-r->block0[j]);
5539 j++;
5540 r->order[j]=ringorder_rp;
5541 r->block0[j]=rOppVar(r, src->block1[i]);
5542 r->block1[j]=rOppVar(r, src->block0[i]);
5543 j++;
5544 break;
5545 }
5546 case ringorder_M: /* M -> M */
5547 {
5548 r->order[j]=ringorder_M;
5549 r->block0[j]=rOppVar(r, src->block1[i]);
5550 r->block1[j]=rOppVar(r, src->block0[i]);
5551 int n=r->block1[j]-r->block0[j];
5552 /* M is a (n+1)x(n+1) matrix */
5553 for (int nn=0; nn<=n; nn++)
5554 {
5555 rOppWeight(&(r->wvhdl[j][nn*(n+1)]), n /*r->block1[j]-r->block0[j]*/);
5556 }
5557 j++;
5558 break;
5559 }
5560 case ringorder_a: /* a(...),ls -> wp/dp */
5561 {
5562 r->block0[j]=rOppVar(r, src->block1[i]);
5563 r->block1[j]=rOppVar(r, src->block0[i]);
5564 rOppWeight(r->wvhdl[j], r->block1[j]-r->block0[j]);
5565 if (src->order[i+1]==ringorder_ls)
5566 {
5567 r->order[j]=ringorder_wp;
5568 i++;
5569 //l=rReallocM1(r,l,j);
5570 }
5571 else
5572 {
5573 r->order[j]=ringorder_a;
5574 }
5575 j++;
5576 break;
5577 }
5578 default:
5579 #if 0
5580 // not yet done:
5581 case ringorder_ls:
5582 case ringorder_rs:
5583 case ringorder_ds:
5584 case ringorder_Ds:
5585 case ringorder_ws:
5586 case ringorder_Ws:
5587 case ringorder_am:
5588 case ringorder_a64:
5589 // should not occur:
5590 case ringorder_S:
5591 case ringorder_IS:
5592 case ringorder_s:
5593 case ringorder_aa:
5594 case ringorder_L:
5595 case ringorder_unspec:
5596 #endif
5597 Werror("order %s not (yet) supported", rSimpleOrdStr(src->order[i]));
5598 break;
5599 }
5600 }
5601 } /* end if (!rIsLPRing(src)) */
5602 if (rIsLPRing(src))
5603 {
5604 // applies to Letterplace only
5605 // Letterplace conventions: dp<->Dp, lp<->rp
5606 // Wp(v) cannot be converted since wp(v) does not encode a monomial ordering
5607 // (a(w),<) is troublesome and thus postponed
5608 for(i=0; src->order[i]!=0; i++)
5609 {
5610 switch (src->order[i])
5611 {
5612 case ringorder_c: /* c-> c */
5613 case ringorder_C: /* C-> C */
5614 case ringorder_no /*=0*/: /* end-of-block */
5615 r->order[j]=src->order[i];
5616 j++; break;
5617 case ringorder_lp: /* lp -> rp */
5618 r->order[j]=ringorder_rp;
5619 r->block0[j]=rOppVar(r, src->block1[i]);
5620 r->block1[j]=rOppVar(r, src->block0[i]);
5621 j++;break;
5622 case ringorder_rp: /* rp -> lp */
5623 r->order[j]=ringorder_lp;
5624 r->block0[j]=rOppVar(r, src->block1[i]);
5625 r->block1[j]=rOppVar(r, src->block0[i]);
5626 j++;break;
5627 case ringorder_dp: /* dp -> Dp */
5628 {
5629 r->order[j]=ringorder_Dp;
5630 r->block0[j]=rOppVar(r, src->block1[i]);
5631 r->block1[j]=rOppVar(r, src->block0[i]);
5632 j++;break;
5633 }
5634 case ringorder_Dp: /* Dp -> dp*/
5635 {
5636 r->order[j]=ringorder_dp;
5637 r->block0[j]=rOppVar(r, src->block1[i]);
5638 r->block1[j]=rOppVar(r, src->block0[i]);
5639 j++;break;
5640 }
5641 // not clear how to do:
5642 case ringorder_wp:
5643 case ringorder_Wp:
5644 case ringorder_M:
5645 case ringorder_a:
5646 // not yet done:
5647 case ringorder_ls:
5648 case ringorder_rs:
5649 case ringorder_ds:
5650 case ringorder_Ds:
5651 case ringorder_ws:
5652 case ringorder_Ws:
5653 case ringorder_am:
5654 case ringorder_a64:
5655 case ringorder_Ip:
5656 // should not occur:
5657 case ringorder_S:
5658 case ringorder_IS:
5659 case ringorder_s:
5660 case ringorder_aa:
5661 case ringorder_L:
5662 case ringorder_unspec:
5663 Werror("order %s not (yet) supported", rSimpleOrdStr(src->order[i]));
5664 break;
5665 }
5666 }
5667 } /* end if (rIsLPRing(src)) */
5668 rComplete(r);
5669
5670 //rChangeCurrRing(r);
5671#ifdef RDEBUG
5672 rTest(r);
5673// rWrite(r);
5674// rDebugPrint(r);
5675#endif
5676
5677#ifdef HAVE_PLURAL
5678 // now, we initialize a non-comm structure on r
5679 if (rIsPluralRing(src))
5680 {
5681// assume( currRing == r);
5682
5683 int *perm = (int *)omAlloc0((rVar(r)+1)*sizeof(int));
5684 int *par_perm = NULL;
5685 nMapFunc nMap = n_SetMap(src->cf,r->cf);
5686 int ni,nj;
5687 for(i=1; i<=r->N; i++)
5688 {
5689 perm[i] = rOppVar(r,i);
5690 }
5691
5692 matrix C = mpNew(rVar(r),rVar(r));
5693 matrix D = mpNew(rVar(r),rVar(r));
5694
5695 for (i=1; i< rVar(r); i++)
5696 {
5697 for (j=i+1; j<=rVar(r); j++)
5698 {
5699 ni = r->N +1 - i;
5700 nj = r->N +1 - j; /* i<j ==> nj < ni */
5701
5702 assume(MATELEM(src->GetNC()->C,i,j) != NULL);
5703 MATELEM(C,nj,ni) = p_PermPoly(MATELEM(src->GetNC()->C,i,j),perm,src,r, nMap,par_perm,rPar(src));
5704
5705 if(MATELEM(src->GetNC()->D,i,j) != NULL)
5706 MATELEM(D,nj,ni) = p_PermPoly(MATELEM(src->GetNC()->D,i,j),perm,src,r, nMap,par_perm,rPar(src));
5707 }
5708 }
5709
5710 id_Test((ideal)C, r);
5711 id_Test((ideal)D, r);
5712
5713 if (nc_CallPlural(C, D, NULL, NULL, r, false, false, true, r)) // no qring setup!
5714 WarnS("Error initializing non-commutative multiplication!");
5715
5716#ifdef RDEBUG
5717 rTest(r);
5718// rWrite(r);
5719// rDebugPrint(r);
5720#endif
5721
5722 assume( r->GetNC()->IsSkewConstant == src->GetNC()->IsSkewConstant);
5723
5724 omFreeSize((ADDRESS)perm,(rVar(r)+1)*sizeof(int));
5725 }
5726#endif /* HAVE_PLURAL */
5727
5728 /* now oppose the qideal for qrings */
5729 if (src->qideal != NULL)
5730 {
5731#ifdef HAVE_PLURAL
5732 r->qideal = idOppose(src, src->qideal, r); // into the currRing: r
5733#else
5734 r->qideal = id_Copy(src->qideal, r); // ?
5735#endif
5736
5737#ifdef HAVE_PLURAL
5738 if( rIsPluralRing(r) )
5739 {
5741#ifdef RDEBUG
5742 rTest(r);
5743// rWrite(r);
5744// rDebugPrint(r);
5745#endif
5746 }
5747#endif
5748 }
5749#ifdef HAVE_PLURAL
5750 if( rIsPluralRing(r) )
5751 assume( ncRingType(r) == ncRingType(src) );
5752#endif
5753 rTest(r);
5754
5755 return r;
5756}
5757
5759 /* creates an enveloping algebra of R */
5760 /* that is R^e = R \tensor_K R^opp */
5761{
5762 ring Ropp = rOpposite(R);
5763 ring Renv = NULL;
5764 int stat = rSum(R, Ropp, Renv); /* takes care of qideals */
5765 if ( stat <=0 )
5766 WarnS("Error in rEnvelope at rSum");
5767 rTest(Renv);
5768 return Renv;
5769}
5770
5771#ifdef HAVE_PLURAL
5773/* returns TRUE is there were errors */
5774/* dest is actualy equals src with the different ordering */
5775/* we map src->nc correctly to dest->src */
5776/* to be executed after rComplete, before rChangeCurrRing */
5777{
5778// NOTE: Originally used only by idElimination to transfer NC structure to dest
5779// ring created by dirty hack (without nc_CallPlural)
5780 rTest(src);
5781
5782 assume(!rIsPluralRing(dest)); // destination must be a newly constructed commutative ring
5783
5784 if (!rIsPluralRing(src))
5785 {
5786 return FALSE;
5787 }
5788
5789 const int N = dest->N;
5790
5791 assume(src->N == N);
5792
5793// ring save = currRing;
5794
5795// if (dest != save)
5796// rChangeCurrRing(dest);
5797
5798 const ring srcBase = src;
5799
5800 assume( n_SetMap(srcBase->cf,dest->cf) == n_SetMap(dest->cf,dest->cf) ); // currRing is important here!
5801
5802 matrix C = mpNew(N,N); // ring independent
5803 matrix D = mpNew(N,N);
5804
5805 matrix C0 = src->GetNC()->C;
5806 matrix D0 = src->GetNC()->D;
5807
5808 // map C and D into dest
5809 for (int i = 1; i < N; i++)
5810 {
5811 for (int j = i + 1; j <= N; j++)
5812 {
5813 const number n = n_Copy(p_GetCoeff(MATELEM(C0,i,j), srcBase), srcBase->cf); // src, mapping for coeffs into currRing = dest!
5814 const poly p = p_NSet(n, dest);
5815 MATELEM(C,i,j) = p;
5816 if (MATELEM(D0,i,j) != NULL)
5817 MATELEM(D,i,j) = prCopyR(MATELEM(D0,i,j), srcBase, dest); // ?
5818 }
5819 }
5820 /* One must test C and D _only_ in r->GetNC()->basering!!! not in r!!! */
5821
5822 id_Test((ideal)C, dest);
5823 id_Test((ideal)D, dest);
5824
5825 if (nc_CallPlural(C, D, NULL, NULL, dest, bSetupQuotient, false, true, dest)) // also takes care about quotient ideal
5826 {
5827 //WarnS("Error transferring non-commutative structure");
5828 // error message should be in the interpreter interface
5829
5830 mp_Delete(&C, dest);
5831 mp_Delete(&D, dest);
5832
5833// if (currRing != save)
5834// rChangeCurrRing(save);
5835
5836 return TRUE;
5837 }
5838
5839// mp_Delete(&C, dest); // used by nc_CallPlural!
5840// mp_Delete(&D, dest);
5841
5842// if (dest != save)
5843// rChangeCurrRing(save);
5844
5845 assume(rIsPluralRing(dest));
5846 return FALSE;
5847}
5848#endif
5849
5850poly rGetVar(const int varIndex, const ring r)
5851{
5852 poly p = p_ISet(1, r);
5853 p_SetExp(p, varIndex, 1, r);
5854 p_Setm(p, r);
5855 return p;
5856}
5857
5858
5859/// TODO: rewrite somehow...
5860int n_IsParam(const number m, const ring r)
5861{
5862 assume(r != NULL);
5863 const coeffs C = r->cf;
5864 assume(C != NULL);
5865
5867
5869
5870 if(( _filed_type == n_algExt )||( _filed_type == n_polyExt ))
5871 return naIsParam(m, C);
5872
5873 if( _filed_type == n_transExt )
5874 return ntIsParam(m, C);
5875
5876 Werror("n_IsParam: IsParam is not to be used for (coeff_type = %d)",getCoeffType(C));
5877
5878 return 0;
5879}
5880
5881ring rPlusVar(const ring r, char *v,int left)
5882{
5883 if (r->order[2]!=0)
5884 {
5885 WerrorS("only for rings with an ordering of one block");
5886 return NULL;
5887 }
5888 int p;
5889 if((r->order[0]==ringorder_C)
5890 ||(r->order[0]==ringorder_c))
5891 p=1;
5892 else
5893 p=0;
5894 if((r->order[p]!=ringorder_dp)
5895 && (r->order[p]!=ringorder_Dp)
5896 && (r->order[p]!=ringorder_lp)
5897 && (r->order[p]!=ringorder_rp)
5898 && (r->order[p]!=ringorder_ds)
5899 && (r->order[p]!=ringorder_Ds)
5900 && (r->order[p]!=ringorder_ls))
5901 {
5902 WerrorS("ordering must be dp,Dp,lp,rp,ds,Ds or ls");
5903 return NULL;
5904 }
5905 for(int i=r->N-1;i>=0;i--)
5906 {
5907 if (strcmp(r->names[i],v)==0)
5908 {
5909 Werror("duplicate variable name >>%s<<",v);
5910 return NULL;
5911 }
5912 }
5913 ring R=rCopy0(r);
5914 char **names;
5915 #ifdef HAVE_SHIFTBBA
5916 if (rIsLPRing(r))
5917 {
5918 R->isLPring=r->isLPring+1;
5919 R->N=((r->N)/r->isLPring)+r->N;
5920 names=(char**)omAlloc(R->N*sizeof(char_ptr));
5921 if (left)
5922 {
5923 for(int b=0;b<((r->N)/r->isLPring);b++)
5924 {
5925 names[b*R->isLPring]=omStrDup(v);
5926 for(int i=R->isLPring-1;i>0;i--)
5927 names[i+b*R->isLPring]=R->names[i-1+b*r->isLPring];
5928 }
5929 }
5930 else
5931 {
5932 for(int b=0;b<((r->N)/r->isLPring);b++)
5933 {
5934 names[(b+1)*R->isLPring-1]=omStrDup(v);
5935 for(int i=R->isLPring-2;i>=0;i--)
5936 names[i+b*R->isLPring]=R->names[i+b*r->isLPring];
5937 }
5938 }
5939 }
5940 else
5941 #endif
5942 {
5943 R->N++;
5944 names=(char**)omAlloc(R->N*sizeof(char_ptr));
5945 if (left)
5946 {
5947 names[0]=omStrDup(v);
5948 for(int i=R->N-1;i>0;i--) names[i]=R->names[i-1];
5949 }
5950 else
5951 {
5952 names[R->N-1]=omStrDup(v);
5953 for(int i=R->N-2;i>=0;i--) names[i]=R->names[i];
5954 }
5955 }
5956 omFreeSize(R->names,r->N*sizeof(char_ptr));
5957 R->names=names;
5958 R->block1[p]=R->N;
5959 rComplete(R);
5960 return R;
5961}
5962
5963ring rMinusVar(const ring r, char *v)
5964{
5965 if (r->order[2]!=0)
5966 {
5967 WerrorS("only for rings with an ordering of one block");
5968 return NULL;
5969 }
5970 int p;
5971 if((r->order[0]==ringorder_C)
5972 ||(r->order[0]==ringorder_c))
5973 p=1;
5974 else
5975 p=0;
5976 if((r->order[p]!=ringorder_dp)
5977 && (r->order[p]!=ringorder_Dp)
5978 && (r->order[p]!=ringorder_lp)
5979 && (r->order[p]!=ringorder_rp)
5980 && (r->order[p]!=ringorder_ds)
5981 && (r->order[p]!=ringorder_Ds)
5982 && (r->order[p]!=ringorder_ls))
5983 {
5984 WerrorS("ordering must be dp,Dp,lp,rp,ds,Ds or ls");
5985 return NULL;
5986 }
5987 ring R=rCopy0(r);
5988 int i=R->N-1;
5989 while(i>=0)
5990 {
5991 if (strcmp(R->names[i],v)==0)
5992 {
5993 R->N--;
5994 omFree(R->names[i]);
5995 for(int j=i;j<R->N;j++) R->names[j]=R->names[j+1];
5996 R->names=(char**)omReallocSize(R->names,r->N*sizeof(char_ptr),R->N*sizeof(char_ptr));
5997 }
5998 i--;
5999 }
6000 R->block1[p]=R->N;
6001 rComplete(R,1);
6002 return R;
6003}
int sgn(const Rational &a)
Definition GMPrat.cc:430
int naIsParam(number m, const coeffs cf)
if m == var(i)/1 => return i,
Definition algext.cc:1106
All the auxiliary stuff.
long int64
Definition auxiliary.h:68
static int si_max(const int a, const int b)
Definition auxiliary.h:124
#define BIT_SIZEOF_LONG
Definition auxiliary.h:80
int BOOLEAN
Definition auxiliary.h:87
#define TRUE
Definition auxiliary.h:100
#define FALSE
Definition auxiliary.h:96
int size(const CanonicalForm &f, const Variable &v)
int size ( const CanonicalForm & f, const Variable & v )
Definition cf_ops.cc:600
const CanonicalForm CFMap CFMap & N
Definition cfEzgcd.cc:56
int l
Definition cfEzgcd.cc:100
int m
Definition cfEzgcd.cc:128
int i
Definition cfEzgcd.cc:132
int k
Definition cfEzgcd.cc:99
Variable x
Definition cfModGcd.cc:4090
int p
Definition cfModGcd.cc:4086
CanonicalForm cf
Definition cfModGcd.cc:4091
CanonicalForm b
Definition cfModGcd.cc:4111
int length() const
int length() const
Definition intvec.h:94
Coefficient rings, fields and other domains suitable for Singular polynomials.
static FORCE_INLINE number n_Copy(number n, const coeffs r)
return a copy of 'n'
Definition coeffs.h:455
static FORCE_INLINE void n_CoeffWrite(const coeffs r, BOOLEAN details=TRUE)
output the coeff description
Definition coeffs.h:720
static FORCE_INLINE BOOLEAN nCoeff_is_Extension(const coeffs r)
Definition coeffs.h:839
n_coeffType
Definition coeffs.h:27
@ n_R
single prescision (6,6) real numbers
Definition coeffs.h:31
@ n_polyExt
used to represent polys as coeffcients
Definition coeffs.h:34
@ n_Q
rational (GMP) numbers
Definition coeffs.h:30
@ n_Znm
only used if HAVE_RINGS is defined
Definition coeffs.h:45
@ n_algExt
used for all algebraic extensions, i.e., the top-most extension in an extension tower is algebraic
Definition coeffs.h:35
@ n_Zn
only used if HAVE_RINGS is defined
Definition coeffs.h:44
@ n_Zp
\F{p < 2^31}
Definition coeffs.h:29
@ n_transExt
used for all transcendental extensions, i.e., the top-most extension in an extension tower is transce...
Definition coeffs.h:38
static FORCE_INLINE char * nCoeffString(const coeffs cf)
TODO: make it a virtual method of coeffs, together with: Decompose & Compose, rParameter & rPar.
Definition coeffs.h:952
static FORCE_INLINE nMapFunc n_SetMap(const coeffs src, const coeffs dst)
set the mapping function pointers for translating numbers from src to dst
Definition coeffs.h:701
coeffs nInitChar(n_coeffType t, void *parameter)
one-time initialisations for new coeffs in case of an error return NULL
Definition numbers.cc:406
static FORCE_INLINE n_coeffType getCoeffType(const coeffs r)
Returns the type of coeffs domain.
Definition coeffs.h:429
static FORCE_INLINE coeffs nCopyCoeff(const coeffs r)
"copy" coeffs, i.e. increment ref
Definition coeffs.h:437
static FORCE_INLINE BOOLEAN nCoeff_is_algExt(const coeffs r)
TRUE iff r represents an algebraic extension field.
Definition coeffs.h:903
number(* nMapFunc)(number a, const coeffs src, const coeffs dst)
maps "a", which lives in src, into dst
Definition coeffs.h:80
void nKillChar(coeffs r)
undo all initialisations
Definition numbers.cc:556
static FORCE_INLINE BOOLEAN n_IsOne(number n, const coeffs r)
TRUE iff 'n' represents the one element.
Definition coeffs.h:472
#define Print
Definition emacs.cc:80
#define Warn
Definition emacs.cc:77
#define WarnS
Definition emacs.cc:78
#define StringAppend
Definition emacs.cc:79
const CanonicalForm int s
Definition facAbsFact.cc:51
CanonicalForm res
Definition facAbsFact.cc:60
const CanonicalForm & w
Definition facAbsFact.cc:51
const Variable & v
< [in] a sqrfree bivariate poly
Definition facBivar.h:39
bool found
int j
Definition facHensel.cc:110
static int min(int a, int b)
Definition fast_mult.cc:268
void WerrorS(const char *s)
Definition feFopen.cc:24
#define D(A)
Definition gentable.cc:126
#define EXTERN_VAR
Definition globaldefs.h:6
#define VAR
Definition globaldefs.h:5
ideal id_Copy(ideal h1, const ring r)
copy an ideal
static BOOLEAN length(leftv result, leftv arg)
Definition interval.cc:257
static bool rIsSCA(const ring r)
Definition nc.h:190
ideal idOppose(ring Rop_src, ideal I, const ring Rop_dst)
opposes a module I from Rop to currRing(dst)
bool nc_rCopy(ring res, const ring r, bool bSetupQuotient)
bool nc_SetupQuotient(ring rGR, const ring rG=NULL, bool bCopy=false)
static nc_type & ncRingType(nc_struct *p)
Definition nc.h:159
BOOLEAN nc_CallPlural(matrix cc, matrix dd, poly cn, poly dn, ring r, bool bSetupQuotient, bool bCopyInput, bool bBeQuiet, ring curr, bool dummy_ring=false)
returns TRUE if there were errors analyze inputs, check them for consistency detects nc_type,...
void nc_rKill(ring r)
complete destructor
#define UPMATELEM(i, j, nVar)
Definition nc.h:36
bool sca_Force(ring rGR, int b, int e)
Definition sca.cc:1159
void maFindPerm(char const *const *const preim_names, int preim_n, char const *const *const preim_par, int preim_p, char const *const *const names, int n, char const *const *const par, int nop, int *perm, int *par_perm, n_coeffType ch)
Definition maps.cc:163
void mp_Delete(matrix *a, const ring r)
Definition matpol.cc:873
matrix mpNew(int r, int c)
create a r x c zero-matrix
Definition matpol.cc:37
void iiWriteMatrix(matrix im, const char *n, int dim, const ring r, int spaces)
set spaces to zero by default
Definition matpol.cc:827
#define MATELEM(mat, i, j)
1-based access to matrix
Definition matpol.h:29
STATIC_VAR unsigned add[]
Definition misc_ip.cc:107
#define assume(x)
Definition mod2.h:387
int dReportError(const char *fmt,...)
Definition dError.cc:44
#define p_GetComp(p, r)
Definition monomials.h:64
#define pIter(p)
Definition monomials.h:37
#define POLYSIZE
Definition monomials.h:233
#define p_GetCoeff(p, r)
Definition monomials.h:50
gmp_float sqrt(const gmp_float &a)
const int MAX_INT_VAL
Definition mylimits.h:12
The main handler for Singular numbers which are suitable for Singular polynomials.
Definition qr.h:46
#define omStrDup(s)
#define omFreeSize(addr, size)
#define omCheckAddr(addr)
#define omAlloc(size)
#define omReallocSize(addr, o_size, size)
#define omAllocBin(bin)
#define omCheckAddrSize(addr, size)
#define omAlloc0Bin(bin)
#define omalloc(size)
#define omFree(addr)
#define omAlloc0(size)
#define omFreeBin(addr, bin)
#define omMemDup(s)
#define omcheckAddrSize(addr, size)
#define omfreeSize(addr, size)
#define omGetSpecBin(size)
Definition omBin.h:11
#define omUnGetSpecBin(bin_ptr)
Definition omBin.h:14
#define NULL
Definition omList.c:12
omBin_t * omBin
Definition omStructs.h:12
VAR unsigned si_opt_1
Definition options.c:5
#define OPT_INTSTRATEGY
Definition options.h:92
#define OPT_REDTAIL
Definition options.h:91
#define TEST_OPT_OLDSTD
Definition options.h:123
#define OPT_REDTHROUGH
Definition options.h:82
#define Sy_bit(x)
Definition options.h:31
#define TEST_OPT_PROT
Definition options.h:103
void p_ProcsSet(ring r, p_Procs_s *p_Procs)
void p_Debug_GetProcNames(const ring r, p_Procs_s *p_Procs)
void p_Debug_GetSpecNames(const ring r, const char *&field, const char *&length, const char *&ord)
void p_Setm_WFirstTotalDegree(poly p, const ring r)
Definition p_polys.cc:553
long pLDegb(poly p, int *l, const ring r)
Definition p_polys.cc:812
long pLDeg1_Totaldegree(poly p, int *l, const ring r)
Definition p_polys.cc:976
long p_WFirstTotalDegree(poly p, const ring r)
Definition p_polys.cc:595
long pLDeg1_WFirstTotalDegree(poly p, int *l, const ring r)
Definition p_polys.cc:1039
long pLDeg1c_WFirstTotalDegree(poly p, int *l, const ring r)
Definition p_polys.cc:1069
void p_Setm_Dummy(poly p, const ring r)
Definition p_polys.cc:540
void p_Setm_TotalDegree(poly p, const ring r)
Definition p_polys.cc:546
poly p_ISet(long i, const ring r)
returns the poly representing the integer i
Definition p_polys.cc:1298
long pLDeg1c_Deg(poly p, int *l, const ring r)
Definition p_polys.cc:942
long pLDeg1(poly p, int *l, const ring r)
Definition p_polys.cc:842
poly p_PermPoly(poly p, const int *perm, const ring oldRing, const ring dst, nMapFunc nMap, const int *par_perm, int OldPar, BOOLEAN use_mult)
Definition p_polys.cc:4151
long pLDeg1_Deg(poly p, int *l, const ring r)
Definition p_polys.cc:911
long p_WTotaldegree(poly p, const ring r)
Definition p_polys.cc:612
p_SetmProc p_GetSetmProc(const ring r)
Definition p_polys.cc:559
void p_Setm_General(poly p, const ring r)
Definition p_polys.cc:158
long pLDeg1c(poly p, int *l, const ring r)
Definition p_polys.cc:878
long pLDeg1c_Totaldegree(poly p, int *l, const ring r)
Definition p_polys.cc:1006
long pLDeg0c(poly p, int *l, const ring r)
Definition p_polys.cc:771
long pLDeg0(poly p, int *l, const ring r)
Definition p_polys.cc:740
poly p_One(const ring r)
Definition p_polys.cc:1314
poly p_NSet(number n, const ring r)
returns the poly representing the number n, destroys n
Definition p_polys.cc:1474
long p_Deg(poly a, const ring r)
Definition p_polys.cc:586
BOOLEAN p_EqualPolys(poly p1, poly p2, const ring r)
Definition p_polys.cc:4561
static long p_FDeg(const poly p, const ring r)
Definition p_polys.h:380
void p_Write(poly p, ring lmRing, ring tailRing)
Definition polys0.cc:342
static unsigned long p_SetExp(poly p, const unsigned long e, const unsigned long iBitmask, const int VarOffset)
set a single variable exponent @Note: VarOffset encodes the position in p->exp
Definition p_polys.h:488
static void p_Setm(poly p, const ring r)
Definition p_polys.h:233
static long p_GetExp(const poly p, const unsigned long iBitmask, const int VarOffset)
get a single variable exponent @Note: the integer VarOffset encodes:
Definition p_polys.h:469
static void p_Delete(poly *p, const ring r)
Definition p_polys.h:901
void p_Write0(poly p, ring lmRing, ring tailRing)
Definition polys0.cc:332
static long p_Totaldegree(poly p, const ring r)
Definition p_polys.h:1521
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:3364
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:2496
int rSum(ring r1, ring r2, ring &sum)
Definition ring.cc:1405
ring rAssure_TDeg(ring r, int &pos)
Definition ring.cc:4558
void rWrite(ring r, BOOLEAN details)
Definition ring.cc:227
ring rAssure_InducedSchreyerOrdering(const ring r, BOOLEAN complete, int sgn)
Definition ring.cc:4928
static ring rAssure_Global(rRingOrder_t b1, rRingOrder_t b2, const ring r)
Definition ring.cc:4835
BOOLEAN rOrder_is_WeightedOrdering(rRingOrder_t order)
Definition ring.cc:1950
void rGetSComps(int **currComponents, long **currShiftedComponents, int *length, ring r)
Definition ring.cc:4445
BOOLEAN rRing_ord_pure_Dp(const ring r)
Definition ring.cc:5285
static void rNChangeSComps(int *currComponents, long *currShiftedComponents, ring r)
Definition ring.cc:4398
ring rModifyRing_Wp(ring r, int *weights)
construct Wp, C ring
Definition ring.cc:2962
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:5315
static void rSetOption(ring r)
Definition ring.cc:3401
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:3465
int r_IsRingVar(const char *n, char **names, int N)
Definition ring.cc:213
#define rOppVar(R, I)
Definition ring.cc:5361
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:5083
static void rNGetSComps(int **currComponents, long **currShiftedComponents, ring r)
Definition ring.cc:4406
#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:2306
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:3432
ring rAssure_SyzComp(const ring r, BOOLEAN complete)
Definition ring.cc:4466
BOOLEAN nc_rComplete(const ring src, ring dest, bool bSetupQuotient)
Definition ring.cc:5772
void p_DebugPrint(poly p, const ring r)
Definition ring.cc:4358
void rKillModifiedRing(ring r)
Definition ring.cc:3076
BOOLEAN rRing_ord_pure_dp(const ring r)
Definition ring.cc:5275
static void rSetVarL(ring r)
set r->VarL_Size, r->VarL_Offset, r->VarL_LowIndex
Definition ring.cc:4058
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:2356
const char * rSimpleOrdStr(int ord)
Definition ring.cc:78
ring rAssure_Wp_C(const ring r, intvec *w)
Definition ring.cc:4881
BOOLEAN rOrd_is_MixedDegree_Ordering(ring r)
Definition ring.cc:3443
static void rDBChangeSComps(int *currComponents, long *currShiftedComponents, int length, ring r)
Definition ring.cc:4414
ring rAssure_c_dp(const ring r)
Definition ring.cc:5073
static void rSetOutParams(ring r)
Definition ring.cc:3097
static void rSetDegStuff(ring r)
Definition ring.cc:3194
static void rDBGetSComps(int **currComponents, long **currShiftedComponents, int *length, ring r)
Definition ring.cc:4424
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:3996
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:5348
static void rO_WDegree_neg(int &place, int &bitplace, int start, int end, long *o, sro_ord &ord_struct, int *weights)
Definition ring.cc:2330
void rKillModified_Wp_Ring(ring r)
Definition ring.cc:3086
ring rMinusVar(const ring r, char *v)
undo rPlusVar
Definition ring.cc:5963
BOOLEAN rRing_has_CompLastBlock(const ring r)
Definition ring.cc:5268
ring rAssure_Dp_C(const ring r)
Definition ring.cc:5063
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:2432
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:2715
ring rAssure_SyzOrder(const ring r, BOOLEAN complete)
Definition ring.cc:4461
static void rO_TDegree(int &place, int &bitplace, int start, int end, long *o, sro_ord &ord_struct)
Definition ring.cc:2216
ring rAssure_C_dp(const ring r)
Definition ring.cc:5068
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:5241
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:5115
char * rString(ring r)
Definition ring.cc:676
ring rAssure_HasComp(const ring r)
Definition ring.cc:4656
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:2284
static void rO_Syz(int &place, int &bitplace, int &prev_ord, int syz_comp, long *o, sro_ord &ord_struct)
Definition ring.cc:2447
BOOLEAN rHas_c_Ordering(const ring r)
Definition ring.cc:1886
static int rRealloc1(ring r, int size, int pos)
Definition ring.cc:5325
#define pFDeg_CASE(A)
static unsigned long rGetExpSize(unsigned long bitmask, int &bits)
Definition ring.cc:2587
void rDebugPrint(const ring r)
Definition ring.cc:4153
static void rCheckOrdSgn(ring r, int i)
Definition ring.cc:3883
BOOLEAN rRing_ord_pure_lp(const ring r)
Definition ring.cc:5295
poly rGetVar(const int varIndex, const ring r)
Definition ring.cc:5850
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:3010
void rChangeSComps(int *currComponents, long *currShiftedComponents, int length, ring r)
Definition ring.cc:4436
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:4381
static unsigned long rGetDivMask(int bits)
get r->divmask depending on bits per exponent
Definition ring.cc:4139
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:4780
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:3167
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:5364
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:4113
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:5881
ring rAssure_CompLastBlock(ring r, BOOLEAN complete)
makes sure that c/C ordering is last ordering
Definition ring.cc:4725
static void rO_ISPrefix(int &place, int &bitplace, int &prev_ord, long *o, int N, int *v, sro_ord &ord_struct)
Definition ring.cc:2473
static void rO_Align(int &place, int &bitplace)
Definition ring.cc:2205
ring rAssure_dp_S(const ring r)
Definition ring.cc:5053
BOOLEAN rOrd_is_ds(const ring r)
Definition ring.cc:2036
static void rO_TDegree_neg(int &place, int &bitplace, int start, int end, long *o, sro_ord &ord_struct)
Definition ring.cc:2230
static void rSetFirstWv(ring r, int i, rRingOrder_t *order, int *block0, int *block1, int **wvhdl)
Definition ring.cc:3135
ring rEnvelope(ring R)
Definition ring.cc:5758
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:5169
static const char *const ringorder_name[]
Definition ring.cc:47
static int sign(int x)
Definition ring.cc:3442
static void rO_WDegree(int &place, int &bitplace, int start, int end, long *o, sro_ord &ord_struct, int *weights)
Definition ring.cc:2244
BOOLEAN rOrd_is_WeightedDegree_Ordering(const ring r)
Definition ring.cc:2044
int n_IsParam(const number m, const ring r)
TODO: rewrite somehow...
Definition ring.cc:5860
int64 * rGetWeightVec(const ring r)
Definition ring.cc:5305
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:2393
ring rAssure_dp_C(const ring r)
Definition ring.cc:5058
ring rCopy(ring r)
Definition ring.cc:1734
VAR int pDBsyzComp
Definition ring.cc:5165
BOOLEAN rDBTest(ring r, const char *fn, const int l)
Definition ring.cc:2055
#define ringorder_rp
Definition ring.h:99
struct p_Procs_s p_Procs_s
Definition ring.h:23
static BOOLEAN rIsPluralRing(const ring r)
we must always have this test!
Definition ring.h:405
ro_typ ord_typ
Definition ring.h:225
static int rBlocks(const ring r)
Definition ring.h:573
static ring rIncRefCnt(ring r)
Definition ring.h:846
static int rPar(const ring r)
(r->cf->P)
Definition ring.h:604
@ ro_wp64
Definition ring.h:55
@ ro_syz
Definition ring.h:60
@ ro_cp
Definition ring.h:58
@ ro_dp
Definition ring.h:52
@ ro_is
Definition ring.h:61
@ ro_wp_neg
Definition ring.h:56
@ ro_wp
Definition ring.h:53
@ ro_isTemp
Definition ring.h:61
@ ro_am
Definition ring.h:54
@ ro_syzcomp
Definition ring.h:59
static BOOLEAN rIsLPRing(const ring r)
Definition ring.h:416
rRingOrder_t
order stuff
Definition ring.h:68
@ ringorder_lp
Definition ring.h:77
@ ringorder_a
Definition ring.h:70
@ ringorder_am
Definition ring.h:89
@ ringorder_a64
for int64 weights
Definition ring.h:71
@ ringorder_C
Definition ring.h:73
@ ringorder_S
S?
Definition ring.h:75
@ ringorder_ds
Definition ring.h:85
@ ringorder_Dp
Definition ring.h:80
@ ringorder_unspec
Definition ring.h:95
@ ringorder_L
Definition ring.h:90
@ ringorder_Ds
Definition ring.h:86
@ ringorder_Ip
Definition ring.h:83
@ ringorder_dp
Definition ring.h:78
@ ringorder_c
Definition ring.h:72
@ ringorder_aa
for idElimination, like a, except pFDeg, pWeigths ignore it
Definition ring.h:92
@ ringorder_no
Definition ring.h:69
@ ringorder_Wp
Definition ring.h:82
@ ringorder_ip
Definition ring.h:79
@ ringorder_is
opposite of ls
Definition ring.h:93
@ ringorder_ws
Definition ring.h:87
@ ringorder_Ws
Definition ring.h:88
@ ringorder_IS
Induced (Schreyer) ordering.
Definition ring.h:94
@ ringorder_ls
degree, ip
Definition ring.h:84
@ ringorder_s
s?
Definition ring.h:76
@ ringorder_wp
Definition ring.h:81
@ ringorder_M
Definition ring.h:74
static BOOLEAN rField_is_Q(const ring r)
Definition ring.h:511
#define ringorder_rs
Definition ring.h:100
static BOOLEAN rShortOut(const ring r)
Definition ring.h:586
rOrderType_t
Definition ring.h:103
@ rOrderType_CompExp
simple ordering, component has priority
Definition ring.h:105
@ rOrderType_Exp
simple ordering, exponent vector has priority component is compatible with exp-vector order
Definition ring.h:108
@ rOrderType_General
non-simple ordering as specified by currRing
Definition ring.h:104
@ rOrderType_ExpComp
simple ordering, exponent vector has priority component not compatible with exp-vector order
Definition ring.h:106
static BOOLEAN rIsNCRing(const ring r)
Definition ring.h:426
static char const ** rParameter(const ring r)
(r->cf->parameter)
Definition ring.h:630
static BOOLEAN rCanShortOut(const ring r)
Definition ring.h:591
static short rVar(const ring r)
#define rVar(r) (r->N)
Definition ring.h:597
#define rTest(r)
Definition ring.h:791
#define rField_is_Ring(R)
Definition ring.h:490
ideal SCAQuotient(const ring r)
Definition sca.h:10
static short scaLastAltVar(ring r)
Definition sca.h:25
static short scaFirstAltVar(ring r)
Definition sca.h:18
ideal idInit(int idsize, int rank)
initialise an ideal / module
void id_Delete(ideal *h, ring r)
deletes an ideal/module/matrix
long id_RankFreeModule(ideal s, ring lmRing, ring tailRing)
return the maximal component number found in any polynomial in s
void idShow(const ideal id, const ring lmRing, const ring tailRing, const int debugPrint)
ideal id_SimpleAdd(ideal h1, ideal h2, const ring R)
concat the lists h1 and h2 without zeros
#define IDELEMS(i)
#define id_Test(A, lR)
#define R
Definition sirandom.c:27
#define A
Definition sirandom.c:24
#define Q
Definition sirandom.c:26
Definition nc.h:68
#define loop
Definition structs.h:75
EXTERN_VAR long * currShiftedComponents
Definition syz.h:118
int ntIsParam(number m, const coeffs cf)
if m == var(i)/1 => return i,
Definition transext.cc:2308