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

Diff for /OpenXM_contrib2/asir2000/builtin/poly.c between version 1.11 and 1.31

version 1.11, 2001/05/28 08:22:00 version 1.31, 2020/10/04 03:14:07
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/poly.c,v 1.10 2001/05/09 01:41:41 noro Exp $   * $OpenXM: OpenXM_contrib2/asir2000/builtin/poly.c,v 1.30 2018/03/29 01:32:50 noro Exp $
 */  */
 #include "ca.h"  #include "ca.h"
 #include "parse.h"  #include "parse.h"
Line 53 
Line 53 
   
 void Pranp();  void Pranp();
   
   void Pheadsgn();
   void Pmul_trunc(),Pquo_trunc();
 void Pumul(),Pumul_ff(),Pusquare(),Pusquare_ff(),Putmul(),Putmul_ff();  void Pumul(),Pumul_ff(),Pusquare(),Pusquare_ff(),Putmul(),Putmul_ff();
 void Pkmul(),Pksquare(),Pktmul();  void Pkmul(),Pksquare(),Pktmul();
 void Pord(), Pcoef0(), Pcoef(), Pdeg(), Pmindeg(), Psetmod();  void Pord(), Premove_vars(), Pcoef0(), Pcoef(), Pdeg(), Pmindeg(), Psetmod();
 void Pcoef_gf2n();  void Pcoef_gf2n();
 void getcoef(), getdeglist(), mergedeglist(), change_mvar(), restore_mvar();  void getcoef(), getdeglist(), mergedeglist(), change_mvar(), restore_mvar();
   
Line 63  void Pp_mag(),Pmaxblen();
Line 65  void Pp_mag(),Pmaxblen();
 void Pmergelist(), Pch_mv(), Pre_mv(), Pdeglist();  void Pmergelist(), Pch_mv(), Pre_mv(), Pdeglist();
 void Pptomp(),Pmptop();  void Pptomp(),Pmptop();
 void Pptolmp(),Plmptop();  void Pptolmp(),Plmptop();
 void Pptosfp(),Psfptop(),Psf_galois_action();  void Pptosfp(),Psfptop(),Psf_galois_action(),Psf_embed(),Psf_find_root();
   void Psf_minipoly(),Psf_log(),Psfptopsfp();
 void Pptogf2n(),Pgf2ntop(),Pgf2ntovect();  void Pptogf2n(),Pgf2ntop(),Pgf2ntovect();
 void Pptogfpn(),Pgfpntop();  void Pptogfpn(),Pgfpntop();
 void Pfind_root_gf2n();  void Pfind_root_gf2n();
Line 106  void Phomogeneous_deg();
Line 109  void Phomogeneous_deg();
 void simp_ff(Obj,Obj *);  void simp_ff(Obj,Obj *);
 void ranp(int,UP *);  void ranp(int,UP *);
 void field_order_ff(N *);  void field_order_ff(N *);
   void update_LASTCO();
   
 extern int current_mod;  
 extern GEN_UP2 current_mod_gf2n;  
 extern int lm_lazy;  
   
 int current_ff;  int current_ff;
   
 struct ftab poly_tab[] = {  struct ftab poly_tab[] = {
         {"homogeneous_deg",Phomogeneous_deg,-2},    {"headsgn",Pheadsgn,1},
         {"homogeneous_part",Phomogeneous_part,-3},    {"quo_trunc",Pquo_trunc,2},
         {"reorder",Preorder,3},    {"mul_trunc",Pmul_trunc,3},
         {"uadj_coef",Puadj_coef,3},    {"homogeneous_deg",Phomogeneous_deg,-2},
         {"ranp",Pranp,2},    {"homogeneous_part",Phomogeneous_part,-3},
         {"p_mag",Pp_mag,1},    {"reorder",Preorder,3},
         {"maxblen",Pmaxblen,1},    {"uadj_coef",Puadj_coef,3},
         {"ord",Pord,-1},    {"ranp",Pranp,2},
         {"coef0",Pcoef0,-3},    {"p_mag",Pp_mag,1},
         {"coef",Pcoef,-3},    {"maxblen",Pmaxblen,1},
         {"coef_gf2n",Pcoef_gf2n,2},    {"ord",Pord,-1},
         {"deg",Pdeg,2},    {"remove_vars",Premove_vars,1},
         {"mindeg",Pmindeg,2},    {"delete_vars",Premove_vars,1},
         {"setmod",Psetmod,-1},    {"coef0",Pcoef0,-3},
     {"coef",Pcoef,-3},
     {"coef_gf2n",Pcoef_gf2n,2},
     {"deg",Pdeg,2},
     {"mindeg",Pmindeg,2},
     {"setmod",Psetmod,-1},
   
         {"sparsemod_gf2n",Psparsemod_gf2n,-1},    {"sparsemod_gf2n",Psparsemod_gf2n,-1},
   
         {"setmod_ff",Psetmod_ff,-2},    {"setmod_ff",Psetmod_ff,-3},
         {"simp_ff",Psimp_ff,1},    {"simp_ff",Psimp_ff,1},
         {"extdeg_ff",Pextdeg_ff,0},    {"extdeg_ff",Pextdeg_ff,0},
         {"characteristic_ff",Pcharacteristic_ff,0},    {"characteristic_ff",Pcharacteristic_ff,0},
         {"field_type_ff",Pfield_type_ff,0},    {"field_type_ff",Pfield_type_ff,0},
         {"field_order_ff",Pfield_order_ff,0},    {"field_order_ff",Pfield_order_ff,0},
         {"random_ff",Prandom_ff,0},    {"random_ff",Prandom_ff,0},
   
         {"deglist",Pdeglist,2},    {"deglist",Pdeglist,2},
         {"mergelist",Pmergelist,2},    {"mergelist",Pmergelist,2},
         {"ch_mv",Pch_mv,2},    {"ch_mv",Pch_mv,2},
         {"re_mv",Pre_mv,2},    {"re_mv",Pre_mv,2},
   
         {"ptomp",Pptomp,2},    {"ptomp",Pptomp,-2},
         {"mptop",Pmptop,1},    {"mptop",Pmptop,1},
   
         {"ptolmp",Pptolmp,1},    {"ptolmp",Pptolmp,1},
         {"lmptop",Plmptop,1},    {"lmptop",Plmptop,1},
   
         {"sf_galois_action",Psf_galois_action,2},    {"sf_galois_action",Psf_galois_action,2},
         {"ptosfp",Pptosfp,1},    {"sf_find_root",Psf_find_root,1},
         {"sfptop",Psfptop,1},    {"sf_minipoly",Psf_minipoly,2},
     {"sf_embed",Psf_embed,3},
     {"sf_log",Psf_log,1},
   
         {"ptogf2n",Pptogf2n,1},    {"ptosfp",Pptosfp,1},
         {"gf2ntop",Pgf2ntop,-2},    {"sfptop",Psfptop,1},
         {"gf2ntovect",Pgf2ntovect,1},    {"sfptopsfp",Psfptopsfp,2},
     {"ptogf2n",Pptogf2n,1},
     {"gf2ntop",Pgf2ntop,-2},
     {"gf2ntovect",Pgf2ntovect,1},
   
         {"ptogfpn",Pptogfpn,1},    {"ptogfpn",Pptogfpn,1},
         {"gfpntop",Pgfpntop,-2},    {"gfpntop",Pgfpntop,-2},
   
         {"kmul",Pkmul,2},    {"kmul",Pkmul,2},
         {"ksquare",Pksquare,1},    {"ksquare",Pksquare,1},
         {"ktmul",Pktmul,3},    {"ktmul",Pktmul,3},
   
         {"umul",Pumul,2},    {"umul",Pumul,2},
         {"usquare",Pusquare,1},    {"usquare",Pusquare,1},
         {"ureverse_inv_as_power_series",Purevinvmod,2},    {"ureverse_inv_as_power_series",Purevinvmod,2},
         {"uinv_as_power_series",Puinvmod,2},    {"uinv_as_power_series",Puinvmod,2},
   
         {"umul_specialmod",Pumul_specialmod,3},    {"umul_specialmod",Pumul_specialmod,3},
         {"usquare_specialmod",Pusquare_specialmod,2},    {"usquare_specialmod",Pusquare_specialmod,2},
         {"utmul_specialmod",Putmul_specialmod,4},    {"utmul_specialmod",Putmul_specialmod,4},
   
         {"utmul",Putmul,3},    {"utmul",Putmul,3},
         {"umul_ff",Pumul_ff,2},    {"umul_ff",Pumul_ff,2},
         {"usquare_ff",Pusquare_ff,1},    {"usquare_ff",Pusquare_ff,1},
         {"utmul_ff",Putmul_ff,3},    {"utmul_ff",Putmul_ff,3},
   
         /* for historical reason */    /* for historical reason */
         {"trunc",Putrunc,2},    {"trunc",Putrunc,2},
         {"decomp",Pudecomp,2},    {"decomp",Pudecomp,2},
   
         {"utrunc",Putrunc,2},    {"utrunc",Putrunc,2},
         {"udecomp",Pudecomp,2},    {"udecomp",Pudecomp,2},
         {"ureverse",Pureverse,-2},    {"ureverse",Pureverse,-2},
         {"urembymul",Purembymul,2},    {"urembymul",Purembymul,2},
         {"urembymul_precomp",Purembymul_precomp,3},    {"urembymul_precomp",Purembymul_precomp,3},
   
         {"lazy_lm",Plazy_lm,1},    {"lazy_lm",Plazy_lm,1},
         {"lazy_ff",Plazy_lm,1},    {"lazy_ff",Plazy_lm,1},
   
         {"pwrmod_ff",Ppwrmod_ff,1},    {"pwrmod_ff",Ppwrmod_ff,1},
         {"generic_pwrmod_ff",Pgeneric_pwrmod_ff,3},    {"generic_pwrmod_ff",Pgeneric_pwrmod_ff,3},
         {"pwrtab_ff",Ppwrtab_ff,2},    {"pwrtab_ff",Ppwrtab_ff,2},
   
         {"tracemod_gf2n",Ptracemod_gf2n,3},    {"tracemod_gf2n",Ptracemod_gf2n,3},
         {"b_find_root_gf2n",Pfind_root_gf2n,1},    {"b_find_root_gf2n",Pfind_root_gf2n,1},
   
         {"is_irred_gf2",Pis_irred_gf2,1},    {"is_irred_gf2",Pis_irred_gf2,1},
         {"is_irred_ddd_gf2",Pis_irred_ddd_gf2,1},    {"is_irred_ddd_gf2",Pis_irred_ddd_gf2,1},
   
         {"kpwrmod_lm",Pkpwrmod_lm,1},    {"kpwrmod_lm",Pkpwrmod_lm,1},
         {"kgeneric_pwrmod_lm",Pkgeneric_pwrmod_lm,3},    {"kgeneric_pwrmod_lm",Pkgeneric_pwrmod_lm,3},
         {"kpwrtab_lm",Pkpwrtab_lm,2},    {"kpwrtab_lm",Pkpwrtab_lm,2},
   
         {"kmulum",Pkmulum,3},    {"kmulum",Pkmulum,3},
         {"ksquareum",Pksquareum,2},    {"ksquareum",Pksquareum,2},
   
         {"fmultest",Pfmultest,3},    {"fmultest",Pfmultest,3},
         {"hfmul_lm",Phfmul_lm,2},    {"hfmul_lm",Phfmul_lm,2},
   
         {"multest_gf2n",Pmultest_gf2n,2},    {"multest_gf2n",Pmultest_gf2n,2},
         {"squaretest_gf2n",Psquaretest_gf2n,1},    {"squaretest_gf2n",Psquaretest_gf2n,1},
         {"bininv_gf2n",Pbininv_gf2n,2},    {"bininv_gf2n",Pbininv_gf2n,2},
         {"invtest_gf2n",Pinvtest_gf2n,1},    {"invtest_gf2n",Pinvtest_gf2n,1},
         {"rinvtest_gf2n",Prinvtest_gf2n,0},    {"rinvtest_gf2n",Prinvtest_gf2n,0},
         {"get_next_fft_prime",Pget_next_fft_prime,2},    {"get_next_fft_prime",Pget_next_fft_prime,2},
         {0,0,0},    {0,0,0},
 };  };
   
 extern V up_var;  void Pheadsgn(NODE arg,Q *rp)
   {
     int s;
   
 void Phomogeneous_part(arg,rp)    s = headsgn((P)ARG0(arg));
 NODE arg;    STOQ(s,*rp);
 P *rp;  }
   
   void Pmul_trunc(NODE arg,P *rp)
 {  {
         if ( argc(arg) == 2 )    P p1,p2,p,h;
                 exthp(CO,(P)ARG0(arg),QTOS((Q)ARG1(arg)),rp);    VL vl0,vl1,vl2,tvl,vl;
         else    VN vn;
                 exthpc_generic(CO,(P)ARG0(arg),QTOS((Q)ARG2(arg)),    int i,n;
                         VR((P)ARG1(arg)),rp);  
     p1 = (P)ARG0(arg);
     p2 = (P)ARG1(arg);
     get_vars((Obj)p1,&vl1); get_vars((Obj)p2,&vl2); mergev(CO,vl1,vl2,&tvl);
     p = (P)ARG2(arg);
     get_vars((Obj)p,&vl0); mergev(CO,tvl,vl0,&vl);
     for ( tvl = vl, n = 0; tvl; tvl = NEXT(tvl), n++ );
     vn = (VN) ALLOCA((n+1)*sizeof(struct oVN));
     for ( i = 0, tvl = vl; i < n; tvl = NEXT(tvl), i++ ) {
       vn[i].v = tvl->v;
       vn[i].n = 0;
     }
     vn[i].v = 0;
     vn[i].n = 0;
     for ( h = p, i = 0; OID(h) == O_P; h = COEF(DC(h)) ) {
       for ( ; vn[i].v != VR(h); i++ );
       vn[i].n = QTOS(DEG(DC(h)));
     }
     mulp_trunc(vl,p1,p2,vn,rp);
 }  }
   
 void Phomogeneous_deg(arg,rp)  void Pquo_trunc(NODE arg,P *rp)
 NODE arg;  
 Q *rp;  
 {  {
         int d;    P p1,p2,p,h;
     VL vl0,vl1,vl2,tvl,vl;
     VN vn;
     int i,n;
   
         if ( argc(arg) == 1 )    p1 = (P)ARG0(arg);
                 d = homdeg((P)ARG0(arg));    p2 = (P)ARG1(arg);
         else    if ( !p1 )
                 d = getchomdeg(VR((P)ARG1(arg)),(P)ARG0(arg));      *rp = 0;
         STOQ(d,*rp);    else if ( NUM(p2) )
       divsp(CO,p1,p2,rp);
     else {
       get_vars((Obj)p1,&vl1); get_vars((Obj)p2,&vl2); mergev(CO,vl1,vl2,&vl);
       for ( tvl = vl, n = 0; tvl; tvl = NEXT(tvl), n++ );
       vn = (VN) ALLOCA((n+1)*sizeof(struct oVN));
       for ( i = 0, tvl = vl; i < n; tvl = NEXT(tvl), i++ ) {
         vn[i].v = tvl->v;
         vn[i].n = 0;
       }
       vn[i].v = 0;
       vn[i].n = 0;
       for ( h = p2, i = 0; OID(h) == O_P; h = COEF(DC(h)) ) {
         for ( ; vn[i].v != VR(h); i++ );
         vn[i].n = QTOS(DEG(DC(h)));
       }
       quop_trunc(vl,p1,p2,vn,rp);
     }
 }  }
   
   void Phomogeneous_part(NODE arg,P *rp)
   {
     if ( argc(arg) == 2 )
       exthp(CO,(P)ARG0(arg),QTOS((Q)ARG1(arg)),rp);
     else
       exthpc_generic(CO,(P)ARG0(arg),QTOS((Q)ARG2(arg)),
         VR((P)ARG1(arg)),rp);
   }
   
   void Phomogeneous_deg(NODE arg,Q *rp)
   {
     int d;
   
     if ( argc(arg) == 1 )
       d = homdeg((P)ARG0(arg));
     else
       d = getchomdeg(VR((P)ARG1(arg)),(P)ARG0(arg));
     STOQ(d,*rp);
   }
   
 /*  /*
         p1 = reorder(p,ovl,nvl) => p1 is 'sorted accoding to nvl.    p1 = reorder(p,ovl,nvl) => p1 is 'sorted accoding to nvl.
 */  */
   
 void Preorder(arg,rp)  void Preorder(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         VL ovl,nvl,tvl;    VL ovl,nvl,tvl;
         NODE n;    NODE n;
   
         for ( ovl = 0, n = BDY((LIST)ARG1(arg)); n; n = NEXT(n) ) {    for ( ovl = 0, n = BDY((LIST)ARG1(arg)); n; n = NEXT(n) ) {
                 if ( !ovl ) {      if ( !ovl ) {
                         NEWVL(ovl); tvl = ovl;        NEWVL(ovl); tvl = ovl;
                 } else {      } else {
                         NEWVL(NEXT(tvl)); tvl = NEXT(tvl);        NEWVL(NEXT(tvl)); tvl = NEXT(tvl);
                 }      }
                         VR(tvl) = VR((P)BDY(n));        VR(tvl) = VR((P)BDY(n));
         }    }
         for ( nvl = 0, n = BDY((LIST)ARG2(arg)); n; n = NEXT(n) ) {    for ( nvl = 0, n = BDY((LIST)ARG2(arg)); n; n = NEXT(n) ) {
                 if ( !nvl ) {      if ( !nvl ) {
                         NEWVL(nvl); tvl = nvl;        NEWVL(nvl); tvl = nvl;
                 } else {      } else {
                         NEWVL(NEXT(tvl)); tvl = NEXT(tvl);        NEWVL(NEXT(tvl)); tvl = NEXT(tvl);
                 }      }
                         VR(tvl) = VR((P)BDY(n));        VR(tvl) = VR((P)BDY(n));
         }    }
         reorderp(nvl,ovl,(P)ARG0(arg),rp);    reorderp(nvl,ovl,(P)ARG0(arg),rp);
 }  }
   
 /*  /*
         uadj_coef(F,M,M2)    uadj_coef(F,M,M2)
         if ( F is a non-negative integer )    if ( F is a non-negative integer )
                 return F > M2 ? F-M : M2;      return F > M2 ? F-M : M2;
         else    else
                 F = CN*V^N+...+C0      F = CN*V^N+...+C0
                 return uadj_coef(CN,M,M2)*V^N+...+uadj_coef(C0,M,M2);      return uadj_coef(CN,M,M2)*V^N+...+uadj_coef(C0,M,M2);
 */  */
   
 void Puadj_coef(arg,rp)  void Puadj_coef(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         UP f,r;    UP f,r;
         N m,m2;    N m,m2;
   
         ptoup((P)ARG0(arg),&f);    ptoup((P)ARG0(arg),&f);
         m = NM((Q)ARG1(arg));    m = NM((Q)ARG1(arg));
         m2 = NM((Q)ARG2(arg));    m2 = NM((Q)ARG2(arg));
         adj_coefup(f,m,m2,&r);    adj_coefup(f,m,m2,&r);
         uptop(r,rp);    uptop(r,rp);
 }  }
   
 /*  /*
         get_next_fft_prime(StartIndex,Bits)    get_next_fft_prime(StartIndex,Bits)
         tries to find smallest Index >= StartIndex s.t.    tries to find smallest Index >= StartIndex s.t.
                 2^(Bits-1)|FFTprime[Index]-1      2^(Bits-1)|FFTprime[Index]-1
         return [Index,Mod] or 0 (not exist)    return [Index,Mod] or 0 (not exist)
 */  */
   
 void Pget_next_fft_prime(arg,rp)  void Pget_next_fft_prime(NODE arg,LIST *rp)
 NODE arg;  
 LIST *rp;  
 {  {
         unsigned int mod,d;    unsigned int mod,d;
         int start,bits,i;    int start,bits,i;
         NODE n;    NODE n;
         Q q,ind;    Q q,ind;
   
         start = QTOS((Q)ARG0(arg));    start = QTOS((Q)ARG0(arg));
         bits = QTOS((Q)ARG1(arg));    bits = QTOS((Q)ARG1(arg));
         for ( i = start; ; i++ ) {    for ( i = start; ; i++ ) {
                 get_fft_prime(i,&mod,&d);      get_fft_prime(i,&mod,&d);
                 if ( !mod ) {      if ( !mod ) {
                         *rp = 0; return;        *rp = 0; return;
                 }      }
                 if ( bits <= d ) {      if ( bits <= (int)d ) {
                         UTOQ(mod,q);        UTOQ(mod,q);
                         UTOQ(i,ind);        UTOQ(i,ind);
                         n = mknode(2,ind,q);        n = mknode(2,ind,q);
                         MKLIST(*rp,n);        MKLIST(*rp,n);
                         return;        return;
                 }      }
         }    }
 }  }
   
 void Pranp(arg,rp)  void Pranp(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         int n;    int n;
         UP c;    UP c;
   
         n = QTOS((Q)ARG0(arg));    n = QTOS((Q)ARG0(arg));
         ranp(n,&c);    ranp(n,&c);
         if ( c ) {    if ( c ) {
                 up_var = VR((P)ARG1(arg));      up_var = VR((P)ARG1(arg));
                 uptop(c,rp);      uptop(c,rp);
         } else    } else
                 *rp = 0;      *rp = 0;
 }  }
   
 void ranp(n,nr)  void ranp(int n,UP *nr)
 int n;  
 UP *nr;  
 {  {
         int i;    int i;
         unsigned int r;    unsigned int r;
         Q q;    Q q;
         UP c;    UP c;
   
         *nr = c = UPALLOC(n);    *nr = c = UPALLOC(n);
         for ( i = 0; i <= n; i++ ) {    for ( i = 0; i <= n; i++ ) {
                 r = random();      r = random();
                 UTOQ(r,q);      UTOQ(r,q);
                 c->c[i] = (Num)q;      c->c[i] = (Num)q;
         }    }
         for ( i = n; i >= 0 && !c->c[i]; i-- );    for ( i = n; i >= 0 && !c->c[i]; i-- );
         if ( i >= 0 )    if ( i >= 0 )
                 c->d = i;      c->d = i;
         else    else
                 *nr = 0;      *nr = 0;
 }  }
   
 void Pmaxblen(arg,rp)  void Pmaxblen(NODE arg,Q *rp)
 NODE arg;  
 Q *rp;  
 {  {
         int l;    int l;
         l = maxblenp(ARG0(arg));    l = maxblenp(ARG0(arg));
         STOQ(l,*rp);    STOQ(l,*rp);
 }  }
   
 void Pp_mag(arg,rp)  void Pp_mag(NODE arg,Q *rp)
 NODE arg;  
 Q *rp;  
 {  {
         int l;    int l;
         l = p_mag(ARG0(arg));    l = p_mag(ARG0(arg));
         STOQ(l,*rp);    STOQ(l,*rp);
 }  }
   
 void Pord(arg,listp)  void Pord(NODE arg,LIST *listp)
 NODE arg;  
 LIST *listp;  
 {  {
         NODE n,tn;    NODE n,tn,p,opt;
         LIST l;    char *key;
         VL vl,tvl,svl;    Obj value;
         P t;    int overwrite=0;
         int i,j;    LIST l;
         V *va;    VL vl,tvl,svl;
         V v;    P t;
     int i,j;
     V *va;
     V v;
   
         if ( argc(arg) ) {  #if 0
                 asir_assert(ARG0(arg),O_LIST,"ord");  printf("LASTCO="); printv(CO,LASTCO->v); printf("\n");
                 for ( vl = 0, i = 0, n = BDY((LIST)ARG0(arg));  #endif
                         n; n = NEXT(n), i++ ) {    if ( current_option ) {
                         if ( !vl ) {      for ( opt = current_option; opt; opt = NEXT(opt) ) {
                                 NEWVL(vl); tvl = vl;        p = BDY((LIST)BDY(opt));
                         } else {        key = BDY((STRING)BDY(p));
                                 NEWVL(NEXT(tvl)); tvl = NEXT(tvl);        value = (Obj)BDY(NEXT(p));
                         }        if ( !strcmp(key,"overwrite") && value ) {
                         if ( !(t = (P)BDY(n)) || (OID(t) != O_P) )          overwrite = value ? 1 : 0;
                                 error("ord : invalid argument");          break;
                         VR(tvl) = VR(t);        }
                 }      }
                 va = (V *)ALLOCA(i*sizeof(V));    }
                 for ( j = 0, svl = vl; j < i; j++, svl = NEXT(svl) )  
                         va[j] = VR(svl);    if ( argc(arg) ) {
                 for ( svl = CO; svl; svl = NEXT(svl) ) {      asir_assert(ARG0(arg),O_LIST,"ord");
                         v = VR(svl);      for ( vl = 0, i = 0, n = BDY((LIST)ARG0(arg));
                         for ( j = 0; j < i; j++ )        n; n = NEXT(n), i++ ) {
                                 if ( v == va[j] )        if ( !vl ) {
                                         break;          NEWVL(vl); tvl = vl;
                         if ( j == i ) {        } else {
                                 if ( !vl ) {          NEWVL(NEXT(tvl)); tvl = NEXT(tvl);
                                         NEWVL(vl); tvl = vl;        }
                                 } else {        if ( !(t = (P)BDY(n)) || (OID(t) != O_P) )
                                         NEWVL(NEXT(tvl)); tvl = NEXT(tvl);          error("ord : invalid argument");
                                 }        VR(tvl) = VR(t);
                                 VR(tvl) = v;      }
                         }      if ( !overwrite ) {
                 }        va = (V *)ALLOCA(i*sizeof(V));
                 if ( vl )        for ( j = 0, svl = vl; j < i; j++, svl = NEXT(svl) )
                         NEXT(tvl) = 0;          va[j] = VR(svl);
                 CO = vl;        for ( svl = CO; svl; svl = NEXT(svl) ) {
         }          v = VR(svl);
         for ( n = 0, vl = CO; vl; vl = NEXT(vl) ) {          for ( j = 0; j < i; j++ )
                 NEXTNODE(n,tn); MKV(VR(vl),t); BDY(tn) = (pointer)t;            if ( v == va[j] )
         }              break;
         NEXT(tn) = 0; MKLIST(l,n); *listp = l;          if ( j == i ) {
             if ( !vl ) {
               NEWVL(vl); tvl = vl;
             } else {
               NEWVL(NEXT(tvl)); tvl = NEXT(tvl);
             }
             VR(tvl) = v;
           }
         }
       } else {
         for ( svl = vl; svl; svl = NEXT(svl) ) {
           if ( svl->v->attr == (pointer)V_PF )
             ((PFINS)svl->v->priv)->pf->ins = 0;
         }
       }
       if ( vl )
         NEXT(tvl) = 0;
       CO = vl;
       update_LASTCO();
     }
     for ( n = 0, vl = CO; vl; vl = NEXT(vl) ) {
       NEXTNODE(n,tn); MKV(VR(vl),t); BDY(tn) = (pointer)t;
     }
     NEXT(tn) = 0; MKLIST(l,n); *listp = l;
 }  }
   
 void Pcoef0(arg,rp)  void Premove_vars(NODE arg,LIST *listp)
 NODE arg;  
 Obj *rp;  
 {  {
         Obj t,n;    NODE l,nd,tnd;
         P s;    V *v,*va;
         DCP dc;    int n,na,i,j;
         int id;    VL vl,vl1;
         V v;    P t;
         VL vl;    LIST list;
   
         if ( !(t = (Obj)ARG0(arg)) || ((id = OID(ARG0(arg))) > O_P) )    asir_assert(ARG0(arg),O_LIST,"remove_vars");
                 *rp = 0;    l = BDY((LIST)ARG0(arg)); n = length(l);
         else if ( (n = (Obj)ARG1(arg)) && (OID(n) > O_N) )    v = (V *)ALLOCA(n*sizeof(V));
                 *rp = 0;    for ( i = 0; i < n; i++, l = NEXT(l) )
         else if ( id == O_N )      if ( !(t = (P)BDY(l)) || (OID(t) != O_P) )
                 if ( !n )        error("ord : invalid argument");
                         *rp = t;      else v[i] = VR(t);
                 else  
                         *rp = 0;    for ( na = 0, vl = CO; vl; vl = NEXT(vl), na++ );
         else {    va = (V *)ALLOCA(na*sizeof(V));
                 if ( argc(arg) == 3 ) {    for ( i = 0, vl = CO; i < na; i++, vl = NEXT(vl) ) va[i] = VR(vl);
                         if ( (v = VR((P)ARG2(arg))) != VR((P)t) ) {    for ( i = 0; i < na; i++ )
                                 reordvar(CO,v,&vl); reorderp(vl,CO,(P)t,&s);      for ( j = 0; j < n; j++ ) if ( va[i] == v[j] ) va[i] = 0;
                         } else    for ( vl = 0, i = na-1; i >= 0; i-- )
                                 s = (P)t;      if ( va[i] ) {
                         if ( VR(s) != v ) {        NEWVL(vl1); VR(vl1) = va[i]; NEXT(vl1) = vl; vl = vl1;
                                 if ( n )      }
                                         *rp = 0;    CO = vl;
                                 else    for ( nd = 0, vl = CO; vl; vl = NEXT(vl) ) {
                                         *rp = t;      NEXTNODE(nd,tnd); MKV(VR(vl),t); BDY(tnd) = (pointer)t;
                                 return;    }
                         }    if ( nd ) NEXT(tnd) = 0;
                 } else    MKLIST(list,nd); *listp = list;
                         s = (P)t;  
                 for ( dc = DC(s); dc && cmpq(DEG(dc),(Q)n); dc = NEXT(dc) );  
                 if ( dc )  
                         *rp = (Obj)COEF(dc);  
                 else  
                         *rp = 0;  
         }  
 }  }
   
 void Pcoef(arg,rp)  void Pcoef0(NODE arg,Obj *rp)
 NODE arg;  
 Obj *rp;  
 {  {
         Obj t,n;    Obj t,n;
         P s;    P s;
         DCP dc;    DCP dc;
         int id;    int id;
         V v;    V v;
     VL vl;
   
         if ( !(t = (Obj)ARG0(arg)) || ((id = OID(ARG0(arg))) > O_P) )    if ( !(t = (Obj)ARG0(arg)) || ((id = OID(ARG0(arg))) > O_P) )
                 *rp = 0;      *rp = 0;
         else if ( (n = (Obj)ARG1(arg)) && (OID(n) > O_N) )    else if ( (n = (Obj)ARG1(arg)) && (OID(n) > O_N) )
                 *rp = 0;      *rp = 0;
         else if ( id == O_N ) {    else if ( id == O_N )
                 if ( !n )      if ( !n )
                         *rp = t;        *rp = t;
                 else      else
                         *rp = 0;        *rp = 0;
         } else {    else {
                 if ( argc(arg) == 3 ) {      if ( argc(arg) == 3 ) {
                         if ( (v = VR((P)ARG2(arg))) != VR((P)t) ) {        if ( (v = VR((P)ARG2(arg))) != VR((P)t) ) {
                                 getcoef(CO,(P)t,v,(Q)n,(P *)rp); return;          reordvar(CO,v,&vl); reorderp(vl,CO,(P)t,&s);
                         } else        } else
                                 s = (P)t;          s = (P)t;
                         if ( VR(s) != v ) {        if ( VR(s) != v ) {
                                 if ( n )          if ( n )
                                         *rp = 0;            *rp = 0;
                                 else          else
                                         *rp = t;            *rp = t;
                                 return;          return;
                         }        }
                 } else      } else
                         s = (P)t;        s = (P)t;
                 for ( dc = DC(s); dc && cmpq(DEG(dc),(Q)n); dc = NEXT(dc) );      for ( dc = DC(s); dc && cmpq(DEG(dc),(Q)n); dc = NEXT(dc) );
                 if ( dc )      if ( dc )
                         *rp = (Obj)COEF(dc);        *rp = (Obj)COEF(dc);
                 else      else
                         *rp = 0;        *rp = 0;
         }    }
 }  }
   
 void Pcoef_gf2n(arg,rp)  void Pcoef(NODE arg,Obj *rp)
 NODE arg;  
 Obj *rp;  
 {  {
         Obj t,n;    Obj t,n;
         int id,d;    P s;
         UP2 up2;    DCP dc;
     int id;
     V v;
   
         if ( !(t = (Obj)ARG0(arg)) || ((id = OID(ARG0(arg))) > O_P) )    if ( !(t = (Obj)ARG0(arg)) || ((id = OID(ARG0(arg))) > O_P) )
                 *rp = 0;      *rp = 0;
         else if ( (n = (Obj)ARG1(arg)) && (OID(n) > O_N) )    else if ( (n = (Obj)ARG1(arg)) && (OID(n) > O_N) )
                 *rp = 0;      *rp = 0;
         else if ( id == O_N && NID((Num)t) == N_GF2N ) {    else if ( id == O_N ) {
                 d = QTOS((Q)n);      if ( !n )
                 up2 = ((GF2N)t)->body;        *rp = t;
                 if ( d > degup2(up2) )      else
                         *rp = 0;        *rp = 0;
                 else    } else {
                         *rp = (Obj)(up2->b[d/BSH]&(((unsigned long)1)<<(d%BSH))?ONE:0);      if ( argc(arg) == 3 ) {
         } else        if ( (v = VR((P)ARG2(arg))) != VR((P)t) ) {
                 *rp = 0;          getcoef(CO,(P)t,v,(Q)n,(P *)rp); return;
         } else
           s = (P)t;
         if ( VR(s) != v ) {
           if ( n )
             *rp = 0;
           else
             *rp = t;
           return;
         }
       } else
         s = (P)t;
       for ( dc = DC(s); dc && cmpq(DEG(dc),(Q)n); dc = NEXT(dc) );
       if ( dc )
         *rp = (Obj)COEF(dc);
       else
         *rp = 0;
     }
 }  }
   
 void Pdeg(arg,rp)  void Pcoef_gf2n(NODE arg,Obj *rp)
 NODE arg;  
 Q *rp;  
 {  {
         Obj t,v;    Obj t,n;
         int d;    int id,d;
     UP2 up2;
   
     if ( !(t = (Obj)ARG0(arg)) || ((id = OID(ARG0(arg))) > O_P) )
       *rp = 0;
     else if ( (n = (Obj)ARG1(arg)) && (OID(n) > O_N) )
       *rp = 0;
     else if ( id == O_N && NID((Num)t) == N_GF2N ) {
       d = QTOS((Q)n);
       up2 = ((GF2N)t)->body;
       if ( d > degup2(up2) )
         *rp = 0;
       else
         *rp = (Obj)(up2->b[d/BSH]&(((unsigned long)1)<<(d%BSH))?ONE:0);
     } else
       *rp = 0;
   }
   
   void Pdeg(NODE arg,Q *rp)
   {
     Obj t,v;
     int d;
   
 #if 0  #if 0
         if ( !(t = (Obj)ARG0(arg)) || (OID(t) != O_P) )    if ( !(t = (Obj)ARG0(arg)) || (OID(t) != O_P) )
                 *rp = 0;      *rp = 0;
         else if ( !(v = (Obj)ARG1(arg)) || (VR((P)v) != VR((P)t)) )    else if ( !(v = (Obj)ARG1(arg)) || (VR((P)v) != VR((P)t)) )
                 *rp = 0;      *rp = 0;
         else    else
                 *rp = (Obj)DEG(DC((P)t));      *rp = (Obj)DEG(DC((P)t));
 #endif  #endif
         if ( !(t = (Obj)ARG0(arg)) )    if ( !(t = (Obj)ARG0(arg)) )
                 STOQ(-1,*rp);      STOQ(-1,*rp);
         else if ( OID(t) != O_P ) {    else if ( OID(t) != O_P ) {
                 if ( OID(t) == O_N && NID(t) == N_GF2N      if ( OID(t) == O_N && NID(t) == N_GF2N
                         && (v=(Obj)ARG1(arg)) && OID(v)== O_N && NID(v) == N_GF2N ) {        && (v=(Obj)ARG1(arg)) && OID(v)== O_N && NID(v) == N_GF2N ) {
                         d = degup2(((GF2N)t)->body);        d = degup2(((GF2N)t)->body);
                         STOQ(d,*rp);        STOQ(d,*rp);
                 } else      } else
                         *rp = 0;        *rp = 0;
         } else    } else
                 degp(VR((P)ARG1(arg)),(P)ARG0(arg),rp);      degp(VR((P)ARG1(arg)),(P)ARG0(arg),rp);
 }  }
   
 void Pmindeg(arg,rp)  void Pmindeg(NODE arg,Q *rp)
 NODE arg;  
 Q *rp;  
 {  {
         Obj t;    Obj t;
   
         if ( !(t = (Obj)ARG0(arg)) || (OID(t) != O_P) )    if ( !(t = (Obj)ARG0(arg)) || (OID(t) != O_P) )
                 *rp = 0;      *rp = 0;
         else    else
                 getmindeg(VR((P)ARG1(arg)),(P)ARG0(arg),rp);      getmindeg(VR((P)ARG1(arg)),(P)ARG0(arg),rp);
 }  }
   
 void Psetmod(arg,rp)  void Psetmod(NODE arg,Q *rp)
 NODE arg;  
 Q *rp;  
 {  {
         if ( arg ) {    if ( arg ) {
                 asir_assert(ARG0(arg),O_N,"setmod");      asir_assert(ARG0(arg),O_N,"setmod");
                 current_mod = QTOS((Q)ARG0(arg));      current_mod = QTOS((Q)ARG0(arg));
         }    }
         STOQ(current_mod,*rp);    STOQ(current_mod,*rp);
 }  }
   
 void Psparsemod_gf2n(arg,rp)  void Psparsemod_gf2n(NODE arg,Q *rp)
 NODE arg;  
 Q *rp;  
 {  {
         int id;    int id;
   
         if ( arg && current_mod_gf2n )    if ( arg && current_mod_gf2n )
                 current_mod_gf2n->id = ARG0(arg)?1:0;      current_mod_gf2n->id = ARG0(arg)?1:0;
         if ( !current_mod_gf2n )    if ( !current_mod_gf2n )
                 id = -1;      id = -1;
         else    else
                 id = current_mod_gf2n->id;      id = current_mod_gf2n->id;
         STOQ(id,*rp);    STOQ(id,*rp);
 }  }
   
 void Pmultest_gf2n(arg,rp)  void Pmultest_gf2n(NODE arg,GF2N *rp)
 NODE arg;  
 GF2N *rp;  
 {  {
         GF2N a,b,c;    GF2N a,b,c;
         int i;    int i;
   
         a = (GF2N)ARG0(arg); b = (GF2N)ARG0(arg);    a = (GF2N)ARG0(arg); b = (GF2N)ARG0(arg);
         for ( i = 0; i < 10000; i++ )    for ( i = 0; i < 10000; i++ )
                 mulgf2n(a,b,&c);      mulgf2n(a,b,&c);
         *rp = c;    *rp = c;
 }  }
   
 void Psquaretest_gf2n(arg,rp)  void Psquaretest_gf2n(NODE arg,GF2N *rp)
 NODE arg;  
 GF2N *rp;  
 {  {
         GF2N a,c;    GF2N a,c;
         int i;    int i;
   
         a = (GF2N)ARG0(arg);    a = (GF2N)ARG0(arg);
         for ( i = 0; i < 10000; i++ )    for ( i = 0; i < 10000; i++ )
                 squaregf2n(a,&c);      squaregf2n(a,&c);
         *rp = c;    *rp = c;
 }  }
   
 void Pinvtest_gf2n(arg,rp)  void Pinvtest_gf2n(NODE arg,GF2N *rp)
 NODE arg;  
 GF2N *rp;  
 {  {
         GF2N a,c;    GF2N a,c;
         int i;    int i;
   
         a = (GF2N)ARG0(arg);    a = (GF2N)ARG0(arg);
         for ( i = 0; i < 10000; i++ )    for ( i = 0; i < 10000; i++ )
                 invgf2n(a,&c);      invgf2n(a,&c);
         *rp = c;    *rp = c;
 }  }
   
 void Pbininv_gf2n(arg,rp)  void Pbininv_gf2n(NODE arg,GF2N *rp)
 NODE arg;  
 GF2N *rp;  
 {  {
         UP2 a,inv;    UP2 a,inv;
         int n;    int n;
   
         a = ((GF2N)ARG0(arg))->body;    a = ((GF2N)ARG0(arg))->body;
         n = QTOS((Q)ARG1(arg));    n = QTOS((Q)ARG1(arg));
         type1_bin_invup2(a,n,&inv);    type1_bin_invup2(a,n,&inv);
         MKGF2N(inv,*rp);    MKGF2N(inv,*rp);
 }  }
   
 void Prinvtest_gf2n(rp)  void Prinvtest_gf2n(Real *rp)
 Real *rp;  
 {  {
         GF2N *a;    GF2N *a;
         GF2N c;    GF2N c;
         double t0,t1,r;    double t0,t1,r;
         int i;    int i;
         double get_clock();    double get_clock();
   
         a = (GF2N *)ALLOCA(1000*sizeof(GF2N));    a = (GF2N *)ALLOCA(1000*sizeof(GF2N));
         for ( i = 0; i < 1000; i++ ) {    for ( i = 0; i < 1000; i++ ) {
                 randomgf2n(&a[i]);      randomgf2n(&a[i]);
         }    }
         t0 = get_clock();    t0 = get_clock();
         for ( i = 0; i < 1000; i++ )    for ( i = 0; i < 1000; i++ )
                 invgf2n(a[i],&c);      invgf2n(a[i],&c);
         t1 = get_clock();    t1 = get_clock();
         r = (t1-t0)/1000;    r = (t1-t0)/1000;
         MKReal(r,*rp);    MKReal(r,*rp);
 }  }
   
 void Pfind_root_gf2n(arg,rp)  void Pfind_root_gf2n(NODE arg,GF2N *rp)
 NODE arg;  
 GF2N *rp;  
 {  {
   
 #if 0  #if 0
         UP p;    UP p;
   
         ptoup((P)ARG0(arg),&p);    ptoup((P)ARG0(arg),&p);
         find_root_gf2n(p,rp);    find_root_gf2n(p,rp);
 #else  #else
         UP2 p;    UP2 p;
   
         ptoup2((P)ARG0(arg),&p);    ptoup2((P)ARG0(arg),&p);
         find_root_up2(p,rp);    find_root_up2(p,rp);
 #endif  #endif
 }  }
   
 void Pis_irred_gf2(arg,rp)  void Pis_irred_gf2(NODE arg,Q *rp)
 NODE arg;  
 Q *rp;  
 {  {
         UP2 t;    UP2 t;
   
         ptoup2(ARG0(arg),&t);    ptoup2(ARG0(arg),&t);
         *rp = irredcheckup2(t) ? ONE : 0;    *rp = irredcheckup2(t) ? ONE : 0;
 }  }
   
 void Pis_irred_ddd_gf2(arg,rp)  void Pis_irred_ddd_gf2(NODE arg,Q *rp)
 NODE arg;  
 Q *rp;  
 {  {
         UP2 t;    UP2 t;
         int ret;    int ret;
   
         ptoup2(ARG0(arg),&t);    ptoup2(ARG0(arg),&t);
         ret = irredcheck_dddup2(t);    ret = irredcheck_dddup2(t);
         STOQ(ret,*rp);    STOQ(ret,*rp);
 }  }
   
 extern P current_gfs_ext;  void Psetmod_ff(NODE arg,Obj *rp)
 extern int current_gfs_p;  
 extern int current_gfs_q;  
 extern int current_gfs_q1;  
 extern int *current_gfs_plus1;  
 extern int *current_gfs_ntoi;  
 extern int *current_gfs_iton;  
   
 void Psetmod_ff(arg,rp)  
 NODE arg;  
 Obj *rp;  
 {  {
         int ac;    int ac;
         int d;    int d;
         Obj mod,defpoly;    Obj mod,defpoly;
         N n;    N n;
         UP up;    UP up;
         UP2 up2;    UP2 up2;
         Q q,r;    UM dp;
         P p;    Q q,r;
         NODE n0,n1;    P p,p1,y;
         LIST list;    NODE n0,n1;
     LIST list;
   
         ac = argc(arg);    ac = argc(arg);
         if ( ac == 1 ) {    if ( ac == 1 ) {
                 mod = (Obj)ARG0(arg);      mod = (Obj)ARG0(arg);
                 if ( !mod )      if ( !mod )
                         error("setmod_ff : invalid argument");              current_ff = FF_NOT_SET;
                 switch ( OID(mod) ) {          else {
                         case O_N:        switch ( OID(mod) ) {
                                 current_ff = FF_GFP;        case O_N:
                                 setmod_lm(NM((Q)mod));          current_ff = FF_GFP;
                                 break;          setmod_lm(NM((Q)mod));
                         case O_P:          break;
                                 current_ff = FF_GF2N;        case O_P:
                                 setmod_gf2n((P)mod); break;          current_ff = FF_GF2N;
                         default:          setmod_gf2n((P)mod); break;
                                 error("setmod_ff : invalid argument");        default:
                 }          error("setmod_ff : invalid argument");
         } else if ( ac == 2 ) {        }
                 if ( OID(ARG0(arg)) == O_N ) {        }
                         /* small finite field; primitive root representation */    } else if ( ac == 2 ) {
                         current_ff = FF_GFS;      if ( OID(ARG0(arg)) == O_N ) {
                         setmod_sf(QTOS((Q)ARG0(arg)),QTOS((Q)ARG1(arg)));        /* small finite field; primitive root representation */
                 } else {        current_ff = FF_GFS;
                         mod = (Obj)ARG1(arg);        setmod_sf(QTOS((Q)ARG0(arg)),QTOS((Q)ARG1(arg)));
                         current_ff = FF_GFPN;      } else {
                         defpoly = (Obj)ARG0(arg);        mod = (Obj)ARG1(arg);
                         if ( !mod || !defpoly )        current_ff = FF_GFPN;
                                 error("setmod_ff : invalid argument");        defpoly = (Obj)ARG0(arg);
                         setmod_lm(NM((Q)mod));        if ( !mod || !defpoly )
                         setmod_gfpn((P)defpoly);          error("setmod_ff : invalid argument");
                 }        setmod_lm(NM((Q)mod));
         }        setmod_gfpn((P)defpoly);
         switch ( current_ff ) {      }
                 case FF_GFP:    } else if ( ac == 3 ) {
                         getmod_lm(&n); NTOQ(n,1,q); *rp = (Obj)q; break;      /* finite extension of a small finite field */
                 case FF_GF2N:      current_ff = FF_GFS;
                         getmod_gf2n(&up2); up2top(up2,&p); *rp = (Obj)p; break;      setmod_sf(QTOS((Q)ARG0(arg)),QTOS((Q)ARG1(arg)));
                 case FF_GFPN:      d = QTOS((Q)ARG2(arg));
                         getmod_lm(&n); NTOQ(n,1,q);      generate_defpoly_sfum(d,&dp);
                         getmod_gfpn(&up); uptop(up,&p);      setmod_gfsn(dp);
                         MKNODE(n1,q,0); MKNODE(n0,p,n1);      current_ff = FF_GFSN;
                         MKLIST(list,n0);    }
                         *rp = (Obj)list; break;    switch ( current_ff ) {
                 case FF_GFS:      case FF_GFP:
                         STOQ(current_gfs_p,q);        getmod_lm(&n); NTOQ(n,1,q); *rp = (Obj)q; break;
                         if ( current_gfs_ext ) {      case FF_GF2N:
                                 enc_to_p(current_gfs_p,current_gfs_iton[1],        getmod_gf2n(&up2); up2top(up2,&p); *rp = (Obj)p; break;
                                         VR(current_gfs_ext),&p);      case FF_GFPN:
                                 n0 = mknode(3,q,current_gfs_ext,p);        getmod_lm(&n); NTOQ(n,1,q);
                         } else {        getmod_gfpn(&up); uptop(up,&p);
                                 if ( current_gfs_p == 2 )        MKNODE(n1,q,0); MKNODE(n0,p,n1);
                                         r = ONE;        MKLIST(list,n0);
                                 else        *rp = (Obj)list; break;
                                         STOQ(current_gfs_iton[1],r);      case FF_GFS:
                                 n0 = mknode(3,q,current_gfs_ext,r);      case FF_GFSN:
                         }        STOQ(current_gfs_p,q);
                         MKLIST(list,n0);        if ( current_gfs_ext )
                         *rp = (Obj)list; break;          enc_to_p(current_gfs_p,current_gfs_iton[1],
                 default:            VR(current_gfs_ext),&p);
                         *rp = 0; break;        else {
         }          if ( current_gfs_p == 2 )
             r = ONE;
           else if ( !current_gfs_ntoi )
             r = 0;
           else
             STOQ(current_gfs_iton[1],r);
           p = (P)r;
         }
         switch ( current_ff ) {
           case FF_GFS:
             n0 = mknode(3,q,current_gfs_ext,p);
             break;
           case FF_GFSN:
             getmod_gfsn(&dp);
             makevar("y",&y);
             sfumtop(VR(y),dp,&p1);
             n0 = mknode(4,q,current_gfs_ext,p,p1);
             break;
         }
         MKLIST(list,n0);
         *rp = (Obj)list; break;
       default:
         *rp = 0; break;
     }
 }  }
   
 void Pextdeg_ff(rp)  void Pextdeg_ff(Q *rp)
 Q *rp;  
 {  {
         int d;    int d;
         UP2 up2;    UP2 up2;
         UP up;    UP up;
     UM dp;
   
         switch ( current_ff ) {    switch ( current_ff ) {
                 case FF_GFP:      case FF_GFP:
                         *rp = ONE; break;        *rp = ONE; break;
                 case FF_GF2N:      case FF_GF2N:
                         getmod_gf2n(&up2); d = degup2(up2); STOQ(d,*rp); break;        getmod_gf2n(&up2); d = degup2(up2); STOQ(d,*rp); break;
                 case FF_GFPN:      case FF_GFPN:
                         getmod_gfpn(&up); STOQ(up->d,*rp); break;        getmod_gfpn(&up); STOQ(up->d,*rp); break;
                 case FF_GFS:      case FF_GFS:
                         if ( !current_gfs_ext )        if ( !current_gfs_ext )
                                 *rp = ONE;          *rp = ONE;
                         else        else
                                 *rp = DEG(DC(current_gfs_ext));          *rp = DEG(DC(current_gfs_ext));
                         break;        break;
                 default:      case FF_GFSN:
                         error("extdeg_ff : current_ff is not set");        getmod_gfsn(&dp);
         }        STOQ(DEG(dp),*rp);
         break;
       default:
         error("extdeg_ff : current_ff is not set");
     }
 }  }
   
 void Pcharacteristic_ff(rp)  void Pcharacteristic_ff(Q *rp)
 Q *rp;  
 {  {
         N lm;    N lm;
   
         switch ( current_ff ) {    switch ( current_ff ) {
                 case FF_GFP:      case FF_GFP:
                 case FF_GFPN:      case FF_GFPN:
                         getmod_lm(&lm); NTOQ(lm,1,*rp); break;        getmod_lm(&lm); NTOQ(lm,1,*rp); break;
                 case FF_GF2N:      case FF_GF2N:
                         STOQ(2,*rp); break;        STOQ(2,*rp); break;
                 case FF_GFS:      case FF_GFS:
                         STOQ(current_gfs_p,*rp); break;      case FF_GFSN:
                 default:        STOQ(current_gfs_p,*rp); break;
                         error("characteristic_ff : current_ff is not set");      default:
         }        error("characteristic_ff : current_ff is not set");
     }
 }  }
   
 void Pfield_type_ff(rp)  void Pfield_type_ff(Q *rp)
 Q *rp;  
 {  {
         STOQ(current_ff,*rp);    STOQ(current_ff,*rp);
 }  }
   
 void Pfield_order_ff(rp)  void Pfield_order_ff(Q *rp)
 Q *rp;  
 {  {
         N n;    N n;
   
         field_order_ff(&n);    field_order_ff(&n);
         NTOQ(n,1,*rp);    NTOQ(n,1,*rp);
 }  }
   
 void field_order_ff(order)  void Prandom_ff(Obj *rp)
 N *order;  
 {  {
         UP2 up2;    LM l;
         UP up;    GF2N g;
         N m;    GFPN p;
         int d,w;    GFS s;
     GFSN spn;
   
         switch ( current_ff ) {    switch ( current_ff ) {
                 case FF_GFP:      case FF_GFP:
                         getmod_lm(order); break;        random_lm(&l); *rp = (Obj)l; break;
                 case FF_GF2N:      case FF_GF2N:
                         getmod_gf2n(&up2); d = degup2(up2);        randomgf2n(&g); *rp = (Obj)g; break;
                         w = (d>>5)+1;      case FF_GFPN:
                         *order = m = NALLOC(w);        randomgfpn(&p); *rp = (Obj)p; break;
                         PL(m)=w;      case FF_GFS:
                         bzero((char *)BD(m),w*sizeof(unsigned int));        randomgfs(&s); *rp = (Obj)s; break;
                         BD(m)[d>>5] |= 1<<(d&31);      case FF_GFSN:
                         break;        randomgfsn(&spn); *rp = (Obj)spn; break;
                 case FF_GFPN:      default:
                         getmod_lm(&m);        error("random_ff : current_ff is not set");
                         getmod_gfpn(&up); pwrn(m,up->d,order); break;    }
                 case FF_GFS:  
                         STON(current_gfs_q,*order); break;  
                 default:  
                         error("field_order_ff : current_ff is not set");  
         }  
 }  }
   
 void Prandom_ff(rp)  void Psimp_ff(NODE arg,Obj *rp)
 Obj *rp;  
 {  {
         LM l;    simp_ff((Obj)ARG0(arg),rp);
         GF2N g;  
         GFPN p;  
         GFS s;  
   
         switch ( current_ff ) {  
                 case FF_GFP:  
                         random_lm(&l); *rp = (Obj)l; break;  
                 case FF_GF2N:  
                         randomgf2n(&g); *rp = (Obj)g; break;  
                 case FF_GFPN:  
                         randomgfpn(&p); *rp = (Obj)p; break;  
                 case FF_GFS:  
                         randomgfs(&s); *rp = (Obj)s; break;  
                 default:  
                         error("random_ff : current_ff is not set");  
         }  
 }  }
   
 void Psimp_ff(arg,rp)  void getcoef(VL vl,P p,V v,Q d,P *r)
 NODE arg;  
 Obj *rp;  
 {  {
         LM r;    P s,t,u,a,b,x;
         GF2N rg;    DCP dc;
         extern lm_lazy;    V w;
   
         simp_ff((Obj)ARG0(arg),rp);    if ( !p )
       *r = 0;
     else if ( NUM(p) )
       *r = d ? 0 : p;
     else if ( (w=VR(p)) == v ) {
       for ( dc = DC(p); dc && cmpq(DEG(dc),d); dc = NEXT(dc) );
       *r = dc ? COEF(dc) : 0;
     } else {
       MKV(w,x);
       for ( dc = DC(p), s = 0; dc; dc = NEXT(dc) ) {
         getcoef(vl,COEF(dc),v,d,&t);
         if ( t ) {
           pwrp(vl,x,DEG(dc),&u); mulp(vl,t,u,&a);
           addp(vl,s,a,&b); s = b;
         }
       }
       *r = s;
     }
 }  }
   
 void simp_ff(p,rp)  void Pdeglist(NODE arg,LIST *rp)
 Obj p;  
 Obj *rp;  
 {  {
         Num n;    NODE d;
         LM r,s;  
         DCP dc,dcr0,dcr;  
         GF2N rg,sg;  
         GFPN rpn,spn;  
         GFS rs;  
         P t;  
         Obj obj;  
   
         lm_lazy = 0;    getdeglist((P)ARG0(arg),VR((P)ARG1(arg)),&d);
         if ( !p )    MKLIST(*rp,d);
                 *rp = 0;  
         else if ( OID(p) == O_N ) {  
                 switch ( current_ff ) {  
                         case FF_GFP:  
                                 ptolmp((P)p,&t); simplm((LM)t,&s); *rp = (Obj)s;  
                                 break;  
                         case FF_GF2N:  
                                 ptogf2n((Obj)p,&rg); simpgf2n((GF2N)rg,&sg); *rp = (Obj)sg;  
                                 break;  
                         case FF_GFPN:  
                                 ntogfpn((Obj)p,&rpn); simpgfpn((GFPN)rpn,&spn); *rp = (Obj)spn;  
                                 break;  
                         case FF_GFS:  
                                 if ( NID((Num)p) == N_GFS )  
                                         *rp = p;  
                                 else {  
                                         ptomp(current_gfs_p,(P)p,&t); mqtogfs(t,&rs);  
                                         *rp = (Obj)rs;  
                                 }  
                                 break;  
                         default:  
                                 *rp = (Obj)p;  
                                 break;  
                 }  
         } else if ( OID(p) == O_P ) {  
                 for ( dc = DC((P)p), dcr0 = 0; dc; dc = NEXT(dc) ) {  
                         simp_ff((Obj)COEF(dc),&obj);  
                         if ( obj ) {  
                                 NEXTDC(dcr0,dcr); DEG(dcr) = DEG(dc); COEF(dcr) = (P)obj;  
                         }  
                 }  
                 if ( !dcr0 )  
                         *rp = 0;  
                 else {  
                         NEXT(dcr) = 0; MKP(VR((P)p),dcr0,t); *rp = (Obj)t;  
                 }  
         } else  
                 error("simp_ff : not implemented yet");  
 }  }
   
 void getcoef(vl,p,v,d,r)  void Pch_mv(NODE arg,P *rp)
 VL vl;  
 P p;  
 V v;  
 Q d;  
 P *r;  
 {  {
         P s,t,u,a,b,x;    change_mvar(CO,(P)ARG0(arg),VR((P)ARG1(arg)),rp);
         DCP dc;  
         V w;  
   
         if ( !p )  
                 *r = 0;  
         else if ( NUM(p) )  
                 *r = d ? 0 : p;  
         else if ( (w=VR(p)) == v ) {  
                 for ( dc = DC(p); dc && cmpq(DEG(dc),d); dc = NEXT(dc) );  
                 *r = dc ? COEF(dc) : 0;  
         } else {  
                 MKV(w,x);  
                 for ( dc = DC(p), s = 0; dc; dc = NEXT(dc) ) {  
                         getcoef(vl,COEF(dc),v,d,&t);  
                         if ( t ) {  
                                 pwrp(vl,x,DEG(dc),&u); mulp(vl,t,u,&a);  
                                 addp(vl,s,a,&b); s = b;  
                         }  
                 }  
                 *r = s;  
         }  
 }  }
   
 void Pdeglist(arg,rp)  void Pre_mv(NODE arg,P *rp)
 NODE arg;  
 LIST *rp;  
 {  {
         NODE d;    restore_mvar(CO,(P)ARG0(arg),VR((P)ARG1(arg)),rp);
   
         getdeglist((P)ARG0(arg),VR((P)ARG1(arg)),&d);  
         MKLIST(*rp,d);  
 }  }
   
 void Pch_mv(arg,rp)  void change_mvar(VL vl,P p,V v,P *r)
 NODE arg;  
 P *rp;  
 {  {
         change_mvar(CO,(P)ARG0(arg),VR((P)ARG1(arg)),rp);    Q d;
     DCP dc,dc0;
     NODE dl;
   
     if ( !p || NUM(p) || (VR(p) == v) )
       *r = p;
     else {
       getdeglist(p,v,&dl);
       for ( dc0 = 0; dl; dl = NEXT(dl) ) {
         NEXTDC(dc0,dc); DEG(dc) = d = (Q)BDY(dl);
         getcoef(vl,p,v,d,&COEF(dc));
       }
       NEXT(dc) = 0; MKP(v,dc0,*r);
     }
 }  }
   
 void Pre_mv(arg,rp)  void restore_mvar(VL vl,P p,V v,P *r)
 NODE arg;  
 P *rp;  
 {  {
         restore_mvar(CO,(P)ARG0(arg),VR((P)ARG1(arg)),rp);    P s,u,a,b,x;
     DCP dc;
   
     if ( !p || NUM(p) || (VR(p) != v) )
       *r = p;
     else {
       MKV(v,x);
       for ( dc = DC(p), s = 0; dc; dc = NEXT(dc) ) {
         pwrp(vl,x,DEG(dc),&u); mulp(vl,COEF(dc),u,&a);
         addp(vl,s,a,&b); s = b;
       }
       *r = s;
     }
 }  }
   
 void change_mvar(vl,p,v,r)  void getdeglist(P p,V v,NODE *d)
 VL vl;  
 P p;  
 V v;  
 P *r;  
 {  {
         Q d;    NODE n,n0,d0,d1,d2;
         DCP dc,dc0;    DCP dc;
         NODE dl;  
   
         if ( !p || NUM(p) || (VR(p) == v) )    if ( !p || NUM(p) ) {
                 *r = p;      MKNODE(n,0,0); *d = n;
         else {    } else if ( VR(p) == v ) {
                 getdeglist(p,v,&dl);      for ( n0 = 0, dc = DC(p); dc; dc = NEXT(dc) ) {
                 for ( dc0 = 0; dl; dl = NEXT(dl) ) {        NEXTNODE(n0,n); BDY(n) = (pointer)DEG(dc);
                         NEXTDC(dc0,dc); DEG(dc) = d = (Q)BDY(dl);      }
                         getcoef(vl,p,v,d,&COEF(dc));      NEXT(n) = 0; *d = n0;
                 }    } else {
                 NEXT(dc) = 0; MKP(v,dc0,*r);      for ( dc = DC(p), d0 = 0; dc; dc = NEXT(dc) ) {
         }        getdeglist(COEF(dc),v,&d1); mergedeglist(d0,d1,&d2); d0 = d2;
       }
       *d = d0;
     }
 }  }
   
 void restore_mvar(vl,p,v,r)  void Pmergelist(NODE arg,LIST *rp)
 VL vl;  
 P p;  
 V v;  
 P *r;  
 {  {
         P s,u,a,b,x;      NODE n;
         DCP dc;  
   
         if ( !p || NUM(p) || (VR(p) != v) )    asir_assert(ARG0(arg),O_LIST,"mergelist");
                 *r = p;    asir_assert(ARG1(arg),O_LIST,"mergelist");
         else {    mergedeglist(BDY((LIST)ARG0(arg)),BDY((LIST)ARG1(arg)),&n);
                 MKV(v,x);    MKLIST(*rp,n);
                 for ( dc = DC(p), s = 0; dc; dc = NEXT(dc) ) {  
                         pwrp(vl,x,DEG(dc),&u); mulp(vl,COEF(dc),u,&a);  
                         addp(vl,s,a,&b); s = b;  
                 }  
                 *r = s;  
         }  
 }  }
   
 void getdeglist(p,v,d)  void mergedeglist(NODE d0,NODE d1,NODE *dr)
 P p;  
 V v;  
 NODE *d;  
 {  {
         NODE n,n0,d0,d1,d2;    NODE t0,t,dt;
         DCP dc;    Q d;
     int c;
   
         if ( !p || NUM(p) ) {    if ( !d0 )
                 MKNODE(n,0,0); *d = n;      *dr = d1;
         } else if ( VR(p) == v ) {    else {
                 for ( n0 = 0, dc = DC(p); dc; dc = NEXT(dc) ) {      while ( d1 ) {
                         NEXTNODE(n0,n); BDY(n) = (pointer)DEG(dc);        dt = d1; d1 = NEXT(d1); d = (Q)BDY(dt);
                 }        for ( t0 = 0, t = d0; t; t0 = t, t = NEXT(t) ) {
                 NEXT(n) = 0; *d = n0;          c = cmpq(d,(Q)BDY(t));
         } else {          if ( !c )
                 for ( dc = DC(p), d0 = 0; dc; dc = NEXT(dc) ) {            break;
                         getdeglist(COEF(dc),v,&d1); mergedeglist(d0,d1,&d2); d0 = d2;          else if ( c > 0 ) {
                 }            if ( !t0 ) {
                 *d = d0;              NEXT(dt) = d0; d0 = dt;
         }            } else {
               NEXT(t0) = dt; NEXT(dt) = t;
             }
             break;
           }
         }
         if ( !t ) {
           NEXT(t0) = dt; *dr = d0; return;
         }
       }
       *dr = d0;
     }
 }  }
 void Pmergelist(arg,rp)  
 NODE arg;  void Pptomp(NODE arg,P *rp)
 LIST *rp;  
 {  {
     NODE n;    int mod;
   
         asir_assert(ARG0(arg),O_LIST,"mergelist");    if ( argc(arg) == 1 ) {
         asir_assert(ARG1(arg),O_LIST,"mergelist");      if ( !current_mod )
         mergedeglist(BDY((LIST)ARG0(arg)),BDY((LIST)ARG1(arg)),&n);        error("ptomp : current_mod is not set");
         MKLIST(*rp,n);      else
         mod = current_mod;
     } else
       mod = QTOS((Q)ARG1(arg));
     ptomp(mod,(P)ARG0(arg),rp);
 }  }
   
 void mergedeglist(d0,d1,dr)  void Pmptop(NODE arg,P *rp)
 NODE d0,d1,*dr;  
 {  {
         NODE t0,t,dt;    mptop((P)ARG0(arg),rp);
         Q d;  }
         int c;  
   
         if ( !d0 )  void Pptolmp(NODE arg,P *rp)
                 *dr = d1;  {
         else {    ptolmp((P)ARG0(arg),rp);
                 while ( d1 ) {  
                         dt = d1; d1 = NEXT(d1); d = (Q)BDY(dt);  
                         for ( t0 = 0, t = d0; t; t0 = t, t = NEXT(t) ) {  
                                 c = cmpq(d,(Q)BDY(t));  
                                 if ( !c )  
                                         break;  
                                 else if ( c > 0 ) {  
                                         if ( !t0 ) {  
                                                 NEXT(dt) = d0; d0 = dt;  
                                         } else {  
                                                 NEXT(t0) = dt; NEXT(dt) = t;  
                                         }  
                                         break;  
                                 }  
                         }  
                         if ( !t ) {  
                                 NEXT(t0) = dt; *dr = d0; return;  
                         }  
                 }  
                 *dr = d0;  
         }  
 }  }
   
 void Pptomp(arg,rp)  void Plmptop(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         ptomp(QTOS((Q)ARG1(arg)),(P)ARG0(arg),rp);    lmptop((P)ARG0(arg),rp);
 }  }
   
 void Pmptop(arg,rp)  void Psf_galois_action(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         mptop((P)ARG0(arg),rp);    sf_galois_action(ARG0(arg),ARG1(arg),rp);
 }  }
   
 void Pptolmp(arg,rp)  /*
 NODE arg;    sf_embed(F,B,PM)
 P *rp;    F : an element of GF(pn)
     B : the image of the primitive root of GF(pn)
     PM : order of GF(pm)
   */
   
   void Psf_embed(NODE arg,P *rp)
 {  {
         ptolmp((P)ARG0(arg),rp);    int k,pm;
   
     /* GF(pn)={0,1,a,a^2,...}->GF(pm)={0,1,b,b^2,...}; a->b^k */
     k = CONT((GFS)ARG1(arg));
     pm = QTOS((Q)ARG2(arg));
     sf_embed((P)ARG0(arg),k,pm,rp);
 }  }
   
 void Plmptop(arg,rp)  void Psf_log(NODE arg,Q *rp)
 NODE arg;  
 P *rp;  
 {  {
         lmptop((P)ARG0(arg),rp);    int k;
   
     if ( !ARG0(arg) )
       error("sf_log : invalid armument");
     k = CONT((GFS)ARG0(arg));
     STOQ(k,*rp);
 }  }
   
 void Psf_galois_action(arg,rp)  void Psf_find_root(NODE arg,GFS *rp)
 NODE arg;  
 P *rp;  
 {  {
         sf_galois_action(ARG0(arg),ARG1(arg),rp);    P p;
     Obj t;
     int d;
     UM u;
     int *root;
   
     p = (P)ARG0(arg);
     simp_ff((Obj)p,&t); p = (P)t;
     d = getdeg(VR(p),p);
     u = W_UMALLOC(d);
     ptosfum(p,u);
     root = (int *)ALLOCA(d*sizeof(int));
     find_rootsf(u,root);
     MKGFS(IFTOF(root[0]),*rp);
 }  }
   
 void Pptosfp(arg,rp)  void Psf_minipoly(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         ptosfp(ARG0(arg),rp);    Obj t;
     P p1,p2;
     int d1,d2;
     UM up1,up2,m;
   
     p1 = (P)ARG0(arg); simp_ff((Obj)p1,&t); p1 = (P)t;
     p2 = (P)ARG1(arg); simp_ff((Obj)p2,&t); p2 = (P)t;
     d1 = getdeg(VR(p1),p1); up1 = W_UMALLOC(d1); ptosfum(p1,up1);
     d2 = getdeg(VR(p2),p2); up2 = W_UMALLOC(d2); ptosfum(p2,up2);
     m = W_UMALLOC(d2);
     minipolysf(up1,up2,m);
     sfumtop(VR(p2),m,&p1);
     sfptop(p1,rp);
 }  }
   
 void Psfptop(arg,rp)  void Pptosfp(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         sfptop((P)ARG0(arg),rp);    ptosfp(ARG0(arg),rp);
 }  }
   
 void Pptogf2n(arg,rp)  void Psfptop(NODE arg,P *rp)
 NODE arg;  
 GF2N *rp;  
 {  {
         ptogf2n((Obj)ARG0(arg),rp);    sfptop((P)ARG0(arg),rp);
 }  }
   
 void Pgf2ntop(arg,rp)  void Psfptopsfp(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         extern V up2_var;    sfptopsfp((P)ARG0(arg),VR((P)ARG1(arg)),rp);
   }
   
         if ( argc(arg) == 2 )  void Pptogf2n(NODE arg,GF2N *rp)
                 up2_var = VR((P)ARG1(arg));  {
         gf2ntop((GF2N)ARG0(arg),rp);    ptogf2n((Obj)ARG0(arg),rp);
 }  }
   
 void Pgf2ntovect(arg,rp)  void Pgf2ntop(NODE arg,P *rp)
 NODE arg;  
 VECT *rp;  
 {  {
         gf2ntovect((GF2N)ARG0(arg),rp);    if ( argc(arg) == 2 )
       up2_var = VR((P)ARG1(arg));
     gf2ntop((GF2N)ARG0(arg),rp);
 }  }
   
 void Pptogfpn(arg,rp)  void Pgf2ntovect(NODE arg,VECT *rp)
 NODE arg;  
 GF2N *rp;  
 {  {
         ptogfpn((Obj)ARG0(arg),rp);    gf2ntovect((GF2N)ARG0(arg),rp);
 }  }
   
 void Pgfpntop(arg,rp)  void Pptogfpn(NODE arg,GFPN *rp)
 NODE arg;  
 P *rp;  
 {  {
         extern V up_var;    ptogfpn((Obj)ARG0(arg),rp);
   }
   
         if ( argc(arg) == 2 )  void Pgfpntop(NODE arg,P *rp)
                 up_var = VR((P)ARG1(arg));  {
         gfpntop((GFPN)ARG0(arg),rp);    if ( argc(arg) == 2 )
       up_var = VR((P)ARG1(arg));
     gfpntop((GFPN)ARG0(arg),rp);
 }  }
   
 void Pureverse(arg,rp)  void Pureverse(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         UP p,r;    UP p,r;
   
         ptoup((P)ARG0(arg),&p);    ptoup((P)ARG0(arg),&p);
         if ( argc(arg) == 1 )    if ( argc(arg) == 1 )
                 reverseup(p,p->d,&r);      reverseup(p,p->d,&r);
         else    else
                 reverseup(p,QTOS((Q)ARG1(arg)),&r);      reverseup(p,QTOS((Q)ARG1(arg)),&r);
         uptop(r,rp);    uptop(r,rp);
 }  }
   
 void Putrunc(arg,rp)  void Putrunc(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         UP p,r;    UP p,r;
   
         ptoup((P)ARG0(arg),&p);    ptoup((P)ARG0(arg),&p);
         truncup(p,QTOS((Q)ARG1(arg))+1,&r);    truncup(p,QTOS((Q)ARG1(arg))+1,&r);
         uptop(r,rp);    uptop(r,rp);
 }  }
   
 void Pudecomp(arg,rp)  void Pudecomp(NODE arg,LIST *rp)
 NODE arg;  
 LIST *rp;  
 {  {
         P u,l;    P u,l;
         UP p,up,low;    UP p,up,low;
         NODE n0,n1;    NODE n0,n1;
   
         ptoup((P)ARG0(arg),&p);    ptoup((P)ARG0(arg),&p);
         decompup(p,QTOS((Q)ARG1(arg))+1,&low,&up);    decompup(p,QTOS((Q)ARG1(arg))+1,&low,&up);
         uptop(low,&l);    uptop(low,&l);
         uptop(up,&u);    uptop(up,&u);
         MKNODE(n1,u,0); MKNODE(n0,l,n1);    MKNODE(n1,u,0); MKNODE(n0,l,n1);
         MKLIST(*rp,n0);    MKLIST(*rp,n0);
 }  }
   
 void Purembymul(arg,rp)  void Purembymul(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         UP p1,p2,r;    UP p1,p2,r;
   
         if ( !ARG0(arg) || !ARG1(arg) )    if ( !ARG0(arg) || !ARG1(arg) )
                 *rp = 0;      *rp = 0;
         else {    else {
                 ptoup((P)ARG0(arg),&p1);      ptoup((P)ARG0(arg),&p1);
                 ptoup((P)ARG1(arg),&p2);      ptoup((P)ARG1(arg),&p2);
                 rembymulup(p1,p2,&r);      rembymulup(p1,p2,&r);
                 uptop(r,rp);      uptop(r,rp);
         }    }
 }  }
   
 /*  /*
Line 1308  P *rp;
Line 1337  P *rp;
  * p2*inv = 1 mod x^d2   * p2*inv = 1 mod x^d2
  */   */
   
 void Purembymul_precomp(arg,rp)  void Purembymul_precomp(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         UP p1,p2,inv,r;    UP p1,p2,inv,r;
   
         if ( !ARG0(arg) || !ARG1(arg) )    if ( !ARG0(arg) || !ARG1(arg) )
                 *rp = 0;      *rp = 0;
         else {    else {
                 ptoup((P)ARG0(arg),&p1);      ptoup((P)ARG0(arg),&p1);
                 ptoup((P)ARG1(arg),&p2);      ptoup((P)ARG1(arg),&p2);
                 ptoup((P)ARG2(arg),&inv);      ptoup((P)ARG2(arg),&inv);
                 if ( p1->d >= 2*p2->d ) {      if ( p1->d >= 2*p2->d ) {
                         error("urembymul_precomp : degree of 1st arg is too large");        error("urembymul_precomp : degree of 1st arg is too large");
 /*                      fprintf(stderr,"urembymul_precomp : degree of 1st arg is too large"); */  /*      fprintf(stderr,"urembymul_precomp : degree of 1st arg is too large"); */
                         remup(p1,p2,&r);        remup(p1,p2,&r);
                 } else      } else
                         hybrid_rembymulup_special(current_ff,p1,p2,inv,&r);        hybrid_rembymulup_special(current_ff,p1,p2,inv,&r);
                 uptop(r,rp);      uptop(r,rp);
         }    }
 }  }
   
 void Puinvmod(arg,rp)  void Puinvmod(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         UP p,r;    UP p,r;
   
         ptoup((P)ARG0(arg),&p);    ptoup((P)ARG0(arg),&p);
         invmodup(p,QTOS((Q)ARG1(arg)),&r);    invmodup(p,QTOS((Q)ARG1(arg)),&r);
         uptop(r,rp);    uptop(r,rp);
 }  }
   
 void Purevinvmod(arg,rp)  void Purevinvmod(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         UP p,pr,r;    UP p,pr,r;
   
         ptoup((P)ARG0(arg),&p);    ptoup((P)ARG0(arg),&p);
         reverseup(p,p->d,&pr);    reverseup(p,p->d,&pr);
         invmodup(pr,QTOS((Q)ARG1(arg)),&r);    invmodup(pr,QTOS((Q)ARG1(arg)),&r);
         uptop(r,rp);    uptop(r,rp);
 }  }
   
 void Ppwrmod_ff(arg,rp)  void Ppwrmod_ff(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         UP p1,p2;    UP p1,p2;
   
         ptoup((P)ARG0(arg),&p1);    ptoup((P)ARG0(arg),&p1);
         switch ( current_ff ) {    switch ( current_ff ) {
                 case FF_GFP:      case FF_GFP:
                         hybrid_powermodup(p1,&p2); break;        hybrid_powermodup(p1,&p2); break;
                 case FF_GF2N:      case FF_GF2N:
                         powermodup_gf2n(p1,&p2); break;        powermodup_gf2n(p1,&p2); break;
                 case FF_GFPN:      case FF_GFPN:
                 case FF_GFS:      case FF_GFS:
                         powermodup(p1,&p2); break;      case FF_GFSN:
                 default:        powermodup(p1,&p2); break;
                         error("pwrmod_ff : current_ff is not set");      default:
         }        error("pwrmod_ff : current_ff is not set");
         uptop(p2,rp);    }
     uptop(p2,rp);
 }  }
   
 void Pgeneric_pwrmod_ff(arg,rp)  void Pgeneric_pwrmod_ff(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         UP g,f,r;    UP g,f,r;
   
         ptoup((P)ARG0(arg),&g);    ptoup((P)ARG0(arg),&g);
         ptoup((P)ARG1(arg),&f);    ptoup((P)ARG1(arg),&f);
         switch ( current_ff ) {    switch ( current_ff ) {
                 case FF_GFP:      case FF_GFP:
                         hybrid_generic_powermodup(g,f,(Q)ARG2(arg),&r); break;        hybrid_generic_powermodup(g,f,(Q)ARG2(arg),&r); break;
                 case FF_GF2N:      case FF_GF2N:
                         generic_powermodup_gf2n(g,f,(Q)ARG2(arg),&r); break;        generic_powermodup_gf2n(g,f,(Q)ARG2(arg),&r); break;
                 case FF_GFPN:      case FF_GFPN:
                 case FF_GFS:      case FF_GFS:
                         generic_powermodup(g,f,(Q)ARG2(arg),&r); break;      case FF_GFSN:
                 default:        generic_powermodup(g,f,(Q)ARG2(arg),&r); break;
                         error("generic_pwrmod_ff : current_ff is not set");      default:
         }        error("generic_pwrmod_ff : current_ff is not set");
         uptop(r,rp);    }
     uptop(r,rp);
 }  }
   
 void Ppwrtab_ff(arg,rp)  void Ppwrtab_ff(NODE arg,VECT *rp)
 NODE arg;  
 VECT *rp;  
 {  {
         UP f,xp;    UP f,xp;
         UP *tab;    UP *tab;
         VECT r;    VECT r;
         int i,d;    int i,d;
   
         ptoup((P)ARG0(arg),&f);    ptoup((P)ARG0(arg),&f);
         ptoup((P)ARG1(arg),&xp);    ptoup((P)ARG1(arg),&xp);
         d = f->d;    d = f->d;
   
         tab = (UP *)ALLOCA(d*sizeof(UP));    tab = (UP *)ALLOCA(d*sizeof(UP));
         switch ( current_ff ) {    switch ( current_ff ) {
                 case FF_GFP:      case FF_GFP:
                         hybrid_powertabup(f,xp,tab); break;        hybrid_powertabup(f,xp,tab); break;
                 case FF_GF2N:      case FF_GF2N:
                         powertabup_gf2n(f,xp,tab); break;        powertabup_gf2n(f,xp,tab); break;
                 case FF_GFPN:      case FF_GFPN:
                 case FF_GFS:      case FF_GFS:
                         powertabup(f,xp,tab); break;      case FF_GFSN:
                 default:        powertabup(f,xp,tab); break;
                         error("pwrtab_ff : current_ff is not set");      default:
         }        error("pwrtab_ff : current_ff is not set");
         MKVECT(r,d); *rp = r;    }
         for ( i = 0; i < d; i++ )    MKVECT(r,d); *rp = r;
                 uptop(tab[i],(P *)&BDY(r)[i]);    for ( i = 0; i < d; i++ )
       uptop(tab[i],(P *)&BDY(r)[i]);
 }  }
   
 void Pkpwrmod_lm(arg,rp)  void Pkpwrmod_lm(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         UP p1,p2;    UP p1,p2;
   
         ptoup((P)ARG0(arg),&p1);    ptoup((P)ARG0(arg),&p1);
         powermodup(p1,&p2);    powermodup(p1,&p2);
         uptop(p2,rp);    uptop(p2,rp);
 }  }
   
 void Pkgeneric_pwrmod_lm(arg,rp)  void Pkgeneric_pwrmod_lm(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         UP g,f,r;    UP g,f,r;
   
         ptoup((P)ARG0(arg),&g);    ptoup((P)ARG0(arg),&g);
         ptoup((P)ARG1(arg),&f);    ptoup((P)ARG1(arg),&f);
         generic_powermodup(g,f,(Q)ARG2(arg),&r);    generic_powermodup(g,f,(Q)ARG2(arg),&r);
         uptop(r,rp);    uptop(r,rp);
 }  }
   
 void Pkpwrtab_lm(arg,rp)  void Pkpwrtab_lm(NODE arg,VECT *rp)
 NODE arg;  
 VECT *rp;  
 {  {
         UP f,xp;    UP f,xp;
         UP *tab;    UP *tab;
         VECT r;    VECT r;
         int i,d;    int i,d;
   
         ptoup((P)ARG0(arg),&f);    ptoup((P)ARG0(arg),&f);
         ptoup((P)ARG1(arg),&xp);    ptoup((P)ARG1(arg),&xp);
         d = f->d;    d = f->d;
   
         tab = (UP *)ALLOCA(d*sizeof(UP));    tab = (UP *)ALLOCA(d*sizeof(UP));
         powertabup(f,xp,tab);    powertabup(f,xp,tab);
         MKVECT(r,d); *rp = r;    MKVECT(r,d); *rp = r;
         for ( i = 0; i < d; i++ )    for ( i = 0; i < d; i++ )
                 uptop(tab[i],(P *)&BDY(r)[i]);      uptop(tab[i],(P *)&BDY(r)[i]);
 }  }
   
 void Plazy_lm(arg,rp)  void Plazy_lm(NODE arg,Q *rp)
 NODE arg;  
 Q *rp;  
 {  {
         lm_lazy = QTOS((Q)ARG0(arg));    lm_lazy = QTOS((Q)ARG0(arg));
         *rp = 0;    *rp = 0;
 }  }
   
 void Pkmul(arg,rp)  void Pkmul(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         P n1,n2;    P n1,n2;
   
         n1 = (P)ARG0(arg); n2 = (P)ARG1(arg);    n1 = (P)ARG0(arg); n2 = (P)ARG1(arg);
         asir_assert(n1,O_P,"kmul");    asir_assert(n1,O_P,"kmul");
         asir_assert(n2,O_P,"kmul");    asir_assert(n2,O_P,"kmul");
         kmulp(CO,n1,n2,rp);    kmulp(CO,n1,n2,rp);
 }  }
   
 void Pksquare(arg,rp)  void Pksquare(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         P n1;    P n1;
   
         n1 = (P)ARG0(arg);    n1 = (P)ARG0(arg);
         asir_assert(n1,O_P,"ksquare");    asir_assert(n1,O_P,"ksquare");
         ksquarep(CO,n1,rp);    ksquarep(CO,n1,rp);
 }  }
   
 void Pktmul(arg,rp)  void Pktmul(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         UP p1,p2,r;    UP p1,p2,r;
   
         ptoup((P)ARG0(arg),&p1);    ptoup((P)ARG0(arg),&p1);
         ptoup((P)ARG1(arg),&p2);    ptoup((P)ARG1(arg),&p2);
         tkmulup(p1,p2,QTOS((Q)ARG2(arg))+1,&r);    tkmulup(p1,p2,QTOS((Q)ARG2(arg))+1,&r);
         uptop(r,rp);    uptop(r,rp);
 }  }
   
 void Pumul(arg,rp)  void Pumul(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         P a1,a2;    P a1,a2;
         UP p1,p2,r;    UP p1,p2,r;
   
         a1 = (P)ARG0(arg); a2 = (P)ARG1(arg);    a1 = (P)ARG0(arg); a2 = (P)ARG1(arg);
         if ( !a1 || !a2 || NUM(a1) || NUM(a2) )    if ( !a1 || !a2 || NUM(a1) || NUM(a2) )
                 mulp(CO,a1,a2,rp);      mulp(CO,a1,a2,rp);
         else {    else {
                 if ( !uzpcheck(a1) || !uzpcheck(a2) || VR(a1) != VR(a2) )      if ( !uzpcheck((Obj)a1) || !uzpcheck((Obj)a2) || VR(a1) != VR(a2) )
                         error("umul : invalid argument");        error("umul : invalid argument");
                 ptoup(a1,&p1);      ptoup(a1,&p1);
                 ptoup(a2,&p2);      ptoup(a2,&p2);
                 hybrid_mulup(0,p1,p2,&r);      hybrid_mulup(0,p1,p2,&r);
                 uptop(r,rp);      uptop(r,rp);
         }    }
 }  }
   
 void Pusquare(arg,rp)  void Pusquare(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         UP p1,p2,r;    UP p1,r;
   
         ptoup((P)ARG0(arg),&p1);    ptoup((P)ARG0(arg),&p1);
         hybrid_squareup(0,p1,&r);    hybrid_squareup(0,p1,&r);
         uptop(r,rp);    uptop(r,rp);
 }  }
   
 void Putmul(arg,rp)  void Putmul(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         UP p1,p2,r;    UP p1,p2,r;
   
         ptoup((P)ARG0(arg),&p1);    ptoup((P)ARG0(arg),&p1);
         ptoup((P)ARG1(arg),&p2);    ptoup((P)ARG1(arg),&p2);
         hybrid_tmulup(0,p1,p2,QTOS((Q)ARG2(arg))+1,&r);    hybrid_tmulup(0,p1,p2,QTOS((Q)ARG2(arg))+1,&r);
         uptop(r,rp);    uptop(r,rp);
 }  }
   
 void Pumul_ff(arg,rp)  void Pumul_ff(NODE arg,Obj *rp)
 NODE arg;  
 Obj *rp;  
 {  {
         P a1,a2;    P a1,a2;
         UP p1,p2,r;    UP p1,p2,r;
         P p;    P p;
   
         a1 = (P)ARG0(arg); a2 = (P)ARG1(arg);    a1 = (P)ARG0(arg); a2 = (P)ARG1(arg);
         ptoup(a1,&p1);    ptoup(a1,&p1);
         ptoup(a2,&p2);    ptoup(a2,&p2);
         hybrid_mulup(current_ff,p1,p2,&r);    hybrid_mulup(current_ff,p1,p2,&r);
         uptop(r,&p);    uptop(r,&p);
         simp_ff((Obj)p,rp);    simp_ff((Obj)p,rp);
 }  }
   
 void Pusquare_ff(arg,rp)  void Pusquare_ff(NODE arg,Obj *rp)
 NODE arg;  
 Obj *rp;  
 {  {
         UP p1,p2,r;    UP p1,r;
         P p;    P p;
   
         ptoup((P)ARG0(arg),&p1);    ptoup((P)ARG0(arg),&p1);
         hybrid_squareup(current_ff,p1,&r);    hybrid_squareup(current_ff,p1,&r);
         uptop(r,&p);    uptop(r,&p);
         simp_ff((Obj)p,rp);    simp_ff((Obj)p,rp);
 }  }
   
 void Putmul_ff(arg,rp)  void Putmul_ff(NODE arg,Obj *rp)
 NODE arg;  
 Obj *rp;  
 {  {
         UP p1,p2,r;    UP p1,p2,r;
         P p;    P p;
   
         ptoup((P)ARG0(arg),&p1);    ptoup((P)ARG0(arg),&p1);
         ptoup((P)ARG1(arg),&p2);    ptoup((P)ARG1(arg),&p2);
         hybrid_tmulup(current_ff,p1,p2,QTOS((Q)ARG2(arg))+1,&r);    hybrid_tmulup(current_ff,p1,p2,QTOS((Q)ARG2(arg))+1,&r);
         uptop(r,&p);    uptop(r,&p);
         simp_ff((Obj)p,rp);    simp_ff((Obj)p,rp);
 }  }
   
 void Phfmul_lm(arg,rp)  void Phfmul_lm(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         UP p1,p2,r;    UP p1,p2,r;
         UP hi,lo,mid,t,s,p10,p11,p20,p21;    UP hi,lo,mid,t,s,p10,p11,p20,p21;
         unsigned int m,d;    unsigned int m,d;
         int i;    int i;
   
         ptoup((P)ARG0(arg),&p1);    ptoup((P)ARG0(arg),&p1);
         ptoup((P)ARG1(arg),&p2);    ptoup((P)ARG1(arg),&p2);
         d = MAX(p1->d,p2->d);    d = MAX(p1->d,p2->d);
         for ( m = 1; m < d; m <<= 1 );    for ( m = 1; m < d; m <<= 1 );
         if ( m > d )    if ( m > d )
                 m >>= 1;      m >>= 1;
         if ( d-m < 10000 ) {    if ( d-m < 10000 ) {
                 decompup(p1,m,&p10,&p11); /* p1 = p11*x^m+p10 */      decompup(p1,m,&p10,&p11); /* p1 = p11*x^m+p10 */
                 decompup(p2,m,&p20,&p21); /* p2 = p21*x^m+p20 */      decompup(p2,m,&p20,&p21); /* p2 = p21*x^m+p20 */
                 fft_mulup_lm(p10,p20,&lo);      fft_mulup_lm(p10,p20,&lo);
                 kmulup(p11,p21,&hi);      kmulup(p11,p21,&hi);
                 kmulup(p11,p20,&t); kmulup(p10,p21,&s); addup(t,s,&mid);      kmulup(p11,p20,&t); kmulup(p10,p21,&s); addup(t,s,&mid);
                 r = UPALLOC(2*d);      r = UPALLOC(2*d);
                 bzero((char *)COEF(r),(2*d+1)*sizeof(Num));      bzero((char *)COEF(r),(2*d+1)*sizeof(Num));
                 if ( lo )      if ( lo )
                         bcopy((char *)COEF(lo),(char *)COEF(r),(DEG(lo)+1)*sizeof(Num));        bcopy((char *)COEF(lo),(char *)COEF(r),(DEG(lo)+1)*sizeof(Num));
                 if ( hi )      if ( hi )
                         bcopy((char *)COEF(hi),(char *)(COEF(r)+2*m),(DEG(hi)+1)*sizeof(Num));        bcopy((char *)COEF(hi),(char *)(COEF(r)+2*m),(DEG(hi)+1)*sizeof(Num));
                 for ( i = 2*d; i >= 0 && !COEF(r)[i]; i-- );      for ( i = 2*d; i >= 0 && !COEF(r)[i]; i-- );
                 if ( i < 0 )      if ( i < 0 )
                         r = 0;        r = 0;
                 else {      else {
                         DEG(r) = i;        DEG(r) = i;
                         t = UPALLOC(DEG(mid)+m); DEG(t) = DEG(mid)+m;        t = UPALLOC(DEG(mid)+m); DEG(t) = DEG(mid)+m;
                         bzero((char *)COEF(t),(DEG(mid)+m+1)*sizeof(Num));        bzero((char *)COEF(t),(DEG(mid)+m+1)*sizeof(Num));
                         bcopy((char *)COEF(mid),(char *)(COEF(t)+m),(DEG(mid)+1)*sizeof(Num));        bcopy((char *)COEF(mid),(char *)(COEF(t)+m),(DEG(mid)+1)*sizeof(Num));
                         addup(t,r,&s);        addup(t,r,&s);
                         r = s;        r = s;
                 }      }
         } else    } else
                 fft_mulup_lm(p1,p2,&r);      fft_mulup_lm(p1,p2,&r);
         uptop(r,rp);    uptop(r,rp);
 }  }
   
 void Pfmultest(arg,rp)  void Pfmultest(NODE arg,LIST *rp)
 NODE arg;  
 LIST *rp;  
 {  {
         P p1,p2,r;    P p1,p2,r;
         int d1,d2;    int d1,d2;
         UM w1,w2,wr;    UM w1,w2,wr;
         unsigned int *f1,*f2,*fr,*w;    unsigned int *f1,*f2,*fr,*w;
         int index,mod,root,d,maxint,i;    int index,mod,root,d,maxint,i;
         int cond;    int cond;
         Q prime;    Q prime;
         NODE n0,n1;    NODE n0,n1;
   
         p1 = (P)ARG0(arg); p2 = (P)ARG1(arg); index = QTOS((Q)ARG2(arg));    p1 = (P)ARG0(arg); p2 = (P)ARG1(arg); index = QTOS((Q)ARG2(arg));
         FFT_primes(index,&mod,&root,&d);    FFT_primes(index,&mod,&root,&d);
         maxint = 1<<d;    maxint = 1<<d;
         d1 = UDEG(p1); d2 = UDEG(p2);    d1 = UDEG(p1); d2 = UDEG(p2);
         if ( maxint < d1+d2+1 )    if ( maxint < d1+d2+1 )
                 *rp = 0;      *rp = 0;
         else {    else {
                 w1 = W_UMALLOC(d1); w2 = W_UMALLOC(d2);      w1 = W_UMALLOC(d1); w2 = W_UMALLOC(d2);
                 wr = W_UMALLOC(d1+d2);      wr = W_UMALLOC(d1+d2);
                 ptoum(mod,p1,w1); ptoum(mod,p2,w2);      ptoum(mod,p1,w1); ptoum(mod,p2,w2);
                 f1 = (unsigned int *)ALLOCA(maxint*sizeof(unsigned int));      f1 = (unsigned int *)ALLOCA(maxint*sizeof(unsigned int));
                 f2 = (unsigned int *)ALLOCA(maxint*sizeof(unsigned int));      f2 = (unsigned int *)ALLOCA(maxint*sizeof(unsigned int));
                 fr = (unsigned int *)ALLOCA(maxint*sizeof(unsigned int));      fr = (unsigned int *)ALLOCA(maxint*sizeof(unsigned int));
                 w = (unsigned int *)ALLOCA(12*maxint*sizeof(unsigned int));      w = (unsigned int *)ALLOCA(12*maxint*sizeof(unsigned int));
   
                 for ( i = 0; i <= d1; i++ )      for ( i = 0; i <= d1; i++ )
                         f1[i] = (unsigned int)w1->c[i];        f1[i] = (unsigned int)w1->c[i];
                 for ( i = 0; i <= d2; i++ )      for ( i = 0; i <= d2; i++ )
                         f2[i] = (unsigned int)w2->c[i];        f2[i] = (unsigned int)w2->c[i];
   
                 cond = FFT_pol_product(d1,f1,d2,f2,fr,index,w);      cond = FFT_pol_product(d1,f1,d2,f2,fr,index,w);
                 if ( cond )      if ( cond )
                         error("fmultest : ???");        error("fmultest : ???");
                 wr->d = d1+d2;      wr->d = d1+d2;
                 for ( i = 0; i <= d1+d2; i++ )      for ( i = 0; i <= d1+d2; i++ )
                         wr->c[i] = (unsigned int)fr[i];        wr->c[i] = (unsigned int)fr[i];
                 umtop(VR(p1),wr,&r);      umtop(VR(p1),wr,&r);
                 STOQ(mod,prime);      STOQ(mod,prime);
                 MKNODE(n1,prime,0);      MKNODE(n1,prime,0);
                 MKNODE(n0,r,n1);      MKNODE(n0,r,n1);
                 MKLIST(*rp,n0);      MKLIST(*rp,n0);
         }    }
 }  }
   
 void Pkmulum(arg,rp)  void Pkmulum(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         P p1,p2;    P p1,p2;
         int d1,d2,mod;    int d1,d2,mod;
         UM w1,w2,wr;    UM w1,w2,wr;
   
         p1 = (P)ARG0(arg); p2 = (P)ARG1(arg); mod = QTOS((Q)ARG2(arg));    p1 = (P)ARG0(arg); p2 = (P)ARG1(arg); mod = QTOS((Q)ARG2(arg));
         d1 = UDEG(p1); d2 = UDEG(p2);    d1 = UDEG(p1); d2 = UDEG(p2);
         w1 = W_UMALLOC(d1); w2 = W_UMALLOC(d2);    w1 = W_UMALLOC(d1); w2 = W_UMALLOC(d2);
         wr = W_UMALLOC(d1+d2);    wr = W_UMALLOC(d1+d2);
         ptoum(mod,p1,w1); ptoum(mod,p2,w2);    ptoum(mod,p1,w1); ptoum(mod,p2,w2);
         kmulum(mod,w1,w2,wr);    kmulum(mod,w1,w2,wr);
         umtop(VR(p1),wr,rp);    umtop(VR(p1),wr,rp);
 }  }
   
 void Pksquareum(arg,rp)  void Pksquareum(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         P p1;    P p1;
         int d1,mod;    int d1,mod;
         UM w1,wr;    UM w1,wr;
   
         p1 = (P)ARG0(arg); mod = QTOS((Q)ARG1(arg));    p1 = (P)ARG0(arg); mod = QTOS((Q)ARG1(arg));
         d1 = UDEG(p1);    d1 = UDEG(p1);
         w1 = W_UMALLOC(d1);    w1 = W_UMALLOC(d1);
         wr = W_UMALLOC(2*d1);    wr = W_UMALLOC(2*d1);
         ptoum(mod,p1,w1);    ptoum(mod,p1,w1);
         kmulum(mod,w1,w1,wr);    kmulum(mod,w1,w1,wr);
         umtop(VR(p1),wr,rp);    umtop(VR(p1),wr,rp);
 }  }
   
 void Ptracemod_gf2n(arg,rp)  void Ptracemod_gf2n(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         UP g,f,r;    UP g,f,r;
   
         ptoup((P)ARG0(arg),&g);    ptoup((P)ARG0(arg),&g);
         ptoup((P)ARG1(arg),&f);    ptoup((P)ARG1(arg),&f);
         tracemodup_gf2n(g,f,(Q)ARG2(arg),&r);    tracemodup_gf2n(g,f,(Q)ARG2(arg),&r);
         uptop(r,rp);    uptop(r,rp);
 }  }
   
 void Pumul_specialmod(arg,rp)  void Pumul_specialmod(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         P a1,a2;    P a1,a2;
         UP p1,p2,r;    UP p1,p2,r;
         int i,nmod;    int i,nmod;
         int *modind;    int *modind;
         NODE t,n;    NODE t,n;
   
         a1 = (P)ARG0(arg); a2 = (P)ARG1(arg);    a1 = (P)ARG0(arg); a2 = (P)ARG1(arg);
         if ( !a1 || !a2 || NUM(a1) || NUM(a2) )    if ( !a1 || !a2 || NUM(a1) || NUM(a2) )
                 mulp(CO,a1,a2,rp);      mulp(CO,a1,a2,rp);
         else {    else {
                 if ( !uzpcheck(a1) || !uzpcheck(a2) || VR(a1) != VR(a2) )      if ( !uzpcheck((Obj)a1) || !uzpcheck((Obj)a2) || VR(a1) != VR(a2) )
                         error("umul_specialmod : invalid argument");        error("umul_specialmod : invalid argument");
                 ptoup(a1,&p1);      ptoup(a1,&p1);
                 ptoup(a2,&p2);      ptoup(a2,&p2);
                 n = BDY((LIST)ARG2(arg));      n = BDY((LIST)ARG2(arg));
                 nmod = length(n);      nmod = length(n);
                 modind = (int *)MALLOC_ATOMIC(nmod*sizeof(int));      modind = (int *)MALLOC_ATOMIC(nmod*sizeof(int));
                 for ( i = 0, t = n; i < nmod; i++, t = NEXT(t) )      for ( i = 0, t = n; i < nmod; i++, t = NEXT(t) )
                         modind[i] = QTOS((Q)BDY(t));        modind[i] = QTOS((Q)BDY(t));
                 fft_mulup_specialmod_main(p1,p2,0,modind,nmod,&r);      fft_mulup_specialmod_main(p1,p2,0,modind,nmod,&r);
                 uptop(r,rp);      uptop(r,rp);
         }    }
 }  }
   
 void Pusquare_specialmod(arg,rp)  void Pusquare_specialmod(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         P a1;    P a1;
         UP p1,r;    UP p1,r;
         int i,nmod;    int i,nmod;
         int *modind;    int *modind;
         NODE t,n;    NODE t,n;
   
         a1 = (P)ARG0(arg);    a1 = (P)ARG0(arg);
         if ( !a1 || NUM(a1) )    if ( !a1 || NUM(a1) )
                 mulp(CO,a1,a1,rp);      mulp(CO,a1,a1,rp);
         else {    else {
                 if ( !uzpcheck(a1) )      if ( !uzpcheck((Obj)a1) )
                         error("usquare_specialmod : invalid argument");        error("usquare_specialmod : invalid argument");
                 ptoup(a1,&p1);      ptoup(a1,&p1);
                 n = BDY((LIST)ARG1(arg));      n = BDY((LIST)ARG1(arg));
                 nmod = length(n);      nmod = length(n);
                 modind = (int *)MALLOC_ATOMIC(nmod*sizeof(int));      modind = (int *)MALLOC_ATOMIC(nmod*sizeof(int));
                 for ( i = 0, t = n; i < nmod; i++, t = NEXT(t) )      for ( i = 0, t = n; i < nmod; i++, t = NEXT(t) )
                         modind[i] = QTOS((Q)BDY(t));        modind[i] = QTOS((Q)BDY(t));
                 fft_mulup_specialmod_main(p1,p1,0,modind,nmod,&r);      fft_mulup_specialmod_main(p1,p1,0,modind,nmod,&r);
                 uptop(r,rp);      uptop(r,rp);
         }    }
 }  }
   
 void Putmul_specialmod(arg,rp)  void Putmul_specialmod(NODE arg,P *rp)
 NODE arg;  
 P *rp;  
 {  {
         P a1,a2;    P a1,a2;
         UP p1,p2,r;    UP p1,p2,r;
         int i,nmod;    int i,nmod;
         int *modind;    int *modind;
         NODE t,n;    NODE t,n;
   
         a1 = (P)ARG0(arg); a2 = (P)ARG1(arg);    a1 = (P)ARG0(arg); a2 = (P)ARG1(arg);
         if ( !a1 || !a2 || NUM(a1) || NUM(a2) )    if ( !a1 || !a2 || NUM(a1) || NUM(a2) )
                 mulp(CO,a1,a2,rp);      mulp(CO,a1,a2,rp);
         else {    else {
                 if ( !uzpcheck(a1) || !uzpcheck(a2) || VR(a1) != VR(a2) )      if ( !uzpcheck((Obj)a1) || !uzpcheck((Obj)a2) || VR(a1) != VR(a2) )
                         error("utmul_specialmod : invalid argument");        error("utmul_specialmod : invalid argument");
                 ptoup(a1,&p1);      ptoup(a1,&p1);
                 ptoup(a2,&p2);      ptoup(a2,&p2);
                 n = BDY((LIST)ARG3(arg));      n = BDY((LIST)ARG3(arg));
                 nmod = length(n);      nmod = length(n);
                 modind = (int *)MALLOC_ATOMIC(nmod*sizeof(int));      modind = (int *)MALLOC_ATOMIC(nmod*sizeof(int));
                 for ( i = 0, t = n; i < nmod; i++, t = NEXT(t) )      for ( i = 0, t = n; i < nmod; i++, t = NEXT(t) )
                         modind[i] = QTOS((Q)BDY(t));        modind[i] = QTOS((Q)BDY(t));
                 fft_mulup_specialmod_main(p1,p2,QTOS((Q)ARG2(arg))+1,modind,nmod,&r);      fft_mulup_specialmod_main(p1,p2,QTOS((Q)ARG2(arg))+1,modind,nmod,&r);
                 uptop(r,rp);      uptop(r,rp);
         }    }
 }  }

Legend:
Removed from v.1.11  
changed lines
  Added in v.1.31

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