Annotation of OpenXM_contrib2/asir2000/engine/_distm.c, Revision 1.8
1.2 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
1.3 noro 26: * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.2 noro 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: *
1.8 ! noro 48: * $OpenXM: OpenXM_contrib2/asir2000/engine/_distm.c,v 1.7 2001/01/11 02:26:49 noro Exp $
1.2 noro 49: */
1.1 noro 50: #include "ca.h"
51: #include "inline.h"
52:
53: extern int (*cmpdl)();
54: extern int do_weyl;
55:
1.5 noro 56: void dpto_dp();
1.1 noro 57: void _dptodp();
1.5 noro 58: void _adddl_dup();
1.4 noro 59: void adddl_destructive();
1.1 noro 60: void _mulmdm_dup();
61: void _free_dp();
62: void _comm_mulmd_dup();
63: void _weyl_mulmd_dup();
64: void _weyl_mulmmm_dup();
65: void _weyl_mulmdm_dup();
1.4 noro 66: void _comm_mulmd_tab();
67: void _comm_mulmd_tab_destructive();
1.1 noro 68:
69: MP _mp_free_list;
70: DP _dp_free_list;
71: DL _dl_free_list;
72: int current_dl_length;
1.6 noro 73:
74: void _free_private_storage()
75: {
76: _mp_free_list = 0;
77: _dp_free_list = 0;
78: _dl_free_list = 0;
79: GC_gcollect();
80: }
1.1 noro 81:
82: void _DL_alloc()
83: {
84: int *p;
85: int i,dl_len;
86: static int DL_alloc_count;
87:
88: /* fprintf(stderr,"DL_alloc : %d \n",++DL_alloc_count); */
89: dl_len = (current_dl_length+1);
1.8 ! noro 90: #if defined(LONG_IS_64BIT)
! 91: if ( dl_len & 1 )
! 92: dl_len += 1;
! 93: #endif
1.1 noro 94: p = (int *)GC_malloc(128*dl_len*sizeof(int));
95: for ( i = 0; i < 128; i++, p += dl_len ) {
96: *(DL *)p = _dl_free_list;
97: _dl_free_list = (DL)p;
98: }
99: }
100:
101: void _MP_alloc()
102: {
103: MP p;
104: int i;
105: static int MP_alloc_count;
106:
107: /* fprintf(stderr,"MP_alloc : %d \n",++MP_alloc_count); */
108: p = (MP)GC_malloc(1024*sizeof(struct oMP));
109: for ( i = 0; i < 1024; i++ ) {
110: p[i].next = _mp_free_list; _mp_free_list = &p[i];
111: }
112: }
113:
114: void _DP_alloc()
115: {
116: DP p;
117: int i;
118: static int DP_alloc_count;
119:
120: /* fprintf(stderr,"DP_alloc : %d \n",++DP_alloc_count); */
121: p = (DP)GC_malloc(1024*sizeof(struct oDP));
122: for ( i = 0; i < 1024; i++ ) {
123: p[i].body = (MP)_dp_free_list; _dp_free_list = &p[i];
124: }
125: }
126:
127: /* merge p1 and p2 into pr */
128:
129: void _addmd_destructive(mod,p1,p2,pr)
130: int mod;
131: DP p1,p2,*pr;
132: {
133: int n;
134: MP m1,m2,mr,mr0,s;
135: int t;
136:
137: if ( !p1 )
138: *pr = p2;
139: else if ( !p2 )
140: *pr = p1;
141: else {
142: for ( n = NV(p1), m1 = BDY(p1), m2 = BDY(p2), mr0 = 0; m1 && m2; )
143: switch ( (*cmpdl)(n,m1->dl,m2->dl) ) {
144: case 0:
145: t = (ITOS(C(m1))+ITOS(C(m2))) - mod;
146: if ( t < 0 )
147: t += mod;
148: s = m1; m1 = NEXT(m1);
149: if ( t ) {
150: _NEXTMP2(mr0,mr,s); C(mr) = STOI(t);
151: } else {
1.5 noro 152: _FREEDL(s->dl); _FREEMP(s);
1.1 noro 153: }
1.5 noro 154: s = m2; m2 = NEXT(m2); _FREEDL(s->dl); _FREEMP(s);
1.1 noro 155: break;
156: case 1:
157: s = m1; m1 = NEXT(m1); _NEXTMP2(mr0,mr,s);
158: break;
159: case -1:
160: s = m2; m2 = NEXT(m2); _NEXTMP2(mr0,mr,s);
161: break;
162: }
163: if ( !mr0 )
164: if ( m1 )
165: mr0 = m1;
166: else if ( m2 )
167: mr0 = m2;
168: else {
169: *pr = 0;
170: return;
171: }
172: else if ( m1 )
173: NEXT(mr) = m1;
174: else if ( m2 )
175: NEXT(mr) = m2;
176: else
177: NEXT(mr) = 0;
178: _MKDP(NV(p1),mr0,*pr);
179: if ( *pr )
180: (*pr)->sugar = MAX(p1->sugar,p2->sugar);
1.5 noro 181: _FREEDP(p1); _FREEDP(p2);
1.1 noro 182: }
183: }
184:
185: void _mulmd_dup(mod,p1,p2,pr)
186: int mod;
187: DP p1,p2,*pr;
188: {
189: if ( !do_weyl )
190: _comm_mulmd_dup(mod,p1,p2,pr);
191: else
192: _weyl_mulmd_dup(mod,p1,p2,pr);
193: }
194:
195: void _comm_mulmd_dup(mod,p1,p2,pr)
196: int mod;
197: DP p1,p2,*pr;
198: {
199: MP m;
200: DP s,t,u;
201: int i,l,l1;
202: static MP *w;
203: static int wlen;
204:
205: if ( !p1 || !p2 )
206: *pr = 0;
207: else {
208: for ( m = BDY(p1), l1 = 0; m; m = NEXT(m), l1++ );
209: for ( m = BDY(p2), l = 0; m; m = NEXT(m), l++ );
210: if ( l1 < l ) {
211: t = p1; p1 = p2; p2 = t;
212: l = l1;
213: }
214: if ( l > wlen ) {
215: if ( w ) GC_free(w);
216: w = (MP *)MALLOC(l*sizeof(MP));
217: wlen = l;
218: }
219: for ( m = BDY(p2), i = 0; i < l; m = NEXT(m), i++ )
220: w[i] = m;
221: for ( s = 0, i = l-1; i >= 0; i-- ) {
222: _mulmdm_dup(mod,p1,w[i],&t); _addmd_destructive(mod,s,t,&u); s = u;
223: }
224: bzero(w,l*sizeof(MP));
225: *pr = s;
226: }
227: }
228:
229: void _weyl_mulmd_dup(mod,p1,p2,pr)
230: int mod;
231: DP p1,p2,*pr;
232: {
233: MP m;
234: DP s,t,u;
235: int i,l,l1;
236: static MP *w;
237: static int wlen;
238:
239: if ( !p1 || !p2 )
240: *pr = 0;
241: else {
1.4 noro 242: for ( m = BDY(p1), l = 0; m; m = NEXT(m), l++ );
1.1 noro 243: if ( l > wlen ) {
244: if ( w ) GC_free(w);
245: w = (MP *)MALLOC(l*sizeof(MP));
246: wlen = l;
247: }
1.4 noro 248: for ( m = BDY(p1), i = 0; i < l; m = NEXT(m), i++ )
1.1 noro 249: w[i] = m;
250: for ( s = 0, i = l-1; i >= 0; i-- ) {
1.4 noro 251: _weyl_mulmdm_dup(mod,w[i],p2,&t); _addmd_destructive(mod,s,t,&u); s = u;
1.1 noro 252: }
253: bzero(w,l*sizeof(MP));
254: *pr = s;
255: }
256: }
257:
258: void _mulmdm_dup(mod,p,m0,pr)
259: int mod;
260: DP p;
261: MP m0;
262: DP *pr;
263: {
264: MP m,mr,mr0;
265: DL d,dt,dm;
266: int c,n,r,i;
267: int *pt,*p1,*p2;
268:
269: if ( !p )
270: *pr = 0;
271: else {
272: for ( mr0 = 0, m = BDY(p), c = ITOS(C(m0)), d = m0->dl, n = NV(p);
273: m; m = NEXT(m) ) {
274: _NEXTMP(mr0,mr);
275: C(mr) = STOI(dmar(ITOS(C(m)),c,0,mod));
276: _NEWDL_NOINIT(dt,n); mr->dl = dt;
277: dm = m->dl;
278: dt->td = d->td + dm->td;
279: for ( i = 0, pt = dt->d, p1=d->d, p2 = dm->d; i < n; i++ )
280: *pt++ = *p1++ + *p2++;
281: }
282: NEXT(mr) = 0; _MKDP(NV(p),mr0,*pr);
283: if ( *pr )
284: (*pr)->sugar = p->sugar + m0->dl->td;
285: }
286: }
287:
1.4 noro 288: void _weyl_mulmmm_dup_bug();
289:
290: void _weyl_mulmdm_dup(mod,m0,p,pr)
1.1 noro 291: int mod;
1.4 noro 292: MP m0;
1.1 noro 293: DP p;
294: DP *pr;
295: {
296: DP r,t,t1;
297: MP m;
1.4 noro 298: DL d0;
299: int n,n2,l,i,j,tlen;
300: static MP *w,*psum;
301: static struct cdlm *tab;
1.1 noro 302: static int wlen;
1.4 noro 303: static int rtlen;
1.1 noro 304:
305: if ( !p )
306: *pr = 0;
307: else {
308: for ( m = BDY(p), l = 0; m; m = NEXT(m), l++ );
309: if ( l > wlen ) {
310: if ( w ) GC_free(w);
311: w = (MP *)MALLOC(l*sizeof(MP));
312: wlen = l;
313: }
314: for ( m = BDY(p), i = 0; i < l; m = NEXT(m), i++ )
315: w[i] = m;
1.4 noro 316: n = NV(p); n2 = n>>1;
317: d0 = m0->dl;
318:
319: for ( i = 0, tlen = 1; i < n2; i++ )
320: tlen *= d0->d[n2+i]+1;
321: if ( tlen > rtlen ) {
322: if ( tab ) GC_free(tab);
323: if ( psum ) GC_free(psum);
324: rtlen = tlen;
325: tab = (struct cdlm *)MALLOC(rtlen*sizeof(struct cdlm));
326: psum = (MP *)MALLOC(rtlen*sizeof(MP));
1.1 noro 327: }
1.4 noro 328: bzero(psum,tlen*sizeof(MP));
329: for ( i = l-1; i >= 0; i-- ) {
330: bzero(tab,tlen*sizeof(struct cdlm));
331: _weyl_mulmmm_dup(mod,m0,w[i],n,tab,tlen);
332: for ( j = 0; j < tlen; j++ ) {
333: if ( tab[j].c ) {
334: _NEWMP(m); m->dl = tab[j].d;
335: C(m) = STOI(tab[j].c); NEXT(m) = psum[j];
336: psum[j] = m;
337: }
338: }
339: }
340: for ( j = tlen-1, r = 0; j >= 0; j-- )
341: if ( psum[j] ) {
342: _MKDP(n,psum[j],t); _addmd_destructive(mod,r,t,&t1); r = t1;
343: }
1.1 noro 344: if ( r )
345: r->sugar = p->sugar + m0->dl->td;
346: *pr = r;
347: }
348: }
1.4 noro 349:
1.1 noro 350: /* m0 = x0^d0*x1^d1*... * dx0^d(n/2)*dx1^d(n/2+1)*... */
351:
1.4 noro 352: void _weyl_mulmmm_dup(mod,m0,m1,n,rtab,rtablen)
1.1 noro 353: int mod;
354: MP m0,m1;
355: int n;
1.4 noro 356: struct cdlm *rtab;
357: int rtablen;
1.1 noro 358: {
359: MP m,mr,mr0;
360: DP r,t,t1;
361: int c,c0,c1,cc;
1.4 noro 362: DL d,d0,d1,dt;
363: int i,j,a,b,k,l,n2,s,min,h,curlen;
364: struct cdlm *p;
365: static int *ctab;
366: static struct cdlm *tab;
1.1 noro 367: static int tablen;
1.4 noro 368: static struct cdlm *tmptab;
369: static int tmptablen;
1.1 noro 370:
1.4 noro 371: if ( !m0 || !m1 ) {
372: rtab[0].c = 0;
373: rtab[0].d = 0;
374: return;
375: }
376: c0 = ITOS(C(m0)); c1 = ITOS(C(m1));
377: c = dmar(c0,c1,0,mod);
378: d0 = m0->dl; d1 = m1->dl;
379: n2 = n>>1;
380: curlen = 1;
381:
382: _NEWDL(d,n);
383: if ( n & 1 )
384: /* offset of h-degree */
385: d->td = d->d[n-1] = d0->d[n-1]+d1->d[n-1];
386: else
387: d->td = 0;
388: rtab[0].c = c;
389: rtab[0].d = d;
390:
391: if ( rtablen > tmptablen ) {
392: if ( tmptab ) GC_free(tmptab);
393: tmptab = (struct cdlm *)MALLOC(rtablen*sizeof(struct cdlm));
394: tmptablen = rtablen;
395: }
1.1 noro 396:
1.4 noro 397: for ( i = 0; i < n2; i++ ) {
398: a = d0->d[i]; b = d1->d[n2+i];
399: k = d0->d[n2+i]; l = d1->d[i];
400: if ( !k || !l ) {
401: a += l;
402: b += k;
403: s = a+b;
404: for ( j = 0, p = rtab; j < curlen; j++, p++ ) {
405: if ( p->c ) {
406: dt = p->d;
407: dt->d[i] = a;
408: dt->d[n2+i] = b;
409: dt->td += s;
410: }
411: }
412: curlen *= k+1;
413: continue;
414: }
415: if ( k+1 > tablen ) {
416: if ( tab ) GC_free(tab);
417: if ( ctab ) GC_free(ctab);
418: tablen = k+1;
419: tab = (struct cdlm *)MALLOC(tablen*sizeof(struct cdlm));
420: ctab = (int *)MALLOC(tablen*sizeof(int));
421: }
422: /* degree of xi^a*(Di^k*xi^l)*Di^b */
423: s = a+k+l+b;
424: /* compute xi^a*(Di^k*xi^l)*Di^b */
425: min = MIN(k,l);
426: mkwcm(k,l,mod,ctab);
427: bzero(tab,(k+1)*sizeof(struct cdlm));
428: /* n&1 != 0 => homogenized computation; dx-xd=h^2 */
1.1 noro 429: if ( n & 1 )
1.4 noro 430: for ( j = 0; j <= min; j++ ) {
431: _NEWDL(d,n);
432: d->d[i] = l-j+a; d->d[n2+i] = k-j+b;
433: d->td = s;
434: d->d[n-1] = s-(d->d[i]+d->d[n2+i]);
435: tab[j].d = d;
436: tab[j].c = ctab[j];
437: }
1.1 noro 438: else
1.4 noro 439: for ( j = 0; j <= min; j++ ) {
440: _NEWDL(d,n);
441: d->d[i] = l-j+a; d->d[n2+i] = k-j+b;
442: d->td = d->d[i]+d->d[n2+i]; /* XXX */
443: tab[j].d = d;
444: tab[j].c = ctab[j];
445: }
446: #if 0
447: _comm_mulmd_tab(mod,n,rtab,curlen,tab,k+1,tmptab);
448: for ( j = 0; j < curlen; j++ )
1.5 noro 449: if ( rtab[j].d ) { _FREEDL(rtab[j].d); }
1.4 noro 450: for ( j = 0; j <= min; j++ )
1.5 noro 451: if ( tab[j].d ) { _FREEDL(tab[j].d); }
1.4 noro 452: curlen *= k+1;
453: bcopy(tmptab,rtab,curlen*sizeof(struct cdlm));
454: #else
455: _comm_mulmd_tab_destructive(mod,n,rtab,curlen,tab,k+1);
456: for ( j = 0; j <= min; j++ )
1.5 noro 457: if ( tab[j].d ) { _FREEDL(tab[j].d); }
1.4 noro 458: curlen *= k+1;
459: #endif
460: }
461: }
462:
463: /* direct product of two cdlm tables
464: rt[] = [
465: t[0]*t1[0],...,t[n-1]*t1[0],
466: t[0]*t1[1],...,t[n-1]*t1[1],
467: ...
468: t[0]*t1[n1-1],...,t[n-1]*t1[n1-1]
469: ]
470: */
471:
472: void _comm_mulmd_tab(mod,nv,t,n,t1,n1,rt)
473: int mod;
474: int nv;
475: struct cdlm *t;
476: int n;
477: struct cdlm *t1;
478: int n1;
479: struct cdlm *rt;
480: {
481: int i,j;
482: struct cdlm *p;
483: int c;
484: DL d;
485:
486: bzero(rt,n*n1*sizeof(struct cdlm));
487: for ( j = 0, p = rt; j < n1; j++ ) {
488: c = t1[j].c;
489: d = t1[j].d;
490: if ( !c )
491: break;
492: for ( i = 0; i < n; i++, p++ ) {
493: if ( t[i].c ) {
494: p->c = dmar(t[i].c,c,0,mod);
1.5 noro 495: _adddl_dup(nv,t[i].d,d,&p->d);
1.4 noro 496: }
497: }
498: }
499: }
500:
501: void _comm_mulmd_tab_destructive(mod,nv,t,n,t1,n1)
502: int mod;
503: int nv;
504: struct cdlm *t;
505: int n;
506: struct cdlm *t1;
507: int n1;
508: {
509: int i,j;
510: struct cdlm *p;
511: int c;
512: DL d;
513:
514: for ( j = 1, p = t+n; j < n1; j++ ) {
515: c = t1[j].c;
516: d = t1[j].d;
517: if ( !c )
518: break;
519: for ( i = 0; i < n; i++, p++ ) {
520: if ( t[i].c ) {
521: p->c = dmar(t[i].c,c,0,mod);
1.5 noro 522: _adddl_dup(nv,t[i].d,d,&p->d);
1.1 noro 523: }
524: }
525: }
1.4 noro 526: c = t1[0].c;
527: d = t1[0].d;
528: for ( i = 0, p = t; i < n; i++, p++ )
529: if ( t[i].c ) {
530: p->c = dmar(t[i].c,c,0,mod);
531: /* t[i].d += d */
532: adddl_destructive(nv,t[i].d,d);
533: }
1.1 noro 534: }
535:
1.5 noro 536: void dlto_dl(d,dr)
537: DL d;
538: DL *dr;
1.1 noro 539: {
540: int i,n;
1.5 noro 541: DL t;
1.1 noro 542:
1.5 noro 543: n = current_dl_length;
544: _NEWDL(t,n); *dr = t;
545: t->td = d->td;
1.1 noro 546: for ( i = 0; i < n; i++ )
1.5 noro 547: t->d[i] = d->d[i];
1.1 noro 548: }
549:
550: void _dltodl(d,dr)
551: DL d;
552: DL *dr;
553: {
554: int i,n;
555: DL t;
556:
557: n = current_dl_length;
558: NEWDL(t,n); *dr = t;
559: t->td = d->td;
560: for ( i = 0; i < n; i++ )
561: t->d[i] = d->d[i];
562: }
563:
1.5 noro 564: void _adddl_dup(n,d1,d2,dr)
1.1 noro 565: int n;
566: DL d1,d2;
567: DL *dr;
568: {
569: DL dt;
570: int i;
571:
1.4 noro 572: _NEWDL(dt,n);
573: *dr = dt;
1.1 noro 574: dt->td = d1->td + d2->td;
575: for ( i = 0; i < n; i++ )
576: dt->d[i] = d1->d[i]+d2->d[i];
1.4 noro 577: }
578:
579: void _free_dlarray(a,n)
580: DL *a;
581: int n;
582: {
583: int i;
584:
1.5 noro 585: for ( i = 0; i < n; i++ ) { _FREEDL(a[i]); }
1.1 noro 586: }
587:
588: void _free_dp(f)
589: DP f;
590: {
591: MP m,s;
592:
593: if ( !f )
594: return;
595: m = f->body;
596: while ( m ) {
1.5 noro 597: s = m; m = NEXT(m); _FREEDL(s->dl); _FREEMP(s);
598: }
599: _FREEDP(f);
600: }
601:
602: void dpto_dp(p,r)
603: DP p;
604: DP *r;
605: {
606: MP m,mr0,mr;
1.7 noro 607: DL t;
1.5 noro 608:
609: if ( !p )
610: *r = 0;
611: else {
1.7 noro 612: /* XXX : dummy call to set current_dl_length */
613: _NEWDL_NOINIT(t,NV(p));
614:
1.5 noro 615: for ( m = BDY(p), mr0 = 0; m; m = NEXT(m) ) {
616: _NEXTMP(mr0,mr);
617: dlto_dl(m->dl,&mr->dl);
618: mr->c = m->c;
619: }
620: NEXT(mr) = 0;
621: _MKDP(p->nv,mr0,*r);
622: (*r)->sugar = p->sugar;
1.1 noro 623: }
624: }
625:
626: void _dptodp(p,r)
627: DP p;
628: DP *r;
629: {
630: MP m,mr0,mr;
631:
632: if ( !p )
633: *r = 0;
634: else {
635: for ( m = BDY(p), mr0 = 0; m; m = NEXT(m) ) {
636: NEXTMP(mr0,mr);
637: _dltodl(m->dl,&mr->dl);
638: mr->c = m->c;
639: }
640: NEXT(mr) = 0;
641: MKDP(p->nv,mr0,*r);
642: (*r)->sugar = p->sugar;
643: }
644: }
645:
1.5 noro 646: /*
647: * destructive merge of two list
648: *
649: * p1, p2 : list of DL
650: * return : a merged list
651: */
652:
653: NODE _symb_merge(m1,m2,n)
654: NODE m1,m2;
655: int n;
656: {
657: NODE top,prev,cur,m,t;
658:
659: if ( !m1 )
660: return m2;
661: else if ( !m2 )
662: return m1;
663: else {
664: switch ( (*cmpdl)(n,(DL)BDY(m1),(DL)BDY(m2)) ) {
665: case 0:
666: top = m1; _FREEDL((DL)BDY(m2)); m = NEXT(m2);
667: break;
668: case 1:
669: top = m1; m = m2;
670: break;
671: case -1:
672: top = m2; m = m1;
1.1 noro 673: break;
674: }
1.5 noro 675: prev = top; cur = NEXT(top);
676: /* BDY(prev) > BDY(m) always holds */
677: while ( cur && m ) {
678: switch ( (*cmpdl)(n,(DL)BDY(cur),(DL)BDY(m)) ) {
679: case 0:
680: _FREEDL(BDY(m)); m = NEXT(m);
681: prev = cur; cur = NEXT(cur);
682: break;
683: case 1:
684: t = NEXT(cur); NEXT(cur) = m; m = t;
685: prev = cur; cur = NEXT(cur);
686: break;
687: case -1:
688: NEXT(prev) = m; m = cur;
689: prev = NEXT(prev); cur = NEXT(prev);
690: break;
1.1 noro 691: }
692: }
1.5 noro 693: if ( !cur )
694: NEXT(prev) = m;
695: return top;
1.1 noro 696: }
697: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>