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

Annotation of OpenXM_contrib2/asir2000/builtin/gf.c, Revision 1.1

1.1     ! noro        1: /* $OpenXM: OpenXM/src/asir99/builtin/gf.c,v 1.1.1.1 1999/11/10 08:12:25 noro Exp $ */
        !             2: #include "ca.h"
        !             3: #include "parse.h"
        !             4:
        !             5: struct resf_dlist {
        !             6:        int ib,id;
        !             7: };
        !             8:
        !             9: int resf_degtest(int,int *,int,struct resf_dlist *);
        !            10: void uhensel(P,NODE,int,int,NODE *);
        !            11: void resf_hensel(int,P,int,P *,ML *);
        !            12: void resf_dtest(P,ML,int,int *,int *,DCP *);
        !            13: void resf_dtest_special(P,ML,int,int *,int *,DCP *);
        !            14: void dtest_special(P,ML,P *);
        !            15: void hensel_special(int,int,P,P *,ML *);
        !            16:
        !            17: void nullspace(UM **,UM,int,int,int *);
        !            18: void nullspace_lm(LM **,int,int *);
        !            19: void nullspace_gf2n(GF2N **,int,int *);
        !            20: void nullspace_gfpn(GFPN **,int,int *);
        !            21: void null_to_sol(int **,int *,int,int,UM *);
        !            22:
        !            23: void showgfmat(UM **,int);
        !            24: void pwr_mod(P,P,V,P,int,N,P *);
        !            25: void rem_mod(P,P,V,P,int,P *);
        !            26:
        !            27: void Pnullspace(),Pgcda_mod(),Pftest(),Presfmain(),Ppwr_mod(),Puhensel();
        !            28:
        !            29: void Pnullspace_ff();
        !            30:
        !            31: void Psolve_linear_equation_gf2n();
        !            32: void Plinear_form_to_vect(),Pvect_to_linear_form();
        !            33:
        !            34: void solve_linear_equation_gf2n(GF2N **,int,int,int *);
        !            35: void linear_form_to_array(P,VL,int,Num *);
        !            36: void array_to_linear_form(Num *,VL,int,P *);
        !            37:
        !            38: extern int current_ff;
        !            39:
        !            40: struct ftab gf_tab[] = {
        !            41:        {"solve_linear_equation_gf2n",Psolve_linear_equation_gf2n,1},
        !            42:        {"nullspace",Pnullspace,3},
        !            43:        {"nullspace_ff",Pnullspace_ff,1},
        !            44: /*     {"gcda_mod",Pgcda_mod,5}, */
        !            45:        {"ftest",Pftest,2},
        !            46:        {"resfmain",Presfmain,4},
        !            47:        {"pwr_mod",Ppwr_mod,6},
        !            48:        {"uhensel",Puhensel,4},
        !            49:        {0,0,0},
        !            50: };
        !            51:
        !            52: int resf_degtest(k,in,nb,dlist)
        !            53: int k;
        !            54: int *in;
        !            55: int nb;
        !            56: struct resf_dlist *dlist;
        !            57: {
        !            58:        int i,d0,d;
        !            59:        int dl_i;
        !            60:        struct resf_dlist *t;
        !            61:
        !            62:        if ( k < nb )
        !            63:                return 0;
        !            64:        if ( nb == 1 )
        !            65:                return 1;
        !            66:        d0 = 0; d = 0; dl_i = 0;
        !            67:        for ( i = 0; i < k; i++ ) {
        !            68:                t = &dlist[in[i]];
        !            69:                if ( t->ib > dl_i + 1 )
        !            70:                        return 0;
        !            71:                else if ( t->ib == dl_i )
        !            72:                        d += t->id;
        !            73:                else if ( !d || (dl_i && d0 != d) )
        !            74:                        return 0;
        !            75:                else {
        !            76:                        d0 = d; dl_i++; d = t->id;
        !            77:                }
        !            78:        }
        !            79:        if ( dl_i != nb - 1 || d0 != d )
        !            80:                return 0;
        !            81:        else
        !            82:                return 1;
        !            83: }
        !            84:
        !            85: void Puhensel(arg,rp)
        !            86: NODE arg;
        !            87: LIST *rp;
        !            88: {
        !            89:        P f;
        !            90:        NODE mfl,r;
        !            91:        int mod,bound;
        !            92:
        !            93:        f = (P)ARG0(arg);
        !            94:        mfl = BDY((LIST)ARG1(arg));
        !            95:        mod = QTOS((Q)ARG2(arg));
        !            96:        bound = QTOS((Q)ARG3(arg));
        !            97:        uhensel(f,mfl,mod,bound,&r);
        !            98:        MKLIST(*rp,r);
        !            99: }
        !           100:
        !           101: void uhensel(f,mfl,mod,bound,rp)
        !           102: P f;
        !           103: NODE mfl;
        !           104: int mod,bound;
        !           105: NODE *rp;
        !           106: {
        !           107:        ML blist,clist,rlist;
        !           108:        LUM fl;
        !           109:        int nf,i;
        !           110:        P s;
        !           111:        V v;
        !           112:        NODE t,top;
        !           113:
        !           114:        nf = length(mfl);
        !           115:        blist = MLALLOC(nf); blist->n = nf; blist->mod = mod;
        !           116:        for ( i = 0, t = mfl; i < nf; i++, t = NEXT(t) ) {
        !           117:                blist->c[i] = (pointer)UMALLOC(UDEG((P)BDY(t)));
        !           118:                ptoum(mod,(P)BDY(t),blist->c[i]);
        !           119:        }
        !           120:        gcdgen(f,blist,&clist);
        !           121:        blist->bound = clist->bound = bound;
        !           122:        W_LUMALLOC((int)UDEG(f),bound,fl);
        !           123:        ptolum(mod,bound,f,fl);
        !           124:        henmain(fl,blist,clist,&rlist);
        !           125:        v = VR(f);
        !           126:        for ( i = nf-1, top = 0; i >= 0; i-- ) {
        !           127:                lumtop(v,mod,bound,rlist->c[i],&s);
        !           128:                MKNODE(t,s,top); top = t;
        !           129:        }
        !           130:        *rp = top;
        !           131: }
        !           132:
        !           133: void Presfmain(arg,rp)
        !           134: NODE arg;
        !           135: LIST *rp;
        !           136: {
        !           137:        P f;
        !           138:        int mod,n,nb,i,j,k;
        !           139:        int *nf,*md;
        !           140:        P *mf;
        !           141:        NODE mfl,mdl,t,s,u;
        !           142:        ML list;
        !           143:        DCP dc;
        !           144:        int sflag;
        !           145:
        !           146:        f = (P)ARG0(arg);
        !           147:        mod = QTOS((Q)ARG1(arg));
        !           148:        mfl = BDY((LIST)ARG2(arg));
        !           149:        mdl = BDY((LIST)ARG3(arg));
        !           150:        for ( n = nb = 0, t = mfl; t; nb++, t = NEXT(t) )
        !           151:                for ( s = BDY((LIST)BDY(t)); s; n++, s = NEXT(s) );
        !           152:        if ( n == nb ) {
        !           153:                /* f must be irreducible! */
        !           154:                NEWDC(dc);
        !           155:                dc->c = f; dc->d = ONE;
        !           156:        } else {
        !           157:                nf = W_ALLOC(nb); md = W_ALLOC(nb); mf = (P *)ALLOCA(n*sizeof(P));
        !           158:                for ( k = i = 0, t = mfl, u = mdl, sflag = 1; t;
        !           159:                        i++, t = NEXT(t), u = NEXT(u) ) {
        !           160:                        if ( sflag && length(BDY((LIST)BDY(t))) != 2 )
        !           161:                                sflag = 0;
        !           162:                        for ( j = 0, s = BDY((LIST)BDY(t)); s; j++, s = NEXT(s) )
        !           163:                                mf[k++] = (P)BDY(s);
        !           164:                        nf[i] = j; md[i] = QTOS((Q)BDY(u));
        !           165:                }
        !           166:                resf_hensel(mod,f,n,mf,&list);
        !           167:                if ( sflag )
        !           168:                        resf_dtest_special(f,list,nb,nf,md,&dc);
        !           169:                else
        !           170:                        resf_dtest(f,list,nb,nf,md,&dc);
        !           171:        }
        !           172:        dcptolist(dc,rp);
        !           173: }
        !           174:
        !           175: void resf_hensel(mod,f,nf,mfl,listp)
        !           176: int mod;
        !           177: P f;
        !           178: int nf;
        !           179: P *mfl;
        !           180: ML *listp;
        !           181: {
        !           182:        register int i,j;
        !           183:        int q,n,bound;
        !           184:        int *p;
        !           185:        int **pp;
        !           186:        ML blist,clist,bqlist,cqlist,rlist;
        !           187:        UM *b;
        !           188:        LUM fl,tl;
        !           189:        LUM *l;
        !           190:
        !           191:        blist = MLALLOC(nf); blist->n = nf; blist->mod = mod;
        !           192:        for ( i = 0; i < nf; i++ ) {
        !           193:                blist->c[i] = (pointer)UMALLOC(UDEG(mfl[i]));
        !           194:                ptoum(mod,mfl[i],blist->c[i]);
        !           195:        }
        !           196:        gcdgen(f,blist,&clist); henprep(f,blist,clist,&bqlist,&cqlist);
        !           197:        n = bqlist->n; q = bqlist->mod;
        !           198:        bqlist->bound = cqlist->bound = bound = mignotte(q,f);
        !           199:        if ( bound == 1 ) {
        !           200:                *listp = rlist = MLALLOC(n);
        !           201:                rlist->n = n; rlist->mod = q; rlist->bound = bound;
        !           202:                for ( i = 0, b = (UM *)bqlist->c, l = (LUM *)rlist->c; i < n; i++ ) {
        !           203:                        tl = LUMALLOC(DEG(b[i]),1); l[i] = tl; p = COEF(b[i]);
        !           204:                        for ( j = 0, pp = COEF(tl); j <= DEG(tl); j++ )
        !           205:                                        pp[j][0] = p[j];
        !           206:                }
        !           207:        } else {
        !           208:                W_LUMALLOC((int)UDEG(f),bound,fl);
        !           209:                ptolum(q,bound,f,fl); henmain(fl,bqlist,cqlist,listp);
        !           210:        }
        !           211: }
        !           212:
        !           213: void resf_dtest(f,list,nb,nfl,mdl,dcp)
        !           214: P f;
        !           215: ML list;
        !           216: int nb;
        !           217: int *nfl,*mdl;
        !           218: DCP *dcp;
        !           219: {
        !           220:        int n,np,bound,q;
        !           221:        int i,j,k;
        !           222:        int *win;
        !           223:        P g,factor,cofactor;
        !           224:        Q csum,csumt;
        !           225:        DCP dcf,dcf0;
        !           226:        LUM *c;
        !           227:        ML wlist;
        !           228:        struct resf_dlist *dlist;
        !           229:        int z;
        !           230:
        !           231:        n = UDEG(f); np = list->n; bound = list->bound; q = list->mod;
        !           232:        win = W_ALLOC(np+1);
        !           233:        ucsump(f,&csum); mulq(csum,(Q)COEF(DC(f)),&csumt); csum = csumt;
        !           234:        wlist = W_MLALLOC(np); wlist->n = list->n;
        !           235:        wlist->mod = list->mod; wlist->bound = list->bound;
        !           236:        c = (LUM *)COEF(wlist);
        !           237:        bcopy((char *)COEF(list),(char *)c,(int)(sizeof(LUM)*np));
        !           238:        dlist = (struct resf_dlist *)ALLOCA(np*sizeof(struct resf_dlist));
        !           239:        for ( i = 0, j = 0; j < nb; j++ )
        !           240:                for ( k = 0; k < nfl[j]; k++, i++ ) {
        !           241:                        dlist[i].ib = j; dlist[i].id = DEG(c[i])/mdl[j];
        !           242:                }
        !           243:        k = nb;
        !           244:        for ( i = 0; i < nb; i++ )
        !           245:                win[i] = i+1;
        !           246:        for ( g = f, dcf = dcf0 = 0, --np, z = 0; ; ) {
        !           247: #if 0
        !           248:                if ( !(z++ % 10000) )
        !           249:                        fputc('.',stderr);
        !           250: #endif
        !           251:                if ( resf_degtest(k,win,nb,dlist) &&
        !           252:                        dtestmain(g,csum,wlist,k,win,&factor,&cofactor) ) {
        !           253:                        NEXTDC(dcf0,dcf); DEG(dcf) = ONE; COEF(dcf) = factor;
        !           254:                        g = cofactor;
        !           255:                        ucsump(g,&csum); mulq(csum,(Q)COEF(DC(g)),&csumt); csum = csumt;
        !           256:                        for ( i = 0; i < k - 1; i++ )
        !           257:                                for ( j = win[i] + 1; j < win[i + 1]; j++ ) {
        !           258:                                        c[j-i-1] = c[j];
        !           259:                                        dlist[j-i-1] = dlist[j];
        !           260:                                }
        !           261:                        for ( j = win[k-1] + 1; j <= np; j++ ) {
        !           262:                                c[j-k] = c[j];
        !           263:                                dlist[j-k] = dlist[j];
        !           264:                        }
        !           265:                        if ( ( np -= k ) < k )
        !           266:                                break;
        !           267:                        if ( np - win[0] + 1 < k )
        !           268:                                if ( ++k > np )
        !           269:                                        break;
        !           270:                                else
        !           271:                                        for ( i = 0; i < k; i++ )
        !           272:                                                win[i] = i + 1;
        !           273:                        else
        !           274:                                for ( i = 1; i < k; i++ )
        !           275:                                        win[i] = win[0] + i;
        !           276:                } else if ( !ncombi(1,np,k,win) )
        !           277:                        if ( k == np )
        !           278:                                break;
        !           279:                        else
        !           280:                                for ( i = 0, ++k; i < k; i++ )
        !           281:                                        win[i] = i + 1;
        !           282:        }
        !           283:        NEXTDC(dcf0,dcf); COEF(dcf) = g;
        !           284:        DEG(dcf) = ONE; NEXT(dcf) = 0;*dcp = dcf0;
        !           285: }
        !           286:
        !           287: void resf_dtest_special(f,list,nb,nfl,mdl,dcp)
        !           288: P f;
        !           289: ML list;
        !           290: int nb;
        !           291: int *nfl,*mdl;
        !           292: DCP *dcp;
        !           293: {
        !           294:        int n,np,bound,q;
        !           295:        int i,j;
        !           296:        int *win;
        !           297:        P g,factor,cofactor;
        !           298:        Q csum,csumt;
        !           299:        DCP dcf,dcf0;
        !           300:        LUM *c;
        !           301:        ML wlist;
        !           302:        int max;
        !           303:
        !           304:        n = UDEG(f); np = list->n; bound = list->bound; q = list->mod;
        !           305:        win = W_ALLOC(np+1);
        !           306:        ucsump(f,&csum); mulq(csum,(Q)COEF(DC(f)),&csumt); csum = csumt;
        !           307:        wlist = W_MLALLOC(np); wlist->n = list->n;
        !           308:        wlist->mod = list->mod; wlist->bound = list->bound;
        !           309:        c = (LUM *)COEF(wlist); bcopy((char *)COEF(list),(char *)c,(int)(sizeof(LUM)*np));
        !           310:        max = 1<<nb;
        !           311:        for ( g = f, dcf = dcf0 = 0, i = 0; i < max; i++ ) {
        !           312: #if 0
        !           313:                if ( !(i % 1000) )
        !           314:                        fprintf(stderr,"i=%d\n",i);
        !           315: #endif
        !           316:                for ( j = 0; j < nb; j++ )
        !           317:                        win[j] = (i&(1<<j)) ? 2*j+1 : 2*j;
        !           318:                if ( dtestmain(g,csum,wlist,nb,win,&factor,&cofactor) ) {
        !           319: #if 0
        !           320:                        fprintf(stderr,"success : i=%d\n",i);
        !           321: #endif
        !           322:                        NEXTDC(dcf0,dcf); DEG(dcf) = ONE; COEF(dcf) = factor;
        !           323:                        NEXTDC(dcf0,dcf); DEG(dcf) = ONE; COEF(dcf) = cofactor;
        !           324:                        NEXT(dcf) = 0;*dcp = dcf0;
        !           325:                        return;
        !           326:                }
        !           327:        }
        !           328:        NEXTDC(dcf0,dcf); COEF(dcf) = g;
        !           329:        DEG(dcf) = ONE; NEXT(dcf) = 0;*dcp = dcf0;
        !           330: }
        !           331:
        !           332: #if 0
        !           333: void Pftest(arg,rp)
        !           334: NODE arg;
        !           335: P *rp;
        !           336: {
        !           337:        ML list;
        !           338:        DCP dc;
        !           339:        P p;
        !           340:        P *mfl;
        !           341:
        !           342:        p = (P)ARG0(arg); mfl = (P *)(((VECT)ARG1(arg))->body);
        !           343:        hensel_special(4,1,p,mfl,&list);
        !           344:        dtest_special(p,list,rp);
        !           345: }
        !           346:
        !           347: void dtest_special(f,list,pr)
        !           348: P f;
        !           349: ML list;
        !           350: P *pr;
        !           351: {
        !           352:        int n,np,bound,q;
        !           353:        int i,j,k;
        !           354:        int *win;
        !           355:        P g,factor,cofactor;
        !           356:        Q csum,csumt;
        !           357:        DCP dc,dcf,dcf0;
        !           358:        LUM *c;
        !           359:        ML wlist;
        !           360:
        !           361:        n = UDEG(f); np = list->n; bound = list->bound; q = list->mod;
        !           362:        win = W_ALLOC(np+1);
        !           363:        ucsump(f,&csum); mulq(csum,(Q)COEF(DC(f)),&csumt); csum = csumt;
        !           364:        wlist = W_MLALLOC(np); wlist->n = list->n;
        !           365:        wlist->mod = list->mod; wlist->bound = list->bound;
        !           366:        c = (LUM *)COEF(wlist); bcopy((char *)COEF(list),(char *)c,(int)(sizeof(LUM)*np));
        !           367:        for ( g = f, i = 130000; i < (1<<20); i++ ) {
        !           368: #if 0
        !           369:                if ( !(i % 1000) )
        !           370:                        fprintf(stderr,"i=%d\n",i);
        !           371: #endif
        !           372:                for ( j = 0; j < 20; j++ )
        !           373:                        win[j] = (i&(1<<j)) ? 2*j+1 : 2*j;
        !           374:                if ( dtestmain(g,csum,wlist,20,win,&factor,&cofactor) ) {
        !           375: #if 0
        !           376:                        fprintf(stderr,"success : i=%d\n",i);
        !           377: #endif
        !           378:                        *pr = factor; return;
        !           379:                }
        !           380:        }
        !           381: }
        !           382:
        !           383: void hensel_special(index,count,f,mfl,listp)
        !           384: int index,count;
        !           385: P f;
        !           386: P *mfl;
        !           387: ML *listp;
        !           388: {
        !           389:        register int i,j;
        !           390:        int q,n,t,d,r,u,br,tmp,bound;
        !           391:        int *c,*p,*m,*w;
        !           392:        int **pp;
        !           393:        DCP dc;
        !           394:        ML blist,clist,bqlist,cqlist,rlist;
        !           395:        UM *b;
        !           396:        LUM fl,tl;
        !           397:        LUM *l;
        !           398:
        !           399:        blist = MLALLOC(40); blist->n = 40; blist->mod = 11;
        !           400:        for ( i = 0; i < 40; i++ ) {
        !           401:                blist->c[i] = (pointer)UMALLOC(6);
        !           402:                ptoum(11,mfl[i],blist->c[i]);
        !           403:        }
        !           404:        gcdgen(f,blist,&clist); henprep(f,blist,clist,&bqlist,&cqlist);
        !           405:        n = bqlist->n; q = bqlist->mod;
        !           406:        bqlist->bound = cqlist->bound = bound = mignotte(q,f);
        !           407:        if ( bound == 1 ) {
        !           408:                *listp = rlist = MLALLOC(n);
        !           409:                rlist->n = n; rlist->mod = q; rlist->bound = bound;
        !           410:                for ( i = 0, b = (UM *)bqlist->c, l = (LUM *)rlist->c; i < n; i++ ) {
        !           411:                        tl = LUMALLOC(DEG(b[i]),1); l[i] = tl; p = COEF(b[i]);
        !           412:                        for ( j = 0, pp = COEF(tl); j <= DEG(tl); j++ )
        !           413:                                        pp[j][0] = p[j];
        !           414:                }
        !           415:        } else {
        !           416:                W_LUMALLOC(UDEG(f),bound,fl);
        !           417:                ptolum(q,bound,f,fl); henmain(fl,bqlist,cqlist,listp);
        !           418:        }
        !           419: }
        !           420: #endif
        !           421:
        !           422: #if 0
        !           423: void Pftest(arg,rp)
        !           424: NODE arg;
        !           425: P *rp;
        !           426: {
        !           427:        ML list;
        !           428:        DCP dc;
        !           429:        P p;
        !           430:        P *mfl;
        !           431:
        !           432:        p = (P)ARG0(arg); mfl = (P *)(((VECT)ARG1(arg))->body);
        !           433:        hensel_special(2,1,p,mfl,&list);
        !           434:        dtest_special(p,list,rp);
        !           435: }
        !           436:
        !           437: void dtest_special(f,list,pr)
        !           438: P f;
        !           439: ML list;
        !           440: P *pr;
        !           441: {
        !           442:        int n,np,bound,q;
        !           443:        int i,j,k,t,b0;
        !           444:        int *win;
        !           445:        P g,factor,cofactor;
        !           446:        Q csum,csumt;
        !           447:        DCP dc,dcf,dcf0;
        !           448:        LUM *c;
        !           449:        ML wlist;
        !           450:        static int nbits[16] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4};
        !           451:
        !           452:        n = UDEG(f); np = list->n; bound = list->bound; q = list->mod;
        !           453:        win = W_ALLOC(np+1);
        !           454:        ucsump(f,&csum); mulq(csum,(Q)COEF(DC(f)),&csumt); csum = csumt;
        !           455:        wlist = W_MLALLOC(np); wlist->n = list->n;
        !           456:        wlist->mod = list->mod; wlist->bound = list->bound;
        !           457:        c = (LUM *)COEF(wlist); bcopy((char *)COEF(list),(char *)c,(int)(sizeof(LUM)*np));
        !           458:        for ( g = f, i = 0; i < (1<<23); i++ ) {
        !           459: #if 0
        !           460:                if ( !(i % 1000) )
        !           461:                fprintf(stderr,"i=%d\n",i);
        !           462: #endif
        !           463:                t = i>>20; b0 = nbits[t];
        !           464:                if ( !b0 )
        !           465:                        continue;
        !           466:                for ( j = 1; j < 6; j++ ) {
        !           467:                        t = (i>>(20-4*j))&0xf;
        !           468:                        if ( nbits[t] != b0 )
        !           469:                                break;
        !           470:                }
        !           471:                if ( j != 6 )
        !           472:                        continue;
        !           473:                for ( j = k = 0; j < 24; j++ )
        !           474:                        if ( i & (1<<(23-j)) )
        !           475:                                win[k++] = j;
        !           476:                if ( dtestmain(g,csum,wlist,k,win,&factor,&cofactor) ) {
        !           477: #if 0
        !           478:                        fprintf(stderr,"success : i=%d\n",i);
        !           479: #endif
        !           480:                        *pr = factor; return;
        !           481:                }
        !           482:        }
        !           483:        *pr = f;
        !           484: }
        !           485:
        !           486: void hensel_special(index,count,f,mfl,listp)
        !           487: int index,count;
        !           488: P f;
        !           489: P *mfl;
        !           490: ML *listp;
        !           491: {
        !           492:        register int i,j;
        !           493:        int q,n,t,d,r,u,br,tmp,bound;
        !           494:        int *c,*p,*m,*w;
        !           495:        int **pp;
        !           496:        DCP dc;
        !           497:        ML blist,clist,bqlist,cqlist,rlist;
        !           498:        UM *b;
        !           499:        LUM fl,tl;
        !           500:        LUM *l;
        !           501:
        !           502:        blist = MLALLOC(24); blist->n = 24; blist->mod = 5;
        !           503:        for ( i = 0; i < 24; i++ ) {
        !           504:                blist->c[i] = (pointer)UMALLOC(7);
        !           505:                ptoum(5,mfl[i],blist->c[i]);
        !           506:        }
        !           507:        gcdgen(f,blist,&clist); henprep(f,blist,clist,&bqlist,&cqlist);
        !           508:        n = bqlist->n; q = bqlist->mod;
        !           509:        bqlist->bound = cqlist->bound = bound = mignotte(q,f);
        !           510:        if ( bound == 1 ) {
        !           511:                *listp = rlist = MLALLOC(n);
        !           512:                rlist->n = n; rlist->mod = q; rlist->bound = bound;
        !           513:                for ( i = 0, b = (UM *)bqlist->c, l = (LUM *)rlist->c; i < n; i++ ) {
        !           514:                        tl = LUMALLOC(DEG(b[i]),1); l[i] = tl; p = COEF(b[i]);
        !           515:                        for ( j = 0, pp = COEF(tl); j <= DEG(tl); j++ )
        !           516:                                        pp[j][0] = p[j];
        !           517:                }
        !           518:        } else {
        !           519:                W_LUMALLOC(UDEG(f),bound,fl);
        !           520:                ptolum(q,bound,f,fl); henmain(fl,bqlist,cqlist,listp);
        !           521:        }
        !           522: }
        !           523: #endif
        !           524:
        !           525: void Pftest(arg,rp)
        !           526: NODE arg;
        !           527: P *rp;
        !           528: {
        !           529:        ML list;
        !           530:        P p;
        !           531:        P *mfl;
        !           532:
        !           533:        p = (P)ARG0(arg); mfl = (P *)(((VECT)ARG1(arg))->body);
        !           534:        hensel_special(5,1,p,mfl,&list);
        !           535:        dtest_special(p,list,rp);
        !           536: }
        !           537:
        !           538: int nbits(a)
        !           539: int a;
        !           540: {
        !           541:        int i,s;
        !           542:
        !           543:        for ( i = 0, s = 0; a && (i < 20); i++, a >>= 1 )
        !           544:                if ( a & 1 ) s++;
        !           545:        return s;
        !           546: }
        !           547:
        !           548: void dtest_special(f,list,pr)
        !           549: P f;
        !           550: ML list;
        !           551: P *pr;
        !           552: {
        !           553:        int n,np,bound,q;
        !           554:        int i,j,k,b0;
        !           555:        int *win;
        !           556:        P g,factor,cofactor;
        !           557:        Q csum,csumt;
        !           558:        LUM *c;
        !           559:        ML wlist;
        !           560:
        !           561:        n = UDEG(f); np = list->n; bound = list->bound; q = list->mod;
        !           562:        win = W_ALLOC(np+1);
        !           563:        ucsump(f,&csum); mulq(csum,(Q)COEF(DC(f)),&csumt); csum = csumt;
        !           564:        wlist = W_MLALLOC(np); wlist->n = list->n;
        !           565:        wlist->mod = list->mod; wlist->bound = list->bound;
        !           566:        c = (LUM *)COEF(wlist); bcopy((char *)COEF(list),(char *)c,(int)(sizeof(LUM)*np));
        !           567:        for ( g = f, i = 0; i < (1<<19); i++ ) {
        !           568: #if 0
        !           569:                if ( !(i % 10000) )
        !           570:                fprintf(stderr,"i=%d\n",i);
        !           571: #endif
        !           572:                b0 = nbits(i>>10);
        !           573:                if ( !b0 || (nbits(i&0x3ff) != b0) )
        !           574:                        continue;
        !           575:                for ( j = k = 0; j < 20; j++ )
        !           576:                        if ( i & (1<<(19-j)) )
        !           577:                                win[k++] = j;
        !           578:                if ( dtestmain(g,csum,wlist,k,win,&factor,&cofactor) ) {
        !           579: #if 0
        !           580:                        fprintf(stderr,"success : i=%d\n",i);
        !           581: #endif
        !           582:                        *pr = factor; return;
        !           583:                }
        !           584:        }
        !           585:        *pr = f;
        !           586: }
        !           587:
        !           588: void hensel_special(index,count,f,mfl,listp)
        !           589: int index,count;
        !           590: P f;
        !           591: P *mfl;
        !           592: ML *listp;
        !           593: {
        !           594:        register int i,j;
        !           595:        int q,n,bound;
        !           596:        int *p;
        !           597:        int **pp;
        !           598:        ML blist,clist,bqlist,cqlist,rlist;
        !           599:        UM *b;
        !           600:        LUM fl,tl;
        !           601:        LUM *l;
        !           602:
        !           603:        blist = MLALLOC(20); blist->n = 20; blist->mod = 11;
        !           604:        for ( i = 0; i < 20; i++ ) {
        !           605:                blist->c[i] = (pointer)UMALLOC(10);
        !           606:                ptoum(11,mfl[i],blist->c[i]);
        !           607:        }
        !           608:        gcdgen(f,blist,&clist); henprep(f,blist,clist,&bqlist,&cqlist);
        !           609:        n = bqlist->n; q = bqlist->mod;
        !           610:        bqlist->bound = cqlist->bound = bound = mignotte(q,f);
        !           611:        if ( bound == 1 ) {
        !           612:                *listp = rlist = MLALLOC(n);
        !           613:                rlist->n = n; rlist->mod = q; rlist->bound = bound;
        !           614:                for ( i = 0, b = (UM *)bqlist->c, l = (LUM *)rlist->c; i < n; i++ ) {
        !           615:                        tl = LUMALLOC(DEG(b[i]),1); l[i] = tl; p = COEF(b[i]);
        !           616:                        for ( j = 0, pp = COEF(tl); j <= DEG(tl); j++ )
        !           617:                                        pp[j][0] = p[j];
        !           618:                }
        !           619:        } else {
        !           620:                W_LUMALLOC((int)UDEG(f),bound,fl);
        !           621:                ptolum(q,bound,f,fl); henmain(fl,bqlist,cqlist,listp);
        !           622:        }
        !           623: }
        !           624:
        !           625: void Pnullspace(arg,rp)
        !           626: NODE arg;
        !           627: LIST *rp;
        !           628: {
        !           629:        int i,j,n,mod;
        !           630:        MAT mat,r;
        !           631:        VECT u;
        !           632:        V v;
        !           633:        P p,z;
        !           634:        Q q;
        !           635:        UM **w;
        !           636:        UM mp;
        !           637:        P *t;
        !           638:        UM *s;
        !           639:        int *ind;
        !           640:        NODE n0,n1;
        !           641:
        !           642:        mat = (MAT)ARG0(arg);
        !           643:        p = (P)ARG1(arg);
        !           644:        v = VR(p);
        !           645:        mod = QTOS((Q)ARG2(arg));
        !           646:        n = mat->row;
        !           647:        w = (UM **)almat_pointer(n,n);
        !           648:        for ( i = 0; i < n; i++ )
        !           649:                for ( j = 0, t = (P *)mat->body[i], s = w[i]; j < n; j++ ) {
        !           650:                        ptomp(mod,t[j],&z);
        !           651:                        s[j] = W_UMALLOC((z&&!NUM(z))?UDEG(z):0);
        !           652:                        mptoum(z,s[j]);
        !           653:                }
        !           654:        mp = W_UMALLOC(UDEG(p)); ptoum(mod,p,mp);
        !           655:        ind = (int *)ALLOCA(n*sizeof(int));
        !           656:        nullspace(w,mp,mod,n,ind);
        !           657:        MKMAT(r,n,n);
        !           658:        for ( i = 0; i < n; i++ )
        !           659:                for ( j = 0, t = (P *)r->body[i], s = w[i]; j < n; j++ )
        !           660:                        umtop(v,s[j],&t[j]);
        !           661:        MKVECT(u,n);
        !           662:        for ( i = 0; i < n; i++ ) {
        !           663:                STOQ(ind[i],q); u->body[i] = (pointer)q;
        !           664:        }
        !           665:        MKNODE(n1,u,0); MKNODE(n0,r,n1); MKLIST(*rp,n0);
        !           666: }
        !           667:
        !           668: void nullspace(mat,p,mod,n,ind)
        !           669: UM **mat;
        !           670: UM p;
        !           671: int mod,n;
        !           672: int *ind;
        !           673: {
        !           674:        int i,j,l,s,d;
        !           675:        UM q,w,w1,h,inv;
        !           676:        UM *t,*u;
        !           677:
        !           678:        d = DEG(p); inv = W_UMALLOC(d); q = W_UMALLOC(2*d);
        !           679:        w = W_UMALLOC(2*d); w1 = W_UMALLOC(2*d); h = W_UMALLOC(d);
        !           680:        bzero(ind,n*sizeof(int));
        !           681:        ind[0] = 0;
        !           682:        for ( i = j = 0; j < n; i++, j++ ) {
        !           683:                for ( ; j < n; j++ ) {
        !           684:                        for ( l = i; l < n; l++ )
        !           685:                                if ( DEG(mat[l][j])>=0 )
        !           686:                                        break;
        !           687:                        if ( l < n ) {
        !           688:                                t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
        !           689:                        } else
        !           690:                                ind[j] = 1;
        !           691:                }
        !           692:                if ( j == n )
        !           693:                        break;
        !           694:                invum(mod,p,mat[i][j],inv);
        !           695:                for ( s = j, t = mat[i]; s < n; s++ ) {
        !           696:                        mulum(mod,t[s],inv,w);
        !           697:                        DEG(w) = divum(mod,w,p,q);
        !           698:                        cpyum(w,t[s]);
        !           699:                }
        !           700:                for ( l = 0; l < n; l++ ) {
        !           701:                        if ( l == i )
        !           702:                                continue;
        !           703:                        u = mat[l]; DEG(w) = -1; subum(mod,w,u[j],h);
        !           704:                        for ( s = j; s < n; s++ ) {
        !           705:                                mulum(mod,h,t[s],w); addum(mod,w,u[s],w1);
        !           706:                                DEG(w1) = divum(mod,w1,p,q); cpyum(w1,u[s]);
        !           707:                        }
        !           708:                }
        !           709:        }
        !           710: }
        !           711:
        !           712: void Pnullspace_ff(arg,rp)
        !           713: NODE arg;
        !           714: LIST *rp;
        !           715: {
        !           716:        int i,j,n;
        !           717:        Q mod;
        !           718:        MAT mat,r;
        !           719:        VECT u;
        !           720:        Q q;
        !           721:        Obj **w;
        !           722:        Obj *t;
        !           723:        Obj *s;
        !           724:        int *ind;
        !           725:        NODE n0,n1;
        !           726:
        !           727:        mat = (MAT)ARG0(arg);
        !           728:        n = mat->row;
        !           729:        w = (Obj **)almat_pointer(n,n);
        !           730:        for ( i = 0; i < n; i++ )
        !           731:                for ( j = 0, t = (Obj *)mat->body[i], s = w[i]; j < n; j++ )
        !           732:                        s[j] = t[j];
        !           733:        ind = (int *)ALLOCA(n*sizeof(int));
        !           734:        switch ( current_ff ) {
        !           735:                case FF_GFP:
        !           736:                        nullspace_lm((LM **)w,n,ind); break;
        !           737:                case FF_GF2N:
        !           738:                        nullspace_gf2n((GF2N **)w,n,ind); break;
        !           739:                case FF_GFPN:
        !           740:                        nullspace_gfpn((GFPN **)w,n,ind); break;
        !           741:                default:
        !           742:                        error("nullspace_ff : current_ff is not set");
        !           743:        }
        !           744:        MKMAT(r,n,n);
        !           745:        for ( i = 0; i < n; i++ )
        !           746:                for ( j = 0, t = (Obj *)r->body[i], s = w[i]; j < n; j++ )
        !           747:                        t[j] = s[j];
        !           748:        MKVECT(u,n);
        !           749:        for ( i = 0; i < n; i++ ) {
        !           750:                STOQ(ind[i],q); u->body[i] = (pointer)q;
        !           751:        }
        !           752:        MKNODE(n1,u,0); MKNODE(n0,r,n1); MKLIST(*rp,n0);
        !           753: }
        !           754:
        !           755: void nullspace_lm(mat,n,ind)
        !           756: LM **mat;
        !           757: int n;
        !           758: int *ind;
        !           759: {
        !           760:        int i,j,l,s;
        !           761:        Q q,mod;
        !           762:        N lm;
        !           763:        LM w,w1,h,inv;
        !           764:        LM *t,*u;
        !           765:
        !           766:        getmod_lm(&lm); NTOQ(lm,1,mod);
        !           767:
        !           768:        bzero(ind,n*sizeof(int));
        !           769:        ind[0] = 0;
        !           770:        for ( i = j = 0; j < n; i++, j++ ) {
        !           771:                for ( ; j < n; j++ ) {
        !           772:                        for ( l = i; l < n; l++ ) {
        !           773:                                simplm(mat[l][j],&w); mat[l][j] = w;
        !           774:                                if ( mat[l][j] )
        !           775:                                        break;
        !           776:                        }
        !           777:                        if ( l < n ) {
        !           778:                                t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
        !           779:                        } else
        !           780:                                ind[j] = 1;
        !           781:                }
        !           782:                if ( j == n )
        !           783:                        break;
        !           784:                NTOQ(mat[i][j]->body,1,q); invl(q,mod,(Q *)&inv);
        !           785:                for ( s = j, t = mat[i]; s < n; s++ ) {
        !           786:                        mullm(t[s],inv,&w); t[s] = w;
        !           787:                }
        !           788:                for ( l = 0; l < n; l++ ) {
        !           789:                        if ( l == i )
        !           790:                                continue;
        !           791:                        u = mat[l]; chsgnlm(u[j],&h);
        !           792:                        for ( s = j; s < n; s++ ) {
        !           793:                                mullm(h,t[s],&w); addlm(w,u[s],&w1); u[s] = w1;
        !           794:                        }
        !           795:                }
        !           796:        }
        !           797: }
        !           798:
        !           799: void nullspace_gf2n(mat,n,ind)
        !           800: GF2N **mat;
        !           801: int n;
        !           802: int *ind;
        !           803: {
        !           804:        int i,j,l,s;
        !           805:        GF2N w,w1,h,inv;
        !           806:        GF2N *t,*u;
        !           807:        extern gf2n_lazy;
        !           808:
        !           809:        bzero(ind,n*sizeof(int));
        !           810:        ind[0] = 0;
        !           811:        for ( i = j = 0; j < n; i++, j++ ) {
        !           812:                for ( ; j < n; j++ ) {
        !           813:                        for ( l = i; l < n; l++ ) {
        !           814:                                simpgf2n(mat[l][j],&w); mat[l][j] = w;
        !           815:                                if ( mat[l][j] )
        !           816:                                        break;
        !           817:                        }
        !           818:                        if ( l < n ) {
        !           819:                                t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
        !           820:                        } else
        !           821:                                ind[j] = 1;
        !           822:                }
        !           823:                if ( j == n )
        !           824:                        break;
        !           825:                invgf2n(mat[i][j],&inv);
        !           826:                for ( s = j, t = mat[i]; s < n; s++ ) {
        !           827:                        mulgf2n(t[s],inv,&w); t[s] = w;
        !           828:                }
        !           829:                for ( l = 0; l < n; l++ ) {
        !           830:                        if ( l == i )
        !           831:                                continue;
        !           832:                        u = mat[l]; h = u[j];
        !           833:                        for ( s = j; s < n; s++ ) {
        !           834:                                mulgf2n(h,t[s],&w); addgf2n(w,u[s],&w1); u[s] = w1;
        !           835:                        }
        !           836:                }
        !           837:        }
        !           838: }
        !           839:
        !           840: void nullspace_gfpn(mat,n,ind)
        !           841: GFPN **mat;
        !           842: int n;
        !           843: int *ind;
        !           844: {
        !           845:        int i,j,l,s;
        !           846:        GFPN w,w1,h,inv;
        !           847:        GFPN *t,*u;
        !           848:
        !           849:        bzero(ind,n*sizeof(int));
        !           850:        ind[0] = 0;
        !           851:        for ( i = j = 0; j < n; i++, j++ ) {
        !           852:                for ( ; j < n; j++ ) {
        !           853:                        for ( l = i; l < n; l++ ) {
        !           854:                                simpgfpn(mat[l][j],&w); mat[l][j] = w;
        !           855:                                if ( mat[l][j] )
        !           856:                                        break;
        !           857:                        }
        !           858:                        if ( l < n ) {
        !           859:                                t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
        !           860:                        } else
        !           861:                                ind[j] = 1;
        !           862:                }
        !           863:                if ( j == n )
        !           864:                        break;
        !           865:                divgfpn((GFPN)ONE,(GFPN)mat[i][j],&inv);
        !           866:                for ( s = j, t = mat[i]; s < n; s++ ) {
        !           867:                        mulgfpn(t[s],inv,&w); t[s] = w;
        !           868:                }
        !           869:                for ( l = 0; l < n; l++ ) {
        !           870:                        if ( l == i )
        !           871:                                continue;
        !           872:                        u = mat[l]; chsgngfpn(u[j],&h);
        !           873:                        for ( s = j; s < n; s++ ) {
        !           874:                                mulgfpn(h,t[s],&w); addgfpn(w,u[s],&w1); u[s] = w1;
        !           875:                        }
        !           876:                }
        !           877:        }
        !           878: }
        !           879: /* p = a(0)vl[0]+a(1)vl[1]+...+a(m-1)vl[m-1]+a(m) -> array = [a(0) a(1) ... a(m)] */
        !           880:
        !           881: void linear_form_to_array(p,vl,m,array)
        !           882: P p;
        !           883: VL vl;
        !           884: int m;
        !           885: Num *array;
        !           886: {
        !           887:        int i;
        !           888:        DCP dc;
        !           889:
        !           890:        bzero((char *)array,(m+1)*sizeof(Num *));
        !           891:        for ( i = 0; p && vl; vl = NEXT(vl), i++ ) {
        !           892:                if ( ID(p) == O_N )
        !           893:                        break;
        !           894:                else if ( VR(p) == vl->v ) {
        !           895:                        dc = DC(p);
        !           896:                        array[i] = (Num)COEF(dc);
        !           897:                        dc = NEXT(dc);
        !           898:                        p = dc ? COEF(dc) : 0;
        !           899:                }
        !           900:        }
        !           901:        array[m] = (Num)p;
        !           902: }
        !           903:
        !           904: void array_to_linear_form(array,vl,m,r)
        !           905: Num *array;
        !           906: VL vl;
        !           907: int m;
        !           908: P *r;
        !           909: {
        !           910:        P t;
        !           911:        DCP dc0,dc1;
        !           912:
        !           913:        if ( !m )
        !           914:                *r = (P)array[0];
        !           915:        else {
        !           916:                array_to_linear_form(array+1,NEXT(vl),m-1,&t);
        !           917:                if ( !array[0] )
        !           918:                        *r = t;
        !           919:                else {
        !           920:                        NEWDC(dc0); DEG(dc0) = ONE; COEF(dc0) = (P)array[0];
        !           921:                        if ( !t )
        !           922:                                NEXT(dc0) = 0;
        !           923:                        else {
        !           924:                                NEWDC(dc1); DEG(dc1) = 0; COEF(dc1) = t;
        !           925:                                NEXT(dc1) = 0;
        !           926:                                NEXT(dc0) = dc1;
        !           927:                        }
        !           928:                        MKP(vl->v,dc0,*r);
        !           929:                }
        !           930:        }
        !           931: }
        !           932:
        !           933: void Psolve_linear_equation_gf2n(arg,rp)
        !           934: NODE arg;
        !           935: LIST *rp;
        !           936: {
        !           937:        NODE eqs,tn;
        !           938:        VL vars,tvl;
        !           939:        int i,j,n,m,dim,codim;
        !           940:        GF2N **w;
        !           941:        int *ind;
        !           942:        NODE n0,n1;
        !           943:
        !           944:        get_vars(ARG0(arg),&vars);
        !           945:        eqs = BDY((LIST)ARG0(arg));
        !           946:        for ( n = 0, tn = eqs; tn; tn = NEXT(tn), n++);
        !           947:        for ( m = 0, tvl = vars; tvl; tvl = NEXT(tvl), m++);
        !           948:        w = (GF2N **)almat_pointer(n,m+1);
        !           949:        for ( i = 0, tn = eqs; i < n; i++, tn = NEXT(tn) )
        !           950:                linear_form_to_array(BDY(tn),vars,m,(Num *)w[i]);
        !           951:        ind = (int *)ALLOCA(m*sizeof(int));
        !           952:        solve_linear_equation_gf2n(w,n,m,ind);
        !           953:        for ( j = 0, dim = 0; j < m; j++ )
        !           954:                if ( ind[j] )
        !           955:                        dim++;
        !           956:        codim = m-dim;
        !           957:        for ( i = codim; i < n; i++ )
        !           958:                if ( w[i][m] ) {
        !           959:                        MKLIST(*rp,0); return;
        !           960:                }
        !           961:        for ( i = 0, n0 = 0; i < codim; i++ ) {
        !           962:                NEXTNODE(n0,n1);
        !           963:                array_to_linear_form((Num *)w[i],vars,m,(P *)&BDY(n1));
        !           964:        }
        !           965:        if ( n0 )
        !           966:                NEXT(n1) = 0;
        !           967:        MKLIST(*rp,n0);
        !           968: }
        !           969:
        !           970: void solve_linear_equation_gf2n(mat,n,m,ind)
        !           971: GF2N **mat;
        !           972: int n;
        !           973: int *ind;
        !           974: {
        !           975:        int i,j,l,s;
        !           976:        GF2N w,w1,h,inv;
        !           977:        GF2N *t,*u;
        !           978:        extern gf2n_lazy;
        !           979:
        !           980:        bzero(ind,m*sizeof(int));
        !           981:        ind[0] = 0;
        !           982:        for ( i = j = 0; j < m; i++, j++ ) {
        !           983:                for ( ; j < m; j++ ) {
        !           984:                        for ( l = i; l < n; l++ ) {
        !           985:                                simpgf2n(mat[l][j],&w); mat[l][j] = w;
        !           986:                                if ( mat[l][j] )
        !           987:                                        break;
        !           988:                        }
        !           989:                        if ( l < n ) {
        !           990:                                t = mat[i]; mat[i] = mat[l]; mat[l] = t; break;
        !           991:                        } else
        !           992:                                ind[j] = 1;
        !           993:                }
        !           994:                if ( j == m )
        !           995:                        break;
        !           996:                invgf2n(mat[i][j],&inv);
        !           997:                for ( s = j, t = mat[i]; s <= m; s++ ) {
        !           998:                        mulgf2n(t[s],inv,&w); t[s] = w;
        !           999:                }
        !          1000:                for ( l = 0; l < n; l++ ) {
        !          1001:                        if ( l == i )
        !          1002:                                continue;
        !          1003:                        u = mat[l]; h = u[j];
        !          1004:                        for ( s = j; s <= m; s++ ) {
        !          1005:                                mulgf2n(h,t[s],&w); addgf2n(w,u[s],&w1); u[s] = w1;
        !          1006:                        }
        !          1007:                }
        !          1008:        }
        !          1009: }
        !          1010:
        !          1011: /*
        !          1012: void null_to_sol(mat,ind,mod,n,r)
        !          1013: int **mat;
        !          1014: int *ind;
        !          1015: int mod,n;
        !          1016: UM *r;
        !          1017: {
        !          1018:        int i,j,k,l;
        !          1019:        int *c;
        !          1020:        UM w;
        !          1021:
        !          1022:        for ( i = 0, l = 0; i < n; i++ ) {
        !          1023:                if ( !ind[i] )
        !          1024:                        continue;
        !          1025:                w = UMALLOC(n);
        !          1026:                for ( j = k = 0, c = COEF(w); j < n; j++ )
        !          1027:                        if ( ind[j] )
        !          1028:                                c[j] = 0;
        !          1029:                        else
        !          1030:                                c[j] = mat[k++][i];
        !          1031:                c[i] = mod-1;
        !          1032:                for ( j = n; j >= 0; j-- )
        !          1033:                        if ( c[j] )
        !          1034:                                break;
        !          1035:                DEG(w) = j;
        !          1036:                r[l++] = w;
        !          1037:        }
        !          1038: }
        !          1039: */
        !          1040:
        !          1041: void showgfmat(mat,n)
        !          1042: UM **mat;
        !          1043: int n;
        !          1044: {
        !          1045:        int i,j,k;
        !          1046:        int *c;
        !          1047:        UM p;
        !          1048:
        !          1049:        for ( i = 0; i < n; i++ ) {
        !          1050:                for ( j = 0; j < n; j++ ) {
        !          1051:                        p = mat[i][j];
        !          1052:                        if ( DEG(p) < 0 )
        !          1053:                                fprintf(asir_out,"0");
        !          1054:                        else
        !          1055:                                for ( p = mat[i][j], k = DEG(p), c = COEF(p); k >= 0; k-- ) {
        !          1056:                                        if ( c[k] )
        !          1057:                                                fprintf(asir_out,"+%d",c[k]);
        !          1058:                                        if ( k > 1 )
        !          1059:                                                fprintf(asir_out,"a^%d",k);
        !          1060:                                        else if ( k == 1 )
        !          1061:                                                fprintf(asir_out,"a",k);
        !          1062:                                }
        !          1063:                        fprintf(asir_out," ");
        !          1064:                }
        !          1065:                fprintf(asir_out,"\n");
        !          1066:        }
        !          1067: }
        !          1068:
        !          1069: #if 0
        !          1070: void Pgcda_mod(arg,rp)
        !          1071: NODE arg;
        !          1072: P *rp;
        !          1073: {
        !          1074:        p1 = (P)ARG0(arg);
        !          1075:        p2 = (P)ARG1(arg);
        !          1076:        v = VR((P)ARG2(arg));
        !          1077:        d = (P)ARG3(arg);
        !          1078:        m = QTOS((Q)ARG4(arg));
        !          1079:        reordvar(CO,v,&vl);
        !          1080:        reorderp(vl,CO,p1,&t); ptomp(m,t,&m1);
        !          1081:        reorderp(vl,CO,p2,&t); ptomp(m,t,&m2);
        !          1082:        if ( NUM(m1) || NUM(m2) || VR(m1) != v || VR(m2) != v ) {
        !          1083:                *rp = ONE; return;
        !          1084:        }
        !          1085:        if ( deg(v,m1) >= deg(v,m2) ) {
        !          1086:                t = m1; m1 = m2; m2 = t;
        !          1087:        }
        !          1088:        while ( 1 ) {
        !          1089:                inva_mod(COEF(DC(m2)),d,m,&inv);
        !          1090:                NEWDC(dc); NEXT(dc) = 0; MKP(v,dc,h);
        !          1091:                d0 = deg(v,m1)-deg(v,m2); STOQ(d0,DEG(dc));
        !          1092:                mulgq(m,d,inv,COEF(DC(m1)),&COEF(dc));
        !          1093:                mulgp(vl,m,d,m2,h,&t); subgp(vl,m,d,m1,t,&s);
        !          1094:        }
        !          1095: }
        !          1096: #endif
        !          1097:
        !          1098: void Ppwr_mod(arg,rp)
        !          1099: NODE arg;
        !          1100: P *rp;
        !          1101: {
        !          1102:        P p,a,d,r;
        !          1103:        int m;
        !          1104:        Q q;
        !          1105:        N n;
        !          1106:
        !          1107:        m = QTOS((Q)ARG4(arg)); q = (Q)ARG5(arg); n = q ? NM(q) : 0;
        !          1108:        ptomp(m,(P)ARG0(arg),&p); ptomp(m,(P)ARG1(arg),&a);
        !          1109:        ptomp(m,(P)ARG3(arg),&d);
        !          1110:        pwr_mod(p,a,VR((P)ARG2(arg)),d,m,n,&r);
        !          1111:        mptop(r,rp);
        !          1112: }
        !          1113:
        !          1114: void pwr_mod(p,a,v,d,m,n,rp)
        !          1115: P p,a,d;
        !          1116: V v;
        !          1117: int m;
        !          1118: N n;
        !          1119: P *rp;
        !          1120: {
        !          1121:        int b;
        !          1122:        P t,s,r;
        !          1123:        N n1;
        !          1124:
        !          1125:        if ( !n )
        !          1126:                *rp = (P)ONEM;
        !          1127:        else if ( UNIN(n) )
        !          1128:                *rp = p;
        !          1129:        else {
        !          1130:                b = divin(n,2,&n1);
        !          1131:                pwr_mod(p,a,v,d,m,n1,&t);
        !          1132:                mulmp(CO,m,t,t,&s); rem_mod(s,a,v,d,m,&r);
        !          1133:                if ( b ) {
        !          1134:                        mulmp(CO,m,r,p,&t); rem_mod(t,a,v,d,m,rp);
        !          1135:                } else
        !          1136:                        *rp = r;
        !          1137:        }
        !          1138: }
        !          1139:
        !          1140: void rem_mod(p,a,v,d,m,rp)
        !          1141: P p,a,d;
        !          1142: V v;
        !          1143: int m;
        !          1144: P *rp;
        !          1145: {
        !          1146:        P tmp,r1,r2;
        !          1147:
        !          1148:        divsrmp(CO,m,p,d,&tmp,&r1);
        !          1149:        divsrmp(CO,m,r1,a,&tmp,&r2);
        !          1150:        divsrmp(CO,m,r2,d,&tmp,rp);
        !          1151: }

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