Annotation of OpenXM_contrib2/asir2018/builtin/dp-supp.c, Revision 1.1
1.1 ! noro 1: /*
! 2: * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
! 3: * All rights reserved.
! 4: *
! 5: * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
! 6: * non-exclusive and royalty-free license to use, copy, modify and
! 7: * redistribute, solely for non-commercial and non-profit purposes, the
! 8: * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
! 9: * conditions of this Agreement. For the avoidance of doubt, you acquire
! 10: * only a limited right to use the SOFTWARE hereunder, and FLL or any
! 11: * third party developer retains all rights, including but not limited to
! 12: * copyrights, in and to the SOFTWARE.
! 13: *
! 14: * (1) FLL does not grant you a license in any way for commercial
! 15: * purposes. You may use the SOFTWARE only for non-commercial and
! 16: * non-profit purposes only, such as academic, research and internal
! 17: * business use.
! 18: * (2) The SOFTWARE is protected by the Copyright Law of Japan and
! 19: * international copyright treaties. If you make copies of the SOFTWARE,
! 20: * with or without modification, as permitted hereunder, you shall affix
! 21: * to all such copies of the SOFTWARE the above copyright notice.
! 22: * (3) An explicit reference to this SOFTWARE and its copyright owner
! 23: * shall be made on your publication or presentation in any form of the
! 24: * results obtained by use of the SOFTWARE.
! 25: * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
! 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
! 27: * for such modification or the source code of the modified part of the
! 28: * SOFTWARE.
! 29: *
! 30: * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
! 31: * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
! 32: * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
! 33: * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
! 34: * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
! 35: * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
! 36: * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
! 37: * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
! 38: * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
! 39: * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
! 40: * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
! 41: * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
! 42: * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
! 43: * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
! 44: * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
! 45: * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
! 46: * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
! 47: *
! 48: * $OpenXM$
! 49: */
! 50: #include "ca.h"
! 51: #include "base.h"
! 52: #include "inline.h"
! 53: #include "parse.h"
! 54: #include "ox.h"
! 55:
! 56: #define HMAG(p) (p_mag((P)BDY(p)->c))
! 57:
! 58: extern int (*cmpdl)();
! 59: extern double pz_t_e,pz_t_d,pz_t_d1,pz_t_c;
! 60: extern int dp_nelim,dp_fcoeffs;
! 61: extern int NoGCD;
! 62: extern int GenTrace;
! 63: extern NODE TraceList;
! 64:
! 65: int show_orderspec;
! 66:
! 67: void print_composite_order_spec(struct order_spec *spec);
! 68: void dpm_rest(DPM,DPM *);
! 69:
! 70: /*
! 71: * content reduction
! 72: *
! 73: */
! 74:
! 75: static NODE RatDenomList;
! 76:
! 77: void init_denomlist()
! 78: {
! 79: RatDenomList = 0;
! 80: }
! 81:
! 82: void add_denomlist(P f)
! 83: {
! 84: NODE n;
! 85:
! 86: if ( OID(f)==O_P ) {
! 87: MKNODE(n,f,RatDenomList); RatDenomList = n;
! 88: }
! 89: }
! 90:
! 91: LIST get_denomlist()
! 92: {
! 93: LIST l;
! 94:
! 95: MKLIST(l,RatDenomList); RatDenomList = 0;
! 96: return l;
! 97: }
! 98:
! 99: void dp_ptozp(DP p,DP *rp)
! 100: {
! 101: MP m,mr,mr0;
! 102: int i,n;
! 103: Q *w;
! 104: Z dvr;
! 105: P t;
! 106:
! 107: if ( !p )
! 108: *rp = 0;
! 109: else {
! 110: for ( m =BDY(p), n = 0; m; m = NEXT(m), n++ );
! 111: w = (Q *)ALLOCA(n*sizeof(Q));
! 112: for ( m =BDY(p), i = 0; i < n; m = NEXT(m), i++ )
! 113: if ( NUM(m->c) )
! 114: w[i] = (Q)m->c;
! 115: else
! 116: ptozp((P)m->c,1,&w[i],&t);
! 117: sortbynm(w,n);
! 118: qltozl(w,n,&dvr);
! 119: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
! 120: NEXTMP(mr0,mr); divsp(CO,(P)m->c,(P)dvr,(P *)&mr->c); mr->dl = m->dl;
! 121: }
! 122: NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
! 123: }
! 124: }
! 125:
! 126: void dp_ptozp2(DP p0,DP p1,DP *hp,DP *rp)
! 127: {
! 128: DP t,s,h,r;
! 129: MP m,mr,mr0,m0;
! 130:
! 131: addd(CO,p0,p1,&t); dp_ptozp(t,&s);
! 132: if ( !p0 ) {
! 133: h = 0; r = s;
! 134: } else if ( !p1 ) {
! 135: h = s; r = 0;
! 136: } else {
! 137: for ( mr0 = 0, m = BDY(s), m0 = BDY(p0); m0;
! 138: m = NEXT(m), m0 = NEXT(m0) ) {
! 139: NEXTMP(mr0,mr); mr->c = m->c; mr->dl = m->dl;
! 140: }
! 141: NEXT(mr) = 0; MKDP(p0->nv,mr0,h); MKDP(p0->nv,m,r);
! 142: }
! 143: if ( h )
! 144: h->sugar = p0->sugar;
! 145: if ( r )
! 146: r->sugar = p1->sugar;
! 147: *hp = h; *rp = r;
! 148: }
! 149:
! 150: void dpm_ptozp(DPM p,DPM *rp)
! 151: {
! 152: DMM m,mr,mr0;
! 153: int i,n;
! 154: Q *w;
! 155: Z dvr;
! 156: P t;
! 157:
! 158: if ( !p )
! 159: *rp = 0;
! 160: else {
! 161: for ( m =BDY(p), n = 0; m; m = NEXT(m), n++ );
! 162: w = (Q *)ALLOCA(n*sizeof(Q));
! 163: for ( m =BDY(p), i = 0; i < n; m = NEXT(m), i++ )
! 164: if ( NUM(m->c) )
! 165: w[i] = (Q)m->c;
! 166: else
! 167: ptozp((P)m->c,1,&w[i],&t);
! 168: sortbynm(w,n);
! 169: qltozl(w,n,&dvr);
! 170: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
! 171: NEXTDMM(mr0,mr); divsp(CO,(P)m->c,(P)dvr,(P *)&mr->c); mr->dl = m->dl; mr->pos = m->pos;
! 172: }
! 173: NEXT(mr) = 0; MKDPM(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
! 174: }
! 175: }
! 176:
! 177: void dpm_ptozp2(DPM p0,DPM p1,DPM *hp,DPM *rp)
! 178: {
! 179: DPM t,s,h,r;
! 180: DMM m,mr,mr0,m0;
! 181:
! 182: adddpm(CO,p0,p1,&t); dpm_ptozp(t,&s);
! 183: if ( !p0 ) {
! 184: h = 0; r = s;
! 185: } else if ( !p1 ) {
! 186: h = s; r = 0;
! 187: } else {
! 188: for ( mr0 = 0, m = BDY(s), m0 = BDY(p0); m0;
! 189: m = NEXT(m), m0 = NEXT(m0) ) {
! 190: NEXTDMM(mr0,mr); mr->c = m->c; mr->dl = m->dl; mr->pos = m->pos;
! 191: }
! 192: NEXT(mr) = 0; MKDPM(p0->nv,mr0,h); MKDPM(p0->nv,m,r);
! 193: }
! 194: if ( h )
! 195: h->sugar = p0->sugar;
! 196: if ( r )
! 197: r->sugar = p1->sugar;
! 198: *hp = h; *rp = r;
! 199: }
! 200:
! 201:
! 202: void dp_ptozp3(DP p,Z *dvr,DP *rp)
! 203: {
! 204: MP m,mr,mr0;
! 205: int i,n;
! 206: Q *w;
! 207: P t;
! 208:
! 209: if ( !p ) {
! 210: *rp = 0; *dvr = 0;
! 211: }else {
! 212: for ( m =BDY(p), n = 0; m; m = NEXT(m), n++ );
! 213: w = (Q *)ALLOCA(n*sizeof(Q));
! 214: for ( m =BDY(p), i = 0; i < n; m = NEXT(m), i++ )
! 215: if ( NUM(m->c) )
! 216: w[i] = (Q)m->c;
! 217: else
! 218: ptozp((P)m->c,1,&w[i],&t);
! 219: sortbynm(w,n);
! 220: qltozl(w,n,dvr);
! 221: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
! 222: NEXTMP(mr0,mr); divsp(CO,(P)m->c,(P)(*dvr),(P *)&mr->c); mr->dl = m->dl;
! 223: }
! 224: NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
! 225: }
! 226: }
! 227:
! 228: void dp_idiv(DP p,Z c,DP *rp)
! 229: {
! 230: MP mr0,m,mr;
! 231:
! 232: if ( !p )
! 233: *rp = 0;
! 234: else if ( MUNIQ((Q)c) )
! 235: *rp = p;
! 236: else if ( MUNIQ((Q)c) )
! 237: chsgnd(p,rp);
! 238: else {
! 239: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
! 240: NEXTMP(mr0,mr);
! 241: divz((Z)(m->c),c,(Z *)&mr->c);
! 242: mr->dl = m->dl;
! 243: }
! 244: NEXT(mr) = 0; MKDP(p->nv,mr0,*rp);
! 245: if ( *rp )
! 246: (*rp)->sugar = p->sugar;
! 247: }
! 248: }
! 249:
! 250: void dp_mbase(NODE hlist,NODE *mbase)
! 251: {
! 252: DL *dl;
! 253: DL d;
! 254: int *t;
! 255: int i,j,k,n,nvar,td;
! 256:
! 257: n = length(hlist); nvar = ((DP)BDY(hlist))->nv;
! 258: dl = (DL *)MALLOC(n*sizeof(DL));
! 259: NEWDL(d,nvar); *mbase = 0;
! 260: for ( i = 0; i < n; i++, hlist = NEXT(hlist) ) {
! 261: dl[i] = BDY((DP)BDY(hlist))->dl;
! 262: /* trivial ideal check */
! 263: if ( (*cmpdl)(nvar,d,dl[i]) == 0 ) {
! 264: return;
! 265: }
! 266: }
! 267: /* zero-dim. ideal check */
! 268: for ( i = 0; i < nvar; i++ ) {
! 269: for ( j = 0; j < n; j++ ) {
! 270: for ( k = 0, t = dl[j]->d; k < nvar; k++ )
! 271: if ( k != i && t[k] != 0 ) break;
! 272: if ( k == nvar ) break;
! 273: }
! 274: if ( j == n )
! 275: error("dp_mbase : input ideal is not zero-dimensional");
! 276: }
! 277: while ( 1 ) {
! 278: insert_to_node(d,mbase,nvar);
! 279: for ( i = nvar-1; i >= 0; ) {
! 280: d->d[i]++;
! 281: d->td += MUL_WEIGHT(1,i);
! 282: for ( j = 0; j < n; j++ ) {
! 283: if ( _dl_redble(dl[j],d,nvar) )
! 284: break;
! 285: }
! 286: if ( j < n ) {
! 287: for ( j = nvar-1; j >= i; j-- )
! 288: d->d[j] = 0;
! 289: for ( j = 0, td = 0; j < i; j++ )
! 290: td += MUL_WEIGHT(d->d[j],j);
! 291: d->td = td;
! 292: i--;
! 293: } else
! 294: break;
! 295: }
! 296: if ( i < 0 )
! 297: break;
! 298: }
! 299: }
! 300:
! 301: int _dl_redble(DL d1,DL d2,int nvar)
! 302: {
! 303: int i;
! 304:
! 305: if ( d1->td > d2->td )
! 306: return 0;
! 307: for ( i = 0; i < nvar; i++ )
! 308: if ( d1->d[i] > d2->d[i] )
! 309: break;
! 310: if ( i < nvar )
! 311: return 0;
! 312: else
! 313: return 1;
! 314: }
! 315:
! 316: void insert_to_node(DL d,NODE *n,int nvar)
! 317: {
! 318: DL d1;
! 319: MP m;
! 320: DP dp;
! 321: NODE n0,n1,n2;
! 322:
! 323: NEWDL(d1,nvar); d1->td = d->td;
! 324: bcopy((char *)d->d,(char *)d1->d,nvar*sizeof(int));
! 325: NEWMP(m); m->dl = d1; m->c = (Obj)ONE; NEXT(m) = 0;
! 326: MKDP(nvar,m,dp); dp->sugar = d->td;
! 327: if ( !(*n) ) {
! 328: MKNODE(n1,dp,0); *n = n1;
! 329: } else {
! 330: for ( n1 = *n, n0 = 0; n1; n0 = n1, n1 = NEXT(n1) )
! 331: if ( (*cmpdl)(nvar,d,BDY((DP)BDY(n1))->dl) > 0 ) {
! 332: MKNODE(n2,dp,n1);
! 333: if ( !n0 )
! 334: *n = n2;
! 335: else
! 336: NEXT(n0) = n2;
! 337: break;
! 338: }
! 339: if ( !n1 ) {
! 340: MKNODE(n2,dp,0); NEXT(n0) = n2;
! 341: }
! 342: }
! 343: }
! 344:
! 345: void dp_vtod(Q *c,DP p,DP *rp)
! 346: {
! 347: MP mr0,m,mr;
! 348: int i;
! 349:
! 350: if ( !p )
! 351: *rp = 0;
! 352: else {
! 353: for ( mr0 = 0, m = BDY(p), i = 0; m; m = NEXT(m), i++ ) {
! 354: NEXTMP(mr0,mr); mr->c = (Obj)c[i]; mr->dl = m->dl;
! 355: }
! 356: NEXT(mr) = 0; MKDP(p->nv,mr0,*rp);
! 357: (*rp)->sugar = p->sugar;
! 358: }
! 359: }
! 360:
! 361: int have_sf_coef(P p)
! 362: {
! 363: DCP dc;
! 364:
! 365: if ( !p )
! 366: return 0;
! 367: else if ( NUM(p) )
! 368: return NID((Num)p) == N_GFS ? 1 : 0;
! 369: else {
! 370: for ( dc = DC(p); dc; dc = NEXT(dc) )
! 371: if ( have_sf_coef(COEF(dc)) )
! 372: return 1;
! 373: return 0;
! 374: }
! 375: }
! 376:
! 377: void head_coef(P p,Num *c)
! 378: {
! 379: if ( !p )
! 380: *c = 0;
! 381: else if ( NUM(p) )
! 382: *c = (Num)p;
! 383: else
! 384: head_coef(COEF(DC(p)),c);
! 385: }
! 386:
! 387: void dp_monic_sf(DP p,DP *rp)
! 388: {
! 389: Num c;
! 390:
! 391: if ( !p )
! 392: *rp = 0;
! 393: else {
! 394: head_coef((P)BDY(p)->c,&c);
! 395: divsdc(CO,p,(P)c,rp);
! 396: }
! 397: }
! 398:
! 399: void dp_prim(DP p,DP *rp)
! 400: {
! 401: P t,g;
! 402: DP p1;
! 403: MP m,mr,mr0;
! 404: int i,n;
! 405: P *w;
! 406: Q *c;
! 407: Z dvr;
! 408: NODE tn;
! 409:
! 410: if ( !p )
! 411: *rp = 0;
! 412: else if ( dp_fcoeffs == N_GFS ) {
! 413: for ( m = BDY(p); m; m = NEXT(m) )
! 414: if ( OID(m->c) == O_N ) {
! 415: /* GCD of coeffs = 1 */
! 416: dp_monic_sf(p,rp);
! 417: return;
! 418: } else break;
! 419: /* compute GCD over the finite fieid */
! 420: for ( m = BDY(p), n = 0; m; m = NEXT(m), n++ );
! 421: w = (P *)ALLOCA(n*sizeof(P));
! 422: for ( m = BDY(p), i = 0; i < n; m = NEXT(m), i++ )
! 423: w[i] = (P)m->c;
! 424: gcdsf(CO,w,n,&g);
! 425: if ( NUM(g) )
! 426: dp_monic_sf(p,rp);
! 427: else {
! 428: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
! 429: NEXTMP(mr0,mr); divsp(CO,(P)m->c,g,(P *)&mr->c); mr->dl = m->dl;
! 430: }
! 431: NEXT(mr) = 0; MKDP(p->nv,mr0,p1); p1->sugar = p->sugar;
! 432: dp_monic_sf(p1,rp);
! 433: }
! 434: return;
! 435: } else if ( dp_fcoeffs )
! 436: *rp = p;
! 437: else if ( NoGCD )
! 438: dp_ptozp(p,rp);
! 439: else {
! 440: dp_ptozp(p,&p1); p = p1;
! 441: for ( m = BDY(p), n = 0; m; m = NEXT(m), n++ );
! 442: if ( n == 1 ) {
! 443: m = BDY(p);
! 444: NEWMP(mr); mr->dl = m->dl; mr->c = (Obj)ONE; NEXT(mr) = 0;
! 445: MKDP(p->nv,mr,*rp); (*rp)->sugar = p->sugar;
! 446: return;
! 447: }
! 448: w = (P *)ALLOCA(n*sizeof(P));
! 449: c = (Q *)ALLOCA(n*sizeof(Q));
! 450: for ( m =BDY(p), i = 0; i < n; m = NEXT(m), i++ )
! 451: if ( NUM(m->c) ) {
! 452: c[i] = (Q)m->c; w[i] = (P)ONE;
! 453: } else
! 454: ptozp((P)m->c,1,&c[i],&w[i]);
! 455: qltozl(c,n,&dvr); heu_nezgcdnpz(CO,w,n,&t); mulp(CO,t,(P)dvr,&g);
! 456: if ( NUM(g) )
! 457: *rp = p;
! 458: else {
! 459: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
! 460: NEXTMP(mr0,mr); divsp(CO,(P)m->c,g,(P *)&mr->c); mr->dl = m->dl;
! 461: }
! 462: NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
! 463: add_denomlist(g);
! 464: }
! 465: }
! 466: }
! 467:
! 468: void heu_nezgcdnpz(VL vl,P *pl,int m,P *pr)
! 469: {
! 470: int i,r;
! 471: P gcd,t,s1,s2,u;
! 472: Z rq;
! 473: DCP dc;
! 474: extern int DP_Print;
! 475:
! 476: while ( 1 ) {
! 477: for ( i = 0, s1 = 0; i < m; i++ ) {
! 478: r = random(); UTOQ(r,rq);
! 479: mulp(vl,pl[i],(P)rq,&t); addp(vl,s1,t,&u); s1 = u;
! 480: }
! 481: for ( i = 0, s2 = 0; i < m; i++ ) {
! 482: r = random(); UTOQ(r,rq);
! 483: mulp(vl,pl[i],(P)rq,&t); addp(vl,s2,t,&u); s2 = u;
! 484: }
! 485: ezgcdp(vl,s1,s2,&gcd);
! 486: if ( DP_Print > 2 )
! 487: { fprintf(asir_out,"(%d)",nmonop(gcd)); fflush(asir_out); }
! 488: for ( i = 0; i < m; i++ ) {
! 489: if ( !divtpz(vl,pl[i],gcd,&t) )
! 490: break;
! 491: }
! 492: if ( i == m )
! 493: break;
! 494: }
! 495: *pr = gcd;
! 496: }
! 497:
! 498: void dp_prim_mod(DP p,int mod,DP *rp)
! 499: {
! 500: P t,g;
! 501: MP m,mr,mr0;
! 502:
! 503: if ( !p )
! 504: *rp = 0;
! 505: else if ( NoGCD )
! 506: *rp = p;
! 507: else {
! 508: for ( m = BDY(p), g = (P)m->c, m = NEXT(m); m; m = NEXT(m) ) {
! 509: gcdprsmp(CO,mod,g,(P)m->c,&t); g = t;
! 510: }
! 511: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
! 512: NEXTMP(mr0,mr); divsmp(CO,mod,(P)m->c,g,(P *)&mr->c); mr->dl = m->dl;
! 513: }
! 514: NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
! 515: }
! 516: }
! 517:
! 518: void dp_cont(DP p,Z *rp)
! 519: {
! 520: VECT v;
! 521:
! 522: dp_dtov(p,&v); gcdvz(v,rp);
! 523: }
! 524:
! 525: void dp_dtov(DP dp,VECT *rp)
! 526: {
! 527: MP m,t;
! 528: int i,n;
! 529: VECT v;
! 530: pointer *p;
! 531:
! 532: m = BDY(dp);
! 533: for ( t = m, n = 0; t; t = NEXT(t), n++ );
! 534: MKVECT(v,n);
! 535: for ( i = 0, p = BDY(v), t = m; i < n; t = NEXT(t), i++ )
! 536: p[i] = (pointer)(t->c);
! 537: *rp = v;
! 538: }
! 539:
! 540: /*
! 541: * s-poly computation
! 542: *
! 543: */
! 544:
! 545: void dp_sp(DP p1,DP p2,DP *rp)
! 546: {
! 547: int i,n,td;
! 548: int *w;
! 549: DL d1,d2,d;
! 550: MP m;
! 551: DP t,s1,s2,u;
! 552: Z c,c1,c2;
! 553: Z gn;
! 554:
! 555: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 556: w = (int *)ALLOCA(n*sizeof(int));
! 557: for ( i = 0, td = 0; i < n; i++ ) {
! 558: w[i] = MAX(d1->d[i],d2->d[i]); td += MUL_WEIGHT(w[i],i);
! 559: }
! 560:
! 561: NEWDL(d,n); d->td = td - d1->td;
! 562: for ( i = 0; i < n; i++ )
! 563: d->d[i] = w[i] - d1->d[i];
! 564: c1 = (Z)BDY(p1)->c; c2 = (Z)BDY(p2)->c;
! 565: if ( INT(c1) && INT(c2) ) {
! 566: gcdz(c1,c2,&gn);
! 567: if ( !UNIQ(gn) ) {
! 568: divz(c1,gn,&c); c1 = c;
! 569: divz(c2,gn,&c);c2 = c;
! 570: }
! 571: }
! 572:
! 573: NEWMP(m); m->dl = d; m->c = (Obj)c2; NEXT(m) = 0;
! 574: MKDP(n,m,s1); s1->sugar = d->td; muld(CO,s1,p1,&t);
! 575:
! 576: NEWDL(d,n); d->td = td - d2->td;
! 577: for ( i = 0; i < n; i++ )
! 578: d->d[i] = w[i] - d2->d[i];
! 579: NEWMP(m); m->dl = d; m->c = (Obj)c1; NEXT(m) = 0;
! 580: MKDP(n,m,s2); s2->sugar = d->td; muld(CO,s2,p2,&u);
! 581:
! 582: subd(CO,t,u,rp);
! 583: if ( GenTrace ) {
! 584: LIST hist;
! 585: NODE node;
! 586:
! 587: node = mknode(4,ONE,NULLP,s1,ONE);
! 588: MKLIST(hist,node);
! 589: MKNODE(TraceList,hist,0);
! 590:
! 591: node = mknode(4,ONE,NULLP,NULLP,ONE);
! 592: chsgnd(s2,(DP *)&ARG2(node));
! 593: MKLIST(hist,node);
! 594: MKNODE(node,hist,TraceList); TraceList = node;
! 595: }
! 596: }
! 597:
! 598: void dpm_sp(DPM p1,DPM p2,DPM *rp)
! 599: {
! 600: int i,n,td;
! 601: int *w;
! 602: DL d1,d2,d;
! 603: MP m;
! 604: DP s1,s2;
! 605: DPM t,u;
! 606: Z c,c1,c2;
! 607: Z gn;
! 608:
! 609: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 610: if ( BDY(p1)->pos != BDY(p2)->pos ) {
! 611: *rp = 0;
! 612: return;
! 613: }
! 614: w = (int *)ALLOCA(n*sizeof(int));
! 615: for ( i = 0, td = 0; i < n; i++ ) {
! 616: w[i] = MAX(d1->d[i],d2->d[i]); td += MUL_WEIGHT(w[i],i);
! 617: }
! 618:
! 619: NEWDL(d,n); d->td = td - d1->td;
! 620: for ( i = 0; i < n; i++ )
! 621: d->d[i] = w[i] - d1->d[i];
! 622: c1 = (Z)BDY(p1)->c; c2 = (Z)BDY(p2)->c;
! 623: if ( INT(c1) && INT(c2) ) {
! 624: gcdz(c1,c2,&gn);
! 625: if ( !UNIQ(gn) ) {
! 626: divz(c1,gn,&c); c1 = c;
! 627: divz(c2,gn,&c);c2 = c;
! 628: }
! 629: }
! 630:
! 631: NEWMP(m); m->dl = d; m->c = (Obj)c2; NEXT(m) = 0;
! 632: MKDP(n,m,s1); s1->sugar = d->td; mulobjdpm(CO,(Obj)s1,p1,&t);
! 633:
! 634: NEWDL(d,n); d->td = td - d2->td;
! 635: for ( i = 0; i < n; i++ )
! 636: d->d[i] = w[i] - d2->d[i];
! 637: NEWMP(m); m->dl = d; m->c = (Obj)c1; NEXT(m) = 0;
! 638: MKDP(n,m,s2); s2->sugar = d->td; mulobjdpm(CO,(Obj)s2,p2,&u);
! 639:
! 640: subdpm(CO,t,u,rp);
! 641: if ( GenTrace ) {
! 642: LIST hist;
! 643: NODE node;
! 644:
! 645: node = mknode(4,ONE,NULLP,s1,ONE);
! 646: MKLIST(hist,node);
! 647: MKNODE(TraceList,hist,0);
! 648:
! 649: node = mknode(4,ONE,NULLP,NULLP,ONE);
! 650: chsgnd(s2,(DP *)&ARG2(node));
! 651: MKLIST(hist,node);
! 652: MKNODE(node,hist,TraceList); TraceList = node;
! 653: }
! 654: }
! 655:
! 656: void _dp_sp_dup(DP p1,DP p2,DP *rp)
! 657: {
! 658: int i,n,td;
! 659: int *w;
! 660: DL d1,d2,d;
! 661: MP m;
! 662: DP t,s1,s2,u;
! 663: Z c,c1,c2;
! 664: Z gn;
! 665:
! 666: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 667: w = (int *)ALLOCA(n*sizeof(int));
! 668: for ( i = 0, td = 0; i < n; i++ ) {
! 669: w[i] = MAX(d1->d[i],d2->d[i]); td += MUL_WEIGHT(w[i],i);
! 670: }
! 671:
! 672: _NEWDL(d,n); d->td = td - d1->td;
! 673: for ( i = 0; i < n; i++ )
! 674: d->d[i] = w[i] - d1->d[i];
! 675: c1 = (Z)BDY(p1)->c; c2 = (Z)BDY(p2)->c;
! 676: if ( INT(c1) && INT(c2) ) {
! 677: gcdz(c1,c2,&gn);
! 678: if ( !UNIQ(gn) ) {
! 679: divz(c1,gn,&c); c1 = c;
! 680: divz(c2,gn,&c);c2 = c;
! 681: }
! 682: }
! 683:
! 684: _NEWMP(m); m->dl = d; m->c = (Obj)c2; NEXT(m) = 0;
! 685: _MKDP(n,m,s1); s1->sugar = d->td; _muld_dup(CO,s1,p1,&t); _free_dp(s1);
! 686:
! 687: _NEWDL(d,n); d->td = td - d2->td;
! 688: for ( i = 0; i < n; i++ )
! 689: d->d[i] = w[i] - d2->d[i];
! 690: _NEWMP(m); m->dl = d; chsgnp((P)c1,(P *)&m->c); NEXT(m) = 0;
! 691: _MKDP(n,m,s2); s2->sugar = d->td; _muld_dup(CO,s2,p2,&u); _free_dp(s2);
! 692:
! 693: _addd_destructive(CO,t,u,rp);
! 694: if ( GenTrace ) {
! 695: LIST hist;
! 696: NODE node;
! 697:
! 698: node = mknode(4,ONE,NULLP,s1,ONE);
! 699: MKLIST(hist,node);
! 700: MKNODE(TraceList,hist,0);
! 701:
! 702: node = mknode(4,ONE,NULLP,NULLP,ONE);
! 703: chsgnd(s2,(DP *)&ARG2(node));
! 704: MKLIST(hist,node);
! 705: MKNODE(node,hist,TraceList); TraceList = node;
! 706: }
! 707: }
! 708:
! 709: void dp_sp_mod(DP p1,DP p2,int mod,DP *rp)
! 710: {
! 711: int i,n,td;
! 712: int *w;
! 713: DL d1,d2,d;
! 714: MP m;
! 715: DP t,s,u;
! 716:
! 717: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 718: w = (int *)ALLOCA(n*sizeof(int));
! 719: for ( i = 0, td = 0; i < n; i++ ) {
! 720: w[i] = MAX(d1->d[i],d2->d[i]); td += MUL_WEIGHT(w[i],i);
! 721: }
! 722: NEWDL_NOINIT(d,n); d->td = td - d1->td;
! 723: for ( i = 0; i < n; i++ )
! 724: d->d[i] = w[i] - d1->d[i];
! 725: NEWMP(m); m->dl = d; m->c = (Obj)BDY(p2)->c; NEXT(m) = 0;
! 726: MKDP(n,m,s); s->sugar = d->td; mulmd(CO,mod,p1,s,&t);
! 727: NEWDL_NOINIT(d,n); d->td = td - d2->td;
! 728: for ( i = 0; i < n; i++ )
! 729: d->d[i] = w[i] - d2->d[i];
! 730: NEWMP(m); m->dl = d; m->c = (Obj)BDY(p1)->c; NEXT(m) = 0;
! 731: MKDP(n,m,s); s->sugar = d->td; mulmd(CO,mod,p2,s,&u);
! 732: submd(CO,mod,t,u,rp);
! 733: }
! 734:
! 735: void _dp_sp_mod_dup(DP p1,DP p2,int mod,DP *rp)
! 736: {
! 737: int i,n,td;
! 738: int *w;
! 739: DL d1,d2,d;
! 740: MP m;
! 741: DP t,s,u;
! 742:
! 743: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 744: w = (int *)ALLOCA(n*sizeof(int));
! 745: for ( i = 0, td = 0; i < n; i++ ) {
! 746: w[i] = MAX(d1->d[i],d2->d[i]); td += MUL_WEIGHT(w[i],i);
! 747: }
! 748: _NEWDL(d,n); d->td = td - d1->td;
! 749: for ( i = 0; i < n; i++ )
! 750: d->d[i] = w[i] - d1->d[i];
! 751: _NEWMP(m); m->dl = d; m->c = BDY(p2)->c; NEXT(m) = 0;
! 752: _MKDP(n,m,s); s->sugar = d->td; _mulmd_dup(mod,s,p1,&t); _free_dp(s);
! 753: _NEWDL(d,n); d->td = td - d2->td;
! 754: for ( i = 0; i < n; i++ )
! 755: d->d[i] = w[i] - d2->d[i];
! 756: _NEWMP(m); m->dl = d; m->c = (Obj)STOI(mod - ITOS(BDY(p1)->c)); NEXT(m) = 0;
! 757: _MKDP(n,m,s); s->sugar = d->td; _mulmd_dup(mod,s,p2,&u); _free_dp(s);
! 758: _addmd_destructive(mod,t,u,rp);
! 759: }
! 760:
! 761: void _dp_sp_mod(DP p1,DP p2,int mod,DP *rp)
! 762: {
! 763: int i,n,td;
! 764: int *w;
! 765: DL d1,d2,d;
! 766: MP m;
! 767: DP t,s,u;
! 768:
! 769: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 770: w = (int *)ALLOCA(n*sizeof(int));
! 771: for ( i = 0, td = 0; i < n; i++ ) {
! 772: w[i] = MAX(d1->d[i],d2->d[i]); td += MUL_WEIGHT(w[i],i);
! 773: }
! 774: NEWDL(d,n); d->td = td - d1->td;
! 775: for ( i = 0; i < n; i++ )
! 776: d->d[i] = w[i] - d1->d[i];
! 777: NEWMP(m); m->dl = d; m->c = BDY(p2)->c; NEXT(m) = 0;
! 778: MKDP(n,m,s); s->sugar = d->td; mulmd_dup(mod,s,p1,&t);
! 779: NEWDL(d,n); d->td = td - d2->td;
! 780: for ( i = 0; i < n; i++ )
! 781: d->d[i] = w[i] - d2->d[i];
! 782: NEWMP(m); m->dl = d; m->c = (Obj)STOI(mod - ITOS(BDY(p1)->c)); NEXT(m) = 0;
! 783: MKDP(n,m,s); s->sugar = d->td; mulmd_dup(mod,s,p2,&u);
! 784: addmd_destructive(mod,t,u,rp);
! 785: }
! 786:
! 787: /*
! 788: * m-reduction
! 789: * do content reduction over Z or Q(x,...)
! 790: * do nothing over finite fields
! 791: *
! 792: */
! 793:
! 794: void dp_red(DP p0,DP p1,DP p2,DP *head,DP *rest,P *dnp,DP *multp)
! 795: {
! 796: int i,n;
! 797: DL d1,d2,d;
! 798: MP m;
! 799: DP t,s,r,h;
! 800: Z c,c1,c2,gn;
! 801: P g,a;
! 802: P p[2];
! 803:
! 804: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 805: NEWDL(d,n); d->td = d1->td - d2->td;
! 806: for ( i = 0; i < n; i++ )
! 807: d->d[i] = d1->d[i]-d2->d[i];
! 808: c1 = (Z)BDY(p1)->c; c2 = (Z)BDY(p2)->c;
! 809: if ( dp_fcoeffs == N_GFS ) {
! 810: p[0] = (P)c1; p[1] = (P)c2;
! 811: gcdsf(CO,p,2,&g);
! 812: divsp(CO,(P)c1,g,&a); c1 = (Z)a; divsp(CO,(P)c2,g,&a); c2 = (Z)a;
! 813: } else if ( dp_fcoeffs ) {
! 814: /* do nothing */
! 815: } else if ( INT(c1) && INT(c2) ) {
! 816: gcdz(c1,c2,&gn);
! 817: if ( !UNIQ(gn) ) {
! 818: divz(c1,gn,&c); c1 = c;
! 819: divz(c2,gn,&c); c2 = c;
! 820: }
! 821: } else {
! 822: ezgcdpz(CO,(P)c1,(P)c2,&g);
! 823: divsp(CO,(P)c1,g,&a); c1 = (Z)a; divsp(CO,(P)c2,g,&a); c2 = (Z)a;
! 824: add_denomlist(g);
! 825: }
! 826: NEWMP(m); m->dl = d; chsgnp((P)c1,(P *)&m->c); NEXT(m) = 0; MKDP(n,m,s); s->sugar = d->td;
! 827: *multp = s;
! 828: muld(CO,s,p2,&t); muldc(CO,p1,(Obj)c2,&s); addd(CO,s,t,&r);
! 829: muldc(CO,p0,(Obj)c2,&h);
! 830: *head = h; *rest = r; *dnp = (P)c2;
! 831: }
! 832:
! 833: void dpm_red(DPM p0,DPM p1,DPM p2,DPM *head,DPM *rest,P *dnp,DP *multp)
! 834: {
! 835: int i,n,pos;
! 836: DL d1,d2,d;
! 837: MP m;
! 838: DP s;
! 839: DPM t,r,h,u,w;
! 840: Z c,c1,c2,gn;
! 841: P g,a;
! 842: P p[2];
! 843:
! 844: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl; pos = BDY(p1)->pos;
! 845: if ( pos != BDY(p2)->pos )
! 846: error("dpm_red : cannot happen");
! 847: NEWDL(d,n); d->td = d1->td - d2->td;
! 848: for ( i = 0; i < n; i++ )
! 849: d->d[i] = d1->d[i]-d2->d[i];
! 850: c1 = (Z)BDY(p1)->c; c2 = (Z)BDY(p2)->c;
! 851: if ( dp_fcoeffs == N_GFS ) {
! 852: p[0] = (P)c1; p[1] = (P)c2;
! 853: gcdsf(CO,p,2,&g);
! 854: divsp(CO,(P)c1,g,&a); c1 = (Z)a; divsp(CO,(P)c2,g,&a); c2 = (Z)a;
! 855: } else if ( dp_fcoeffs ) {
! 856: /* do nothing */
! 857: } else if ( INT(c1) && INT(c2) ) {
! 858: gcdz(c1,c2,&gn);
! 859: if ( !UNIQ(gn) ) {
! 860: divz(c1,gn,&c); c1 = c;
! 861: divz(c2,gn,&c); c2 = c;
! 862: }
! 863: } else {
! 864: ezgcdpz(CO,(P)c1,(P)c2,&g);
! 865: divsp(CO,(P)c1,g,&a); c1 = (Z)a; divsp(CO,(P)c2,g,&a); c2 = (Z)a;
! 866: add_denomlist(g);
! 867: }
! 868: NEWMP(m); m->dl = d; chsgnp((P)c1,(P *)&m->c); NEXT(m) = 0; MKDP(n,m,s); s->sugar = d->td;
! 869: *multp = s;
! 870: mulobjdpm(CO,(Obj)s,p2,&u); mulobjdpm(CO,(Obj)c2,p1,&w); adddpm(CO,u,w,&r);
! 871: mulobjdpm(CO,(Obj)c2,p0,&h);
! 872: *head = h; *rest = r; *dnp = (P)c2;
! 873: }
! 874:
! 875:
! 876: /*
! 877: * m-reduction by a marked poly
! 878: * do content reduction over Z or Q(x,...)
! 879: * do nothing over finite fields
! 880: *
! 881: */
! 882:
! 883:
! 884: void dp_red_marked(DP p0,DP p1,DP p2,DP hp2,DP *head,DP *rest,P *dnp,DP *multp)
! 885: {
! 886: int i,n;
! 887: DL d1,d2,d;
! 888: MP m;
! 889: DP t,s,r,h;
! 890: Z c,c1,c2,gn;
! 891: P g,a;
! 892: P p[2];
! 893:
! 894: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(hp2)->dl;
! 895: NEWDL(d,n); d->td = d1->td - d2->td;
! 896: for ( i = 0; i < n; i++ )
! 897: d->d[i] = d1->d[i]-d2->d[i];
! 898: c1 = (Z)BDY(p1)->c; c2 = (Z)BDY(hp2)->c;
! 899: if ( dp_fcoeffs == N_GFS ) {
! 900: p[0] = (P)c1; p[1] = (P)c2;
! 901: gcdsf(CO,p,2,&g);
! 902: divsp(CO,(P)c1,g,&a); c1 = (Z)a; divsp(CO,(P)c2,g,&a); c2 = (Z)a;
! 903: } else if ( dp_fcoeffs ) {
! 904: /* do nothing */
! 905: } else if ( INT(c1) && INT(c2) ) {
! 906: gcdz(c1,c2,&gn);
! 907: if ( !UNIQ(gn) ) {
! 908: divz(c1,gn,&c); c1 = c;
! 909: divz(c2,gn,&c); c2 = c;
! 910: }
! 911: } else {
! 912: ezgcdpz(CO,(P)c1,(P)c2,&g);
! 913: divsp(CO,(P)c1,g,&a); c1 = (Z)a; divsp(CO,(P)c2,g,&a); c2 = (Z)a;
! 914: }
! 915: NEWMP(m); m->dl = d; m->c = (Obj)c1; NEXT(m) = 0; MKDP(n,m,s); s->sugar = d->td;
! 916: *multp = s;
! 917: muld(CO,s,p2,&t); muldc(CO,p1,(Obj)c2,&s); subd(CO,s,t,&r);
! 918: muldc(CO,p0,(Obj)c2,&h);
! 919: *head = h; *rest = r; *dnp = (P)c2;
! 920: }
! 921:
! 922: void dp_red_marked_mod(DP p0,DP p1,DP p2,DP hp2,int mod,DP *head,DP *rest,P *dnp,DP *multp)
! 923: {
! 924: int i,n;
! 925: DL d1,d2,d;
! 926: MP m;
! 927: DP t,s,r,h;
! 928: P c1,c2,g,u;
! 929:
! 930: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(hp2)->dl;
! 931: NEWDL(d,n); d->td = d1->td - d2->td;
! 932: for ( i = 0; i < n; i++ )
! 933: d->d[i] = d1->d[i]-d2->d[i];
! 934: c1 = (P)BDY(p1)->c; c2 = (P)BDY(hp2)->c;
! 935: gcdprsmp(CO,mod,c1,c2,&g);
! 936: divsmp(CO,mod,c1,g,&u); c1 = u; divsmp(CO,mod,c2,g,&u); c2 = u;
! 937: if ( NUM(c2) ) {
! 938: divsmp(CO,mod,c1,c2,&u); c1 = u; c2 = (P)ONEM;
! 939: }
! 940: NEWMP(m); m->dl = d; m->c = (Obj)c1; NEXT(m) = 0;
! 941: MKDP(n,m,s); s->sugar = d->td;
! 942: *multp = s;
! 943: mulmd(CO,mod,s,p2,&t);
! 944: if ( NUM(c2) ) {
! 945: submd(CO,mod,p1,t,&r); h = p0;
! 946: } else {
! 947: mulmdc(CO,mod,p1,c2,&s); submd(CO,mod,s,t,&r); mulmdc(CO,mod,p0,c2,&h);
! 948: }
! 949: *head = h; *rest = r; *dnp = c2;
! 950: }
! 951:
! 952: /* m-reduction over a field */
! 953:
! 954: void dp_red_f(DP p1,DP p2,DP *rest)
! 955: {
! 956: int i,n;
! 957: DL d1,d2,d;
! 958: MP m;
! 959: DP t,s;
! 960: Obj a,b;
! 961:
! 962: n = p1->nv;
! 963: d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 964:
! 965: NEWDL(d,n); d->td = d1->td - d2->td;
! 966: for ( i = 0; i < n; i++ )
! 967: d->d[i] = d1->d[i]-d2->d[i];
! 968:
! 969: NEWMP(m); m->dl = d;
! 970: divr(CO,(Obj)BDY(p1)->c,(Obj)BDY(p2)->c,&a); chsgnr(a,&b);
! 971: C(m) = (Obj)b;
! 972: NEXT(m) = 0; MKDP(n,m,s); s->sugar = d->td;
! 973:
! 974: muld(CO,s,p2,&t); addd(CO,p1,t,rest);
! 975: }
! 976:
! 977: void dpm_red_f(DPM p1,DPM p2,DPM *rest)
! 978: {
! 979: int i,n;
! 980: DL d1,d2,d;
! 981: MP m;
! 982: DPM t;
! 983: DP s;
! 984: Obj a,b;
! 985:
! 986: n = p1->nv;
! 987: d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 988:
! 989: NEWDL(d,n); d->td = d1->td - d2->td;
! 990: for ( i = 0; i < n; i++ )
! 991: d->d[i] = d1->d[i]-d2->d[i];
! 992:
! 993: NEWMP(m); m->dl = d;
! 994: arf_div(CO,(Obj)BDY(p1)->c,(Obj)BDY(p2)->c,&a); arf_chsgn(a,&b);
! 995: C(m) = b;
! 996: NEXT(m) = 0; MKDP(n,m,s); s->sugar = d->td;
! 997:
! 998: mulobjdpm(CO,(Obj)s,p2,&t); adddpm(CO,p1,t,rest);
! 999: }
! 1000:
! 1001:
! 1002: void dp_red_mod(DP p0,DP p1,DP p2,int mod,DP *head,DP *rest,P *dnp)
! 1003: {
! 1004: int i,n;
! 1005: DL d1,d2,d;
! 1006: MP m;
! 1007: DP t,s,r,h;
! 1008: P c1,c2,g,u;
! 1009:
! 1010: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 1011: NEWDL(d,n); d->td = d1->td - d2->td;
! 1012: for ( i = 0; i < n; i++ )
! 1013: d->d[i] = d1->d[i]-d2->d[i];
! 1014: c1 = (P)BDY(p1)->c; c2 = (P)BDY(p2)->c;
! 1015: gcdprsmp(CO,mod,c1,c2,&g);
! 1016: divsmp(CO,mod,c1,g,&u); c1 = u; divsmp(CO,mod,c2,g,&u); c2 = u;
! 1017: if ( NUM(c2) ) {
! 1018: divsmp(CO,mod,c1,c2,&u); c1 = u; c2 = (P)ONEM;
! 1019: }
! 1020: NEWMP(m); m->dl = d; chsgnmp(mod,(P)c1,(P *)&m->c); NEXT(m) = 0;
! 1021: MKDP(n,m,s); s->sugar = d->td; mulmd(CO,mod,s,p2,&t);
! 1022: if ( NUM(c2) ) {
! 1023: addmd(CO,mod,p1,t,&r); h = p0;
! 1024: } else {
! 1025: mulmdc(CO,mod,p1,c2,&s); addmd(CO,mod,s,t,&r); mulmdc(CO,mod,p0,c2,&h);
! 1026: }
! 1027: *head = h; *rest = r; *dnp = c2;
! 1028: }
! 1029:
! 1030: struct oEGT eg_red_mod;
! 1031:
! 1032: void _dp_red_mod_destructive(DP p1,DP p2,int mod,DP *rp)
! 1033: {
! 1034: int i,n;
! 1035: DL d1,d2,d;
! 1036: MP m;
! 1037: DP t,s;
! 1038: int c,c1,c2;
! 1039: extern int do_weyl;
! 1040:
! 1041: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 1042: _NEWDL(d,n); d->td = d1->td - d2->td;
! 1043: for ( i = 0; i < n; i++ )
! 1044: d->d[i] = d1->d[i]-d2->d[i];
! 1045: c = invm(ITOS(BDY(p2)->c),mod);
! 1046: c2 = ITOS(BDY(p1)->c);
! 1047: DMAR(c,c2,0,mod,c1);
! 1048: _NEWMP(m); m->dl = d; m->c = (Obj)STOI(mod-c1); NEXT(m) = 0;
! 1049: #if 0
! 1050: _MKDP(n,m,s); s->sugar = d->td;
! 1051: _mulmd_dup(mod,s,p2,&t); _free_dp(s);
! 1052: #else
! 1053: if ( do_weyl ) {
! 1054: _MKDP(n,m,s); s->sugar = d->td;
! 1055: _mulmd_dup(mod,s,p2,&t); _free_dp(s);
! 1056: } else {
! 1057: _mulmdm_dup(mod,p2,m,&t); _FREEMP(m);
! 1058: }
! 1059: #endif
! 1060: /* get_eg(&t0); */
! 1061: _addmd_destructive(mod,p1,t,rp);
! 1062: /* get_eg(&t1); add_eg(&eg_red_mod,&t0,&t1); */
! 1063: }
! 1064:
! 1065: /*
! 1066: * normal form computation
! 1067: *
! 1068: */
! 1069:
! 1070: void dp_true_nf(NODE b,DP g,DP *ps,int full,DP *rp,P *dnp)
! 1071: {
! 1072: DP u,p,d,s,t,dmy;
! 1073: NODE l;
! 1074: MP m,mr;
! 1075: int i,n;
! 1076: int *wb;
! 1077: int sugar,psugar;
! 1078: P dn,tdn,tdn1;
! 1079:
! 1080: dn = (P)ONE;
! 1081: if ( !g ) {
! 1082: *rp = 0; *dnp = dn; return;
! 1083: }
! 1084: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1085: wb = (int *)ALLOCA(n*sizeof(int));
! 1086: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1087: wb[i] = QTOS((Q)BDY(l));
! 1088: sugar = g->sugar;
! 1089: for ( d = 0; g; ) {
! 1090: for ( u = 0, i = 0; i < n; i++ ) {
! 1091: if ( dp_redble(g,p = ps[wb[i]]) ) {
! 1092: dp_red(d,g,p,&t,&u,&tdn,&dmy);
! 1093: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1094: sugar = MAX(sugar,psugar);
! 1095: if ( !u ) {
! 1096: if ( d )
! 1097: d->sugar = sugar;
! 1098: *rp = d; *dnp = dn; return;
! 1099: } else {
! 1100: d = t;
! 1101: mulp(CO,dn,tdn,&tdn1); dn = tdn1;
! 1102: }
! 1103: break;
! 1104: }
! 1105: }
! 1106: if ( u )
! 1107: g = u;
! 1108: else if ( !full ) {
! 1109: if ( g ) {
! 1110: MKDP(g->nv,BDY(g),t); t->sugar = sugar; g = t;
! 1111: }
! 1112: *rp = g; *dnp = dn; return;
! 1113: } else {
! 1114: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
! 1115: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
! 1116: addd(CO,d,t,&s); d = s;
! 1117: dp_rest(g,&t); g = t;
! 1118: }
! 1119: }
! 1120: if ( d )
! 1121: d->sugar = sugar;
! 1122: *rp = d; *dnp = dn;
! 1123: }
! 1124:
! 1125: void dp_removecont2(DP p1,DP p2,DP *r1p,DP *r2p,Z *contp)
! 1126: {
! 1127: struct oVECT v;
! 1128: int i,n1,n2,n;
! 1129: MP m,m0,t;
! 1130: Z *w;
! 1131: Z h;
! 1132:
! 1133: if ( p1 ) {
! 1134: for ( i = 0, m = BDY(p1); m; m = NEXT(m), i++ );
! 1135: n1 = i;
! 1136: } else
! 1137: n1 = 0;
! 1138: if ( p2 ) {
! 1139: for ( i = 0, m = BDY(p2); m; m = NEXT(m), i++ );
! 1140: n2 = i;
! 1141: } else
! 1142: n2 = 0;
! 1143: n = n1+n2;
! 1144: if ( !n ) {
! 1145: *r1p = 0; *r2p = 0; *contp = ONE; return;
! 1146: }
! 1147: w = (Z *)ALLOCA(n*sizeof(Q));
! 1148: v.len = n;
! 1149: v.body = (pointer *)w;
! 1150: i = 0;
! 1151: if ( p1 )
! 1152: for ( m = BDY(p1); i < n1; m = NEXT(m), i++ ) w[i] = (Z)m->c;
! 1153: if ( p2 )
! 1154: for ( m = BDY(p2); i < n; m = NEXT(m), i++ ) w[i] = (Z)m->c;
! 1155: h = w[0]; removecont_array((P *)w,n,1); divz(h,w[0],contp);
! 1156: i = 0;
! 1157: if ( p1 ) {
! 1158: for ( m0 = 0, t = BDY(p1); i < n1; i++, t = NEXT(t) ) {
! 1159: NEXTMP(m0,m); m->c = (Obj)w[i]; m->dl = t->dl;
! 1160: }
! 1161: NEXT(m) = 0;
! 1162: MKDP(p1->nv,m0,*r1p); (*r1p)->sugar = p1->sugar;
! 1163: } else
! 1164: *r1p = 0;
! 1165: if ( p2 ) {
! 1166: for ( m0 = 0, t = BDY(p2); i < n; i++, t = NEXT(t) ) {
! 1167: NEXTMP(m0,m); m->c = (Obj)w[i]; m->dl = t->dl;
! 1168: }
! 1169: NEXT(m) = 0;
! 1170: MKDP(p2->nv,m0,*r2p); (*r2p)->sugar = p2->sugar;
! 1171: } else
! 1172: *r2p = 0;
! 1173: }
! 1174:
! 1175: /* true nf by a marked GB */
! 1176:
! 1177: void dp_true_nf_marked(NODE b,DP g,DP *ps,DP *hps,DP *rp,P *nmp,P *dnp)
! 1178: {
! 1179: DP u,p,d,s,t,dmy,hp;
! 1180: NODE l;
! 1181: MP m,mr;
! 1182: int i,n,hmag;
! 1183: int *wb;
! 1184: int sugar,psugar,multiple;
! 1185: P nm,tnm1,dn,tdn,tdn1;
! 1186: Z cont;
! 1187:
! 1188: multiple = 0;
! 1189: hmag = multiple*HMAG(g);
! 1190: nm = (P)ONE;
! 1191: dn = (P)ONE;
! 1192: if ( !g ) {
! 1193: *rp = 0; *dnp = dn; return;
! 1194: }
! 1195: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1196: wb = (int *)ALLOCA(n*sizeof(int));
! 1197: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1198: wb[i] = QTOS((Z)BDY(l));
! 1199: sugar = g->sugar;
! 1200: for ( d = 0; g; ) {
! 1201: for ( u = 0, i = 0; i < n; i++ ) {
! 1202: if ( dp_redble(g,hp = hps[wb[i]]) ) {
! 1203: p = ps[wb[i]];
! 1204: dp_red_marked(d,g,p,hp,&t,&u,&tdn,&dmy);
! 1205: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1206: sugar = MAX(sugar,psugar);
! 1207: if ( !u ) {
! 1208: goto last;
! 1209: } else {
! 1210: d = t;
! 1211: mulp(CO,dn,tdn,&tdn1); dn = tdn1;
! 1212: }
! 1213: break;
! 1214: }
! 1215: }
! 1216: if ( u ) {
! 1217: g = u;
! 1218: if ( multiple && ((d && HMAG(d)>hmag) || (HMAG(g)>hmag)) ) {
! 1219: dp_removecont2(d,g,&t,&u,&cont); d = t; g = u;
! 1220: mulp(CO,nm,(P)cont,&tnm1); nm = tnm1;
! 1221: if ( d )
! 1222: hmag = multiple*HMAG(d);
! 1223: else
! 1224: hmag = multiple*HMAG(g);
! 1225: }
! 1226: } else {
! 1227: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
! 1228: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
! 1229: addd(CO,d,t,&s); d = s;
! 1230: dp_rest(g,&t); g = t;
! 1231: }
! 1232: }
! 1233: last:
! 1234: if ( d ) {
! 1235: dp_removecont2(d,0,&t,&u,&cont); d = t;
! 1236: mulp(CO,nm,(P)cont,&tnm1); nm = tnm1;
! 1237: d->sugar = sugar;
! 1238: }
! 1239: *rp = d; *nmp = nm; *dnp = dn;
! 1240: }
! 1241:
! 1242: void dp_true_nf_marked_mod(NODE b,DP g,DP *ps,DP *hps,int mod,DP *rp,P *dnp)
! 1243: {
! 1244: DP hp,u,p,d,s,t,dmy;
! 1245: NODE l;
! 1246: MP m,mr;
! 1247: int i,n;
! 1248: int *wb;
! 1249: int sugar,psugar;
! 1250: P dn,tdn,tdn1;
! 1251:
! 1252: dn = (P)ONEM;
! 1253: if ( !g ) {
! 1254: *rp = 0; *dnp = dn; return;
! 1255: }
! 1256: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1257: wb = (int *)ALLOCA(n*sizeof(int));
! 1258: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1259: wb[i] = QTOS((Q)BDY(l));
! 1260: sugar = g->sugar;
! 1261: for ( d = 0; g; ) {
! 1262: for ( u = 0, i = 0; i < n; i++ ) {
! 1263: if ( dp_redble(g,hp = hps[wb[i]]) ) {
! 1264: p = ps[wb[i]];
! 1265: dp_red_marked_mod(d,g,p,hp,mod,&t,&u,&tdn,&dmy);
! 1266: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1267: sugar = MAX(sugar,psugar);
! 1268: if ( !u ) {
! 1269: if ( d )
! 1270: d->sugar = sugar;
! 1271: *rp = d; *dnp = dn; return;
! 1272: } else {
! 1273: d = t;
! 1274: mulmp(CO,mod,dn,tdn,&tdn1); dn = tdn1;
! 1275: }
! 1276: break;
! 1277: }
! 1278: }
! 1279: if ( u )
! 1280: g = u;
! 1281: else {
! 1282: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
! 1283: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
! 1284: addmd(CO,mod,d,t,&s); d = s;
! 1285: dp_rest(g,&t); g = t;
! 1286: }
! 1287: }
! 1288: if ( d )
! 1289: d->sugar = sugar;
! 1290: *rp = d; *dnp = dn;
! 1291: }
! 1292:
! 1293: /* true nf by a marked GB and collect quotients */
! 1294:
! 1295: DP *dp_true_nf_and_quotient_marked (NODE b,DP g,DP *ps,DP *hps,DP *rp,P *dnp)
! 1296: {
! 1297: DP u,p,d,s,t,dmy,hp,mult;
! 1298: DP *q;
! 1299: NODE l;
! 1300: MP m,mr;
! 1301: int i,n,j;
! 1302: int *wb;
! 1303: int sugar,psugar,multiple;
! 1304: P nm,tnm1,dn,tdn,tdn1;
! 1305: Q cont;
! 1306:
! 1307: dn = (P)ONE;
! 1308: if ( !g ) {
! 1309: *rp = 0; *dnp = dn; return 0;
! 1310: }
! 1311: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1312: wb = (int *)ALLOCA(n*sizeof(int));
! 1313: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1314: wb[i] = QTOS((Q)BDY(l));
! 1315: q = (DP *)MALLOC(n*sizeof(DP));
! 1316: for ( i = 0; i < n; i++ ) q[i] = 0;
! 1317: sugar = g->sugar;
! 1318: for ( d = 0; g; ) {
! 1319: for ( u = 0, i = 0; i < n; i++ ) {
! 1320: if ( dp_redble(g,hp = hps[wb[i]]) ) {
! 1321: p = ps[wb[i]];
! 1322: dp_red_marked(d,g,p,hp,&t,&u,&tdn,&mult);
! 1323: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1324: sugar = MAX(sugar,psugar);
! 1325: for ( j = 0; j < n; j++ ) {
! 1326: muldc(CO,q[j],(Obj)tdn,&dmy); q[j] = dmy;
! 1327: }
! 1328: addd(CO,q[wb[i]],mult,&dmy); q[wb[i]] = dmy;
! 1329: mulp(CO,dn,tdn,&tdn1); dn = tdn1;
! 1330: d = t;
! 1331: if ( !u ) goto last;
! 1332: break;
! 1333: }
! 1334: }
! 1335: if ( u ) {
! 1336: g = u;
! 1337: } else {
! 1338: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
! 1339: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
! 1340: addd(CO,d,t,&s); d = s;
! 1341: dp_rest(g,&t); g = t;
! 1342: }
! 1343: }
! 1344: last:
! 1345: if ( d ) d->sugar = sugar;
! 1346: *rp = d; *dnp = dn;
! 1347: return q;
! 1348: }
! 1349:
! 1350: DP *dp_true_nf_and_quotient_marked_mod(NODE b,DP g,DP *ps,DP *hps,int mod,DP *rp,P *dnp)
! 1351: {
! 1352: DP u,p,d,s,t,dmy,hp,mult;
! 1353: DP *q;
! 1354: NODE l;
! 1355: MP m,mr;
! 1356: int i,n,j;
! 1357: int *wb;
! 1358: int sugar,psugar;
! 1359: P dn,tdn,tdn1;
! 1360:
! 1361: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1362: q = (DP *)MALLOC(n*sizeof(DP));
! 1363: for ( i = 0; i < n; i++ ) q[i] = 0;
! 1364: dn = (P)ONEM;
! 1365: if ( !g ) {
! 1366: *rp = 0; *dnp = dn; return 0;
! 1367: }
! 1368: wb = (int *)ALLOCA(n*sizeof(int));
! 1369: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1370: wb[i] = QTOS((Q)BDY(l));
! 1371: sugar = g->sugar;
! 1372: for ( d = 0; g; ) {
! 1373: for ( u = 0, i = 0; i < n; i++ ) {
! 1374: if ( dp_redble(g,hp = hps[wb[i]]) ) {
! 1375: p = ps[wb[i]];
! 1376: dp_red_marked_mod(d,g,p,hp,mod,&t,&u,&tdn,&mult);
! 1377: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1378: sugar = MAX(sugar,psugar);
! 1379: for ( j = 0; j < n; j++ ) {
! 1380: mulmdc(CO,mod,q[j],(P)tdn,&dmy); q[j] = dmy;
! 1381: }
! 1382: addmd(CO,mod,q[wb[i]],mult,&dmy); q[wb[i]] = dmy;
! 1383: mulmp(CO,mod,dn,tdn,&tdn1); dn = tdn1;
! 1384: d = t;
! 1385: if ( !u ) goto last;
! 1386: break;
! 1387: }
! 1388: }
! 1389: if ( u )
! 1390: g = u;
! 1391: else {
! 1392: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
! 1393: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
! 1394: addmd(CO,mod,d,t,&s); d = s;
! 1395: dp_rest(g,&t); g = t;
! 1396: }
! 1397: }
! 1398: last:
! 1399: if ( d )
! 1400: d->sugar = sugar;
! 1401: *rp = d; *dnp = dn;
! 1402: return q;
! 1403: }
! 1404:
! 1405: /* nf computation over Z */
! 1406:
! 1407: void dp_nf_z(NODE b,DP g,DP *ps,int full,int multiple,DP *rp)
! 1408: {
! 1409: DP u,p,d,s,t,dmy1;
! 1410: P dmy;
! 1411: NODE l;
! 1412: MP m,mr;
! 1413: int i,n;
! 1414: int *wb;
! 1415: int hmag;
! 1416: int sugar,psugar;
! 1417:
! 1418: if ( !g ) {
! 1419: *rp = 0; return;
! 1420: }
! 1421: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1422: wb = (int *)ALLOCA(n*sizeof(int));
! 1423: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1424: wb[i] = QTOS((Q)BDY(l));
! 1425:
! 1426: hmag = multiple*HMAG(g);
! 1427: sugar = g->sugar;
! 1428:
! 1429: for ( d = 0; g; ) {
! 1430: for ( u = 0, i = 0; i < n; i++ ) {
! 1431: if ( dp_redble(g,p = ps[wb[i]]) ) {
! 1432: dp_red(d,g,p,&t,&u,&dmy,&dmy1);
! 1433: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1434: sugar = MAX(sugar,psugar);
! 1435: if ( !u ) {
! 1436: if ( d )
! 1437: d->sugar = sugar;
! 1438: *rp = d; return;
! 1439: }
! 1440: d = t;
! 1441: break;
! 1442: }
! 1443: }
! 1444: if ( u ) {
! 1445: g = u;
! 1446: if ( d ) {
! 1447: if ( multiple && HMAG(d) > hmag ) {
! 1448: dp_ptozp2(d,g,&t,&u); d = t; g = u;
! 1449: hmag = multiple*HMAG(d);
! 1450: }
! 1451: } else {
! 1452: if ( multiple && HMAG(g) > hmag ) {
! 1453: dp_ptozp(g,&t); g = t;
! 1454: hmag = multiple*HMAG(g);
! 1455: }
! 1456: }
! 1457: }
! 1458: else if ( !full ) {
! 1459: if ( g ) {
! 1460: MKDP(g->nv,BDY(g),t); t->sugar = sugar; g = t;
! 1461: }
! 1462: *rp = g; return;
! 1463: } else {
! 1464: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
! 1465: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
! 1466: addd(CO,d,t,&s); d = s;
! 1467: dp_rest(g,&t); g = t;
! 1468:
! 1469: }
! 1470: }
! 1471: if ( d )
! 1472: d->sugar = sugar;
! 1473: *rp = d;
! 1474: }
! 1475:
! 1476: void dpm_nf_z(NODE b,DPM g,DPM *ps,int full,int multiple,DPM *rp)
! 1477: {
! 1478: DPM u,p,d,s,t;
! 1479: DP dmy1;
! 1480: P dmy;
! 1481: NODE l;
! 1482: DMM m,mr;
! 1483: int i,n;
! 1484: int *wb;
! 1485: int hmag;
! 1486: int sugar,psugar;
! 1487:
! 1488: if ( !g ) {
! 1489: *rp = 0; return;
! 1490: }
! 1491: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1492: wb = (int *)ALLOCA(n*sizeof(int));
! 1493: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1494: wb[i] = QTOS((Q)BDY(l));
! 1495:
! 1496: hmag = multiple*HMAG(g);
! 1497: sugar = g->sugar;
! 1498:
! 1499: for ( d = 0; g; ) {
! 1500: for ( u = 0, i = 0; i < n; i++ ) {
! 1501: if ( dpm_redble(g,p = ps[wb[i]]) ) {
! 1502: dpm_red(d,g,p,&t,&u,&dmy,&dmy1);
! 1503: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1504: sugar = MAX(sugar,psugar);
! 1505: if ( !u ) {
! 1506: if ( d )
! 1507: d->sugar = sugar;
! 1508: *rp = d; return;
! 1509: }
! 1510: d = t;
! 1511: break;
! 1512: }
! 1513: }
! 1514: if ( u ) {
! 1515: g = u;
! 1516: if ( d ) {
! 1517: if ( multiple && HMAG(d) > hmag ) {
! 1518: dpm_ptozp2(d,g,&t,&u); d = t; g = u;
! 1519: hmag = multiple*HMAG(d);
! 1520: }
! 1521: } else {
! 1522: if ( multiple && HMAG(g) > hmag ) {
! 1523: dpm_ptozp(g,&t); g = t;
! 1524: hmag = multiple*HMAG(g);
! 1525: }
! 1526: }
! 1527: }
! 1528: else if ( !full ) {
! 1529: if ( g ) {
! 1530: MKDPM(g->nv,BDY(g),t); t->sugar = sugar; g = t;
! 1531: }
! 1532: *rp = g; return;
! 1533: } else {
! 1534: m = BDY(g); NEWDMM(mr); mr->dl = m->dl; mr->c = m->c; mr->pos = m->pos;
! 1535: NEXT(mr) = 0; MKDPM(g->nv,mr,t); t->sugar = mr->dl->td;
! 1536: adddpm(CO,d,t,&s); d = s;
! 1537: dpm_rest(g,&t); g = t;
! 1538: }
! 1539: }
! 1540: if ( d )
! 1541: d->sugar = sugar;
! 1542: *rp = d;
! 1543: }
! 1544:
! 1545: /* nf computation over a field */
! 1546:
! 1547: void dp_nf_f(NODE b,DP g,DP *ps,int full,DP *rp)
! 1548: {
! 1549: DP u,p,d,s,t;
! 1550: NODE l;
! 1551: MP m,mr;
! 1552: int i,n;
! 1553: int *wb;
! 1554: int sugar,psugar;
! 1555:
! 1556: if ( !g ) {
! 1557: *rp = 0; return;
! 1558: }
! 1559: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1560: wb = (int *)ALLOCA(n*sizeof(int));
! 1561: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1562: wb[i] = QTOS((Q)BDY(l));
! 1563:
! 1564: sugar = g->sugar;
! 1565: for ( d = 0; g; ) {
! 1566: for ( u = 0, i = 0; i < n; i++ ) {
! 1567: if ( dp_redble(g,p = ps[wb[i]]) ) {
! 1568: dp_red_f(g,p,&u);
! 1569: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1570: sugar = MAX(sugar,psugar);
! 1571: if ( !u ) {
! 1572: if ( d )
! 1573: d->sugar = sugar;
! 1574: *rp = d; return;
! 1575: }
! 1576: break;
! 1577: }
! 1578: }
! 1579: if ( u )
! 1580: g = u;
! 1581: else if ( !full ) {
! 1582: if ( g ) {
! 1583: MKDP(g->nv,BDY(g),t); t->sugar = sugar; g = t;
! 1584: }
! 1585: *rp = g; return;
! 1586: } else {
! 1587: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
! 1588: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
! 1589: addd(CO,d,t,&s); d = s;
! 1590: dp_rest(g,&t); g = t;
! 1591: }
! 1592: }
! 1593: if ( d )
! 1594: d->sugar = sugar;
! 1595: *rp = d;
! 1596: }
! 1597:
! 1598: void dpm_nf_f(NODE b,DPM g,DPM *ps,int full,DPM *rp)
! 1599: {
! 1600: DPM u,p,d,s,t;
! 1601: NODE l;
! 1602: DMM m,mr;
! 1603: int i,n;
! 1604: int *wb;
! 1605: int sugar,psugar;
! 1606:
! 1607: if ( !g ) {
! 1608: *rp = 0; return;
! 1609: }
! 1610: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1611: wb = (int *)ALLOCA(n*sizeof(int));
! 1612: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1613: wb[i] = QTOS((Q)BDY(l));
! 1614:
! 1615: sugar = g->sugar;
! 1616: for ( d = 0; g; ) {
! 1617: for ( u = 0, i = 0; i < n; i++ ) {
! 1618: if ( dpm_redble(g,p = ps[wb[i]]) ) {
! 1619: dpm_red_f(g,p,&u);
! 1620: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1621: sugar = MAX(sugar,psugar);
! 1622: if ( !u ) {
! 1623: if ( d )
! 1624: d->sugar = sugar;
! 1625: *rp = d; return;
! 1626: }
! 1627: break;
! 1628: }
! 1629: }
! 1630: if ( u )
! 1631: g = u;
! 1632: else if ( !full ) {
! 1633: if ( g ) {
! 1634: MKDPM(g->nv,BDY(g),t); t->sugar = sugar; g = t;
! 1635: }
! 1636: *rp = g; return;
! 1637: } else {
! 1638: m = BDY(g); NEWDMM(mr); mr->dl = m->dl; mr->c = m->c; mr->pos = m->pos;
! 1639: NEXT(mr) = 0; MKDPM(g->nv,mr,t); t->sugar = mr->dl->td;
! 1640: adddpm(CO,d,t,&s); d = s;
! 1641: dpm_rest(g,&t); g = t;
! 1642: }
! 1643: }
! 1644: if ( d )
! 1645: d->sugar = sugar;
! 1646: *rp = d;
! 1647: }
! 1648:
! 1649: /* nf computation over GF(mod) (only for internal use) */
! 1650:
! 1651: void dp_nf_mod(NODE b,DP g,DP *ps,int mod,int full,DP *rp)
! 1652: {
! 1653: DP u,p,d,s,t;
! 1654: P dmy;
! 1655: NODE l;
! 1656: MP m,mr;
! 1657: int sugar,psugar;
! 1658:
! 1659: if ( !g ) {
! 1660: *rp = 0; return;
! 1661: }
! 1662: sugar = g->sugar;
! 1663: for ( d = 0; g; ) {
! 1664: for ( u = 0, l = b; l; l = NEXT(l) ) {
! 1665: if ( dp_redble(g,p = ps[(long)BDY(l)]) ) {
! 1666: dp_red_mod(d,g,p,mod,&t,&u,&dmy);
! 1667: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1668: sugar = MAX(sugar,psugar);
! 1669: if ( !u ) {
! 1670: if ( d )
! 1671: d->sugar = sugar;
! 1672: *rp = d; return;
! 1673: }
! 1674: d = t;
! 1675: break;
! 1676: }
! 1677: }
! 1678: if ( u )
! 1679: g = u;
! 1680: else if ( !full ) {
! 1681: if ( g ) {
! 1682: MKDP(g->nv,BDY(g),t); t->sugar = sugar; g = t;
! 1683: }
! 1684: *rp = g; return;
! 1685: } else {
! 1686: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
! 1687: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
! 1688: addmd(CO,mod,d,t,&s); d = s;
! 1689: dp_rest(g,&t); g = t;
! 1690: }
! 1691: }
! 1692: if ( d )
! 1693: d->sugar = sugar;
! 1694: *rp = d;
! 1695: }
! 1696:
! 1697: void dp_true_nf_mod(NODE b,DP g,DP *ps,int mod,int full,DP *rp,P *dnp)
! 1698: {
! 1699: DP u,p,d,s,t;
! 1700: NODE l;
! 1701: MP m,mr;
! 1702: int i,n;
! 1703: int *wb;
! 1704: int sugar,psugar;
! 1705: P dn,tdn,tdn1;
! 1706:
! 1707: dn = (P)ONEM;
! 1708: if ( !g ) {
! 1709: *rp = 0; *dnp = dn; return;
! 1710: }
! 1711: for ( n = 0, l = b; l; l = NEXT(l), n++ );
! 1712: wb = (int *)ALLOCA(n*sizeof(int));
! 1713: for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
! 1714: wb[i] = QTOS((Q)BDY(l));
! 1715: sugar = g->sugar;
! 1716: for ( d = 0; g; ) {
! 1717: for ( u = 0, i = 0; i < n; i++ ) {
! 1718: if ( dp_redble(g,p = ps[wb[i]]) ) {
! 1719: dp_red_mod(d,g,p,mod,&t,&u,&tdn);
! 1720: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1721: sugar = MAX(sugar,psugar);
! 1722: if ( !u ) {
! 1723: if ( d )
! 1724: d->sugar = sugar;
! 1725: *rp = d; *dnp = dn; return;
! 1726: } else {
! 1727: d = t;
! 1728: mulmp(CO,mod,dn,tdn,&tdn1); dn = tdn1;
! 1729: }
! 1730: break;
! 1731: }
! 1732: }
! 1733: if ( u )
! 1734: g = u;
! 1735: else if ( !full ) {
! 1736: if ( g ) {
! 1737: MKDP(g->nv,BDY(g),t); t->sugar = sugar; g = t;
! 1738: }
! 1739: *rp = g; *dnp = dn; return;
! 1740: } else {
! 1741: m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
! 1742: NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
! 1743: addmd(CO,mod,d,t,&s); d = s;
! 1744: dp_rest(g,&t); g = t;
! 1745: }
! 1746: }
! 1747: if ( d )
! 1748: d->sugar = sugar;
! 1749: *rp = d; *dnp = dn;
! 1750: }
! 1751:
! 1752: void _dp_nf_mod_destructive(NODE b,DP g,DP *ps,int mod,int full,DP *rp)
! 1753: {
! 1754: DP u,p,d;
! 1755: NODE l;
! 1756: MP m,mrd;
! 1757: int sugar,psugar,n,h_reducible;
! 1758:
! 1759: if ( !g ) {
! 1760: *rp = 0; return;
! 1761: }
! 1762: sugar = g->sugar;
! 1763: n = g->nv;
! 1764: for ( d = 0; g; ) {
! 1765: for ( h_reducible = 0, l = b; l; l = NEXT(l) ) {
! 1766: if ( dp_redble(g,p = ps[(long)BDY(l)]) ) {
! 1767: h_reducible = 1;
! 1768: psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
! 1769: _dp_red_mod_destructive(g,p,mod,&u); g = u;
! 1770: sugar = MAX(sugar,psugar);
! 1771: if ( !g ) {
! 1772: if ( d )
! 1773: d->sugar = sugar;
! 1774: _dptodp(d,rp); _free_dp(d); return;
! 1775: }
! 1776: break;
! 1777: }
! 1778: }
! 1779: if ( !h_reducible ) {
! 1780: /* head term is not reducible */
! 1781: if ( !full ) {
! 1782: if ( g )
! 1783: g->sugar = sugar;
! 1784: _dptodp(g,rp); _free_dp(g); return;
! 1785: } else {
! 1786: m = BDY(g);
! 1787: if ( NEXT(m) ) {
! 1788: BDY(g) = NEXT(m); NEXT(m) = 0;
! 1789: } else {
! 1790: _FREEDP(g); g = 0;
! 1791: }
! 1792: if ( d ) {
! 1793: for ( mrd = BDY(d); NEXT(mrd); mrd = NEXT(mrd) );
! 1794: NEXT(mrd) = m;
! 1795: } else {
! 1796: _MKDP(n,m,d);
! 1797: }
! 1798: }
! 1799: }
! 1800: }
! 1801: if ( d )
! 1802: d->sugar = sugar;
! 1803: _dptodp(d,rp); _free_dp(d);
! 1804: }
! 1805:
! 1806: /* reduction by linear base over a field */
! 1807:
! 1808: void dp_lnf_f(DP p1,DP p2,NODE g,DP *r1p,DP *r2p)
! 1809: {
! 1810: DP r1,r2,b1,b2,t,s;
! 1811: Obj c,c1,c2;
! 1812: NODE l,b;
! 1813: int n;
! 1814:
! 1815: if ( !p1 ) {
! 1816: *r1p = p1; *r2p = p2; return;
! 1817: }
! 1818: n = p1->nv;
! 1819: for ( l = g, r1 = p1, r2 = p2; l; l = NEXT(l) ) {
! 1820: if ( !r1 ) {
! 1821: *r1p = r1; *r2p = r2; return;
! 1822: }
! 1823: b = BDY((LIST)BDY(l)); b1 = (DP)BDY(b);
! 1824: if ( dl_equal(n,BDY(r1)->dl,BDY(b1)->dl) ) {
! 1825: b2 = (DP)BDY(NEXT(b));
! 1826: divr(CO,(Obj)ONE,(Obj)BDY(b1)->c,&c1);
! 1827: mulr(CO,c1,(Obj)BDY(r1)->c,&c2); chsgnr(c2,&c);
! 1828: muldc(CO,b1,(Obj)c,&t); addd(CO,r1,t,&s); r1 = s;
! 1829: muldc(CO,b2,(Obj)c,&t); addd(CO,r2,t,&s); r2 = s;
! 1830: }
! 1831: }
! 1832: *r1p = r1; *r2p = r2;
! 1833: }
! 1834:
! 1835: /* reduction by linear base over GF(mod) */
! 1836:
! 1837: void dp_lnf_mod(DP p1,DP p2,NODE g,int mod,DP *r1p,DP *r2p)
! 1838: {
! 1839: DP r1,r2,b1,b2,t,s;
! 1840: P c;
! 1841: MQ c1,c2;
! 1842: NODE l,b;
! 1843: int n;
! 1844:
! 1845: if ( !p1 ) {
! 1846: *r1p = p1; *r2p = p2; return;
! 1847: }
! 1848: n = p1->nv;
! 1849: for ( l = g, r1 = p1, r2 = p2; l; l = NEXT(l) ) {
! 1850: if ( !r1 ) {
! 1851: *r1p = r1; *r2p = r2; return;
! 1852: }
! 1853: b = BDY((LIST)BDY(l)); b1 = (DP)BDY(b);
! 1854: if ( dl_equal(n,BDY(r1)->dl,BDY(b1)->dl) ) {
! 1855: b2 = (DP)BDY(NEXT(b));
! 1856: invmq(mod,(MQ)BDY(b1)->c,&c1);
! 1857: mulmq(mod,c1,(MQ)BDY(r1)->c,&c2); chsgnmp(mod,(P)c2,&c);
! 1858: mulmdc(CO,mod,b1,c,&t); addmd(CO,mod,r1,t,&s); r1 = s;
! 1859: mulmdc(CO,mod,b2,c,&t); addmd(CO,mod,r2,t,&s); r2 = s;
! 1860: }
! 1861: }
! 1862: *r1p = r1; *r2p = r2;
! 1863: }
! 1864:
! 1865: void dp_nf_tab_mod(DP p,LIST *tab,int mod,DP *rp)
! 1866: {
! 1867: DP s,t,u;
! 1868: MP m;
! 1869: DL h;
! 1870: int i,n;
! 1871:
! 1872: if ( !p ) {
! 1873: *rp = p; return;
! 1874: }
! 1875: n = p->nv;
! 1876: for ( s = 0, i = 0, m = BDY(p); m; m = NEXT(m) ) {
! 1877: h = m->dl;
! 1878: while ( !dl_equal(n,h,BDY((DP)BDY(BDY(tab[i])))->dl ) )
! 1879: i++;
! 1880: mulmdc(CO,mod,(DP)BDY(NEXT(BDY(tab[i]))),(P)m->c,&t);
! 1881: addmd(CO,mod,s,t,&u); s = u;
! 1882: }
! 1883: *rp = s;
! 1884: }
! 1885:
! 1886: void dp_nf_tab_f(DP p,LIST *tab,DP *rp)
! 1887: {
! 1888: DP s,t,u;
! 1889: MP m;
! 1890: DL h;
! 1891: int i,n;
! 1892:
! 1893: if ( !p ) {
! 1894: *rp = p; return;
! 1895: }
! 1896: n = p->nv;
! 1897: for ( s = 0, i = 0, m = BDY(p); m; m = NEXT(m) ) {
! 1898: h = m->dl;
! 1899: while ( !dl_equal(n,h,BDY((DP)BDY(BDY(tab[i])))->dl ) )
! 1900: i++;
! 1901: muldc(CO,(DP)BDY(NEXT(BDY(tab[i]))),m->c,&t);
! 1902: addd(CO,s,t,&u); s = u;
! 1903: }
! 1904: *rp = s;
! 1905: }
! 1906:
! 1907: /*
! 1908: * setting flags
! 1909: * call create_order_spec with vl=0 to set old type order.
! 1910: *
! 1911: */
! 1912:
! 1913: int create_order_spec(VL vl,Obj obj,struct order_spec **specp)
! 1914: {
! 1915: int i,j,n,s,row,col,ret,wlen;
! 1916: struct order_spec *spec;
! 1917: struct order_pair *l;
! 1918: Obj wp,wm;
! 1919: NODE node,t,tn,wpair;
! 1920: MAT m;
! 1921: VECT v;
! 1922: pointer **b,*bv;
! 1923: int **w;
! 1924:
! 1925: if ( vl && obj && OID(obj) == O_LIST ) {
! 1926: ret = create_composite_order_spec(vl,(LIST)obj,specp);
! 1927: if ( show_orderspec )
! 1928: print_composite_order_spec(*specp);
! 1929: return ret;
! 1930: }
! 1931:
! 1932: *specp = spec = (struct order_spec *)MALLOC(sizeof(struct order_spec));
! 1933: if ( !obj || NUM(obj) ) {
! 1934: spec->id = 0; spec->obj = obj;
! 1935: spec->ord.simple = QTOS((Q)obj);
! 1936: return 1;
! 1937: } else if ( OID(obj) == O_LIST ) {
! 1938: /* module order; obj = [0|1,w,ord] or [0|1,ord] */
! 1939: node = BDY((LIST)obj);
! 1940: if ( !BDY(node) || NUM(BDY(node)) ) {
! 1941: switch ( length(node) ) {
! 1942: case 2:
! 1943: create_order_spec(0,(Obj)BDY(NEXT(node)),&spec);
! 1944: spec->id += 256; spec->obj = obj;
! 1945: spec->top_weight = 0;
! 1946: spec->module_rank = 0;
! 1947: spec->module_top_weight = 0;
! 1948: spec->ispot = (BDY(node)!=0);
! 1949: if ( spec->ispot ) {
! 1950: n = QTOS((Q)BDY(node));
! 1951: if ( n < 0 )
! 1952: spec->pot_nelim = -n;
! 1953: else
! 1954: spec->pot_nelim = 0;
! 1955: }
! 1956: break;
! 1957:
! 1958: case 3:
! 1959: create_order_spec(0,(Obj)BDY(NEXT(NEXT(node))),&spec);
! 1960: spec->id += 256; spec->obj = obj;
! 1961: spec->ispot = (BDY(node)!=0);
! 1962: node = NEXT(node);
! 1963: if ( !BDY(node) || OID(BDY(node)) != O_LIST )
! 1964: error("create_order_spec : [weight_for_poly,weight_for_modlue] must be specified as a module topweight");
! 1965: wpair = BDY((LIST)BDY(node));
! 1966: if ( length(wpair) != 2 )
! 1967: error("create_order_spec : [weight_for_poly,weight_for_modlue] must be specified as a module topweight");
! 1968:
! 1969: wp = BDY(wpair);
! 1970: wm = BDY(NEXT(wpair));
! 1971: if ( !wp || OID(wp) != O_LIST || !wm || OID(wm) != O_LIST )
! 1972: error("create_order_spec : [weight_for_poly,weight_for_modlue] must be specified as a module topweight");
! 1973: spec->nv = length(BDY((LIST)wp));
! 1974: spec->top_weight = (int *)MALLOC_ATOMIC(spec->nv*sizeof(int));
! 1975: for ( i = 0, t = BDY((LIST)wp); i < spec->nv; t = NEXT(t), i++ )
! 1976: spec->top_weight[i] = QTOS((Q)BDY(t));
! 1977:
! 1978: spec->module_rank = length(BDY((LIST)wm));
! 1979: spec->module_top_weight = (int *)MALLOC_ATOMIC(spec->module_rank*sizeof(int));
! 1980: for ( i = 0, t = BDY((LIST)wm); i < spec->module_rank; t = NEXT(t), i++ )
! 1981: spec->module_top_weight[i] = QTOS((Q)BDY(t));
! 1982: break;
! 1983: default:
! 1984: error("create_order_spec : invalid arguments for module order");
! 1985: }
! 1986:
! 1987: *specp = spec;
! 1988: return 1;
! 1989: } else {
! 1990: /* block order in polynomial ring */
! 1991: for ( n = 0, t = node; t; t = NEXT(t), n++ );
! 1992: l = (struct order_pair *)MALLOC_ATOMIC(n*sizeof(struct order_pair));
! 1993: for ( i = 0, t = node, s = 0; i < n; t = NEXT(t), i++ ) {
! 1994: tn = BDY((LIST)BDY(t)); l[i].order = QTOS((Q)BDY(tn));
! 1995: tn = NEXT(tn); l[i].length = QTOS((Q)BDY(tn));
! 1996: s += l[i].length;
! 1997: }
! 1998: spec->id = 1; spec->obj = obj;
! 1999: spec->ord.block.order_pair = l;
! 2000: spec->ord.block.length = n; spec->nv = s;
! 2001: return 1;
! 2002: }
! 2003: } else if ( OID(obj) == O_MAT ) {
! 2004: m = (MAT)obj; row = m->row; col = m->col; b = BDY(m);
! 2005: w = almat(row,col);
! 2006: for ( i = 0; i < row; i++ )
! 2007: for ( j = 0; j < col; j++ )
! 2008: w[i][j] = QTOS((Q)b[i][j]);
! 2009: spec->id = 2; spec->obj = obj;
! 2010: spec->nv = col; spec->ord.matrix.row = row;
! 2011: spec->ord.matrix.matrix = w;
! 2012: return 1;
! 2013: } else
! 2014: return 0;
! 2015: }
! 2016:
! 2017: void print_composite_order_spec(struct order_spec *spec)
! 2018: {
! 2019: int nv,n,len,i,j,k,start;
! 2020: struct weight_or_block *worb;
! 2021:
! 2022: nv = spec->nv;
! 2023: n = spec->ord.composite.length;
! 2024: worb = spec->ord.composite.w_or_b;
! 2025: for ( i = 0; i < n; i++, worb++ ) {
! 2026: len = worb->length;
! 2027: printf("[ ");
! 2028: switch ( worb->type ) {
! 2029: case IS_DENSE_WEIGHT:
! 2030: for ( j = 0; j < len; j++ )
! 2031: printf("%d ",worb->body.dense_weight[j]);
! 2032: for ( ; j < nv; j++ )
! 2033: printf("0 ");
! 2034: break;
! 2035: case IS_SPARSE_WEIGHT:
! 2036: for ( j = 0, k = 0; j < nv; j++ )
! 2037: if ( j == worb->body.sparse_weight[k].pos )
! 2038: printf("%d ",worb->body.sparse_weight[k++].value);
! 2039: else
! 2040: printf("0 ");
! 2041: break;
! 2042: case IS_BLOCK:
! 2043: start = worb->body.block.start;
! 2044: for ( j = 0; j < start; j++ ) printf("0 ");
! 2045: switch ( worb->body.block.order ) {
! 2046: case 0:
! 2047: for ( k = 0; k < len; k++, j++ ) printf("R ");
! 2048: break;
! 2049: case 1:
! 2050: for ( k = 0; k < len; k++, j++ ) printf("G ");
! 2051: break;
! 2052: case 2:
! 2053: for ( k = 0; k < len; k++, j++ ) printf("L ");
! 2054: break;
! 2055: }
! 2056: for ( ; j < nv; j++ ) printf("0 ");
! 2057: break;
! 2058: }
! 2059: printf("]\n");
! 2060: }
! 2061: }
! 2062:
! 2063: struct order_spec *append_block(struct order_spec *spec,
! 2064: int nv,int nalg,int ord)
! 2065: {
! 2066: MAT m,mat;
! 2067: int i,j,row,col,n;
! 2068: Z **b,**wp;
! 2069: int **w;
! 2070: NODE t,s,s0;
! 2071: struct order_pair *l,*l0;
! 2072: int n0,nv0;
! 2073: LIST list0,list1,list;
! 2074: Z oq,nq;
! 2075: struct order_spec *r;
! 2076:
! 2077: r = (struct order_spec *)MALLOC(sizeof(struct order_spec));
! 2078: switch ( spec->id ) {
! 2079: case 0:
! 2080: STOQ(spec->ord.simple,oq); STOQ(nv,nq);
! 2081: t = mknode(2,oq,nq); MKLIST(list0,t);
! 2082: STOQ(ord,oq); STOQ(nalg,nq);
! 2083: t = mknode(2,oq,nq); MKLIST(list1,t);
! 2084: t = mknode(2,list0,list1); MKLIST(list,t);
! 2085: l = (struct order_pair *)MALLOC_ATOMIC(2*sizeof(struct order_pair));
! 2086: l[0].order = spec->ord.simple; l[0].length = nv;
! 2087: l[1].order = ord; l[1].length = nalg;
! 2088: r->id = 1; r->obj = (Obj)list;
! 2089: r->ord.block.order_pair = l;
! 2090: r->ord.block.length = 2;
! 2091: r->nv = nv+nalg;
! 2092: break;
! 2093: case 1:
! 2094: if ( spec->nv != nv )
! 2095: error("append_block : number of variables mismatch");
! 2096: l0 = spec->ord.block.order_pair;
! 2097: n0 = spec->ord.block.length;
! 2098: nv0 = spec->nv;
! 2099: list0 = (LIST)spec->obj;
! 2100: n = n0+1;
! 2101: l = (struct order_pair *)MALLOC_ATOMIC(n*sizeof(struct order_pair));
! 2102: for ( i = 0; i < n0; i++ )
! 2103: l[i] = l0[i];
! 2104: l[i].order = ord; l[i].length = nalg;
! 2105: for ( t = BDY(list0), s0 = 0; t; t = NEXT(t) ) {
! 2106: NEXTNODE(s0,s); BDY(s) = BDY(t);
! 2107: }
! 2108: STOQ(ord,oq); STOQ(nalg,nq);
! 2109: t = mknode(2,oq,nq); MKLIST(list,t);
! 2110: NEXTNODE(s0,s); BDY(s) = (pointer)list; NEXT(s) = 0;
! 2111: MKLIST(list,s0);
! 2112: r->id = 1; r->obj = (Obj)list;
! 2113: r->ord.block.order_pair = l;
! 2114: r->ord.block.length = n;
! 2115: r->nv = nv+nalg;
! 2116: break;
! 2117: case 2:
! 2118: if ( spec->nv != nv )
! 2119: error("append_block : number of variables mismatch");
! 2120: m = (MAT)spec->obj;
! 2121: row = m->row; col = m->col; b = (Z **)BDY(m);
! 2122: w = almat(row+nalg,col+nalg);
! 2123: MKMAT(mat,row+nalg,col+nalg); wp = (Z **)BDY(mat);
! 2124: for ( i = 0; i < row; i++ )
! 2125: for ( j = 0; j < col; j++ ) {
! 2126: w[i][j] = QTOS(b[i][j]);
! 2127: wp[i][j] = b[i][j];
! 2128: }
! 2129: for ( i = 0; i < nalg; i++ ) {
! 2130: w[i+row][i+col] = 1;
! 2131: wp[i+row][i+col] = ONE;
! 2132: }
! 2133: r->id = 2; r->obj = (Obj)mat;
! 2134: r->nv = col+nalg; r->ord.matrix.row = row+nalg;
! 2135: r->ord.matrix.matrix = w;
! 2136: break;
! 2137: case 3:
! 2138: default:
! 2139: /* XXX */
! 2140: error("append_block : not implemented yet");
! 2141: }
! 2142: return r;
! 2143: }
! 2144:
! 2145: int comp_sw(struct sparse_weight *a, struct sparse_weight *b)
! 2146: {
! 2147: if ( a->pos > b->pos ) return 1;
! 2148: else if ( a->pos < b->pos ) return -1;
! 2149: else return 0;
! 2150: }
! 2151:
! 2152: /* order = [w_or_b, w_or_b, ... ] */
! 2153: /* w_or_b = w or b */
! 2154: /* w = [1,2,...] or [x,1,y,2,...] */
! 2155: /* b = [@lex,x,y,...,z] etc */
! 2156:
! 2157: int create_composite_order_spec(VL vl,LIST order,struct order_spec **specp)
! 2158: {
! 2159: NODE wb,t,p;
! 2160: struct order_spec *spec;
! 2161: VL tvl;
! 2162: int n,i,j,k,l,start,end,len,w;
! 2163: int *dw;
! 2164: struct sparse_weight *sw;
! 2165: struct weight_or_block *w_or_b;
! 2166: Obj a0;
! 2167: NODE a;
! 2168: V v,sv,ev;
! 2169: SYMBOL sym;
! 2170: int *top;
! 2171:
! 2172: /* l = number of vars in vl */
! 2173: for ( l = 0, tvl = vl; tvl; tvl = NEXT(tvl), l++ );
! 2174: /* n = number of primitives in order */
! 2175: wb = BDY(order);
! 2176: n = length(wb);
! 2177: *specp = spec = (struct order_spec *)MALLOC(sizeof(struct order_spec));
! 2178: spec->id = 3;
! 2179: spec->obj = (Obj)order;
! 2180: spec->nv = l;
! 2181: spec->ord.composite.length = n;
! 2182: w_or_b = spec->ord.composite.w_or_b = (struct weight_or_block *)
! 2183: MALLOC(sizeof(struct weight_or_block)*(n+1));
! 2184:
! 2185: /* top : register the top variable in each w_or_b specification */
! 2186: top = (int *)ALLOCA(l*sizeof(int));
! 2187: for ( i = 0; i < l; i++ ) top[i] = 0;
! 2188:
! 2189: for ( t = wb, i = 0; t; t = NEXT(t), i++ ) {
! 2190: if ( !BDY(t) || OID((Obj)BDY(t)) != O_LIST )
! 2191: error("a list of lists must be specified for the key \"order\"");
! 2192: a = BDY((LIST)BDY(t));
! 2193: len = length(a);
! 2194: a0 = (Obj)BDY(a);
! 2195: if ( !a0 || OID(a0) == O_N ) {
! 2196: /* a is a dense weight vector */
! 2197: dw = (int *)MALLOC(sizeof(int)*len);
! 2198: for ( j = 0, p = a; j < len; p = NEXT(p), j++ ) {
! 2199: if ( !INT((Q)BDY(p)) )
! 2200: error("a dense weight vector must be specified as a list of integers");
! 2201: dw[j] = QTOS((Q)BDY(p));
! 2202: }
! 2203: w_or_b[i].type = IS_DENSE_WEIGHT;
! 2204: w_or_b[i].length = len;
! 2205: w_or_b[i].body.dense_weight = dw;
! 2206:
! 2207: /* find the top */
! 2208: for ( k = 0; k < len && !dw[k]; k++ );
! 2209: if ( k < len ) top[k] = 1;
! 2210:
! 2211: } else if ( OID(a0) == O_P ) {
! 2212: /* a is a sparse weight vector */
! 2213: len >>= 1;
! 2214: sw = (struct sparse_weight *)
! 2215: MALLOC(sizeof(struct sparse_weight)*len);
! 2216: for ( j = 0, p = a; j < len; j++ ) {
! 2217: if ( !BDY(p) || OID((P)BDY(p)) != O_P )
! 2218: error("a sparse weight vector must be specified as [var1,weight1,...]");
! 2219: v = VR((P)BDY(p)); p = NEXT(p);
! 2220: for ( tvl = vl, k = 0; tvl && tvl->v != v;
! 2221: k++, tvl = NEXT(tvl) );
! 2222: if ( !tvl )
! 2223: error("invalid variable name in a sparse weight vector");
! 2224: sw[j].pos = k;
! 2225: if ( !INT((Q)BDY(p)) )
! 2226: error("a sparse weight vector must be specified as [var1,weight1,...]");
! 2227: sw[j].value = QTOS((Q)BDY(p)); p = NEXT(p);
! 2228: }
! 2229: qsort(sw,len,sizeof(struct sparse_weight),
! 2230: (int (*)(const void *,const void *))comp_sw);
! 2231: w_or_b[i].type = IS_SPARSE_WEIGHT;
! 2232: w_or_b[i].length = len;
! 2233: w_or_b[i].body.sparse_weight = sw;
! 2234:
! 2235: /* find the top */
! 2236: for ( k = 0; k < len && !sw[k].value; k++ );
! 2237: if ( k < len ) top[sw[k].pos] = 1;
! 2238: } else if ( OID(a0) == O_RANGE ) {
! 2239: /* [range(v1,v2),w] */
! 2240: sv = VR((P)(((RANGE)a0)->start));
! 2241: ev = VR((P)(((RANGE)a0)->end));
! 2242: for ( tvl = vl, start = 0; tvl && tvl->v != sv; start++, tvl = NEXT(tvl) );
! 2243: if ( !tvl )
! 2244: error("invalid range");
! 2245: for ( end = start; tvl && tvl->v != ev; end++, tvl = NEXT(tvl) );
! 2246: if ( !tvl )
! 2247: error("invalid range");
! 2248: len = end-start+1;
! 2249: sw = (struct sparse_weight *)
! 2250: MALLOC(sizeof(struct sparse_weight)*len);
! 2251: w = QTOS((Q)BDY(NEXT(a)));
! 2252: for ( tvl = vl, k = 0; k < start; k++, tvl = NEXT(tvl) );
! 2253: for ( j = 0 ; k <= end; k++, tvl = NEXT(tvl), j++ ) {
! 2254: sw[j].pos = k;
! 2255: sw[j].value = w;
! 2256: }
! 2257: w_or_b[i].type = IS_SPARSE_WEIGHT;
! 2258: w_or_b[i].length = len;
! 2259: w_or_b[i].body.sparse_weight = sw;
! 2260:
! 2261: /* register the top */
! 2262: if ( w ) top[start] = 1;
! 2263: } else if ( OID(a0) == O_SYMBOL ) {
! 2264: /* a is a block */
! 2265: sym = (SYMBOL)a0; a = NEXT(a); len--;
! 2266: if ( OID((Obj)BDY(a)) == O_RANGE ) {
! 2267: sv = VR((P)(((RANGE)BDY(a))->start));
! 2268: ev = VR((P)(((RANGE)BDY(a))->end));
! 2269: for ( tvl = vl, start = 0; tvl && tvl->v != sv; start++, tvl = NEXT(tvl) );
! 2270: if ( !tvl )
! 2271: error("invalid range");
! 2272: for ( end = start; tvl && tvl->v != ev; end++, tvl = NEXT(tvl) );
! 2273: if ( !tvl )
! 2274: error("invalid range");
! 2275: len = end-start+1;
! 2276: } else {
! 2277: for ( start = 0, tvl = vl; tvl->v != VR((P)BDY(a));
! 2278: tvl = NEXT(tvl), start++ );
! 2279: for ( p = NEXT(a), tvl = NEXT(tvl); p;
! 2280: p = NEXT(p), tvl = NEXT(tvl) ) {
! 2281: if ( !BDY(p) || OID((P)BDY(p)) != O_P )
! 2282: error("a block must be specified as [ordsymbol,var1,var2,...]");
! 2283: if ( tvl->v != VR((P)BDY(p)) ) break;
! 2284: }
! 2285: if ( p )
! 2286: error("a block must be contiguous in the variable list");
! 2287: }
! 2288: w_or_b[i].type = IS_BLOCK;
! 2289: w_or_b[i].length = len;
! 2290: w_or_b[i].body.block.start = start;
! 2291: if ( !strcmp(sym->name,"@grlex") )
! 2292: w_or_b[i].body.block.order = 0;
! 2293: else if ( !strcmp(sym->name,"@glex") )
! 2294: w_or_b[i].body.block.order = 1;
! 2295: else if ( !strcmp(sym->name,"@lex") )
! 2296: w_or_b[i].body.block.order = 2;
! 2297: else
! 2298: error("invalid ordername");
! 2299: /* register the tops */
! 2300: for ( j = 0, k = start; j < len; j++, k++ )
! 2301: top[k] = 1;
! 2302: }
! 2303: }
! 2304: for ( k = 0; k < l && top[k]; k++ );
! 2305: if ( k < l ) {
! 2306: /* incomplete order specification; add @grlex */
! 2307: w_or_b[n].type = IS_BLOCK;
! 2308: w_or_b[n].length = l;
! 2309: w_or_b[n].body.block.start = 0;
! 2310: w_or_b[n].body.block.order = 0;
! 2311: spec->ord.composite.length = n+1;
! 2312: }
! 2313: }
! 2314:
! 2315: /* module order spec */
! 2316:
! 2317: void create_modorder_spec(int id,LIST shift,struct modorder_spec **s)
! 2318: {
! 2319: struct modorder_spec *spec;
! 2320: NODE n,t;
! 2321: LIST list;
! 2322: int *ds;
! 2323: int i,l;
! 2324: Z q;
! 2325:
! 2326: *s = spec = (struct modorder_spec *)MALLOC(sizeof(struct modorder_spec));
! 2327: spec->id = id;
! 2328: if ( shift ) {
! 2329: n = BDY(shift);
! 2330: spec->len = l = length(n);
! 2331: spec->degree_shift = ds = (int *)MALLOC_ATOMIC(l*sizeof(int));
! 2332: for ( t = n, i = 0; t; t = NEXT(t), i++ )
! 2333: ds[i] = QTOS((Q)BDY(t));
! 2334: } else {
! 2335: spec->len = 0;
! 2336: spec->degree_shift = 0;
! 2337: }
! 2338: STOQ(id,q);
! 2339: n = mknode(2,q,shift);
! 2340: MKLIST(list,n);
! 2341: spec->obj = (Obj)list;
! 2342: }
! 2343:
! 2344: /*
! 2345: * converters
! 2346: *
! 2347: */
! 2348:
! 2349: void dp_homo(DP p,DP *rp)
! 2350: {
! 2351: MP m,mr,mr0;
! 2352: int i,n,nv,td;
! 2353: DL dl,dlh;
! 2354:
! 2355: if ( !p )
! 2356: *rp = 0;
! 2357: else {
! 2358: n = p->nv; nv = n + 1;
! 2359: m = BDY(p); td = sugard(m);
! 2360: for ( mr0 = 0; m; m = NEXT(m) ) {
! 2361: NEXTMP(mr0,mr); mr->c = m->c;
! 2362: dl = m->dl;
! 2363: mr->dl = dlh = (DL)MALLOC_ATOMIC((nv+1)*sizeof(int));
! 2364: dlh->td = td;
! 2365: for ( i = 0; i < n; i++ )
! 2366: dlh->d[i] = dl->d[i];
! 2367: dlh->d[n] = td - dl->td;
! 2368: }
! 2369: NEXT(mr) = 0; MKDP(nv,mr0,*rp); (*rp)->sugar = p->sugar;
! 2370: }
! 2371: }
! 2372:
! 2373: void dp_dehomo(DP p,DP *rp)
! 2374: {
! 2375: MP m,mr,mr0;
! 2376: int i,n,nv;
! 2377: DL dl,dlh;
! 2378:
! 2379: if ( !p )
! 2380: *rp = 0;
! 2381: else {
! 2382: n = p->nv; nv = n - 1;
! 2383: m = BDY(p);
! 2384: for ( mr0 = 0; m; m = NEXT(m) ) {
! 2385: NEXTMP(mr0,mr); mr->c = m->c;
! 2386: dlh = m->dl;
! 2387: mr->dl = dl = (DL)MALLOC_ATOMIC((nv+1)*sizeof(int));
! 2388: dl->td = dlh->td - dlh->d[nv];
! 2389: for ( i = 0; i < nv; i++ )
! 2390: dl->d[i] = dlh->d[i];
! 2391: }
! 2392: NEXT(mr) = 0; MKDP(nv,mr0,*rp); (*rp)->sugar = p->sugar;
! 2393: }
! 2394: }
! 2395:
! 2396: void dp_mod(DP p,int mod,NODE subst,DP *rp)
! 2397: {
! 2398: MP m,mr,mr0;
! 2399: P t,s,s1;
! 2400: V v;
! 2401: NODE tn;
! 2402:
! 2403: if ( !p )
! 2404: *rp = 0;
! 2405: else {
! 2406: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
! 2407: for ( tn = subst, s = (P)m->c; tn; tn = NEXT(tn) ) {
! 2408: v = VR((P)BDY(tn)); tn = NEXT(tn);
! 2409: substp(CO,s,v,(P)BDY(tn),&s1); s = s1;
! 2410: }
! 2411: ptomp(mod,s,&t);
! 2412: if ( t ) {
! 2413: NEXTMP(mr0,mr); mr->c = (Obj)t; mr->dl = m->dl;
! 2414: }
! 2415: }
! 2416: if ( mr0 ) {
! 2417: NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
! 2418: } else
! 2419: *rp = 0;
! 2420: }
! 2421: }
! 2422:
! 2423: void dp_rat(DP p,DP *rp)
! 2424: {
! 2425: MP m,mr,mr0;
! 2426:
! 2427: if ( !p )
! 2428: *rp = 0;
! 2429: else {
! 2430: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
! 2431: NEXTMP(mr0,mr); mptop((P)m->c,(P *)&mr->c); mr->dl = m->dl;
! 2432: }
! 2433: if ( mr0 ) {
! 2434: NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
! 2435: } else
! 2436: *rp = 0;
! 2437: }
! 2438: }
! 2439:
! 2440:
! 2441: void homogenize_order(struct order_spec *old,int n,struct order_spec **newp)
! 2442: {
! 2443: struct order_pair *l;
! 2444: int length,nv,row,i,j;
! 2445: int **newm,**oldm;
! 2446: struct order_spec *new;
! 2447: int onv,nnv,nlen,olen,owlen;
! 2448: struct weight_or_block *owb,*nwb;
! 2449:
! 2450: *newp = new = (struct order_spec *)MALLOC(sizeof(struct order_spec));
! 2451: switch ( old->id ) {
! 2452: case 0:
! 2453: switch ( old->ord.simple ) {
! 2454: case 0:
! 2455: new->id = 0; new->ord.simple = 0; break;
! 2456: case 1:
! 2457: l = (struct order_pair *)
! 2458: MALLOC_ATOMIC(2*sizeof(struct order_pair));
! 2459: l[0].length = n; l[0].order = 1;
! 2460: l[1].length = 1; l[1].order = 2;
! 2461: new->id = 1;
! 2462: new->ord.block.order_pair = l;
! 2463: new->ord.block.length = 2; new->nv = n+1;
! 2464: break;
! 2465: case 2:
! 2466: new->id = 0; new->ord.simple = 1; break;
! 2467: case 3: case 4: case 5:
! 2468: new->id = 0; new->ord.simple = old->ord.simple+3;
! 2469: dp_nelim = n-1; break;
! 2470: case 6: case 7: case 8: case 9:
! 2471: new->id = 0; new->ord.simple = old->ord.simple; break;
! 2472: default:
! 2473: error("homogenize_order : invalid input");
! 2474: }
! 2475: break;
! 2476: case 1: case 257:
! 2477: length = old->ord.block.length;
! 2478: l = (struct order_pair *)
! 2479: MALLOC_ATOMIC((length+1)*sizeof(struct order_pair));
! 2480: bcopy((char *)old->ord.block.order_pair,(char *)l,length*sizeof(struct order_pair));
! 2481: l[length].order = 2; l[length].length = 1;
! 2482: new->id = old->id; new->nv = n+1;
! 2483: new->ord.block.order_pair = l;
! 2484: new->ord.block.length = length+1;
! 2485: new->ispot = old->ispot;
! 2486: break;
! 2487: case 2: case 258:
! 2488: nv = old->nv; row = old->ord.matrix.row;
! 2489: oldm = old->ord.matrix.matrix; newm = almat(row+1,nv+1);
! 2490: for ( i = 0; i <= nv; i++ )
! 2491: newm[0][i] = 1;
! 2492: for ( i = 0; i < row; i++ ) {
! 2493: for ( j = 0; j < nv; j++ )
! 2494: newm[i+1][j] = oldm[i][j];
! 2495: newm[i+1][j] = 0;
! 2496: }
! 2497: new->id = old->id; new->nv = nv+1;
! 2498: new->ord.matrix.row = row+1; new->ord.matrix.matrix = newm;
! 2499: new->ispot = old->ispot;
! 2500: break;
! 2501: case 3: case 259:
! 2502: onv = old->nv;
! 2503: nnv = onv+1;
! 2504: olen = old->ord.composite.length;
! 2505: nlen = olen+1;
! 2506: owb = old->ord.composite.w_or_b;
! 2507: nwb = (struct weight_or_block *)
! 2508: MALLOC(nlen*sizeof(struct weight_or_block));
! 2509: for ( i = 0; i < olen; i++ ) {
! 2510: nwb[i].type = owb[i].type;
! 2511: switch ( owb[i].type ) {
! 2512: case IS_DENSE_WEIGHT:
! 2513: owlen = owb[i].length;
! 2514: nwb[i].length = owlen+1;
! 2515: nwb[i].body.dense_weight = (int *)MALLOC((owlen+1)*sizeof(int));
! 2516: for ( j = 0; j < owlen; j++ )
! 2517: nwb[i].body.dense_weight[j] = owb[i].body.dense_weight[j];
! 2518: nwb[i].body.dense_weight[owlen] = 0;
! 2519: break;
! 2520: case IS_SPARSE_WEIGHT:
! 2521: nwb[i].length = owb[i].length;
! 2522: nwb[i].body.sparse_weight = owb[i].body.sparse_weight;
! 2523: break;
! 2524: case IS_BLOCK:
! 2525: nwb[i].length = owb[i].length;
! 2526: nwb[i].body.block = owb[i].body.block;
! 2527: break;
! 2528: }
! 2529: }
! 2530: nwb[i].type = IS_SPARSE_WEIGHT;
! 2531: nwb[i].body.sparse_weight =
! 2532: (struct sparse_weight *)MALLOC(sizeof(struct sparse_weight));
! 2533: nwb[i].body.sparse_weight[0].pos = onv;
! 2534: nwb[i].body.sparse_weight[0].value = 1;
! 2535: new->id = old->id;
! 2536: new->nv = nnv;
! 2537: new->ord.composite.length = nlen;
! 2538: new->ord.composite.w_or_b = nwb;
! 2539: new->ispot = old->ispot;
! 2540: print_composite_order_spec(new);
! 2541: break;
! 2542: case 256: /* simple module order */
! 2543: switch ( old->ord.simple ) {
! 2544: case 0:
! 2545: new->id = 256; new->ord.simple = 0; break;
! 2546: case 1:
! 2547: l = (struct order_pair *)
! 2548: MALLOC_ATOMIC(2*sizeof(struct order_pair));
! 2549: l[0].length = n; l[0].order = old->ord.simple;
! 2550: l[1].length = 1; l[1].order = 2;
! 2551: new->id = 257;
! 2552: new->ord.block.order_pair = l;
! 2553: new->ord.block.length = 2; new->nv = n+1;
! 2554: break;
! 2555: case 2:
! 2556: new->id = 256; new->ord.simple = 1; break;
! 2557: default:
! 2558: error("homogenize_order : invalid input");
! 2559: }
! 2560: new->ispot = old->ispot;
! 2561: break;
! 2562: default:
! 2563: error("homogenize_order : invalid input");
! 2564: }
! 2565: }
! 2566:
! 2567: int comp_nm(Q *a,Q *b)
! 2568: {
! 2569: Z z,nma,nmb;
! 2570:
! 2571: nmq(*a,&z); absz(z,&nma);
! 2572: nmq(*b,&z); absz(z,&nmb);
! 2573: return cmpz(nma,nmb);
! 2574: }
! 2575:
! 2576: void sortbynm(Q *w,int n)
! 2577: {
! 2578: qsort(w,n,sizeof(Q),(int (*)(const void *,const void *))comp_nm);
! 2579: }
! 2580:
! 2581:
! 2582: /*
! 2583: * simple operations
! 2584: *
! 2585: */
! 2586:
! 2587: int dp_redble(DP p1,DP p2)
! 2588: {
! 2589: int i,n;
! 2590: DL d1,d2;
! 2591:
! 2592: d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 2593: if ( d1->td < d2->td )
! 2594: return 0;
! 2595: else {
! 2596: for ( i = 0, n = p1->nv; i < n; i++ )
! 2597: if ( d1->d[i] < d2->d[i] )
! 2598: return 0;
! 2599: return 1;
! 2600: }
! 2601: }
! 2602:
! 2603: int dpm_redble(DPM p1,DPM p2)
! 2604: {
! 2605: int i,n;
! 2606: DL d1,d2;
! 2607:
! 2608: if ( BDY(p1)->pos != BDY(p2)->pos ) return 0;
! 2609: d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 2610: if ( d1->td < d2->td )
! 2611: return 0;
! 2612: else {
! 2613: for ( i = 0, n = p1->nv; i < n; i++ )
! 2614: if ( d1->d[i] < d2->d[i] )
! 2615: return 0;
! 2616: return 1;
! 2617: }
! 2618: }
! 2619:
! 2620:
! 2621: void dp_subd(DP p1,DP p2,DP *rp)
! 2622: {
! 2623: int i,n;
! 2624: DL d1,d2,d;
! 2625: MP m;
! 2626: DP s;
! 2627:
! 2628: n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
! 2629: NEWDL(d,n); d->td = d1->td - d2->td;
! 2630: for ( i = 0; i < n; i++ )
! 2631: d->d[i] = d1->d[i]-d2->d[i];
! 2632: NEWMP(m); m->dl = d; m->c = (Obj)ONE; NEXT(m) = 0;
! 2633: MKDP(n,m,s); s->sugar = d->td;
! 2634: *rp = s;
! 2635: }
! 2636:
! 2637: void dltod(DL d,int n,DP *rp)
! 2638: {
! 2639: MP m;
! 2640: DP s;
! 2641:
! 2642: NEWMP(m); m->dl = d; m->c = (Obj)ONE; NEXT(m) = 0;
! 2643: MKDP(n,m,s); s->sugar = d->td;
! 2644: *rp = s;
! 2645: }
! 2646:
! 2647: void dp_hm(DP p,DP *rp)
! 2648: {
! 2649: MP m,mr;
! 2650:
! 2651: if ( !p )
! 2652: *rp = 0;
! 2653: else {
! 2654: m = BDY(p);
! 2655: NEWMP(mr); mr->dl = m->dl; mr->c = m->c; NEXT(mr) = 0;
! 2656: MKDP(p->nv,mr,*rp); (*rp)->sugar = mr->dl->td; /* XXX */
! 2657: }
! 2658: }
! 2659:
! 2660: void dp_ht(DP p,DP *rp)
! 2661: {
! 2662: MP m,mr;
! 2663:
! 2664: if ( !p )
! 2665: *rp = 0;
! 2666: else {
! 2667: m = BDY(p);
! 2668: NEWMP(mr); mr->dl = m->dl; mr->c = (Obj)ONE; NEXT(mr) = 0;
! 2669: MKDP(p->nv,mr,*rp); (*rp)->sugar = mr->dl->td; /* XXX */
! 2670: }
! 2671: }
! 2672:
! 2673: void dpm_hm(DPM p,DPM *rp)
! 2674: {
! 2675: DMM m,mr;
! 2676:
! 2677: if ( !p )
! 2678: *rp = 0;
! 2679: else {
! 2680: m = BDY(p);
! 2681: NEWDMM(mr); mr->dl = m->dl; mr->c = m->c; mr->pos = m->pos; NEXT(mr) = 0;
! 2682: MKDPM(p->nv,mr,*rp); (*rp)->sugar = mr->dl->td; /* XXX */
! 2683: }
! 2684: }
! 2685:
! 2686: void dpm_ht(DPM p,DPM *rp)
! 2687: {
! 2688: DMM m,mr;
! 2689:
! 2690: if ( !p )
! 2691: *rp = 0;
! 2692: else {
! 2693: m = BDY(p);
! 2694: NEWDMM(mr); mr->dl = m->dl; mr->pos = m->pos; mr->c = (Obj)ONE; NEXT(mr) = 0;
! 2695: MKDPM(p->nv,mr,*rp); (*rp)->sugar = mr->dl->td; /* XXX */
! 2696: }
! 2697: }
! 2698:
! 2699:
! 2700: void dp_rest(DP p,DP *rp)
! 2701: {
! 2702: MP m;
! 2703:
! 2704: m = BDY(p);
! 2705: if ( !NEXT(m) )
! 2706: *rp = 0;
! 2707: else {
! 2708: MKDP(p->nv,NEXT(m),*rp);
! 2709: if ( *rp )
! 2710: (*rp)->sugar = p->sugar;
! 2711: }
! 2712: }
! 2713:
! 2714: void dpm_rest(DPM p,DPM *rp)
! 2715: {
! 2716: DMM m;
! 2717:
! 2718: m = BDY(p);
! 2719: if ( !NEXT(m) )
! 2720: *rp = 0;
! 2721: else {
! 2722: MKDPM(p->nv,NEXT(m),*rp);
! 2723: if ( *rp )
! 2724: (*rp)->sugar = p->sugar;
! 2725: }
! 2726: }
! 2727:
! 2728: DL lcm_of_DL(int nv,DL dl1,DL dl2,DL dl)
! 2729: {
! 2730: register int i, *d1, *d2, *d, td;
! 2731:
! 2732: if ( !dl ) NEWDL(dl,nv);
! 2733: d = dl->d, d1 = dl1->d, d2 = dl2->d;
! 2734: for ( td = 0, i = 0; i < nv; d1++, d2++, d++, i++ ) {
! 2735: *d = *d1 > *d2 ? *d1 : *d2;
! 2736: td += MUL_WEIGHT(*d,i);
! 2737: }
! 2738: dl->td = td;
! 2739: return dl;
! 2740: }
! 2741:
! 2742: int dl_equal(int nv,DL dl1,DL dl2)
! 2743: {
! 2744: register int *d1, *d2, n;
! 2745:
! 2746: if ( dl1->td != dl2->td ) return 0;
! 2747: for ( d1 = dl1->d, d2 = dl2->d, n = nv; --n >= 0; d1++, d2++ )
! 2748: if ( *d1 != *d2 ) return 0;
! 2749: return 1;
! 2750: }
! 2751:
! 2752: int dp_nt(DP p)
! 2753: {
! 2754: int i;
! 2755: MP m;
! 2756:
! 2757: if ( !p )
! 2758: return 0;
! 2759: else {
! 2760: for ( i = 0, m = BDY(p); m; m = NEXT(m), i++ );
! 2761: return i;
! 2762: }
! 2763: }
! 2764:
! 2765: int dp_homogeneous(DP p)
! 2766: {
! 2767: MP m;
! 2768: int d;
! 2769:
! 2770: if ( !p )
! 2771: return 1;
! 2772: else {
! 2773: m = BDY(p);
! 2774: d = m->dl->td;
! 2775: m = NEXT(m);
! 2776: for ( ; m; m = NEXT(m) ) {
! 2777: if ( m->dl->td != d )
! 2778: return 0;
! 2779: }
! 2780: return 1;
! 2781: }
! 2782: }
! 2783:
! 2784: void _print_mp(int nv,MP m)
! 2785: {
! 2786: int i;
! 2787:
! 2788: if ( !m )
! 2789: return;
! 2790: for ( ; m; m = NEXT(m) ) {
! 2791: fprintf(stderr,"%d<",ITOS(C(m)));
! 2792: for ( i = 0; i < nv; i++ ) {
! 2793: fprintf(stderr,"%d",m->dl->d[i]);
! 2794: if ( i != nv-1 )
! 2795: fprintf(stderr," ");
! 2796: }
! 2797: fprintf(stderr,">",C(m));
! 2798: }
! 2799: fprintf(stderr,"\n");
! 2800: }
! 2801:
! 2802: static int cmp_mp_nvar;
! 2803:
! 2804: int comp_mp(MP *a,MP *b)
! 2805: {
! 2806: return -(*cmpdl)(cmp_mp_nvar,(*a)->dl,(*b)->dl);
! 2807: }
! 2808:
! 2809: void dp_sort(DP p,DP *rp)
! 2810: {
! 2811: MP t,mp,mp0;
! 2812: int i,n;
! 2813: DP r;
! 2814: MP *w;
! 2815:
! 2816: if ( !p ) {
! 2817: *rp = 0;
! 2818: return;
! 2819: }
! 2820: for ( t = BDY(p), n = 0; t; t = NEXT(t), n++ );
! 2821: w = (MP *)ALLOCA(n*sizeof(MP));
! 2822: for ( t = BDY(p), i = 0; i < n; t = NEXT(t), i++ )
! 2823: w[i] = t;
! 2824: cmp_mp_nvar = NV(p);
! 2825: qsort(w,n,sizeof(MP),(int (*)(const void *,const void *))comp_mp);
! 2826: mp0 = 0;
! 2827: for ( i = n-1; i >= 0; i-- ) {
! 2828: NEWMP(mp); mp->dl = w[i]->dl; C(mp) = C(w[i]);
! 2829: NEXT(mp) = mp0; mp0 = mp;
! 2830: }
! 2831: MKDP(p->nv,mp0,r);
! 2832: r->sugar = p->sugar;
! 2833: *rp = r;
! 2834: }
! 2835:
! 2836: DP extract_initial_term_from_dp(DP p,int *weight,int n);
! 2837: LIST extract_initial_term(LIST f,int *weight,int n);
! 2838:
! 2839: DP extract_initial_term_from_dp(DP p,int *weight,int n)
! 2840: {
! 2841: int w,t,i,top;
! 2842: MP m,r0,r;
! 2843: DP dp;
! 2844:
! 2845: if ( !p ) return 0;
! 2846: top = 1;
! 2847: for ( m = BDY(p); m; m = NEXT(m) ) {
! 2848: for ( i = 0, t = 0; i < n; i++ )
! 2849: t += weight[i]*m->dl->d[i];
! 2850: if ( top || t > w ) {
! 2851: r0 = 0;
! 2852: w = t;
! 2853: top = 0;
! 2854: }
! 2855: if ( t == w ) {
! 2856: NEXTMP(r0,r);
! 2857: r->dl = m->dl;
! 2858: r->c = m->c;
! 2859: }
! 2860: }
! 2861: NEXT(r) = 0;
! 2862: MKDP(p->nv,r0,dp);
! 2863: return dp;
! 2864: }
! 2865:
! 2866: LIST extract_initial_term(LIST f,int *weight,int n)
! 2867: {
! 2868: NODE nd,r0,r;
! 2869: Obj p;
! 2870: LIST l;
! 2871:
! 2872: nd = BDY(f);
! 2873: for ( r0 = 0; nd; nd = NEXT(nd) ) {
! 2874: NEXTNODE(r0,r);
! 2875: p = (Obj)BDY(nd);
! 2876: BDY(r) = (pointer)extract_initial_term_from_dp((DP)p,weight,n);
! 2877: }
! 2878: if ( r0 ) NEXT(r) = 0;
! 2879: MKLIST(l,r0);
! 2880: return l;
! 2881: }
! 2882:
! 2883: LIST dp_initial_term(LIST f,struct order_spec *ord)
! 2884: {
! 2885: int n,l,i;
! 2886: struct weight_or_block *worb;
! 2887: int *weight;
! 2888:
! 2889: switch ( ord->id ) {
! 2890: case 2: /* matrix order */
! 2891: /* extract the first row */
! 2892: n = ord->nv;
! 2893: weight = ord->ord.matrix.matrix[0];
! 2894: return extract_initial_term(f,weight,n);
! 2895: case 3: /* composite order */
! 2896: /* the first w_or_b */
! 2897: worb = ord->ord.composite.w_or_b;
! 2898: switch ( worb->type ) {
! 2899: case IS_DENSE_WEIGHT:
! 2900: n = worb->length;
! 2901: weight = worb->body.dense_weight;
! 2902: return extract_initial_term(f,weight,n);
! 2903: case IS_SPARSE_WEIGHT:
! 2904: n = ord->nv;
! 2905: weight = (int *)ALLOCA(n*sizeof(int));
! 2906: for ( i = 0; i < n; i++ ) weight[i] = 0;
! 2907: l = worb->length;
! 2908: for ( i = 0; i < l; i++ )
! 2909: weight[worb->body.sparse_weight[i].pos]
! 2910: = worb->body.sparse_weight[i].value;
! 2911: return extract_initial_term(f,weight,n);
! 2912: default:
! 2913: error("dp_initial_term : unsupported order");
! 2914: }
! 2915: default:
! 2916: error("dp_initial_term : unsupported order");
! 2917: }
! 2918: }
! 2919:
! 2920: int highest_order_dp(DP p,int *weight,int n);
! 2921: LIST highest_order(LIST f,int *weight,int n);
! 2922:
! 2923: int highest_order_dp(DP p,int *weight,int n)
! 2924: {
! 2925: int w,t,i,top;
! 2926: MP m;
! 2927:
! 2928: if ( !p ) return -1;
! 2929: top = 1;
! 2930: for ( m = BDY(p); m; m = NEXT(m) ) {
! 2931: for ( i = 0, t = 0; i < n; i++ )
! 2932: t += weight[i]*m->dl->d[i];
! 2933: if ( top || t > w ) {
! 2934: w = t;
! 2935: top = 0;
! 2936: }
! 2937: }
! 2938: return w;
! 2939: }
! 2940:
! 2941: LIST highest_order(LIST f,int *weight,int n)
! 2942: {
! 2943: int h;
! 2944: NODE nd,r0,r;
! 2945: Obj p;
! 2946: LIST l;
! 2947: Z q;
! 2948:
! 2949: nd = BDY(f);
! 2950: for ( r0 = 0; nd; nd = NEXT(nd) ) {
! 2951: NEXTNODE(r0,r);
! 2952: p = (Obj)BDY(nd);
! 2953: h = highest_order_dp((DP)p,weight,n);
! 2954: STOQ(h,q);
! 2955: BDY(r) = (pointer)q;
! 2956: }
! 2957: if ( r0 ) NEXT(r) = 0;
! 2958: MKLIST(l,r0);
! 2959: return l;
! 2960: }
! 2961:
! 2962: LIST dp_order(LIST f,struct order_spec *ord)
! 2963: {
! 2964: int n,l,i;
! 2965: struct weight_or_block *worb;
! 2966: int *weight;
! 2967:
! 2968: switch ( ord->id ) {
! 2969: case 2: /* matrix order */
! 2970: /* extract the first row */
! 2971: n = ord->nv;
! 2972: weight = ord->ord.matrix.matrix[0];
! 2973: return highest_order(f,weight,n);
! 2974: case 3: /* composite order */
! 2975: /* the first w_or_b */
! 2976: worb = ord->ord.composite.w_or_b;
! 2977: switch ( worb->type ) {
! 2978: case IS_DENSE_WEIGHT:
! 2979: n = worb->length;
! 2980: weight = worb->body.dense_weight;
! 2981: return highest_order(f,weight,n);
! 2982: case IS_SPARSE_WEIGHT:
! 2983: n = ord->nv;
! 2984: weight = (int *)ALLOCA(n*sizeof(int));
! 2985: for ( i = 0; i < n; i++ ) weight[i] = 0;
! 2986: l = worb->length;
! 2987: for ( i = 0; i < l; i++ )
! 2988: weight[worb->body.sparse_weight[i].pos]
! 2989: = worb->body.sparse_weight[i].value;
! 2990: return highest_order(f,weight,n);
! 2991: default:
! 2992: error("dp_initial_term : unsupported order");
! 2993: }
! 2994: default:
! 2995: error("dp_initial_term : unsupported order");
! 2996: }
! 2997: }
! 2998:
! 2999: int dpv_ht(DPV p,DP *h)
! 3000: {
! 3001: int len,max,maxi,i,t;
! 3002: DP *e;
! 3003: MP m,mr;
! 3004:
! 3005: len = p->len;
! 3006: e = p->body;
! 3007: max = -1;
! 3008: maxi = -1;
! 3009: for ( i = 0; i < len; i++ )
! 3010: if ( e[i] && (t = BDY(e[i])->dl->td) > max ) {
! 3011: max = t;
! 3012: maxi = i;
! 3013: }
! 3014: if ( max < 0 ) {
! 3015: *h = 0;
! 3016: return -1;
! 3017: } else {
! 3018: m = BDY(e[maxi]);
! 3019: NEWMP(mr); mr->dl = m->dl; mr->c = (Obj)ONE; NEXT(mr) = 0;
! 3020: MKDP(e[maxi]->nv,mr,*h); (*h)->sugar = mr->dl->td; /* XXX */
! 3021: return maxi;
! 3022: }
! 3023: }
! 3024:
! 3025: /* return 1 if 0 <_w1 v && v <_w2 0 */
! 3026:
! 3027: int in_c12(int n,int *v,int row1,int **w1,int row2, int **w2)
! 3028: {
! 3029: int t1,t2;
! 3030:
! 3031: t1 = compare_zero(n,v,row1,w1);
! 3032: t2 = compare_zero(n,v,row2,w2);
! 3033: if ( t1 > 0 && t2 < 0 ) return 1;
! 3034: else return 0;
! 3035: }
! 3036:
! 3037: /* 0 < u => 1, 0 > u => -1 */
! 3038:
! 3039: int compare_zero(int n,int *u,int row,int **w)
! 3040: {
! 3041: int i,j,t;
! 3042: int *wi;
! 3043:
! 3044: for ( i = 0; i < row; i++ ) {
! 3045: wi = w[i];
! 3046: for ( j = 0, t = 0; j < n; j++ ) t += u[j]*wi[j];
! 3047: if ( t > 0 ) return 1;
! 3048: else if ( t < 0 ) return -1;
! 3049: }
! 3050: return 0;
! 3051: }
! 3052:
! 3053: /* functions for generic groebner walk */
! 3054: /* u=0 means u=-infty */
! 3055:
! 3056: int compare_facet_preorder(int n,int *u,int *v,
! 3057: int row1,int **w1,int row2,int **w2)
! 3058: {
! 3059: int i,j,s,t,tu,tv;
! 3060: int *w2i,*uv;
! 3061:
! 3062: if ( !u ) return 1;
! 3063: uv = W_ALLOC(n);
! 3064: for ( i = 0; i < row2; i++ ) {
! 3065: w2i = w2[i];
! 3066: for ( j = 0, tu = tv = 0; j < n; j++ )
! 3067: if ( s = w2i[j] ) {
! 3068: tu += s*u[j]; tv += s*v[j];
! 3069: }
! 3070: for ( j = 0; j < n; j++ ) uv[j] = u[j]*tv-v[j]*tu;
! 3071: t = compare_zero(n,uv,row1,w1);
! 3072: if ( t > 0 ) return 1;
! 3073: else if ( t < 0 ) return 0;
! 3074: }
! 3075: return 1;
! 3076: }
! 3077:
! 3078: Q inner_product_with_small_vector(VECT w,int *v)
! 3079: {
! 3080: int n,i;
! 3081: Z q;
! 3082: Q s,t,u;
! 3083:
! 3084: n = w->len;
! 3085: s = 0;
! 3086: for ( i = 0; i < n; i++ ) {
! 3087: STOQ(v[i],q); mulq((Q)w->body[i],(Q)q,&t); addq(t,s,&u); s = u;
! 3088: }
! 3089: return s;
! 3090: }
! 3091:
! 3092: Q compute_last_t(NODE g,NODE gh,Q t,VECT w1,VECT w2,NODE *homo,VECT *wp)
! 3093: {
! 3094: int n,i;
! 3095: int *wt;
! 3096: Q last,d1,d2,dn,nm,s,t1;
! 3097: VECT wd,wt1,wt2,w;
! 3098: NODE tg,tgh;
! 3099: MP f;
! 3100: int *h;
! 3101: NODE r0,r;
! 3102: MP m0,m;
! 3103: DP d;
! 3104:
! 3105: n = w1->len;
! 3106: wt = W_ALLOC(n);
! 3107: last = (Q)ONE;
! 3108: /* t1 = 1-t */
! 3109: for ( tg = g, tgh = gh; tg; tg = NEXT(tg), tgh = NEXT(tgh ) ) {
! 3110: f = BDY((DP)BDY(tg));
! 3111: h = BDY((DP)BDY(tgh))->dl->d;
! 3112: for ( ; f; f = NEXT(f) ) {
! 3113: for ( i = 0; i < n; i++ ) wt[i] = h[i]-f->dl->d[i];
! 3114: for ( i = 0; i < n && !wt[i]; i++ );
! 3115: if ( i == n ) continue;
! 3116: d1 = inner_product_with_small_vector(w1,wt);
! 3117: d2 = inner_product_with_small_vector(w2,wt);
! 3118: nm = d1; subq(d1,d2,&dn);
! 3119: /* if d1=d2 then nothing happens */
! 3120: if ( !dn ) continue;
! 3121: /* s satisfies ds = 0*/
! 3122: divq(nm,dn,&s);
! 3123:
! 3124: if ( cmpq(s,t) > 0 && cmpq(s,last) < 0 )
! 3125: last = s;
! 3126: else if ( !cmpq(s,t) ) {
! 3127: if ( cmpq(d2,0) < 0 ) {
! 3128: last = t;
! 3129: break;
! 3130: }
! 3131: }
! 3132: }
! 3133: }
! 3134: nmq(last,(Z *)&nm);
! 3135: dnq(last,(Z *)&dn);
! 3136: /* (1-n/d)*w1+n/d*w2 -> w=(d-n)*w1+n*w2 */
! 3137: subq(dn,nm,&t1); mulvect(CO,(Obj)w1,(Obj)t1,(Obj *)&wt1);
! 3138: mulvect(CO,(Obj)w2,(Obj)nm,(Obj *)&wt2); addvect(CO,wt1,wt2,&w);
! 3139:
! 3140: r0 = 0;
! 3141: for ( tg = g, tgh = gh; tg; tg = NEXT(tg), tgh = NEXT(tgh ) ) {
! 3142: f = BDY((DP)BDY(tg));
! 3143: h = BDY((DP)BDY(tgh))->dl->d;
! 3144: for ( m0 = 0; f; f = NEXT(f) ) {
! 3145: for ( i = 0; i < n; i++ ) wt[i] = h[i]-f->dl->d[i];
! 3146: for ( i = 0; i < n && !wt[i]; i++ );
! 3147: if ( !inner_product_with_small_vector(w,wt) ) {
! 3148: NEXTMP(m0,m); m->c = f->c; m->dl = f->dl;
! 3149: }
! 3150: }
! 3151: NEXT(m) = 0;
! 3152: MKDP(((DP)BDY(tg))->nv,m0,d); d->sugar = ((DP)BDY(tg))->sugar;
! 3153: NEXTNODE(r0,r); BDY(r) = (pointer)d;
! 3154: }
! 3155: NEXT(r) = 0;
! 3156: *homo = r0;
! 3157: *wp = w;
! 3158: return last;
! 3159: }
! 3160:
! 3161: /* return 0 if last_w = infty */
! 3162:
! 3163: NODE compute_last_w(NODE g,NODE gh,int n,int **w,
! 3164: int row1,int **w1,int row2,int **w2)
! 3165: {
! 3166: DP d;
! 3167: MP f,m0,m;
! 3168: int *wt,*v,*h;
! 3169: NODE t,s,n0,tn,n1,r0,r;
! 3170: int i;
! 3171:
! 3172: wt = W_ALLOC(n);
! 3173: n0 = 0;
! 3174: for ( t = g, s = gh; t; t = NEXT(t), s = NEXT(s) ) {
! 3175: f = BDY((DP)BDY(t));
! 3176: h = BDY((DP)BDY(s))->dl->d;
! 3177: for ( ; f; f = NEXT(f) ) {
! 3178: for ( i = 0; i < n; i++ ) wt[i] = h[i]-f->dl->d[i];
! 3179: for ( i = 0; i < n && !wt[i]; i++ );
! 3180: if ( i == n ) continue;
! 3181:
! 3182: if ( in_c12(n,wt,row1,w1,row2,w2) &&
! 3183: compare_facet_preorder(n,*w,wt,row1,w1,row2,w2) ) {
! 3184: v = (int *)MALLOC_ATOMIC(n*sizeof(int));
! 3185: for ( i = 0; i < n; i++ ) v[i] = wt[i];
! 3186: MKNODE(n1,v,n0); n0 = n1;
! 3187: }
! 3188: }
! 3189: }
! 3190: if ( !n0 ) return 0;
! 3191: for ( t = n0; t; t = NEXT(t) ) {
! 3192: v = (int *)BDY(t);
! 3193: for ( s = n0; s; s = NEXT(s) )
! 3194: if ( !compare_facet_preorder(n,v,(int *)BDY(s),row1,w1,row2,w2) )
! 3195: break;
! 3196: if ( !s ) {
! 3197: *w = v;
! 3198: break;
! 3199: }
! 3200: }
! 3201: if ( !t )
! 3202: error("compute_last_w : cannot happen");
! 3203: r0 = 0;
! 3204: for ( t = g, s = gh; t; t = NEXT(t), s = NEXT(s) ) {
! 3205: f = BDY((DP)BDY(t));
! 3206: h = BDY((DP)BDY(s))->dl->d;
! 3207: for ( m0 = 0; f; f = NEXT(f) ) {
! 3208: for ( i = 0; i < n; i++ ) wt[i] = h[i]-f->dl->d[i];
! 3209: for ( i = 0; i < n && !wt[i]; i++ );
! 3210: if ( i == n ||
! 3211: (compare_facet_preorder(n,wt,*w,row1,w1,row2,w2)
! 3212: && compare_facet_preorder(n,*w,wt,row1,w1,row2,w2)) ) {
! 3213: NEXTMP(m0,m); m->c = f->c; m->dl = f->dl;
! 3214: }
! 3215: }
! 3216: NEXT(m) = 0;
! 3217: MKDP(((DP)BDY(t))->nv,m0,d); d->sugar = ((DP)BDY(t))->sugar;
! 3218: NEXTNODE(r0,r); BDY(r) = (pointer)d;
! 3219: }
! 3220: NEXT(r) = 0;
! 3221: return r0;
! 3222: }
! 3223:
! 3224: /* compute a sufficient set of d(f)=u-v */
! 3225:
! 3226: NODE compute_essential_df(DP *g,DP *gh,int ng)
! 3227: {
! 3228: int nv,i,j,k,t,lj;
! 3229: NODE r,r1,ri,rt,r0;
! 3230: MP m;
! 3231: MP *mj;
! 3232: DL di,hj,dl,dlt;
! 3233: int *d,*dt;
! 3234: LIST l;
! 3235: Z q;
! 3236:
! 3237: nv = g[0]->nv;
! 3238: r = 0;
! 3239: for ( j = 0; j < ng; j++ ) {
! 3240: for ( m = BDY(g[j]), lj = 0; m; m = NEXT(m), lj++ );
! 3241: mj = (MP *)ALLOCA(lj*sizeof(MP));
! 3242: for ( m = BDY(g[j]), k = 0; m; m = NEXT(m), k++ )
! 3243: mj[k] = m;
! 3244: for ( i = 0; i < lj; i++ ) {
! 3245: for ( di = mj[i]->dl, k = i+1; k < lj; k++ )
! 3246: if ( _dl_redble(di,mj[k]->dl,nv) ) break;
! 3247: if ( k < lj ) mj[i] = 0;
! 3248: }
! 3249: hj = BDY(gh[j])->dl;
! 3250: _NEWDL(dl,nv); d = dl->d;
! 3251: r0 = r;
! 3252: for ( i = 0; i < lj; i++ ) {
! 3253: if ( mj[i] && !dl_equal(nv,di=mj[i]->dl,hj) ) {
! 3254: for ( k = 0, t = 0; k < nv; k++ ) {
! 3255: d[k] = hj->d[k]-di->d[k];
! 3256: t += d[k];
! 3257: }
! 3258: dl->td = t;
! 3259: #if 1
! 3260: for ( rt = r0; rt; rt = NEXT(rt) ) {
! 3261: dlt = (DL)BDY(rt);
! 3262: if ( dlt->td != dl->td ) continue;
! 3263: for ( dt = dlt->d, k = 0; k < nv; k++ )
! 3264: if ( d[k] != dt[k] ) break;
! 3265: if ( k == nv ) break;
! 3266: }
! 3267: #else
! 3268: rt = 0;
! 3269: #endif
! 3270: if ( !rt ) {
! 3271: MKNODE(r1,dl,r); r = r1;
! 3272: _NEWDL(dl,nv); d = dl->d;
! 3273: }
! 3274: }
! 3275: }
! 3276: }
! 3277: for ( rt = r; rt; rt = NEXT(rt) ) {
! 3278: dl = (DL)BDY(rt); d = dl->d;
! 3279: ri = 0;
! 3280: for ( k = nv-1; k >= 0; k-- ) {
! 3281: STOQ(d[k],q);
! 3282: MKNODE(r1,q,ri); ri = r1;
! 3283: }
! 3284: MKNODE(r1,0,ri); MKLIST(l,r1);
! 3285: BDY(rt) = (pointer)l;
! 3286: }
! 3287: return r;
! 3288: }
! 3289:
! 3290: int comp_bits_divisible(int *a,int *b,int n)
! 3291: {
! 3292: int bpi,i,wi,bi;
! 3293:
! 3294: bpi = (sizeof(int)/sizeof(char))*8;
! 3295: for ( i = 0; i < n; i++ ) {
! 3296: wi = i/bpi; bi = i%bpi;
! 3297: if ( !(a[wi]&(1<<bi)) && (b[wi]&(1<<bi)) ) return 0;
! 3298: }
! 3299: return 1;
! 3300: }
! 3301:
! 3302: int comp_bits_lex(int *a,int *b,int n)
! 3303: {
! 3304: int bpi,i,wi,ba,bb,bi;
! 3305:
! 3306: bpi = (sizeof(int)/sizeof(char))*8;
! 3307: for ( i = 0; i < n; i++ ) {
! 3308: wi = i/bpi; bi = i%bpi;
! 3309: ba = (a[wi]&(1<<bi))?1:0;
! 3310: bb = (b[wi]&(1<<bi))?1:0;
! 3311: if ( ba > bb ) return 1;
! 3312: else if ( ba < bb ) return -1;
! 3313: }
! 3314: return 0;
! 3315: }
! 3316:
! 3317: NODE mono_raddec(NODE ideal)
! 3318: {
! 3319: DP p;
! 3320: int nv,w,i,bpi,di,c,len;
! 3321: int *d,*s,*u,*new;
! 3322: NODE t,t1,v,r,rem,prev;
! 3323:
! 3324: if( !ideal ) return 0;
! 3325: p = (DP)BDY(ideal);
! 3326: nv = NV(p);
! 3327: bpi = (sizeof(int)/sizeof(char))*8;
! 3328: w = (nv+(bpi-1))/bpi;
! 3329: d = p->body->dl->d;
! 3330: if ( !NEXT(ideal) ) {
! 3331: for ( t = 0, i = nv-1; i >= 0; i-- ) {
! 3332: if ( d[i] ) {
! 3333: s = (int *)CALLOC(w,sizeof(int));
! 3334: s[i/bpi] |= 1<<(i%bpi);
! 3335: MKNODE(t1,s,t);
! 3336: t = t1;
! 3337: }
! 3338: }
! 3339: return t;
! 3340: }
! 3341: rem = mono_raddec(NEXT(ideal));
! 3342: r = 0;
! 3343: len = w*sizeof(int);
! 3344: u = (int *)CALLOC(w,sizeof(int));
! 3345: for ( i = nv-1; i >= 0; i-- ) {
! 3346: if ( d[i] ) {
! 3347: for ( t = rem; t; t = NEXT(t) ) {
! 3348: bcopy((char *)BDY(t),(char *)u,len);
! 3349: u[i/bpi] |= 1<<(i%bpi);
! 3350: for ( v = r; v; v = NEXT(v) ) {
! 3351: if ( comp_bits_divisible(u,(int *)BDY(v),nv) ) break;
! 3352: }
! 3353: if ( v ) continue;
! 3354: for ( v = r, prev = 0; v; v = NEXT(v) ) {
! 3355: if ( comp_bits_divisible((int *)BDY(v),u,nv) ) {
! 3356: if ( prev ) NEXT(prev) = NEXT(v);
! 3357: else r = NEXT(r);
! 3358: } else prev =v;
! 3359: }
! 3360: for ( v = r, prev = 0; v; prev = v, v = NEXT(v) ) {
! 3361: if ( comp_bits_lex(u,(int *)BDY(v),nv) < 0 ) break;
! 3362: }
! 3363: new = (int *)CALLOC(w,sizeof(int));
! 3364: bcopy((char *)u,(char *)new,len);
! 3365: MKNODE(t1,new,v);
! 3366: if ( prev ) NEXT(prev) = t1;
! 3367: else r = t1;
! 3368: }
! 3369: }
! 3370: }
! 3371: return r;
! 3372: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>