[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     ! 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>