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

Diff for /OpenXM_contrib2/asir2000/builtin/algnum.c between version 1.15 and 1.16

version 1.15, 2017/08/31 02:36:20 version 1.16, 2018/03/29 01:32:50
Line 45 
Line 45 
  * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,   * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
  * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.   * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
  *   *
  * $OpenXM: OpenXM_contrib2/asir2000/builtin/algnum.c,v 1.14 2013/11/17 17:34:59 ohara Exp $   * $OpenXM: OpenXM_contrib2/asir2000/builtin/algnum.c,v 1.15 2017/08/31 02:36:20 noro Exp $
 */  */
 #include "ca.h"  #include "ca.h"
 #include "parse.h"  #include "parse.h"
Line 72  void Pdalgtodp();
Line 72  void Pdalgtodp();
 void Pdptodalg();  void Pdptodalg();
   
 struct ftab alg_tab[] = {  struct ftab alg_tab[] = {
         {"set_field",Pset_field,-3},    {"set_field",Pset_field,-3},
         {"get_field_defpoly",Pget_field_defpoly,1},    {"get_field_defpoly",Pget_field_defpoly,1},
         {"get_field_generator",Pget_field_generator,1},    {"get_field_generator",Pget_field_generator,1},
         {"algtodalg",Palgtodalg,1},    {"algtodalg",Palgtodalg,1},
         {"dalgtoalg",Pdalgtoalg,1},    {"dalgtoalg",Pdalgtoalg,1},
         {"dalgtodp",Pdalgtodp,1},    {"dalgtodp",Pdalgtodp,1},
         {"dalgtoup",Pdalgtoup,1},    {"dalgtoup",Pdalgtoup,1},
         {"dptodalg",Pdptodalg,1},    {"dptodalg",Pdptodalg,1},
         {"inv_or_split_dalg",Pinv_or_split_dalg,1},    {"inv_or_split_dalg",Pinv_or_split_dalg,1},
         {"invalg_chrem",Pinvalg_chrem,2},    {"invalg_chrem",Pinvalg_chrem,2},
         {"invalg_le",Pinvalg_le,1},    {"invalg_le",Pinvalg_le,1},
         {"defpoly",Pdefpoly,1},    {"defpoly",Pdefpoly,1},
         {"newalg",Pnewalg,1},    {"newalg",Pnewalg,1},
         {"mainalg",Pmainalg,1},    {"mainalg",Pmainalg,1},
         {"algtorat",Palgtorat,1},    {"algtorat",Palgtorat,1},
         {"rattoalg",Prattoalg,1},    {"rattoalg",Prattoalg,1},
         {"getalg",Pgetalg,1},    {"getalg",Pgetalg,1},
         {"getalgtree",Pgetalgtree,1},    {"getalgtree",Pgetalgtree,1},
         {"alg",Palg,1},    {"alg",Palg,1},
         {"algv",Palgv,1},    {"algv",Palgv,1},
         {0,0,0},    {0,0,0},
 };  };
   
 static int UCN,ACNT;  static int UCN,ACNT;
   
 void Pset_field(NODE arg,Q *rp)  void Pset_field(NODE arg,Q *rp)
 {  {
         int ac;    int ac;
         NODE a0,a1;    NODE a0,a1;
         VL vl0,vl;    VL vl0,vl;
         struct order_spec *spec;    struct order_spec *spec;
   
         if ( (ac = argc(arg)) == 1 )    if ( (ac = argc(arg)) == 1 )
                 setfield_dalg(BDY((LIST)ARG0(arg)));      setfield_dalg(BDY((LIST)ARG0(arg)));
         else if ( ac == 3 ) {    else if ( ac == 3 ) {
                 a0 = BDY((LIST)ARG0(arg));      a0 = BDY((LIST)ARG0(arg));
                 a1 = BDY((LIST)ARG1(arg));      a1 = BDY((LIST)ARG1(arg));
                 for ( vl0 = 0; a1; a1 = NEXT(a1) ) {      for ( vl0 = 0; a1; a1 = NEXT(a1) ) {
                         NEXTVL(vl0,vl);        NEXTVL(vl0,vl);
                         vl->v = VR((P)BDY(a1));        vl->v = VR((P)BDY(a1));
                 }      }
                 if ( vl0 ) NEXT(vl) = 0;      if ( vl0 ) NEXT(vl) = 0;
                 create_order_spec(0,ARG2(arg),&spec);      create_order_spec(0,ARG2(arg),&spec);
                 setfield_gb(a0,vl0,spec);      setfield_gb(a0,vl0,spec);
         }    }
         *rp = 0;    *rp = 0;
 }  }
   
 void Palgtodalg(NODE arg,DAlg *rp)  void Palgtodalg(NODE arg,DAlg *rp)
 {  {
         algtodalg((Alg)ARG0(arg),rp);    algtodalg((Alg)ARG0(arg),rp);
 }  }
   
 void Pdalgtoalg(NODE arg,Alg *rp)  void Pdalgtoalg(NODE arg,Alg *rp)
 {  {
         dalgtoalg((DAlg)ARG0(arg),rp);    dalgtoalg((DAlg)ARG0(arg),rp);
 }  }
   
 void Pdalgtodp(NODE arg,LIST *r)  void Pdalgtodp(NODE arg,LIST *r)
 {  {
         NODE b;    NODE b;
         DP nm;    DP nm;
         Q dn;    Q dn;
         DAlg da;    DAlg da;
   
         da = (DAlg)ARG0(arg);    da = (DAlg)ARG0(arg);
         nm = da->nm;    nm = da->nm;
         dn = da->dn;    dn = da->dn;
         b = mknode(2,nm,dn);    b = mknode(2,nm,dn);
         MKLIST(*r,b);    MKLIST(*r,b);
 }  }
   
 void Pdptodalg(NODE arg,DAlg *r)  void Pdptodalg(NODE arg,DAlg *r)
 {  {
         DP d,nm,nm1;    DP d,nm,nm1;
         MP m;    MP m;
         Q c,a;    Q c,a;
         DAlg t;    DAlg t;
   
         d = (DP)ARG0(arg);    d = (DP)ARG0(arg);
         if ( !d ) *r = 0;    if ( !d ) *r = 0;
         else {    else {
                 for ( m = BDY(d); m; m = NEXT(m) )      for ( m = BDY(d); m; m = NEXT(m) )
                         if ( !INT((Q)m->c) ) break;        if ( !INT((Q)m->c) ) break;
                 if ( !m ) {      if ( !m ) {
                         MKDAlg(d,(Q)ONE,t);        MKDAlg(d,(Q)ONE,t);
                 } else {      } else {
                         dp_ptozp(d,&nm);        dp_ptozp(d,&nm);
                         divq((Q)BDY(d)->c,(Q)BDY(nm)->c,&c);        divq((Q)BDY(d)->c,(Q)BDY(nm)->c,&c);
                         NTOQ(NM(c),SGN(c),a);        NTOQ(NM(c),SGN(c),a);
                         muldc(CO,nm,(Obj)a,&nm1);        muldc(CO,nm,(Obj)a,&nm1);
                         NTOQ(DN(c),1,a);        NTOQ(DN(c),1,a);
                         MKDAlg(nm1,a,t);        MKDAlg(nm1,a,t);
                 }      }
                 simpdalg(t,r);      simpdalg(t,r);
         }    }
 }  }
   
 void Pdalgtoup(NODE arg,LIST *r)  void Pdalgtoup(NODE arg,LIST *r)
 {  {
         NODE b;    NODE b;
         int pos;    int pos;
         P up;    P up;
         DP nm;    DP nm;
         Q dn,q;    Q dn,q;
   
         pos = dalgtoup((DAlg)ARG0(arg),&up,&dn);    pos = dalgtoup((DAlg)ARG0(arg),&up,&dn);
         STOQ(pos,q);    STOQ(pos,q);
         b = mknode(3,up,dn,q);    b = mknode(3,up,dn,q);
         MKLIST(*r,b);    MKLIST(*r,b);
 }  }
   
 NODE inv_or_split_dalg(DAlg,DAlg *);  NODE inv_or_split_dalg(DAlg,DAlg *);
 NumberField     get_numberfield();  NumberField  get_numberfield();
   
 void Pget_field_defpoly(NODE arg,DAlg *r)  void Pget_field_defpoly(NODE arg,DAlg *r)
 {  {
         NumberField nf;    NumberField nf;
         DP d;    DP d;
   
         nf = get_numberfield();    nf = get_numberfield();
         d = nf->ps[QTOS((Q)ARG0(arg))];    d = nf->ps[QTOS((Q)ARG0(arg))];
         MKDAlg(d,ONE,*r);    MKDAlg(d,ONE,*r);
 }  }
   
 void Pget_field_generator(NODE arg,DAlg *r)  void Pget_field_generator(NODE arg,DAlg *r)
 {  {
         int index,n,i;    int index,n,i;
         DL dl;    DL dl;
         MP m;    MP m;
         DP d;    DP d;
   
         index = QTOS((Q)ARG0(arg));    index = QTOS((Q)ARG0(arg));
         n = get_numberfield()->n;    n = get_numberfield()->n;
         NEWDL(dl,n);    NEWDL(dl,n);
         for ( i = 0; i < n; i++ ) dl->d[i] = 0;    for ( i = 0; i < n; i++ ) dl->d[i] = 0;
         dl->d[index] = 1; dl->td = 1;    dl->d[index] = 1; dl->td = 1;
         NEWMP(m); m->dl = dl; m->c = (Obj)ONE; NEXT(m) = 0;    NEWMP(m); m->dl = dl; m->c = (Obj)ONE; NEXT(m) = 0;
         MKDP(n,m,d);    MKDP(n,m,d);
         MKDAlg(d,ONE,*r);    MKDAlg(d,ONE,*r);
 }  }
   
   
 void Pinv_or_split_dalg(NODE arg,Obj *rp)  void Pinv_or_split_dalg(NODE arg,Obj *rp)
 {  {
         NODE gen,t,nd0,nd;    NODE gen,t,nd0,nd;
         LIST list;    LIST list;
         int l,i,j,n;    int l,i,j,n;
         DP *ps,*ps1,*psw;    DP *ps,*ps1,*psw;
         NumberField nf;    NumberField nf;
         DAlg inv;    DAlg inv;
         extern struct order_spec *dp_current_spec;    extern struct order_spec *dp_current_spec;
         struct order_spec *current_spec;    struct order_spec *current_spec;
   
         gen = inv_or_split_dalg((DAlg)ARG0(arg),&inv);    gen = inv_or_split_dalg((DAlg)ARG0(arg),&inv);
         if ( !gen )    if ( !gen )
                 *rp = (Obj)inv;      *rp = (Obj)inv;
         else {    else {
                 nf = get_numberfield();      nf = get_numberfield();
                 current_spec = dp_current_spec; initd(nf->spec);      current_spec = dp_current_spec; initd(nf->spec);
                 l = length(gen);      l = length(gen);
                 n = nf->n;      n = nf->n;
                 ps = nf->ps;      ps = nf->ps;
                 psw = (DP *)ALLOCA((n+l)*sizeof(DP));      psw = (DP *)ALLOCA((n+l)*sizeof(DP));
                 for ( i = j = 0; i < n; i++ ) {      for ( i = j = 0; i < n; i++ ) {
                         for ( t = gen; t; t = NEXT(t) )        for ( t = gen; t; t = NEXT(t) )
                                 if ( dp_redble(ps[i],(DP)BDY(t)) ) break;          if ( dp_redble(ps[i],(DP)BDY(t)) ) break;
                         if ( !t )        if ( !t )
                                 psw[j++] = ps[i];          psw[j++] = ps[i];
                 }      }
                 nd0  = 0;      nd0  = 0;
                 /* gen[0] < gen[1] < ... */      /* gen[0] < gen[1] < ... */
                 /* psw[0] > psw[1] > ... */      /* psw[0] > psw[1] > ... */
                 for ( i = j-1, t = gen; i >= 0 && t; ) {      for ( i = j-1, t = gen; i >= 0 && t; ) {
                         NEXTNODE(nd0,nd);        NEXTNODE(nd0,nd);
                         if ( compd(CO,psw[i],(DP)BDY(t)) > 0 ) {        if ( compd(CO,psw[i],(DP)BDY(t)) > 0 ) {
                                 BDY(nd) = BDY(t); t = NEXT(t);          BDY(nd) = BDY(t); t = NEXT(t);
                         } else        } else
                                 BDY(nd) = (pointer)psw[i--];          BDY(nd) = (pointer)psw[i--];
                 }      }
                 for ( ; i >= 0; i-- ) {      for ( ; i >= 0; i-- ) {
                         NEXTNODE(nd0,nd); BDY(nd) = (pointer)psw[i];        NEXTNODE(nd0,nd); BDY(nd) = (pointer)psw[i];
                 }      }
                 for ( ; t; t = NEXT(t) ) {      for ( ; t; t = NEXT(t) ) {
                         NEXTNODE(nd0,nd); BDY(nd) = BDY(t);        NEXTNODE(nd0,nd); BDY(nd) = BDY(t);
                 }      }
                 NEXT(nd) = 0;      NEXT(nd) = 0;
                 MKLIST(list,nd0);      MKLIST(list,nd0);
                 initd(current_spec);      initd(current_spec);
                 *rp = (Obj)list;      *rp = (Obj)list;
         }    }
 }  }
   
 void Pnewalg(arg,rp)  void Pnewalg(arg,rp)
 NODE arg;  NODE arg;
 Alg *rp;  Alg *rp;
 {  {
         P p;    P p;
         VL vl;    VL vl;
         P c;    P c;
   
         p = (P)ARG0(arg);    p = (P)ARG0(arg);
         if ( !p || OID(p) != O_P )    if ( !p || OID(p) != O_P )
                 error("newalg : invalid argument");      error("newalg : invalid argument");
         clctv(CO,p,&vl);    clctv(CO,p,&vl);
         if ( NEXT(vl) )    if ( NEXT(vl) )
                 error("newalg : invalid argument");      error("newalg : invalid argument");
         c = COEF(DC(p));    c = COEF(DC(p));
         if ( !NUM(c) || !RATN(c) )    if ( !NUM(c) || !RATN(c) )
                 error("newalg : invalid argument");      error("newalg : invalid argument");
         mkalg(p,rp);    mkalg(p,rp);
 }  }
   
 void mkalg(p,r)  void mkalg(p,r)
 P p;  P p;
 Alg *r;  Alg *r;
 {  {
         VL vl,mvl,nvl;    VL vl,mvl,nvl;
         V a,tv;    V a,tv;
         char buf[BUFSIZ];    char buf[BUFSIZ];
         char *name;    char *name;
         P x,t,s;    P x,t,s;
         Num c;    Num c;
         DCP dc,dcr,dcr0;    DCP dc,dcr,dcr0;
   
         for ( vl = ALG; vl; vl = NEXT(vl) )    for ( vl = ALG; vl; vl = NEXT(vl) )
                 if ( !cmpalgp(p,(P)vl->v->attr) ) {      if ( !cmpalgp(p,(P)vl->v->attr) ) {
                         a = vl->v; break;        a = vl->v; break;
                 }      }
         if ( !vl ) {    if ( !vl ) {
                 NEWVL(vl); NEXT(vl) = ALG; ALG = vl;      NEWVL(vl); NEXT(vl) = ALG; ALG = vl;
                 NEWV(a); vl->v = a;      NEWV(a); vl->v = a;
                 sprintf(buf,"#%d",ACNT++);      sprintf(buf,"#%d",ACNT++);
                 name = (char *)MALLOC(strlen(buf)+1);      name = (char *)MALLOC(strlen(buf)+1);
                 strcpy(name,buf); NAME(a) = name;      strcpy(name,buf); NAME(a) = name;
   
                 for ( dc = DC(p), dcr0 = 0; dc; dc = NEXT(dc) ) {      for ( dc = DC(p), dcr0 = 0; dc; dc = NEXT(dc) ) {
                         NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc); c = (Num)COEF(dc);        NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc); c = (Num)COEF(dc);
                         if ( NID(c) != N_A )        if ( NID(c) != N_A )
                                 COEF(dcr) = (P)c;          COEF(dcr) = (P)c;
                         else        else
                                 COEF(dcr) = (P)BDY(((Alg)c));          COEF(dcr) = (P)BDY(((Alg)c));
                 }      }
                 NEXT(dcr) = 0; MKP(a,dcr0,t); a->attr = (pointer)t;      NEXT(dcr) = 0; MKP(a,dcr0,t); a->attr = (pointer)t;
   
                 sprintf(buf,"t%s",name); makevar(buf,&s);      sprintf(buf,"t%s",name); makevar(buf,&s);
   
                 if ( NEXT(ALG) ) {      if ( NEXT(ALG) ) {
                         tv = (V)NEXT(ALG)->v->priv;        tv = (V)NEXT(ALG)->v->priv;
                         for ( vl = CO; NEXT(NEXT(vl)); vl = NEXT(vl) );        for ( vl = CO; NEXT(NEXT(vl)); vl = NEXT(vl) );
                         nvl = NEXT(vl); NEXT(vl) = 0;        nvl = NEXT(vl); NEXT(vl) = 0;
                         for ( vl = CO; NEXT(vl) && (NEXT(vl)->v != tv); vl = NEXT(vl) );        for ( vl = CO; NEXT(vl) && (NEXT(vl)->v != tv); vl = NEXT(vl) );
                         mvl = NEXT(vl); NEXT(vl) = nvl; NEXT(nvl) = mvl;        mvl = NEXT(vl); NEXT(vl) = nvl; NEXT(nvl) = mvl;
                 }      }
   
                 a->priv = (pointer)VR(s); VR(s)->priv = (pointer)a;      a->priv = (pointer)VR(s); VR(s)->priv = (pointer)a;
         }    }
         MKV(a,x); MKAlg(x,*r);    MKV(a,x); MKAlg(x,*r);
 }  }
   
 int cmpalgp(p,defp)  int cmpalgp(p,defp)
 P p,defp;  P p,defp;
 {  {
         DCP dc,dcd;    DCP dc,dcd;
         P t;    P t;
   
         for ( dc = DC(p), dcd = DC(defp); dc && dcd;    for ( dc = DC(p), dcd = DC(defp); dc && dcd;
                 dc = NEXT(dc), dcd = NEXT(dcd) ) {      dc = NEXT(dc), dcd = NEXT(dcd) ) {
                 if ( cmpq(DEG(dc),DEG(dcd)) )      if ( cmpq(DEG(dc),DEG(dcd)) )
                         break;        break;
                 t = NID((Num)COEF(dc)) == N_A ? (P)BDY((Alg)COEF(dc)) : COEF(dc);      t = NID((Num)COEF(dc)) == N_A ? (P)BDY((Alg)COEF(dc)) : COEF(dc);
                 if ( compp(ALG,t,COEF(dcd)) )      if ( compp(ALG,t,COEF(dcd)) )
                         break;        break;
         }    }
         if ( dc || dcd )    if ( dc || dcd )
                 return 1;      return 1;
         else    else
                 return 0;      return 0;
 }  }
   
 void Pdefpoly(arg,rp)  void Pdefpoly(arg,rp)
 NODE arg;  NODE arg;
 P *rp;  P *rp;
 {  {
         asir_assert(ARG0(arg),O_N,"defpoly");    asir_assert(ARG0(arg),O_N,"defpoly");
         algptop((P)VR((P)BDY((Alg)ARG0(arg)))->attr,rp);    algptop((P)VR((P)BDY((Alg)ARG0(arg)))->attr,rp);
 }  }
   
 void Pmainalg(arg,r)  void Pmainalg(arg,r)
 NODE arg;  NODE arg;
 Alg *r;  Alg *r;
 {  {
         Num c;    Num c;
         V v;    V v;
         P b;    P b;
   
         c = (Num)(ARG0(arg));    c = (Num)(ARG0(arg));
         if ( NID(c) <= N_R )    if ( NID(c) <= N_R )
                 *r = 0;      *r = 0;
         else {    else {
                 v = VR((P)BDY((Alg)c)); MKV(v,b); MKAlg(b,*r);      v = VR((P)BDY((Alg)c)); MKV(v,b); MKAlg(b,*r);
         }    }
 }  }
   
 void Palgtorat(arg,rp)  void Palgtorat(arg,rp)
 NODE arg;  NODE arg;
 Obj *rp;  Obj *rp;
 {  {
         asir_assert(ARG0(arg),O_N,"algtorat");    asir_assert(ARG0(arg),O_N,"algtorat");
         algtorat((Num)ARG0(arg),rp);    algtorat((Num)ARG0(arg),rp);
 }  }
   
 void Prattoalg(arg,rp)  void Prattoalg(arg,rp)
 NODE arg;  NODE arg;
 Alg *rp;  Alg *rp;
 {  {
         asir_assert(ARG0(arg),O_R,"rattoalg");    asir_assert(ARG0(arg),O_R,"rattoalg");
         rattoalg((Obj)ARG0(arg),rp);    rattoalg((Obj)ARG0(arg),rp);
 }  }
   
 void Pgetalg(arg,rp)  void Pgetalg(arg,rp)
 NODE arg;  NODE arg;
 LIST *rp;  LIST *rp;
 {  {
         Obj t;    Obj t;
         P p;    P p;
         VL vl;    VL vl;
         Num a;    Num a;
         Alg b;    Alg b;
         NODE n0,n;    NODE n0,n;
   
         if ( !(a = (Num)ARG0(arg)) || NID(a) <= N_R )    if ( !(a = (Num)ARG0(arg)) || NID(a) <= N_R )
                 vl = 0;      vl = 0;
         else {    else {
                 t = BDY((Alg)a);      t = BDY((Alg)a);
                 switch ( OID(t) ) {      switch ( OID(t) ) {
                         case O_P: case O_R:        case O_P: case O_R:
                                 clctvr(ALG,t,&vl); break;          clctvr(ALG,t,&vl); break;
                         default:        default:
                                 vl = 0; break;          vl = 0; break;
                 }      }
         }    }
         for ( n0 = 0; vl; vl = NEXT(vl) ) {    for ( n0 = 0; vl; vl = NEXT(vl) ) {
                 NEXTNODE(n0,n); MKV(vl->v,p); MKAlg(p,b); BDY(n) = (pointer)b;      NEXTNODE(n0,n); MKV(vl->v,p); MKAlg(p,b); BDY(n) = (pointer)b;
         }    }
         if ( n0 )    if ( n0 )
                 NEXT(n) = 0;      NEXT(n) = 0;
         MKLIST(*rp,n0);    MKLIST(*rp,n0);
 }  }
   
 void Pgetalgtree(arg,rp)  void Pgetalgtree(arg,rp)
 NODE arg;  NODE arg;
 LIST *rp;  LIST *rp;
 {  {
         Obj t;    Obj t;
         P p;    P p;
         VL vl,vl1,vl2;    VL vl,vl1,vl2;
         Num a;    Num a;
         Alg b;    Alg b;
         NODE n0,n;    NODE n0,n;
   
 #if 0  #if 0
         if ( !(a = (Num)ARG0(arg)) || NID(a) <= N_R )    if ( !(a = (Num)ARG0(arg)) || NID(a) <= N_R )
                 vl = 0;      vl = 0;
         else {    else {
                 t = BDY((Alg)a);      t = BDY((Alg)a);
                 switch ( OID(t) ) {      switch ( OID(t) ) {
                         case O_P:        case O_P:
                                 clctalg((P)t,&vl); break;          clctalg((P)t,&vl); break;
                         case O_R:        case O_R:
                                 clctalg(NM((R)t),&vl1);          clctalg(NM((R)t),&vl1);
                                 clctalg(DN((R)t),&vl2);          clctalg(DN((R)t),&vl2);
                                 mergev(ALG,vl1,vl2,&vl); break;          mergev(ALG,vl1,vl2,&vl); break;
                         default:        default:
                                 vl = 0; break;          vl = 0; break;
                 }      }
         }    }
 #else  #else
         get_algtree((Obj)ARG0(arg),&vl);    get_algtree((Obj)ARG0(arg),&vl);
 #endif  #endif
         for ( n0 = 0; vl; vl = NEXT(vl) ) {    for ( n0 = 0; vl; vl = NEXT(vl) ) {
                 NEXTNODE(n0,n); MKV(vl->v,p); MKAlg(p,b); BDY(n) = (pointer)b;      NEXTNODE(n0,n); MKV(vl->v,p); MKAlg(p,b); BDY(n) = (pointer)b;
         }    }
         if ( n0 )    if ( n0 )
                 NEXT(n) = 0;      NEXT(n) = 0;
         MKLIST(*rp,n0);    MKLIST(*rp,n0);
 }  }
   
 void clctalg(p,vl)  void clctalg(p,vl)
 P p;  P p;
 VL *vl;  VL *vl;
 {  {
         int n,i;    int n,i;
         VL tvl;    VL tvl;
         VN vn,vn1;    VN vn,vn1;
         P d;    P d;
         DCP dc;    DCP dc;
   
         for ( n = 0, tvl = ALG; tvl; tvl = NEXT(tvl), n++ );    for ( n = 0, tvl = ALG; tvl; tvl = NEXT(tvl), n++ );
         vn = (VN) ALLOCA((n+1)*sizeof(struct oVN));    vn = (VN) ALLOCA((n+1)*sizeof(struct oVN));
         for ( i = n-1, tvl = ALG; tvl; tvl = NEXT(tvl), i-- ) {    for ( i = n-1, tvl = ALG; tvl; tvl = NEXT(tvl), i-- ) {
                 vn[i].v = tvl->v;      vn[i].v = tvl->v;
                 vn[i].n = 0;      vn[i].n = 0;
         }    }
         markv(vn,n,p);    markv(vn,n,p);
         for ( i = n-1; i >= 0; i-- ) {    for ( i = n-1; i >= 0; i-- ) {
                 if ( !vn[i].n )      if ( !vn[i].n )
                         continue;        continue;
                 d = (P)vn[i].v->attr;      d = (P)vn[i].v->attr;
                 for ( dc = DC(d); dc; dc = NEXT(dc) )      for ( dc = DC(d); dc; dc = NEXT(dc) )
                         markv(vn,i,COEF(dc));        markv(vn,i,COEF(dc));
         }    }
         vn1 = (VN) ALLOCA((n+1)*sizeof(struct oVN));    vn1 = (VN) ALLOCA((n+1)*sizeof(struct oVN));
         for ( i = 0; i < n; i++ ) {    for ( i = 0; i < n; i++ ) {
                 vn1[i].v = vn[n-1-i].v; vn1[i].n = vn[n-1-i].n;      vn1[i].v = vn[n-1-i].v; vn1[i].n = vn[n-1-i].n;
         }    }
         vntovl(vn1,n,vl);    vntovl(vn1,n,vl);
 }  }
   
 void Palg(arg,rp)  void Palg(arg,rp)
 NODE arg;  NODE arg;
 Alg *rp;  Alg *rp;
 {  {
         Q a;    Q a;
         VL vl;    VL vl;
         P x;    P x;
         int n;    int n;
   
         a = (Q)ARG0(arg);    a = (Q)ARG0(arg);
         if ( a && (OID(a) != O_N || NID(a) != N_Q || !INT(a)) )    if ( a && (OID(a) != O_N || NID(a) != N_Q || !INT(a)) )
                 *rp = 0;      *rp = 0;
         else {    else {
                 n = ACNT-QTOS(a)-1;      n = ACNT-QTOS(a)-1;
                 for ( vl = ALG; vl && n; vl = NEXT(vl), n-- );      for ( vl = ALG; vl && n; vl = NEXT(vl), n-- );
                 if ( vl ) {      if ( vl ) {
                         MKV(vl->v,x); MKAlg(x,*rp);        MKV(vl->v,x); MKAlg(x,*rp);
                 } else      } else
                         *rp = 0;        *rp = 0;
         }    }
 }  }
   
 void Palgv(arg,rp)  void Palgv(arg,rp)
 NODE arg;  NODE arg;
 Obj *rp;  Obj *rp;
 {  {
         Q a;    Q a;
         VL vl;    VL vl;
         P x;    P x;
         int n;    int n;
         Alg b;    Alg b;
   
         a = (Q)ARG0(arg);    a = (Q)ARG0(arg);
         if ( a && (OID(a) != O_N || NID(a) != N_Q || !INT(a)) )    if ( a && (OID(a) != O_N || NID(a) != N_Q || !INT(a)) )
                 *rp = 0;      *rp = 0;
         else {    else {
                 n = ACNT-QTOS(a)-1;      n = ACNT-QTOS(a)-1;
                 for ( vl = ALG; vl && n; vl = NEXT(vl), n-- );      for ( vl = ALG; vl && n; vl = NEXT(vl), n-- );
                 if ( vl ) {      if ( vl ) {
                         MKV(vl->v,x); MKAlg(x,b); algtorat((Num)b,rp);        MKV(vl->v,x); MKAlg(x,b); algtorat((Num)b,rp);
                 } else      } else
                         *rp = 0;        *rp = 0;
         }    }
 }  }
   
 void algptop(p,r)  void algptop(p,r)
 P p,*r;  P p,*r;
 {  {
         DCP dc,dcr,dcr0;    DCP dc,dcr,dcr0;
   
         if ( NUM(p) )    if ( NUM(p) )
                 *r = (P)p;      *r = (P)p;
         else {    else {
                 for ( dc = DC(p), dcr0 = 0; dc; dc = NEXT(dc) ) {      for ( dc = DC(p), dcr0 = 0; dc; dc = NEXT(dc) ) {
                         NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc);        NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc);
                         algptop(COEF(dc),&COEF(dcr));        algptop(COEF(dc),&COEF(dcr));
                 }      }
                 NEXT(dcr) = 0; MKP((V)(VR(p)->priv),dcr0,*r);      NEXT(dcr) = 0; MKP((V)(VR(p)->priv),dcr0,*r);
         }    }
 }  }
   
 void algtorat(n,r)  void algtorat(n,r)
 Num n;  Num n;
 Obj *r;  Obj *r;
 {  {
         Obj obj;    Obj obj;
         P nm,dn;    P nm,dn;
   
         if ( !n || NID(n) <= N_R )    if ( !n || NID(n) <= N_R )
                 *r = (Obj)n;      *r = (Obj)n;
         else {    else {
                 obj = BDY((Alg)n);      obj = BDY((Alg)n);
                 if ( ID(obj) <= O_P )      if ( ID(obj) <= O_P )
                         algptop((P)obj,(P *)r);        algptop((P)obj,(P *)r);
                 else {      else {
                         algptop(NM((R)obj),&nm); algptop(DN((R)obj),&dn);        algptop(NM((R)obj),&nm); algptop(DN((R)obj),&dn);
                         divr(CO,(Obj)nm,(Obj)dn,r);        divr(CO,(Obj)nm,(Obj)dn,r);
                 }      }
         }    }
 }  }
   
 void rattoalg(obj,n)  void rattoalg(obj,n)
 Obj obj;  Obj obj;
 Alg *n;  Alg *n;
 {  {
         P nm,dn;    P nm,dn;
         Obj t;    Obj t;
   
         if ( !obj || ID(obj) == O_N )    if ( !obj || ID(obj) == O_N )
                 *n = (Alg)obj;      *n = (Alg)obj;
         else if ( ID(obj) == O_P ) {    else if ( ID(obj) == O_P ) {
                 ptoalgp((P)obj,(P *)&t); MKAlg(t,*n);      ptoalgp((P)obj,(P *)&t); MKAlg(t,*n);
         } else {    } else {
                 ptoalgp(NM((R)obj),&nm); ptoalgp(DN((R)obj),&dn);      ptoalgp(NM((R)obj),&nm); ptoalgp(DN((R)obj),&dn);
                 divr(ALG,(Obj)nm,(Obj)dn,&t); MKAlg(t,*n);      divr(ALG,(Obj)nm,(Obj)dn,&t); MKAlg(t,*n);
         }    }
 }  }
   
 void ptoalgp(p,r)  void ptoalgp(p,r)
 P p,*r;  P p,*r;
 {  {
         DCP dc,dcr,dcr0;    DCP dc,dcr,dcr0;
   
         if ( NUM(p) )    if ( NUM(p) )
                 *r = (P)p;      *r = (P)p;
         else {    else {
                 for ( dc = DC(p), dcr0 = 0; dc; dc = NEXT(dc) ) {      for ( dc = DC(p), dcr0 = 0; dc; dc = NEXT(dc) ) {
                         NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc);        NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc);
                         ptoalgp(COEF(dc),&COEF(dcr));        ptoalgp(COEF(dc),&COEF(dcr));
                 }      }
                 NEXT(dcr) = 0; MKP((V)(VR(p)->priv),dcr0,*r);      NEXT(dcr) = 0; MKP((V)(VR(p)->priv),dcr0,*r);
         }    }
 }  }
   
 void Pinvalg_chrem(NODE arg,LIST *r)  void Pinvalg_chrem(NODE arg,LIST *r)
 {  {
         NODE n;    NODE n;
   
         inva_chrem((P)ARG0(arg),(P)ARG1(arg),&n);    inva_chrem((P)ARG0(arg),(P)ARG1(arg),&n);
         MKLIST(*r,n);    MKLIST(*r,n);
 }  }
   
 void invalg_le(Alg a,LIST *r);  void invalg_le(Alg a,LIST *r);
   
 void Pinvalg_le(NODE arg,LIST *r)  void Pinvalg_le(NODE arg,LIST *r)
 {  {
         invalg_le((Alg)ARG0(arg),r);    invalg_le((Alg)ARG0(arg),r);
 }  }
   
 typedef struct oMono_nf {  typedef struct oMono_nf {
         DP mono;    DP mono;
         DP nf;    DP nf;
         Q dn;    Q dn;
 } *Mono_nf;  } *Mono_nf;
   
 void invalg_le(Alg a,LIST *r)  void invalg_le(Alg a,LIST *r)
 {  {
         Alg inv;    Alg inv;
         MAT mobj,sol;    MAT mobj,sol;
         int *rinfo,*cinfo;    int *rinfo,*cinfo;
         P p,dn,dn1,ap;    P p,dn,dn1,ap;
         VL vl,tvl;    VL vl,tvl;
         Q c1,c2,c3,cont,c,two,iq,dn0,mul,dnsol;    Q c1,c2,c3,cont,c,two,iq,dn0,mul,dnsol;
         int i,j,n,len,k;    int i,j,n,len,k;
         MP mp,mp0;    MP mp,mp0;
         DP dp,nm,nm1,m,d,u,u1;    DP dp,nm,nm1,m,d,u,u1;
         NODE b,b1,hlist,mblist,t,s,rev0,rev,hist;    NODE b,b1,hlist,mblist,t,s,rev0,rev,hist;
         DP *ps;    DP *ps;
         struct order_spec *spec;    struct order_spec *spec;
         Mono_nf h,h1;    Mono_nf h,h1;
         N nq,nr,nl,ng;    N nq,nr,nl,ng;
         Q **mat,**solmat;    Q **mat,**solmat;
         Q *w;    Q *w;
         int *wi;    int *wi;
   
         ap = (P)BDY(a);    ap = (P)BDY(a);
         asir_assert(ap,O_P,"invalg_le");    asir_assert(ap,O_P,"invalg_le");
   
         /* collecting algebraic numbers */    /* collecting algebraic numbers */
         clctalg(ap,&vl);    clctalg(ap,&vl);
   
         /* setup */    /* setup */
         ptozp(ap,1,&c,&p);    ptozp(ap,1,&c,&p);
         STOQ(2,two); create_order_spec(0,(Obj)two,&spec); initd(spec);    STOQ(2,two); create_order_spec(0,(Obj)two,&spec); initd(spec);
         for ( n = 0, tvl = vl; tvl; tvl = NEXT(tvl), n++ );    for ( n = 0, tvl = vl; tvl; tvl = NEXT(tvl), n++ );
         ps = (DP *)ALLOCA(n*sizeof(DP));    ps = (DP *)ALLOCA(n*sizeof(DP));
   
         /* conversion to DP */    /* conversion to DP */
         for ( i = 0, tvl = vl; i < n; i++, tvl = NEXT(tvl) ) {    for ( i = 0, tvl = vl; i < n; i++, tvl = NEXT(tvl) ) {
                 ptod(ALG,vl,tvl->v->attr,&ps[i]);      ptod(ALG,vl,tvl->v->attr,&ps[i]);
         }    }
         ptod(ALG,vl,p,&dp);    ptod(ALG,vl,p,&dp);
         /* index list */    /* index list */
         for ( b = 0, i = 0; i < n; i++ ) {    for ( b = 0, i = 0; i < n; i++ ) {
                 STOQ(i,iq); MKNODE(b1,(pointer)iq,b); b = b1;      STOQ(i,iq); MKNODE(b1,(pointer)iq,b); b = b1;
         }    }
         /* simplification */    /* simplification */
         dp_true_nf(b,dp,ps,1,&nm,&dn);    dp_true_nf(b,dp,ps,1,&nm,&dn);
   
         /* construction of NF table */    /* construction of NF table */
   
         /* stdmono: <<0,...,0>> < ... < max */    /* stdmono: <<0,...,0>> < ... < max */
         for ( hlist = 0, i = 0; i < n; i++ ) {    for ( hlist = 0, i = 0; i < n; i++ ) {
                 MKNODE(b1,(pointer)ps[i],hlist); hlist = b1;      MKNODE(b1,(pointer)ps[i],hlist); hlist = b1;
         }    }
         dp_mbase(hlist,&rev0);    dp_mbase(hlist,&rev0);
         for ( mblist = 0, rev = rev0; rev; rev = NEXT(rev) ) {    for ( mblist = 0, rev = rev0; rev; rev = NEXT(rev) ) {
                 MKNODE(b1,BDY(rev),mblist); mblist = b1;      MKNODE(b1,BDY(rev),mblist); mblist = b1;
         }    }
         dn0 = ONE;    dn0 = ONE;
         for ( hist = 0, t = mblist; t; t = NEXT(t) ) {    for ( hist = 0, t = mblist; t; t = NEXT(t) ) {
                 /* searching a predecessor */      /* searching a predecessor */
                 for ( m = (DP)BDY(t), s = hist; s; s = NEXT(s) ) {      for ( m = (DP)BDY(t), s = hist; s; s = NEXT(s) ) {
                         h = (Mono_nf)BDY(s);        h = (Mono_nf)BDY(s);
                         if ( dp_redble(m,h->mono) )        if ( dp_redble(m,h->mono) )
                                 break;          break;
                 }      }
                 h1 = (Mono_nf)ALLOCA(sizeof(struct oMono_nf));      h1 = (Mono_nf)ALLOCA(sizeof(struct oMono_nf));
                 if ( s ) {      if ( s ) {
                         dp_subd(m,h->mono,&d);        dp_subd(m,h->mono,&d);
                         muld(CO,d,h->nf,&u);        muld(CO,d,h->nf,&u);
                         dp_true_nf(b,u,ps,1,&nm1,&dn1);        dp_true_nf(b,u,ps,1,&nm1,&dn1);
                         mulq(h->dn,(Q)dn1,&h1->dn);        mulq(h->dn,(Q)dn1,&h1->dn);
                 } else {      } else {
                         muld(CO,m,nm,&u);        muld(CO,m,nm,&u);
                         dp_true_nf(b,u,ps,1,&nm1,&dn1);        dp_true_nf(b,u,ps,1,&nm1,&dn1);
                         h1->dn = (Q)dn1;        h1->dn = (Q)dn1;
                 }      }
                 h1->mono = m;      h1->mono = m;
                 h1->nf = nm1;      h1->nf = nm1;
                 MKNODE(b1,(pointer)h1,hist); hist = b1;      MKNODE(b1,(pointer)h1,hist); hist = b1;
   
                 /* dn0 = LCM(dn0,h1->dn) */      /* dn0 = LCM(dn0,h1->dn) */
                 gcdn(NM(dn0),NM(h1->dn),&ng); divn(NM(dn0),ng,&nq,&nr);      gcdn(NM(dn0),NM(h1->dn),&ng); divn(NM(dn0),ng,&nq,&nr);
                 muln(nq,NM(h1->dn),&nl); NTOQ(nl,1,dn0);      muln(nq,NM(h1->dn),&nl); NTOQ(nl,1,dn0);
         }    }
         /* create a matrix */    /* create a matrix */
         len = length(mblist);    len = length(mblist);
         MKMAT(mobj,len,len+1);    MKMAT(mobj,len,len+1);
         mat = (Q **)BDY(mobj);    mat = (Q **)BDY(mobj);
         mat[len-1][len] = dn0;    mat[len-1][len] = dn0;
         for ( j = 0, t = hist; j < len; j++, t = NEXT(t) ) {    for ( j = 0, t = hist; j < len; j++, t = NEXT(t) ) {
                 h = (Mono_nf)BDY(t);      h = (Mono_nf)BDY(t);
                 nm1 = h->nf;      nm1 = h->nf;
                 divq((Q)dn0,h->dn,&mul);      divq((Q)dn0,h->dn,&mul);
                 for ( i = 0, rev = rev0, mp = BDY(nm1); mp && i < len; i++, rev = NEXT(rev) )      for ( i = 0, rev = rev0, mp = BDY(nm1); mp && i < len; i++, rev = NEXT(rev) )
                         if ( dl_equal(n,BDY((DP)BDY(rev))->dl,mp->dl) ) {        if ( dl_equal(n,BDY((DP)BDY(rev))->dl,mp->dl) ) {
                                 mulq(mul,(Q)mp->c,&mat[i][j]);          mulq(mul,(Q)mp->c,&mat[i][j]);
                                 mp = NEXT(mp);          mp = NEXT(mp);
                         }        }
         }    }
 #if 0  #if 0
         w = (Q *)ALLOCA((len+1)*sizeof(Q));    w = (Q *)ALLOCA((len+1)*sizeof(Q));
         wi = (int *)ALLOCA((len+1)*sizeof(int));    wi = (int *)ALLOCA((len+1)*sizeof(int));
         for ( i = 0; i < len; i++ ) {    for ( i = 0; i < len; i++ ) {
                 for ( j = 0, k = 0; j <= len; j++ )      for ( j = 0, k = 0; j <= len; j++ )
                         if ( mat[i][j] ) {        if ( mat[i][j] ) {
                                 w[k] = mat[i][j];          w[k] = mat[i][j];
                                 wi[k] = j;          wi[k] = j;
                                 k++;          k++;
                         }        }
                 removecont_array(w,k);      removecont_array(w,k);
                 for ( j = 0; j < k; j++ )      for ( j = 0; j < k; j++ )
                         mat[i][wi[j]] = w[j];        mat[i][wi[j]] = w[j];
         }    }
 #endif  #endif
         generic_gauss_elim_hensel(mobj,&sol,&dnsol,&rinfo,&cinfo);    generic_gauss_elim_hensel(mobj,&sol,&dnsol,&rinfo,&cinfo);
         solmat = (Q **)BDY(sol);    solmat = (Q **)BDY(sol);
         for ( i = 0, t = rev0, mp0 = 0; i < len; i++, t = NEXT(t) )    for ( i = 0, t = rev0, mp0 = 0; i < len; i++, t = NEXT(t) )
                 if ( solmat[i][0] ) {      if ( solmat[i][0] ) {
                         NEXTMP(mp0,mp);        NEXTMP(mp0,mp);
                         mp->c = (Obj)solmat[i][0];        mp->c = (Obj)solmat[i][0];
                         mp->dl = BDY((DP)BDY(t))->dl;        mp->dl = BDY((DP)BDY(t))->dl;
                 }      }
         NEXT(mp) = 0; MKDP(n,mp0,u);    NEXT(mp) = 0; MKDP(n,mp0,u);
         dp_ptozp(u,&u1);    dp_ptozp(u,&u1);
         divq((Q)BDY(u)->c,(Q)BDY(u1)->c,&cont);    divq((Q)BDY(u)->c,(Q)BDY(u1)->c,&cont);
         dtop(ALG,vl,u1,(Obj *)&ap);    dtop(ALG,vl,u1,(Obj *)&ap);
         MKAlg(ap,inv);    MKAlg(ap,inv);
         mulq(dnsol,(Q)dn,&c1);    mulq(dnsol,(Q)dn,&c1);
         mulq(c1,c,&c2);    mulq(c1,c,&c2);
         divq(c2,cont,&c3);    divq(c2,cont,&c3);
         b = mknode(2,inv,c3);    b = mknode(2,inv,c3);
         MKLIST(*r,b);    MKLIST(*r,b);
 }  }
   
 void get_algtree(Obj f,VL *r)  void get_algtree(Obj f,VL *r)
 {  {
         VL vl1,vl2,vl3;    VL vl1,vl2,vl3;
         Obj t;    Obj t;
         DCP dc;    DCP dc;
         NODE b;    NODE b;
         pointer *a;    pointer *a;
         pointer **m;    pointer **m;
         int len,row,col,i,j,l;    int len,row,col,i,j,l;
   
         if ( !f ) *r = 0;    if ( !f ) *r = 0;
         else    else
                 switch ( OID(f) ) {      switch ( OID(f) ) {
                         case O_N:        case O_N:
                                 if ( NID((Num)f) != N_A ) *r = 0;          if ( NID((Num)f) != N_A ) *r = 0;
                                 else  {          else  {
                                         t = BDY((Alg)f);            t = BDY((Alg)f);
                                         switch ( OID(t) ) {            switch ( OID(t) ) {
                                                 case O_P:              case O_P:
                                                         clctalg((P)t,r); break;                clctalg((P)t,r); break;
                                                 case O_R:              case O_R:
                                                         clctalg(NM((R)t),&vl1);                clctalg(NM((R)t),&vl1);
                                                         clctalg(DN((R)t),&vl2);                clctalg(DN((R)t),&vl2);
                                                         mergev(ALG,vl1,vl2,r); break;                mergev(ALG,vl1,vl2,r); break;
                                                 default:              default:
                                                         *r = 0; break;                *r = 0; break;
                                         }            }
                                 }          }
                                 break;          break;
                         case O_P:        case O_P:
                                 vl1 = 0;          vl1 = 0;
                                 for ( dc = DC((P)f); dc; dc = NEXT(dc) ) {          for ( dc = DC((P)f); dc; dc = NEXT(dc) ) {
                                         get_algtree((Obj)COEF(dc),&vl2);            get_algtree((Obj)COEF(dc),&vl2);
                                         mergev(ALG,vl1,vl2,&vl3);            mergev(ALG,vl1,vl2,&vl3);
                                         vl1 = vl3;            vl1 = vl3;
                                 }          }
                                 *r = vl1;          *r = vl1;
                                 break;          break;
                         case O_R:        case O_R:
                                 get_algtree((Obj)NM((R)f),&vl1);          get_algtree((Obj)NM((R)f),&vl1);
                                 get_algtree((Obj)DN((R)f),&vl2);          get_algtree((Obj)DN((R)f),&vl2);
                                 mergev(ALG,vl1,vl2,r);          mergev(ALG,vl1,vl2,r);
                                 break;          break;
                         case O_LIST:        case O_LIST:
                                 vl1 = 0;          vl1 = 0;
                                 for ( b = BDY((LIST)f); b; b = NEXT(b) ) {          for ( b = BDY((LIST)f); b; b = NEXT(b) ) {
                                         get_algtree((Obj)BDY(b),&vl2);            get_algtree((Obj)BDY(b),&vl2);
                                         mergev(ALG,vl1,vl2,&vl3);            mergev(ALG,vl1,vl2,&vl3);
                                         vl1 = vl3;            vl1 = vl3;
                                 }          }
                                 *r = vl1;          *r = vl1;
                                 break;          break;
                         case O_VECT:        case O_VECT:
                                 vl1 = 0;          vl1 = 0;
                                 l = ((VECT)f)->len;          l = ((VECT)f)->len;
                                 a = BDY((VECT)f);          a = BDY((VECT)f);
                                 for ( i = 0; i < l; i++ ) {          for ( i = 0; i < l; i++ ) {
                                         get_algtree((Obj)a[i],&vl2);            get_algtree((Obj)a[i],&vl2);
                                         mergev(ALG,vl1,vl2,&vl3);            mergev(ALG,vl1,vl2,&vl3);
                                         vl1 = vl3;            vl1 = vl3;
                                 }          }
                                 *r = vl1;          *r = vl1;
                                 break;          break;
                         case O_MAT:        case O_MAT:
                                 vl1 = 0;          vl1 = 0;
                                 row = ((MAT)f)->row; col = ((MAT)f)->col;          row = ((MAT)f)->row; col = ((MAT)f)->col;
                                 m = BDY((MAT)f);          m = BDY((MAT)f);
                                 for ( i = 0; i < row; i++ )          for ( i = 0; i < row; i++ )
                                         for ( j = 0; j < col; j++ ) {            for ( j = 0; j < col; j++ ) {
                                                 get_algtree((Obj)m[i][j],&vl2);              get_algtree((Obj)m[i][j],&vl2);
                                                 mergev(ALG,vl1,vl2,&vl3);              mergev(ALG,vl1,vl2,&vl3);
                                                 vl1 = vl3;              vl1 = vl3;
                                         }            }
                                 *r = vl1;          *r = vl1;
                                 break;          break;
                         default:        default:
                                 *r = 0;          *r = 0;
                                 break;          break;
                 }      }
 }  }
   
 void algobjtorat(Obj f,Obj *r)  void algobjtorat(Obj f,Obj *r)
 {  {
         Obj t;    Obj t;
         DCP dc,dcr,dcr0;    DCP dc,dcr,dcr0;
         P p,nm,dn;    P p,nm,dn;
         R rat;    R rat;
         NODE b,s,s0;    NODE b,s,s0;
         VECT v;    VECT v;
         MAT mat;    MAT mat;
         LIST list;    LIST list;
         pointer *a;    pointer *a;
         pointer **m;    pointer **m;
         int len,row,col,i,j,l;    int len,row,col,i,j,l;
   
         if ( !f ) *r = 0;    if ( !f ) *r = 0;
         else    else
                 switch ( OID(f) ) {      switch ( OID(f) ) {
                         case O_N:        case O_N:
                                 algtorat((Num)f,r);          algtorat((Num)f,r);
                                 break;          break;
                         case O_P:        case O_P:
                                 dcr0 = 0;          dcr0 = 0;
                                 for ( dc = DC((P)f); dc; dc = NEXT(dc) ) {          for ( dc = DC((P)f); dc; dc = NEXT(dc) ) {
                                         NEXTDC(dcr0,dcr);            NEXTDC(dcr0,dcr);
                                         algobjtorat((Obj)COEF(dc),&t);            algobjtorat((Obj)COEF(dc),&t);
                                         COEF(dcr) = (P)t;            COEF(dcr) = (P)t;
                                         DEG(dcr) = DEG(dc);            DEG(dcr) = DEG(dc);
                                 }          }
                                 NEXT(dcr) = 0; MKP(VR((P)f),dcr0,p); *r = (Obj)p;          NEXT(dcr) = 0; MKP(VR((P)f),dcr0,p); *r = (Obj)p;
                                 break;          break;
                         case O_R:        case O_R:
                                 algobjtorat((Obj)NM((R)f),&t); nm = (P)t;          algobjtorat((Obj)NM((R)f),&t); nm = (P)t;
                                 algobjtorat((Obj)DN((R)f),&t); dn = (P)t;          algobjtorat((Obj)DN((R)f),&t); dn = (P)t;
                                 MKRAT(nm,dn,0,rat); *r = (Obj)rat;          MKRAT(nm,dn,0,rat); *r = (Obj)rat;
                                 break;          break;
                         case O_LIST:        case O_LIST:
                                 s0 = 0;          s0 = 0;
                                 for ( b = BDY((LIST)f); b; b = NEXT(b) ) {          for ( b = BDY((LIST)f); b; b = NEXT(b) ) {
                                         NEXTNODE(s0,s);            NEXTNODE(s0,s);
                                         algobjtorat((Obj)BDY(b),&t);            algobjtorat((Obj)BDY(b),&t);
                                         BDY(s) = (pointer)t;            BDY(s) = (pointer)t;
                                 }          }
                                 NEXT(s) = 0;          NEXT(s) = 0;
                                 MKLIST(list,s0);          MKLIST(list,s0);
                                 *r = (Obj)list;          *r = (Obj)list;
                                 break;          break;
                         case O_VECT:        case O_VECT:
                                 l = ((VECT)f)->len;          l = ((VECT)f)->len;
                                 a = BDY((VECT)f);          a = BDY((VECT)f);
                                 MKVECT(v,l);          MKVECT(v,l);
                                 for ( i = 0; i < l; i++ ) {          for ( i = 0; i < l; i++ ) {
                                         algobjtorat((Obj)a[i],&t);            algobjtorat((Obj)a[i],&t);
                                         BDY(v)[i] = (pointer)t;            BDY(v)[i] = (pointer)t;
                                 }          }
                                 *r = (Obj)v;          *r = (Obj)v;
                                 break;          break;
                         case O_MAT:        case O_MAT:
                                 row = ((MAT)f)->row; col = ((MAT)f)->col;          row = ((MAT)f)->row; col = ((MAT)f)->col;
                                 m = BDY((MAT)f);          m = BDY((MAT)f);
                                 MKMAT(mat,row,col);          MKMAT(mat,row,col);
                                 for ( i = 0; i < row; i++ )          for ( i = 0; i < row; i++ )
                                         for ( j = 0; j < col; j++ ) {            for ( j = 0; j < col; j++ ) {
                                                 algobjtorat((Obj)m[i][j],&t);              algobjtorat((Obj)m[i][j],&t);
                                                 BDY(mat)[i][j] = (pointer)t;              BDY(mat)[i][j] = (pointer)t;
                                         }            }
                                 *r = (Obj)mat;          *r = (Obj)mat;
                                 break;          break;
                         default:        default:
                                 *r = f;          *r = f;
                                 break;          break;
                 }      }
 }  }

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

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