=================================================================== RCS file: /home/cvs/OpenXM_contrib2/asir2000/engine/nd.c,v retrieving revision 1.162 retrieving revision 1.189 diff -u -p -r1.162 -r1.189 --- OpenXM_contrib2/asir2000/engine/nd.c 2009/01/05 02:47:39 1.162 +++ OpenXM_contrib2/asir2000/engine/nd.c 2010/05/06 09:22:09 1.189 @@ -1,4 +1,4 @@ -/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.161 2009/01/05 02:08:18 noro Exp $ */ +/* $OpenXM: OpenXM_contrib2/asir2000/engine/nd.c,v 1.188 2010/04/26 01:10:04 noro Exp $ */ #include "nd.h" @@ -46,7 +46,11 @@ static int nd_worb_len; static int nd_found,nd_create,nd_notfirst; static int nmv_adv; static int nd_demand; -static int nd_module,nd_ispot,nd_mpos; +static int nd_module,nd_ispot,nd_mpos,nd_pot_nelim; +static NODE nd_tracelist; +static NODE nd_alltracelist; +static int nd_gentrace,nd_gensyz,nd_nora; +static int *nd_gbblock; NumberField get_numberfield(); UINT *nd_det_compute_bound(NDV **dm,int n,int j); @@ -59,6 +63,13 @@ NDV pltondv(VL vl,VL dvl,LIST p); void pltozpl(LIST l,Q *cont,LIST *pp); void ndl_max(UINT *d1,unsigned *d2,UINT *d); pointer GC_malloc_atomic_ignore_off_page(int); +void nmtodp(int mod,NM m,DP *r); +NODE reverse_node(NODE n); +P ndc_div(int mod,union oNDC a,union oNDC b); +P ndctop(int mod,union oNDC c); +void finalize_tracelist(int i,P cont); +void conv_ilist(int demand,int trace,NODE g,int **indp); +void parse_nd_option(NODE opt); extern int Denominator,DP_Multiple; @@ -217,7 +228,7 @@ INLINE int ndl_reducible(UINT *d1,UINT *d2) * order is either 0 or 2. */ -void ndl_homogenize(UINT *d,UINT *r,int obpe,EPOS oepos,int weight) +void ndl_homogenize(UINT *d,UINT *r,int obpe,EPOS oepos,int ompos,int weight) { int w,i,e,n,omask0; @@ -230,9 +241,9 @@ void ndl_homogenize(UINT *d,UINT *r,int obpe,EPOS oepo } w = TD(d); PUT_EXP(r,nd_nvar-1,weight-w); + if ( nd_module ) MPOS(r) = d[ompos]; TD(r) = weight; if ( nd_blockmask ) ndl_weight_mask(r); - if ( nd_module ) MPOS(r) = MPOS(d); } void ndl_dehomogenize(UINT *d) @@ -364,9 +375,9 @@ void ndl_lcm(UINT *d1,unsigned *d2,UINT *d) d[i] = u; } #endif + if ( nd_module ) MPOS(d) = MPOS(d1); TD(d) = ndl_weight(d); if ( nd_blockmask ) ndl_weight_mask(d); - if ( nd_module ) MPOS(d) = MPOS(d1); } void ndl_max(UINT *d1,unsigned *d2,UINT *d) @@ -399,8 +410,8 @@ int ndl_weight(UINT *d) for ( j = 0; j < nd_epw; j++, u>>=nd_bpe ) t += (u&nd_mask0); } - if ( nd_module && current_module_weight_vector && MPOS(d) ) - t += current_module_weight_vector[MPOS(d)]; + if ( nd_module && current_module_weight_vector && MPOS(d) ) + t += current_module_weight_vector[MPOS(d)]; return t; } @@ -568,17 +579,23 @@ int ndl_ww_lex_compare(UINT *d1,UINT *d2) int ndl_module_grlex_compare(UINT *d1,UINT *d2) { - int i; + int i,c; if ( nd_ispot ) { + if ( nd_pot_nelim && MPOS(d1)>=nd_pot_nelim+1 && MPOS(d2) >= nd_pot_nelim+1 ) { + if ( TD(d1) > TD(d2) ) return 1; + else if ( TD(d1) < TD(d2) ) return -1; + if ( c = ndl_lex_compare(d1,d2) ) return c; + if ( MPOS(d1) < MPOS(d2) ) return 1; + else if ( MPOS(d1) > MPOS(d2) ) return -1; + return 0; + } if ( MPOS(d1) < MPOS(d2) ) return 1; else if ( MPOS(d1) > MPOS(d2) ) return -1; } if ( TD(d1) > TD(d2) ) return 1; else if ( TD(d1) < TD(d2) ) return -1; - for ( i = nd_nvar-1; i >= 0; i-- ) - if ( GET_EXP(d1,i) < GET_EXP(d2,i) ) return 1; - else if ( GET_EXP(d1,i) > GET_EXP(d2,i) ) return -1; + if ( c = ndl_lex_compare(d1,d2) ) return c; if ( !nd_ispot ) { if ( MPOS(d1) < MPOS(d2) ) return 1; else if ( MPOS(d1) > MPOS(d2) ) return -1; @@ -588,7 +605,7 @@ int ndl_module_grlex_compare(UINT *d1,UINT *d2) int ndl_module_glex_compare(UINT *d1,UINT *d2) { - int i; + int i,c; if ( nd_ispot ) { if ( MPOS(d1) < MPOS(d2) ) return 1; @@ -596,9 +613,7 @@ int ndl_module_glex_compare(UINT *d1,UINT *d2) } if ( TD(d1) > TD(d2) ) return 1; else if ( TD(d1) < TD(d2) ) return -1; - for ( i = 0; i < nd_nvar; i++ ) - if ( GET_EXP(d1,i) > GET_EXP(d2,i) ) return 1; - else if ( GET_EXP(d1,i) < GET_EXP(d2,i) ) return -1; + if ( c = ndl_lex_compare(d1,d2) ) return c; if ( !nd_ispot ) { if ( MPOS(d1) < MPOS(d2) ) return 1; else if ( MPOS(d1) > MPOS(d2) ) return -1; @@ -608,15 +623,13 @@ int ndl_module_glex_compare(UINT *d1,UINT *d2) int ndl_module_lex_compare(UINT *d1,UINT *d2) { - int i; + int i,c; if ( nd_ispot ) { if ( MPOS(d1) < MPOS(d2) ) return 1; else if ( MPOS(d1) > MPOS(d2) ) return -1; } - for ( i = 0; i < nd_nvar; i++ ) - if ( GET_EXP(d1,i) > GET_EXP(d2,i) ) return 1; - else if ( GET_EXP(d1,i) < GET_EXP(d2,i) ) return -1; + if ( c = ndl_lex_compare(d1,d2) ) return c; if ( !nd_ispot ) { if ( MPOS(d1) < MPOS(d2) ) return 1; else if ( MPOS(d1) > MPOS(d2) ) return -1; @@ -729,7 +742,7 @@ INLINE void ndl_add(UINT *d1,UINT *d2,UINT *d) if ( nd_module ) { if ( MPOS(d1) && MPOS(d2) && (MPOS(d1) != MPOS(d2)) ) - error("ndl_add : invalid operation"); + error("ndl_add : invalid operation"); } #if 1 switch ( nd_wpd ) { @@ -1237,18 +1250,20 @@ ND nd_add_sf(ND p1,ND p2) } } -ND nd_reduce2(int mod,ND d,ND g,NDV p,NM mul,NDC dn) +ND nd_reduce2(int mod,ND d,ND g,NDV p,NM mul,NDC dn,Obj *divp) { int c,c1,c2; Q cg,cred,gcd,tq; P cgp,credp,gcdp; Obj tr,tr1; - if ( mod == -1 ) + if ( mod == -1 ) { CM(mul) = _mulsf(_invsf(HCM(p)),_chsgnsf(HCM(g))); - else if ( mod ) { + *divp = (Obj)ONE; + } else if ( mod ) { c1 = invm(HCM(p),mod); c2 = mod-HCM(g); DMAR(c1,c2,0,mod,c); CM(mul) = c; + *divp = (Obj)ONE; } else if ( nd_vc ) { ezgcdpz(nd_vc,HCP(g),HCP(p),&gcdp); divsp(nd_vc,HCP(g),gcdp,&cgp); divsp(nd_vc,HCP(p),gcdp,&credp); @@ -1258,6 +1273,7 @@ ND nd_reduce2(int mod,ND d,ND g,NDV p,NM mul,NDC dn) mulr(nd_vc,(Obj)dn->r,(Obj)credp,&tr); reductr(nd_vc,tr,&tr1); dn->r = (R)tr1; } + *divp = (Obj)credp; } else { igcd_cofactor(HCQ(g),HCQ(p),&gcd,&cg,&cred); chsgnq(cg,&CQ(mul)); @@ -1265,6 +1281,7 @@ ND nd_reduce2(int mod,ND d,ND g,NDV p,NM mul,NDC dn) if ( dn ) { mulq(dn->z,cred,&tq); dn->z = tq; } + *divp = (Obj)cred; } return nd_add(mod,g,ndv_mul_nm(mod,mul,p)); } @@ -1278,10 +1295,15 @@ int nd_nf(int mod,ND d,ND g,NDV *ps,int full,NDC dn,ND int c,c1,c2,dummy; RHist h; NDV p,red; - Q cg,cred,gcd,tq,qq; + Q cg,cred,gcd,tq,qq,iq; + DP dmul; + NODE node; + LIST hist; double hmag; P tp,tp1; - Obj tr,tr1; + Obj tr,tr1,div; + union oNDC hg; + P cont; if ( dn ) { if ( mod ) @@ -1312,23 +1334,33 @@ int nd_nf(int mod,ND d,ND g,NDV *ps,int full,NDC dn,ND return 0; } p = nd_demand ? ndv_load(index) : ps[index]; - g = nd_reduce2(mod,d,g,p,mul,dn); + /* d+g -> div*(d+g)+mul*p */ + g = nd_reduce2(mod,d,g,p,mul,dn,&div); + if ( nd_gentrace ) { + /* Trace=[div,index,mul,ONE] */ + STOQ(index,iq); + nmtodp(mod,mul,&dmul); + node = mknode(4,div,iq,dmul,ONE); + } sugar = MAX(sugar,SG(p)+TD(DL(mul))); if ( !mod && g && ((double)(p_mag(HCP(g))) > hmag) ) { - tp = HCP(g); + hg = HCU(g); nd_removecont2(d,g); - if ( dn ) { - if ( nd_vc ) { - divsp(nd_vc,tp,HCP(g),&tp1); - divr(nd_vc,(Obj)dn->r,(Obj)tp1,&tr); - reductr(nd_vc,(Obj)tr,&tr1); dn->r = (R)tr1; - } else { - divq((Q)tp,HCQ(g),&qq); - divq(dn->z,qq,&tq); dn->z = tq; + if ( dn || nd_gentrace ) { + /* overwrite cont : Trace=[div,index,mul,cont] */ + cont = ndc_div(mod,hg,HCU(g)); + if ( dn ) { + if ( nd_vc ) { + divr(nd_vc,(Obj)dn->r,(Obj)cont,&tr); + reductr(nd_vc,(Obj)tr,&tr1); dn->r = (R)tr1; + } else divq(dn->z,(Q)cont,&dn->z); } + if ( nd_gentrace && !UNIQ(cont) ) ARG3(node) = (pointer)cont; } hmag = ((double)p_mag(HCP(g)))*nd_scale; } + MKLIST(hist,node); + MKNODE(node,hist,nd_tracelist); nd_tracelist = node; } else if ( !full ) { *rp = g; return 1; @@ -1455,36 +1487,44 @@ int nd_nf_pbucket(int mod,ND g,NDV *ps,int full,ND *rp /* input : list of NDV, cand : list of NDV */ -int ndv_check_candidate(NODE input,int obpe,int oadv,EPOS oepos,NODE cand) +int ndv_check_membership(int m,NODE input,int obpe,int oadv,EPOS oepos,NODE cand) { int n,i,stat; ND nf,d; NDV r; NODE t,s; union oNDC dn; + Q q; + LIST list; - ndv_setup(0,0,cand,0,1); + ndv_setup(m,0,cand,nd_gentrace?1:0,1); n = length(cand); + if ( nd_gentrace ) { nd_alltracelist = 0; nd_tracelist = 0; } /* membercheck : list is a subset of Id(cand) ? */ - for ( t = input; t; t = NEXT(t) ) { + for ( t = input, i = 0; t; t = NEXT(t), i++ ) { again: + nd_tracelist = 0; if ( nd_bpe > obpe ) r = ndv_dup_realloc((NDV)BDY(t),obpe,oadv,oepos); else r = (NDV)BDY(t); - d = ndvtond(0,r); - stat = nd_nf(0,0,d,nd_ps,0,0,&nf); + d = ndvtond(m,r); + stat = nd_nf(m,0,d,nd_ps,0,0,&nf); if ( !stat ) { nd_reconstruct(0,0); goto again; } else if ( nf ) return 0; + if ( nd_gentrace ) { + nd_tracelist = reverse_node(nd_tracelist); + MKLIST(list,nd_tracelist); + STOQ(i,q); s = mknode(2,q,list); MKLIST(list,s); + MKNODE(s,list,nd_alltracelist); + nd_alltracelist = s; nd_tracelist = 0; + } if ( DP_Print ) { printf("."); fflush(stdout); } } if ( DP_Print ) { printf("\n"); } - /* gbcheck : cand is a GB of Id(cand) ? */ - if ( !nd_gb(0,0,1) ) return 0; - /* XXX */ return 1; } @@ -1785,9 +1825,18 @@ int do_diagonalize(int sugar,int m) ND h,nf,s,head; NDV nfv; Q q,num,den; - P nm,nmp,dn,mnp,dnp; + P nm,nmp,dn,mnp,dnp,cont,cont1; + union oNDC hc; + NODE node; + LIST l; + Q iq; for ( i = nd_psn-1; i >= 0 && SG(nd_psh[i]) == sugar; i-- ) { + if ( nd_gentrace ) { + /* Trace = [1,index,1,1] */ + STOQ(i,iq); node = mknode(4,ONE,iq,ONE,ONE); + MKLIST(l,node); MKNODE(nd_tracelist,l,0); + } if ( nd_demand ) nfv = ndv_load(i); else @@ -1797,7 +1846,9 @@ int do_diagonalize(int sugar,int m) stat = nd_nf(m,head,s,nd_ps,1,0,&nf); if ( !stat ) return 0; ndv_free(nfv); - nd_removecont(m,nf); + hc = HCU(nf); nd_removecont(m,nf); + cont = ndc_div(m,hc,HCU(nf)); + if ( nd_gentrace ) finalize_tracelist(i,cont); nfv = ndtondv(m,nf); nd_free(nf); nd_bound[i] = ndv_compute_bound(nfv); @@ -1813,7 +1864,7 @@ int do_diagonalize(int sugar,int m) /* return value = 0 => input is not a GB */ -NODE nd_gb(int m,int ishomo,int checkonly) +NODE nd_gb(int m,int ishomo,int checkonly,int gensyz,int **indp) { int i,nh,sugar,stat; NODE r,g,t; @@ -1822,12 +1873,14 @@ NODE nd_gb(int m,int ishomo,int checkonly) ND h,nf,s,head,nf1; NDV nfv; Q q,num,den; - union oNDC dn; + union oNDC dn,hc; int diag_count = 0; + P cont; + LIST list; g = 0; d = 0; for ( i = 0; i < nd_psn; i++ ) { - d = update_pairs(d,g,i); + d = update_pairs(d,g,i,gensyz); g = update_base(g,i); } sugar = 0; @@ -1854,7 +1907,8 @@ again: goto again; } #if USE_GEOBUCKET - stat = m?nd_nf_pbucket(m,h,nd_ps,!Top,&nf):nd_nf(m,0,h,nd_ps,!Top,0,&nf); + stat = (m&&!nd_gentrace)?nd_nf_pbucket(m,h,nd_ps,!Top,&nf) + :nd_nf(m,0,h,nd_ps,!Top,0,&nf); #else stat = nd_nf(m,0,h,nd_ps,!Top,0,&nf); #endif @@ -1863,13 +1917,22 @@ again: d = nd_reconstruct(0,d); goto again; } else if ( nf ) { - if ( checkonly ) return 0; + if ( checkonly || gensyz ) return 0; if ( DP_Print ) { printf("+"); fflush(stdout); } + hc = HCU(nf); nd_removecont(m,nf); if ( !m && nd_nalg ) { nd_monic(0,&nf); nd_removecont(m,nf); } + if ( nd_gentrace ) { + cont = ndc_div(m,hc,HCU(nf)); + if ( m || !UNIQ(cont) ) { + t = mknode(4,0,0,0,cont); + MKLIST(list,t); MKNODE(t,list,nd_tracelist); + nd_tracelist = t; + } + } nfv = ndtondv(m,nf); nd_free(nf); nh = ndv_newps(m,nfv,0); if ( !m && (ishomo && ++diag_count == diag_period) ) { @@ -1881,20 +1944,22 @@ again: goto again; } } - d = update_pairs(d,g,nh); + d = update_pairs(d,g,nh,0); g = update_base(g,nh); FREENDP(l); } else { + if ( nd_gentrace && gensyz ) { + nd_tracelist = reverse_node(nd_tracelist); + MKLIST(list,nd_tracelist); + STOQ(-1,q); t = mknode(2,q,list); MKLIST(list,t); + MKNODE(t,list,nd_alltracelist); + nd_alltracelist = t; nd_tracelist = 0; + } if ( DP_Print ) { printf("."); fflush(stdout); } FREENDP(l); } } - if ( nd_demand ) - for ( t = g; t; t = NEXT(t) ) - BDY(t) = (pointer)ndv_load((long)BDY(t)); - else - for ( t = g; t; t = NEXT(t) ) - BDY(t) = (pointer)nd_ps[(long)BDY(t)]; + conv_ilist(nd_demand,0,g,indp); if ( !checkonly && DP_Print ) { printf("nd_gb done.\n"); fflush(stdout); } return g; } @@ -1906,8 +1971,18 @@ int do_diagonalize_trace(int sugar,int m) ND h,nf,nfq,s,head; NDV nfv,nfqv; Q q,den,num; + union oNDC hc; + NODE node; + LIST l; + Q iq; + P cont,cont1; for ( i = nd_psn-1; i >= 0 && SG(nd_psh[i]) == sugar; i-- ) { + if ( nd_gentrace ) { + /* Trace = [1,index,1,1] */ + STOQ(i,iq); node = mknode(4,ONE,iq,ONE,ONE); + MKLIST(l,node); MKNODE(nd_tracelist,l,0); + } /* for nd_ps */ s = ndvtond(m,nd_ps[i]); s = nd_separate_head(s,&head); @@ -1928,7 +2003,9 @@ int do_diagonalize_trace(int sugar,int m) stat = nd_nf(0,head,s,nd_ps_trace,1,0,&nf); if ( !stat ) return 0; ndv_free(nfv); - nd_removecont(0,nf); + hc = HCU(nf); nd_removecont(0,nf); + cont = ndc_div(0,hc,HCU(nf)); + if ( nd_gentrace ) finalize_tracelist(i,cont); nfv = ndtondv(0,nf); nd_free(nf); nd_bound[i] = ndv_compute_bound(nfv); @@ -1956,7 +2033,7 @@ void nd_subst_vector(VL vl,P p,NODE subst,P *r) *r = p; } -NODE nd_gb_trace(int m,int ishomo) +NODE nd_gb_trace(int m,int ishomo,int **indp) { int i,nh,sugar,stat; NODE r,g,t; @@ -1966,16 +2043,18 @@ NODE nd_gb_trace(int m,int ishomo) NDV nfv,nfqv; Q q,den,num; P hc; - union oNDC dn; + union oNDC dn,hnfq; struct oEGT eg_monic,egm0,egm1; int diag_count = 0; + P cont; + LIST list; init_eg(&eg_monic); init_eg(&eg_invdalg); init_eg(&eg_le); g = 0; d = 0; for ( i = 0; i < nd_psn; i++ ) { - d = update_pairs(d,g,i); + d = update_pairs(d,g,i,0); g = update_base(g,i); } sugar = 0; @@ -2036,6 +2115,7 @@ again: if ( !rem(NM(q),m) ) return 0; if ( DP_Print ) { printf("+"); fflush(stdout); } + hnfq = HCU(nfq); if ( nd_nalg ) { /* m|DN(HC(nf)^(-1)) => failure */ get_eg(&egm0); @@ -2047,6 +2127,14 @@ again: nd_removecont(0,nfq); nfqv = ndtondv(0,nfq); nd_free(nfq); nd_removecont(m,nf); nfv = ndtondv(m,nf); nd_free(nf); } + if ( nd_gentrace ) { + cont = ndc_div(0,hnfq,HCU(nfqv)); + if ( !UNIQ(cont) ) { + t = mknode(4,0,0,0,cont); + MKLIST(list,t); MKNODE(t,list,nd_tracelist); + nd_tracelist = t; + } + } nh = ndv_newps(0,nfv,nfqv); if ( ishomo && ++diag_count == diag_period ) { diag_count = 0; @@ -2059,7 +2147,7 @@ again: goto again; } } - d = update_pairs(d,g,nh); + d = update_pairs(d,g,nh,0); g = update_base(g,nh); } else { if ( DP_Print ) { printf("*"); fflush(stdout); } @@ -2069,17 +2157,12 @@ again: } FREENDP(l); } - if ( nd_demand ) - for ( t = g; t; t = NEXT(t) ) - BDY(t) = (pointer)ndv_load((long)BDY(t)); - else - for ( t = g; t; t = NEXT(t) ) - BDY(t) = (pointer)nd_ps_trace[(long)BDY(t)]; if ( nd_nalg ) { print_eg("monic",&eg_monic); print_eg("invdalg",&eg_invdalg); print_eg("le",&eg_le); } + conv_ilist(nd_demand,1,g,indp); if ( DP_Print ) { printf("nd_gb_trace done.\n"); fflush(stdout); } return g; } @@ -2094,25 +2177,44 @@ int ndv_compare_rev(NDV *p1,NDV *p2) return -DL_COMPARE(HDL(*p1),HDL(*p2)); } +int ndvi_compare(NDVI p1,NDVI p2) +{ + return DL_COMPARE(HDL(p1->p),HDL(p2->p)); +} + +int ndvi_compare_rev(NDVI p1,NDVI p2) +{ + return -DL_COMPARE(HDL(p1->p),HDL(p2->p)); +} + NODE ndv_reduceall(int m,NODE f) { - int i,n,stat; + int i,j,n,stat; ND nf,g,head; NODE t,a0,a; union oNDC dn; - NDV *w; Q q,num,den; + NODE node; + LIST l; + Q iq,jq; + int *perm; + union oNDC hc; + P cont,cont1; + if ( nd_nora ) return f; n = length(f); -#if 0 - w = (NDV *)ALLOCA(n*sizeof(NDV)); - for ( i = 0, t = f; i < n; i++, t = NEXT(t) ) w[i] = (NDV)BDY(t); - qsort(w,n,sizeof(NDV), - (int (*)(const void *,const void *))ndv_compare); - for ( t = f, i = 0; t; i++, t = NEXT(t) ) BDY(t) = (pointer)w[i]; -#endif ndv_setup(m,0,f,0,1); + perm = (int *)MALLOC(n*sizeof(int)); + if ( nd_gentrace ) { + for ( t = nd_tracelist, i = 0; i < n; i++, t = NEXT(t) ) + perm[i] = QTOS((Q)ARG1(BDY((LIST)BDY(t)))); + } for ( i = 0; i < n; ) { + if ( nd_gentrace ) { + /* Trace = [1,index,1,1] */ + STOQ(i,iq); node = mknode(4,ONE,iq,ONE,ONE); + MKLIST(l,node); MKNODE(nd_tracelist,l,0); + } g = ndvtond(m,nd_ps[i]); g = nd_separate_head(g,&head); stat = nd_nf(m,head,g,nd_ps,1,0,&nf); @@ -2121,7 +2223,15 @@ NODE ndv_reduceall(int m,NODE f) else { if ( DP_Print ) { printf("."); fflush(stdout); } ndv_free(nd_ps[i]); - nd_removecont(m,nf); + hc = HCU(nf); nd_removecont(m,nf); + if ( nd_gentrace ) { + for ( t = nd_tracelist; t; t = NEXT(t) ) { + jq = ARG1(BDY((LIST)BDY(t))); j = QTOS(jq); + STOQ(perm[j],jq); ARG1(BDY((LIST)BDY(t))) = jq; + } + cont = ndc_div(m,hc,HCU(nf)); + finalize_tracelist(perm[i],cont); + } nd_ps[i] = ndtondv(m,nf); nd_free(nf); nd_bound[i] = ndv_compute_bound(nd_ps[i]); i++; @@ -2130,22 +2240,38 @@ NODE ndv_reduceall(int m,NODE f) if ( DP_Print ) { printf("\n"); } for ( a0 = 0, i = 0; i < n; i++ ) { NEXTNODE(a0,a); - BDY(a) = (pointer)nd_ps[i]; + if ( !nd_gentrace ) BDY(a) = (pointer)nd_ps[i]; + else { + for ( j = 0; j < n; j++ ) if ( perm[j] == i ) break; + BDY(a) = (pointer)nd_ps[j]; + } } NEXT(a) = 0; return a0; } -ND_pairs update_pairs( ND_pairs d, NODE /* of index */ g, int t) +ND_pairs update_pairs( ND_pairs d, NODE /* of index */ g, int t, int gensyz) { ND_pairs d1,nd,cur,head,prev,remove; if ( !g ) return d; + /* for testing */ + if ( gensyz && nd_gensyz == 2 ) { + d1 = nd_newpairs(g,t); + if ( !d ) + return d1; + else { + nd = d; + while ( NEXT(nd) ) nd = NEXT(nd); + NEXT(nd) = d1; + return d; + } + } d = crit_B(d,t); d1 = nd_newpairs(g,t); d1 = crit_M(d1); d1 = crit_F(d1); - if ( do_weyl ) + if ( gensyz || do_weyl ) head = d1; else { prev = 0; cur = head = d1; @@ -2175,7 +2301,7 @@ ND_pairs nd_newpairs( NODE g, int t ) { NODE h; UINT *dl; - int ts,s; + int ts,s,i,t0,min,max; ND_pairs r,r0; dl = DL(nd_psh[t]); @@ -2183,6 +2309,16 @@ ND_pairs nd_newpairs( NODE g, int t ) for ( r0 = 0, h = g; h; h = NEXT(h) ) { if ( nd_module && (MPOS(DL(nd_psh[(long)BDY(h)])) != MPOS(dl)) ) continue; + if ( nd_gbblock ) { + t0 = (long)BDY(h); + for ( i = 0; nd_gbblock[i] >= 0; i += 2 ) { + min = nd_gbblock[i]; max = nd_gbblock[i+1]; + if ( t0 >= min && t0 <= max && t >= min && t <= max ) + break; + } + if ( nd_gbblock[i] >= 0 ) + continue; + } NEXTND_pairs(r0,r); r->i1 = (long)BDY(h); r->i2 = t; @@ -2209,16 +2345,24 @@ ND_pairs crit_B( ND_pairs d, int s ) lcm = (UINT *)ALLOCA(nd_wpd*sizeof(UINT)); while ( cur ) { tl = cur->lcm; - if ( ndl_reducible(tl,t) - && (ndl_lcm(DL(nd_psh[cur->i1]),t,lcm),!ndl_equal(lcm,tl)) - && (ndl_lcm(DL(nd_psh[cur->i2]),t,lcm),!ndl_equal(lcm,tl)) ) { - remove = cur; - if ( !prev ) { - head = cur = NEXT(cur); + if ( ndl_reducible(tl,t) ) { + ndl_lcm(DL(nd_psh[cur->i1]),t,lcm); + if ( !ndl_equal(lcm,tl) ) { + ndl_lcm(DL(nd_psh[cur->i2]),t,lcm); + if (!ndl_equal(lcm,tl)) { + remove = cur; + if ( !prev ) { + head = cur = NEXT(cur); + } else { + cur = NEXT(prev) = NEXT(cur); + } + FREENDP(remove); + } else { + prev = cur; cur = NEXT(cur); + } } else { - cur = NEXT(prev) = NEXT(cur); + prev = cur; cur = NEXT(cur); } - FREENDP(remove); } else { prev = cur; cur = NEXT(cur); } @@ -2418,6 +2562,9 @@ int ndv_newps(int m,NDV a,NDV aq) int len; RHist r; NDV b; + NODE tn; + LIST l; + Q iq; if ( nd_psn == nd_pslen ) { nd_pslen *= 2; @@ -2448,31 +2595,48 @@ int ndv_newps(int m,NDV a,NDV aq) nd_ps[nd_psn] = 0; } } + if ( nd_gentrace ) { + /* reverse the tracelist and append it to alltracelist */ + nd_tracelist = reverse_node(nd_tracelist); MKLIST(l,nd_tracelist); + STOQ(nd_psn,iq); tn = mknode(2,iq,l); MKLIST(l,tn); + MKNODE(tn,l,nd_alltracelist); nd_alltracelist = tn; nd_tracelist = 0; + } return nd_psn++; } -void ndv_setup(int mod,int trace,NODE f,int dont_sort,int dont_removecont) +/* nd_tracelist = [[0,index,div],...,[nd_psn-1,index,div]] */ +/* return 1 if success, 0 if failure (HC(a mod p)) */ + +int ndv_setup(int mod,int trace,NODE f,int dont_sort,int dont_removecont) { int i,j,td,len,max; - NODE s,s0,f0; + NODE s,s0,f0,tn; UINT *d; RHist r; - NDV *w; + NDVI w; NDV a,am; + union oNDC hc; + NODE node; + P hcp; + Q iq,jq,hcq; + LIST l; nd_found = 0; nd_notfirst = 0; nd_create = 0; + /* initialize the tracelist */ + nd_tracelist = 0; for ( nd_psn = 0, s = f; s; s = NEXT(s) ) if ( BDY(s) ) nd_psn++; - w = (NDV *)ALLOCA(nd_psn*sizeof(NDV)); - for ( i = 0, s = f; s; s = NEXT(s) ) if ( BDY(s) ) w[i++] = BDY(s); + w = (NDVI)ALLOCA(nd_psn*sizeof(struct oNDVI)); + for ( i = j = 0, s = f; s; s = NEXT(s), j++ ) + if ( BDY(s) ) { w[i].p = BDY(s); w[i].i = j; i++; } if ( !dont_sort ) { /* XXX heuristic */ if ( !nd_ord->id && (nd_ord->ord.simple<2) ) - qsort(w,nd_psn,sizeof(NDV), - (int (*)(const void *,const void *))ndv_compare_rev); + qsort(w,nd_psn,sizeof(struct oNDVI), + (int (*)(const void *,const void *))ndvi_compare_rev); else - qsort(w,nd_psn,sizeof(NDV), - (int (*)(const void *,const void *))ndv_compare); + qsort(w,nd_psn,sizeof(struct oNDVI), + (int (*)(const void *,const void *))ndvi_compare); } nd_pslen = 2*nd_psn; nd_ps = (NDV *)MALLOC(nd_pslen*sizeof(NDV)); @@ -2490,18 +2654,27 @@ void ndv_setup(int mod,int trace,NODE f,int dont_sort, nd_red = (RHist *)MALLOC(REDTAB_LEN*sizeof(RHist)); for ( i = 0; i < REDTAB_LEN; i++ ) nd_red[i] = 0; for ( i = 0; i < nd_psn; i++ ) { + hc = HCU(w[i].p); if ( trace ) { - a = nd_ps_trace[i] = ndv_dup(0,w[i]); + a = nd_ps_trace[i] = ndv_dup(0,w[i].p); if ( !dont_removecont) ndv_removecont(0,a); register_hcf(a); am = nd_ps[i] = ndv_dup(mod,a); ndv_mod(mod,am); + if ( DL_COMPARE(HDL(am),HDL(a)) ) + return 0; ndv_removecont(mod,am); } else { - a = nd_ps[i] = ndv_dup(mod,w[i]); + a = nd_ps[i] = ndv_dup(mod,w[i].p); if ( mod || !dont_removecont ) ndv_removecont(mod,a); if ( !mod ) register_hcf(a); } + if ( nd_gentrace ) { + STOQ(i,iq); STOQ(w[i].i,jq); node = mknode(3,iq,jq,ONE); + if ( !dont_removecont ) + ARG2(node) = (pointer)ndc_div(trace?0:mod,hc,HCU(a)); + MKLIST(l,node); NEXTNODE(nd_tracelist,tn); BDY(tn) = l; + } NEWRHist(r); SG(r) = HTD(a); ndl_copy(HDL(a),DL(r)); nd_bound[i] = ndv_compute_bound(a); nd_psh[i] = r; @@ -2515,6 +2688,8 @@ void ndv_setup(int mod,int trace,NODE f,int dont_sort, } } } + if ( nd_gentrace && nd_tracelist ) NEXT(tn) = 0; + return 1; } struct order_spec *append_block(struct order_spec *spec, @@ -2550,7 +2725,7 @@ void preprocess_algcoef(VL vv,VL av,struct order_spec } NEXT(t) = 0; - /* simplification, makeing polynomials monic */ + /* simplification, making polynomials monic */ setfield_dalg(alist); obj_algtodalg(f,&f1); for ( t = BDY(f); t; t = NEXT(t) ) { @@ -2622,13 +2797,14 @@ NODE postprocess_algcoef(VL av,NODE alist,NODE r) return u0; } -void nd_gr(LIST f,LIST v,int m,int f4,struct order_spec *ord,LIST *rp) +void nd_gr(LIST f,LIST v,int m,int homo,int f4,struct order_spec *ord,LIST *rp) { VL tv,fv,vv,vc,av; NODE fd,fd0,r,r0,t,x,s,xx,alist; int e,max,nvar,i; NDV b; - int ishomo,nalg,mrank,trank; + int ishomo,nalg,mrank,trank,wmax,len; + NMV a; Alg alpha,dp; P p,zp; Q dmy; @@ -2636,9 +2812,18 @@ void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe Obj obj; NumberField nf; struct order_spec *ord1; + NODE tr,tl1,tl2,tl3,tl4; + LIST l1,l2,l3,l4,l5; + int j; + Q jq; + int *perm; + EPOS oepos; + int obpe,oadv,ompos; + nd_module = 0; if ( !m && Demand ) nd_demand = 1; else nd_demand = 0; + parse_nd_option(current_option); if ( DP_Multiple ) nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1); @@ -2672,7 +2857,7 @@ void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe } nd_init_ord(ord); mrank = 0; - for ( t = BDY(f), max = 0; t; t = NEXT(t) ) + for ( t = BDY(f), max = 1; t; t = NEXT(t) ) for ( tv = vv; tv; tv = NEXT(tv) ) { if ( nd_module ) { s = BDY((LIST)BDY(t)); @@ -2688,35 +2873,93 @@ void nd_gr(LIST f,LIST v,int m,int f4,struct order_spe } } nd_setup_parameters(nvar,max); + obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos; ishomo = 1; for ( fd0 = 0, t = BDY(f); t; t = NEXT(t) ) { - if ( nd_module ) { - pltozpl((LIST)BDY(t),&dmy,&zpl); + if ( nd_module ) { + if ( !m && !nd_gentrace ) pltozpl((LIST)BDY(t),&dmy,&zpl); + else zpl = (LIST)BDY(t); b = (pointer)pltondv(CO,vv,zpl); } else { - ptozp((P)BDY(t),1,&dmy,&zp); + if ( !m && !nd_gentrace ) ptozp((P)BDY(t),1,&dmy,&zp); + else zp = (P)BDY(t); b = (pointer)ptondv(CO,vv,zp); - } + } if ( ishomo ) ishomo = ishomo && ndv_ishomo(b); if ( m ) ndv_mod(m,b); if ( b ) { NEXTNODE(fd0,fd); BDY(fd) = (pointer)b; } } if ( fd0 ) NEXT(fd) = 0; - ndv_setup(m,0,fd0,0,0); - x = f4?nd_f4(m):nd_gb(m,ishomo,0); + + if ( !ishomo && homo ) { + for ( t = fd0, wmax = max; t; t = NEXT(t) ) { + b = (NDV)BDY(t); len = LEN(b); + for ( a = BDY(b), i = 0; i < len; i++, NMV_ADV(a) ) + wmax = MAX(TD(DL(a)),wmax); + } + homogenize_order(ord,nvar,&ord1); + nd_init_ord(ord1); + nd_setup_parameters(nvar+1,wmax); + for ( t = fd0; t; t = NEXT(t) ) + ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos); + } + + ndv_setup(m,0,fd0,nd_gbblock?1:0,0); + if ( nd_gentrace ) { + MKLIST(l1,nd_tracelist); MKNODE(nd_alltracelist,l1,0); + } + x = f4?nd_f4(m,&perm):nd_gb(m,ishomo || homo,0,0,&perm); + if ( !ishomo && homo ) { + /* dehomogenization */ + for ( t = x; t; t = NEXT(t) ) ndv_dehomogenize((NDV)BDY(t),ord); + nd_init_ord(ord); + nd_setup_parameters(nvar,0); + } nd_demand = 0; - x = ndv_reducebase(x); + x = ndv_reducebase(x,perm); + if ( nd_gentrace ) { tl1 = nd_alltracelist; nd_alltracelist = 0; } x = ndv_reduceall(m,x); + if ( nd_gentrace ) { + tl2 = nd_alltracelist; nd_alltracelist = 0; + ndv_check_membership(m,fd0,obpe,oadv,oepos,x); + if ( nd_gentrace ) { + tl3 = nd_alltracelist; nd_alltracelist = 0; + } else tl3 = 0; + nd_gb(m,0,1,nd_gensyz?1:0,0)!=0; + if ( nd_gentrace && nd_gensyz ) { + tl4 = nd_alltracelist; nd_alltracelist = 0; + } else tl4 = 0; + } for ( r0 = 0, t = x; t; t = NEXT(t) ) { NEXTNODE(r0,r); - if ( nd_module ) BDY(r) = ndvtopl(m,CO,vv,BDY(t),mrank); + if ( nd_module ) BDY(r) = ndvtopl(m,CO,vv,BDY(t),mrank); else BDY(r) = ndvtop(m,CO,vv,BDY(t)); } if ( r0 ) NEXT(r) = 0; if ( nalg ) r0 = postprocess_algcoef(av,alist,r0); MKLIST(*rp,r0); + if ( nd_gentrace ) { + tl1 = reverse_node(tl1); tl2 = reverse_node(tl2); + tl3 = reverse_node(tl3); + /* tl2 = [[i,[[*,j,*,*],...]],...] */ + for ( t = tl2; t; t = NEXT(t) ) { + /* s = [i,[*,j,*,*],...] */ + s = BDY((LIST)BDY(t)); + j = perm[QTOS((Q)ARG0(s))]; STOQ(j,jq); ARG0(s) = (pointer)jq; + for ( s = BDY((LIST)ARG1(s)); s; s = NEXT(s) ) { + j = perm[QTOS((Q)ARG1(BDY((LIST)BDY(s))))]; STOQ(j,jq); + ARG1(BDY((LIST)BDY(s))) = (pointer)jq; + } + } + for ( j = length(x)-1, t = 0; j >= 0; j-- ) { + STOQ(perm[j],jq); MKNODE(s,jq,t); t = s; + } + MKLIST(l1,tl1); MKLIST(l2,tl2); MKLIST(l3,t); MKLIST(l4,tl3); + MKLIST(l5,tl4); + tr = mknode(7,*rp,(!ishomo&&homo)?ONE:0,l1,l2,l3,l4,l5); MKLIST(*rp,tr); + } #if 0 fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc); #endif @@ -2736,6 +2979,7 @@ void nd_gr_postproc(LIST f,LIST v,int m,struct order_s Obj obj; NumberField nf; struct order_spec *ord1; + int *perm; get_vars((Obj)f,&fv); pltovl(v,&vv); vlminus(fv,vv,&nd_vc); for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ ); @@ -2763,7 +3007,7 @@ void nd_gr_postproc(LIST f,LIST v,int m,struct order_s nvar += nalg; } nd_init_ord(ord); - for ( t = BDY(f), max = 0; t; t = NEXT(t) ) + for ( t = BDY(f), max = 1; t; t = NEXT(t) ) for ( tv = vv; tv; tv = NEXT(tv) ) { e = getdeg(tv->v,(P)BDY(t)); max = MAX(e,max); @@ -2783,16 +3027,21 @@ void nd_gr_postproc(LIST f,LIST v,int m,struct order_s for ( x = 0, i = 0; i < nd_psn; i++ ) x = update_base(x,i); if ( do_check ) { - x = nd_gb(m,ishomo,1); + x = nd_gb(m,ishomo,1,0,&perm); if ( !x ) { *rp = 0; return; } } else { +#if 0 + /* bug ? */ for ( t = x; t; t = NEXT(t) ) BDY(t) = (pointer)nd_ps[(long)BDY(t)]; +#else + conv_ilist(0,0,x,&perm); +#endif } - x = ndv_reducebase(x); + x = ndv_reducebase(x,perm); x = ndv_reduceall(m,x); for ( r0 = 0, t = x; t; t = NEXT(t) ) { NEXTNODE(r0,r); @@ -2814,7 +3063,7 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int P p,zp; Q dmy; EPOS oepos; - int obpe,oadv,wmax,i,len,cbpe,ishomo,nalg,mrank,trank; + int obpe,oadv,wmax,i,len,cbpe,ishomo,nalg,mrank,trank,ompos; Alg alpha,dp; P poly; LIST f1,f2,zpl; @@ -2822,7 +3071,14 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int NumberField nf; struct order_spec *ord1; struct oEGT eg_check,eg0,eg1; + NODE tr,tl1,tl2,tl3,tl4; + LIST l1,l2,l3,l4,l5; + int *perm; + int j,ret; + Q jq; + nd_module = 0; + parse_nd_option(current_option); if ( DP_Multiple ) nd_scale = ((double)DP_Multiple)/(double)(Denominator?Denominator:1); @@ -2863,7 +3119,7 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int m = trace > 1 ? trace : get_lprime(mindex); nd_init_ord(ord); mrank = 0; - for ( t = BDY(f), max = 0; t; t = NEXT(t) ) + for ( t = BDY(f), max = 1; t; t = NEXT(t) ) for ( tv = vv; tv; tv = NEXT(tv) ) { if ( nd_module ) { s = BDY((LIST)BDY(t)); @@ -2879,16 +3135,18 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int } } nd_setup_parameters(nvar,max); - obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; + obpe = nd_bpe; oadv = nmv_adv; oepos = nd_epos; ompos = nd_mpos; ishomo = 1; for ( in0 = 0, fd0 = 0, t = BDY(f); t; t = NEXT(t) ) { - if ( nd_module ) { - pltozpl((LIST)BDY(t),&dmy,&zpl); + if ( nd_module ) { + if ( !nd_gentrace ) pltozpl((LIST)BDY(t),&dmy,&zpl); + else zpl = (LIST)BDY(t); c = (pointer)pltondv(CO,vv,zpl); } else { - ptozp((P)BDY(t),1,&dmy,&zp); + if ( !nd_gentrace ) ptozp((P)BDY(t),1,&dmy,&zp); + else zp = (P)BDY(t); c = (pointer)ptondv(CO,vv,zp); - } + } if ( ishomo ) ishomo = ishomo && ndv_ishomo(c); if ( c ) { @@ -2908,14 +3166,19 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int nd_init_ord(ord1); nd_setup_parameters(nvar+1,wmax); for ( t = fd0; t; t = NEXT(t) ) - ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos); + ndv_homogenize((NDV)BDY(t),obpe,oadv,oepos,ompos); } while ( 1 ) { + tl1 = tl2 = tl3 = tl4 = 0; if ( Demand ) nd_demand = 1; - ndv_setup(m,1,fd0,0,0); - cand = f4?nd_f4_trace(m):nd_gb_trace(m,ishomo || homo); - if ( !cand ) { + ret = ndv_setup(m,1,fd0,nd_gbblock?1:0,0); + if ( nd_gentrace ) { + MKLIST(l1,nd_tracelist); MKNODE(nd_alltracelist,l1,0); + } + if ( ret ) + cand = f4?nd_f4_trace(m,&perm):nd_gb_trace(m,ishomo || homo,&perm); + if ( !ret || !cand ) { /* failure */ if ( trace > 1 ) { *rp = 0; return; } else m = get_lprime(++mindex); @@ -2928,15 +3191,25 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int nd_setup_parameters(nvar,0); } nd_demand = 0; - cand = ndv_reducebase(cand); + cand = ndv_reducebase(cand,perm); + if ( nd_gentrace ) { tl1 = nd_alltracelist; nd_alltracelist = 0; } cand = ndv_reduceall(0,cand); cbpe = nd_bpe; + if ( nd_gentrace ) { tl2 = nd_alltracelist; nd_alltracelist = 0; } + get_eg(&eg0); if ( nocheck ) break; - get_eg(&eg0); - if ( ndv_check_candidate(in0,obpe,oadv,oepos,cand) ) - /* success */ - break; + if ( ret = ndv_check_membership(0,in0,obpe,oadv,oepos,cand) ) { + if ( nd_gentrace ) { + tl3 = nd_alltracelist; nd_alltracelist = 0; + } else tl3 = 0; + /* gbcheck : cand is a GB of Id(cand) ? */ + ret = nd_gb(0,0,1,nd_gensyz?1:0,0)!=0; + if ( nd_gentrace && nd_gensyz ) { + tl4 = nd_alltracelist; nd_alltracelist = 0; + } else tl4 = 0; + } + if ( ret ) break; else if ( trace > 1 ) { /* failure */ *rp = 0; return; @@ -2960,12 +3233,32 @@ void nd_gr_trace(LIST f,LIST v,int trace,int homo,int nd_bpe = cbpe; nd_setup_parameters(nd_nvar,0); for ( r = cand; r; r = NEXT(r) ) { - if ( nd_module ) BDY(r) = ndvtopl(0,CO,vv,BDY(r),mrank); + if ( nd_module ) BDY(r) = ndvtopl(0,CO,vv,BDY(r),mrank); else BDY(r) = (pointer)ndvtop(0,CO,vv,BDY(r)); } if ( nalg ) cand = postprocess_algcoef(av,alist,cand); MKLIST(*rp,cand); + if ( nd_gentrace ) { + tl1 = reverse_node(tl1); tl2 = reverse_node(tl2); + tl3 = reverse_node(tl3); + /* tl2 = [[i,[[*,j,*,*],...]],...] */ + for ( t = tl2; t; t = NEXT(t) ) { + /* s = [i,[*,j,*,*],...] */ + s = BDY((LIST)BDY(t)); + j = perm[QTOS((Q)ARG0(s))]; STOQ(j,jq); ARG0(s) = (pointer)jq; + for ( s = BDY((LIST)ARG1(s)); s; s = NEXT(s) ) { + j = perm[QTOS((Q)ARG1(BDY((LIST)BDY(s))))]; STOQ(j,jq); + ARG1(BDY((LIST)BDY(s))) = (pointer)jq; + } + } + for ( j = length(cand)-1, t = 0; j >= 0; j-- ) { + STOQ(perm[j],jq); MKNODE(s,jq,t); t = s; + } + MKLIST(l1,tl1); MKLIST(l2,tl2); MKLIST(l3,t); MKLIST(l4,tl3); + MKLIST(l5,tl4); + tr = mknode(7,*rp,(!ishomo&&homo)?ONE:0,l1,l2,l3,l4,l5); MKLIST(*rp,tr); + } } /* XXX : module element is not considered */ @@ -3016,6 +3309,18 @@ DL ndltodl(int n,UINT *ndl) return dl; } +void nmtodp(int mod,NM m,DP *r) +{ + DP dp; + MP mr; + + NEWMP(mr); + mr->dl = ndltodl(nd_nvar,DL(m)); + mr->c = ndctop(mod,m->c); + NEXT(mr) = 0; MKDP(nd_nvar,mr,dp); dp->sugar = mr->dl->td; + *r = dp; +} + void ndl_print(UINT *dl) { int n; @@ -3170,20 +3475,20 @@ void ndv_removecont(int mod,NDV p) /* koko */ -void ndv_homogenize(NDV p,int obpe,int oadv,EPOS oepos) +void ndv_homogenize(NDV p,int obpe,int oadv,EPOS oepos,int ompos) { int len,i,max; NMV m,mr0,mr,t; len = p->len; - for ( m = BDY(p), i = 0, max = 0; i < len; NMV_OADV(m), i++ ) + for ( m = BDY(p), i = 0, max = 1; i < len; NMV_OADV(m), i++ ) max = MAX(max,TD(DL(m))); mr0 = nmv_adv>oadv?(NMV)REALLOC(BDY(p),len*nmv_adv):BDY(p); m = (NMV)((char *)mr0+(len-1)*oadv); mr = (NMV)((char *)mr0+(len-1)*nmv_adv); t = (NMV)ALLOCA(nmv_adv); for ( i = 0; i < len; i++, NMV_OPREV(m), NMV_PREV(mr) ) { - ndl_homogenize(DL(m),DL(t),obpe,oepos,max); + ndl_homogenize(DL(m),DL(t),obpe,oepos,ompos,max); CQ(mr) = CQ(m); ndl_copy(DL(t),DL(mr)); } @@ -3193,7 +3498,8 @@ void ndv_homogenize(NDV p,int obpe,int oadv,EPOS oepos void ndv_dehomogenize(NDV p,struct order_spec *ord) { - int i,j,adj,len,newnvar,newwpd,newadv,newexporigin; + int i,j,adj,len,newnvar,newwpd,newadv,newexporigin,newmpos; + int pos; Q *w; Q dvr,t; NMV m,r; @@ -3201,6 +3507,7 @@ void ndv_dehomogenize(NDV p,struct order_spec *ord) len = p->len; newnvar = nd_nvar-1; newexporigin = nd_get_exporigin(ord); + if ( nd_module ) newmpos = newexporigin-1; newwpd = newnvar/nd_epw+(newnvar%nd_epw?1:0)+newexporigin; for ( m = BDY(p), i = 0; i < len; NMV_ADV(m), i++ ) ndl_dehomogenize(DL(m)); @@ -3208,9 +3515,13 @@ void ndv_dehomogenize(NDV p,struct order_spec *ord) newadv = ROUND_FOR_ALIGN(sizeof(struct oNMV)+(newwpd-1)*sizeof(UINT)); for ( m = r = BDY(p), i = 0; i < len; NMV_ADV(m), NDV_NADV(r), i++ ) { CQ(r) = CQ(m); + if ( nd_module ) pos = MPOS(DL(m)); for ( j = 0; j < newexporigin; j++ ) DL(r)[j] = DL(m)[j]; adj = nd_exporigin-newexporigin; for ( ; j < newwpd; j++ ) DL(r)[j] = DL(m)[j+adj]; + if ( nd_module ) { + DL(r)[newmpos] = pos; + } } } NV(p)--; @@ -3636,8 +3947,11 @@ int nd_sp(int mod,int trace,ND_pairs p,ND *rp) ND t1,t2; UINT *lcm; P gp,tp; - Q g,t; + Q g,t,iq; int td; + LIST hist; + NODE node; + DP d; if ( !mod && nd_demand ) { p1 = ndv_load(p->i1); p2 = ndv_load(p->i2); @@ -3671,6 +3985,14 @@ int nd_sp(int mod,int trace,ND_pairs p,ND *rp) } t1 = ndv_mul_nm(mod,m1,p1); t2 = ndv_mul_nm(mod,m2,p2); *rp = nd_add(mod,t1,t2); + if ( nd_gentrace ) { + /* nd_tracelist is initialized */ + STOQ(p->i1,iq); nmtodp(mod,m1,&d); node = mknode(4,ONE,iq,d,ONE); + MKLIST(hist,node); MKNODE(nd_tracelist,hist,0); + STOQ(p->i2,iq); nmtodp(mod,m2,&d); node = mknode(4,ONE,iq,d,ONE); + MKLIST(hist,node); MKNODE(node,hist,nd_tracelist); + nd_tracelist = node; + } FREENM(m1); FREENM(m2); return 1; } @@ -3757,10 +4079,15 @@ void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *ta for ( i = 0; i < tlen; i++ ) tab[i] = 0; if ( !m0 || !m1 ) return; d0 = DL(m0); d1 = DL(m1); n2 = n>>1; + if ( nd_module ) + if ( MPOS(d0) ) error("weyl_mul_nm_nmv : invalid operation"); + NEWNM(m); d = DL(m); if ( mod ) { c0 = CM(m0); c1 = CM(m1); DMAR(c0,c1,0,mod,c); CM(m) = c; - } else + } else if ( nd_vc ) + mulp(nd_vc,CP(m0),CP(m1),&CP(m)); + else mulq(CQ(m0),CQ(m1),&CQ(m)); for ( i = 0; i < nd_wpd; i++ ) d[i] = 0; homo = n&1 ? 1 : 0; @@ -3771,10 +4098,6 @@ void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *ta TD(DL(m)) = h; if ( nd_blockmask ) ndl_weight_mask(DL(m)); } - if ( nd_module ) { - mpos = MPOS(d1); - if ( MPOS(d0) ) error("weyl_mul_nm_nmv : invalid operation"); - } tab[0] = m; NEWNM(m); d = DL(m); for ( i = 0, curlen = 1; i < n2; i++ ) { @@ -3810,7 +4133,6 @@ void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *ta PUT_EXP(d,n-1,s-h); } else TD(d) = h; if ( nd_blockmask ) ndl_weight_mask(d); - if ( nd_module ) MPOS(d) = mpos; if ( mod ) c = ctab[j]; else q = ctab_q[j]; p = tab+curlen*j; @@ -3820,7 +4142,9 @@ void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *ta ndl_addto(DL(tab[u]),d); if ( mod ) { c0 = CM(tab[u]); DMAR(c0,c,0,mod,c1); CM(tab[u]) = c1; - } else { + } else if ( nd_vc ) + mulp(nd_vc,CP(tab[u]),(P)q,&CP(tab[u])); + else { mulq(CQ(tab[u]),q,&q1); CQ(tab[u]) = q1; } } @@ -3832,7 +4156,9 @@ void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *ta ndl_add(DL(tab[u]),d,DL(t)); if ( mod ) { c0 = CM(tab[u]); DMAR(c0,c,0,mod,c1); CM(t) = c1; - } else + } else if ( nd_vc ) + mulp(nd_vc,CP(tab[u]),(P)q,&CP(t)); + else mulq(CQ(tab[u]),q,&CQ(t)); *p = t; } @@ -3842,6 +4168,15 @@ void weyl_mul_nm_nmv(int n,int mod,NM m0,NMV m1,NM *ta curlen *= k+1; } FREENM(m); + if ( nd_module ) { + mpos = MPOS(d1); + for ( i = 0; i < tlen; i++ ) + if ( tab[i] ) { + d = DL(tab[i]); + MPOS(d) = mpos; + TD(d) = ndl_weight(d); + } + } } ND ndv_mul_nm_symbolic(NM m0,NDV p) @@ -4150,9 +4485,12 @@ NDV pltondv(VL vl,VL dvl,LIST p) r = 0; for ( i = 1, t = BDY(p); t; t = NEXT(t), i++ ) { ri = ptond(vl,dvl,(P)BDY(t)); - if ( ri ) - for ( m = BDY(ri); m; m = NEXT(m) ) + if ( ri ) + for ( m = BDY(ri); m; m = NEXT(m) ) { MPOS(DL(m)) = i; + TD(DL(m)) = ndl_weight(DL(m)); + if ( nd_blockmask ) ndl_weight_mask(DL(m)); + } r = nd_add(0,r,ri); } return ndtondv(0,r); @@ -4372,24 +4710,29 @@ void ndv_print_q(NDV p) } } -NODE ndv_reducebase(NODE x) +NODE ndv_reducebase(NODE x,int *perm) { int len,i,j; - NDV *w; + NDVI w; NODE t,t0; len = length(x); - w = (NDV *)ALLOCA(len*sizeof(NDV)); - for ( i = 0, t = x; i < len; i++, t = NEXT(t) ) w[i] = BDY(t); + w = (NDVI)ALLOCA(len*sizeof(struct oNDVI)); + for ( i = 0, t = x; i < len; i++, t = NEXT(t) ) { + w[i].p = BDY(t); w[i].i = perm[i]; + } for ( i = 0; i < len; i++ ) { for ( j = 0; j < i; j++ ) { - if ( w[i] && w[j] ) - if ( ndl_reducible(HDL(w[i]),HDL(w[j])) ) w[i] = 0; - else if ( ndl_reducible(HDL(w[j]),HDL(w[i])) ) w[j] = 0; + if ( w[i].p && w[j].p ) + if ( ndl_reducible(HDL(w[i].p),HDL(w[j].p)) ) w[i].p = 0; + else if ( ndl_reducible(HDL(w[j].p),HDL(w[i].p)) ) w[j].p = 0; } } - for ( i = len-1, t0 = 0; i >= 0; i-- ) { - if ( w[i] ) { NEXTNODE(t0,t); BDY(t) = (pointer)w[i]; } + for ( i = j = 0, t0 = 0; i < len; i++ ) { + if ( w[i].p ) { + NEXTNODE(t0,t); BDY(t) = (pointer)w[i].p; + perm[j++] = w[i].i; + } } NEXT(t) = 0; x = t0; return x; @@ -4454,16 +4797,19 @@ void nd_init_ord(struct order_spec *ord) /* module order */ case 256: nd_ispot = ord->ispot; + nd_pot_nelim = ord->pot_nelim; nd_dcomp = -1; - nd_isrlex = 0; switch ( ord->ord.simple ) { case 0: + nd_isrlex = 1; ndl_compare_function = ndl_module_grlex_compare; break; case 1: + nd_isrlex = 0; ndl_compare_function = ndl_module_glex_compare; break; case 2: + nd_isrlex = 0; ndl_compare_function = ndl_module_lex_compare; break; default: @@ -4472,16 +4818,28 @@ void nd_init_ord(struct order_spec *ord) break; case 257: /* block order */ + nd_ispot = ord->ispot; + nd_pot_nelim = ord->pot_nelim; + nd_dcomp = -1; + nd_isrlex = 0; ndl_compare_function = ndl_module_block_compare; break; case 258: /* matrix order */ + nd_ispot = ord->ispot; + nd_pot_nelim = ord->pot_nelim; + nd_dcomp = -1; + nd_isrlex = 0; nd_matrix_len = ord->ord.matrix.row; nd_matrix = ord->ord.matrix.matrix; ndl_compare_function = ndl_module_matrix_compare; break; case 259: /* composite order */ + nd_ispot = ord->ispot; + nd_pot_nelim = ord->pot_nelim; + nd_dcomp = -1; + nd_isrlex = 0; nd_worb_len = ord->ord.composite.length; nd_worb = ord->ord.composite.w_or_b; ndl_compare_function = ndl_module_composite_compare; @@ -4497,7 +4855,7 @@ BlockMask nd_create_blockmask(struct order_spec *ord) BlockMask bm; /* we only create mask table for block order */ - if ( ord->id != 1 ) + if ( ord->id != 1 && ord->id != 257 ) return 0; n = ord->ord.block.length; bm = (BlockMask)MALLOC(sizeof(struct oBlockMask)); @@ -4521,7 +4879,7 @@ EPOS nd_create_epos(struct order_spec *ord) epos = (EPOS)MALLOC_ATOMIC(nd_nvar*sizeof(struct oEPOS)); switch ( ord->id ) { - case 0: + case 0: case 256: if ( nd_isrlex ) { for ( i = 0; i < nd_nvar; i++ ) { epos[i].i = nd_exporigin + (nd_nvar-1-i)/nd_epw; @@ -4534,7 +4892,7 @@ EPOS nd_create_epos(struct order_spec *ord) } } break; - case 1: + case 1: case 257: /* block order */ l = ord->ord.block.length; op = ord->ord.block.order_pair; @@ -4558,7 +4916,7 @@ EPOS nd_create_epos(struct order_spec *ord) /* matrix order */ case 3: /* composite order */ - default: + default: for ( i = 0; i < nd_nvar; i++ ) { epos[i].i = nd_exporigin + i/nd_epw; epos[i].s = (nd_epw-(i%nd_epw)-1)*nd_bpe; @@ -4589,7 +4947,7 @@ void nd_nf_p(P f,LIST g,LIST v,int m,struct order_spec for ( nvar = 0, tv = vv; tv; tv = NEXT(tv), nvar++ ); /* get the degree bound */ - for ( t = BDY(g), max = 0; t; t = NEXT(t) ) + for ( t = BDY(g), max = 1; t; t = NEXT(t) ) for ( tv = vv; tv; tv = NEXT(tv) ) { e = getdeg(tv->v,(P)BDY(t)); max = MAX(e,max); @@ -5089,7 +5447,7 @@ int nd_symbolic_preproc(PGeoBucket bucket,int trace,UI return col; } -NODE nd_f4(int m) +NODE nd_f4(int m,int **indp) { int i,nh,stat,index; NODE r,g; @@ -5115,7 +5473,7 @@ NODE nd_f4(int m) #endif g = 0; d = 0; for ( i = 0; i < nd_psn; i++ ) { - d = update_pairs(d,g,i); + d = update_pairs(d,g,i,0); g = update_base(g,i); } while ( d ) { @@ -5159,18 +5517,18 @@ NODE nd_f4(int m) nf = ndtondv(m,nf1); } nh = ndv_newps(m,nf,0); - d = update_pairs(d,g,nh); + d = update_pairs(d,g,nh,0); g = update_base(g,nh); } } - for ( r = g; r; r = NEXT(r) ) BDY(r) = (pointer)nd_ps[(long)BDY(r)]; #if 0 fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc); #endif + conv_ilist(0,0,g,indp); return g; } -NODE nd_f4_trace(int m) +NODE nd_f4_trace(int m,int **indp) { int i,nh,stat,index; NODE r,g; @@ -5193,7 +5551,7 @@ NODE nd_f4_trace(int m) g = 0; d = 0; for ( i = 0; i < nd_psn; i++ ) { - d = update_pairs(d,g,i); + d = update_pairs(d,g,i,0); g = update_base(g,i); } while ( d ) { @@ -5259,17 +5617,120 @@ NODE nd_f4_trace(int m) ndv_mod(m,nfv); ndv_removecont(m,nfv); nh = ndv_newps(0,nfv,nfqv); - d = update_pairs(d,g,nh); + d = update_pairs(d,g,nh,0); g = update_base(g,nh); } } - for ( r = g; r; r = NEXT(r) ) BDY(r) = (pointer)nd_ps_trace[(long)BDY(r)]; #if 0 fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc); #endif + conv_ilist(0,1,g,indp); return g; } +NODE nd_f4_pseudo_trace(int m,int **indp) +{ + int i,nh,stat,index; + NODE r,g; + ND_pairs d,l,l0,t; + ND spol,red; + NDV nf,redv,nfqv,nfv; + NM s0,s; + NODE rp0,srp0,nflist; + int nsp,nred,col,rank,len,k,j,a; + UINT c; + UINT **spmat; + UINT *s0vect,*svect,*p,*v; + int *colstat; + IndArray *imat; + int *rhead; + int spcol,sprow; + int sugar; + PGeoBucket bucket; + struct oEGT eg0,eg1,eg_f4; + + g = 0; d = 0; + for ( i = 0; i < nd_psn; i++ ) { + d = update_pairs(d,g,i,0); + g = update_base(g,i); + } + while ( d ) { + get_eg(&eg0); + l = nd_minsugarp(d,&d); + sugar = SG(l); + bucket = create_pbucket(); + stat = nd_sp_f4(m,0,l,bucket); + if ( !stat ) { + for ( t = l; NEXT(t); t = NEXT(t) ); + NEXT(t) = d; d = l; + d = nd_reconstruct(1,d); + continue; + } + if ( bucket->m < 0 ) continue; + col = nd_symbolic_preproc(bucket,0,&s0vect,&rp0); + if ( !col ) { + for ( t = l; NEXT(t); t = NEXT(t) ); + NEXT(t) = d; d = l; + d = nd_reconstruct(1,d); + continue; + } + get_eg(&eg1); init_eg(&eg_f4); add_eg(&eg_f4,&eg0,&eg1); + if ( DP_Print ) + fprintf(asir_out,"sugar=%d,symb=%fsec,", + sugar,eg_f4.exectime+eg_f4.gctime); + nflist = nd_f4_red(m,l,0,s0vect,col,rp0,&l0); + if ( !l0 ) continue; + l = l0; + + /* over Q */ + while ( 1 ) { + bucket = create_pbucket(); + stat = nd_sp_f4(0,1,l,bucket); + if ( !stat ) { + for ( t = l; NEXT(t); t = NEXT(t) ); + NEXT(t) = d; d = l; + d = nd_reconstruct(1,d); + continue; + } + if ( bucket->m < 0 ) continue; + col = nd_symbolic_preproc(bucket,1,&s0vect,&rp0); + if ( !col ) { + for ( t = l; NEXT(t); t = NEXT(t) ); + NEXT(t) = d; d = l; + d = nd_reconstruct(1,d); + continue; + } + nflist = nd_f4_red(0,l,1,s0vect,col,rp0,0); + } + + /* adding new bases */ + for ( r = nflist; r; r = NEXT(r) ) { + nfqv = (NDV)BDY(r); + ndv_removecont(0,nfqv); + if ( !rem(NM(HCQ(nfqv)),m) ) return 0; + if ( nd_nalg ) { + ND nf1; + + nf1 = ndvtond(m,nfqv); + nd_monic(0,&nf1); + nd_removecont(0,nf1); + nfqv = ndtondv(0,nf1); nd_free(nf1); + } + nfv = ndv_dup(0,nfqv); + ndv_mod(m,nfv); + ndv_removecont(m,nfv); + nh = ndv_newps(0,nfv,nfqv); + d = update_pairs(d,g,nh,0); + g = update_base(g,nh); + } + } +#if 0 + fprintf(asir_out,"ndv_alloc=%d\n",ndv_alloc); +#endif + conv_ilist(0,1,g,indp); + return g; +} + NODE nd_f4_red(int m,ND_pairs sp0,int trace,UINT *s0vect,int col,NODE rp0,ND_pairs *nz) { IndArray *imat; @@ -5778,31 +6239,13 @@ void nd_exec_f4_red_dist() int nd_gauss_elim_q(Q **mat0,int *sugar,int row,int col,int *colstat) { - int mod,i,j,t,c,rank,rank0,inv; + int i,j,t,c,rank,inv; int *ci,*ri; Q dn; MAT m,nm; - int **wmat; - /* XXX */ - mod = 99999989; - wmat = (int **)ALLOCA(row*sizeof(int *)); - for ( i = 0; i < row; i++ ) { - wmat[i] = (int *)ALLOCA(col*sizeof(int)); - for ( j = 0; j < col; j++ ) { - if ( mat0[i][j] ) { - t = rem(NM(mat0[i][j]),mod); - if ( SGN(mat0[i][j]) < 0 ) t = mod-t; - wmat[i][j] = t; - } else - wmat[i][j] = 0; - } - } - rank0 = nd_gauss_elim_mod(wmat,sugar,0,row,col,mod,colstat); NEWMAT(m); m->row = row; m->col = col; m->body = (pointer **)mat0; rank = generic_gauss_elim(m,&nm,&dn,&ri,&ci); - if ( rank != rank0 ) - error("afo"); for ( i = 0; i < row; i++ ) for ( j = 0; j < col; j++ ) mat0[i][j] = 0; @@ -5812,19 +6255,6 @@ int nd_gauss_elim_q(Q **mat0,int *sugar,int row,int co for ( j = 0; j < c; j++ ) mat0[i][ci[j]] = (Q)BDY(nm)[i][j]; } - inv = invm(rem(NM(dn),mod),mod); - if ( SGN(dn) < 0 ) inv = mod-inv; - for ( i = 0; i < row; i++ ) - for ( j = 0; j < col; j++ ) { - if ( mat0[i][j] ) { - t = rem(NM(mat0[i][j]),mod); - if ( SGN(mat0[i][j]) < 0 ) t = mod-t; - } else - t = 0; - c = dmar(t,inv,0,mod); - if ( wmat[i][j] != c ) - error("afo"); - } return rank; } @@ -6112,7 +6542,7 @@ void nd_det(int mod,MAT f,P *rp) m = (pointer **)w; } - for ( i = 0, max = 0; i < n; i++ ) + for ( i = 0, max = 1; i < n; i++ ) for ( j = 0; j < n; j++ ) for ( tv = fv; tv; tv = NEXT(tv) ) { e = getdeg(tv->v,(P)m[i][j]); @@ -6120,7 +6550,7 @@ void nd_det(int mod,MAT f,P *rp) } nd_setup_parameters(nvar,max); dm = (NDV **)almat_pointer(n,n); - for ( i = 0, max = 0; i < n; i++ ) + for ( i = 0, max = 1; i < n; i++ ) for ( j = 0; j < n; j++ ) { dm[i][j] = ptondv(CO,fv,m[i][j]); if ( mod ) ndv_mod(mod,dm[i][j]); @@ -6170,16 +6600,24 @@ void nd_det(int mod,MAT f,P *rp) bucket = create_pbucket(); if ( mi[k] ) { nmv = BDY(mjj); len = LEN(mjj); + fprintf(stderr,"len=%d\n",len); for ( a = 0; a < len; a++, NMV_ADV(nmv) ) { + fprintf(stderr,"."); u = ndv_mul_nmv_trunc(mod,nmv,mi[k],DL(BDY(d))); add_pbucket(mod,bucket,u); + if ( !(a%1000) ) + fprintf(stderr,"%d\n",a); } } if ( mj[k] && mij ) { nmv = BDY(mij); len = LEN(mij); + fprintf(stderr,"len=%d\n",len); for ( a = 0; a < len; a++, NMV_ADV(nmv) ) { + fprintf(stderr,"."); u = ndv_mul_nmv_trunc(mod,nmv,mj[k],DL(BDY(d))); add_pbucket(mod,bucket,u); + if ( !(a%1000) ) + fprintf(stderr,"%d\n",a); } } u = nd_quo(mod,bucket,d); @@ -6416,9 +6854,9 @@ int nd_monic(int mod,ND *p) PUT_EXP(DL(mr),i+nd_ntrans,e); td += MUL_WEIGHT(e,i+nd_ntrans); } + if ( nd_module ) MPOS(DL(mr)) = MPOS(DL(m)); TD(DL(mr)) = td; if ( nd_blockmask) ndl_weight_mask(DL(mr)); - if ( nd_module ) MPOS(DL(mr)) = MPOS(DL(m)); } } NEXT(mr) = 0; @@ -6429,4 +6867,113 @@ int nd_monic(int mod,ND *p) nd_free(*p); *p = r; return 1; +} + +NODE reverse_node(NODE n) +{ + NODE t,t1; + + for ( t = 0; n; n = NEXT(n) ) { + MKNODE(t1,BDY(n),t); t = t1; + } + return t; +} + +P ndc_div(int mod,union oNDC a,union oNDC b) +{ + union oNDC c; + int inv,t; + + if ( mod == -1 ) c.m = _mulsf(a.m,_invsf(b.m)); + else if ( mod ) { + inv = invm(b.m,mod); + DMAR(a.m,inv,0,mod,t); c.m = t; + } else if ( nd_vc ) + divsp(nd_vc,a.p,b.p,&c.p); + else + divq(a.z,b.z,&c.z); + return ndctop(mod,c); +} + +P ndctop(int mod,union oNDC c) +{ + Q q; + int e; + GFS gfs; + + if ( mod == -1 ) { + e = IFTOF(c.m); MKGFS(e,gfs); return (P)gfs; + } else if ( mod ) { + STOQ(c.m,q); return (P)q; + } else + return (P)c.p; +} + +/* [0,0,0,cont] = p -> p/cont */ + +void finalize_tracelist(int i,P cont) +{ + LIST l; + NODE node; + Q iq; + + if ( !UNIQ(cont) ) { + node = mknode(4,0,0,0,cont); + MKLIST(l,node); MKNODE(node,l,nd_tracelist); + nd_tracelist = node; + } + STOQ(i,iq); + nd_tracelist = reverse_node(nd_tracelist); + MKLIST(l,nd_tracelist); + node = mknode(2,iq,l); MKLIST(l,node); + MKNODE(node,l,nd_alltracelist); MKLIST(l,node); + nd_alltracelist = node; nd_tracelist = 0; +} + +void conv_ilist(int demand,int trace,NODE g,int **indp) +{ + int n,i,j; + int *ind; + NODE t; + + n = length(g); + ind = (int *)MALLOC(n*sizeof(int)); + for ( i = 0, t = g; i < n; i++, t = NEXT(t) ) { + j = (long)BDY(t); ind[i] = j; + BDY(t) = (pointer)(demand?ndv_load(j):(trace?nd_ps_trace[j]:nd_ps[j])); + } + if ( indp ) *indp = ind; +} + +void parse_nd_option(NODE opt) +{ + NODE t,p,u; + int i,s; + char *key; + Obj value; + + nd_gentrace = 0; nd_gensyz = 0; nd_nora = 0; nd_gbblock = 0; + for ( t = opt; t; t = NEXT(t) ) { + p = BDY((LIST)BDY(t)); + key = BDY((STRING)BDY(p)); + value = (Obj)BDY(NEXT(p)); + if ( !strcmp(key,"gentrace") ) + nd_gentrace = value?1:0; + else if ( !strcmp(key,"gensyz") ) + nd_gensyz = value?1:0; + else if ( !strcmp(key,"nora") ) + nd_nora = value?1:0; + else if ( !strcmp(key,"gbblock") ) { + if ( !value || OID(value) != O_LIST ) + error("nd_* : invalid value for gbblock option"); + u = BDY((LIST)value); + nd_gbblock = MALLOC((2*length(u)+1)*sizeof(int)); + for ( i = 0; u; u = NEXT(u) ) { + p = BDY((LIST)BDY(u)); + s = nd_gbblock[i++] = QTOS((Q)BDY(p)); + nd_gbblock[i++] = s+QTOS((Q)BDY(NEXT(p)))-1; + } + nd_gbblock[i] = -1; + } + } }