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

Diff for /OpenXM_contrib2/asir2000/builtin/dp-supp.c between version 1.46 and 1.66

version 1.46, 2007/09/19 05:42:59 version 1.66, 2017/08/31 02:36:20
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/dp-supp.c,v 1.45 2007/09/16 09:08:25 noro Exp $   * $OpenXM: OpenXM_contrib2/asir2000/builtin/dp-supp.c,v 1.65 2017/03/27 09:05:46 noro Exp $
 */  */
 #include "ca.h"  #include "ca.h"
 #include "base.h"  #include "base.h"
Line 53 
Line 53 
 #include "parse.h"  #include "parse.h"
 #include "ox.h"  #include "ox.h"
   
 #define HMAG(p) (p_mag(BDY(p)->c))  #define HMAG(p) (p_mag((P)BDY(p)->c))
   
 extern int (*cmpdl)();  extern int (*cmpdl)();
 extern double pz_t_e,pz_t_d,pz_t_d1,pz_t_c;  extern double pz_t_e,pz_t_d,pz_t_d1,pz_t_c;
Line 65  extern NODE TraceList;
Line 65  extern NODE TraceList;
 int show_orderspec;  int show_orderspec;
   
 void print_composite_order_spec(struct order_spec *spec);  void print_composite_order_spec(struct order_spec *spec);
   void dpm_rest(DPM,DPM *);
   
 /*  /*
  * content reduction   * content reduction
Line 112  void dp_ptozp(DP p,DP *rp)
Line 113  void dp_ptozp(DP p,DP *rp)
                         if ( NUM(m->c) )                          if ( NUM(m->c) )
                                 w[i] = (Q)m->c;                                  w[i] = (Q)m->c;
                         else                          else
                                 ptozp(m->c,1,&w[i],&t);                                  ptozp((P)m->c,1,&w[i],&t);
                 sortbynm(w,n);                  sortbynm(w,n);
                 qltozl(w,n,&dvr);                  qltozl(w,n,&dvr);
                 for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {                  for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
                         NEXTMP(mr0,mr); divsp(CO,m->c,(P)dvr,&mr->c); mr->dl = m->dl;                          NEXTMP(mr0,mr); divsp(CO,(P)m->c,(P)dvr,(P *)&mr->c); mr->dl = m->dl;
                 }                  }
                 NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;                  NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
         }          }
Line 146  void dp_ptozp2(DP p0,DP p1,DP *hp,DP *rp)
Line 147  void dp_ptozp2(DP p0,DP p1,DP *hp,DP *rp)
         *hp = h; *rp = r;          *hp = h; *rp = r;
 }  }
   
   void dpm_ptozp(DPM p,DPM *rp)
   {
           DMM m,mr,mr0;
           int i,n;
           Q *w;
           Q dvr;
           P t;
   
           if ( !p )
                   *rp = 0;
           else {
                   for ( m =BDY(p), n = 0; m; m = NEXT(m), n++ );
                   w = (Q *)ALLOCA(n*sizeof(Q));
                   for ( m =BDY(p), i = 0; i < n; m = NEXT(m), i++ )
                           if ( NUM(m->c) )
                                   w[i] = (Q)m->c;
                           else
                                   ptozp((P)m->c,1,&w[i],&t);
                   sortbynm(w,n);
                   qltozl(w,n,&dvr);
                   for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
                           NEXTDMM(mr0,mr); divsp(CO,(P)m->c,(P)dvr,(P *)&mr->c); mr->dl = m->dl; mr->pos = m->pos;
                   }
                   NEXT(mr) = 0; MKDPM(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
           }
   }
   
   void dpm_ptozp2(DPM p0,DPM p1,DPM *hp,DPM *rp)
   {
           DPM t,s,h,r;
           DMM m,mr,mr0,m0;
   
           adddpm(CO,p0,p1,&t); dpm_ptozp(t,&s);
           if ( !p0 ) {
                   h = 0; r = s;
           } else if ( !p1 ) {
                   h = s; r = 0;
           } else {
                   for ( mr0 = 0, m = BDY(s), m0 = BDY(p0); m0;
                           m = NEXT(m), m0 = NEXT(m0) ) {
                           NEXTDMM(mr0,mr); mr->c = m->c; mr->dl = m->dl; mr->pos = m->pos;
                   }
                   NEXT(mr) = 0; MKDPM(p0->nv,mr0,h); MKDPM(p0->nv,m,r);
           }
           if ( h )
                   h->sugar = p0->sugar;
           if ( r )
                   r->sugar = p1->sugar;
           *hp = h; *rp = r;
   }
   
   
 void dp_ptozp3(DP p,Q *dvr,DP *rp)  void dp_ptozp3(DP p,Q *dvr,DP *rp)
 {  {
         MP m,mr,mr0;          MP m,mr,mr0;
Line 162  void dp_ptozp3(DP p,Q *dvr,DP *rp)
Line 215  void dp_ptozp3(DP p,Q *dvr,DP *rp)
                         if ( NUM(m->c) )                          if ( NUM(m->c) )
                                 w[i] = (Q)m->c;                                  w[i] = (Q)m->c;
                         else                          else
                                 ptozp(m->c,1,&w[i],&t);                                  ptozp((P)m->c,1,&w[i],&t);
                 sortbynm(w,n);                  sortbynm(w,n);
                 qltozl(w,n,dvr);                  qltozl(w,n,dvr);
                 for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {                  for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
                         NEXTMP(mr0,mr); divsp(CO,m->c,(P)(*dvr),&mr->c); mr->dl = m->dl;                          NEXTMP(mr0,mr); divsp(CO,(P)m->c,(P)(*dvr),(P *)&mr->c); mr->dl = m->dl;
                 }                  }
                 NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;                  NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
         }          }
Line 193  void dp_idiv(DP p,Q c,DP *rp)
Line 246  void dp_idiv(DP p,Q c,DP *rp)
                         divsn(NM((Q)(m->c)),nm,&q);                          divsn(NM((Q)(m->c)),nm,&q);
                         s = sgn*SGN((Q)(m->c));                          s = sgn*SGN((Q)(m->c));
                         NTOQ(q,s,t);                          NTOQ(q,s,t);
                         mr->c = (P)t;                          mr->c = (Obj)t;
                         mr->dl = m->dl;                          mr->dl = m->dl;
                 }                  }
                 NEXT(mr) = 0; MKDP(p->nv,mr0,*rp);                  NEXT(mr) = 0; MKDP(p->nv,mr0,*rp);
Line 206  void dp_mbase(NODE hlist,NODE *mbase)
Line 259  void dp_mbase(NODE hlist,NODE *mbase)
 {  {
         DL *dl;          DL *dl;
         DL d;          DL d;
         int i,j,n,nvar,td;    int *t;
           int i,j,k,n,nvar,td;
   
         n = length(hlist); nvar = ((DP)BDY(hlist))->nv;          n = length(hlist); nvar = ((DP)BDY(hlist))->nv;
         dl = (DL *)MALLOC(n*sizeof(DL));          dl = (DL *)MALLOC(n*sizeof(DL));
         for ( i = 0; i < n; i++, hlist = NEXT(hlist) )  
                 dl[i] = BDY((DP)BDY(hlist))->dl;  
         NEWDL(d,nvar); *mbase = 0;          NEWDL(d,nvar); *mbase = 0;
           for ( i = 0; i < n; i++, hlist = NEXT(hlist) ) {
                   dl[i] = BDY((DP)BDY(hlist))->dl;
       /* trivial ideal check */
                   if ( (*cmpdl)(nvar,d,dl[i]) == 0 ) {
         return;
       }
     }
     /* zero-dim. ideal check */
     for ( i = 0; i < nvar; i++ ) {
       for ( j = 0; j < n; j++ ) {
         for ( k = 0, t = dl[j]->d; k < nvar; k++ )
           if ( k != i && t[k] != 0 ) break;
         if ( k == nvar ) break;
       }
       if ( j == n )
         error("dp_mbase : input ideal is not zero-dimensional");
     }
         while ( 1 ) {          while ( 1 ) {
                 insert_to_node(d,mbase,nvar);                  insert_to_node(d,mbase,nvar);
                 for ( i = nvar-1; i >= 0; ) {                  for ( i = nvar-1; i >= 0; ) {
Line 261  void insert_to_node(DL d,NODE *n,int nvar)
Line 330  void insert_to_node(DL d,NODE *n,int nvar)
   
         NEWDL(d1,nvar); d1->td = d->td;          NEWDL(d1,nvar); d1->td = d->td;
         bcopy((char *)d->d,(char *)d1->d,nvar*sizeof(int));          bcopy((char *)d->d,(char *)d1->d,nvar*sizeof(int));
         NEWMP(m); m->dl = d1; m->c = (P)ONE; NEXT(m) = 0;          NEWMP(m); m->dl = d1; m->c = (Obj)ONE; NEXT(m) = 0;
         MKDP(nvar,m,dp); dp->sugar = d->td;          MKDP(nvar,m,dp); dp->sugar = d->td;
         if ( !(*n) ) {          if ( !(*n) ) {
                 MKNODE(n1,dp,0); *n = n1;                  MKNODE(n1,dp,0); *n = n1;
Line 290  void dp_vtod(Q *c,DP p,DP *rp)
Line 359  void dp_vtod(Q *c,DP p,DP *rp)
                 *rp = 0;                  *rp = 0;
         else {          else {
                 for ( mr0 = 0, m = BDY(p), i = 0; m; m = NEXT(m), i++ ) {                  for ( mr0 = 0, m = BDY(p), i = 0; m; m = NEXT(m), i++ ) {
                         NEXTMP(mr0,mr); mr->c = (P)c[i]; mr->dl = m->dl;                          NEXTMP(mr0,mr); mr->c = (Obj)c[i]; mr->dl = m->dl;
                 }                  }
                 NEXT(mr) = 0; MKDP(p->nv,mr0,*rp);                  NEXT(mr) = 0; MKDP(p->nv,mr0,*rp);
                 (*rp)->sugar = p->sugar;                  (*rp)->sugar = p->sugar;
Line 332  void dp_ptozp_d(DP p,DP *rp)
Line 401  void dp_ptozp_d(DP p,DP *rp)
                 if ( PCoeffs ) {                  if ( PCoeffs ) {
                         dp_ptozp(p,rp); return;                          dp_ptozp(p,rp); return;
                 }                  }
                 if ( !Dist || p_mag(BDY(p)->c) <= mpi_mag ) {                  if ( !Dist || p_mag((P)BDY(p)->c) <= mpi_mag ) {
                         dist = 0; ndist = 0;                          dist = 0; ndist = 0;
                         if ( DP_NFStat ) fprintf(asir_out,"L");                          if ( DP_NFStat ) fprintf(asir_out,"L");
                 } else {                  } else {
Line 458  void dp_monic_sf(DP p,DP *rp)
Line 527  void dp_monic_sf(DP p,DP *rp)
         if ( !p )          if ( !p )
                 *rp = 0;                  *rp = 0;
         else {          else {
                 head_coef(BDY(p)->c,&c);                  head_coef((P)BDY(p)->c,&c);
                 divsdc(CO,p,(P)c,rp);                  divsdc(CO,p,(P)c,rp);
         }          }
 }  }
Line 487  void dp_prim(DP p,DP *rp)
Line 556  void dp_prim(DP p,DP *rp)
                 for ( m = BDY(p), n = 0; m; m = NEXT(m), n++ );                  for ( m = BDY(p), n = 0; m; m = NEXT(m), n++ );
                 w = (P *)ALLOCA(n*sizeof(P));                  w = (P *)ALLOCA(n*sizeof(P));
                 for ( m = BDY(p), i = 0; i < n; m = NEXT(m), i++ )                  for ( m = BDY(p), i = 0; i < n; m = NEXT(m), i++ )
                         w[i] = m->c;                          w[i] = (P)m->c;
                 gcdsf(CO,w,n,&g);                  gcdsf(CO,w,n,&g);
                 if ( NUM(g) )                  if ( NUM(g) )
                         dp_monic_sf(p,rp);                          dp_monic_sf(p,rp);
                 else {                  else {
                         for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {                          for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
                                 NEXTMP(mr0,mr); divsp(CO,m->c,g,&mr->c); mr->dl = m->dl;                                  NEXTMP(mr0,mr); divsp(CO,(P)m->c,g,(P *)&mr->c); mr->dl = m->dl;
                         }                          }
                         NEXT(mr) = 0; MKDP(p->nv,mr0,p1); p1->sugar = p->sugar;                          NEXT(mr) = 0; MKDP(p->nv,mr0,p1); p1->sugar = p->sugar;
                         dp_monic_sf(p1,rp);                          dp_monic_sf(p1,rp);
Line 508  void dp_prim(DP p,DP *rp)
Line 577  void dp_prim(DP p,DP *rp)
                 for ( m = BDY(p), n = 0; m; m = NEXT(m), n++ );                  for ( m = BDY(p), n = 0; m; m = NEXT(m), n++ );
                 if ( n == 1 ) {                  if ( n == 1 ) {
                         m = BDY(p);                          m = BDY(p);
                         NEWMP(mr); mr->dl = m->dl; mr->c = (P)ONE; NEXT(mr) = 0;                          NEWMP(mr); mr->dl = m->dl; mr->c = (Obj)ONE; NEXT(mr) = 0;
                         MKDP(p->nv,mr,*rp); (*rp)->sugar = p->sugar;                          MKDP(p->nv,mr,*rp); (*rp)->sugar = p->sugar;
                         return;                          return;
                 }                  }
Line 518  void dp_prim(DP p,DP *rp)
Line 587  void dp_prim(DP p,DP *rp)
                         if ( NUM(m->c) ) {                          if ( NUM(m->c) ) {
                                 c[i] = (Q)m->c; w[i] = (P)ONE;                                  c[i] = (Q)m->c; w[i] = (P)ONE;
                         } else                          } else
                                 ptozp(m->c,1,&c[i],&w[i]);                                  ptozp((P)m->c,1,&c[i],&w[i]);
                 qltozl(c,n,&dvr); heu_nezgcdnpz(CO,w,n,&t); mulp(CO,t,(P)dvr,&g);                  qltozl(c,n,&dvr); heu_nezgcdnpz(CO,w,n,&t); mulp(CO,t,(P)dvr,&g);
                 if ( NUM(g) )                  if ( NUM(g) )
                         *rp = p;                          *rp = p;
                 else {                  else {
                         for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {                          for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
                                 NEXTMP(mr0,mr); divsp(CO,m->c,g,&mr->c); mr->dl = m->dl;                                  NEXTMP(mr0,mr); divsp(CO,(P)m->c,g,(P *)&mr->c); mr->dl = m->dl;
                         }                          }
                         NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;                          NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
                         add_denomlist(g);                          add_denomlist(g);
Line 572  void dp_prim_mod(DP p,int mod,DP *rp)
Line 641  void dp_prim_mod(DP p,int mod,DP *rp)
         else if ( NoGCD )          else if ( NoGCD )
                 *rp = p;                  *rp = p;
         else {          else {
                 for ( m = BDY(p), g = m->c, m = NEXT(m); m; m = NEXT(m) ) {                  for ( m = BDY(p), g = (P)m->c, m = NEXT(m); m; m = NEXT(m) ) {
                         gcdprsmp(CO,mod,g,m->c,&t); g = t;                          gcdprsmp(CO,mod,g,(P)m->c,&t); g = t;
                 }                  }
                 for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {                  for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
                         NEXTMP(mr0,mr); divsmp(CO,mod,m->c,g,&mr->c); mr->dl = m->dl;                          NEXTMP(mr0,mr); divsmp(CO,mod,(P)m->c,g,(P *)&mr->c); mr->dl = m->dl;
                 }                  }
                 NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;                  NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
         }          }
Line 637  void dp_sp(DP p1,DP p2,DP *rp)
Line 706  void dp_sp(DP p1,DP p2,DP *rp)
                 }                  }
         }          }
   
         NEWMP(m); m->dl = d; m->c = (P)c2; NEXT(m) = 0;          NEWMP(m); m->dl = d; m->c = (Obj)c2; NEXT(m) = 0;
         MKDP(n,m,s1); s1->sugar = d->td; muld(CO,s1,p1,&t);          MKDP(n,m,s1); s1->sugar = d->td; muld(CO,s1,p1,&t);
   
         NEWDL(d,n); d->td = td - d2->td;          NEWDL(d,n); d->td = td - d2->td;
         for ( i = 0; i < n; i++ )          for ( i = 0; i < n; i++ )
                 d->d[i] = w[i] - d2->d[i];                  d->d[i] = w[i] - d2->d[i];
         NEWMP(m); m->dl = d; m->c = (P)c1; NEXT(m) = 0;          NEWMP(m); m->dl = d; m->c = (Obj)c1; NEXT(m) = 0;
         MKDP(n,m,s2); s2->sugar = d->td; muld(CO,s2,p2,&u);          MKDP(n,m,s2); s2->sugar = d->td; muld(CO,s2,p2,&u);
   
         subd(CO,t,u,rp);          subd(CO,t,u,rp);
Line 651  void dp_sp(DP p1,DP p2,DP *rp)
Line 720  void dp_sp(DP p1,DP p2,DP *rp)
                 LIST hist;                  LIST hist;
                 NODE node;                  NODE node;
   
                 node = mknode(4,ONE,0,s1,ONE);                  node = mknode(4,ONE,NULLP,s1,ONE);
                 MKLIST(hist,node);                  MKLIST(hist,node);
                 MKNODE(TraceList,hist,0);                  MKNODE(TraceList,hist,0);
   
                 node = mknode(4,ONE,0,0,ONE);                  node = mknode(4,ONE,NULLP,NULLP,ONE);
                 chsgnd(s2,(DP *)&ARG2(node));                  chsgnd(s2,(DP *)&ARG2(node));
                 MKLIST(hist,node);                  MKLIST(hist,node);
                 MKNODE(node,hist,TraceList); TraceList = node;                  MKNODE(node,hist,TraceList); TraceList = node;
         }          }
 }  }
   
   void dpm_sp(DPM p1,DPM p2,DPM *rp)
   {
           int i,n,td;
           int *w;
           DL d1,d2,d;
           MP m;
           DP s1,s2;
     DPM t,u;
           Q c,c1,c2;
           N gn,tn;
   
           n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
     if ( BDY(p1)->pos != BDY(p2)->pos ) {
       *rp = 0;
       return;
     }
           w = (int *)ALLOCA(n*sizeof(int));
           for ( i = 0, td = 0; i < n; i++ ) {
                   w[i] = MAX(d1->d[i],d2->d[i]); td += MUL_WEIGHT(w[i],i);
           }
   
           NEWDL(d,n); d->td = td - d1->td;
           for ( i = 0; i < n; i++ )
                   d->d[i] = w[i] - d1->d[i];
           c1 = (Q)BDY(p1)->c; c2 = (Q)BDY(p2)->c;
           if ( INT(c1) && INT(c2) ) {
                   gcdn(NM(c1),NM(c2),&gn);
                   if ( !UNIN(gn) ) {
                           divsn(NM(c1),gn,&tn); NTOQ(tn,SGN(c1),c); c1 = c;
                           divsn(NM(c2),gn,&tn); NTOQ(tn,SGN(c2),c); c2 = c;
                   }
           }
   
           NEWMP(m); m->dl = d; m->c = (Obj)c2; NEXT(m) = 0;
           MKDP(n,m,s1); s1->sugar = d->td; mulobjdpm(CO,(Obj)s1,p1,&t);
   
           NEWDL(d,n); d->td = td - d2->td;
           for ( i = 0; i < n; i++ )
                   d->d[i] = w[i] - d2->d[i];
           NEWMP(m); m->dl = d; m->c = (Obj)c1; NEXT(m) = 0;
           MKDP(n,m,s2); s2->sugar = d->td; mulobjdpm(CO,(Obj)s2,p2,&u);
   
           subdpm(CO,t,u,rp);
           if ( GenTrace ) {
                   LIST hist;
                   NODE node;
   
                   node = mknode(4,ONE,NULLP,s1,ONE);
                   MKLIST(hist,node);
                   MKNODE(TraceList,hist,0);
   
                   node = mknode(4,ONE,NULLP,NULLP,ONE);
                   chsgnd(s2,(DP *)&ARG2(node));
                   MKLIST(hist,node);
                   MKNODE(node,hist,TraceList); TraceList = node;
           }
   }
   
 void _dp_sp_dup(DP p1,DP p2,DP *rp)  void _dp_sp_dup(DP p1,DP p2,DP *rp)
 {  {
         int i,n,td;          int i,n,td;
Line 690  void _dp_sp_dup(DP p1,DP p2,DP *rp)
Line 817  void _dp_sp_dup(DP p1,DP p2,DP *rp)
                 }                  }
         }          }
   
         _NEWMP(m); m->dl = d; m->c = (P)c2; NEXT(m) = 0;          _NEWMP(m); m->dl = d; m->c = (Obj)c2; NEXT(m) = 0;
         _MKDP(n,m,s1); s1->sugar = d->td; _muld_dup(CO,s1,p1,&t); _free_dp(s1);          _MKDP(n,m,s1); s1->sugar = d->td; _muld_dup(CO,s1,p1,&t); _free_dp(s1);
   
         _NEWDL(d,n); d->td = td - d2->td;          _NEWDL(d,n); d->td = td - d2->td;
         for ( i = 0; i < n; i++ )          for ( i = 0; i < n; i++ )
                 d->d[i] = w[i] - d2->d[i];                  d->d[i] = w[i] - d2->d[i];
         _NEWMP(m); m->dl = d; chsgnp((P)c1,&m->c); NEXT(m) = 0;          _NEWMP(m); m->dl = d; chsgnp((P)c1,(P *)&m->c); NEXT(m) = 0;
         _MKDP(n,m,s2); s2->sugar = d->td; _muld_dup(CO,s2,p2,&u); _free_dp(s2);          _MKDP(n,m,s2); s2->sugar = d->td; _muld_dup(CO,s2,p2,&u); _free_dp(s2);
   
         _addd_destructive(CO,t,u,rp);          _addd_destructive(CO,t,u,rp);
Line 704  void _dp_sp_dup(DP p1,DP p2,DP *rp)
Line 831  void _dp_sp_dup(DP p1,DP p2,DP *rp)
                 LIST hist;                  LIST hist;
                 NODE node;                  NODE node;
   
                 node = mknode(4,ONE,0,s1,ONE);                  node = mknode(4,ONE,NULLP,s1,ONE);
                 MKLIST(hist,node);                  MKLIST(hist,node);
                 MKNODE(TraceList,hist,0);                  MKNODE(TraceList,hist,0);
   
                 node = mknode(4,ONE,0,0,ONE);                  node = mknode(4,ONE,NULLP,NULLP,ONE);
                 chsgnd(s2,(DP *)&ARG2(node));                  chsgnd(s2,(DP *)&ARG2(node));
                 MKLIST(hist,node);                  MKLIST(hist,node);
                 MKNODE(node,hist,TraceList); TraceList = node;                  MKNODE(node,hist,TraceList); TraceList = node;
Line 731  void dp_sp_mod(DP p1,DP p2,int mod,DP *rp)
Line 858  void dp_sp_mod(DP p1,DP p2,int mod,DP *rp)
         NEWDL_NOINIT(d,n); d->td = td - d1->td;          NEWDL_NOINIT(d,n); d->td = td - d1->td;
         for ( i = 0; i < n; i++ )          for ( i = 0; i < n; i++ )
                 d->d[i] = w[i] - d1->d[i];                  d->d[i] = w[i] - d1->d[i];
         NEWMP(m); m->dl = d; m->c = (P)BDY(p2)->c; NEXT(m) = 0;          NEWMP(m); m->dl = d; m->c = (Obj)BDY(p2)->c; NEXT(m) = 0;
         MKDP(n,m,s); s->sugar = d->td; mulmd(CO,mod,p1,s,&t);          MKDP(n,m,s); s->sugar = d->td; mulmd(CO,mod,p1,s,&t);
         NEWDL_NOINIT(d,n); d->td = td - d2->td;          NEWDL_NOINIT(d,n); d->td = td - d2->td;
         for ( i = 0; i < n; i++ )          for ( i = 0; i < n; i++ )
                 d->d[i] = w[i] - d2->d[i];                  d->d[i] = w[i] - d2->d[i];
         NEWMP(m); m->dl = d; m->c = (P)BDY(p1)->c; NEXT(m) = 0;          NEWMP(m); m->dl = d; m->c = (Obj)BDY(p1)->c; NEXT(m) = 0;
         MKDP(n,m,s); s->sugar = d->td; mulmd(CO,mod,p2,s,&u);          MKDP(n,m,s); s->sugar = d->td; mulmd(CO,mod,p2,s,&u);
         submd(CO,mod,t,u,rp);          submd(CO,mod,t,u,rp);
 }  }
Line 762  void _dp_sp_mod_dup(DP p1,DP p2,int mod,DP *rp)
Line 889  void _dp_sp_mod_dup(DP p1,DP p2,int mod,DP *rp)
         _NEWDL(d,n); d->td = td - d2->td;          _NEWDL(d,n); d->td = td - d2->td;
         for ( i = 0; i < n; i++ )          for ( i = 0; i < n; i++ )
                 d->d[i] = w[i] - d2->d[i];                  d->d[i] = w[i] - d2->d[i];
         _NEWMP(m); m->dl = d; m->c = STOI(mod - ITOS(BDY(p1)->c)); NEXT(m) = 0;          _NEWMP(m); m->dl = d; m->c = (Obj)STOI(mod - ITOS(BDY(p1)->c)); NEXT(m) = 0;
         _MKDP(n,m,s); s->sugar = d->td; _mulmd_dup(mod,s,p2,&u); _free_dp(s);          _MKDP(n,m,s); s->sugar = d->td; _mulmd_dup(mod,s,p2,&u); _free_dp(s);
         _addmd_destructive(mod,t,u,rp);          _addmd_destructive(mod,t,u,rp);
 }  }
Line 788  void _dp_sp_mod(DP p1,DP p2,int mod,DP *rp)
Line 915  void _dp_sp_mod(DP p1,DP p2,int mod,DP *rp)
         NEWDL(d,n); d->td = td - d2->td;          NEWDL(d,n); d->td = td - d2->td;
         for ( i = 0; i < n; i++ )          for ( i = 0; i < n; i++ )
                 d->d[i] = w[i] - d2->d[i];                  d->d[i] = w[i] - d2->d[i];
         NEWMP(m); m->dl = d; m->c = STOI(mod - ITOS(BDY(p1)->c)); NEXT(m) = 0;          NEWMP(m); m->dl = d; m->c = (Obj)STOI(mod - ITOS(BDY(p1)->c)); NEXT(m) = 0;
         MKDP(n,m,s); s->sugar = d->td; mulmd_dup(mod,s,p2,&u);          MKDP(n,m,s); s->sugar = d->td; mulmd_dup(mod,s,p2,&u);
         addmd_destructive(mod,t,u,rp);          addmd_destructive(mod,t,u,rp);
 }  }
Line 833  void dp_red(DP p0,DP p1,DP p2,DP *head,DP *rest,P *dnp
Line 960  void dp_red(DP p0,DP p1,DP p2,DP *head,DP *rest,P *dnp
                 divsp(CO,(P)c1,g,&a); c1 = (Q)a; divsp(CO,(P)c2,g,&a); c2 = (Q)a;                  divsp(CO,(P)c1,g,&a); c1 = (Q)a; divsp(CO,(P)c2,g,&a); c2 = (Q)a;
                 add_denomlist(g);                  add_denomlist(g);
         }          }
         NEWMP(m); m->dl = d; chsgnp((P)c1,&m->c); NEXT(m) = 0; MKDP(n,m,s); s->sugar = d->td;          NEWMP(m); m->dl = d; chsgnp((P)c1,(P *)&m->c); NEXT(m) = 0; MKDP(n,m,s); s->sugar = d->td;
         *multp = s;          *multp = s;
         muld(CO,s,p2,&t); muldc(CO,p1,(P)c2,&s); addd(CO,s,t,&r);          muld(CO,s,p2,&t); muldc(CO,p1,(Obj)c2,&s); addd(CO,s,t,&r);
         muldc(CO,p0,(P)c2,&h);          muldc(CO,p0,(Obj)c2,&h);
         *head = h; *rest = r; *dnp = (P)c2;          *head = h; *rest = r; *dnp = (P)c2;
 }  }
   
   void dpm_red(DPM p0,DPM p1,DPM p2,DPM *head,DPM *rest,P *dnp,DP *multp)
   {
           int i,n,pos;
           DL d1,d2,d;
           MP m;
     DP s;
           DPM t,r,h,u,w;
           Q c,c1,c2;
           N gn,tn;
           P g,a;
           P p[2];
   
           n = p1->nv; d1 = BDY(p1)->dl; d2 = BDY(p2)->dl; pos = BDY(p1)->pos;
     if ( pos != BDY(p2)->pos )
       error("dpm_red : cannot happen");
           NEWDL(d,n); d->td = d1->td - d2->td;
           for ( i = 0; i < n; i++ )
                   d->d[i] = d1->d[i]-d2->d[i];
           c1 = (Q)BDY(p1)->c; c2 = (Q)BDY(p2)->c;
           if ( dp_fcoeffs == N_GFS ) {
                   p[0] = (P)c1; p[1] = (P)c2;
                   gcdsf(CO,p,2,&g);
                   divsp(CO,(P)c1,g,&a); c1 = (Q)a; divsp(CO,(P)c2,g,&a); c2 = (Q)a;
           } else if ( dp_fcoeffs ) {
                   /* do nothing */
           } else if ( INT(c1) && INT(c2) ) {
                   gcdn(NM(c1),NM(c2),&gn);
                   if ( !UNIN(gn) ) {
                           divsn(NM(c1),gn,&tn); NTOQ(tn,SGN(c1),c); c1 = c;
                           divsn(NM(c2),gn,&tn); NTOQ(tn,SGN(c2),c); c2 = c;
                   }
           } else {
                   ezgcdpz(CO,(P)c1,(P)c2,&g);
                   divsp(CO,(P)c1,g,&a); c1 = (Q)a; divsp(CO,(P)c2,g,&a); c2 = (Q)a;
                   add_denomlist(g);
           }
           NEWMP(m); m->dl = d; chsgnp((P)c1,(P *)&m->c); NEXT(m) = 0; MKDP(n,m,s); s->sugar = d->td;
           *multp = s;
           mulobjdpm(CO,(Obj)s,p2,&u); mulobjdpm(CO,(Obj)c2,p1,&w); adddpm(CO,u,w,&r);
           mulobjdpm(CO,(Obj)c2,p0,&h);
           *head = h; *rest = r; *dnp = (P)c2;
   }
   
   
 /*  /*
  * m-reduction by a marked poly   * m-reduction by a marked poly
  * do content reduction over Z or Q(x,...)   * do content reduction over Z or Q(x,...)
Line 880  void dp_red_marked(DP p0,DP p1,DP p2,DP hp2,DP *head,D
Line 1051  void dp_red_marked(DP p0,DP p1,DP p2,DP hp2,DP *head,D
                 ezgcdpz(CO,(P)c1,(P)c2,&g);                  ezgcdpz(CO,(P)c1,(P)c2,&g);
                 divsp(CO,(P)c1,g,&a); c1 = (Q)a; divsp(CO,(P)c2,g,&a); c2 = (Q)a;                  divsp(CO,(P)c1,g,&a); c1 = (Q)a; divsp(CO,(P)c2,g,&a); c2 = (Q)a;
         }          }
         NEWMP(m); m->dl = d; chsgnp((P)c1,&m->c); NEXT(m) = 0; MKDP(n,m,s); s->sugar = d->td;          NEWMP(m); m->dl = d; m->c = (Obj)c1; NEXT(m) = 0; MKDP(n,m,s); s->sugar = d->td;
         *multp = s;          *multp = s;
         muld(CO,s,p2,&t); muldc(CO,p1,(P)c2,&s); addd(CO,s,t,&r);          muld(CO,s,p2,&t); muldc(CO,p1,(Obj)c2,&s); subd(CO,s,t,&r);
         muldc(CO,p0,(P)c2,&h);          muldc(CO,p0,(Obj)c2,&h);
         *head = h; *rest = r; *dnp = (P)c2;          *head = h; *rest = r; *dnp = (P)c2;
 }  }
   
 void dp_red_marked_mod(DP p0,DP p1,DP p2,DP hp2,int mod,DP *head,DP *rest,P *dnp)  void dp_red_marked_mod(DP p0,DP p1,DP p2,DP hp2,int mod,DP *head,DP *rest,P *dnp,DP *multp)
 {  {
         int i,n;          int i,n;
         DL d1,d2,d;          DL d1,d2,d;
Line 905  void dp_red_marked_mod(DP p0,DP p1,DP p2,DP hp2,int mo
Line 1076  void dp_red_marked_mod(DP p0,DP p1,DP p2,DP hp2,int mo
         if ( NUM(c2) ) {          if ( NUM(c2) ) {
                 divsmp(CO,mod,c1,c2,&u); c1 = u; c2 = (P)ONEM;                  divsmp(CO,mod,c1,c2,&u); c1 = u; c2 = (P)ONEM;
         }          }
         NEWMP(m); m->dl = d; chsgnmp(mod,(P)c1,&m->c); NEXT(m) = 0;          NEWMP(m); m->dl = d; m->c = (Obj)c1; NEXT(m) = 0;
         MKDP(n,m,s); s->sugar = d->td; mulmd(CO,mod,s,p2,&t);          MKDP(n,m,s); s->sugar = d->td;
           *multp = s;
           mulmd(CO,mod,s,p2,&t);
         if ( NUM(c2) ) {          if ( NUM(c2) ) {
                 addmd(CO,mod,p1,t,&r); h = p0;                  submd(CO,mod,p1,t,&r); h = p0;
         } else {          } else {
                 mulmdc(CO,mod,p1,c2,&s); addmd(CO,mod,s,t,&r); mulmdc(CO,mod,p0,c2,&h);                  mulmdc(CO,mod,p1,c2,&s); submd(CO,mod,s,t,&r); mulmdc(CO,mod,p0,c2,&h);
         }          }
         *head = h; *rest = r; *dnp = c2;          *head = h; *rest = r; *dnp = c2;
 }  }
Line 934  void dp_red_f(DP p1,DP p2,DP *rest)
Line 1107  void dp_red_f(DP p1,DP p2,DP *rest)
   
         NEWMP(m); m->dl = d;          NEWMP(m); m->dl = d;
         divr(CO,(Obj)BDY(p1)->c,(Obj)BDY(p2)->c,&a); chsgnr(a,&b);          divr(CO,(Obj)BDY(p1)->c,(Obj)BDY(p2)->c,&a); chsgnr(a,&b);
         C(m) = (P)b;          C(m) = (Obj)b;
         NEXT(m) = 0; MKDP(n,m,s); s->sugar = d->td;          NEXT(m) = 0; MKDP(n,m,s); s->sugar = d->td;
   
         muld(CO,s,p2,&t); addd(CO,p1,t,rest);          muld(CO,s,p2,&t); addd(CO,p1,t,rest);
 }  }
   
   void dpm_red_f(DPM p1,DPM p2,DPM *rest)
   {
           int i,n;
           DL d1,d2,d;
           MP m;
           DPM t;
     DP s;
           Obj a,b;
   
           n = p1->nv;
           d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
   
           NEWDL(d,n); d->td = d1->td - d2->td;
           for ( i = 0; i < n; i++ )
                   d->d[i] = d1->d[i]-d2->d[i];
   
           NEWMP(m); m->dl = d;
           arf_div(CO,(Obj)BDY(p1)->c,(Obj)BDY(p2)->c,&a); arf_chsgn(a,&b);
           C(m) = b;
           NEXT(m) = 0; MKDP(n,m,s); s->sugar = d->td;
   
           mulobjdpm(CO,(Obj)s,p2,&t); adddpm(CO,p1,t,rest);
   }
   
   
 void dp_red_mod(DP p0,DP p1,DP p2,int mod,DP *head,DP *rest,P *dnp)  void dp_red_mod(DP p0,DP p1,DP p2,int mod,DP *head,DP *rest,P *dnp)
 {  {
         int i,n;          int i,n;
Line 958  void dp_red_mod(DP p0,DP p1,DP p2,int mod,DP *head,DP 
Line 1156  void dp_red_mod(DP p0,DP p1,DP p2,int mod,DP *head,DP 
         if ( NUM(c2) ) {          if ( NUM(c2) ) {
                 divsmp(CO,mod,c1,c2,&u); c1 = u; c2 = (P)ONEM;                  divsmp(CO,mod,c1,c2,&u); c1 = u; c2 = (P)ONEM;
         }          }
         NEWMP(m); m->dl = d; chsgnmp(mod,(P)c1,&m->c); NEXT(m) = 0;          NEWMP(m); m->dl = d; chsgnmp(mod,(P)c1,(P *)&m->c); NEXT(m) = 0;
         MKDP(n,m,s); s->sugar = d->td; mulmd(CO,mod,s,p2,&t);          MKDP(n,m,s); s->sugar = d->td; mulmd(CO,mod,s,p2,&t);
         if ( NUM(c2) ) {          if ( NUM(c2) ) {
                 addmd(CO,mod,p1,t,&r); h = p0;                  addmd(CO,mod,p1,t,&r); h = p0;
Line 986  void _dp_red_mod_destructive(DP p1,DP p2,int mod,DP *r
Line 1184  void _dp_red_mod_destructive(DP p1,DP p2,int mod,DP *r
         c = invm(ITOS(BDY(p2)->c),mod);          c = invm(ITOS(BDY(p2)->c),mod);
         c2 = ITOS(BDY(p1)->c);          c2 = ITOS(BDY(p1)->c);
         DMAR(c,c2,0,mod,c1);          DMAR(c,c2,0,mod,c1);
         _NEWMP(m); m->dl = d; m->c = STOI(mod-c1); NEXT(m) = 0;          _NEWMP(m); m->dl = d; m->c = (Obj)STOI(mod-c1); NEXT(m) = 0;
 #if 0  #if 0
         _MKDP(n,m,s); s->sugar = d->td;          _MKDP(n,m,s); s->sugar = d->td;
         _mulmd_dup(mod,s,p2,&t); _free_dp(s);          _mulmd_dup(mod,s,p2,&t); _free_dp(s);
Line 1097  void dp_removecont2(DP p1,DP p2,DP *r1p,DP *r2p,Q *con
Line 1295  void dp_removecont2(DP p1,DP p2,DP *r1p,DP *r2p,Q *con
         i = 0;          i = 0;
         if ( p1 ) {          if ( p1 ) {
                 for ( m0 = 0, t = BDY(p1); i < n1; i++, t = NEXT(t) ) {                  for ( m0 = 0, t = BDY(p1); i < n1; i++, t = NEXT(t) ) {
                         NEXTMP(m0,m); m->c = (P)w[i]; m->dl = t->dl;                          NEXTMP(m0,m); m->c = (Obj)w[i]; m->dl = t->dl;
                 }                  }
                 NEXT(m) = 0;                  NEXT(m) = 0;
                 MKDP(p1->nv,m0,*r1p); (*r1p)->sugar = p1->sugar;                  MKDP(p1->nv,m0,*r1p); (*r1p)->sugar = p1->sugar;
Line 1105  void dp_removecont2(DP p1,DP p2,DP *r1p,DP *r2p,Q *con
Line 1303  void dp_removecont2(DP p1,DP p2,DP *r1p,DP *r2p,Q *con
                 *r1p = 0;                  *r1p = 0;
         if ( p2 ) {          if ( p2 ) {
                 for ( m0 = 0, t = BDY(p2); i < n; i++, t = NEXT(t) ) {                  for ( m0 = 0, t = BDY(p2); i < n; i++, t = NEXT(t) ) {
                         NEXTMP(m0,m); m->c = (P)w[i]; m->dl = t->dl;                          NEXTMP(m0,m); m->c = (Obj)w[i]; m->dl = t->dl;
                 }                  }
                 NEXT(m) = 0;                  NEXT(m) = 0;
                 MKDP(p2->nv,m0,*r2p); (*r2p)->sugar = p2->sugar;                  MKDP(p2->nv,m0,*r2p); (*r2p)->sugar = p2->sugar;
Line 1182  last:
Line 1380  last:
   
 void dp_true_nf_marked_mod(NODE b,DP g,DP *ps,DP *hps,int mod,DP *rp,P *dnp)  void dp_true_nf_marked_mod(NODE b,DP g,DP *ps,DP *hps,int mod,DP *rp,P *dnp)
 {  {
         DP hp,u,p,d,s,t;          DP hp,u,p,d,s,t,dmy;
         NODE l;          NODE l;
         MP m,mr;          MP m,mr;
         int i,n;          int i,n;
Line 1203  void dp_true_nf_marked_mod(NODE b,DP g,DP *ps,DP *hps,
Line 1401  void dp_true_nf_marked_mod(NODE b,DP g,DP *ps,DP *hps,
                 for ( u = 0, i = 0; i < n; i++ ) {                  for ( u = 0, i = 0; i < n; i++ ) {
                         if ( dp_redble(g,hp = hps[wb[i]]) ) {                          if ( dp_redble(g,hp = hps[wb[i]]) ) {
                                 p = ps[wb[i]];                                  p = ps[wb[i]];
                                 dp_red_marked_mod(d,g,p,hp,mod,&t,&u,&tdn);                                  dp_red_marked_mod(d,g,p,hp,mod,&t,&u,&tdn,&dmy);
                                 psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;                                  psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
                                 sugar = MAX(sugar,psugar);                                  sugar = MAX(sugar,psugar);
                                 if ( !u ) {                                  if ( !u ) {
Line 1231  void dp_true_nf_marked_mod(NODE b,DP g,DP *ps,DP *hps,
Line 1429  void dp_true_nf_marked_mod(NODE b,DP g,DP *ps,DP *hps,
         *rp = d; *dnp = dn;          *rp = d; *dnp = dn;
 }  }
   
   /* true nf by a marked GB and collect quotients */
   
   DP *dp_true_nf_and_quotient_marked (NODE b,DP g,DP *ps,DP *hps,DP *rp,P *dnp)
   {
           DP u,p,d,s,t,dmy,hp,mult;
           DP *q;
           NODE l;
           MP m,mr;
           int i,n,j;
           int *wb;
           int sugar,psugar,multiple;
           P nm,tnm1,dn,tdn,tdn1;
           Q cont;
   
           dn = (P)ONE;
           if ( !g ) {
                   *rp = 0; *dnp = dn; return 0;
           }
           for ( n = 0, l = b; l; l = NEXT(l), n++ );
           wb = (int *)ALLOCA(n*sizeof(int));
           for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
                   wb[i] = QTOS((Q)BDY(l));
           q = (DP *)MALLOC(n*sizeof(DP));
           for ( i = 0; i < n; i++ ) q[i] = 0;
           sugar = g->sugar;
           for ( d = 0; g; ) {
                   for ( u = 0, i = 0; i < n; i++ ) {
                           if ( dp_redble(g,hp = hps[wb[i]]) ) {
                                   p = ps[wb[i]];
                                   dp_red_marked(d,g,p,hp,&t,&u,&tdn,&mult);
                                   psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
                                   sugar = MAX(sugar,psugar);
                                   for ( j = 0; j < n; j++ ) {
                                           muldc(CO,q[j],(Obj)tdn,&dmy); q[j] = dmy;
                                   }
                                   addd(CO,q[wb[i]],mult,&dmy); q[wb[i]] = dmy;
                                   mulp(CO,dn,tdn,&tdn1); dn = tdn1;
                                   d = t;
                                   if ( !u ) goto last;
                                   break;
                           }
                   }
                   if ( u ) {
                           g = u;
                   } else {
                           m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
                           NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
                           addd(CO,d,t,&s); d = s;
                           dp_rest(g,&t); g = t;
                   }
           }
   last:
           if ( d ) d->sugar = sugar;
           *rp = d; *dnp = dn;
           return q;
   }
   
   DP *dp_true_nf_and_quotient_marked_mod(NODE b,DP g,DP *ps,DP *hps,int mod,DP *rp,P *dnp)
   {
           DP u,p,d,s,t,dmy,hp,mult;
           DP *q;
           NODE l;
           MP m,mr;
           int i,n,j;
           int *wb;
           int sugar,psugar;
           P dn,tdn,tdn1;
   
           for ( n = 0, l = b; l; l = NEXT(l), n++ );
           q = (DP *)MALLOC(n*sizeof(DP));
           for ( i = 0; i < n; i++ ) q[i] = 0;
           dn = (P)ONEM;
           if ( !g ) {
                   *rp = 0; *dnp = dn; return 0;
           }
           wb = (int *)ALLOCA(n*sizeof(int));
           for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
                   wb[i] = QTOS((Q)BDY(l));
           sugar = g->sugar;
           for ( d = 0; g; ) {
                   for ( u = 0, i = 0; i < n; i++ ) {
                           if ( dp_redble(g,hp = hps[wb[i]]) ) {
                                   p = ps[wb[i]];
                                   dp_red_marked_mod(d,g,p,hp,mod,&t,&u,&tdn,&mult);
                                   psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
                                   sugar = MAX(sugar,psugar);
                                   for ( j = 0; j < n; j++ ) {
                                           mulmdc(CO,mod,q[j],(P)tdn,&dmy); q[j] = dmy;
                                   }
                                   addmd(CO,mod,q[wb[i]],mult,&dmy); q[wb[i]] = dmy;
                                   mulmp(CO,mod,dn,tdn,&tdn1); dn = tdn1;
                                   d = t;
                                   if ( !u ) goto last;
                                   break;
                           }
                   }
                   if ( u )
                           g = u;
                   else {
                           m = BDY(g); NEWMP(mr); mr->dl = m->dl; mr->c = m->c;
                           NEXT(mr) = 0; MKDP(g->nv,mr,t); t->sugar = mr->dl->td;
                           addmd(CO,mod,d,t,&s); d = s;
                           dp_rest(g,&t); g = t;
                   }
           }
   last:
           if ( d )
                   d->sugar = sugar;
           *rp = d; *dnp = dn;
           return q;
   }
   
 /* nf computation over Z */  /* nf computation over Z */
   
 void dp_nf_z(NODE b,DP g,DP *ps,int full,int multiple,DP *rp)  void dp_nf_z(NODE b,DP g,DP *ps,int full,int multiple,DP *rp)
Line 1302  void dp_nf_z(NODE b,DP g,DP *ps,int full,int multiple,
Line 1612  void dp_nf_z(NODE b,DP g,DP *ps,int full,int multiple,
         *rp = d;          *rp = d;
 }  }
   
   void dpm_nf_z(NODE b,DPM g,DPM *ps,int full,int multiple,DPM *rp)
   {
           DPM u,p,d,s,t;
     DP dmy1;
           P dmy;
           NODE l;
           DMM m,mr;
           int i,n;
           int *wb;
           int hmag;
           int sugar,psugar;
   
           if ( !g ) {
                   *rp = 0; return;
           }
           for ( n = 0, l = b; l; l = NEXT(l), n++ );
           wb = (int *)ALLOCA(n*sizeof(int));
           for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
                   wb[i] = QTOS((Q)BDY(l));
   
           hmag = multiple*HMAG(g);
           sugar = g->sugar;
   
           for ( d = 0; g; ) {
                   for ( u = 0, i = 0; i < n; i++ ) {
                           if ( dpm_redble(g,p = ps[wb[i]]) ) {
                                   dpm_red(d,g,p,&t,&u,&dmy,&dmy1);
                                   psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
                                   sugar = MAX(sugar,psugar);
                                   if ( !u ) {
                                           if ( d )
                                                   d->sugar = sugar;
                                           *rp = d; return;
                                   }
                                   d = t;
                                   break;
                           }
                   }
                   if ( u ) {
                           g = u;
                           if ( d ) {
                                   if ( multiple && HMAG(d) > hmag ) {
                                           dpm_ptozp2(d,g,&t,&u); d = t; g = u;
                                           hmag = multiple*HMAG(d);
                                   }
                           } else {
                                   if ( multiple && HMAG(g) > hmag ) {
                                           dpm_ptozp(g,&t); g = t;
                                           hmag = multiple*HMAG(g);
                                   }
                           }
                   }
                   else if ( !full ) {
                           if ( g ) {
                                   MKDPM(g->nv,BDY(g),t); t->sugar = sugar; g = t;
                           }
                           *rp = g; return;
                   } else {
                           m = BDY(g); NEWDMM(mr); mr->dl = m->dl; mr->c = m->c; mr->pos = m->pos;
                           NEXT(mr) = 0; MKDPM(g->nv,mr,t); t->sugar = mr->dl->td;
                           adddpm(CO,d,t,&s); d = s;
                           dpm_rest(g,&t); g = t;
                   }
           }
           if ( d )
                   d->sugar = sugar;
           *rp = d;
   }
   
 /* nf computation over a field */  /* nf computation over a field */
   
 void dp_nf_f(NODE b,DP g,DP *ps,int full,DP *rp)  void dp_nf_f(NODE b,DP g,DP *ps,int full,DP *rp)
Line 1355  void dp_nf_f(NODE b,DP g,DP *ps,int full,DP *rp)
Line 1734  void dp_nf_f(NODE b,DP g,DP *ps,int full,DP *rp)
         *rp = d;          *rp = d;
 }  }
   
   void dpm_nf_f(NODE b,DPM g,DPM *ps,int full,DPM *rp)
   {
           DPM u,p,d,s,t;
           NODE l;
           DMM m,mr;
           int i,n;
           int *wb;
           int sugar,psugar;
   
           if ( !g ) {
                   *rp = 0; return;
           }
           for ( n = 0, l = b; l; l = NEXT(l), n++ );
           wb = (int *)ALLOCA(n*sizeof(int));
           for ( i = 0, l = b; i < n; l = NEXT(l), i++ )
                   wb[i] = QTOS((Q)BDY(l));
   
           sugar = g->sugar;
           for ( d = 0; g; ) {
                   for ( u = 0, i = 0; i < n; i++ ) {
                           if ( dpm_redble(g,p = ps[wb[i]]) ) {
                                   dpm_red_f(g,p,&u);
                                   psugar = (BDY(g)->dl->td - BDY(p)->dl->td) + p->sugar;
                                   sugar = MAX(sugar,psugar);
                                   if ( !u ) {
                                           if ( d )
                                                   d->sugar = sugar;
                                           *rp = d; return;
                                   }
                                   break;
                           }
                   }
                   if ( u )
                           g = u;
                   else if ( !full ) {
                           if ( g ) {
                                   MKDPM(g->nv,BDY(g),t); t->sugar = sugar; g = t;
                           }
                           *rp = g; return;
                   } else {
                           m = BDY(g); NEWDMM(mr); mr->dl = m->dl; mr->c = m->c; mr->pos = m->pos;
                           NEXT(mr) = 0; MKDPM(g->nv,mr,t); t->sugar = mr->dl->td;
                           adddpm(CO,d,t,&s); d = s;
                           dpm_rest(g,&t); g = t;
                   }
           }
           if ( d )
                   d->sugar = sugar;
           *rp = d;
   }
   
 /* nf computation over GF(mod) (only for internal use) */  /* nf computation over GF(mod) (only for internal use) */
   
 void dp_nf_mod(NODE b,DP g,DP *ps,int mod,int full,DP *rp)  void dp_nf_mod(NODE b,DP g,DP *ps,int mod,int full,DP *rp)
Line 1534  void dp_lnf_f(DP p1,DP p2,NODE g,DP *r1p,DP *r2p)
Line 1964  void dp_lnf_f(DP p1,DP p2,NODE g,DP *r1p,DP *r2p)
                                 b2 = (DP)BDY(NEXT(b));                                  b2 = (DP)BDY(NEXT(b));
                                 divr(CO,(Obj)ONE,(Obj)BDY(b1)->c,&c1);                                  divr(CO,(Obj)ONE,(Obj)BDY(b1)->c,&c1);
                                 mulr(CO,c1,(Obj)BDY(r1)->c,&c2); chsgnr(c2,&c);                                  mulr(CO,c1,(Obj)BDY(r1)->c,&c2); chsgnr(c2,&c);
                                 muldc(CO,b1,(P)c,&t); addd(CO,r1,t,&s); r1 = s;                                  muldc(CO,b1,(Obj)c,&t); addd(CO,r1,t,&s); r1 = s;
                                 muldc(CO,b2,(P)c,&t); addd(CO,r2,t,&s); r2 = s;                                  muldc(CO,b2,(Obj)c,&t); addd(CO,r2,t,&s); r2 = s;
                         }                          }
         }          }
         *r1p = r1; *r2p = r2;          *r1p = r1; *r2p = r2;
Line 1586  void dp_nf_tab_mod(DP p,LIST *tab,int mod,DP *rp)
Line 2016  void dp_nf_tab_mod(DP p,LIST *tab,int mod,DP *rp)
                 h = m->dl;                  h = m->dl;
                 while ( !dl_equal(n,h,BDY((DP)BDY(BDY(tab[i])))->dl ) )                  while ( !dl_equal(n,h,BDY((DP)BDY(BDY(tab[i])))->dl ) )
                         i++;                          i++;
                 mulmdc(CO,mod,(DP)BDY(NEXT(BDY(tab[i]))),m->c,&t);                  mulmdc(CO,mod,(DP)BDY(NEXT(BDY(tab[i]))),(P)m->c,&t);
                 addmd(CO,mod,s,t,&u); s = u;                  addmd(CO,mod,s,t,&u); s = u;
         }          }
         *rp = s;          *rp = s;
Line 1621  void dp_nf_tab_f(DP p,LIST *tab,DP *rp)
Line 2051  void dp_nf_tab_f(DP p,LIST *tab,DP *rp)
   
 int create_order_spec(VL vl,Obj obj,struct order_spec **specp)  int create_order_spec(VL vl,Obj obj,struct order_spec **specp)
 {  {
         int i,j,n,s,row,col,ret;          int i,j,n,s,row,col,ret,wlen;
         struct order_spec *spec;          struct order_spec *spec;
         struct order_pair *l;          struct order_pair *l;
         NODE node,t,tn;    Obj wp,wm;
           NODE node,t,tn,wpair;
         MAT m;          MAT m;
         pointer **b;          VECT v;
           pointer **b,*bv;
         int **w;          int **w;
   
         if ( vl && obj && OID(obj) == O_LIST ) {          if ( vl && obj && OID(obj) == O_LIST ) {
Line 1642  int create_order_spec(VL vl,Obj obj,struct order_spec 
Line 2074  int create_order_spec(VL vl,Obj obj,struct order_spec 
                 spec->ord.simple = QTOS((Q)obj);                  spec->ord.simple = QTOS((Q)obj);
                 return 1;                  return 1;
         } else if ( OID(obj) == O_LIST ) {          } else if ( OID(obj) == O_LIST ) {
       /* module order; obj = [0|1,w,ord] or [0|1,ord] */
                 node = BDY((LIST)obj);                  node = BDY((LIST)obj);
                 for ( n = 0, t = node; t; t = NEXT(t), n++ );                  if ( !BDY(node) || NUM(BDY(node)) ) {
                 l = (struct order_pair *)MALLOC_ATOMIC(n*sizeof(struct order_pair));        switch ( length(node) ) {
                 for ( i = 0, t = node, s = 0; i < n; t = NEXT(t), i++ ) {        case 2:
                         tn = BDY((LIST)BDY(t)); l[i].order = QTOS((Q)BDY(tn));                            create_order_spec(0,(Obj)BDY(NEXT(node)),&spec);
                         tn = NEXT(tn); l[i].length = QTOS((Q)BDY(tn));                            spec->id += 256; spec->obj = obj;
                         s += l[i].length;          spec->top_weight = 0;
                 }          spec->module_rank = 0;
                 spec->id = 1; spec->obj = obj;          spec->module_top_weight = 0;
                 spec->ord.block.order_pair = l;                            spec->ispot = (BDY(node)!=0);
                 spec->ord.block.length = n; spec->nv = s;                            if ( spec->ispot ) {
                 return 1;                                  n = QTOS((Q)BDY(node));
                                   if ( n < 0 )
                                           spec->pot_nelim = -n;
                                   else
                                           spec->pot_nelim = 0;
                             }
           break;
   
         case 3:
                             create_order_spec(0,(Obj)BDY(NEXT(NEXT(node))),&spec);
                             spec->id += 256; spec->obj = obj;
                             spec->ispot = (BDY(node)!=0);
           node = NEXT(node);
           if ( !BDY(node) || OID(BDY(node)) != O_LIST )
                                     error("create_order_spec : [weight_for_poly,weight_for_modlue] must be specified as a module topweight");
           wpair = BDY((LIST)BDY(node));
           if ( length(wpair) != 2 )
                                     error("create_order_spec : [weight_for_poly,weight_for_modlue] must be specified as a module topweight");
   
           wp = BDY(wpair);
           wm = BDY(NEXT(wpair));
           if ( !wp || OID(wp) != O_LIST || !wm || OID(wm) != O_LIST )
                                     error("create_order_spec : [weight_for_poly,weight_for_modlue] must be specified as a module topweight");
           spec->nv = length(BDY((LIST)wp));
           spec->top_weight = (int *)MALLOC_ATOMIC(spec->nv*sizeof(int));
                       for ( i = 0, t = BDY((LIST)wp); i < spec->nv; t = NEXT(t), i++ )
             spec->top_weight[i] = QTOS((Q)BDY(t));
   
           spec->module_rank = length(BDY((LIST)wm));
           spec->module_top_weight = (int *)MALLOC_ATOMIC(spec->module_rank*sizeof(int));
                       for ( i = 0, t = BDY((LIST)wm); i < spec->module_rank; t = NEXT(t), i++ )
             spec->module_top_weight[i] = QTOS((Q)BDY(t));
           break;
         default:
                                   error("create_order_spec : invalid arguments for module order");
         }
   
                           *specp = spec;
                           return 1;
                   } else {
         /* block order in polynomial ring */
                     for ( n = 0, t = node; t; t = NEXT(t), n++ );
                     l = (struct order_pair *)MALLOC_ATOMIC(n*sizeof(struct order_pair));
                     for ( i = 0, t = node, s = 0; i < n; t = NEXT(t), i++ ) {
                             tn = BDY((LIST)BDY(t)); l[i].order = QTOS((Q)BDY(tn));
                             tn = NEXT(tn); l[i].length = QTOS((Q)BDY(tn));
                             s += l[i].length;
                     }
                     spec->id = 1; spec->obj = obj;
                     spec->ord.block.order_pair = l;
                     spec->ord.block.length = n; spec->nv = s;
                     return 1;
       }
         } else if ( OID(obj) == O_MAT ) {          } else if ( OID(obj) == O_MAT ) {
                 m = (MAT)obj; row = m->row; col = m->col; b = BDY(m);                  m = (MAT)obj; row = m->row; col = m->col; b = BDY(m);
                 w = almat(row,col);                  w = almat(row,col);
Line 2058  void dp_mod(DP p,int mod,NODE subst,DP *rp)
Line 2543  void dp_mod(DP p,int mod,NODE subst,DP *rp)
                 *rp = 0;                  *rp = 0;
         else {          else {
                 for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {                  for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
                         for ( tn = subst, s = m->c; tn; tn = NEXT(tn) ) {                          for ( tn = subst, s = (P)m->c; tn; tn = NEXT(tn) ) {
                                 v = VR((P)BDY(tn)); tn = NEXT(tn);                                  v = VR((P)BDY(tn)); tn = NEXT(tn);
                                 substp(CO,s,v,(P)BDY(tn),&s1); s = s1;                                  substp(CO,s,v,(P)BDY(tn),&s1); s = s1;
                         }                          }
                         ptomp(mod,s,&t);                          ptomp(mod,s,&t);
                         if ( t ) {                          if ( t ) {
                                 NEXTMP(mr0,mr); mr->c = t; mr->dl = m->dl;                                  NEXTMP(mr0,mr); mr->c = (Obj)t; mr->dl = m->dl;
                         }                          }
                 }                  }
                 if ( mr0 ) {                  if ( mr0 ) {
Line 2082  void dp_rat(DP p,DP *rp)
Line 2567  void dp_rat(DP p,DP *rp)
                 *rp = 0;                  *rp = 0;
         else {          else {
                 for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {                  for ( mr0 = 0, m = BDY(p); m; m = NEXT(m) ) {
                         NEXTMP(mr0,mr); mptop(m->c,&mr->c); mr->dl = m->dl;                          NEXTMP(mr0,mr); mptop((P)m->c,(P *)&mr->c); mr->dl = m->dl;
                 }                  }
                 if ( mr0 ) {                  if ( mr0 ) {
                         NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;                          NEXT(mr) = 0; MKDP(p->nv,mr0,*rp); (*rp)->sugar = p->sugar;
Line 2127  void homogenize_order(struct order_spec *old,int n,str
Line 2612  void homogenize_order(struct order_spec *old,int n,str
                                         error("homogenize_order : invalid input");                                          error("homogenize_order : invalid input");
                         }                          }
                         break;                          break;
                 case 1:                  case 1: case 257:
                         length = old->ord.block.length;                          length = old->ord.block.length;
                         l = (struct order_pair *)                          l = (struct order_pair *)
                                 MALLOC_ATOMIC((length+1)*sizeof(struct order_pair));                                  MALLOC_ATOMIC((length+1)*sizeof(struct order_pair));
                         bcopy((char *)old->ord.block.order_pair,(char *)l,length*sizeof(struct order_pair));                          bcopy((char *)old->ord.block.order_pair,(char *)l,length*sizeof(struct order_pair));
                         l[length].order = 2; l[length].length = 1;                          l[length].order = 2; l[length].length = 1;
                         new->id = 1; new->nv = n+1;                          new->id = old->id; new->nv = n+1;
                         new->ord.block.order_pair = l;                          new->ord.block.order_pair = l;
                         new->ord.block.length = length+1;                          new->ord.block.length = length+1;
                           new->ispot = old->ispot;
                         break;                          break;
                 case 2:                  case 2: case 258:
                         nv = old->nv; row = old->ord.matrix.row;                          nv = old->nv; row = old->ord.matrix.row;
                         oldm = old->ord.matrix.matrix; newm = almat(row+1,nv+1);                          oldm = old->ord.matrix.matrix; newm = almat(row+1,nv+1);
                         for ( i = 0; i <= nv; i++ )                          for ( i = 0; i <= nv; i++ )
Line 2147  void homogenize_order(struct order_spec *old,int n,str
Line 2633  void homogenize_order(struct order_spec *old,int n,str
                                         newm[i+1][j] = oldm[i][j];                                          newm[i+1][j] = oldm[i][j];
                                 newm[i+1][j] = 0;                                  newm[i+1][j] = 0;
                         }                          }
                         new->id = 2; new->nv = nv+1;                          new->id = old->id; new->nv = nv+1;
                         new->ord.matrix.row = row+1; new->ord.matrix.matrix = newm;                          new->ord.matrix.row = row+1; new->ord.matrix.matrix = newm;
                           new->ispot = old->ispot;
                         break;                          break;
                 case 3:                  case 3: case 259:
                         onv = old->nv;                          onv = old->nv;
                         nnv = onv+1;                          nnv = onv+1;
                         olen = old->ord.composite.length;                          olen = old->ord.composite.length;
Line 2184  void homogenize_order(struct order_spec *old,int n,str
Line 2671  void homogenize_order(struct order_spec *old,int n,str
                                 (struct sparse_weight *)MALLOC(sizeof(struct sparse_weight));                                  (struct sparse_weight *)MALLOC(sizeof(struct sparse_weight));
                         nwb[i].body.sparse_weight[0].pos = onv;                          nwb[i].body.sparse_weight[0].pos = onv;
                         nwb[i].body.sparse_weight[0].value = 1;                          nwb[i].body.sparse_weight[0].value = 1;
                         new->id = 3;                          new->id = old->id;
                         new->nv = nnv;                          new->nv = nnv;
                         new->ord.composite.length = nlen;                          new->ord.composite.length = nlen;
                         new->ord.composite.w_or_b = nwb;                          new->ord.composite.w_or_b = nwb;
                           new->ispot = old->ispot;
                         print_composite_order_spec(new);                          print_composite_order_spec(new);
                         break;                          break;
                   case 256: /* simple module order */
                           switch ( old->ord.simple ) {
                                   case 0:
                                           new->id = 256; new->ord.simple = 0; break;
                                   case 1:
                                           l = (struct order_pair *)
                                                   MALLOC_ATOMIC(2*sizeof(struct order_pair));
                                           l[0].length = n; l[0].order = old->ord.simple;
                                           l[1].length = 1; l[1].order = 2;
                                           new->id = 257;
                                           new->ord.block.order_pair = l;
                                           new->ord.block.length = 2; new->nv = n+1;
                                           break;
                                   case 2:
                                           new->id = 256; new->ord.simple = 1; break;
                                   default:
                                           error("homogenize_order : invalid input");
                           }
                           new->ispot = old->ispot;
                           break;
                 default:                  default:
                         error("homogenize_order : invalid input");                          error("homogenize_order : invalid input");
         }          }
Line 2210  void qltozl(Q *w,int n,Q *dvr)
Line 2718  void qltozl(Q *w,int n,Q *dvr)
                 v.id = O_VECT; v.len = n; v.body = (pointer *)w;                  v.id = O_VECT; v.len = n; v.body = (pointer *)w;
                 igcdv(&v,dvr); return;                  igcdv(&v,dvr); return;
         }          }
         c = w[0]; nm = NM(c); dn = INT(c) ? ONEN : DN(c);          for ( i = 0; !w[i]; i++ );
         for ( i = 1; i < n; i++ ) {          c = w[i]; nm = NM(c); dn = INT(c) ? ONEN : DN(c);
                 c = w[i]; l1 = INT(c) ? ONEN : DN(c);          for ( i++; i < n; i++ ) {
                   c = w[i];
                   if ( !c ) continue;
                   l1 = INT(c) ? ONEN : DN(c);
                 gcdn(nm,NM(c),&g); nm = g;                  gcdn(nm,NM(c),&g); nm = g;
                 gcdn(dn,l1,&l2); muln(dn,l1,&l3); divsn(l3,l2,&dn);                  gcdn(dn,l1,&l2); muln(dn,l1,&l3); divsn(l3,l2,&dn);
         }          }
Line 2255  int dp_redble(DP p1,DP p2)
Line 2766  int dp_redble(DP p1,DP p2)
         }          }
 }  }
   
   int dpm_redble(DPM p1,DPM p2)
   {
           int i,n;
           DL d1,d2;
   
     if ( BDY(p1)->pos != BDY(p2)->pos ) return 0;
           d1 = BDY(p1)->dl; d2 = BDY(p2)->dl;
           if ( d1->td < d2->td )
                   return 0;
           else {
                   for ( i = 0, n = p1->nv; i < n; i++ )
                           if ( d1->d[i] < d2->d[i] )
                                   return 0;
                   return 1;
           }
   }
   
   
 void dp_subd(DP p1,DP p2,DP *rp)  void dp_subd(DP p1,DP p2,DP *rp)
 {  {
         int i,n;          int i,n;
Line 2266  void dp_subd(DP p1,DP p2,DP *rp)
Line 2795  void dp_subd(DP p1,DP p2,DP *rp)
         NEWDL(d,n); d->td = d1->td - d2->td;          NEWDL(d,n); d->td = d1->td - d2->td;
         for ( i = 0; i < n; i++ )          for ( i = 0; i < n; i++ )
                 d->d[i] = d1->d[i]-d2->d[i];                  d->d[i] = d1->d[i]-d2->d[i];
         NEWMP(m); m->dl = d; m->c = (P)ONE; NEXT(m) = 0;          NEWMP(m); m->dl = d; m->c = (Obj)ONE; NEXT(m) = 0;
         MKDP(n,m,s); s->sugar = d->td;          MKDP(n,m,s); s->sugar = d->td;
         *rp = s;          *rp = s;
 }  }
Line 2276  void dltod(DL d,int n,DP *rp)
Line 2805  void dltod(DL d,int n,DP *rp)
         MP m;          MP m;
         DP s;          DP s;
   
         NEWMP(m); m->dl = d; m->c = (P)ONE; NEXT(m) = 0;          NEWMP(m); m->dl = d; m->c = (Obj)ONE; NEXT(m) = 0;
         MKDP(n,m,s); s->sugar = d->td;          MKDP(n,m,s); s->sugar = d->td;
         *rp = s;          *rp = s;
 }  }
Line 2302  void dp_ht(DP p,DP *rp)
Line 2831  void dp_ht(DP p,DP *rp)
                 *rp = 0;                  *rp = 0;
         else {          else {
                 m = BDY(p);                  m = BDY(p);
                 NEWMP(mr); mr->dl = m->dl; mr->c = (P)ONE; NEXT(mr) = 0;                  NEWMP(mr); mr->dl = m->dl; mr->c = (Obj)ONE; NEXT(mr) = 0;
                 MKDP(p->nv,mr,*rp); (*rp)->sugar = mr->dl->td;  /* XXX */                  MKDP(p->nv,mr,*rp); (*rp)->sugar = mr->dl->td;  /* XXX */
         }          }
 }  }
   
   void dpm_hm(DPM p,DPM *rp)
   {
           DMM m,mr;
   
           if ( !p )
                   *rp = 0;
           else {
                   m = BDY(p);
                   NEWDMM(mr); mr->dl = m->dl; mr->c = m->c; mr->pos = m->pos; NEXT(mr) = 0;
                   MKDPM(p->nv,mr,*rp); (*rp)->sugar = mr->dl->td;         /* XXX */
           }
   }
   
   void dpm_ht(DPM p,DPM *rp)
   {
           DMM m,mr;
   
           if ( !p )
                   *rp = 0;
           else {
                   m = BDY(p);
                   NEWDMM(mr); mr->dl = m->dl; mr->pos = m->pos; mr->c = (Obj)ONE; NEXT(mr) = 0;
                   MKDPM(p->nv,mr,*rp); (*rp)->sugar = mr->dl->td;         /* XXX */
           }
   }
   
   
 void dp_rest(DP p,DP *rp)  void dp_rest(DP p,DP *rp)
 {  {
         MP m;          MP m;
Line 2321  void dp_rest(DP p,DP *rp)
Line 2877  void dp_rest(DP p,DP *rp)
         }          }
 }  }
   
   void dpm_rest(DPM p,DPM *rp)
   {
           DMM m;
   
           m = BDY(p);
           if ( !NEXT(m) )
                   *rp = 0;
           else {
                   MKDPM(p->nv,NEXT(m),*rp);
                   if ( *rp )
                           (*rp)->sugar = p->sugar;
           }
   }
   
 DL lcm_of_DL(int nv,DL dl1,DL dl2,DL dl)  DL lcm_of_DL(int nv,DL dl1,DL dl2,DL dl)
 {  {
         register int i, *d1, *d2, *d, td;          register int i, *d1, *d2, *d, td;
Line 2612  int dpv_ht(DPV p,DP *h)
Line 3182  int dpv_ht(DPV p,DP *h)
                 return -1;                  return -1;
         } else {          } else {
                 m = BDY(e[maxi]);                  m = BDY(e[maxi]);
                 NEWMP(mr); mr->dl = m->dl; mr->c = (P)ONE; NEXT(mr) = 0;                  NEWMP(mr); mr->dl = m->dl; mr->c = (Obj)ONE; NEXT(mr) = 0;
                 MKDP(e[maxi]->nv,mr,*h); (*h)->sugar = mr->dl->td;  /* XXX */                  MKDP(e[maxi]->nv,mr,*h); (*h)->sugar = mr->dl->td;  /* XXX */
                 return maxi;                  return maxi;
         }          }
Line 2671  int compare_facet_preorder(int n,int *u,int *v,
Line 3241  int compare_facet_preorder(int n,int *u,int *v,
         return 1;          return 1;
 }  }
   
   Q inner_product_with_small_vector(VECT w,int *v)
   {
           int n,i;
           Q q,s,t,u;
   
           n = w->len;
           s = 0;
           for ( i = 0; i < n; i++ ) {
                   STOQ(v[i],q); mulq((Q)w->body[i],q,&t); addq(t,s,&u); s = u;
           }
           return s;
   }
   
   Q compute_last_t(NODE g,NODE gh,Q t,VECT w1,VECT w2,NODE *homo,VECT *wp)
   {
           int n,i;
           int *wt;
           Q last,d1,d2,dn,nm,s,t1;
           VECT wd,wt1,wt2,w;
           NODE tg,tgh;
           MP f;
           int *h;
           NODE r0,r;
           MP m0,m;
           DP d;
   
           n = w1->len;
           wt = W_ALLOC(n);
           last = ONE;
           /* t1 = 1-t */
           for ( tg = g, tgh = gh; tg; tg = NEXT(tg), tgh = NEXT(tgh ) ) {
                   f = BDY((DP)BDY(tg));
                   h = BDY((DP)BDY(tgh))->dl->d;
                   for ( ; f; f = NEXT(f) ) {
                           for ( i = 0; i < n; i++ ) wt[i] = h[i]-f->dl->d[i];
                           for ( i = 0; i < n && !wt[i]; i++ );
                           if ( i == n ) continue;
                           d1 = inner_product_with_small_vector(w1,wt);
                           d2 = inner_product_with_small_vector(w2,wt);
                           nm = d1; subq(d1,d2,&dn);
                           /* if d1=d2 then nothing happens */
                           if ( !dn ) continue;
                           /* s satisfies ds = 0*/
                           divq(nm,dn,&s);
   
                           if ( cmpq(s,t) > 0 && cmpq(s,last) < 0 )
                                   last = s;
                           else if ( !cmpq(s,t) ) {
                                   if ( cmpq(d2,0) < 0 ) {
                                           last = t;
                                           break;
                                   }
                           }
                   }
           }
           if ( !last ) {
                   dn = ONE; nm = 0;
           } else {
                   NTOQ(NM(last),1,nm);
                   if ( INT(last) ) dn = ONE;
                   else {
                           NTOQ(DN(last),1,dn);
                   }
           }
           /* (1-n/d)*w1+n/d*w2 -> w=(d-n)*w1+n*w2 */
           subq(dn,nm,&t1); mulvect(CO,(Obj)w1,(Obj)t1,(Obj *)&wt1);
           mulvect(CO,(Obj)w2,(Obj)nm,(Obj *)&wt2); addvect(CO,wt1,wt2,&w);
   
           r0 = 0;
           for ( tg = g, tgh = gh; tg; tg = NEXT(tg), tgh = NEXT(tgh ) ) {
                   f = BDY((DP)BDY(tg));
                   h = BDY((DP)BDY(tgh))->dl->d;
                   for ( m0 = 0; f; f = NEXT(f) ) {
                           for ( i = 0; i < n; i++ ) wt[i] = h[i]-f->dl->d[i];
                           for ( i = 0; i < n && !wt[i]; i++ );
                           if ( !inner_product_with_small_vector(w,wt) ) {
                                   NEXTMP(m0,m); m->c = f->c; m->dl = f->dl;
                           }
                   }
                   NEXT(m) = 0;
                   MKDP(((DP)BDY(tg))->nv,m0,d);  d->sugar = ((DP)BDY(tg))->sugar;
                   NEXTNODE(r0,r); BDY(r) = (pointer)d;
           }
           NEXT(r) = 0;
           *homo = r0;
           *wp = w;
           return last;
   }
   
 /* return 0 if last_w = infty */  /* return 0 if last_w = infty */
   
 NODE compute_last_w(NODE g,NODE gh,int n,int **w,  NODE compute_last_w(NODE g,NODE gh,int n,int **w,
Line 2796  NODE compute_essential_df(DP *g,DP *gh,int ng)
Line 3455  NODE compute_essential_df(DP *g,DP *gh,int ng)
                 }                  }
                 MKNODE(r1,0,ri); MKLIST(l,r1);                  MKNODE(r1,0,ri); MKLIST(l,r1);
                 BDY(rt) = (pointer)l;                  BDY(rt) = (pointer)l;
           }
           return r;
   }
   
   int comp_bits_divisible(int *a,int *b,int n)
   {
           int bpi,i,wi,bi;
   
           bpi = (sizeof(int)/sizeof(char))*8;
           for ( i = 0; i < n; i++ ) {
                   wi = i/bpi; bi = i%bpi;
                   if ( !(a[wi]&(1<<bi)) && (b[wi]&(1<<bi)) ) return 0;
           }
           return 1;
   }
   
   int comp_bits_lex(int *a,int *b,int n)
   {
           int bpi,i,wi,ba,bb,bi;
   
           bpi = (sizeof(int)/sizeof(char))*8;
           for ( i = 0; i < n; i++ ) {
                   wi = i/bpi; bi = i%bpi;
                   ba = (a[wi]&(1<<bi))?1:0;
                   bb = (b[wi]&(1<<bi))?1:0;
                   if ( ba > bb ) return 1;
                   else if ( ba < bb ) return -1;
           }
           return 0;
   }
   
   NODE mono_raddec(NODE ideal)
   {
           DP p;
           int nv,w,i,bpi,di,c,len;
           int *d,*s,*u,*new;
           NODE t,t1,v,r,rem,prev;
   
           if( !ideal ) return 0;
           p = (DP)BDY(ideal);
           nv = NV(p);
           bpi = (sizeof(int)/sizeof(char))*8;
           w = (nv+(bpi-1))/bpi;
           d = p->body->dl->d;
           if ( !NEXT(ideal) )     {
                   for ( t = 0, i = nv-1; i >= 0; i-- ) {
                           if ( d[i] ) {
                                   s = (int *)CALLOC(w,sizeof(int));
                                   s[i/bpi] |= 1<<(i%bpi);
                                   MKNODE(t1,s,t);
                                   t = t1;
                           }
                   }
                   return t;
           }
           rem = mono_raddec(NEXT(ideal));
           r = 0;
           len = w*sizeof(int);
           u = (int *)CALLOC(w,sizeof(int));
           for ( i = nv-1; i >= 0; i-- ) {
                   if ( d[i] ) {
                           for ( t = rem; t; t = NEXT(t) ) {
                                   bcopy((char *)BDY(t),(char *)u,len);
                                   u[i/bpi] |= 1<<(i%bpi);
                                   for ( v = r; v; v = NEXT(v) ) {
                                           if ( comp_bits_divisible(u,(int *)BDY(v),nv) ) break;
                                   }
                                   if ( v ) continue;
                                   for ( v = r, prev = 0; v; v = NEXT(v) ) {
                                           if ( comp_bits_divisible((int *)BDY(v),u,nv) ) {
                                                   if ( prev ) NEXT(prev) = NEXT(v);
                                                   else r = NEXT(r);
                                           } else prev =v;
                                   }
                                   for ( v = r, prev = 0; v; prev = v, v = NEXT(v) ) {
                                           if ( comp_bits_lex(u,(int *)BDY(v),nv) < 0 ) break;
                                   }
                                   new = (int *)CALLOC(w,sizeof(int));
                                   bcopy((char *)u,(char *)new,len);
                                   MKNODE(t1,new,v);
                                   if ( prev ) NEXT(prev) = t1;
                                   else r = t1;
                           }
                   }
         }          }
         return r;          return r;
 }  }

Legend:
Removed from v.1.46  
changed lines
  Added in v.1.66

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