[BACK]Return to puref.c CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / parse

Annotation of OpenXM_contrib2/asir2000/parse/puref.c, Revision 1.1.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>