Annotation of OpenXM_contrib2/asir2000/parse/puref.c, Revision 1.1
1.1 ! noro 1: /* $OpenXM: OpenXM/src/asir99/parse/puref.c,v 1.1.1.1 1999/11/10 08:12:34 noro Exp $ */
! 2: #include "ca.h"
! 3: #include "parse.h"
! 4:
! 5: NODE pflist;
! 6:
! 7: void searchpf(name,fp)
! 8: char *name;
! 9: FUNC *fp;
! 10: {
! 11: NODE node;
! 12: PF pf;
! 13: FUNC t;
! 14:
! 15: for ( node = pflist; node; node = NEXT(node) )
! 16: if ( !strcmp(name,((PF)node->body)->name) ) {
! 17: pf = (PF)node->body;
! 18: *fp = t = (FUNC)MALLOC(sizeof(struct oFUNC));
! 19: t->name = name; t->id = A_PURE; t->argc = pf->argc;
! 20: t->f.puref = pf;
! 21: return;
! 22: }
! 23: *fp = 0;
! 24: }
! 25:
! 26: void searchc(name,fp)
! 27: char *name;
! 28: FUNC *fp;
! 29: {
! 30: NODE node;
! 31: PF pf;
! 32: FUNC t;
! 33:
! 34: for ( node = pflist; node; node = NEXT(node) )
! 35: if ( !strcmp(name,((PF)node->body)->name)
! 36: && !((PF)node->body)->argc ) {
! 37: pf = (PF)node->body;
! 38: *fp = t = (FUNC)MALLOC(sizeof(struct oFUNC));
! 39: t->name = name; t->id = A_PURE; t->argc = pf->argc;
! 40: t->f.puref = pf;
! 41: return;
! 42: }
! 43: *fp = 0;
! 44: }
! 45:
! 46: void mkpf(name,body,argc,args,parif,libmf,simp,pfp)
! 47: char *name;
! 48: Obj body;
! 49: int argc;
! 50: V *args;
! 51: int (*parif)(),(*simp)();
! 52: double (*libmf)();
! 53: PF *pfp;
! 54: {
! 55: PF pf;
! 56: NODE node;
! 57:
! 58: NEWPF(pf); pf->name = name; pf->body = body;
! 59: pf->argc = argc; pf->args = args; pf->pari = parif; pf->simplify = simp;
! 60: pf->libm = libmf;
! 61: for ( node = pflist; node; node = NEXT(node) )
! 62: if ( !strcmp(((PF)BDY(node))->name,name) )
! 63: break;
! 64: if ( !node ) {
! 65: NEWNODE(node); NEXT(node) = pflist; pflist = node;
! 66: /* fprintf(stderr,"%s() defined.\n",name); */
! 67: } else
! 68: fprintf(stderr,"%s() redefined.\n",name);
! 69: BDY(node) = (pointer)pf; *pfp = pf;
! 70: }
! 71:
! 72: /*
! 73: create an instance of a pure function. args are given
! 74: as an array of V. So we have to create a P object for
! 75: each arg.
! 76: */
! 77:
! 78: void mkpfins(pf,args,vp)
! 79: PF pf;
! 80: V *args;
! 81: V *vp;
! 82: {
! 83: V v;
! 84: PFINS ins;
! 85: PFAD ad;
! 86: int i;
! 87: P t;
! 88:
! 89: NEWV(v); NAME(v) = 0; v->attr = (pointer)V_PF;
! 90: ins = (PFINS)MALLOC(sizeof(PF)+pf->argc*sizeof(struct oPFAD));
! 91: bzero((char *)ins,(int)(sizeof(PF)+pf->argc*sizeof(struct oPFAD)));
! 92: ins->pf = pf;
! 93: v->priv = (pointer)ins;
! 94: for ( i = 0, ad = ins->ad; i < pf->argc; i++ ) {
! 95: ad[i].d = 0; MKV(args[i],t); ad[i].arg = (Obj)t;
! 96: }
! 97: appendpfins(v,vp);
! 98: }
! 99:
! 100: /* the same as above. Argements are given as an array of Obj */
! 101:
! 102: void _mkpfins(pf,args,vp)
! 103: PF pf;
! 104: Obj *args;
! 105: V *vp;
! 106: {
! 107: V v;
! 108: PFINS ins;
! 109: PFAD ad;
! 110: int i;
! 111:
! 112: NEWV(v); NAME(v) = 0; v->attr = (pointer)V_PF;
! 113: ins = (PFINS)MALLOC(sizeof(PF)+pf->argc*sizeof(struct oPFAD));
! 114: bzero((char *)ins,(int)(sizeof(PF)+pf->argc*sizeof(struct oPFAD)));
! 115: ins->pf = pf;
! 116: v->priv = (pointer)ins;
! 117: for ( i = 0, ad = ins->ad; i < pf->argc; i++ ) {
! 118: ad[i].d = 0; ad[i].arg = args[i];
! 119: }
! 120: appendpfins(v,vp);
! 121: }
! 122:
! 123: /* the same as above. darray is also given */
! 124:
! 125: void _mkpfins_with_darray(pf,args,darray,vp)
! 126: PF pf;
! 127: Obj *args;
! 128: int *darray;
! 129: V *vp;
! 130: {
! 131: V v;
! 132: PFINS ins;
! 133: PFAD ad;
! 134: int i;
! 135:
! 136: NEWV(v); NAME(v) = 0; v->attr = (pointer)V_PF;
! 137: ins = (PFINS)MALLOC(sizeof(PF)+pf->argc*sizeof(struct oPFAD));
! 138: bzero((char *)ins,(int)(sizeof(PF)+pf->argc*sizeof(struct oPFAD)));
! 139: ins->pf = pf;
! 140: v->priv = (pointer)ins;
! 141: for ( i = 0, ad = ins->ad; i < pf->argc; i++ ) {
! 142: ad[i].d = darray[i]; ad[i].arg = args[i];
! 143: }
! 144: appendpfins(v,vp);
! 145: }
! 146:
! 147: void appendpfins(v,vp)
! 148: V v;
! 149: V *vp;
! 150: {
! 151: PF fdef;
! 152: PFAD ad,tad;
! 153: NODE node;
! 154: int i;
! 155:
! 156: fdef = ((PFINS)v->priv)->pf; ad = ((PFINS)v->priv)->ad;
! 157: for ( node = fdef->ins; node; node = NEXT(node) ) {
! 158: for ( i = 0, tad = ((PFINS)((V)node->body)->priv)->ad;
! 159: i < fdef->argc; i++ )
! 160: if ( (ad[i].d != tad[i].d) || compr(CO,ad[i].arg,tad[i].arg) )
! 161: break;
! 162: if ( i == fdef->argc ) {
! 163: *vp = (V)node->body;
! 164: return;
! 165: }
! 166: }
! 167: NEWNODE(node); node->body = (pointer)v; NEXT(node) = fdef->ins;
! 168: fdef->ins = node; appendvar(CO,v); *vp = v;
! 169: }
! 170:
! 171: void duppfins(v,vp)
! 172: V v;
! 173: V *vp;
! 174: {
! 175: V tv;
! 176: PFINS tins;
! 177: int size;
! 178:
! 179: NEWV(tv); tv->name = v->name; tv->attr = v->attr;
! 180: size = sizeof(PF)+((PFINS)v->priv)->pf->argc*sizeof(struct oPFAD);
! 181: tins = (PFINS)MALLOC(size); bcopy((char *)v->priv,(char *)tins,size);
! 182: tv->priv = (pointer)tins;
! 183: *vp = tv;
! 184: }
! 185:
! 186: void derivvar(vl,pf,v,a)
! 187: VL vl;
! 188: V pf,v;
! 189: Obj *a;
! 190: {
! 191: Obj t,s,u,w,u1;
! 192: P p;
! 193: V tv,sv;
! 194: PF fdef;
! 195: PFAD ad;
! 196: int i,j;
! 197:
! 198: fdef = ((PFINS)pf->priv)->pf; ad = ((PFINS)pf->priv)->ad;
! 199: if ( fdef->deriv ) {
! 200: for ( t = 0, i = 0; i < fdef->argc; i++ ) {
! 201: derivr(vl,ad[i].arg,v,&s);
! 202: for ( j = 0, u = fdef->deriv[i]; j < fdef->argc; j++ ) {
! 203: substr(vl,0,u,fdef->args[j],ad[j].arg,&u1); u = u1;
! 204: }
! 205: mulr(vl,s,u,&w); addr(vl,t,w,&s); t = s;
! 206: }
! 207: *a = t;
! 208: } else {
! 209: for ( t = 0, i = 0; i < fdef->argc; i++ ) {
! 210: derivr(vl,ad[i].arg,v,&s);
! 211: duppfins(pf,&tv); (((PFINS)tv->priv)->ad)[i].d++;
! 212: appendpfins(tv,&sv);
! 213: MKV(sv,p); mulr(vl,s,(Obj)p,&w); addr(vl,t,w,&s); t = s;
! 214: }
! 215: *a = t;
! 216: }
! 217: }
! 218:
! 219: void derivr(vl,a,v,b)
! 220: VL vl;
! 221: V v;
! 222: Obj a,*b;
! 223: {
! 224: VL tvl,svl;
! 225: Obj r,s,t,u,nm,dn,dnm,ddn,m;
! 226:
! 227: if ( !a )
! 228: *b = 0;
! 229: else
! 230: switch ( OID(a) ) {
! 231: case O_N:
! 232: *b = 0; break;
! 233: case O_P:
! 234: clctvr(vl,a,&tvl);
! 235: for ( dnm = 0, svl = tvl; svl; svl = NEXT(svl) ) {
! 236: if ( svl->v == v ) {
! 237: pderivr(vl,a,v,&s); addr(vl,s,dnm,&u); dnm = u;
! 238: } else if ( (vid)svl->v->attr == V_PF ) {
! 239: pderivr(vl,a,svl->v,&s); derivvar(vl,svl->v,v,&r);
! 240: mulr(vl,s,r,&u); addr(vl,u,dnm,&s); dnm = s;
! 241: }
! 242: }
! 243: *b = (Obj)dnm; break;
! 244: case O_R:
! 245: clctvr(vl,a,&tvl);
! 246: nm = (Obj)NM((R)a); dn = (Obj)DN((R)a);
! 247: for ( dnm = ddn = 0, svl = tvl; svl; svl = NEXT(svl) ) {
! 248: if ( svl->v == v ) {
! 249: pderivr(vl,nm,v,&s); addr(vl,s,dnm,&u); dnm = u;
! 250: pderivr(vl,dn,v,&s); addr(vl,s,ddn,&u); ddn = u;
! 251: } else if ( (vid)svl->v->attr == V_PF ) {
! 252: pderivr(vl,nm,svl->v,&s); derivvar(vl,svl->v,v,&r);
! 253: mulr(vl,s,r,&u); addr(vl,u,dnm,&s); dnm = s;
! 254: pderivr(vl,dn,svl->v,&s); derivvar(vl,svl->v,v,&r);
! 255: mulr(vl,s,r,&u); addr(vl,u,ddn,&s); ddn = s;
! 256: }
! 257: }
! 258: mulr(vl,dnm,dn,&t); mulr(vl,ddn,nm,&s);
! 259: subr(vl,t,s,&u); reductr(vl,u,&t);
! 260: if ( !t )
! 261: *b = 0;
! 262: else {
! 263: mulp(vl,(P)dn,(P)dn,(P *)&m); divr(vl,t,m,b);
! 264: }
! 265: break;
! 266: }
! 267: }
! 268:
! 269: void substr(vl,partial,a,v,b,c)
! 270: VL vl;
! 271: int partial;
! 272: Obj a;
! 273: V v;
! 274: Obj b;
! 275: Obj *c;
! 276: {
! 277: Obj nm,dn,t;
! 278:
! 279: if ( !a )
! 280: *c = 0;
! 281: else {
! 282: switch ( OID(a) ) {
! 283: case O_N:
! 284: *c = a; break;
! 285: case O_P:
! 286: substpr(vl,partial,a,v,b,c); break;
! 287: case O_R:
! 288: substpr(vl,partial,(Obj)NM((R)a),v,b,&nm);
! 289: substpr(vl,partial,(Obj)DN((R)a),v,b,&dn);
! 290: divr(vl,nm,dn,&t); reductr(vl,t,c);
! 291: break;
! 292: default:
! 293: *c = 0; break;
! 294: }
! 295: }
! 296: }
! 297:
! 298: void substpr(vl,partial,p,v0,p0,pr)
! 299: VL vl;
! 300: int partial;
! 301: V v0;
! 302: Obj p;
! 303: Obj p0;
! 304: Obj *pr;
! 305: {
! 306: P x;
! 307: Obj t,m,c,s,a;
! 308: DCP dc;
! 309: Q d;
! 310: V v;
! 311: PF pf;
! 312: PFAD ad,tad;
! 313: PFINS tins;
! 314: int i;
! 315:
! 316: if ( !p )
! 317: *pr = 0;
! 318: else if ( NUM(p) )
! 319: *pr = (Obj)p;
! 320: else if ( (v = VR((P)p)) != v0 ) {
! 321: if ( !partial && ((vid)v->attr == V_PF) ) {
! 322: ad = ((PFINS)v->priv)->ad; pf = ((PFINS)v->priv)->pf;
! 323: tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));
! 324: tins->pf = pf;
! 325: for ( i = 0, tad = tins->ad; i < pf->argc; i++ ) {
! 326: tad[i].d = ad[i].d;
! 327: substr(vl,partial,ad[i].arg,v0,p0,&tad[i].arg);
! 328: }
! 329: simplify_ins(tins,(Obj *)&x);
! 330: } else
! 331: MKV(VR((P)p),x);
! 332: for ( c = 0, dc = DC((P)p); dc; dc = NEXT(dc) ) {
! 333: substpr(vl,partial,(Obj)COEF(dc),v0,p0,&t);
! 334: if ( DEG(dc) ) {
! 335: pwrp(vl,x,DEG(dc),(P *)&s); mulr(vl,s,t,&m);
! 336: addr(vl,m,c,&a); c = a;
! 337: } else {
! 338: addr(vl,t,c,&a); c = a;
! 339: }
! 340: }
! 341: *pr = c;
! 342: } else {
! 343: dc = DC((P)p);
! 344: if ( !partial )
! 345: substpr(vl,partial,(Obj)COEF(dc),v0,p0,&c);
! 346: else
! 347: c = (Obj)COEF(dc);
! 348: for ( d = DEG(dc), dc = NEXT(dc); dc; d = DEG(dc), dc = NEXT(dc) ) {
! 349: subq(d,DEG(dc),(Q *)&t); pwrr(vl,p0,t,&s); mulr(vl,s,c,&m);
! 350: if ( !partial )
! 351: substpr(vl,partial,(Obj)COEF(dc),v0,p0,&t);
! 352: else
! 353: t = (Obj)COEF(dc);
! 354: addr(vl,m,t,&c);
! 355: }
! 356: if ( d ) {
! 357: pwrr(vl,p0,(Obj)d,&t); mulr(vl,t,c,&m);
! 358: c = m;
! 359: }
! 360: *pr = c;
! 361: }
! 362: }
! 363:
! 364: void evalr(vl,a,prec,c)
! 365: VL vl;
! 366: Obj a;
! 367: int prec;
! 368: Obj *c;
! 369: {
! 370: Obj nm,dn;
! 371:
! 372: if ( !a )
! 373: *c = 0;
! 374: else {
! 375: switch ( OID(a) ) {
! 376: case O_N:
! 377: *c = a; break;
! 378: case O_P:
! 379: evalp(vl,(P)a,prec,(P *)c); break;
! 380: case O_R:
! 381: evalp(vl,NM((R)a),prec,(P *)&nm); evalp(vl,DN((R)a),prec,(P *)&dn);
! 382: divr(vl,nm,dn,c);
! 383: break;
! 384: default:
! 385: error("evalr : not implemented"); break;
! 386: }
! 387: }
! 388: }
! 389:
! 390: void evalp(vl,p,prec,pr)
! 391: VL vl;
! 392: P p;
! 393: int prec;
! 394: P *pr;
! 395: {
! 396: P t;
! 397: DCP dc,dcr0,dcr;
! 398: Obj u;
! 399:
! 400: if ( !p || NUM(p) )
! 401: *pr = p;
! 402: else {
! 403: for ( dcr0 = 0, dc = DC((P)p); dc; dc = NEXT(dc) ) {
! 404: evalp(vl,COEF(dc),prec,&t);
! 405: if ( t ) {
! 406: NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc); COEF(dcr) = t;
! 407: }
! 408: }
! 409: if ( !dcr0 ) {
! 410: *pr = 0; return;
! 411: } else {
! 412: NEXT(dcr) = 0; MKP(VR(p),dcr0,t);
! 413: }
! 414: if ( NUM(t) || (VR(t) != VR(p)) || ((vid)VR(p)->attr != V_PF) ) {
! 415: *pr = t; return;
! 416: } else {
! 417: evalv(vl,VR(p),prec,&u); substr(vl,1,(Obj)t,VR(p),u,(Obj *)pr);
! 418: }
! 419: }
! 420: }
! 421:
! 422: void evalv(vl,v,prec,rp)
! 423: VL vl;
! 424: V v;
! 425: int prec;
! 426: Obj *rp;
! 427: {
! 428: PFINS ins,tins;
! 429: PFAD ad,tad;
! 430: PF pf;
! 431: P t;
! 432: int i;
! 433:
! 434: if ( (vid)v->attr != V_PF ) {
! 435: MKV(v,t); *rp = (Obj)t;
! 436: } else {
! 437: ins = (PFINS)v->priv; ad = ins->ad; pf = ins->pf;
! 438: tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));
! 439: tins->pf = pf;
! 440: for ( i = 0, tad = tins->ad; i < pf->argc; i++ ) {
! 441: tad[i].d = ad[i].d; evalr(vl,ad[i].arg,prec,&tad[i].arg);
! 442: }
! 443: evalins(tins,prec,rp);
! 444: }
! 445: }
! 446:
! 447: void evalins(ins,prec,rp)
! 448: PFINS ins;
! 449: int prec;
! 450: Obj *rp;
! 451: {
! 452: PF pf;
! 453: PFAD ad;
! 454: int i;
! 455: Q q;
! 456: V v;
! 457: P x;
! 458: NODE n0,n;
! 459:
! 460: pf = ins->pf; ad = ins->ad;
! 461: for ( i = 0; i < pf->argc; i++ )
! 462: if ( ad[i].d || (ad[i].arg && !NUM(ad[i].arg)) )
! 463: break;
! 464: if ( (i != pf->argc) || !pf->pari ) {
! 465: instov(ins,&v); MKV(v,x); *rp = (Obj)x;
! 466: } else {
! 467: for ( n0 = 0, i = 0; i < pf->argc; i++ ) {
! 468: NEXTNODE(n0,n); BDY(n) = (pointer)ad[i].arg;
! 469: }
! 470: if ( prec ) {
! 471: NEXTNODE(n0,n); STOQ(prec,q); BDY(n) = (pointer)q;
! 472: }
! 473: if ( n0 )
! 474: NEXT(n) = 0;
! 475: (*pf->pari)(n0,rp);
! 476: }
! 477: }
! 478:
! 479: void devalins(PFINS,Obj *);
! 480: void devalv(VL,V,Obj *);
! 481: void devalp(VL,P,P *);
! 482: void devalr(VL,Obj,Obj *);
! 483:
! 484: void devalr(vl,a,c)
! 485: VL vl;
! 486: Obj a;
! 487: Obj *c;
! 488: {
! 489: Obj nm,dn;
! 490: double d;
! 491: Real r;
! 492:
! 493: if ( !a )
! 494: *c = 0;
! 495: else {
! 496: switch ( OID(a) ) {
! 497: case O_N:
! 498: d = ToReal(a);
! 499: MKReal(d,r);
! 500: *c = (Obj)r;
! 501: break;
! 502: case O_P:
! 503: devalp(vl,(P)a,(P *)c); break;
! 504: case O_R:
! 505: devalp(vl,NM((R)a),(P *)&nm);
! 506: devalp(vl,DN((R)a),(P *)&dn);
! 507: divr(vl,nm,dn,c);
! 508: break;
! 509: default:
! 510: error("devalr : not implemented"); break;
! 511: }
! 512: }
! 513: }
! 514:
! 515: void devalp(vl,p,pr)
! 516: VL vl;
! 517: P p;
! 518: P *pr;
! 519: {
! 520: P t;
! 521: DCP dc,dcr0,dcr;
! 522: Obj u,s;
! 523: double d;
! 524: Real r;
! 525:
! 526: if ( !p || NUM(p) ) {
! 527: d = ToReal(p);
! 528: MKReal(d,r);
! 529: *pr = (P)r;
! 530: } else {
! 531: for ( dcr0 = 0, dc = DC((P)p); dc; dc = NEXT(dc) ) {
! 532: devalp(vl,COEF(dc),&t);
! 533: if ( t ) {
! 534: NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc); COEF(dcr) = t;
! 535: }
! 536: }
! 537: if ( !dcr0 )
! 538: *pr = 0;
! 539: else {
! 540: NEXT(dcr) = 0; MKP(VR(p),dcr0,t);
! 541: if ( NUM(t) ) {
! 542: d = ToReal((Num)t);
! 543: MKReal(d,r);
! 544: *pr = (P)r;
! 545: } else if ( (VR(t) != VR(p)) || (VR(p)->attr != (pointer)V_PF) )
! 546: *pr = t;
! 547: else {
! 548: devalv(vl,VR(p),&u);
! 549: substr(vl,1,(Obj)t,VR(p),u,&s);
! 550: if ( s && NUM(s) ) {
! 551: d = ToReal((Num)s);
! 552: MKReal(d,r);
! 553: *pr = (P)r;
! 554: } else
! 555: *pr = (P)s;
! 556: }
! 557: }
! 558: }
! 559: }
! 560:
! 561: void devalv(vl,v,rp)
! 562: VL vl;
! 563: V v;
! 564: Obj *rp;
! 565: {
! 566: PFINS ins,tins;
! 567: PFAD ad,tad;
! 568: PF pf;
! 569: P t;
! 570: Obj s;
! 571: int i;
! 572:
! 573: if ( (vid)v->attr != V_PF ) {
! 574: MKV(v,t); *rp = (Obj)t;
! 575: } else {
! 576: ins = (PFINS)v->priv; ad = ins->ad; pf = ins->pf;
! 577: tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));
! 578: tins->pf = pf;
! 579: for ( i = 0, tad = tins->ad; i < pf->argc; i++ ) {
! 580: tad[i].d = ad[i].d; devalr(vl,ad[i].arg,&tad[i].arg);
! 581: }
! 582: devalins(tins,rp);
! 583: }
! 584: }
! 585:
! 586: void devalins(ins,rp)
! 587: PFINS ins;
! 588: Obj *rp;
! 589: {
! 590: PF pf;
! 591: PFAD ad;
! 592: int i;
! 593: Real r;
! 594: double d;
! 595: Q q;
! 596: V v;
! 597: P x;
! 598:
! 599: pf = ins->pf; ad = ins->ad;
! 600: for ( i = 0; i < pf->argc; i++ )
! 601: if ( ad[i].d || (ad[i].arg && !NUM(ad[i].arg)) )
! 602: break;
! 603: if ( (i != pf->argc) || !pf->libm ) {
! 604: instov(ins,&v); MKV(v,x); *rp = (Obj)x;
! 605: } else {
! 606: switch ( pf->argc ) {
! 607: case 0:
! 608: d = (*pf->libm)(); break;
! 609: case 1:
! 610: d = (*pf->libm)(ToReal(ad[0].arg)); break;
! 611: case 2:
! 612: d = (*pf->libm)(ToReal(ad[0].arg),ToReal(ad[1].arg)); break;
! 613: case 3:
! 614: d = (*pf->libm)(ToReal(ad[0].arg),ToReal(ad[1].arg),
! 615: ToReal(ad[2].arg)); break;
! 616: case 4:
! 617: d = (*pf->libm)(ToReal(ad[0].arg),ToReal(ad[1].arg),
! 618: ToReal(ad[2].arg),ToReal(ad[3].arg)); break;
! 619: default:
! 620: error("devalv : not supported");
! 621: }
! 622: MKReal(d,r); *rp = (Obj)r;
! 623: }
! 624: }
! 625:
! 626: void simplify_ins(ins,rp)
! 627: PFINS ins;
! 628: Obj *rp;
! 629: {
! 630: V v;
! 631: P t;
! 632:
! 633: if ( ins->pf->simplify )
! 634: (*ins->pf->simplify)(ins,rp);
! 635: else {
! 636: instov(ins,&v); MKV(v,t); *rp = (Obj)t;
! 637: }
! 638: }
! 639:
! 640: void instov(ins,vp)
! 641: PFINS ins;
! 642: V *vp;
! 643: {
! 644: V v;
! 645:
! 646: NEWV(v); NAME(v) = 0;
! 647: v->attr = (pointer)V_PF; v->priv = (pointer)ins;
! 648: appendpfins(v,vp);
! 649: }
! 650:
! 651: void substfr(vl,a,u,f,c)
! 652: VL vl;
! 653: Obj a;
! 654: PF u,f;
! 655: Obj *c;
! 656: {
! 657: Obj nm,dn;
! 658:
! 659: if ( !a )
! 660: *c = 0;
! 661: else {
! 662: switch ( OID(a) ) {
! 663: case O_N:
! 664: *c = a; break;
! 665: case O_P:
! 666: substfp(vl,a,u,f,c); break;
! 667: case O_R:
! 668: substfp(vl,(Obj)NM((R)a),u,f,&nm); substfp(vl,(Obj)DN((R)a),u,f,&dn);
! 669: divr(vl,nm,dn,c);
! 670: break;
! 671: default:
! 672: error("substfr : not implemented"); break;
! 673: }
! 674: }
! 675: }
! 676:
! 677: void substfp(vl,p,u,f,pr)
! 678: VL vl;
! 679: Obj p;
! 680: PF u,f;
! 681: Obj *pr;
! 682: {
! 683: V v;
! 684: DCP dc;
! 685: Obj a,c,m,s,t,p0;
! 686: Q d;
! 687: P x;
! 688:
! 689: if ( !p )
! 690: *pr = 0;
! 691: else if ( NUM(p) )
! 692: *pr = (Obj)p;
! 693: else {
! 694: v = VR((P)p); dc = DC((P)p);
! 695: if ( (int)v->attr != V_PF ) {
! 696: MKV(VR((P)p),x);
! 697: for ( c = 0; dc; dc = NEXT(dc) ) {
! 698: substfp(vl,(Obj)COEF(dc),u,f,&t);
! 699: if ( DEG(dc) ) {
! 700: pwrp(vl,x,DEG(dc),(P *)&s); mulr(vl,s,t,&m);
! 701: addr(vl,m,c,&a); c = a;
! 702: } else {
! 703: addr(vl,t,c,&a); c = a;
! 704: }
! 705: }
! 706: } else {
! 707: substfv(vl,v,u,f,&p0);
! 708: substfp(vl,(Obj)COEF(dc),u,f,&c);
! 709: for ( d = DEG(dc), dc = NEXT(dc); dc; d = DEG(dc), dc = NEXT(dc) ) {
! 710: subq(d,DEG(dc),(Q *)&t); pwrr(vl,p0,t,&s); mulr(vl,s,c,&m);
! 711: substfp(vl,(Obj)COEF(dc),u,f,&t); addr(vl,m,t,&c);
! 712: }
! 713: if ( d ) {
! 714: pwrr(vl,p0,(Obj)d,&t); mulr(vl,t,c,&m);
! 715: c = m;
! 716: }
! 717: }
! 718: *pr = c;
! 719: }
! 720: }
! 721:
! 722: void substfv(vl,v,u,f,c)
! 723: VL vl;
! 724: V v;
! 725: PF u,f;
! 726: Obj *c;
! 727: {
! 728: P t;
! 729: Obj r,s,w;
! 730: int i,j;
! 731: PFINS ins,tins;
! 732: PFAD ad,tad;
! 733:
! 734: ins = (PFINS)v->priv; ad = ins->ad;
! 735: if ( ins->pf == u ) {
! 736: if ( u->argc != f->argc )
! 737: error("substfv : argument mismatch");
! 738: if ( !f->body ) {
! 739: mkpfins(f,f->args,&v); MKV(v,t); r = (Obj)t;
! 740: } else
! 741: r = f->body;
! 742: for ( i = 0; i < f->argc; i++ )
! 743: for ( j = 0; j < ad[i].d; j++ ) {
! 744: derivr(vl,r,f->args[i],&s); r = s;
! 745: }
! 746: for ( i = 0; i < f->argc; i++ ) {
! 747: substfr(vl,ad[i].arg,u,f,&w);
! 748: substr(vl,0,r,f->args[i],w,&s); r = s;
! 749: }
! 750: *c = r;
! 751: } else {
! 752: tins = (PFINS)MALLOC(sizeof(PF)+f->argc*sizeof(struct oPFAD));
! 753: tins->pf = ins->pf; tad = tins->ad;
! 754: for ( i = 0; i < f->argc; i++ ) {
! 755: tad[i].d = ad[i].d; substfr(vl,ad[i].arg,u,f,&tad[i].arg);
! 756: }
! 757: instov(tins,&v); MKV(v,t); *c = (Obj)t;
! 758: }
! 759: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>