Annotation of OpenXM_contrib2/asir2000/engine/nd.c, Revision 1.16
1.16 ! noro 1: /* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.15 2003/07/31 01:02:39 noro Exp $ */
1.2 noro 2:
1.1 noro 3: #include "ca.h"
4: #include "inline.h"
5:
1.6 noro 6: #define USE_NDV 1
1.4 noro 7:
1.1 noro 8: #if defined(__GNUC__)
9: #define INLINE inline
10: #elif defined(VISUAL)
11: #define INLINE __inline
12: #else
13: #define INLINE
14: #endif
15:
16: #define REDTAB_LEN 32003
17:
18: typedef struct oPGeoBucket {
19: int m;
20: struct oND *body[32];
21: } *PGeoBucket;
22:
23: typedef struct oND {
24: struct oNM *body;
25: int nv;
26: int sugar;
27: } *ND;
28:
1.3 noro 29: typedef struct oNDV {
30: struct oNMV *body;
31: int nv;
32: int sugar;
33: int len;
34: } *NDV;
35:
1.1 noro 36: typedef struct oNM {
37: struct oNM *next;
1.14 noro 38: union {
39: int m;
40: Q z;
41: } c;
1.1 noro 42: int td;
43: unsigned int dl[1];
44: } *NM;
45:
1.3 noro 46: typedef struct oNMV {
1.14 noro 47: union {
48: int m;
49: Q z;
50: } c;
1.3 noro 51: int td;
52: unsigned int dl[1];
53: } *NMV;
54:
1.13 noro 55: typedef struct oRHist {
56: struct oRHist *next;
57: int index;
58: int td;
59: unsigned int dl[1];
60: } *RHist;
61:
1.1 noro 62: typedef struct oND_pairs {
63: struct oND_pairs *next;
64: int i1,i2;
65: int td,sugar;
66: unsigned int lcm[1];
67: } *ND_pairs;
68:
69: static unsigned int **nd_bound;
70: int nd_mod,nd_nvar;
71: int is_rlex;
72: int nd_epw,nd_bpe,nd_wpd;
73: unsigned int nd_mask[32];
74: unsigned int nd_mask0,nd_mask1;
75: NM _nm_free_list;
76: ND _nd_free_list;
77: ND_pairs _ndp_free_list;
1.13 noro 78: RHist *nd_red;
1.1 noro 79: int nd_red_len;
80:
81: extern int Top,Reverse;
82: int nd_psn,nd_pslen;
83: int nd_found,nd_create,nd_notfirst;
1.6 noro 84: int *nd_psl;
1.13 noro 85: RHist *nd_psh;
86: int nm_adv;
87: #define NM_ADV(m) (m = (NM)(((char *)m)+nm_adv))
1.1 noro 88:
89: void GC_gcollect();
90: NODE append_one(NODE,int);
91:
92: #define HTD(d) ((d)->body->td)
93: #define HDL(d) ((d)->body->dl)
1.14 noro 94: #define HCM(d) ((d)->body->c.m)
1.16 ! noro 95: #define HCQ(d) ((d)->body->c.z)
1.14 noro 96: #define CM(a) ((a)->c.m)
1.16 ! noro 97: #define CQ(a) ((a)->c.z)
1.14 noro 98: #define DL(a) ((a)->dl)
99: #define TD(a) ((a)->td)
100: #define SG(a) ((a)->sugar)
101: #define LEN(a) ((a)->len)
1.1 noro 102:
1.15 noro 103: #define NEWRHist(r) \
104: ((r)=(RHist)MALLOC(sizeof(struct oRHist)+(nd_wpd-1)*sizeof(unsigned int)))
1.1 noro 105: #define NEWND_pairs(m) if(!_ndp_free_list)_NDP_alloc(); (m)=_ndp_free_list; _ndp_free_list = NEXT(_ndp_free_list)
106: #define NEWNM(m) if(!_nm_free_list)_NM_alloc(); (m)=_nm_free_list; _nm_free_list = NEXT(_nm_free_list)
107: #define MKND(n,m,d) if(!_nd_free_list)_ND_alloc(); (d)=_nd_free_list; _nd_free_list = (ND)BDY(_nd_free_list); (d)->nv=(n); BDY(d)=(m)
108:
1.13 noro 109: #define NEXTRHist(r,c) \
110: if(!(r)){NEWRHist(r);(c)=(r);}else{NEWRHist(NEXT(c));(c)=NEXT(c);}
1.1 noro 111: #define NEXTNM(r,c) \
112: if(!(r)){NEWNM(r);(c)=(r);}else{NEWNM(NEXT(c));(c)=NEXT(c);}
113: #define NEXTNM2(r,c,s) \
114: if(!(r)){(c)=(r)=(s);}else{NEXT(c)=(s);(c)=(s);}
115: #define FREENM(m) NEXT(m)=_nm_free_list; _nm_free_list=(m)
116: #define FREENDP(m) NEXT(m)=_ndp_free_list; _ndp_free_list=(m)
117: #define FREEND(m) BDY(m)=(NM)_nd_free_list; _nd_free_list=(m)
118:
119: #define NEXTND_pairs(r,c) \
120: if(!(r)){NEWND_pairs(r);(c)=(r);}else{NEWND_pairs(NEXT(c));(c)=NEXT(c);}
121:
1.16 ! noro 122: void nd_removecont(ND p);
! 123: void ndv_removecont(NDV p);
! 124: void ndv_mul_c_q(NDV p,Q mul);
! 125: void nd_mul_c_q(ND p,Q mul);
! 126:
1.1 noro 127: ND_pairs crit_B( ND_pairs d, int s );
128: void nd_gr(LIST f,LIST v,int m,struct order_spec *ord,LIST *rp);
1.16 ! noro 129: NODE nd_setup(int mod,NODE f);
! 130: int nd_newps(int mod,ND a);
1.1 noro 131: ND_pairs nd_minp( ND_pairs d, ND_pairs *prest );
132: NODE update_base(NODE nd,int ndp);
133: static ND_pairs equivalent_pairs( ND_pairs d1, ND_pairs *prest );
134: int crit_2( int dp1, int dp2 );
135: ND_pairs crit_F( ND_pairs d1 );
136: ND_pairs crit_M( ND_pairs d1 );
137: ND_pairs nd_newpairs( NODE g, int t );
138: ND_pairs update_pairs( ND_pairs d, NODE /* of index */ g, int t);
1.16 ! noro 139: NODE nd_gb(int m,NODE f);
1.1 noro 140: void nd_free_private_storage();
141: void _NM_alloc();
142: void _ND_alloc();
143: int ndl_td(unsigned int *d);
144: ND nd_add(ND p1,ND p2);
145: ND nd_mul_nm(ND p,NM m0);
1.6 noro 146: ND nd_mul_ind_nm(int index,NM m0);
1.1 noro 147: ND nd_mul_term(ND p,int td,unsigned int *d);
1.16 ! noro 148: int nd_sp(int mod,ND_pairs p,ND *nf);
1.6 noro 149: int nd_find_reducer(ND g);
1.16 ! noro 150: int nd_nf(int mod,ND g,int full,ND *nf);
1.1 noro 151: ND nd_reduce(ND p1,ND p2);
152: ND nd_reduce_special(ND p1,ND p2);
153: void nd_free(ND p);
154: void ndl_print(unsigned int *dl);
155: void nd_print(ND p);
1.16 ! noro 156: void nd_print_q(ND p);
! 157: void ndv_print(NDV p);
! 158: void ndv_print_q(NDV p);
1.1 noro 159: void ndp_print(ND_pairs d);
160: int nd_length(ND p);
161: void nd_monic(ND p);
162: void nd_mul_c(ND p,int mul);
163: void nd_free_redlist();
164: void nd_append_red(unsigned int *d,int td,int i);
165: unsigned int *nd_compute_bound(ND p);
1.5 noro 166: unsigned int *dp_compute_bound(DP p);
1.1 noro 167: ND_pairs nd_reconstruct(ND_pairs);
168: void nd_setup_parameters();
1.11 noro 169: void nd_realloc(ND p,int obpe);
1.6 noro 170: ND nd_copy(ND p);
1.1 noro 171: void ndl_dup(int obpe,unsigned int *d,unsigned int *r);
1.4 noro 172:
173: #if USE_NDV
1.11 noro 174: static NDV *nd_ps;
175:
1.4 noro 176: #define NMV_ADV(m) (m = (NMV)(((char *)m)+nmv_adv))
177: #define NEWNDV(d) ((d)=(NDV)MALLOC(sizeof(struct oNDV)))
1.14 noro 178: #define MKNDV(n,m,l,d) NEWNDV(d); NV(d)=(n); BDY(d)=(m); LEN(d) = l;
1.4 noro 179:
180: int nmv_adv;
181: int nmv_len;
182: NDV ndv_red;
183:
1.11 noro 184: void ndv_mul_c(NDV p,int mul);
1.4 noro 185: ND ndv_add(ND p1,NDV p2);
1.16 ! noro 186: ND ndv_add_q(ND p1,NDV p2);
! 187: NDV ndtondv(int mod,ND p);
! 188: void ndv_mul_nm(int mod,NDV pv,NM m,NDV r);
! 189: ND ndv_mul_nm_create(int mod,NDV p,NM m0);
1.11 noro 190: void ndv_realloc(NDV p,int obpe,int oadv);
1.16 ! noro 191: NDV dptondv(int,DP);
! 192: DP ndvtodp(int,NDV);
1.11 noro 193: #else
194: static ND *nd_ps;
195: ND dptond(DP);
196: DP ndtodp(ND);
1.4 noro 197: #endif
1.1 noro 198:
199: void nd_free_private_storage()
200: {
201: _nd_free_list = 0;
202: _nm_free_list = 0;
1.5 noro 203: _ndp_free_list = 0;
1.13 noro 204: bzero(nd_red,sizeof(REDTAB_LEN*sizeof(RHist)));
1.1 noro 205: GC_gcollect();
206: }
207:
208: void _NM_alloc()
209: {
210: NM p;
211: int i;
212:
1.11 noro 213: for ( i = 0; i < 1024; i++ ) {
1.1 noro 214: p = (NM)GC_malloc(sizeof(struct oNM)+(nd_wpd-1)*sizeof(unsigned int));
215: p->next = _nm_free_list; _nm_free_list = p;
216: }
217: }
218:
219: void _ND_alloc()
220: {
221: ND p;
222: int i;
223:
224: for ( i = 0; i < 1024; i++ ) {
225: p = (ND)GC_malloc(sizeof(struct oND));
226: p->body = (NM)_nd_free_list; _nd_free_list = p;
227: }
228: }
229:
230: void _NDP_alloc()
231: {
232: ND_pairs p;
233: int i;
234:
1.11 noro 235: for ( i = 0; i < 1024; i++ ) {
1.1 noro 236: p = (ND_pairs)GC_malloc(sizeof(struct oND_pairs)
237: +(nd_wpd-1)*sizeof(unsigned int));
238: p->next = _ndp_free_list; _ndp_free_list = p;
239: }
240: }
241:
242: INLINE nd_length(ND p)
243: {
244: NM m;
245: int i;
246:
247: if ( !p )
248: return 0;
249: else {
250: for ( i = 0, m = BDY(p); m; m = NEXT(m), i++ );
251: return i;
252: }
253: }
254:
255: INLINE int ndl_reducible(unsigned int *d1,unsigned int *d2)
256: {
257: unsigned int u1,u2;
258: int i,j;
259:
260: switch ( nd_bpe ) {
261: case 4:
262: for ( i = 0; i < nd_wpd; i++ ) {
263: u1 = d1[i]; u2 = d2[i];
264: if ( (u1&0xf0000000) < (u2&0xf0000000) ) return 0;
265: if ( (u1&0xf000000) < (u2&0xf000000) ) return 0;
266: if ( (u1&0xf00000) < (u2&0xf00000) ) return 0;
267: if ( (u1&0xf0000) < (u2&0xf0000) ) return 0;
268: if ( (u1&0xf000) < (u2&0xf000) ) return 0;
269: if ( (u1&0xf00) < (u2&0xf00) ) return 0;
270: if ( (u1&0xf0) < (u2&0xf0) ) return 0;
271: if ( (u1&0xf) < (u2&0xf) ) return 0;
272: }
273: return 1;
274: break;
275: case 6:
276: for ( i = 0; i < nd_wpd; i++ ) {
277: u1 = d1[i]; u2 = d2[i];
278: if ( (u1&0x3f000000) < (u2&0x3f000000) ) return 0;
279: if ( (u1&0xfc0000) < (u2&0xfc0000) ) return 0;
280: if ( (u1&0x3f000) < (u2&0x3f000) ) return 0;
281: if ( (u1&0xfc0) < (u2&0xfc0) ) return 0;
282: if ( (u1&0x3f) < (u2&0x3f) ) return 0;
283: }
284: return 1;
285: break;
286: case 8:
287: for ( i = 0; i < nd_wpd; i++ ) {
288: u1 = d1[i]; u2 = d2[i];
289: if ( (u1&0xff000000) < (u2&0xff000000) ) return 0;
290: if ( (u1&0xff0000) < (u2&0xff0000) ) return 0;
291: if ( (u1&0xff00) < (u2&0xff00) ) return 0;
292: if ( (u1&0xff) < (u2&0xff) ) return 0;
293: }
294: return 1;
295: break;
296: case 16:
297: for ( i = 0; i < nd_wpd; i++ ) {
298: u1 = d1[i]; u2 = d2[i];
299: if ( (u1&0xffff0000) < (u2&0xffff0000) ) return 0;
300: if ( (u1&0xffff) < (u2&0xffff) ) return 0;
301: }
302: return 1;
303: break;
304: case 32:
305: for ( i = 0; i < nd_wpd; i++ )
306: if ( d1[i] < d2[i] ) return 0;
307: return 1;
308: break;
309: default:
310: for ( i = 0; i < nd_wpd; i++ ) {
311: u1 = d1[i]; u2 = d2[i];
312: for ( j = 0; j < nd_epw; j++ )
313: if ( (u1&nd_mask[j]) < (u2&nd_mask[j]) ) return 0;
314: }
315: return 1;
316: }
317: }
318:
319: void ndl_lcm(unsigned int *d1,unsigned *d2,unsigned int *d)
320: {
321: unsigned int t1,t2,u,u1,u2;
322: int i,j;
323:
324: switch ( nd_bpe ) {
325: case 4:
326: for ( i = 0; i < nd_wpd; i++ ) {
327: u1 = d1[i]; u2 = d2[i];
328: t1 = (u1&0xf0000000); t2 = (u2&0xf0000000); u = t1>t2?t1:t2;
329: t1 = (u1&0xf000000); t2 = (u2&0xf000000); u |= t1>t2?t1:t2;
330: t1 = (u1&0xf00000); t2 = (u2&0xf00000); u |= t1>t2?t1:t2;
331: t1 = (u1&0xf0000); t2 = (u2&0xf0000); u |= t1>t2?t1:t2;
332: t1 = (u1&0xf000); t2 = (u2&0xf000); u |= t1>t2?t1:t2;
333: t1 = (u1&0xf00); t2 = (u2&0xf00); u |= t1>t2?t1:t2;
334: t1 = (u1&0xf0); t2 = (u2&0xf0); u |= t1>t2?t1:t2;
335: t1 = (u1&0xf); t2 = (u2&0xf); u |= t1>t2?t1:t2;
336: d[i] = u;
337: }
338: break;
339: case 6:
340: for ( i = 0; i < nd_wpd; i++ ) {
341: u1 = d1[i]; u2 = d2[i];
342: t1 = (u1&0x3f000000); t2 = (u2&0x3f000000); u = t1>t2?t1:t2;
343: t1 = (u1&0xfc0000); t2 = (u2&0xfc0000); u |= t1>t2?t1:t2;
344: t1 = (u1&0x3f000); t2 = (u2&0x3f000); u |= t1>t2?t1:t2;
345: t1 = (u1&0xfc0); t2 = (u2&0xfc0); u |= t1>t2?t1:t2;
346: t1 = (u1&0x3f); t2 = (u2&0x3f); u |= t1>t2?t1:t2;
347: d[i] = u;
348: }
349: break;
350: case 8:
351: for ( i = 0; i < nd_wpd; i++ ) {
352: u1 = d1[i]; u2 = d2[i];
353: t1 = (u1&0xff000000); t2 = (u2&0xff000000); u = t1>t2?t1:t2;
354: t1 = (u1&0xff0000); t2 = (u2&0xff0000); u |= t1>t2?t1:t2;
355: t1 = (u1&0xff00); t2 = (u2&0xff00); u |= t1>t2?t1:t2;
356: t1 = (u1&0xff); t2 = (u2&0xff); u |= t1>t2?t1:t2;
357: d[i] = u;
358: }
359: break;
360: case 16:
361: for ( i = 0; i < nd_wpd; i++ ) {
362: u1 = d1[i]; u2 = d2[i];
363: t1 = (u1&0xffff0000); t2 = (u2&0xffff0000); u = t1>t2?t1:t2;
364: t1 = (u1&0xffff); t2 = (u2&0xffff); u |= t1>t2?t1:t2;
365: d[i] = u;
366: }
367: break;
368: case 32:
369: for ( i = 0; i < nd_wpd; i++ ) {
370: u1 = d1[i]; u2 = d2[i];
371: d[i] = u1>u2?u1:u2;
372: }
373: break;
374: default:
375: for ( i = 0; i < nd_wpd; i++ ) {
376: u1 = d1[i]; u2 = d2[i];
377: for ( j = 0, u = 0; j < nd_epw; j++ ) {
378: t1 = (u1&nd_mask[j]); t2 = (u2&nd_mask[j]); u |= t1>t2?t1:t2;
379: }
380: d[i] = u;
381: }
382: break;
383: }
384: }
385:
386: int ndl_td(unsigned int *d)
387: {
388: unsigned int t,u;
389: int i,j;
390:
391: for ( t = 0, i = 0; i < nd_wpd; i++ ) {
392: u = d[i];
393: for ( j = 0; j < nd_epw; j++, u>>=nd_bpe )
394: t += (u&nd_mask0);
395: }
396: return t;
397: }
398:
399: INLINE int ndl_compare(unsigned int *d1,unsigned int *d2)
400: {
401: int i;
402:
403: for ( i = 0; i < nd_wpd; i++, d1++, d2++ )
404: if ( *d1 > *d2 )
405: return is_rlex ? -1 : 1;
406: else if ( *d1 < *d2 )
407: return is_rlex ? 1 : -1;
408: return 0;
409: }
410:
411: INLINE int ndl_equal(unsigned int *d1,unsigned int *d2)
412: {
413: int i;
414:
415: for ( i = 0; i < nd_wpd; i++ )
416: if ( d1[i] != d2[i] )
417: return 0;
418: return 1;
419: }
420:
1.6 noro 421: INLINE void ndl_copy(unsigned int *d1,unsigned int *d2)
422: {
423: int i;
424:
425: switch ( nd_wpd ) {
426: case 1:
427: d2[0] = d1[0];
428: break;
429: case 2:
430: d2[0] = d1[0];
431: d2[1] = d1[1];
432: break;
433: default:
434: for ( i = 0; i < nd_wpd; i++ )
435: d2[i] = d1[i];
436: break;
437: }
438: }
439:
1.1 noro 440: INLINE void ndl_add(unsigned int *d1,unsigned int *d2,unsigned int *d)
441: {
442: int i;
443:
1.6 noro 444: switch ( nd_wpd ) {
445: case 1:
446: d[0] = d1[0]+d2[0];
447: break;
448: case 2:
449: d[0] = d1[0]+d2[0];
450: d[1] = d1[1]+d2[1];
451: break;
452: default:
453: for ( i = 0; i < nd_wpd; i++ )
454: d[i] = d1[i]+d2[i];
455: break;
456: }
457: }
458:
459: INLINE void ndl_add2(unsigned int *d1,unsigned int *d2)
460: {
461: int i;
462:
463: switch ( nd_wpd ) {
464: case 1:
465: d2[0] += d1[0];
466: break;
467: case 2:
468: d2[0] += d1[0];
469: d2[1] += d1[1];
470: break;
471: default:
472: for ( i = 0; i < nd_wpd; i++ )
473: d2[i] += d1[i];
474: break;
1.1 noro 475: }
476: }
477:
478: void ndl_sub(unsigned int *d1,unsigned int *d2,unsigned int *d)
479: {
480: int i;
481:
482: for ( i = 0; i < nd_wpd; i++ )
483: d[i] = d1[i]-d2[i];
484: }
485:
486: int ndl_disjoint(unsigned int *d1,unsigned int *d2)
487: {
488: unsigned int t1,t2,u,u1,u2;
489: int i,j;
490:
491: switch ( nd_bpe ) {
492: case 4:
493: for ( i = 0; i < nd_wpd; i++ ) {
494: u1 = d1[i]; u2 = d2[i];
495: t1 = u1&0xf0000000; t2 = u2&0xf0000000; if ( t1&&t2 ) return 0;
496: t1 = u1&0xf000000; t2 = u2&0xf000000; if ( t1&&t2 ) return 0;
497: t1 = u1&0xf00000; t2 = u2&0xf00000; if ( t1&&t2 ) return 0;
498: t1 = u1&0xf0000; t2 = u2&0xf0000; if ( t1&&t2 ) return 0;
499: t1 = u1&0xf000; t2 = u2&0xf000; if ( t1&&t2 ) return 0;
500: t1 = u1&0xf00; t2 = u2&0xf00; if ( t1&&t2 ) return 0;
501: t1 = u1&0xf0; t2 = u2&0xf0; if ( t1&&t2 ) return 0;
502: t1 = u1&0xf; t2 = u2&0xf; if ( t1&&t2 ) return 0;
503: }
504: return 1;
505: break;
506: case 6:
507: for ( i = 0; i < nd_wpd; i++ ) {
508: u1 = d1[i]; u2 = d2[i];
509: t1 = u1&0x3f000000; t2 = u2&0x3f000000; if ( t1&&t2 ) return 0;
510: t1 = u1&0xfc0000; t2 = u2&0xfc0000; if ( t1&&t2 ) return 0;
511: t1 = u1&0x3f000; t2 = u2&0x3f000; if ( t1&&t2 ) return 0;
512: t1 = u1&0xfc0; t2 = u2&0xfc0; if ( t1&&t2 ) return 0;
513: t1 = u1&0x3f; t2 = u2&0x3f; if ( t1&&t2 ) return 0;
514: }
515: return 1;
516: break;
517: case 8:
518: for ( i = 0; i < nd_wpd; i++ ) {
519: u1 = d1[i]; u2 = d2[i];
520: t1 = u1&0xff000000; t2 = u2&0xff000000; if ( t1&&t2 ) return 0;
521: t1 = u1&0xff0000; t2 = u2&0xff0000; if ( t1&&t2 ) return 0;
522: t1 = u1&0xff00; t2 = u2&0xff00; if ( t1&&t2 ) return 0;
523: t1 = u1&0xff; t2 = u2&0xff; if ( t1&&t2 ) return 0;
524: }
525: return 1;
526: break;
527: case 16:
528: for ( i = 0; i < nd_wpd; i++ ) {
529: u1 = d1[i]; u2 = d2[i];
530: t1 = u1&0xffff0000; t2 = u2&0xffff0000; if ( t1&&t2 ) return 0;
531: t1 = u1&0xffff; t2 = u2&0xffff; if ( t1&&t2 ) return 0;
532: }
533: return 1;
534: break;
535: case 32:
536: for ( i = 0; i < nd_wpd; i++ )
537: if ( d1[i] && d2[i] ) return 0;
538: return 1;
539: break;
540: default:
541: for ( i = 0; i < nd_wpd; i++ ) {
542: u1 = d1[i]; u2 = d2[i];
543: for ( j = 0; j < nd_epw; j++ ) {
544: if ( (u1&nd_mask0) && (u2&nd_mask0) ) return 0;
545: u1 >>= nd_bpe; u2 >>= nd_bpe;
546: }
547: }
548: return 1;
549: break;
550: }
551: }
552:
553: ND nd_reduce(ND p1,ND p2)
554: {
555: int c,c1,c2,t,td,td2,mul;
556: NM m2,prev,head,cur,new;
557: unsigned int *d;
558:
559: if ( !p1 )
560: return 0;
561: else {
1.14 noro 562: c2 = invm(HCM(p2),nd_mod);
563: c1 = nd_mod-HCM(p1);
1.1 noro 564: DMAR(c1,c2,0,nd_mod,mul);
565: td = HTD(p1)-HTD(p2);
566: d = (unsigned int *)ALLOCA(nd_wpd*sizeof(unsigned int));
567: ndl_sub(HDL(p1),HDL(p2),d);
568: prev = 0; head = cur = BDY(p1);
569: NEWNM(new);
570: for ( m2 = BDY(p2); m2; ) {
1.14 noro 571: td2 = TD(new) = TD(m2)+td;
572: ndl_add(DL(m2),d,DL(new));
1.1 noro 573: if ( !cur ) {
1.14 noro 574: c1 = CM(m2);
1.1 noro 575: DMAR(c1,mul,0,nd_mod,c2);
1.14 noro 576: CM(new) = c2;
1.1 noro 577: if ( !prev ) {
578: prev = new;
579: NEXT(prev) = 0;
580: head = prev;
581: } else {
582: NEXT(prev) = new;
583: NEXT(new) = 0;
584: prev = new;
585: }
586: m2 = NEXT(m2);
587: NEWNM(new);
588: continue;
589: }
1.14 noro 590: if ( TD(cur) > td2 )
1.1 noro 591: c = 1;
1.14 noro 592: else if ( TD(cur) < td2 )
1.1 noro 593: c = -1;
594: else
1.14 noro 595: c = ndl_compare(DL(cur),DL(new));
1.1 noro 596: switch ( c ) {
597: case 0:
1.14 noro 598: c2 = CM(m2);
599: c1 = CM(cur);
1.1 noro 600: DMAR(c2,mul,c1,nd_mod,t);
601: if ( t )
1.14 noro 602: CM(cur) = t;
1.1 noro 603: else if ( !prev ) {
604: head = NEXT(cur);
605: FREENM(cur);
606: cur = head;
607: } else {
608: NEXT(prev) = NEXT(cur);
609: FREENM(cur);
610: cur = NEXT(prev);
611: }
612: m2 = NEXT(m2);
613: break;
614: case 1:
615: prev = cur;
616: cur = NEXT(cur);
617: break;
618: case -1:
619: if ( !prev ) {
620: /* cur = head */
621: prev = new;
1.14 noro 622: c2 = CM(m2);
1.1 noro 623: DMAR(c2,mul,0,nd_mod,c1);
1.14 noro 624: CM(prev) = c1;
1.1 noro 625: NEXT(prev) = head;
626: head = prev;
627: } else {
1.14 noro 628: c2 = CM(m2);
1.1 noro 629: DMAR(c2,mul,0,nd_mod,c1);
1.14 noro 630: CM(new) = c1;
1.1 noro 631: NEXT(prev) = new;
632: NEXT(new) = cur;
633: prev = new;
634: }
635: NEWNM(new);
636: m2 = NEXT(m2);
637: break;
638: }
639: }
640: FREENM(new);
641: if ( head ) {
642: BDY(p1) = head;
1.14 noro 643: SG(p1) = MAX(SG(p1),SG(p2)+td);
1.1 noro 644: return p1;
645: } else {
646: FREEND(p1);
647: return 0;
648: }
649:
650: }
651: }
652:
653: /* HDL(p1) = HDL(p2) */
654:
655: ND nd_reduce_special(ND p1,ND p2)
656: {
657: int c,c1,c2,t,td,td2,mul;
658: NM m2,prev,head,cur,new;
659:
660: if ( !p1 )
661: return 0;
662: else {
1.14 noro 663: c2 = invm(HCM(p2),nd_mod);
664: c1 = nd_mod-HCM(p1);
1.1 noro 665: DMAR(c1,c2,0,nd_mod,mul);
666: prev = 0; head = cur = BDY(p1);
667: NEWNM(new);
668: for ( m2 = BDY(p2); m2; ) {
1.14 noro 669: td2 = TD(new) = TD(m2);
1.1 noro 670: if ( !cur ) {
1.14 noro 671: c1 = CM(m2);
1.1 noro 672: DMAR(c1,mul,0,nd_mod,c2);
1.14 noro 673: CM(new) = c2;
674: bcopy(DL(m2),DL(new),nd_wpd*sizeof(unsigned int));
1.1 noro 675: if ( !prev ) {
676: prev = new;
677: NEXT(prev) = 0;
678: head = prev;
679: } else {
680: NEXT(prev) = new;
681: NEXT(new) = 0;
682: prev = new;
683: }
684: m2 = NEXT(m2);
685: NEWNM(new);
686: continue;
687: }
1.14 noro 688: if ( TD(cur) > td2 )
1.1 noro 689: c = 1;
1.14 noro 690: else if ( TD(cur) < td2 )
1.1 noro 691: c = -1;
692: else
1.14 noro 693: c = ndl_compare(DL(cur),DL(m2));
1.1 noro 694: switch ( c ) {
695: case 0:
1.14 noro 696: c2 = CM(m2);
697: c1 = CM(cur);
1.1 noro 698: DMAR(c2,mul,c1,nd_mod,t);
699: if ( t )
1.14 noro 700: CM(cur) = t;
1.1 noro 701: else if ( !prev ) {
702: head = NEXT(cur);
703: FREENM(cur);
704: cur = head;
705: } else {
706: NEXT(prev) = NEXT(cur);
707: FREENM(cur);
708: cur = NEXT(prev);
709: }
710: m2 = NEXT(m2);
711: break;
712: case 1:
713: prev = cur;
714: cur = NEXT(cur);
715: break;
716: case -1:
1.14 noro 717: bcopy(DL(m2),DL(new),nd_wpd*sizeof(unsigned int));
1.1 noro 718: if ( !prev ) {
719: /* cur = head */
720: prev = new;
1.14 noro 721: c2 = CM(m2);
1.1 noro 722: DMAR(c2,mul,0,nd_mod,c1);
1.14 noro 723: CM(prev) = c1;
1.1 noro 724: NEXT(prev) = head;
725: head = prev;
726: } else {
1.14 noro 727: c2 = CM(m2);
1.1 noro 728: DMAR(c2,mul,0,nd_mod,c1);
1.14 noro 729: CM(new) = c1;
1.1 noro 730: NEXT(prev) = new;
731: NEXT(new) = cur;
732: prev = new;
733: }
734: NEWNM(new);
735: m2 = NEXT(m2);
736: break;
737: }
738: }
739: FREENM(new);
740: if ( head ) {
741: BDY(p1) = head;
1.14 noro 742: SG(p1)= MAX(SG(p1),SG(p2)+td);
1.1 noro 743: return p1;
744: } else {
745: FREEND(p1);
746: return 0;
747: }
748:
749: }
750: }
751:
1.5 noro 752: int ndl_check_bound2(int index,unsigned int *d2)
1.1 noro 753: {
1.5 noro 754: unsigned int u2;
755: unsigned int *d1;
756: int i,j,ind,k;
1.1 noro 757:
1.5 noro 758: d1 = nd_bound[index];
759: ind = 0;
760: switch ( nd_bpe ) {
761: case 4:
762: for ( i = 0; i < nd_wpd; i++ ) {
763: u2 = d2[i];
764: if ( d1[ind++]+((u2>>28)&0xf) >= 0x10 ) return 1;
765: if ( d1[ind++]+((u2>>24)&0xf) >= 0x10 ) return 1;
766: if ( d1[ind++]+((u2>>20)&0xf) >= 0x10 ) return 1;
767: if ( d1[ind++]+((u2>>16)&0xf) >= 0x10 ) return 1;
768: if ( d1[ind++]+((u2>>12)&0xf) >= 0x10 ) return 1;
769: if ( d1[ind++]+((u2>>8)&0xf) >= 0x10 ) return 1;
770: if ( d1[ind++]+((u2>>4)&0xf) >= 0x10 ) return 1;
771: if ( d1[ind++]+(u2&0xf) >= 0x10 ) return 1;
772: }
773: return 0;
774: break;
775: case 6:
776: for ( i = 0; i < nd_wpd; i++ ) {
777: u2 = d2[i];
778: if ( d1[ind++]+((u2>>24)&0x3f) >= 0x40 ) return 1;
779: if ( d1[ind++]+((u2>>18)&0x3f) >= 0x40 ) return 1;
780: if ( d1[ind++]+((u2>>12)&0x3f) >= 0x40 ) return 1;
781: if ( d1[ind++]+((u2>>6)&0x3f) >= 0x40 ) return 1;
782: if ( d1[ind++]+(u2&0x3f) >= 0x40 ) return 1;
783: }
784: return 0;
785: break;
786: case 8:
787: for ( i = 0; i < nd_wpd; i++ ) {
788: u2 = d2[i];
789: if ( d1[ind++]+((u2>>24)&0xff) >= 0x100 ) return 1;
790: if ( d1[ind++]+((u2>>16)&0xff) >= 0x100 ) return 1;
791: if ( d1[ind++]+((u2>>8)&0xff) >= 0x100 ) return 1;
792: if ( d1[ind++]+(u2&0xff) >= 0x100 ) return 1;
793: }
794: return 0;
795: break;
796: case 16:
797: for ( i = 0; i < nd_wpd; i++ ) {
798: u2 = d2[i];
799: if ( d1[ind++]+((u2>>16)&0xffff) > 0x10000 ) return 1;
800: if ( d1[ind++]+(u2&0xffff) > 0x10000 ) return 1;
801: }
802: return 0;
803: break;
804: case 32:
805: for ( i = 0; i < nd_wpd; i++ )
806: if ( d1[i]+d2[i]<d1[i] ) return 1;
807: return 0;
808: break;
809: default:
810: for ( i = 0; i < nd_wpd; i++ ) {
811: u2 = d2[i];
812: k = (nd_epw-1)*nd_bpe;
813: for ( j = 0; j < nd_epw; j++, k -= nd_bpe )
814: if ( d1[ind++]+((u2>>k)&nd_mask0) > nd_mask0 ) return 1;
815: }
816: return 0;
817: break;
818: }
1.1 noro 819: }
820:
1.6 noro 821: INLINE int ndl_hash_value(int td,unsigned int *d)
1.1 noro 822: {
823: int i;
824: int r;
825:
826: r = td;
827: for ( i = 0; i < nd_wpd; i++ )
828: r = ((r<<16)+d[i])%REDTAB_LEN;
829: return r;
830: }
831:
1.9 noro 832: INLINE int nd_find_reducer(ND g)
1.1 noro 833: {
1.13 noro 834: RHist r;
1.6 noro 835: int d,k,i;
1.1 noro 836:
837: d = ndl_hash_value(HTD(g),HDL(g));
1.13 noro 838: for ( r = nd_red[d], k = 0; r; r = NEXT(r), k++ ) {
1.14 noro 839: if ( HTD(g) == TD(r) && ndl_equal(HDL(g),DL(r)) ) {
1.1 noro 840: if ( k > 0 ) nd_notfirst++;
841: nd_found++;
1.13 noro 842: return r->index;
1.1 noro 843: }
844: }
845:
1.13 noro 846: if ( Reverse )
847: for ( i = nd_psn-1; i >= 0; i-- ) {
848: r = nd_psh[i];
1.14 noro 849: if ( HTD(g) >= TD(r) && ndl_reducible(HDL(g),DL(r)) ) {
1.13 noro 850: nd_create++;
851: nd_append_red(HDL(g),HTD(g),i);
852: return i;
853: }
854: }
855: else
856: for ( i = 0; i < nd_psn; i++ ) {
857: r = nd_psh[i];
1.14 noro 858: if ( HTD(g) >= TD(r) && ndl_reducible(HDL(g),DL(r)) ) {
1.13 noro 859: nd_create++;
860: nd_append_red(HDL(g),HTD(g),i);
861: return i;
862: }
1.1 noro 863: }
1.6 noro 864: return -1;
1.1 noro 865: }
866:
867: ND nd_add(ND p1,ND p2)
868: {
869: int n,c;
870: int t;
871: ND r;
872: NM m1,m2,mr0,mr,s;
873:
874: if ( !p1 )
875: return p2;
876: else if ( !p2 )
877: return p1;
878: else {
879: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; ) {
1.14 noro 880: if ( TD(m1) > TD(m2) )
1.1 noro 881: c = 1;
1.14 noro 882: else if ( TD(m1) < TD(m2) )
1.1 noro 883: c = -1;
884: else
1.14 noro 885: c = ndl_compare(DL(m1),DL(m2));
1.1 noro 886: switch ( c ) {
887: case 0:
1.14 noro 888: t = ((CM(m1))+(CM(m2))) - nd_mod;
1.1 noro 889: if ( t < 0 )
890: t += nd_mod;
891: s = m1; m1 = NEXT(m1);
892: if ( t ) {
1.14 noro 893: NEXTNM2(mr0,mr,s); CM(mr) = (t);
1.1 noro 894: } else {
895: FREENM(s);
896: }
897: s = m2; m2 = NEXT(m2); FREENM(s);
898: break;
899: case 1:
900: s = m1; m1 = NEXT(m1); NEXTNM2(mr0,mr,s);
901: break;
902: case -1:
903: s = m2; m2 = NEXT(m2); NEXTNM2(mr0,mr,s);
904: break;
905: }
906: }
907: if ( !mr0 )
908: if ( m1 )
909: mr0 = m1;
910: else if ( m2 )
911: mr0 = m2;
912: else
913: return 0;
914: else if ( m1 )
915: NEXT(mr) = m1;
916: else if ( m2 )
917: NEXT(mr) = m2;
918: else
919: NEXT(mr) = 0;
920: BDY(p1) = mr0;
1.14 noro 921: SG(p1) = MAX(SG(p1),SG(p2));
1.1 noro 922: FREEND(p2);
923: return p1;
924: }
925: }
926:
927: #if 1
928: /* ret=1 : success, ret=0 : overflow */
1.16 ! noro 929: int nd_nf(int mod,ND g,int full,ND *rp)
1.1 noro 930: {
1.11 noro 931: ND d;
1.1 noro 932: NM m,mrd,tail;
1.7 noro 933: NM mul;
1.10 noro 934: int n,sugar,psugar,sugar0,stat,index;
1.6 noro 935: int c,c1,c2;
1.4 noro 936: #if USE_NDV
1.11 noro 937: NDV p,red;
1.4 noro 938: #else
1.11 noro 939: ND p,red;
1.4 noro 940: #endif
1.16 ! noro 941: Q cg,cred,gcd;
1.1 noro 942:
943: if ( !g ) {
944: *rp = 0;
945: return 1;
946: }
1.14 noro 947: sugar0 = sugar = SG(g);
1.1 noro 948: n = NV(g);
1.7 noro 949: mul = (NM)ALLOCA(sizeof(struct oNM)+(nd_wpd-1)*sizeof(unsigned int));
1.1 noro 950: for ( d = 0; g; ) {
1.6 noro 951: index = nd_find_reducer(g);
952: if ( index >= 0 ) {
953: p = nd_ps[index];
1.14 noro 954: ndl_sub(HDL(g),HDL(p),DL(mul));
955: TD(mul) = HTD(g)-HTD(p);
1.10 noro 956: #if 0
1.14 noro 957: if ( d && (SG(p)+TD(mul)) > sugar ) {
1.10 noro 958: goto afo;
959: }
960: #endif
1.14 noro 961: if ( ndl_check_bound2(index,DL(mul)) ) {
1.6 noro 962: nd_free(g); nd_free(d);
963: return 0;
964: }
1.4 noro 965: #if USE_NDV
1.16 ! noro 966: if ( mod ) {
! 967: c1 = invm(HCM(p),nd_mod); c2 = nd_mod-HCM(g);
! 968: DMAR(c1,c2,0,nd_mod,c); CM(mul) = c;
! 969: ndv_mul_nm(mod,nd_ps[index],mul,ndv_red);
! 970: g = ndv_add(g,ndv_red);
! 971: } else {
! 972: igcd_cofactor(HCQ(g),HCQ(nd_ps[index]),&gcd,&cg,&cred);
! 973: chsgnq(cg,&CQ(mul));
! 974: nd_mul_c_q(d,cred);
! 975: nd_mul_c_q(g,cred);
! 976: ndv_mul_nm(mod,nd_ps[index],mul,ndv_red);
! 977: g = ndv_add_q(g,ndv_red);
! 978: }
1.14 noro 979: sugar = MAX(sugar,SG(ndv_red));
1.4 noro 980: #else
1.16 ! noro 981: c1 = invm(HCM(p),nd_mod); c2 = nd_mod-HCM(g);
! 982: DMAR(c1,c2,0,nd_mod,c); CM(mul) = c;
1.7 noro 983: red = nd_mul_ind_nm(index,mul);
1.1 noro 984: g = nd_add(g,red);
1.14 noro 985: sugar = MAX(sugar,SG(red));
1.1 noro 986: #endif
987: } else if ( !full ) {
988: *rp = g;
989: return 1;
990: } else {
1.10 noro 991: afo:
1.1 noro 992: m = BDY(g);
993: if ( NEXT(m) ) {
994: BDY(g) = NEXT(m); NEXT(m) = 0;
995: } else {
996: FREEND(g); g = 0;
997: }
998: if ( d ) {
999: NEXT(tail)=m;
1000: tail=m;
1001: } else {
1002: MKND(n,m,d);
1003: tail = BDY(d);
1004: }
1005: }
1006: }
1007: if ( d )
1.14 noro 1008: SG(d) = sugar;
1.1 noro 1009: *rp = d;
1010: return 1;
1011: }
1012: #else
1013:
1014: ND nd_remove_head(ND p)
1015: {
1016: NM m;
1017:
1018: m = BDY(p);
1019: if ( !NEXT(m) ) {
1020: FREEND(p);
1021: p = 0;
1022: } else
1023: BDY(p) = NEXT(m);
1024: FREENM(m);
1025: return p;
1026: }
1027:
1028: PGeoBucket create_pbucket()
1029: {
1030: PGeoBucket g;
1031:
1032: g = CALLOC(1,sizeof(struct oPGeoBucket));
1033: g->m = -1;
1034: return g;
1035: }
1036:
1037: void add_pbucket(PGeoBucket g,ND d)
1038: {
1039: int l,k,m;
1040:
1041: l = nd_length(d);
1042: for ( k = 0, m = 1; l > m; k++, m <<= 2 );
1043: /* 4^(k-1) < l <= 4^k */
1044: d = nd_add(g->body[k],d);
1045: for ( ; d && nd_length(d) > 1<<(2*k); k++ ) {
1046: g->body[k] = 0;
1047: d = nd_add(g->body[k+1],d);
1048: }
1049: g->body[k] = d;
1050: g->m = MAX(g->m,k);
1051: }
1052:
1053: int head_pbucket(PGeoBucket g)
1054: {
1055: int j,i,c,k,nv,sum;
1056: unsigned int *di,*dj;
1057: ND gi,gj;
1058:
1059: k = g->m;
1060: while ( 1 ) {
1061: j = -1;
1062: for ( i = 0; i <= k; i++ ) {
1063: if ( !(gi = g->body[i]) )
1064: continue;
1065: if ( j < 0 ) {
1066: j = i;
1067: gj = g->body[j];
1068: dj = HDL(gj);
1.14 noro 1069: sum = HCM(gj);
1.1 noro 1070: } else {
1071: di = HDL(gi);
1072: nv = NV(gi);
1073: if ( HTD(gi) > HTD(gj) )
1074: c = 1;
1075: else if ( HTD(gi) < HTD(gj) )
1076: c = -1;
1077: else
1078: c = ndl_compare(di,dj);
1079: if ( c > 0 ) {
1080: if ( sum )
1.14 noro 1081: HCM(gj) = sum;
1.1 noro 1082: else
1083: g->body[j] = nd_remove_head(gj);
1084: j = i;
1085: gj = g->body[j];
1086: dj = HDL(gj);
1.14 noro 1087: sum = HCM(gj);
1.1 noro 1088: } else if ( c == 0 ) {
1.14 noro 1089: sum = sum+HCM(gi)-nd_mod;
1.1 noro 1090: if ( sum < 0 )
1091: sum += nd_mod;
1092: g->body[i] = nd_remove_head(gi);
1093: }
1094: }
1095: }
1096: if ( j < 0 )
1097: return -1;
1098: else if ( sum ) {
1.14 noro 1099: HCM(gj) = sum;
1.1 noro 1100: return j;
1101: } else
1102: g->body[j] = nd_remove_head(gj);
1103: }
1104: }
1105:
1106: ND normalize_pbucket(PGeoBucket g)
1107: {
1108: int i;
1109: ND r,t;
1110:
1111: r = 0;
1112: for ( i = 0; i <= g->m; i++ )
1113: r = nd_add(r,g->body[i]);
1114: return r;
1115: }
1116:
1117: ND nd_nf(ND g,int full)
1118: {
1119: ND u,p,d,red;
1120: NODE l;
1121: NM m,mrd;
1122: int sugar,psugar,n,h_reducible,h;
1123: PGeoBucket bucket;
1124:
1125: if ( !g ) {
1126: return 0;
1127: }
1.14 noro 1128: sugar = SG(g);
1129: n = NV(g);
1.1 noro 1130: bucket = create_pbucket();
1131: add_pbucket(bucket,g);
1132: d = 0;
1133: while ( 1 ) {
1134: h = head_pbucket(bucket);
1135: if ( h < 0 ) {
1136: if ( d )
1.14 noro 1137: SG(d) = sugar;
1.1 noro 1138: return d;
1139: }
1140: g = bucket->body[h];
1141: red = nd_find_reducer(g);
1142: if ( red ) {
1143: bucket->body[h] = nd_remove_head(g);
1144: red = nd_remove_head(red);
1145: add_pbucket(bucket,red);
1.14 noro 1146: sugar = MAX(sugar,SG(red));
1.1 noro 1147: } else if ( !full ) {
1148: g = normalize_pbucket(bucket);
1149: if ( g )
1.14 noro 1150: SG(g) = sugar;
1.1 noro 1151: return g;
1152: } else {
1153: m = BDY(g);
1154: if ( NEXT(m) ) {
1155: BDY(g) = NEXT(m); NEXT(m) = 0;
1156: } else {
1157: FREEND(g); g = 0;
1158: }
1159: bucket->body[h] = g;
1160: NEXT(m) = 0;
1161: if ( d ) {
1162: for ( mrd = BDY(d); NEXT(mrd); mrd = NEXT(mrd) );
1163: NEXT(mrd) = m;
1164: } else {
1165: MKND(n,m,d);
1166: }
1167: }
1168: }
1169: }
1170: #endif
1171:
1.16 ! noro 1172: NODE nd_gb(int m,NODE f)
1.1 noro 1173: {
1174: int i,nh,sugar,stat;
1175: NODE r,g,gall;
1176: ND_pairs d;
1177: ND_pairs l;
1178: ND h,nf;
1179:
1180: for ( gall = g = 0, d = 0, r = f; r; r = NEXT(r) ) {
1181: i = (int)BDY(r);
1182: d = update_pairs(d,g,i);
1183: g = update_base(g,i);
1184: gall = append_one(gall,i);
1185: }
1186: sugar = 0;
1187: while ( d ) {
1188: again:
1189: l = nd_minp(d,&d);
1.14 noro 1190: if ( SG(l) != sugar ) {
1191: sugar = SG(l);
1.1 noro 1192: fprintf(asir_out,"%d",sugar);
1193: }
1.16 ! noro 1194: stat = nd_sp(m,l,&h);
1.1 noro 1195: if ( !stat ) {
1196: NEXT(l) = d; d = l;
1197: d = nd_reconstruct(d);
1198: goto again;
1199: }
1.16 ! noro 1200: stat = nd_nf(m,h,!Top,&nf);
1.1 noro 1201: if ( !stat ) {
1202: NEXT(l) = d; d = l;
1203: d = nd_reconstruct(d);
1204: goto again;
1205: } else if ( nf ) {
1206: printf("+"); fflush(stdout);
1.16 ! noro 1207: nh = nd_newps(m,nf);
1.1 noro 1208: d = update_pairs(d,g,nh);
1209: g = update_base(g,nh);
1210: gall = append_one(gall,nh);
1211: FREENDP(l);
1212: } else {
1213: printf("."); fflush(stdout);
1214: FREENDP(l);
1215: }
1216: }
1217: return g;
1218: }
1219:
1220: ND_pairs update_pairs( ND_pairs d, NODE /* of index */ g, int t)
1221: {
1222: ND_pairs d1,nd,cur,head,prev,remove;
1223:
1224: if ( !g ) return d;
1225: d = crit_B(d,t);
1226: d1 = nd_newpairs(g,t);
1227: d1 = crit_M(d1);
1228: d1 = crit_F(d1);
1229: prev = 0; cur = head = d1;
1230: while ( cur ) {
1231: if ( crit_2( cur->i1,cur->i2 ) ) {
1232: remove = cur;
1233: if ( !prev ) {
1234: head = cur = NEXT(cur);
1235: } else {
1236: cur = NEXT(prev) = NEXT(cur);
1237: }
1238: FREENDP(remove);
1239: } else {
1240: prev = cur;
1241: cur = NEXT(cur);
1242: }
1243: }
1244: if ( !d )
1245: return head;
1246: else {
1247: nd = d;
1248: while ( NEXT(nd) )
1249: nd = NEXT(nd);
1250: NEXT(nd) = head;
1251: return d;
1252: }
1253: }
1254:
1255: ND_pairs nd_newpairs( NODE g, int t )
1256: {
1257: NODE h;
1258: unsigned int *dl;
1259: int td,ts,s;
1260: ND_pairs r,r0;
1261:
1262: dl = HDL(nd_ps[t]);
1263: td = HTD(nd_ps[t]);
1.14 noro 1264: ts = SG(nd_ps[t]) - td;
1.1 noro 1265: for ( r0 = 0, h = g; h; h = NEXT(h) ) {
1266: NEXTND_pairs(r0,r);
1267: r->i1 = (int)BDY(h);
1268: r->i2 = t;
1269: ndl_lcm(HDL(nd_ps[r->i1]),dl,r->lcm);
1.14 noro 1270: TD(r) = ndl_td(r->lcm);
1271: s = SG(nd_ps[r->i1])-HTD(nd_ps[r->i1]);
1272: SG(r) = MAX(s,ts) + TD(r);
1.1 noro 1273: }
1274: NEXT(r) = 0;
1275: return r0;
1276: }
1277:
1278: ND_pairs crit_B( ND_pairs d, int s )
1279: {
1280: ND_pairs cur,head,prev,remove;
1281: unsigned int *t,*tl,*lcm;
1282: int td,tdl;
1283:
1284: if ( !d ) return 0;
1285: t = HDL(nd_ps[s]);
1286: prev = 0;
1287: head = cur = d;
1288: lcm = (unsigned int *)ALLOCA(nd_wpd*sizeof(unsigned int));
1289: while ( cur ) {
1290: tl = cur->lcm;
1291: if ( ndl_reducible(tl,t)
1292: && (ndl_lcm(HDL(nd_ps[cur->i1]),t,lcm),!ndl_equal(lcm,tl))
1293: && (ndl_lcm(HDL(nd_ps[cur->i2]),t,lcm),!ndl_equal(lcm,tl)) ) {
1294: remove = cur;
1295: if ( !prev ) {
1296: head = cur = NEXT(cur);
1297: } else {
1298: cur = NEXT(prev) = NEXT(cur);
1299: }
1300: FREENDP(remove);
1301: } else {
1302: prev = cur;
1303: cur = NEXT(cur);
1304: }
1305: }
1306: return head;
1307: }
1308:
1309: ND_pairs crit_M( ND_pairs d1 )
1310: {
1311: ND_pairs e,d2,d3,dd,p;
1312: unsigned int *id,*jd;
1313: int itd,jtd;
1314:
1315: for ( dd = 0, e = d1; e; e = d3 ) {
1316: if ( !(d2 = NEXT(e)) ) {
1317: NEXT(e) = dd;
1318: return e;
1319: }
1320: id = e->lcm;
1.14 noro 1321: itd = TD(e);
1.1 noro 1322: for ( d3 = 0; d2; d2 = p ) {
1323: p = NEXT(d2),
1324: jd = d2->lcm;
1.14 noro 1325: jtd = TD(d2);
1.1 noro 1326: if ( jtd == itd )
1327: if ( id == jd );
1328: else if ( ndl_reducible(jd,id) ) continue;
1329: else if ( ndl_reducible(id,jd) ) goto delit;
1330: else ;
1331: else if ( jtd > itd )
1332: if ( ndl_reducible(jd,id) ) continue;
1333: else ;
1334: else if ( ndl_reducible(id,jd ) ) goto delit;
1335: NEXT(d2) = d3;
1336: d3 = d2;
1337: }
1338: NEXT(e) = dd;
1339: dd = e;
1340: continue;
1341: /**/
1342: delit: NEXT(d2) = d3;
1343: d3 = d2;
1344: for ( ; p; p = d2 ) {
1345: d2 = NEXT(p);
1346: NEXT(p) = d3;
1347: d3 = p;
1348: }
1349: FREENDP(e);
1350: }
1351: return dd;
1352: }
1353:
1354: ND_pairs crit_F( ND_pairs d1 )
1355: {
1356: ND_pairs rest, head,remove;
1357: ND_pairs last, p, r, w;
1358: int s;
1359:
1360: for ( head = last = 0, p = d1; NEXT(p); ) {
1361: r = w = equivalent_pairs(p,&rest);
1.14 noro 1362: s = SG(r);
1.1 noro 1363: w = NEXT(w);
1364: while ( w ) {
1365: if ( crit_2(w->i1,w->i2) ) {
1366: r = w;
1367: w = NEXT(w);
1368: while ( w ) {
1369: remove = w;
1370: w = NEXT(w);
1371: FREENDP(remove);
1372: }
1373: break;
1.14 noro 1374: } else if ( SG(w) < s ) {
1.1 noro 1375: FREENDP(r);
1376: r = w;
1.14 noro 1377: s = SG(r);
1.1 noro 1378: w = NEXT(w);
1379: } else {
1380: remove = w;
1381: w = NEXT(w);
1382: FREENDP(remove);
1383: }
1384: }
1385: if ( last ) NEXT(last) = r;
1386: else head = r;
1387: NEXT(last = r) = 0;
1388: p = rest;
1389: if ( !p ) return head;
1390: }
1391: if ( !last ) return p;
1392: NEXT(last) = p;
1393: return head;
1394: }
1395:
1396: int crit_2( int dp1, int dp2 )
1397: {
1398: return ndl_disjoint(HDL(nd_ps[dp1]),HDL(nd_ps[dp2]));
1399: }
1400:
1401: static ND_pairs equivalent_pairs( ND_pairs d1, ND_pairs *prest )
1402: {
1403: ND_pairs w,p,r,s;
1404: unsigned int *d;
1405: int td;
1406:
1407: w = d1;
1408: d = w->lcm;
1.14 noro 1409: td = TD(w);
1.1 noro 1410: s = NEXT(w);
1411: NEXT(w) = 0;
1412: for ( r = 0; s; s = p ) {
1413: p = NEXT(s);
1.14 noro 1414: if ( td == TD(s) && ndl_equal(d,s->lcm) ) {
1.1 noro 1415: NEXT(s) = w;
1416: w = s;
1417: } else {
1418: NEXT(s) = r;
1419: r = s;
1420: }
1421: }
1422: *prest = r;
1423: return w;
1424: }
1425:
1426: NODE update_base(NODE nd,int ndp)
1427: {
1428: unsigned int *dl, *dln;
1429: NODE last, p, head;
1430: int td,tdn;
1431:
1432: dl = HDL(nd_ps[ndp]);
1433: td = HTD(nd_ps[ndp]);
1434: for ( head = last = 0, p = nd; p; ) {
1435: dln = HDL(nd_ps[(int)BDY(p)]);
1436: tdn = HTD(nd_ps[(int)BDY(p)]);
1437: if ( tdn >= td && ndl_reducible( dln, dl ) ) {
1438: p = NEXT(p);
1439: if ( last ) NEXT(last) = p;
1440: } else {
1441: if ( !last ) head = p;
1442: p = NEXT(last = p);
1443: }
1444: }
1445: head = append_one(head,ndp);
1446: return head;
1447: }
1448:
1449: ND_pairs nd_minp( ND_pairs d, ND_pairs *prest )
1450: {
1451: ND_pairs m,ml,p,l;
1452: unsigned int *lcm;
1453: int s,td,len,tlen,c;
1454:
1455: if ( !(p = NEXT(m = d)) ) {
1456: *prest = p;
1457: NEXT(m) = 0;
1458: return m;
1459: }
1460: lcm = m->lcm;
1.14 noro 1461: s = SG(m);
1462: td = TD(m);
1.6 noro 1463: len = nd_psl[m->i1]+nd_psl[m->i2];
1.1 noro 1464: for ( ml = 0, l = m; p; p = NEXT(l = p) ) {
1.14 noro 1465: if (SG(p) < s)
1.1 noro 1466: goto find;
1.14 noro 1467: else if ( SG(p) == s ) {
1468: if ( TD(p) < td )
1.1 noro 1469: goto find;
1.14 noro 1470: else if ( TD(p) == td ) {
1.1 noro 1471: c = ndl_compare(p->lcm,lcm);
1472: if ( c < 0 )
1473: goto find;
1.10 noro 1474: #if 0
1.1 noro 1475: else if ( c == 0 ) {
1.6 noro 1476: tlen = nd_psl[p->i1]+nd_psl[p->i2];
1.1 noro 1477: if ( tlen < len )
1478: goto find;
1479: }
1.10 noro 1480: #endif
1.1 noro 1481: }
1482: }
1483: continue;
1484: find:
1485: ml = l;
1486: m = p;
1487: lcm = m->lcm;
1.14 noro 1488: s = SG(m);
1489: td = TD(m);
1.1 noro 1490: len = tlen;
1491: }
1492: if ( !ml ) *prest = NEXT(m);
1493: else {
1494: NEXT(ml) = NEXT(m);
1495: *prest = d;
1496: }
1497: NEXT(m) = 0;
1498: return m;
1499: }
1500:
1.16 ! noro 1501: int nd_newps(int mod,ND a)
1.1 noro 1502: {
1.3 noro 1503: int len;
1.13 noro 1504: RHist r;
1.3 noro 1505:
1.1 noro 1506: if ( nd_psn == nd_pslen ) {
1507: nd_pslen *= 2;
1.6 noro 1508: nd_psl = (int *)REALLOC((char *)nd_psl,nd_pslen*sizeof(int));
1.4 noro 1509: #if USE_NDV
1.11 noro 1510: nd_ps = (NDV *)REALLOC((char *)nd_ps,nd_pslen*sizeof(NDV));
1511: #else
1512: nd_ps = (ND *)REALLOC((char *)nd_ps,nd_pslen*sizeof(ND));
1.4 noro 1513: #endif
1.13 noro 1514: nd_psh = (RHist *)REALLOC((char *)nd_psh,nd_pslen*sizeof(RHist));
1.1 noro 1515: nd_bound = (unsigned int **)
1516: REALLOC((char *)nd_bound,nd_pslen*sizeof(unsigned int *));
1517: }
1.16 ! noro 1518: if ( mod )
! 1519: nd_monic(a);
! 1520: else
! 1521: nd_removecont(a);
1.1 noro 1522: nd_bound[nd_psn] = nd_compute_bound(a);
1.14 noro 1523: NEWRHist(r); TD(r) = HTD(a); ndl_copy(HDL(a),DL(r)); nd_psh[nd_psn] = r;
1.5 noro 1524: #if USE_NDV
1.16 ! noro 1525: nd_ps[nd_psn]= ndtondv(mod,a);
1.13 noro 1526: nd_free(a);
1.14 noro 1527: nd_psl[nd_psn] = len = LEN(nd_ps[nd_psn]);
1.3 noro 1528: if ( len > nmv_len ) {
1529: nmv_len = 2*len;
1530: BDY(ndv_red) = (NMV)REALLOC(BDY(ndv_red),nmv_len*nmv_adv);
1531: }
1.11 noro 1532: #else
1533: nd_ps[nd_psn] = a;
1534: nd_psl[nd_psn] = nd_length(a);
1.4 noro 1535: #endif
1.1 noro 1536: return nd_psn++;
1537: }
1538:
1.16 ! noro 1539: NODE nd_setup(int mod,NODE f)
1.1 noro 1540: {
1.5 noro 1541: int i,j,td,len,max;
1.1 noro 1542: NODE s,s0,f0;
1.5 noro 1543: unsigned int *d;
1.13 noro 1544: RHist r;
1.11 noro 1545:
1546: nd_found = 0; nd_notfirst = 0; nd_create = 0;
1.1 noro 1547:
1548: nd_psn = length(f); nd_pslen = 2*nd_psn;
1.6 noro 1549: nd_psl = (int *)MALLOC(nd_pslen*sizeof(int));
1.4 noro 1550: #if USE_NDV
1.11 noro 1551: nd_ps = (NDV *)MALLOC(nd_pslen*sizeof(NDV));
1552: #else
1553: nd_ps = (ND *)MALLOC(nd_pslen*sizeof(ND));
1.4 noro 1554: #endif
1.13 noro 1555: nd_psh = (RHist *)MALLOC(nd_pslen*sizeof(RHist));
1.1 noro 1556: nd_bound = (unsigned int **)MALLOC(nd_pslen*sizeof(unsigned int *));
1.5 noro 1557: for ( max = 0, i = 0, s = f; i < nd_psn; i++, s = NEXT(s) ) {
1558: nd_bound[i] = d = dp_compute_bound((DP)BDY(s));
1559: for ( j = 0; j < nd_nvar; j++ )
1560: max = MAX(d[j],max);
1561: }
1.11 noro 1562: if ( !nd_red )
1.13 noro 1563: nd_red = (RHist *)MALLOC(REDTAB_LEN*sizeof(RHist));
1564: bzero(nd_red,REDTAB_LEN*sizeof(RHist));
1.5 noro 1565:
1566: if ( max < 2 )
1567: nd_bpe = 2;
1568: else if ( max < 4 )
1569: nd_bpe = 4;
1570: else if ( max < 64 )
1571: nd_bpe = 6;
1572: else if ( max < 256 )
1573: nd_bpe = 8;
1574: else if ( max < 65536 )
1575: nd_bpe = 16;
1576: else
1577: nd_bpe = 32;
1.13 noro 1578:
1.1 noro 1579: nd_setup_parameters();
1580: nd_free_private_storage();
1.3 noro 1581: len = 0;
1.1 noro 1582: for ( i = 0; i < nd_psn; i++, f = NEXT(f) ) {
1.11 noro 1583: #if USE_NDV
1.16 ! noro 1584: nd_ps[i] = dptondv(mod,(DP)BDY(f));
! 1585: if ( mod )
! 1586: ndv_mul_c(nd_ps[i],invm(HCM(nd_ps[i]),nd_mod));
! 1587: else
! 1588: ndv_removecont(nd_ps[i]);
1.14 noro 1589: len = MAX(len,LEN(nd_ps[i]));
1.11 noro 1590: #else
1.1 noro 1591: nd_ps[i] = dptond((DP)BDY(f));
1.11 noro 1592: nd_mul_c(nd_ps[i],1);
1.6 noro 1593: nd_psl[i] = nd_length(nd_ps[i]);
1.4 noro 1594: #endif
1.14 noro 1595: NEWRHist(r); TD(r) = HTD(nd_ps[i]); ndl_copy(HDL(nd_ps[i]),DL(r));
1.13 noro 1596: nd_psh[i] = r;
1.1 noro 1597: }
1.4 noro 1598: #if USE_NDV
1.3 noro 1599: nmv_len = 16*len;
1600: NEWNDV(ndv_red);
1.16 ! noro 1601: if ( mod )
! 1602: BDY(ndv_red) = (NMV)MALLOC_ATOMIC(nmv_len*nmv_adv);
! 1603: else
! 1604: BDY(ndv_red) = (NMV)MALLOC(nmv_len*nmv_adv);
1.4 noro 1605: #endif
1.1 noro 1606: for ( s0 = 0, i = 0; i < nd_psn; i++ ) {
1607: NEXTNODE(s0,s); BDY(s) = (pointer)i;
1608: }
1609: if ( s0 ) NEXT(s) = 0;
1610: return s0;
1611: }
1612:
1613: void nd_gr(LIST f,LIST v,int m,struct order_spec *ord,LIST *rp)
1614: {
1615: struct order_spec ord1;
1616: VL fv,vv,vc;
1617: NODE fd,fd0,r,r0,t,x,s,xx;
1618: DP a,b,c;
1619:
1620: get_vars((Obj)f,&fv); pltovl(v,&vv);
1621: nd_nvar = length(vv);
1622: if ( ord->id )
1623: error("nd_gr : unsupported order");
1624: switch ( ord->ord.simple ) {
1625: case 0:
1626: is_rlex = 1;
1627: break;
1628: case 1:
1629: is_rlex = 0;
1630: break;
1631: default:
1632: error("nd_gr : unsupported order");
1633: }
1634: initd(ord);
1635: nd_mod = m;
1636: for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) {
1637: ptod(CO,vv,(P)BDY(t),&b);
1.16 ! noro 1638: if ( m )
! 1639: _dp_mod(b,m,0,&c);
! 1640: else
! 1641: c = b;
1.1 noro 1642: if ( c ) {
1643: NEXTNODE(fd0,fd); BDY(fd) = (pointer)c;
1644: }
1645: }
1646: if ( fd0 ) NEXT(fd) = 0;
1.16 ! noro 1647: s = nd_setup(m,fd0);
! 1648: x = nd_gb(m,s);
1.1 noro 1649: #if 0
1650: x = nd_reduceall(x,m);
1651: #endif
1652: for ( r0 = 0; x; x = NEXT(x) ) {
1653: NEXTNODE(r0,r);
1.11 noro 1654: #if USE_NDV
1.16 ! noro 1655: a = ndvtodp(m,nd_ps[(int)BDY(x)]);
1.11 noro 1656: #else
1.16 ! noro 1657: a = ndtodp(m,nd_ps[(int)BDY(x)]);
1.11 noro 1658: #endif
1.16 ! noro 1659: if ( m )
! 1660: _dtop_mod(CO,vv,a,(P *)&BDY(r));
! 1661: else
! 1662: dtop(CO,vv,a,(P *)&BDY(r));
1.1 noro 1663: }
1664: if ( r0 ) NEXT(r) = 0;
1665: MKLIST(*rp,r0);
1666: fprintf(asir_out,"found=%d,notfirst=%d,create=%d\n",
1667: nd_found,nd_notfirst,nd_create);
1668: }
1669:
1670: void dltondl(int n,DL dl,unsigned int *r)
1671: {
1672: unsigned int *d;
1673: int i;
1674:
1675: d = dl->d;
1676: bzero(r,nd_wpd*sizeof(unsigned int));
1677: if ( is_rlex )
1678: for ( i = 0; i < n; i++ )
1679: r[(n-1-i)/nd_epw] |= (d[i]<<((nd_epw-((n-1-i)%nd_epw)-1)*nd_bpe));
1680: else
1681: for ( i = 0; i < n; i++ )
1682: r[i/nd_epw] |= d[i]<<((nd_epw-(i%nd_epw)-1)*nd_bpe);
1683: }
1684:
1685: DL ndltodl(int n,int td,unsigned int *ndl)
1686: {
1687: DL dl;
1688: int *d;
1689: int i;
1690:
1691: NEWDL(dl,n);
1.14 noro 1692: TD(dl) = td;
1.1 noro 1693: d = dl->d;
1694: if ( is_rlex )
1695: for ( i = 0; i < n; i++ )
1696: d[i] = (ndl[(n-1-i)/nd_epw]>>((nd_epw-((n-1-i)%nd_epw)-1)*nd_bpe))
1697: &((1<<nd_bpe)-1);
1698: else
1699: for ( i = 0; i < n; i++ )
1700: d[i] = (ndl[i/nd_epw]>>((nd_epw-(i%nd_epw)-1)*nd_bpe))
1701: &((1<<nd_bpe)-1);
1702: return dl;
1703: }
1704:
1705: ND dptond(DP p)
1706: {
1707: ND d;
1708: NM m0,m;
1709: MP t;
1710: int n;
1711:
1712: if ( !p )
1713: return 0;
1714: n = NV(p);
1715: m0 = 0;
1716: for ( t = BDY(p); t; t = NEXT(t) ) {
1717: NEXTNM(m0,m);
1.14 noro 1718: CM(m) = ITOS(C(t));
1719: TD(m) = TD(DL(t));
1720: dltondl(n,DL(t),DL(m));
1.1 noro 1721: }
1722: NEXT(m) = 0;
1723: MKND(n,m0,d);
1.14 noro 1724: NV(d) = n;
1725: SG(d) = SG(p);
1.1 noro 1726: return d;
1727: }
1728:
1729: DP ndtodp(ND p)
1730: {
1731: DP d;
1732: MP m0,m;
1733: NM t;
1734: int n;
1735:
1736: if ( !p )
1737: return 0;
1738: n = NV(p);
1739: m0 = 0;
1740: for ( t = BDY(p); t; t = NEXT(t) ) {
1741: NEXTMP(m0,m);
1.14 noro 1742: C(m) = STOI(CM(t));
1743: DL(m) = ndltodl(n,TD(t),DL(t));
1.1 noro 1744: }
1745: NEXT(m) = 0;
1746: MKDP(n,m0,d);
1.14 noro 1747: SG(d) = SG(p);
1.1 noro 1748: return d;
1749: }
1750:
1751: void ndl_print(unsigned int *dl)
1752: {
1753: int n;
1754: int i;
1755:
1756: n = nd_nvar;
1757: printf("<<");
1758: if ( is_rlex )
1759: for ( i = 0; i < n; i++ )
1760: printf(i==n-1?"%d":"%d,",
1761: (dl[(n-1-i)/nd_epw]>>((nd_epw-((n-1-i)%nd_epw)-1)*nd_bpe))
1762: &((1<<nd_bpe)-1));
1763: else
1764: for ( i = 0; i < n; i++ )
1765: printf(i==n-1?"%d":"%d,",
1766: (dl[i/nd_epw]>>((nd_epw-(i%nd_epw)-1)*nd_bpe))
1767: &((1<<nd_bpe)-1));
1768: printf(">>");
1769: }
1770:
1771: void nd_print(ND p)
1772: {
1773: NM m;
1774:
1775: if ( !p )
1776: printf("0\n");
1777: else {
1778: for ( m = BDY(p); m; m = NEXT(m) ) {
1.14 noro 1779: printf("+%d*",CM(m));
1780: ndl_print(DL(m));
1.1 noro 1781: }
1782: printf("\n");
1783: }
1784: }
1785:
1.16 ! noro 1786: void nd_print_q(ND p)
! 1787: {
! 1788: NM m;
! 1789:
! 1790: if ( !p )
! 1791: printf("0\n");
! 1792: else {
! 1793: for ( m = BDY(p); m; m = NEXT(m) ) {
! 1794: printf("+");
! 1795: printexpr(CO,CQ(m));
! 1796: printf("*");
! 1797: ndl_print(DL(m));
! 1798: }
! 1799: printf("\n");
! 1800: }
! 1801: }
! 1802:
1.1 noro 1803: void ndp_print(ND_pairs d)
1804: {
1805: ND_pairs t;
1806:
1807: for ( t = d; t; t = NEXT(t) ) {
1808: printf("%d,%d ",t->i1,t->i2);
1809: }
1810: printf("\n");
1811: }
1812:
1.16 ! noro 1813: void nd_removecont(ND p)
! 1814: {
! 1815: int i,n;
! 1816: Q *w;
! 1817: Q dvr,t;
! 1818: NM m;
! 1819:
! 1820: for ( m = BDY(p), n = 0; m; m = NEXT(m), n++ );
! 1821: w = (Q *)ALLOCA(n*sizeof(Q));
! 1822: for ( m = BDY(p), i = 0; i < n; m = NEXT(m), i++ )
! 1823: w[i] = CQ(m);
! 1824: sortbynm(w,n);
! 1825: qltozl(w,n,&dvr);
! 1826: for ( m = BDY(p); m; m = NEXT(m) ) {
! 1827: divq(CQ(m),dvr,&t); CQ(m) = t;
! 1828: }
! 1829: }
! 1830:
! 1831: void ndv_removecont(NDV p)
! 1832: {
! 1833: int i,len;
! 1834: Q *w;
! 1835: Q dvr,t;
! 1836: NMV m;
! 1837:
! 1838: len = p->len;
! 1839: w = (Q *)ALLOCA(len*sizeof(Q));
! 1840: for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ )
! 1841: w[i] = CQ(m);
! 1842: sortbynm(w,len);
! 1843: qltozl(w,len,&dvr);
! 1844: for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ ) {
! 1845: divq(CQ(m),dvr,&t); CQ(m) = t;
! 1846: }
! 1847: }
! 1848:
1.1 noro 1849: void nd_monic(ND p)
1850: {
1851: if ( !p )
1852: return;
1853: else
1.14 noro 1854: nd_mul_c(p,invm(HCM(p),nd_mod));
1.1 noro 1855: }
1856:
1857: void nd_mul_c(ND p,int mul)
1858: {
1859: NM m;
1860: int c,c1;
1861:
1862: if ( !p )
1863: return;
1864: for ( m = BDY(p); m; m = NEXT(m) ) {
1.14 noro 1865: c1 = CM(m);
1.1 noro 1866: DMAR(c1,mul,0,nd_mod,c);
1.14 noro 1867: CM(m) = c;
1.1 noro 1868: }
1869: }
1870:
1.16 ! noro 1871: void nd_mul_c_q(ND p,Q mul)
! 1872: {
! 1873: NM m;
! 1874: Q c;
! 1875:
! 1876: if ( !p )
! 1877: return;
! 1878: for ( m = BDY(p); m; m = NEXT(m) ) {
! 1879: mulq(CQ(m),mul,&c); CQ(m) = c;
! 1880: }
! 1881: }
! 1882:
1.1 noro 1883: void nd_free(ND p)
1884: {
1885: NM t,s;
1886:
1887: if ( !p )
1888: return;
1889: t = BDY(p);
1890: while ( t ) {
1891: s = NEXT(t);
1892: FREENM(t);
1893: t = s;
1894: }
1895: FREEND(p);
1896: }
1897:
1898: void nd_append_red(unsigned int *d,int td,int i)
1899: {
1.13 noro 1900: RHist m,m0;
1.1 noro 1901: int h;
1902:
1.13 noro 1903: NEWRHist(m);
1.1 noro 1904: h = ndl_hash_value(td,d);
1.13 noro 1905: m->index = i;
1.14 noro 1906: TD(m) = td;
1907: ndl_copy(d,DL(m));
1.1 noro 1908: NEXT(m) = nd_red[h];
1909: nd_red[h] = m;
1910: }
1911:
1.5 noro 1912: unsigned int *dp_compute_bound(DP p)
1913: {
1914: unsigned int *d,*d1,*d2,*t;
1915: MP m;
1.7 noro 1916: int i,l;
1.5 noro 1917:
1918: if ( !p )
1919: return 0;
1920: d1 = (unsigned int *)ALLOCA(nd_nvar*sizeof(unsigned int));
1921: d2 = (unsigned int *)ALLOCA(nd_nvar*sizeof(unsigned int));
1922: m = BDY(p);
1.14 noro 1923: bcopy(DL(m)->d,d1,nd_nvar*sizeof(unsigned int));
1.5 noro 1924: for ( m = NEXT(BDY(p)); m; m = NEXT(m) ) {
1.14 noro 1925: d = DL(m)->d;
1.5 noro 1926: for ( i = 0; i < nd_nvar; i++ )
1927: d2[i] = d[i] > d1[i] ? d[i] : d1[i];
1928: t = d1; d1 = d2; d2 = t;
1929: }
1.13 noro 1930: l = (nd_nvar+31);
1.7 noro 1931: t = (unsigned int *)MALLOC_ATOMIC(l*sizeof(unsigned int));
1932: bzero(t,l*sizeof(unsigned int));
1.5 noro 1933: bcopy(d1,t,nd_nvar*sizeof(unsigned int));
1934: return t;
1935: }
1936:
1.1 noro 1937: unsigned int *nd_compute_bound(ND p)
1938: {
1939: unsigned int *d1,*d2,*t;
1.9 noro 1940: int i,l;
1.1 noro 1941: NM m;
1942:
1943: if ( !p )
1944: return 0;
1945: d1 = (unsigned int *)ALLOCA(nd_wpd*sizeof(unsigned int));
1946: d2 = (unsigned int *)ALLOCA(nd_wpd*sizeof(unsigned int));
1947: bcopy(HDL(p),d1,nd_wpd*sizeof(unsigned int));
1948: for ( m = NEXT(BDY(p)); m; m = NEXT(m) ) {
1.14 noro 1949: ndl_lcm(DL(m),d1,d2);
1.1 noro 1950: t = d1; d1 = d2; d2 = t;
1951: }
1.12 noro 1952: l = nd_nvar+31;
1.9 noro 1953: t = (unsigned int *)MALLOC_ATOMIC(l*sizeof(unsigned int));
1954: bzero(t,l*sizeof(unsigned int));
1.5 noro 1955: for ( i = 0; i < nd_nvar; i++ )
1956: t[i] = (d1[i/nd_epw]>>((nd_epw-(i%nd_epw)-1)*nd_bpe))&nd_mask0;
1.1 noro 1957: return t;
1958: }
1959:
1960: void nd_setup_parameters() {
1961: int i;
1962:
1963: nd_epw = (sizeof(unsigned int)*8)/nd_bpe;
1964: nd_wpd = nd_nvar/nd_epw+(nd_nvar%nd_epw?1:0);
1965: if ( nd_bpe < 32 ) {
1966: nd_mask0 = (1<<nd_bpe)-1;
1967: } else {
1968: nd_mask0 = 0xffffffff;
1969: }
1970: bzero(nd_mask,sizeof(nd_mask));
1971: nd_mask1 = 0;
1972: for ( i = 0; i < nd_epw; i++ ) {
1973: nd_mask[nd_epw-i-1] = (nd_mask0<<(i*nd_bpe));
1974: nd_mask1 |= (1<<(nd_bpe-1))<<(i*nd_bpe);
1975: }
1.13 noro 1976: nm_adv = sizeof(struct oNM)+(nd_wpd-1)*sizeof(unsigned int);
1.4 noro 1977: #if USE_NDV
1.3 noro 1978: nmv_adv = sizeof(struct oNMV)+(nd_wpd-1)*sizeof(unsigned int);
1.4 noro 1979: #endif
1.1 noro 1980: }
1981:
1982: ND_pairs nd_reconstruct(ND_pairs d)
1983: {
1.11 noro 1984: int i,obpe,oadv;
1.13 noro 1985: NM prev_nm_free_list;
1986: RHist mr0,mr;
1987: RHist r;
1.1 noro 1988: ND_pairs s0,s,t,prev_ndp_free_list;
1.15 noro 1989:
1.1 noro 1990: obpe = nd_bpe;
1.11 noro 1991: #if USE_NDV
1992: oadv = nmv_adv;
1993: #endif
1.5 noro 1994: if ( obpe < 4 )
1995: nd_bpe = 4;
1996: else if ( obpe < 6 )
1997: nd_bpe = 6;
1998: else if ( obpe < 8 )
1999: nd_bpe = 8;
2000: else if ( obpe < 16 )
2001: nd_bpe = 16;
2002: else if ( obpe < 32 )
2003: nd_bpe = 32;
2004: else
2005: error("nd_reconstruct : exponent too large");
2006:
1.1 noro 2007: nd_setup_parameters();
2008: prev_nm_free_list = _nm_free_list;
2009: prev_ndp_free_list = _ndp_free_list;
2010: _nm_free_list = 0;
2011: _ndp_free_list = 0;
1.13 noro 2012: for ( i = nd_psn-1; i >= 0; i-- ) {
1.4 noro 2013: #if USE_NDV
1.11 noro 2014: ndv_realloc(nd_ps[i],obpe,oadv);
2015: #else
2016: nd_realloc(nd_ps[i],obpe);
1.4 noro 2017: #endif
1.1 noro 2018: }
2019: s0 = 0;
2020: for ( t = d; t; t = NEXT(t) ) {
2021: NEXTND_pairs(s0,s);
2022: s->i1 = t->i1;
2023: s->i2 = t->i2;
1.14 noro 2024: TD(s) = TD(t);
2025: SG(s) = SG(t);
1.1 noro 2026: ndl_dup(obpe,t->lcm,s->lcm);
2027: }
1.6 noro 2028: for ( i = 0; i < REDTAB_LEN; i++ ) {
1.13 noro 2029: for ( mr0 = 0, r = nd_red[i]; r; r = NEXT(r) ) {
1.16 ! noro 2030: NEXTRHist(mr0,mr);
1.13 noro 2031: mr->index = r->index;
1.14 noro 2032: TD(mr) = TD(r);
2033: ndl_dup(obpe,DL(r),DL(mr));
1.6 noro 2034: }
2035: if ( mr0 ) NEXT(mr) = 0;
2036: nd_red[i] = mr0;
2037: }
1.11 noro 2038: for ( i = 0; i < nd_psn; i++ ) {
1.14 noro 2039: NEWRHist(r); TD(r) = TD(nd_psh[i]); ndl_dup(obpe,DL(nd_psh[i]),DL(r));
1.13 noro 2040: nd_psh[i] = r;
1.11 noro 2041: }
1.1 noro 2042: if ( s0 ) NEXT(s) = 0;
2043: prev_nm_free_list = 0;
2044: prev_ndp_free_list = 0;
1.4 noro 2045: #if USE_NDV
1.3 noro 2046: BDY(ndv_red) = (NMV)REALLOC(BDY(ndv_red),nmv_len*nmv_adv);
1.4 noro 2047: #endif
1.1 noro 2048: GC_gcollect();
2049: return s0;
2050: }
2051:
2052: void ndl_dup(int obpe,unsigned int *d,unsigned int *r)
2053: {
2054: int n,i,ei,oepw,cepw,cbpe;
2055:
2056: n = nd_nvar;
2057: oepw = (sizeof(unsigned int)*8)/obpe;
2058: cepw = nd_epw;
2059: cbpe = nd_bpe;
1.15 noro 2060: for ( i = 0; i < nd_wpd; i++ )
2061: r[i] = 0;
1.1 noro 2062: if ( is_rlex )
2063: for ( i = 0; i < n; i++ ) {
2064: ei = (d[(n-1-i)/oepw]>>((oepw-((n-1-i)%oepw)-1)*obpe))
2065: &((1<<obpe)-1);
2066: r[(n-1-i)/cepw] |= (ei<<((cepw-((n-1-i)%cepw)-1)*cbpe));
2067: }
2068: else
2069: for ( i = 0; i < n; i++ ) {
2070: ei = (d[i/oepw]>>((oepw-(i%oepw)-1)*obpe))
2071: &((1<<obpe)-1);
2072: r[i/cepw] |= (ei<<((cepw-(i%cepw)-1)*cbpe));
2073: }
2074: }
2075:
1.11 noro 2076: void nd_realloc(ND p,int obpe)
1.1 noro 2077: {
2078: NM m,mr,mr0;
2079:
1.11 noro 2080: if ( p ) {
2081: m = BDY(p);
1.1 noro 2082: for ( mr0 = 0; m; m = NEXT(m) ) {
2083: NEXTNM(mr0,mr);
1.14 noro 2084: CM(mr) = CM(m);
2085: TD(mr) = TD(m);
2086: ndl_dup(obpe,DL(m),DL(mr));
1.1 noro 2087: }
2088: NEXT(mr) = 0;
1.11 noro 2089: BDY(p) = mr0;
1.1 noro 2090: }
2091: }
1.3 noro 2092:
1.6 noro 2093: ND nd_copy(ND p)
2094: {
2095: NM m,mr,mr0;
2096: int c,n,s;
2097: ND r;
2098:
2099: if ( !p )
2100: return 0;
2101: else {
2102: s = sizeof(struct oNM)+(nd_wpd-1)*sizeof(unsigned int);
2103: for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
2104: NEXTNM(mr0,mr);
1.14 noro 2105: CM(mr) = CM(m);
2106: TD(mr) = TD(m);
2107: ndl_copy(DL(m),DL(mr));
1.6 noro 2108: }
2109: NEXT(mr) = 0;
2110: MKND(NV(p),mr0,r);
1.14 noro 2111: SG(r) = SG(p);
1.6 noro 2112: return r;
2113: }
2114: }
2115:
1.4 noro 2116: #if USE_NDV
1.16 ! noro 2117: int nd_sp(int mod,ND_pairs p,ND *rp)
1.11 noro 2118: {
2119: NM m;
2120: NDV p1,p2;
2121: ND t1,t2;
2122: unsigned int *lcm;
2123: int td;
2124:
2125: p1 = nd_ps[p->i1];
2126: p2 = nd_ps[p->i2];
2127: lcm = p->lcm;
1.14 noro 2128: td = TD(p);
1.11 noro 2129: NEWNM(m);
1.16 ! noro 2130: if ( mod ) CM(m) = HCM(p2);
! 2131: else CQ(m) = HCQ(p2);
! 2132: TD(m) = td-HTD(p1); ndl_sub(lcm,HDL(p1),DL(m));
1.14 noro 2133: if ( ndl_check_bound2(p->i1,DL(m)) )
1.11 noro 2134: return 0;
1.16 ! noro 2135: t1 = ndv_mul_nm_create(mod,p1,m);
! 2136: if ( mod )
! 2137: CM(m) = mod-HCM(p1);
! 2138: else
! 2139: chsgnq(HCQ(p1),&CQ(m));
! 2140: TD(m) = td-HTD(p2); ndl_sub(lcm,HDL(p2),DL(m));
1.14 noro 2141: if ( ndl_check_bound2(p->i2,DL(m)) ) {
1.11 noro 2142: nd_free(t1);
2143: return 0;
2144: }
1.16 ! noro 2145: ndv_mul_nm(mod,p2,m,ndv_red);
1.11 noro 2146: FREENM(m);
1.16 ! noro 2147: if ( mod )
! 2148: *rp = ndv_add(t1,ndv_red);
! 2149: else
! 2150: *rp = ndv_add_q(t1,ndv_red);
1.11 noro 2151: return 1;
2152: }
2153:
2154: void ndv_mul_c(NDV p,int mul)
2155: {
2156: NMV m;
2157: int c,c1,len,i;
2158:
2159: if ( !p )
2160: return;
1.14 noro 2161: len = LEN(p);
1.11 noro 2162: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
1.14 noro 2163: c1 = CM(m);
1.11 noro 2164: DMAR(c1,mul,0,nd_mod,c);
1.14 noro 2165: CM(m) = c;
1.11 noro 2166: }
2167: }
2168:
1.16 ! noro 2169: void ndv_mul_c_q(NDV p,Q mul)
! 2170: {
! 2171: NMV m;
! 2172: Q c;
! 2173: int len,i;
! 2174:
! 2175: if ( !p )
! 2176: return;
! 2177: len = LEN(p);
! 2178: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
! 2179: mulq(CQ(m),mul,&c); CQ(m) = c;
! 2180: }
! 2181: }
! 2182:
! 2183: void ndv_mul_nm(int mod,NDV p,NM m0,NDV r)
1.4 noro 2184: {
2185: NMV m,mr,mr0;
2186: unsigned int *d,*dt,*dm;
2187: int c,n,td,i,c1,c2,len;
1.16 ! noro 2188: Q q;
1.4 noro 2189:
2190: if ( !p )
2191: /* XXX */
1.14 noro 2192: LEN(r) = 0;
1.4 noro 2193: else {
1.14 noro 2194: n = NV(p); m = BDY(p); len = LEN(p);
1.16 ! noro 2195: d = DL(m0); td = TD(m0);
1.4 noro 2196: mr = BDY(r);
1.16 ! noro 2197: if ( mod ) {
! 2198: c = CM(m0);
! 2199: for ( ; len > 0; len--, NMV_ADV(m), NMV_ADV(mr) ) {
! 2200: c1 = CM(m); DMAR(c1,c,0,nd_mod,c2); CM(mr) = c2;
! 2201: TD(mr) = TD(m)+td; ndl_add(DL(m),d,DL(mr));
! 2202: }
! 2203: } else {
! 2204: q = CQ(m0);
! 2205: for ( ; len > 0; len--, NMV_ADV(m), NMV_ADV(mr) ) {
! 2206: mulq(CQ(m),q,&CQ(mr));
! 2207: TD(mr) = TD(m)+td; ndl_add(DL(m),d,DL(mr));
! 2208: }
1.9 noro 2209: }
2210: NV(r) = NV(p);
1.14 noro 2211: LEN(r) = LEN(p);
2212: SG(r) = SG(p) + td;
1.9 noro 2213: }
2214: }
2215:
1.16 ! noro 2216: ND ndv_mul_nm_create(int mod,NDV p,NM m0)
1.9 noro 2217: {
2218: NM mr,mr0;
2219: NMV m;
2220: unsigned int *d,*dt,*dm;
2221: int c,n,td,i,c1,c2,len;
1.16 ! noro 2222: Q q;
1.9 noro 2223: ND r;
2224:
2225: if ( !p )
2226: return 0;
2227: else {
2228: n = NV(p); m = BDY(p);
1.16 ! noro 2229: d = DL(m0); td = TD(m0);
1.14 noro 2230: len = LEN(p);
1.9 noro 2231: mr0 = 0;
1.16 ! noro 2232: if ( mod ) {
! 2233: c = CM(m0);
! 2234: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
! 2235: NEXTNM(mr0,mr);
! 2236: c1 = CM(m);
! 2237: DMAR(c1,c,0,nd_mod,c2);
! 2238: CM(mr) = c2;
! 2239: TD(mr) = TD(m)+td;
! 2240: ndl_add(DL(m),d,DL(mr));
! 2241: }
! 2242: } else {
! 2243: q = CQ(m0);
! 2244: for ( i = 0; i < len; i++, NMV_ADV(m) ) {
! 2245: NEXTNM(mr0,mr);
! 2246: mulq(CQ(m),q,&CQ(mr));
! 2247: TD(mr) = TD(m)+td;
! 2248: ndl_add(DL(m),d,DL(mr));
! 2249: }
1.4 noro 2250: }
1.9 noro 2251: NEXT(mr) = 0;
2252: MKND(NV(p),mr0,r);
1.14 noro 2253: SG(r) = SG(p) + td;
1.9 noro 2254: return r;
1.4 noro 2255: }
2256: }
2257:
2258: ND ndv_add(ND p1,NDV p2)
2259: {
1.9 noro 2260: register NM prev,cur,new;
1.4 noro 2261: int c,c1,c2,t,td,td2,mul,len,i;
1.9 noro 2262: NM head;
1.4 noro 2263: unsigned int *d;
2264: NMV m2;
1.16 ! noro 2265: Q q;
1.4 noro 2266:
2267: if ( !p1 )
2268: return 0;
2269: else {
2270: prev = 0; head = cur = BDY(p1);
1.14 noro 2271: NEWNM(new); len = LEN(p2);
1.9 noro 2272: for ( m2 = BDY(p2), i = 0; cur && i < len; ) {
1.14 noro 2273: td2 = TD(new) = TD(m2);
2274: if ( TD(cur) > td2 ) {
1.13 noro 2275: prev = cur; cur = NEXT(cur);
2276: continue;
1.14 noro 2277: } else if ( TD(cur) < td2 ) c = -1;
1.13 noro 2278: else if ( nd_wpd == 1 ) {
1.14 noro 2279: if ( DL(cur)[0] > DL(m2)[0] ) c = is_rlex ? -1 : 1;
2280: else if ( DL(cur)[0] < DL(m2)[0] ) c = is_rlex ? 1 : -1;
1.13 noro 2281: else c = 0;
2282: }
1.14 noro 2283: else c = ndl_compare(DL(cur),DL(m2));
1.4 noro 2284: switch ( c ) {
2285: case 0:
1.14 noro 2286: t = CM(m2)+CM(cur)-nd_mod;
1.9 noro 2287: if ( t < 0 ) t += nd_mod;
1.14 noro 2288: if ( t ) CM(cur) = t;
1.4 noro 2289: else if ( !prev ) {
1.9 noro 2290: head = NEXT(cur); FREENM(cur); cur = head;
1.4 noro 2291: } else {
1.9 noro 2292: NEXT(prev) = NEXT(cur); FREENM(cur); cur = NEXT(prev);
1.4 noro 2293: }
2294: NMV_ADV(m2); i++;
2295: break;
2296: case 1:
1.9 noro 2297: prev = cur; cur = NEXT(cur);
1.4 noro 2298: break;
2299: case -1:
1.14 noro 2300: ndl_copy(DL(m2),DL(new));
1.16 ! noro 2301: CQ(new) = CQ(m2);
! 2302: if ( !prev ) {
! 2303: /* cur = head */
! 2304: prev = new; NEXT(prev) = head; head = prev;
! 2305: } else {
! 2306: NEXT(prev) = new; NEXT(new) = cur; prev = new;
! 2307: }
! 2308: NEWNM(new); NMV_ADV(m2); i++;
! 2309: break;
! 2310: }
! 2311: }
! 2312: for ( ; i < len; i++, NMV_ADV(m2) ) {
! 2313: td2 = TD(new) = TD(m2); CQ(new) = CQ(m2); ndl_copy(DL(m2),DL(new));
! 2314: if ( !prev ) {
! 2315: prev = new; NEXT(prev) = 0; head = prev;
! 2316: } else {
! 2317: NEXT(prev) = new; NEXT(new) = 0; prev = new;
! 2318: }
! 2319: NEWNM(new);
! 2320: }
! 2321: FREENM(new);
! 2322: if ( head ) {
! 2323: BDY(p1) = head; SG(p1) = MAX(SG(p1),SG(p2));
! 2324: return p1;
! 2325: } else {
! 2326: FREEND(p1);
! 2327: return 0;
! 2328: }
! 2329:
! 2330: }
! 2331: }
! 2332:
! 2333: ND ndv_add_q(ND p1,NDV p2)
! 2334: {
! 2335: register NM prev,cur,new;
! 2336: int c,c1,c2,t,td,td2,mul,len,i;
! 2337: NM head;
! 2338: unsigned int *d;
! 2339: NMV m2;
! 2340: Q q;
! 2341:
! 2342: if ( !p1 )
! 2343: return 0;
! 2344: else {
! 2345: prev = 0; head = cur = BDY(p1);
! 2346: NEWNM(new); len = LEN(p2);
! 2347: for ( m2 = BDY(p2), i = 0; cur && i < len; ) {
! 2348: td2 = TD(new) = TD(m2);
! 2349: if ( TD(cur) > td2 ) {
! 2350: prev = cur; cur = NEXT(cur);
! 2351: continue;
! 2352: } else if ( TD(cur) < td2 ) c = -1;
! 2353: else if ( nd_wpd == 1 ) {
! 2354: if ( DL(cur)[0] > DL(m2)[0] ) c = is_rlex ? -1 : 1;
! 2355: else if ( DL(cur)[0] < DL(m2)[0] ) c = is_rlex ? 1 : -1;
! 2356: else c = 0;
! 2357: }
! 2358: else c = ndl_compare(DL(cur),DL(m2));
! 2359: switch ( c ) {
! 2360: case 0:
! 2361: addq(CQ(cur),CQ(m2),&q);
! 2362: if ( q )
! 2363: CQ(cur) = q;
! 2364: else if ( !prev ) {
! 2365: head = NEXT(cur); FREENM(cur); cur = head;
! 2366: } else {
! 2367: NEXT(prev) = NEXT(cur); FREENM(cur); cur = NEXT(prev);
! 2368: }
! 2369: NMV_ADV(m2); i++;
! 2370: break;
! 2371: case 1:
! 2372: prev = cur; cur = NEXT(cur);
! 2373: break;
! 2374: case -1:
! 2375: ndl_copy(DL(m2),DL(new));
! 2376: CQ(new) = CQ(m2);
1.4 noro 2377: if ( !prev ) {
2378: /* cur = head */
1.9 noro 2379: prev = new; NEXT(prev) = head; head = prev;
1.4 noro 2380: } else {
1.9 noro 2381: NEXT(prev) = new; NEXT(new) = cur; prev = new;
1.4 noro 2382: }
1.9 noro 2383: NEWNM(new); NMV_ADV(m2); i++;
1.4 noro 2384: break;
2385: }
2386: }
1.9 noro 2387: for ( ; i < len; i++, NMV_ADV(m2) ) {
1.16 ! noro 2388: td2 = TD(new) = TD(m2); CQ(new) = CQ(m2); ndl_copy(DL(m2),DL(new));
1.9 noro 2389: if ( !prev ) {
2390: prev = new; NEXT(prev) = 0; head = prev;
2391: } else {
2392: NEXT(prev) = new; NEXT(new) = 0; prev = new;
2393: }
2394: NEWNM(new);
2395: }
1.4 noro 2396: FREENM(new);
2397: if ( head ) {
1.14 noro 2398: BDY(p1) = head; SG(p1) = MAX(SG(p1),SG(p2));
1.4 noro 2399: return p1;
2400: } else {
2401: FREEND(p1);
2402: return 0;
2403: }
2404:
2405: }
2406: }
2407:
1.11 noro 2408: void ndv_realloc(NDV p,int obpe,int oadv)
2409: {
1.13 noro 2410: NMV m,mr,mr0,t;
2411: int len,i,k;
1.11 noro 2412:
1.13 noro 2413: #define NMV_OPREV(m) (m = (NMV)(((char *)m)-oadv))
2414: #define NMV_PREV(m) (m = (NMV)(((char *)m)-nmv_adv))
1.11 noro 2415:
2416: if ( p ) {
1.14 noro 2417: m = BDY(p); len = LEN(p);
1.15 noro 2418: if ( nmv_adv > oadv )
2419: mr0 = (NMV)REALLOC(BDY(p),len*nmv_adv);
2420: else
2421: mr0 = BDY(p);
1.13 noro 2422: m = (NMV)((char *)mr0+(len-1)*oadv);
2423: mr = (NMV)((char *)mr0+(len-1)*nmv_adv);
2424: t = (NMV)ALLOCA(nmv_adv);
2425: for ( i = 0; i < len; i++, NMV_OPREV(m), NMV_PREV(mr) ) {
1.16 ! noro 2426: CQ(t) = CQ(m);
1.14 noro 2427: TD(t) = TD(m);
2428: for ( k = 0; k < nd_wpd; k++ ) DL(t)[k] = 0;
2429: ndl_dup(obpe,DL(m),DL(t));
1.16 ! noro 2430: CQ(mr) = CQ(t);
1.14 noro 2431: TD(mr) = TD(t);
2432: ndl_copy(DL(t),DL(mr));
1.11 noro 2433: }
2434: BDY(p) = mr0;
2435: }
2436: }
2437:
1.16 ! noro 2438: NDV ndtondv(int mod,ND p)
1.3 noro 2439: {
2440: NDV d;
2441: NMV m,m0;
2442: NM t;
2443: int i,len;
2444:
2445: if ( !p )
2446: return 0;
2447: len = nd_length(p);
1.16 ! noro 2448: if ( mod )
! 2449: m0 = m = (NMV)MALLOC_ATOMIC(len*nmv_adv);
! 2450: else
! 2451: m0 = m = (NMV)MALLOC(len*nmv_adv);
1.3 noro 2452: for ( t = BDY(p), i = 0; t; t = NEXT(t), i++, NMV_ADV(m) ) {
1.14 noro 2453: TD(m) = TD(t);
2454: ndl_copy(DL(t),DL(m));
1.16 ! noro 2455: CQ(m) = CQ(t);
1.3 noro 2456: }
2457: MKNDV(NV(p),m0,len,d);
1.14 noro 2458: SG(d) = SG(p);
1.3 noro 2459: return d;
2460: }
2461:
1.16 ! noro 2462: NDV dptondv(int mod,DP p)
1.11 noro 2463: {
2464: NDV d;
2465: NMV m0,m;
2466: MP t;
2467: int l,i,n;
2468:
2469: if ( !p )
2470: return 0;
2471: for ( t = BDY(p), l = 0; t; t = NEXT(t), l++ );
1.16 ! noro 2472: if ( mod )
! 2473: m0 = m = (NMV)MALLOC_ATOMIC(l*nmv_adv);
! 2474: else
! 2475: m0 = m = (NMV)MALLOC(l*nmv_adv);
1.11 noro 2476: n = NV(p);
1.16 ! noro 2477: if ( mod ) {
! 2478: for ( t = BDY(p), i = 0; i < l; i++, t = NEXT(t), NMV_ADV(m) ) {
! 2479: CM(m) = ITOS(C(t));
! 2480: TD(m) = TD(DL(t));
! 2481: dltondl(n,DL(t),DL(m));
! 2482: }
! 2483: } else {
! 2484: for ( t = BDY(p), i = 0; i < l; i++, t = NEXT(t), NMV_ADV(m) ) {
! 2485: CQ(m) = (Q)C(t);
! 2486: TD(m) = TD(DL(t));
! 2487: dltondl(n,DL(t),DL(m));
! 2488: }
1.11 noro 2489: }
2490: MKNDV(n,m0,l,d);
1.14 noro 2491: SG(d) = SG(p);
1.11 noro 2492: return d;
2493: }
2494:
1.16 ! noro 2495: DP ndvtodp(int mod,NDV p)
1.11 noro 2496: {
2497: DP d;
2498: MP m0,m;
2499: NMV t;
2500: int len,i,n;
2501:
2502: if ( !p )
2503: return 0;
2504: m0 = 0;
1.14 noro 2505: len = LEN(p);
1.11 noro 2506: n = NV(p);
1.16 ! noro 2507: if ( mod ) {
! 2508: for ( t = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) {
! 2509: NEXTMP(m0,m);
! 2510: C(m) = STOI(CM(t));
! 2511: DL(m) = ndltodl(n,TD(t),DL(t));
! 2512: }
! 2513: } else {
! 2514: for ( t = BDY(p), i = 0; i < len; i++, NMV_ADV(t) ) {
! 2515: NEXTMP(m0,m);
! 2516: C(m) = (P)CQ(t);
! 2517: DL(m) = ndltodl(n,TD(t),DL(t));
! 2518: }
1.11 noro 2519: }
2520: NEXT(m) = 0;
2521: MKDP(NV(p),m0,d);
1.14 noro 2522: SG(d) = SG(p);
1.11 noro 2523: return d;
2524: }
2525:
1.3 noro 2526: void ndv_print(NDV p)
2527: {
2528: NMV m;
2529: int i,len;
2530:
2531: if ( !p )
2532: printf("0\n");
2533: else {
1.14 noro 2534: len = LEN(p);
1.3 noro 2535: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
1.14 noro 2536: printf("+%d*",CM(m));
1.16 ! noro 2537: ndl_print(DL(m));
! 2538: }
! 2539: printf("\n");
! 2540: }
! 2541: }
! 2542:
! 2543: void ndv_print_q(NDV p)
! 2544: {
! 2545: NMV m;
! 2546: int i,len;
! 2547:
! 2548: if ( !p )
! 2549: printf("0\n");
! 2550: else {
! 2551: len = LEN(p);
! 2552: for ( m = BDY(p), i = 0; i < len; i++, NMV_ADV(m) ) {
! 2553: printf("+");
! 2554: printexpr(CO,CQ(m));
! 2555: printf("*");
1.14 noro 2556: ndl_print(DL(m));
1.3 noro 2557: }
2558: printf("\n");
2559: }
1.11 noro 2560: }
2561: #else
2562: int nd_sp(ND_pairs p,ND *rp)
2563: {
2564: NM m;
2565: ND p1,p2;
2566: ND t1,t2;
2567: unsigned int *lcm;
2568: int td;
2569:
2570: p1 = nd_ps[p->i1];
2571: p2 = nd_ps[p->i2];
2572: lcm = p->lcm;
1.14 noro 2573: td = TD(p);
1.11 noro 2574: NEWNM(m);
1.14 noro 2575: CM(m) = HCM(p2); TD(m) = td-HTD(p1); ndl_sub(lcm,HDL(p1),DL(m));
2576: if ( ndl_check_bound2(p->i1,DL(m)) )
1.11 noro 2577: return 0;
2578: t1 = nd_mul_ind_nm(p->i1,m);
1.14 noro 2579: CM(m) = nd_mod-HCM(p1); TD(m) = td-HTD(p2); ndl_sub(lcm,HDL(p2),DL(m));
2580: if ( ndl_check_bound2(p->i2,DL(m)) ) {
1.11 noro 2581: nd_free(t1);
2582: return 0;
2583: }
2584: t2 = nd_mul_ind_nm(p->i2,m);
2585: FREENM(m);
2586: *rp = nd_add(t1,t2);
2587: return 1;
2588: }
2589:
2590: ND nd_mul_nm(ND p,NM m0)
2591: {
2592: NM m,mr,mr0;
2593: unsigned int *d,*dt,*dm;
2594: int c,n,td,i,c1,c2;
2595: int *pt,*p1,*p2;
2596: ND r;
2597:
2598: if ( !p )
2599: return 0;
2600: else {
2601: n = NV(p); m = BDY(p);
1.14 noro 2602: d = DL(m0); td = TD(m0); c = CM(m0);
1.11 noro 2603: mr0 = 0;
2604: for ( ; m; m = NEXT(m) ) {
2605: NEXTNM(mr0,mr);
1.14 noro 2606: c1 = CM(m);
1.11 noro 2607: DMAR(c1,c,0,nd_mod,c2);
1.14 noro 2608: CM(mr) = c2;
2609: TD(mr) = TD(m)+td;
2610: ndl_add(DL(m),d,DL(mr));
1.11 noro 2611: }
2612: NEXT(mr) = 0;
2613: MKND(NV(p),mr0,r);
1.14 noro 2614: SG(r) = SG(p) + td;
1.11 noro 2615: return r;
2616: }
2617: }
2618:
2619: ND nd_mul_ind_nm(int index,NM m0)
2620: {
2621: register int c1,c2,c;
2622: register NM m,new,prev;
2623: NM mr0;
2624: unsigned int *d;
2625: int n,td,i,len,d0,d1;
2626: ND p,r;
2627:
2628: p = nd_ps[index];
2629: len = nd_psl[index];
2630: n = NV(p); m = BDY(p);
1.14 noro 2631: d = DL(m0); td = TD(m0); c = CM(m0);
1.11 noro 2632:
2633: NEWNM(mr0);
1.14 noro 2634: c1 = CM(m); DMAR(c1,c,0,nd_mod,c2); CM(mr0) = c2;
2635: TD(mr0) = TD(m)+td; ndl_add(DL(m),d,DL(mr0));
1.11 noro 2636: prev = mr0; m = NEXT(m);
2637: len--;
2638:
2639: switch ( nd_wpd ) {
2640: case 1:
2641: d0 = d[0];
2642: while ( len-- ) {
1.14 noro 2643: c1 = CM(m); DMAR(c1,c,0,nd_mod,c2);
2644: NEWNM(new); CM(new) = c2;
2645: TD(new) = TD(m)+td; DL(new)[0] = DL(m)[0]+d0;
1.11 noro 2646: m = NEXT(m); NEXT(prev) = new; prev = new;
2647: }
2648: break;
2649: case 2:
2650: d0 = d[0]; d1 = d[1];
2651: while ( len-- ) {
1.14 noro 2652: c1 = CM(m); DMAR(c1,c,0,nd_mod,c2);
2653: NEWNM(new); CM(new) = c2;
2654: TD(new) = TD(m)+td;
2655: DL(new)[0] = DL(m)[0]+d0;
2656: DL(new)[1] = DL(m)[1]+d1;
1.11 noro 2657: m = NEXT(m); NEXT(prev) = new; prev = new;
2658: }
2659: break;
2660: default:
2661: while ( len-- ) {
1.14 noro 2662: c1 = CM(m); DMAR(c1,c,0,nd_mod,c2);
2663: NEWNM(new); CM(new) = c2;
2664: TD(new) = TD(m)+td; ndl_add(DL(m),d,DL(new));
1.11 noro 2665: m = NEXT(m); NEXT(prev) = new; prev = new;
2666: }
2667: break;
2668: }
2669:
2670: NEXT(prev) = 0;
2671: MKND(NV(p),mr0,r);
1.14 noro 2672: SG(r) = SG(p) + td;
1.11 noro 2673: return r;
1.3 noro 2674: }
1.4 noro 2675: #endif
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>