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

Diff for /OpenXM_contrib2/asir2000/parse/puref.c between version 1.1 and 1.16

version 1.1, 1999/12/03 07:39:12 version 1.16, 2019/11/12 10:52:05
Line 1 
Line 1 
 /* $OpenXM: OpenXM/src/asir99/parse/puref.c,v 1.1.1.1 1999/11/10 08:12:34 noro Exp $ */  /*
    * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
    * All rights reserved.
    *
    * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
    * non-exclusive and royalty-free license to use, copy, modify and
    * redistribute, solely for non-commercial and non-profit purposes, the
    * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
    * conditions of this Agreement. For the avoidance of doubt, you acquire
    * only a limited right to use the SOFTWARE hereunder, and FLL or any
    * third party developer retains all rights, including but not limited to
    * copyrights, in and to the SOFTWARE.
    *
    * (1) FLL does not grant you a license in any way for commercial
    * purposes. You may use the SOFTWARE only for non-commercial and
    * non-profit purposes only, such as academic, research and internal
    * business use.
    * (2) The SOFTWARE is protected by the Copyright Law of Japan and
    * international copyright treaties. If you make copies of the SOFTWARE,
    * with or without modification, as permitted hereunder, you shall affix
    * to all such copies of the SOFTWARE the above copyright notice.
    * (3) An explicit reference to this SOFTWARE and its copyright owner
    * shall be made on your publication or presentation in any form of the
    * results obtained by use of the SOFTWARE.
    * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
    * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
    * for such modification or the source code of the modified part of the
    * SOFTWARE.
    *
    * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
    * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
    * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
    * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
    * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
    * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
    * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
    * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
    * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
    * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
    * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
    * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
    * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
    * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
    * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
    * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
    * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
    *
    * $OpenXM: OpenXM_contrib2/asir2000/parse/puref.c,v 1.15 2018/03/29 01:32:54 noro Exp $
   */
 #include "ca.h"  #include "ca.h"
 #include "parse.h"  #include "parse.h"
   
   void instoobj(PFINS ins,Obj *rp);
   
 NODE pflist;  NODE pflist;
   
 void searchpf(name,fp)  void searchpf(char *name,FUNC *fp)
 char *name;  
 FUNC *fp;  
 {  {
         NODE node;    NODE node;
         PF pf;    PF pf;
         FUNC t;    FUNC t;
   
         for ( node = pflist; node; node = NEXT(node) )    for ( node = pflist; node; node = NEXT(node) )
                 if ( !strcmp(name,((PF)node->body)->name) ) {      if ( !strcmp(name,((PF)node->body)->name) ) {
                         pf = (PF)node->body;        pf = (PF)node->body;
                         *fp = t = (FUNC)MALLOC(sizeof(struct oFUNC));        *fp = t = (FUNC)MALLOC(sizeof(struct oFUNC));
                         t->name = name; t->id = A_PURE; t->argc = pf->argc;        t->name = name; t->id = A_PURE; t->argc = pf->argc;
                         t->f.puref = pf;        t->f.puref = pf; t->fullname = name;
                         return;        return;
                 }      }
         *fp = 0;    *fp = 0;
 }  }
   
 void searchc(name,fp)  void searchc(char *name,FUNC *fp)
 char *name;  
 FUNC *fp;  
 {  {
         NODE node;    NODE node;
         PF pf;    PF pf;
         FUNC t;    FUNC t;
   
         for ( node = pflist; node; node = NEXT(node) )    for ( node = pflist; node; node = NEXT(node) )
                 if ( !strcmp(name,((PF)node->body)->name)      if ( !strcmp(name,((PF)node->body)->name)
                         && !((PF)node->body)->argc ) {        && !((PF)node->body)->argc ) {
                         pf = (PF)node->body;        pf = (PF)node->body;
                         *fp = t = (FUNC)MALLOC(sizeof(struct oFUNC));        *fp = t = (FUNC)MALLOC(sizeof(struct oFUNC));
                         t->name = name; t->id = A_PURE; t->argc = pf->argc;        t->name = name; t->id = A_PURE; t->argc = pf->argc;
                         t->f.puref = pf;        t->f.puref = pf; t->fullname = name;
                         return;        return;
                 }      }
         *fp = 0;    *fp = 0;
 }  }
   
 void mkpf(name,body,argc,args,parif,libmf,simp,pfp)  #if defined(INTERVAL)
 char *name;  void mkpf(char *name,Obj body,int argc,V *args,
 Obj body;    int (*parif)(),double (*libmf)(), int (*simp)(), void (**intervalfunc)(), PF *pfp)
 int argc;  #else
 V *args;  void mkpf(char *name,Obj body,int argc,V *args,
 int (*parif)(),(*simp)();    int (*parif)(),double (*libmf)(), int (*simp)(),PF *pfp)
 double (*libmf)();  #endif
 PF *pfp;  
 {  {
         PF pf;    PF pf;
         NODE node;    NODE node;
   
         NEWPF(pf); pf->name = name; pf->body = body;    NEWPF(pf); pf->name = name; pf->body = body;
         pf->argc = argc; pf->args = args; pf->pari = parif; pf->simplify = simp;    pf->argc = argc; pf->args = args; pf->pari = parif; pf->simplify = simp;
         pf->libm = libmf;    pf->libm = libmf;
         for ( node = pflist; node; node = NEXT(node) )  #if defined(INTERVAL)
                 if ( !strcmp(((PF)BDY(node))->name,name) )    pf->intervalfunc = intervalfunc;
                         break;  #endif
         if ( !node ) {    for ( node = pflist; node; node = NEXT(node) )
                 NEWNODE(node); NEXT(node) = pflist; pflist = node;      if ( !strcmp(((PF)BDY(node))->name,name) )
 /*              fprintf(stderr,"%s() defined.\n",name); */        break;
         } else    if ( !node ) {
                 fprintf(stderr,"%s() redefined.\n",name);      NEWNODE(node); NEXT(node) = pflist; pflist = node;
         BDY(node) = (pointer)pf; *pfp = pf;  /*    fprintf(stderr,"%s() defined.\n",name); */
     } else
       fprintf(stderr,"%s() redefined.\n",name);
     BDY(node) = (pointer)pf; *pfp = pf;
 }  }
   
 /*  /*
Line 75  PF *pfp;
Line 123  PF *pfp;
    each arg.     each arg.
  */   */
   
 void mkpfins(pf,args,vp)  void mkpfins(PF pf,V *args,V *vp)
 PF pf;  
 V *args;  
 V *vp;  
 {  {
         V v;    V v;
         PFINS ins;    PFINS ins;
         PFAD ad;    PFAD ad;
         int i;    int i;
         P t;    P t;
   
         NEWV(v); NAME(v) = 0; v->attr = (pointer)V_PF;    NEWV(v); NAME(v) = 0; v->attr = (pointer)V_PF;
         ins = (PFINS)MALLOC(sizeof(PF)+pf->argc*sizeof(struct oPFAD));    ins = (PFINS)MALLOC(sizeof(PF)+pf->argc*sizeof(struct oPFAD));
         bzero((char *)ins,(int)(sizeof(PF)+pf->argc*sizeof(struct oPFAD)));    bzero((char *)ins,(int)(sizeof(PF)+pf->argc*sizeof(struct oPFAD)));
         ins->pf = pf;    ins->pf = pf;
         v->priv = (pointer)ins;    v->priv = (pointer)ins;
         for ( i = 0, ad = ins->ad; i < pf->argc; i++ ) {    for ( i = 0, ad = ins->ad; i < pf->argc; i++ ) {
                 ad[i].d = 0; MKV(args[i],t); ad[i].arg = (Obj)t;      ad[i].d = 0; MKV(args[i],t); ad[i].arg = (Obj)t;
         }    }
         appendpfins(v,vp);    appendpfins(v,vp);
 }  }
   
 /* the same as above. Argements are given as an array of Obj */  /* the same as above. Argements are given as an array of Obj */
   
 void _mkpfins(pf,args,vp)  void _mkpfins(PF pf,Obj *args,V *vp)
 PF pf;  
 Obj *args;  
 V *vp;  
 {  {
         V v;    V v;
         PFINS ins;    PFINS ins;
         PFAD ad;    PFAD ad;
         int i;    int i;
   
         NEWV(v); NAME(v) = 0; v->attr = (pointer)V_PF;    NEWV(v); NAME(v) = 0; v->attr = (pointer)V_PF;
         ins = (PFINS)MALLOC(sizeof(PF)+pf->argc*sizeof(struct oPFAD));    ins = (PFINS)MALLOC(sizeof(PF)+pf->argc*sizeof(struct oPFAD));
         bzero((char *)ins,(int)(sizeof(PF)+pf->argc*sizeof(struct oPFAD)));    bzero((char *)ins,(int)(sizeof(PF)+pf->argc*sizeof(struct oPFAD)));
         ins->pf = pf;    ins->pf = pf;
         v->priv = (pointer)ins;    v->priv = (pointer)ins;
         for ( i = 0, ad = ins->ad; i < pf->argc; i++ ) {    for ( i = 0, ad = ins->ad; i < pf->argc; i++ ) {
                 ad[i].d = 0; ad[i].arg = args[i];      ad[i].d = 0; ad[i].arg = args[i];
         }    }
         appendpfins(v,vp);    appendpfins(v,vp);
 }  }
   
 /* the same as above. darray is also given */  /* the same as above. darray is also given */
   
 void _mkpfins_with_darray(pf,args,darray,vp)  void _mkpfins_with_darray(PF pf,Obj *args,int *darray,V *vp)
 PF pf;  
 Obj *args;  
 int *darray;  
 V *vp;  
 {  {
         V v;    V v;
         PFINS ins;    PFINS ins;
         PFAD ad;    PFAD ad;
         int i;    int i;
   
         NEWV(v); NAME(v) = 0; v->attr = (pointer)V_PF;    NEWV(v); NAME(v) = 0; v->attr = (pointer)V_PF;
         ins = (PFINS)MALLOC(sizeof(PF)+pf->argc*sizeof(struct oPFAD));    ins = (PFINS)MALLOC(sizeof(PF)+pf->argc*sizeof(struct oPFAD));
         bzero((char *)ins,(int)(sizeof(PF)+pf->argc*sizeof(struct oPFAD)));    bzero((char *)ins,(int)(sizeof(PF)+pf->argc*sizeof(struct oPFAD)));
         ins->pf = pf;    ins->pf = pf;
         v->priv = (pointer)ins;    v->priv = (pointer)ins;
         for ( i = 0, ad = ins->ad; i < pf->argc; i++ ) {    for ( i = 0, ad = ins->ad; i < pf->argc; i++ ) {
                 ad[i].d = darray[i]; ad[i].arg = args[i];      ad[i].d = darray[i]; ad[i].arg = args[i];
         }    }
         appendpfins(v,vp);    appendpfins(v,vp);
 }  }
   
 void appendpfins(v,vp)  void appendpfins(V v,V *vp)
 V v;  
 V *vp;  
 {  {
         PF fdef;    PF fdef;
         PFAD ad,tad;    PFAD ad,tad;
         NODE node;    NODE node;
         int i;    int i;
   
         fdef = ((PFINS)v->priv)->pf; ad = ((PFINS)v->priv)->ad;    fdef = ((PFINS)v->priv)->pf; ad = ((PFINS)v->priv)->ad;
         for ( node = fdef->ins; node; node = NEXT(node) ) {    for ( node = fdef->ins; node; node = NEXT(node) ) {
                 for ( i = 0, tad = ((PFINS)((V)node->body)->priv)->ad;      for ( i = 0, tad = ((PFINS)((V)node->body)->priv)->ad;
                         i < fdef->argc; i++ )        i < fdef->argc; i++ )
                         if ( (ad[i].d != tad[i].d) || compr(CO,ad[i].arg,tad[i].arg) )        if ( (ad[i].d != tad[i].d) || !equalr(CO,ad[i].arg,tad[i].arg) )
                                 break;          break;
                 if ( i == fdef->argc ) {      if ( i == fdef->argc ) {
                         *vp = (V)node->body;        *vp = (V)node->body;
                         return;        return;
                 }      }
         }    }
         NEWNODE(node); node->body = (pointer)v; NEXT(node) = fdef->ins;    NEWNODE(node); node->body = (pointer)v; NEXT(node) = fdef->ins;
         fdef->ins = node; appendvar(CO,v); *vp = v;    fdef->ins = node; appendvar(CO,v); *vp = v;
 }  }
   
 void duppfins(v,vp)  void duppfins(V v,V *vp)
 V v;  
 V *vp;  
 {  {
         V tv;    V tv;
         PFINS tins;    PFINS tins;
         int size;    int size;
   
         NEWV(tv); tv->name = v->name; tv->attr = v->attr;    NEWV(tv); tv->name = v->name; tv->attr = v->attr;
         size = sizeof(PF)+((PFINS)v->priv)->pf->argc*sizeof(struct oPFAD);    size = sizeof(PF)+((PFINS)v->priv)->pf->argc*sizeof(struct oPFAD);
         tins = (PFINS)MALLOC(size); bcopy((char *)v->priv,(char *)tins,size);    tins = (PFINS)MALLOC(size); bcopy((char *)v->priv,(char *)tins,size);
         tv->priv = (pointer)tins;    tv->priv = (pointer)tins;
         *vp = tv;    *vp = tv;
 }  }
   
 void derivvar(vl,pf,v,a)  void derivvar(VL vl,V pf,V v,Obj *a)
 VL vl;  
 V pf,v;  
 Obj *a;  
 {  {
         Obj t,s,u,w,u1;    Obj t,s,u,w,u1;
         P p;    P p;
         V tv,sv;    V tv,sv;
         PF fdef;    PF fdef;
         PFAD ad;    PFAD ad;
         int i,j;    int i,j;
   
         fdef = ((PFINS)pf->priv)->pf; ad = ((PFINS)pf->priv)->ad;    fdef = ((PFINS)pf->priv)->pf; ad = ((PFINS)pf->priv)->ad;
         if ( fdef->deriv ) {    if ( fdef->deriv ) {
                 for ( t = 0, i = 0; i < fdef->argc; i++ ) {      for ( t = 0, i = 0; i < fdef->argc; i++ ) {
                         derivr(vl,ad[i].arg,v,&s);        derivr(vl,ad[i].arg,v,&s);
                         for ( j = 0, u = fdef->deriv[i]; j < fdef->argc; j++ ) {        for ( j = 0, u = fdef->deriv[i]; j < fdef->argc; j++ ) {
                                 substr(vl,0,u,fdef->args[j],ad[j].arg,&u1); u = u1;          substr(vl,0,u,fdef->args[j],ad[j].arg,&u1); u = u1;
                         }        }
                         mulr(vl,s,u,&w); addr(vl,t,w,&s); t = s;        mulr(vl,s,u,&w); addr(vl,t,w,&s); t = s;
                 }      }
                 *a = t;      *a = t;
         } else {    } else {
                 for ( t = 0, i = 0; i < fdef->argc; i++ ) {      for ( t = 0, i = 0; i < fdef->argc; i++ ) {
                         derivr(vl,ad[i].arg,v,&s);        derivr(vl,ad[i].arg,v,&s);
                         duppfins(pf,&tv); (((PFINS)tv->priv)->ad)[i].d++;        duppfins(pf,&tv); (((PFINS)tv->priv)->ad)[i].d++;
                         appendpfins(tv,&sv);        appendpfins(tv,&sv);
                         MKV(sv,p); mulr(vl,s,(Obj)p,&w); addr(vl,t,w,&s); t = s;        MKV(sv,p); mulr(vl,s,(Obj)p,&w); addr(vl,t,w,&s); t = s;
                 }      }
                 *a = t;      *a = t;
         }    }
 }  }
   
 void derivr(vl,a,v,b)  void derivr(VL vl,Obj a,V v,Obj *b)
 VL vl;  
 V v;  
 Obj a,*b;  
 {  {
         VL tvl,svl;    VL tvl,svl;
         Obj r,s,t,u,nm,dn,dnm,ddn,m;    Obj r,s,t,u,nm,dn,dnm,ddn,m;
   
         if ( !a )    if ( !a )
                 *b = 0;      *b = 0;
         else    else
                 switch ( OID(a) ) {      switch ( OID(a) ) {
                         case O_N:        case O_N:
                                 *b = 0; break;          *b = 0; break;
                         case O_P:        case O_P:
                                 clctvr(vl,a,&tvl);          clctvr(vl,a,&tvl);
                                 for ( dnm = 0, svl = tvl; svl; svl = NEXT(svl) ) {          for ( dnm = 0, svl = tvl; svl; svl = NEXT(svl) ) {
                                         if ( svl->v == v ) {            if ( svl->v == v ) {
                                                 pderivr(vl,a,v,&s); addr(vl,s,dnm,&u); dnm = u;              pderivr(vl,a,v,&s); addr(vl,s,dnm,&u); dnm = u;
                                         } else if ( (vid)svl->v->attr == V_PF ) {            } else if ( (vid)svl->v->attr == V_PF ) {
                                                 pderivr(vl,a,svl->v,&s); derivvar(vl,svl->v,v,&r);              pderivr(vl,a,svl->v,&s); derivvar(vl,svl->v,v,&r);
                                                 mulr(vl,s,r,&u); addr(vl,u,dnm,&s); dnm = s;              mulr(vl,s,r,&u); addr(vl,u,dnm,&s); dnm = s;
                                         }            }
                                 }          }
                                 *b = (Obj)dnm; break;          *b = (Obj)dnm; break;
                         case O_R:        case O_R:
                                 clctvr(vl,a,&tvl);          clctvr(vl,a,&tvl);
                                 nm = (Obj)NM((R)a); dn = (Obj)DN((R)a);          nm = (Obj)NM((R)a); dn = (Obj)DN((R)a);
                                 for ( dnm = ddn = 0, svl = tvl; svl; svl = NEXT(svl) ) {          for ( dnm = ddn = 0, svl = tvl; svl; svl = NEXT(svl) ) {
                                         if ( svl->v == v ) {            if ( svl->v == v ) {
                                                 pderivr(vl,nm,v,&s); addr(vl,s,dnm,&u); dnm = u;              pderivr(vl,nm,v,&s); addr(vl,s,dnm,&u); dnm = u;
                                                 pderivr(vl,dn,v,&s); addr(vl,s,ddn,&u); ddn = u;              pderivr(vl,dn,v,&s); addr(vl,s,ddn,&u); ddn = u;
                                         } else if ( (vid)svl->v->attr == V_PF ) {            } else if ( (vid)svl->v->attr == V_PF ) {
                                                 pderivr(vl,nm,svl->v,&s); derivvar(vl,svl->v,v,&r);              pderivr(vl,nm,svl->v,&s); derivvar(vl,svl->v,v,&r);
                                                 mulr(vl,s,r,&u); addr(vl,u,dnm,&s); dnm = s;              mulr(vl,s,r,&u); addr(vl,u,dnm,&s); dnm = s;
                                                 pderivr(vl,dn,svl->v,&s); derivvar(vl,svl->v,v,&r);              pderivr(vl,dn,svl->v,&s); derivvar(vl,svl->v,v,&r);
                                                 mulr(vl,s,r,&u); addr(vl,u,ddn,&s); ddn = s;              mulr(vl,s,r,&u); addr(vl,u,ddn,&s); ddn = s;
                                         }            }
                                 }          }
                                 mulr(vl,dnm,dn,&t); mulr(vl,ddn,nm,&s);          mulr(vl,dnm,dn,&t); mulr(vl,ddn,nm,&s);
                                 subr(vl,t,s,&u); reductr(vl,u,&t);          subr(vl,t,s,&u); reductr(vl,u,&t);
                                 if ( !t )          if ( !t )
                                         *b = 0;            *b = 0;
                                 else {          else {
                                         mulp(vl,(P)dn,(P)dn,(P *)&m); divr(vl,t,m,b);            mulp(vl,(P)dn,(P)dn,(P *)&m); divr(vl,t,m,b);
                                 }          }
                                 break;          break;
         }    }
 }  }
   
 void substr(vl,partial,a,v,b,c)  void simple_derivr(VL vl,Obj a,V v,Obj *b)
 VL vl;  
 int partial;  
 Obj a;  
 V v;  
 Obj b;  
 Obj *c;  
 {  {
         Obj nm,dn,t;    Obj r,s,t,u,nm,dn;
   
         if ( !a )    if ( !a || NUM(a) )
                 *c = 0;      *b = 0;
         else {    else
                 switch ( OID(a) ) {      switch ( OID(a) ) {
                         case O_N:        case O_P:
                                 *c = a; break;          pderivr(vl,a,v,b); break;
                         case O_P:        case O_R:
                                 substpr(vl,partial,a,v,b,c); break;          nm = (Obj)NM((R)a); dn = (Obj)DN((R)a);
                         case O_R:          /* (nm/dn)' = nm'/dn - dn'/dn*nm/dn */
                                 substpr(vl,partial,(Obj)NM((R)a),v,b,&nm);          pderivr(vl,nm,v,&s); divr(vl,s,dn,&u); reductr(vl,u,&t);
                                 substpr(vl,partial,(Obj)DN((R)a),v,b,&dn);          pderivr(vl,dn,v,&s); divr(vl,s,dn,&u); reductr(vl,u,&s); mulr(vl,s,a,&u);
                                 divr(vl,nm,dn,&t); reductr(vl,t,c);          subr(vl,t,u,&s); reductr(vl,s,b);
                                 break;          break;
                         default:        default:
                                 *c = 0; break;          error("simple_derivr : invalid argument");
                 }    }
         }  
 }  }
   
 void substpr(vl,partial,p,v0,p0,pr)  int obj_is_dependent(Obj a,V v)
 VL vl;  
 int partial;  
 V v0;  
 Obj p;  
 Obj p0;  
 Obj *pr;  
 {  {
         P x;    if ( !a || OID(a) <= O_N ) return 0;
         Obj t,m,c,s,a;    else if ( OID(a) == O_P ) return poly_is_dependent((P)a,v);
         DCP dc;    else if ( OID(a) == O_R ) return poly_is_dependent(NM((R)a),v)
         Q d;      || poly_is_dependent(DN((R)a),v);
         V v;    else
         PF pf;      error("obj_is_dependent : not implemented");
         PFAD ad,tad;  }
         PFINS tins;  
         int i;  
   
         if ( !p )  int poly_is_dependent(P p,V v)
                 *pr = 0;  {
         else if ( NUM(p) )    DCP dc;
                 *pr = (Obj)p;  
         else if ( (v = VR((P)p)) != v0 ) {    if ( !p || OID(p) <= O_N ) return 0;
                 if ( !partial && ((vid)v->attr == V_PF) ) {    else if ( v == VR(p) ) return 1;
                         ad = ((PFINS)v->priv)->ad; pf = ((PFINS)v->priv)->pf;    else {
                         tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));      for ( dc = DC(p); dc; dc = NEXT(dc) )
                         tins->pf = pf;        if ( poly_is_dependent(COEF(dc),v) ) return 1;
                         for ( i = 0, tad = tins->ad; i < pf->argc; i++ ) {      return 0;
                                 tad[i].d = ad[i].d;    }
                                 substr(vl,partial,ad[i].arg,v0,p0,&tad[i].arg);  
                         }  
                         simplify_ins(tins,(Obj *)&x);  
                 } else  
                         MKV(VR((P)p),x);  
                 for ( c = 0, dc = DC((P)p); dc; dc = NEXT(dc) ) {  
                         substpr(vl,partial,(Obj)COEF(dc),v0,p0,&t);  
                         if ( DEG(dc) ) {  
                                 pwrp(vl,x,DEG(dc),(P *)&s); mulr(vl,s,t,&m);  
                                 addr(vl,m,c,&a); c = a;  
                         } else {  
                                 addr(vl,t,c,&a); c = a;  
                         }  
                 }  
                 *pr = c;  
         } else {  
                 dc = DC((P)p);  
                 if ( !partial )  
                         substpr(vl,partial,(Obj)COEF(dc),v0,p0,&c);  
                 else  
                         c = (Obj)COEF(dc);  
                 for ( d = DEG(dc), dc = NEXT(dc); dc; d = DEG(dc), dc = NEXT(dc) ) {  
                                 subq(d,DEG(dc),(Q *)&t); pwrr(vl,p0,t,&s); mulr(vl,s,c,&m);  
                                 if ( !partial )  
                                         substpr(vl,partial,(Obj)COEF(dc),v0,p0,&t);  
                                 else  
                                         t = (Obj)COEF(dc);  
                                 addr(vl,m,t,&c);  
                 }  
                 if ( d ) {  
                         pwrr(vl,p0,(Obj)d,&t); mulr(vl,t,c,&m);  
                         c = m;  
                 }  
                 *pr = c;  
         }  
 }  }
   
 void evalr(vl,a,prec,c)  void gen_pwrr(VL vl,Obj a,Obj d,Obj *r)
 VL vl;  
 Obj a;  
 int prec;  
 Obj *c;  
 {  {
         Obj nm,dn;    if ( INT(d) )
       pwrr(vl,a,d,r);
     else
       mkpow(vl,a,d,r);
   }
   
         if ( !a )  void substr(VL vl,int partial,Obj a,V v,Obj b,Obj *c)
                 *c = 0;  {
         else {    Obj nm,dn,t;
                 switch ( OID(a) ) {  
                         case O_N:    if ( !a )
                                 *c = a; break;      *c = 0;
                         case O_P:    else {
                                 evalp(vl,(P)a,prec,(P *)c); break;      switch ( OID(a) ) {
                         case O_R:        case O_N:
                                 evalp(vl,NM((R)a),prec,(P *)&nm); evalp(vl,DN((R)a),prec,(P *)&dn);          *c = a; break;
                                 divr(vl,nm,dn,c);        case O_P:
                                 break;          substpr(vl,partial,a,v,b,c); break;
                         default:        case O_R:
                                 error("evalr : not implemented"); break;          substpr(vl,partial,(Obj)NM((R)a),v,b,&nm);
                 }          substpr(vl,partial,(Obj)DN((R)a),v,b,&dn);
         }          divr(vl,nm,dn,&t); reductr(vl,t,c);
           break;
         default:
           *c = 0; break;
       }
     }
 }  }
   
 void evalp(vl,p,prec,pr)  void substpr(VL vl,int partial,Obj p,V v0,Obj p0,Obj *pr)
 VL vl;  
 P p;  
 int prec;  
 P *pr;  
 {  {
         P t;    P x;
         DCP dc,dcr0,dcr;    Obj t,m,c,s,a;
         Obj u;    DCP dc;
     Q d;
     V v;
     PF pf;
     PFAD ad,tad;
     PFINS tins;
     int i;
   
         if ( !p || NUM(p) )    if ( !p )
                 *pr = p;      *pr = 0;
         else {    else if ( NUM(p) )
                 for ( dcr0 = 0, dc = DC((P)p); dc; dc = NEXT(dc) ) {      *pr = (Obj)p;
                         evalp(vl,COEF(dc),prec,&t);    else if ( (v = VR((P)p)) != v0 ) {
                         if ( t ) {      if ( !partial && ((vid)v->attr == V_PF) ) {
                                 NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc); COEF(dcr) = t;        ad = ((PFINS)v->priv)->ad; pf = ((PFINS)v->priv)->pf;
                         }        tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));
                 }        tins->pf = pf;
                 if ( !dcr0 ) {        for ( i = 0, tad = tins->ad; i < pf->argc; i++ ) {
                         *pr = 0; return;          tad[i].d = ad[i].d;
                 } else {          substr(vl,partial,ad[i].arg,v0,p0,&tad[i].arg);
                         NEXT(dcr) = 0; MKP(VR(p),dcr0,t);        }
                 }        simplify_ins(tins,(Obj *)&x);
                 if ( NUM(t) || (VR(t) != VR(p)) || ((vid)VR(p)->attr != V_PF) ) {      } else
                         *pr = t; return;        MKV(VR((P)p),x);
                 } else {      for ( c = 0, dc = DC((P)p); dc; dc = NEXT(dc) ) {
                         evalv(vl,VR(p),prec,&u); substr(vl,1,(Obj)t,VR(p),u,(Obj *)pr);        substpr(vl,partial,(Obj)COEF(dc),v0,p0,&t);
                 }        if ( DEG(dc) ) {
         }          gen_pwrr(vl,(Obj)x,(Obj)DEG(dc),&s);
           mulr(vl,s,t,&m);
           addr(vl,m,c,&a); c = a;
         } else {
           addr(vl,t,c,&a); c = a;
         }
       }
       *pr = c;
     } else {
       dc = DC((P)p);
       if ( !partial )
         substpr(vl,partial,(Obj)COEF(dc),v0,p0,&c);
       else
         c = (Obj)COEF(dc);
       for ( d = DEG(dc), dc = NEXT(dc); dc; d = DEG(dc), dc = NEXT(dc) ) {
           subq(d,DEG(dc),(Q *)&t);
           gen_pwrr(vl,p0,t,&s); mulr(vl,s,c,&m);
           if ( !partial )
             substpr(vl,partial,(Obj)COEF(dc),v0,p0,&t);
           else
             t = (Obj)COEF(dc);
           addr(vl,m,t,&c);
       }
       if ( d ) {
         gen_pwrr(vl,p0,(Obj)d,&t);
         mulr(vl,t,c,&m);
         c = m;
       }
       *pr = c;
     }
 }  }
   
 void evalv(vl,v,prec,rp)  void evalr(VL vl,Obj a,int prec,Obj *c)
 VL vl;  
 V v;  
 int prec;  
 Obj *rp;  
 {  {
         PFINS ins,tins;    Obj nm,dn;
         PFAD ad,tad;  
         PF pf;  
         P t;  
         int i;  
   
         if ( (vid)v->attr != V_PF ) {    if ( !a )
                 MKV(v,t); *rp = (Obj)t;      *c = 0;
         } else {    else {
                 ins = (PFINS)v->priv; ad = ins->ad; pf = ins->pf;      switch ( OID(a) ) {
                 tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));        case O_N:
                 tins->pf = pf;          *c = a; break;
                 for ( i = 0, tad = tins->ad; i < pf->argc; i++ ) {        case O_P:
                         tad[i].d = ad[i].d; evalr(vl,ad[i].arg,prec,&tad[i].arg);          evalp(vl,(P)a,prec,(P *)c); break;
                 }        case O_R:
                 evalins(tins,prec,rp);          evalp(vl,NM((R)a),prec,(P *)&nm); evalp(vl,DN((R)a),prec,(P *)&dn);
         }          divr(vl,nm,dn,c);
           break;
         default:
           error("evalr : not implemented"); break;
       }
     }
 }  }
   
 void evalins(ins,prec,rp)  void evalp(VL vl,P p,int prec,P *pr)
 PFINS ins;  
 int prec;  
 Obj *rp;  
 {  {
         PF pf;    P t;
         PFAD ad;    DCP dc,dcr0,dcr;
         int i;    Obj u;
         Q q;  
         V v;  
         P x;  
         NODE n0,n;  
   
         pf = ins->pf; ad = ins->ad;    if ( !p || NUM(p) )
         for ( i = 0; i < pf->argc; i++ )      *pr = p;
                 if ( ad[i].d || (ad[i].arg && !NUM(ad[i].arg)) )    else {
                         break;      for ( dcr0 = 0, dc = DC((P)p); dc; dc = NEXT(dc) ) {
         if ( (i != pf->argc) || !pf->pari ) {        evalp(vl,COEF(dc),prec,&t);
                 instov(ins,&v); MKV(v,x); *rp = (Obj)x;        if ( t ) {
         } else {          NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc); COEF(dcr) = t;
                 for ( n0 = 0, i = 0; i < pf->argc; i++ ) {        }
                         NEXTNODE(n0,n); BDY(n) = (pointer)ad[i].arg;      }
                 }      if ( !dcr0 ) {
                 if ( prec ) {        *pr = 0; return;
                         NEXTNODE(n0,n); STOQ(prec,q); BDY(n) = (pointer)q;      } else {
                 }        NEXT(dcr) = 0; MKP(VR(p),dcr0,t);
                 if ( n0 )      }
                         NEXT(n) = 0;      if ( NUM(t) || (VR(t) != VR(p)) || ((vid)VR(p)->attr != V_PF) ) {
                 (*pf->pari)(n0,rp);        *pr = t; return;
         }      } else {
         evalv(vl,VR(p),prec,&u); substr(vl,1,(Obj)t,VR(p),u,(Obj *)pr);
       }
     }
 }  }
   
 void devalins(PFINS,Obj *);  void evalv(VL vl,V v,int prec,Obj *rp)
 void devalv(VL,V,Obj *);  {
 void devalp(VL,P,P *);    PFINS ins,tins;
 void devalr(VL,Obj,Obj *);    PFAD ad,tad;
     PF pf;
     P t;
     int i;
   
 void devalr(vl,a,c)    if ( (vid)v->attr != V_PF ) {
 VL vl;      MKV(v,t); *rp = (Obj)t;
 Obj a;    } else {
 Obj *c;      ins = (PFINS)v->priv; ad = ins->ad; pf = ins->pf;
       tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));
       tins->pf = pf;
       for ( i = 0, tad = tins->ad; i < pf->argc; i++ ) {
         tad[i].d = ad[i].d; evalr(vl,ad[i].arg,prec,&tad[i].arg);
       }
       evalins(tins,prec,rp);
     }
   }
   
   void evalins(PFINS ins,int prec,Obj *rp)
 {  {
         Obj nm,dn;    PF pf;
         double d;    PFINS tins;
         Real r;    PFAD ad,tad;
     int i;
     Q q;
     V v;
     P x;
     NODE n0,n;
   
         if ( !a )    pf = ins->pf; ad = ins->ad;
                 *c = 0;    tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));
         else {    tins->pf = pf; tad = tins->ad;
                 switch ( OID(a) ) {    for ( i = 0; i < pf->argc; i++ ) {
                         case O_N:      tad[i].d = ad[i].d; evalr(CO,ad[i].arg,prec,&tad[i].arg);
                                 d = ToReal(a);     }
                                 MKReal(d,r);    for ( i = 0; i < pf->argc; i++ )
                                 *c = (Obj)r;      if ( tad[i].d || (tad[i].arg && !NUM(tad[i].arg)) ) break;
                                 break;    if ( (i != pf->argc) || !pf->pari ) {
                         case O_P:      instoobj(tins,rp);
                                 devalp(vl,(P)a,(P *)c); break;    } else {
                         case O_R:      for ( n0 = 0, i = 0; i < pf->argc; i++ ) {
                                 devalp(vl,NM((R)a),(P *)&nm);        NEXTNODE(n0,n); BDY(n) = (pointer)tad[i].arg;
                                 devalp(vl,DN((R)a),(P *)&dn);      }
                                 divr(vl,nm,dn,c);      if ( prec ) {
                                 break;        NEXTNODE(n0,n); STOQ(prec,q); BDY(n) = (pointer)q;
                         default:      }
                                 error("devalr : not implemented"); break;      if ( n0 )
                 }        NEXT(n) = 0;
         }      (*pf->pari)(n0,rp);
     }
 }  }
   
 void devalp(vl,p,pr)  void devalr(VL vl,Obj a,Obj *c)
 VL vl;  
 P p;  
 P *pr;  
 {  {
         P t;    Obj nm,dn;
         DCP dc,dcr0,dcr;    double d;
         Obj u,s;    Real r,re,im;
         double d;    C z;
         Real r;    int nid;
   
         if ( !p || NUM(p) ) {    if ( !a )
                 d = ToReal(p);      *c = 0;
                 MKReal(d,r);    else {
                 *pr = (P)r;      switch ( OID(a) ) {
         } else {        case O_N:
                 for ( dcr0 = 0, dc = DC((P)p); dc; dc = NEXT(dc) ) {          nid = NID((Num)a);
                         devalp(vl,COEF(dc),&t);          if ( nid == N_C ) {
                         if ( t ) {            d = ToReal(((C)a)->r); MKReal(d,re);
                                 NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc); COEF(dcr) = t;            d = ToReal(((C)a)->i); MKReal(d,im);
                         }            reimtocplx(re,im,&z);
                 }            *c = (Obj)z;
                 if ( !dcr0 )          } else if ( nid == N_Q || nid == N_R || nid == N_B ) {
                         *pr = 0;            d = ToReal(a);
                 else {            MKReal(d,r);
                         NEXT(dcr) = 0; MKP(VR(p),dcr0,t);            *c = (Obj)r;
                         if ( NUM(t) ) {          } else
                                 d = ToReal((Num)t);            error("devalr : unsupported");
                                 MKReal(d,r);          break;
                                 *pr = (P)r;        case O_P:
                         } else if ( (VR(t) != VR(p)) || (VR(p)->attr != (pointer)V_PF) )          devalp(vl,(P)a,(P *)c); break;
                                 *pr = t;        case O_R:
                         else {          devalp(vl,NM((R)a),(P *)&nm);
                                 devalv(vl,VR(p),&u);          devalp(vl,DN((R)a),(P *)&dn);
                                 substr(vl,1,(Obj)t,VR(p),u,&s);          divr(vl,nm,dn,c);
                                 if ( s && NUM(s) ) {          break;
                                         d = ToReal((Num)s);        default:
                                         MKReal(d,r);          error("devalr : not implemented"); break;
                                         *pr = (P)r;      }
                                 } else    }
                                         *pr = (P)s;  
                         }  
                 }  
         }  
 }  }
   
 void devalv(vl,v,rp)  void devalp(VL vl,P p,P *pr)
 VL vl;  
 V v;  
 Obj *rp;  
 {  {
         PFINS ins,tins;    P t;
         PFAD ad,tad;    DCP dc,dcr0,dcr;
         PF pf;    Obj u,s;
         P t;    double d;
         Obj s;    Real r;
         int i;  
   
         if ( (vid)v->attr != V_PF ) {    if ( !p || NUM(p) ) {
                 MKV(v,t); *rp = (Obj)t;      d = ToReal(p);
         } else {      MKReal(d,r);
                 ins = (PFINS)v->priv; ad = ins->ad; pf = ins->pf;      *pr = (P)r;
                 tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));    } else {
                 tins->pf = pf;      for ( dcr0 = 0, dc = DC((P)p); dc; dc = NEXT(dc) ) {
                 for ( i = 0, tad = tins->ad; i < pf->argc; i++ ) {        devalp(vl,COEF(dc),&t);
                         tad[i].d = ad[i].d; devalr(vl,ad[i].arg,&tad[i].arg);        if ( t ) {
                 }          NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc); COEF(dcr) = t;
                 devalins(tins,rp);        }
         }      }
       if ( !dcr0 )
         *pr = 0;
       else {
         NEXT(dcr) = 0; MKP(VR(p),dcr0,t);
         if ( NUM(t) ) {
           d = ToReal((Num)t);
           MKReal(d,r);
           *pr = (P)r;
         } else if ( (VR(t) != VR(p)) || (VR(p)->attr != (pointer)V_PF) )
           *pr = t;
         else {
           devalv(vl,VR(p),&u);
           substr(vl,1,(Obj)t,VR(p),u,&s);
           if ( s && NUM(s) ) {
             d = ToReal((Num)s);
             MKReal(d,r);
             *pr = (P)r;
           } else
             *pr = (P)s;
         }
       }
     }
 }  }
   
 void devalins(ins,rp)  void devalv(VL vl,V v,Obj *rp)
 PFINS ins;  
 Obj *rp;  
 {  {
         PF pf;    PFINS ins,tins;
         PFAD ad;    PFAD ad,tad;
         int i;    PF pf;
         Real r;    P t;
         double d;    int i;
         Q q;  
         V v;  
         P x;  
   
         pf = ins->pf; ad = ins->ad;    if ( (vid)v->attr != V_PF ) {
         for ( i = 0; i < pf->argc; i++ )      MKV(v,t); *rp = (Obj)t;
                 if ( ad[i].d || (ad[i].arg && !NUM(ad[i].arg)) )    } else {
                         break;      ins = (PFINS)v->priv; ad = ins->ad; pf = ins->pf;
         if ( (i != pf->argc) || !pf->libm ) {      tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));
                 instov(ins,&v); MKV(v,x); *rp = (Obj)x;      tins->pf = pf;
         } else {      for ( i = 0, tad = tins->ad; i < pf->argc; i++ ) {
                 switch ( pf->argc ) {        tad[i].d = ad[i].d; devalr(vl,ad[i].arg,&tad[i].arg);
                         case 0:      }
                                 d = (*pf->libm)(); break;      devalins(tins,rp);
                         case 1:    }
                                 d = (*pf->libm)(ToReal(ad[0].arg)); break;  
                         case 2:  
                                 d = (*pf->libm)(ToReal(ad[0].arg),ToReal(ad[1].arg)); break;  
                         case 3:  
                                 d = (*pf->libm)(ToReal(ad[0].arg),ToReal(ad[1].arg),  
                                         ToReal(ad[2].arg)); break;  
                         case 4:  
                                 d = (*pf->libm)(ToReal(ad[0].arg),ToReal(ad[1].arg),  
                                         ToReal(ad[2].arg),ToReal(ad[3].arg)); break;  
                         default:  
                                 error("devalv : not supported");  
                 }  
                 MKReal(d,r); *rp = (Obj)r;  
         }  
 }  }
   
 void simplify_ins(ins,rp)  void devalins(PFINS ins,Obj *rp)
 PFINS ins;  
 Obj *rp;  
 {  {
         V v;    PFINS tins;
         P t;    PF pf;
     PFAD ad,tad;
     int i;
     Real r;
     double d;
     V v;
     P x;
   
         if ( ins->pf->simplify )    pf = ins->pf; ad = ins->ad;
                 (*ins->pf->simplify)(ins,rp);    tins = (PFINS)CALLOC(1,sizeof(PF)+pf->argc*sizeof(struct oPFAD));
         else {    tins->pf = pf; tad = tins->ad;
                 instov(ins,&v); MKV(v,t); *rp = (Obj)t;    for ( i = 0; i < pf->argc; i++ ) {
         }      tad[i].d = ad[i].d; devalr(CO,ad[i].arg,&tad[i].arg);
      }
     for ( i = 0; i < pf->argc; i++ )
       if ( tad[i].d || (tad[i].arg && !NUM(tad[i].arg)) ) break;
     if ( (i != pf->argc) || !pf->libm ) {
       instoobj(tins,rp);
     } else {
       for ( i = 0; i < pf->argc; i++ )
         if ( tad[i].arg && NID((Num)tad[i].arg) == N_C )
           error("devalins : not supported");
       switch ( pf->argc ) {
         case 0:
           d = (*pf->libm)(); break;
         case 1:
           d = (*pf->libm)(ToReal(tad[0].arg)); break;
         case 2:
           d = (*pf->libm)(ToReal(tad[0].arg),ToReal(tad[1].arg)); break;
         case 3:
           d = (*pf->libm)(ToReal(tad[0].arg),ToReal(tad[1].arg),
             ToReal(tad[2].arg)); break;
         case 4:
           d = (*pf->libm)(ToReal(tad[0].arg),ToReal(tad[1].arg),
             ToReal(tad[2].arg),ToReal(tad[3].arg)); break;
         default:
           error("devalins : not supported");
       }
       MKReal(d,r); *rp = (Obj)r;
     }
 }  }
   
 void instov(ins,vp)  extern int evalef,bigfloat;
 PFINS ins;  
 V *vp;  void simplify_elemfunc_ins(PFINS ins,Obj *rp)
 {  {
         V v;    if ( evalef ) {
       if ( bigfloat ) evalins(ins,0,rp);
       else devalins(ins,rp);
     } else instoobj(ins,rp);
   }
   
         NEWV(v); NAME(v) = 0;  void simplify_factorial_ins(PFINS ins,Obj *rp)
         v->attr = (pointer)V_PF; v->priv = (pointer)ins;  {
         appendpfins(v,vp);    PFAD ad;
     Obj a;
     Q q;
   
     ad = ins->ad;
     a = ad[0].arg;
     if ( !ad[0].d && INT(a) && ( !a || (PL(NM((Q)a)) == 1 && SGN((Q)a) > 0) ) ) {
       factorial(QTOS((Q)a),&q);
       *rp = (Obj)q;
     } else simplify_elemfunc_ins(ins,rp);
 }  }
   
 void substfr(vl,a,u,f,c)  void simplify_abs_ins(PFINS ins,Obj *rp)
 VL vl;  
 Obj a;  
 PF u,f;  
 Obj *c;  
 {  {
         Obj nm,dn;    PFAD ad;
     Obj a;
     Q q;
     double t;
     Real r;
     struct oNODE arg0;
   
         if ( !a )    ad = ins->ad;
                 *c = 0;    a = ad[0].arg;
         else {    if ( !ad[0].d && NUM(a) && (!a || RATN(a)) ) {
                 switch ( OID(a) ) {      if ( !a || SGN((Q)a) > 0 ) *rp = (Obj)a;
                         case O_N:      else {
                                 *c = a; break;        chsgnq((Q)a,&q); *rp = (Obj)q;
                         case O_P:      }
                                 substfp(vl,a,u,f,c); break;    } else if ( !ad[0].d && REAL(a) ) {
                         case O_R:      t = fabs(((Real)a)->body);
                                 substfp(vl,(Obj)NM((R)a),u,f,&nm); substfp(vl,(Obj)DN((R)a),u,f,&dn);      MKReal(t,r); *rp = (Obj)r;
                                 divr(vl,nm,dn,c);    } else if ( !ad[0].d && BIGFLOAT(a) ) {
                                 break;      arg0.body = (pointer)a; arg0.next = 0;
                         default:      mp_abs(&arg0,rp);
                                 error("substfr : not implemented"); break;  #if defined(INTERVAL)
                 }    } else if ( !ad[0].d && ITVD(a) ) {
         }      absintvald((IntervalDouble)a,(IntervalDouble*)rp);
     } else if ( !ad[0].d && ITVF(a) ) {
       absintvalp((Itv)a,(Itv*)rp);
   #endif
     } else simplify_elemfunc_ins(ins,rp);
 }  }
   
 void substfp(vl,p,u,f,pr)  void simplify_ins(PFINS ins,Obj *rp)
 VL vl;  
 Obj p;  
 PF u,f;  
 Obj *pr;  
 {  {
         V v;    V v;
         DCP dc;    P t;
         Obj a,c,m,s,t,p0;  
         Q d;  
         P x;  
   
         if ( !p )    if ( ins->pf->simplify )
                 *pr = 0;      (*ins->pf->simplify)(ins,rp);
         else if ( NUM(p) )    else {
                 *pr = (Obj)p;      instoobj(ins,rp);
         else {    }
                 v = VR((P)p); dc = DC((P)p);  
                 if ( (int)v->attr != V_PF ) {  
                         MKV(VR((P)p),x);  
                         for ( c = 0; dc; dc = NEXT(dc) ) {  
                                 substfp(vl,(Obj)COEF(dc),u,f,&t);  
                                 if ( DEG(dc) ) {  
                                         pwrp(vl,x,DEG(dc),(P *)&s); mulr(vl,s,t,&m);  
                                         addr(vl,m,c,&a); c = a;  
                                 } else {  
                                         addr(vl,t,c,&a); c = a;  
                                 }  
                         }  
                 } else {  
                         substfv(vl,v,u,f,&p0);  
                         substfp(vl,(Obj)COEF(dc),u,f,&c);  
                         for ( d = DEG(dc), dc = NEXT(dc); dc; d = DEG(dc), dc = NEXT(dc) ) {  
                                         subq(d,DEG(dc),(Q *)&t); pwrr(vl,p0,t,&s); mulr(vl,s,c,&m);  
                                         substfp(vl,(Obj)COEF(dc),u,f,&t); addr(vl,m,t,&c);  
                         }  
                         if ( d ) {  
                                 pwrr(vl,p0,(Obj)d,&t); mulr(vl,t,c,&m);  
                                 c = m;  
                         }  
                 }  
                 *pr = c;  
         }  
 }  }
   
 void substfv(vl,v,u,f,c)  void instoobj(PFINS ins,Obj *rp)
 VL vl;  
 V v;  
 PF u,f;  
 Obj *c;  
 {  {
         P t;    V v,newv;
         Obj r,s,w;    P t;
         int i,j;  
         PFINS ins,tins;  
         PFAD ad,tad;  
   
         ins = (PFINS)v->priv; ad = ins->ad;    NEWV(v); NAME(v) = 0;
         if ( ins->pf == u ) {    v->attr = (pointer)V_PF; v->priv = (pointer)ins;
                 if ( u->argc != f->argc )    appendpfins(v,&newv);
                         error("substfv : argument mismatch");    MKV(newv,t);
                 if ( !f->body ) {    *rp = (Obj)t;
                         mkpfins(f,f->args,&v); MKV(v,t); r = (Obj)t;  }
                 } else  
                         r = f->body;  void substfr(VL vl,Obj a,PF u,PF f,Obj *c)
                 for ( i = 0; i < f->argc; i++ )  {
                         for ( j = 0; j < ad[i].d; j++ ) {    Obj nm,dn;
                                 derivr(vl,r,f->args[i],&s); r = s;  
                         }    if ( !a )
                 for ( i = 0; i < f->argc; i++ ) {      *c = 0;
                         substfr(vl,ad[i].arg,u,f,&w);    else {
                         substr(vl,0,r,f->args[i],w,&s); r = s;      switch ( OID(a) ) {
                 }        case O_N:
                 *c = r;          *c = a; break;
         } else {        case O_P:
                 tins = (PFINS)MALLOC(sizeof(PF)+f->argc*sizeof(struct oPFAD));          substfp(vl,a,u,f,c); break;
                 tins->pf = ins->pf; tad = tins->ad;        case O_R:
                 for ( i = 0; i < f->argc; i++ ) {          substfp(vl,(Obj)NM((R)a),u,f,&nm); substfp(vl,(Obj)DN((R)a),u,f,&dn);
                         tad[i].d = ad[i].d; substfr(vl,ad[i].arg,u,f,&tad[i].arg);          divr(vl,nm,dn,c);
                 }          break;
                 instov(tins,&v); MKV(v,t); *c = (Obj)t;        default:
         }          error("substfr : not implemented"); break;
       }
     }
   }
   
   void substfp(VL vl,Obj p,PF u,PF f,Obj *pr)
   {
     V v;
     DCP dc;
     Obj a,c,m,s,t,p0;
     Q d;
     P x;
   
     if ( !p )
       *pr = 0;
     else if ( NUM(p) )
       *pr = (Obj)p;
     else {
       v = VR((P)p); dc = DC((P)p);
       if ( (int)v->attr != V_PF ) {
         MKV(VR((P)p),x);
         for ( c = 0; dc; dc = NEXT(dc) ) {
           substfp(vl,(Obj)COEF(dc),u,f,&t);
           if ( DEG(dc) ) {
             gen_pwrr(vl,(Obj)x,(Obj)DEG(dc),&s);
             mulr(vl,s,t,&m);
             addr(vl,m,c,&a); c = a;
           } else {
             addr(vl,t,c,&a); c = a;
           }
         }
       } else {
         substfv(vl,v,u,f,&p0);
         substfp(vl,(Obj)COEF(dc),u,f,&c);
         for ( d = DEG(dc), dc = NEXT(dc); dc; d = DEG(dc), dc = NEXT(dc) ) {
             subq(d,DEG(dc),(Q *)&t);
             gen_pwrr(vl,p0,t,&s); mulr(vl,s,c,&m);
             substfp(vl,(Obj)COEF(dc),u,f,&t); addr(vl,m,t,&c);
         }
         if ( d ) {
           gen_pwrr(vl,p0,(Obj)d,&t); mulr(vl,t,c,&m);
           c = m;
         }
       }
       *pr = c;
     }
   }
   
   void substfv(VL vl,V v,PF u,PF f,Obj *c)
   {
     P t;
     Obj r,s,w;
     int i,j;
     PFINS ins,tins;
     PFAD ad,tad;
   
     ins = (PFINS)v->priv; ad = ins->ad;
     if ( ins->pf == u ) {
       if ( u->argc != f->argc )
         error("substfv : argument mismatch");
       if ( !f->body ) {
         mkpfins(f,f->args,&v); MKV(v,t); r = (Obj)t;
       } else
         r = f->body;
       for ( i = 0; i < f->argc; i++ )
         for ( j = 0; j < ad[i].d; j++ ) {
           derivr(vl,r,f->args[i],&s); r = s;
         }
       for ( i = 0; i < f->argc; i++ ) {
         substfr(vl,ad[i].arg,u,f,&w);
         substr(vl,0,r,f->args[i],w,&s); r = s;
       }
       *c = r;
     } else {
       tins = (PFINS)MALLOC(sizeof(PF)+f->argc*sizeof(struct oPFAD));
       tins->pf = ins->pf; tad = tins->ad;
       for ( i = 0; i < f->argc; i++ ) {
         tad[i].d = ad[i].d; substfr(vl,ad[i].arg,u,f,&tad[i].arg);
       }
       instoobj(tins,c);
     }
 }  }

Legend:
Removed from v.1.1  
changed lines
  Added in v.1.16

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>