[BACK]Return to gr CVS log [TXT][DIR] Up to [local] / OpenXM_contrib2 / asir2000 / lib

Annotation of OpenXM_contrib2/asir2000/lib/gr, Revision 1.27

1.5       noro        1: /*
                      2:  * Copyright (c) 1994-2000 FUJITSU LABORATORIES LIMITED
                      3:  * All rights reserved.
                      4:  *
                      5:  * FUJITSU LABORATORIES LIMITED ("FLL") hereby grants you a limited,
                      6:  * non-exclusive and royalty-free license to use, copy, modify and
                      7:  * redistribute, solely for non-commercial and non-profit purposes, the
                      8:  * computer program, "Risa/Asir" ("SOFTWARE"), subject to the terms and
                      9:  * conditions of this Agreement. For the avoidance of doubt, you acquire
                     10:  * only a limited right to use the SOFTWARE hereunder, and FLL or any
                     11:  * third party developer retains all rights, including but not limited to
                     12:  * copyrights, in and to the SOFTWARE.
                     13:  *
                     14:  * (1) FLL does not grant you a license in any way for commercial
                     15:  * purposes. You may use the SOFTWARE only for non-commercial and
                     16:  * non-profit purposes only, such as academic, research and internal
                     17:  * business use.
                     18:  * (2) The SOFTWARE is protected by the Copyright Law of Japan and
                     19:  * international copyright treaties. If you make copies of the SOFTWARE,
                     20:  * with or without modification, as permitted hereunder, you shall affix
                     21:  * to all such copies of the SOFTWARE the above copyright notice.
                     22:  * (3) An explicit reference to this SOFTWARE and its copyright owner
                     23:  * shall be made on your publication or presentation in any form of the
                     24:  * results obtained by use of the SOFTWARE.
                     25:  * (4) In the event that you modify the SOFTWARE, you shall notify FLL by
1.6       noro       26:  * e-mail at risa-admin@sec.flab.fujitsu.co.jp of the detailed specification
1.5       noro       27:  * for such modification or the source code of the modified part of the
                     28:  * SOFTWARE.
                     29:  *
                     30:  * THE SOFTWARE IS PROVIDED AS IS WITHOUT ANY WARRANTY OF ANY KIND. FLL
                     31:  * MAKES ABSOLUTELY NO WARRANTIES, EXPRESSED, IMPLIED OR STATUTORY, AND
                     32:  * EXPRESSLY DISCLAIMS ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS
                     33:  * FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT OF THIRD PARTIES'
                     34:  * RIGHTS. NO FLL DEALER, AGENT, EMPLOYEES IS AUTHORIZED TO MAKE ANY
                     35:  * MODIFICATIONS, EXTENSIONS, OR ADDITIONS TO THIS WARRANTY.
                     36:  * UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, TORT, CONTRACT,
                     37:  * OR OTHERWISE, SHALL FLL BE LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
                     38:  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, PUNITIVE OR CONSEQUENTIAL
                     39:  * DAMAGES OF ANY CHARACTER, INCLUDING, WITHOUT LIMITATION, DAMAGES
                     40:  * ARISING OUT OF OR RELATING TO THE SOFTWARE OR THIS AGREEMENT, DAMAGES
                     41:  * FOR LOSS OF GOODWILL, WORK STOPPAGE, OR LOSS OF DATA, OR FOR ANY
                     42:  * DAMAGES, EVEN IF FLL SHALL HAVE BEEN INFORMED OF THE POSSIBILITY OF
                     43:  * SUCH DAMAGES, OR FOR ANY CLAIM BY ANY OTHER PARTY. EVEN IF A PART
                     44:  * OF THE SOFTWARE HAS BEEN DEVELOPED BY A THIRD PARTY, THE THIRD PARTY
                     45:  * DEVELOPER SHALL HAVE NO LIABILITY IN CONNECTION WITH THE USE,
                     46:  * PERFORMANCE OR NON-PERFORMANCE OF THE SOFTWARE.
                     47:  *
1.27    ! ohara      48:  * $OpenXM: OpenXM_contrib2/asir2000/lib/gr,v 1.26 2007/07/17 08:17:42 noro Exp $
1.5       noro       49: */
1.19      takayama   50:
                     51: module gr $
                     52:   /* Empty for now.  It will be used in a future. */
                     53: endmodule $
                     54:
1.1       noro       55: extern INIT_COUNT,ITOR_FAIL$
                     56: extern REMOTE_MATRIX,REMOTE_NF,REMOTE_VARS$
                     57:
                     58: #define MAX(a,b) ((a)>(b)?(a):(b))
                     59: #define HigherDim 0
                     60: #define ZeroDim   1
                     61: #define MiniPoly  2
                     62:
                     63: /* toplevel functions for Groebner basis computation */
                     64:
                     65: def gr(B,V,O)
                     66: {
1.27    ! ohara      67:        Ord=dp_ord();
1.1       noro       68:        G = dp_gr_main(B,V,0,1,O);
1.27    ! ohara      69:        dp_ord(Ord);
1.1       noro       70:        return G;
                     71: }
                     72:
                     73: def hgr(B,V,O)
                     74: {
1.27    ! ohara      75:        Ord=dp_ord();
1.1       noro       76:        G = dp_gr_main(B,V,1,1,O);
1.27    ! ohara      77:        dp_ord(Ord);
1.1       noro       78:        return G;
                     79: }
                     80:
                     81: def gr_mod(B,V,O,M)
                     82: {
1.27    ! ohara      83:        Ord=dp_ord();
1.1       noro       84:        G = dp_gr_mod_main(B,V,0,M,O);
1.27    ! ohara      85:        dp_ord(Ord);
1.1       noro       86:        return G;
                     87: }
                     88:
                     89: def hgr_mod(B,V,O,M)
                     90: {
1.27    ! ohara      91:        Ord=dp_ord();
1.1       noro       92:        G = dp_gr_mod_main(B,V,1,M,O);
1.27    ! ohara      93:        dp_ord(Ord);
1.1       noro       94:        return G;
                     95: }
                     96:
                     97: /* toplevel functions for change-of-ordering */
                     98:
                     99: def lex_hensel(B,V,O,W,H)
                    100: {
                    101:        G = dp_gr_main(B,V,H,1,O);
                    102:        return tolex(G,V,O,W);
                    103: }
                    104:
                    105: def lex_hensel_gsl(B,V,O,W,H)
                    106: {
                    107:        G = dp_gr_main(B,V,H,1,O);
                    108:        return tolex_gsl(G,V,O,W);
                    109: }
                    110:
                    111: def gr_minipoly(B,V,O,P,V0,H)
                    112: {
                    113:        G = dp_gr_main(B,V,H,1,O);
                    114:        return minipoly(G,V,O,P,V0);
                    115: }
                    116:
                    117: def lex_tl(B,V,O,W,H)
                    118: {
                    119:        G = dp_gr_main(B,V,H,1,O);
                    120:        return tolex_tl(G,V,O,W,H);
                    121: }
                    122:
                    123: def tolex_tl(G0,V,O,W,H)
                    124: {
                    125:        N = length(V); HM = hmlist(G0,V,O); ZD = zero_dim(HM,V,O);
                    126:        for ( I = 0; ; I++ ) {
                    127:                M = lprime(I);
                    128:                if ( !valid_modulus(HM,M) )
                    129:                        continue;
                    130:                if ( ZD ) {
                    131:                        if ( G3 = dp_gr_main(G0,W,H,-M,3) )
                    132:                                for ( J = 0; ; J++ )
                    133:                                        if ( G2 = dp_gr_main(G3,W,0,-lprime(J),2) )
                    134:                                                return G2;
                    135:                } else if ( G2 = dp_gr_main(G0,W,H,-M,2) )
                    136:                        return G2;
                    137:        }
                    138: }
                    139:
                    140: def tolex(G0,V,O,W)
                    141: {
1.17      noro      142:        Procs = getopt(procs);
                    143:
1.1       noro      144:        TM = TE = TNF = 0;
                    145:        N = length(V); HM = hmlist(G0,V,O); ZD = zero_dim(HM,V,O);
1.16      noro      146:        if ( ZD )
                    147:                MB = dp_mbase(map(dp_ptod,HM,V));
                    148:        else
                    149:                MB = 0;
1.1       noro      150:        for ( J = 0; ; J++ ) {
                    151:                M = lprime(J);
                    152:                if ( !valid_modulus(HM,M) )
                    153:                        continue;
1.16      noro      154:                T0 = time()[0];
                    155:                if ( ZD ) {
                    156:                        GM = tolexm(G0,V,O,W,M);
                    157:                        dp_ord(2);
                    158:                        DL = map(dp_etov,map(dp_ht,map(dp_ptod,GM,W)));
                    159:                        D = newvect(N); TL = [];
                    160:                        do
                    161:                                TL = cons(dp_dtop(dp_vtoe(D),W),TL);
                    162:                        while ( nextm(D,DL,N) );
                    163:                } else {
1.25      noro      164:                        HVN = "h";
                    165:                        WN = map(rtostr,W);
                    166:                        while ( member(HVN,WN) ) HVN += "h";
                    167:                        HV = strtov(HVN);
                    168:                        G0H = map(homogenize,G0,W,HV);
                    169:                        GMH = nd_gr(G0H,append(W,[HV]),M,1);
                    170:                        GMH=map(subst,GMH,HV,1);
                    171:                        GM = nd_gr_postproc(GMH,W,M,2,0);
1.16      noro      172:                        dp_ord(2);
                    173:                        for ( T = GM, S = 0; T != []; T = cdr(T) )
                    174:                                for ( D = dp_ptod(car(T),V); D; D = dp_rest(D) )
                    175:                                        S += dp_ht(D);
                    176:                        TL = dp_terms(S,V);
                    177:                }
                    178:                TM += time()[0] - T0;
                    179:                T0 = time()[0]; NF = gennf(G0,TL,V,O,W[N-1],ZD)[0];
1.1       noro      180:                TNF += time()[0] - T0;
                    181:                T0 = time()[0];
1.17      noro      182:                if ( type(Procs) != -1 )
                    183:                        R = tolex_d_main(V,O,NF,GM,M,MB,Procs);
                    184:                else
                    185:                        R = tolex_main(V,O,NF,GM,M,MB);
1.1       noro      186:                TE += time()[0] - T0;
                    187:                if ( R ) {
                    188:                        if ( dp_gr_print() )
                    189:                                print("mod="+rtostr(TM)+",nf="+rtostr(TNF)+",eq="+rtostr(TE));
                    190:                        return R;
                    191:                }
                    192:        }
                    193: }
                    194:
                    195: def tolex_gsl(G0,V,O,W)
                    196: {
                    197:        TM = TE = TNF = 0;
                    198:        N = length(V); HM = hmlist(G0,V,O); ZD = zero_dim(HM,V,O);
                    199:        MB = dp_mbase(map(dp_ptod,HM,V));
                    200:        if ( !ZD )
                    201:                error("tolex_gsl : ideal is not zero-dimensional!");
                    202:        for ( J = 0; ; J++ ) {
                    203:                M = lprime(J);
                    204:                if ( !valid_modulus(HM,M) )
                    205:                        continue;
                    206:                T0 = time()[0]; GM = tolexm(G0,V,O,W,M); TM += time()[0] - T0;
                    207:                dp_ord(2);
                    208:                DL = map(dp_etov,map(dp_ht,map(dp_ptod,GM,W)));
                    209:                D = newvect(N); TL = [];
                    210:                do
                    211:                        TL = cons(dp_dtop(dp_vtoe(D),W),TL);
                    212:                while ( nextm(D,DL,N) );
                    213:                L = npos_check(DL); NPOSV = L[0]; DIM = L[1];
                    214:                if ( NPOSV >= 0 ) {
1.25      noro      215:                        if ( dp_gr_print() ) print("shape base");
1.1       noro      216:                        V0 = W[NPOSV];
                    217:                        T0 = time()[0]; NFL = gennf(G0,TL,V,O,V0,1);
                    218:                        TNF += time()[0] - T0;
                    219:                        T0 = time()[0];
                    220:                        R = tolex_gsl_main(G0,V,O,W,NFL,NPOSV,GM,M,MB);
                    221:                        TE += time()[0] - T0;
                    222:                } else {
                    223:                        T0 = time()[0]; NF = gennf(G0,TL,V,O,W[N-1],1)[0];
                    224:                        TNF += time()[0] - T0;
                    225:                        T0 = time()[0];
                    226:                        R = tolex_main(V,O,NF,GM,M,MB);
                    227:                        TE += time()[0] - T0;
                    228:                }
                    229:                if ( R ) {
                    230:                        if ( dp_gr_print() )
                    231:                                print("mod="+rtostr(TM)+",nf="+rtostr(TNF)+",eq="+rtostr(TE));
                    232:                        return R;
                    233:                }
                    234:        }
                    235: }
                    236:
                    237: def termstomat(NF,TERMS,MB,MOD)
                    238: {
                    239:        DN = NF[1];
                    240:        NF = NF[0];
                    241:        N = length(MB);
                    242:        M = length(TERMS);
                    243:        MAT = newmat(N,M);
                    244:        W = newvect(N);
                    245:        Len = length(NF);
                    246:        for ( I = 0; I < M; I++ ) {
                    247:                T = TERMS[I];
                    248:                for ( K = 0; K < Len; K++ )
                    249:                        if ( T == NF[K][1] )
                    250:                                break;
                    251:                dptov(NF[K][0],W,MB);
                    252:                for ( J = 0; J < N; J++ )
                    253:                        MAT[J][I] = W[J];
                    254:        }
                    255:        return [henleq_prep(MAT,MOD),DN];
                    256: }
                    257:
                    258: def tolex_gsl_main(G0,V,O,W,NFL,NPOSV,GM,M,MB)
                    259: {
                    260:        NF = NFL[0]; PS = NFL[1]; GI = NFL[2];
                    261:        V0 = W[NPOSV]; N = length(W);
                    262:        DIM = length(MB);
                    263:        DV = newvect(DIM);
                    264:        TERMS = gather_terms(GM,W,M,NPOSV);
                    265:        Len = length(TERMS);
                    266:        dp_ord(O); RHS = termstomat(NF,map(dp_ptod,TERMS,V),MB,M);
                    267:        for ( T = GM; T != []; T = cdr(T) )
                    268:                if ( vars(car(T)) == [V0]       )
                    269:                        break;
                    270:        dp_ord(0); NHT = nf_tab_gsl(dp_ptod(V0^deg(car(T),V0),V),NF);
                    271:        dptov(NHT[0],DV,MB);
                    272:        B = hen_ttob_gsl([DV,NHT[1]],RHS,TERMS,M);
                    273:        if ( !B )
                    274:                return 0;
                    275:        for ( I = 0, U = B[1]*V0^deg(car(T),V0); I < Len; I++ )
                    276:                U += B[0][I]*TERMS[I];
                    277:        DN0 = diff(U,V0);
                    278:        dp_ord(O); DN0NF = nf_tab_gsl(dp_ptod(DN0,V),NF);
                    279:        SL = [[V0,U,DN0]];
                    280:        for ( I = N-1, LCM = 1; I >= 0; I-- ) {
                    281:                if ( I == NPOSV )
                    282:                        continue;
                    283:                V1 = W[I];
                    284:                dp_ord(O); L = nf(GI,DN0NF[0]*dp_ptod(-LCM*V1,V),DN0NF[1],PS);
                    285:                L = remove_cont(L);
                    286:                dptov(L[0],DV,MB);
                    287:                dp_ord(O); B = hen_ttob_gsl([DV,L[1]],RHS,TERMS,M);
                    288:                if ( !B )
                    289:                        return 0;
                    290:                for ( K = 0, R = 0; K < Len; K++ )
                    291:                        R += B[0][K]*TERMS[K];
                    292:                LCM *= B[1];
                    293:                SL = cons(cons(V1,[R,LCM]),SL);
1.7       noro      294:                if ( dp_gr_print() )
                    295:                        print(["DN",B[1]]);
1.1       noro      296:        }
                    297:        return SL;
                    298: }
                    299:
                    300: def hen_ttob_gsl(LHS,RHS,TERMS,M)
                    301: {
                    302:        LDN = LHS[1]; RDN = RHS[1]; LCM = ilcm(LDN,RDN);
                    303:        L1 = idiv(LCM,LDN); R1 = idiv(LCM,RDN);
                    304:        T0 = time()[0];
                    305:        S = henleq_gsl(RHS[0],LHS[0]*L1,M);
1.7       noro      306:        if ( dp_gr_print() )
                    307:                print(["henleq_gsl",time()[0]-T0]);
1.1       noro      308:        N = length(TERMS);
                    309:        return [S[0],S[1]*R1];
                    310: }
                    311:
                    312: def    gather_terms(GM,W,M,NPOSV)
                    313: {
                    314:        N = length(W); V0 = W[NPOSV];
                    315:        for ( T = GM; T != []; T = cdr(T) ) {
                    316:                if ( vars(car(T)) == [V0] )
                    317:                        break;
                    318:        }
                    319:        U = car(T); DU = diff(U,V0);
                    320:        R = tpoly(cdr(p_terms(U,W,2)));
                    321:        for ( I = 0; I < N; I++ ) {
                    322:                if ( I == NPOSV )
                    323:                        continue;
                    324:                V1 = W[I];
                    325:                for ( T = GM; T != []; T = cdr(T) )
                    326:                        if ( member(V1,vars(car(T))) )
                    327:                                break;
                    328:                P = car(T);
                    329:                R += tpoly(p_terms(srem(DU*coef(P,0,V1),U,M),W,2));
                    330:        }
                    331:        return p_terms(R,W,2);
                    332: }
                    333:
                    334: def tpoly(L)
                    335: {
                    336:        for ( R = 0; L != []; L = cdr(L) )
                    337:                R += car(L);
                    338:        return R;
                    339: }
                    340:
                    341: def dptov(P,W,MB)
                    342: {
                    343:        N = size(W)[0];
                    344:        for ( I = 0; I < N; I++ )
                    345:                W[I] = 0;
                    346:        for ( I = 0, S = MB; P; P = dp_rest(P) ) {
                    347:                HM = dp_hm(P); C = dp_hc(HM); T = dp_ht(HM);
                    348:                for ( ; T != car(S); S = cdr(S), I++ );
                    349:                W[I] = C;
                    350:                I++; S = cdr(S);
                    351:        }
                    352: }
                    353:
                    354: def tolex_main(V,O,NF,GM,M,MB)
                    355: {
1.16      noro      356:        if ( MB ) {
                    357:                PosDim = 0;
                    358:                DIM = length(MB);
                    359:                DV = newvect(DIM);
                    360:        } else
                    361:                PosDim = 1;
1.1       noro      362:        for ( T = GM, SL = [], LCM = 1; T != []; T = cdr(T) ) {
                    363:                S = p_terms(car(T),V,2);
1.16      noro      364:                if ( PosDim ) {
                    365:                        MB = gather_nf_terms(S,NF,V,O);
                    366:                        DV = newvect(length(MB));
                    367:                }
1.1       noro      368:                dp_ord(O); RHS = termstomat(NF,map(dp_ptod,cdr(S),V),MB,M);
1.16      noro      369:                dp_ord(O); NHT = nf_tab_gsl(dp_ptod(LCM*car(S),V),NF);
1.1       noro      370:                dptov(NHT[0],DV,MB);
                    371:                dp_ord(O); B = hen_ttob_gsl([DV,NHT[1]],RHS,cdr(S),M);
                    372:                if ( !B )
                    373:                        return 0;
                    374:                Len = length(S);
                    375:                LCM *= B[1];
                    376:                for ( U = LCM*car(S), I = 1; I < Len; I++  )
                    377:                        U += B[0][I-1]*S[I];
                    378:                R = ptozp(U);
                    379:                SL = cons(R,SL);
1.7       noro      380:                if ( dp_gr_print() )
                    381:                        print(["DN",B[1]]);
1.1       noro      382:        }
                    383:        return SL;
1.17      noro      384: }
                    385:
                    386: def tolex_d_main(V,O,NF,GM,M,MB,Procs)
                    387: {
                    388:        map(ox_reset,Procs);
                    389:        /* register data in servers */
                    390:        map(ox_cmo_rpc,Procs,"register_data_for_find_base",NF,V,O,MB,M);
                    391:        /* discard return value in stack */
                    392:        map(ox_pop_cmo,Procs);
                    393:        Free = Procs;
                    394:        Busy = [];
                    395:        T = GM;
                    396:        SL = [];
                    397:        while ( T != [] || Busy != []  ){
                    398:                if ( Free == [] || T == [] ) {
                    399:                        /* someone is working; wait for data */
                    400:                        Ready = ox_select(Busy);
                    401:                        Busy = setminus(Busy,Ready);
                    402:                        Free = append(Ready,Free);
                    403:                        for ( ; Ready != []; Ready = cdr(Ready) )
                    404:                                SL = cons(ox_get(car(Ready)),SL);
                    405:                } else {
                    406:                        P = car(Free);
                    407:                        Free = cdr(Free);
                    408:                        Busy = cons(P,Busy);
                    409:                        Template = car(T);
                    410:                        T = cdr(T);
                    411:                        ox_cmo_rpc(P,"find_base",Template);
                    412:                        ox_push_cmd(P,262); /* 262 = OX_popCMO */
                    413:                }
                    414:        }
                    415:        return SL;
                    416: }
                    417:
                    418: struct find_base_data { NF,V,O,MB,M,PosDim,DV }$
                    419: extern Find_base$
                    420:
                    421: def register_data_for_find_base(NF,V,O,MB,M)
                    422: {
                    423:        Find_base = newstruct(find_base_data);
                    424:        Find_base->NF = NF;
                    425:        Find_base->V = V;
                    426:        Find_base->O = O;
                    427:        Find_base->M = M;
                    428:        Find_base->MB = MB;
                    429:
                    430:        if ( MB ) {
                    431:                Find_base->PosDim = 0;
                    432:                DIM = length(MB);
                    433:                Find_base->DV = newvect(DIM);
                    434:        } else
                    435:                Find_base->PosDim = 1;
                    436: }
                    437:
                    438: def find_base(S) {
                    439:        NF = Find_base->NF;
                    440:        V = Find_base->V;
                    441:        O = Find_base->O;
                    442:        MB = Find_base->MB;
                    443:        M = Find_base->M;
                    444:        PosDim = Find_base->PosDim;
                    445:        DV = Find_base->DV;
                    446:
                    447:        S = p_terms(S,V,2);
                    448:        if ( PosDim ) {
                    449:                MB = gather_nf_terms(S,NF,V,O);
                    450:                DV = newvect(length(MB));
                    451:        }
                    452:        dp_ord(O); RHS = termstomat(NF,map(dp_ptod,cdr(S),V),MB,M);
                    453:        dp_ord(O); NHT = nf_tab_gsl(dp_ptod(car(S),V),NF);
                    454:        dptov(NHT[0],DV,MB);
                    455:        dp_ord(O); B = hen_ttob_gsl([DV,NHT[1]],RHS,cdr(S),M);
                    456:        if ( !B )
                    457:                return 0;
                    458:        Len = length(S);
                    459:        for ( U = B[1]*car(S), I = 1; I < Len; I++  )
                    460:                U += B[0][I-1]*S[I];
                    461:        R = ptozp(U);
                    462:        return R;
1.1       noro      463: }
                    464:
1.16      noro      465: /*
                    466:  * NF = [Pairs,DN]
                    467:  *  Pairs = [[NF1,T1],[NF2,T2],...]
                    468:  */
                    469:
                    470: def gather_nf_terms(S,NF,V,O)
                    471: {
                    472:        R = 0;
                    473:        for ( T = S; T != []; T = cdr(T) ) {
                    474:                DT = dp_ptod(car(T),V);
                    475:                for ( U = NF[0]; U != []; U = cdr(U) )
                    476:                        if ( car(U)[1] == DT ) {
                    477:                                R += tpoly(dp_terms(car(U)[0],V));
                    478:                                break;
                    479:                        }
                    480:        }
                    481:        return map(dp_ptod,p_terms(R,V,O),V);
                    482: }
                    483:
1.1       noro      484: def reduce_dn(L)
                    485: {
                    486:        NM = L[0]; DN = L[1]; V = vars(NM);
                    487:        T = remove_cont([dp_ptod(NM,V),DN]);
                    488:        return [dp_dtop(T[0],V),T[1]];
                    489: }
                    490:
                    491: /* a function for computation of  minimal polynomial */
                    492:
                    493: def minipoly(G0,V,O,P,V0)
                    494: {
                    495:        if ( !zero_dim(hmlist(G0,V,O),V,O) )
                    496:                error("tolex : ideal is not zero-dimensional!");
                    497:
1.15      noro      498:        Pin = P;
                    499:        P = ptozp(P);
                    500:        CP = sdiv(P,Pin);
1.1       noro      501:        G1 = cons(V0-P,G0);
                    502:        O1 = [[0,1],[O,length(V)]];
                    503:        V1 = cons(V0,V);
                    504:        W = append(V,[V0]);
                    505:
                    506:        N = length(V1);
                    507:        dp_ord(O1);
                    508:        HM = hmlist(G1,V1,O1);
                    509:        MB = dp_mbase(map(dp_ptod,HM,V1));
                    510:        dp_ord(O);
                    511:
                    512:        for ( J = 0; ; J++ ) {
                    513:                M = lprime(J);
                    514:                if ( !valid_modulus(HM,M) )
                    515:                        continue;
                    516:                MP = minipolym(G0,V,O,P,V0,M);
                    517:                for ( D = deg(MP,V0), TL = [], J = 0; J <= D; J++ )
                    518:                        TL = cons(V0^J,TL);
                    519:                NF = gennf(G1,TL,V1,O1,V0,1)[0];
                    520:                R = tolex_main(V1,O1,NF,[MP],M,MB);
1.15      noro      521:                return ptozp(subst(R[0],V0,CP*V0));
1.1       noro      522:        }
                    523: }
                    524:
                    525: /* subroutines */
                    526:
                    527: def gennf(G,TL,V,O,V0,FLAG)
                    528: {
1.21      noro      529:        F = dp_gr_flags();
                    530:        for ( T = F; T != []; T = cdr(T) ) {
                    531:                Key = car(T); T = cdr(T);
                    532:                if ( Key == "Demand" ) {
                    533:                        Dir = car(T); break;
                    534:                }
                    535:        }
                    536:        if ( Dir )
                    537:                return gennf_demand(G,TL,V,O,V0,FLAG,Dir);
1.1       noro      538:        N = length(V); Len = length(G); dp_ord(O); PS = newvect(Len);
                    539:        for ( I = 0, T = G, HL = []; T != []; T = cdr(T), I++ ) {
                    540:                PS[I] = dp_ptod(car(T),V); HL = cons(dp_ht(PS[I]),HL);
                    541:        }
                    542:        for ( I = 0, DTL = []; TL != []; TL = cdr(TL) )
                    543:                DTL = cons(dp_ptod(car(TL),V),DTL);
                    544:        for ( I = Len - 1, GI = []; I >= 0; I-- )
                    545:                GI = cons(I,GI);
                    546:        T = car(DTL); DTL = cdr(DTL);
                    547:        H = [nf(GI,T,T,PS)];
                    548:
                    549:        USE_TAB = (FLAG != 0);
                    550:        if ( USE_TAB ) {
                    551:                T0 = time()[0];
                    552:                MB = dp_mbase(HL); DIM = length(MB);
                    553:                U = dp_ptod(V0,V);
                    554:                UTAB = newvect(DIM);
                    555:                for ( I = 0; I < DIM; I++ ) {
                    556:                        UTAB[I] = [MB[I],remove_cont(dp_true_nf(GI,U*MB[I],PS,1))];
                    557:                        if ( dp_gr_print() )
                    558:                                print(".",2);
                    559:                }
1.7       noro      560:                if ( dp_gr_print() )
                    561:                        print("");
1.1       noro      562:                TTAB = time()[0]-T0;
                    563:        }
                    564:
                    565:        T0 = time()[0];
                    566:        for ( LCM = 1; DTL != []; ) {
                    567:                if ( dp_gr_print() )
                    568:                        print(".",2);
                    569:                T = car(DTL); DTL = cdr(DTL);
                    570:                if ( L = search_redble(T,H) ) {
                    571:                        DD = dp_subd(T,L[1]);
                    572:                        if ( USE_TAB && (DD == U) ) {
                    573:                                NF = nf_tab(L[0],UTAB);
                    574:                                NF = [NF[0],dp_hc(L[1])*NF[1]*T];
                    575:                        } else
                    576:                                NF = nf(GI,L[0]*dp_subd(T,L[1]),dp_hc(L[1])*T,PS);
                    577:                } else
                    578:                        NF = nf(GI,T,T,PS);
                    579:                NF = remove_cont(NF);
                    580:                H = cons(NF,H);
                    581:                LCM = ilcm(LCM,dp_hc(NF[1]));
                    582:        }
                    583:        TNF = time()[0]-T0;
                    584:        if ( dp_gr_print() )
                    585:                print("gennf(TAB="+rtostr(TTAB)+" NF="+rtostr(TNF)+")");
                    586:        return [[map(adj_dn,H,LCM),LCM],PS,GI];
1.21      noro      587: }
                    588:
                    589: def gennf_demand(G,TL,V,O,V0,FLAG,Dir)
                    590: {
                    591:        N = length(V); Len = length(G); dp_ord(O); PS = newvect(Len);
                    592:        NTL = length(TL);
                    593:        for ( I = 0, T = G, HL = []; T != []; T = cdr(T), I++ ) {
                    594:                PS[I] = dp_ptod(car(T),V); HL = cons(dp_ht(PS[I]),HL);
                    595:        }
                    596:        for ( I = 0, DTL = []; TL != []; TL = cdr(TL) )
                    597:                DTL = cons(dp_ptod(car(TL),V),DTL);
                    598:        for ( I = Len - 1, GI = []; I >= 0; I-- )
                    599:                GI = cons(I,GI);
                    600:
                    601:        USE_TAB = (FLAG != 0);
                    602:        if ( USE_TAB ) {
                    603:                T0 = time()[0];
                    604:                MB = dp_mbase(HL); DIM = length(MB);
                    605:                U = dp_ptod(V0,V);
                    606:                UTAB = newvect(DIM);
                    607:                for ( I = 0; I < DIM; I++ ) {
                    608:                        UTAB[I] = [MB[I],remove_cont(dp_true_nf(GI,U*MB[I],PS,1))];
                    609:                        if ( dp_gr_print() )
                    610:                                print(".",2);
                    611:                }
                    612:                if ( dp_gr_print() )
                    613:                        print("");
                    614:                TTAB = time()[0]-T0;
                    615:        }
                    616:
                    617:        T0 = time()[0];
                    618:        for ( LCM = 1, Index = 0, H = []; DTL != []; Index++ ) {
                    619:                if ( dp_gr_print() )
                    620:                        print(".",2);
                    621:                T = car(DTL); DTL = cdr(DTL);
                    622:                if ( L = search_redble(T,H) ) {
                    623:                        L = nf_load(Dir,L[0]);
                    624:                        DD = dp_subd(T,L[1]);
                    625:                        if ( USE_TAB && (DD == U) ) {
                    626:                                NF = nf_tab(L[0],UTAB);
                    627:                                NF = [NF[0],dp_hc(L[1])*NF[1]*T];
                    628:                        } else
                    629:                                NF = nf(GI,L[0]*dp_subd(T,L[1]),dp_hc(L[1])*T,PS);
                    630:                } else
                    631:                        NF = nf(GI,T,T,PS);
                    632:                NF = remove_cont(NF);
                    633:                nf_save(NF,Dir,Index);
                    634:                H = cons([Index,NF[1]],H);
                    635:                LCM = ilcm(LCM,dp_hc(NF[1]));
                    636:        }
                    637:        TNF = time()[0]-T0;
                    638:        if ( dp_gr_print() )
                    639:                print("gennf(TAB="+rtostr(TTAB)+" NF="+rtostr(TNF)+")");
                    640:
                    641:        for ( I = 0; I < NTL; I++ ) {
                    642:                NF = nf_load(Dir,I);
                    643:                NF = adj_dn(NF,LCM);
                    644:                nf_save(NF,Dir,I);
                    645:        }
                    646:        for ( H = [], I = NTL-1; I >= 0; I-- )
                    647:                H = cons(nf_load(Dir,I),H);
                    648:        return [[H,LCM],PS,GI];
                    649: }
                    650:
                    651: def nf_load(Dir,I)
                    652: {
                    653:        return bload(Dir+"/nf"+rtostr(I));
                    654: }
                    655:
                    656: def nf_save(NF,Dir,I)
                    657: {
                    658:        bsave(NF,Dir+"/nf"+rtostr(I));
1.1       noro      659: }
                    660:
                    661: def adj_dn(P,D)
                    662: {
                    663:        return [(idiv(D,dp_hc(P[1])))*P[0],dp_ht(P[1])];
                    664: }
                    665:
                    666: def hen_ttob(T,NF,LHS,V,MOD)
                    667: {
                    668:        if ( length(T) == 1 )
                    669:                return car(T);
                    670:        T0 = time()[0]; M = etom(leq_nf(T,NF,LHS,V)); TE = time()[0] - T0;
                    671:        T0 = time()[0]; U = henleq(M,MOD); TH = time()[0] - T0;
                    672:        if ( dp_gr_print() ) {
                    673:                print("(etom="+rtostr(TE)+" hen="+rtostr(TH)+")");
                    674:        }
                    675:        return U ? vtop(T,U,LHS) : 0;
                    676: }
                    677:
                    678: def vtop(S,L,GSL)
                    679: {
                    680:        U = L[0]; H = L[1];
                    681:        if ( GSL ) {
                    682:                for ( A = 0, I = 0; S != []; S = cdr(S), I++ )
                    683:                        A += U[I]*car(S);
                    684:                return [A,H];
                    685:        } else {
                    686:                for ( A = H*car(S), S = cdr(S), I = 0; S != []; S = cdr(S), I++ )
                    687:                        A += U[I]*car(S);
                    688:                return ptozp(A);
                    689:        }
                    690: }
1.16      noro      691:
                    692: /* broken */
1.1       noro      693:
                    694: def leq_nf(TL,NF,LHS,V)
                    695: {
                    696:        TLen = length(NF);
                    697:        T = newvect(TLen); M = newvect(TLen);
                    698:        for ( I = 0; I < TLen; I++ ) {
                    699:                T[I] = dp_ht(NF[I][1]);
                    700:                M[I] = dp_hc(NF[I][1]);
                    701:        }
                    702:        Len = length(TL); INDEX = newvect(Len); COEF = newvect(Len);
                    703:        for ( L = TL, J = 0; L != []; L = cdr(L), J++ ) {
                    704:                D = dp_ptod(car(L),V);
                    705:                for ( I = 0; I < TLen; I++ )
                    706:                        if ( D == T[I] )
                    707:                                break;
                    708:                INDEX[J] = I; COEF[J] = strtov("u"+rtostr(J));
                    709:        }
                    710:        if ( !LHS ) {
                    711:                COEF[0] = 1; NM = 0; DN = 1;
                    712:        } else {
                    713:                NM = LHS[0]; DN = LHS[1];
                    714:        }
                    715:        for ( J = 0, S = -NM; J < Len; J++ ) {
                    716:                DNJ = M[INDEX[J]];
                    717:                GCD = igcd(DN,DNJ); CS = DNJ/GCD; CJ = DN/GCD;
                    718:                S = CS*S + CJ*NF[INDEX[J]][0]*COEF[J];
                    719:                DN *= CS;
                    720:        }
                    721:        for ( D = S, E = []; D; D = dp_rest(D) )
                    722:                E = cons(dp_hc(D),E);
                    723:        BOUND = LHS ? 0 : 1;
                    724:        for ( I = Len - 1, W = []; I >= BOUND; I-- )
                    725:                        W = cons(COEF[I],W);
                    726:        return [E,W];
                    727: }
                    728:
                    729: def nf_tab(F,TAB)
                    730: {
                    731:        for ( NM = 0, DN = 1, I = 0; F; F = dp_rest(F) ) {
                    732:                T = dp_ht(F);
                    733:                for ( ; TAB[I][0] != T; I++);
                    734:                NF = TAB[I][1]; N = NF[0]; D = NF[1];
                    735:                G = igcd(DN,D); DN1 = idiv(DN,G); D1 = idiv(D,G);
                    736:                NM = D1*NM + DN1*dp_hc(F)*N; DN *= D1;
                    737:        }
                    738:        return [NM,DN];
                    739: }
                    740:
                    741: def nf_tab_gsl(A,NF)
                    742: {
                    743:        DN = NF[1];
                    744:        NF = NF[0];
                    745:        TLen = length(NF);
                    746:        for ( R = 0; A; A = dp_rest(A) ) {
                    747:                HM = dp_hm(A); C = dp_hc(HM); T = dp_ht(HM);
                    748:                for ( I = 0; I < TLen; I++ )
                    749:                        if ( NF[I][1] == T )
                    750:                                break;
                    751:                R += C*NF[I][0];
                    752:        }
                    753:        return remove_cont([R,DN]);
                    754: }
                    755:
                    756: def redble(D1,D2,N)
                    757: {
                    758:        for ( I = 0; I < N; I++ )
                    759:                if ( D1[I] > D2[I] )
                    760:                        break;
                    761:        return I == N ? 1 : 0;
                    762: }
                    763:
                    764: def tolexm(G,V,O,W,M)
                    765: {
                    766:        N = length(V); Len = length(G);
                    767:        dp_ord(O); setmod(M); PS = newvect(Len);
                    768:        for ( I = 0, T = G; T != []; T = cdr(T), I++ )
                    769:                PS[I] = dp_mod(dp_ptod(car(T),V),M,[]);
                    770:        for ( I = Len-1, HL = []; I >= 0; I-- )
                    771:                HL = cons(dp_ht(PS[I]),HL);
                    772:        G2 = tolexm_main(PS,HL,V,W,M,ZeroDim);
                    773:        L = map(dp_dtop,G2,V);
                    774:        return L;
                    775: }
                    776:
                    777: def tolexm_main(PS,HL,V,W,M,FLAG)
                    778: {
                    779:        N = length(W); D = newvect(N); Len = size(PS)[0];
                    780:        for ( I = Len - 1, GI = []; I >= 0; I-- )
                    781:                GI = cons(I,GI);
                    782:        MB = dp_mbase(HL); DIM = length(MB);
                    783:        U = dp_mod(dp_ptod(W[N-1],V),M,[]);
                    784:        UTAB = newvect(DIM);
                    785:        for ( I = 0; I < DIM; I++ ) {
                    786:                if ( dp_gr_print() )
                    787:                        print(".",2);
                    788:                UTAB[I] = [MB[I],dp_nf_mod(GI,U*dp_mod(MB[I],M,[]),PS,1,M)];
                    789:        }
1.7       noro      790:        if ( dp_gr_print() )
                    791:                print("");
1.1       noro      792:        T = dp_mod(dp_ptod(dp_dtop(dp_vtoe(D),W),V),M,[]);
                    793:        H = G = [[T,T]];
                    794:        DL = []; G2 = [];
                    795:        TNF = 0;
                    796:        while ( 1 ) {
                    797:                if ( dp_gr_print() )
                    798:                        print(".",2);
                    799:                S = nextm(D,DL,N);
                    800:                if ( !S )
                    801:                        break;
                    802:                T = dp_mod(dp_ptod(dp_dtop(dp_vtoe(D),W),V),M,[]);
                    803:                T0 = time()[0];
                    804:                if ( L = search_redble(T,H) ) {
                    805:                        DD = dp_mod(dp_subd(T,L[1]),M,[]);
                    806:                        if ( DD == U )
                    807:                                NT = dp_nf_tab_mod(L[0],UTAB,M);
                    808:                        else
                    809:                                NT = dp_nf_mod(GI,L[0]*DD,PS,1,M);
                    810:                } else
                    811:                        NT = dp_nf_mod(GI,T,PS,1,M);
                    812:                TNF += time()[0] - T0;
                    813:                H = cons([NT,T],H);
                    814:                T0 = time()[0];
                    815:                L = dp_lnf_mod([NT,T],G,M); N1 = L[0]; N2 = L[1];
                    816:                TLNF += time()[0] - T0;
                    817:                if ( !N1 ) {
                    818:                        G2 = cons(N2,G2);
                    819:                        if ( FLAG == MiniPoly )
                    820:                                break;
                    821:                        D1 = newvect(N);
                    822:                        for ( I = 0; I < N; I++ )
                    823:                                D1[I] = D[I];
                    824:                        DL = cons(D1,DL);
                    825:                } else
                    826:                        G = insert(G,L);
                    827:        }
                    828:        if ( dp_gr_print() )
                    829:                print("tolexm(nfm="+rtostr(TNF)+" lnfm="+rtostr(TLNF)+")");
                    830:        return G2;
                    831: }
                    832:
                    833: def minipolym(G,V,O,P,V0,M)
                    834: {
                    835:        N = length(V); Len = length(G);
                    836:        dp_ord(O); setmod(M); PS = newvect(Len);
                    837:        for ( I = 0, T = G; T != []; T = cdr(T), I++ )
                    838:                PS[I] = dp_mod(dp_ptod(car(T),V),M,[]);
                    839:        for ( I = Len-1, HL = []; I >= 0; I-- )
                    840:                HL = cons(dp_ht(PS[I]),HL);
                    841:        for ( I = Len - 1, GI = []; I >= 0; I-- )
                    842:                GI = cons(I,GI);
                    843:        MB = dp_mbase(HL); DIM = length(MB); UT = newvect(DIM);
                    844:        U = dp_mod(dp_ptod(P,V),M,[]);
                    845:        for ( I = 0; I < DIM; I++ )
                    846:                UT[I] = [MB[I],dp_nf_mod(GI,U*dp_mod(MB[I],M,[]),PS,1,M)];
                    847:        T = dp_mod(<<0>>,M,[]); TT = dp_mod(dp_ptod(1,V),M,[]);
                    848:        G = H = [[TT,T]]; TNF = TLNF = 0;
                    849:        for ( I = 1; ; I++ ) {
                    850:                T = dp_mod(<<I>>,M,[]);
                    851:                T0 = time()[0]; NT = dp_nf_tab_mod(H[0][0],UT,M); TNF += time()[0] - T0;
                    852:                H = cons([NT,T],H);
                    853:                T0 = time()[0]; L = dp_lnf_mod([NT,T],G,M); TLNF += time()[0] - T0;
                    854:                if ( !L[0] ) {
                    855:                        if ( dp_gr_print() ) print(["nfm",TNF,"lnfm",TLNF]);
                    856:                        return dp_dtop(L[1],[V0]);
                    857:                } else
                    858:                        G = insert(G,L);
                    859:        }
                    860: }
                    861:
                    862: def nextm(D,DL,N)
                    863: {
                    864:        for ( I = N-1; I >= 0; ) {
                    865:                D[I]++;
                    866:                for ( T = DL; T != []; T = cdr(T) )
                    867:                        if ( car(T) == D )
                    868:                                return 1;
                    869:                        else if ( redble(car(T),D,N) )
                    870:                                break;
                    871:                if ( T != [] ) {
                    872:                        for ( J = N-1; J >= I; J-- )
                    873:                                D[J] = 0;
                    874:                        I--;
                    875:                } else
                    876:                        break;
                    877:        }
                    878:        if ( I < 0 )
                    879:                return 0;
                    880:        else
                    881:                return 1;
                    882: }
                    883:
                    884: def search_redble(T,G)
                    885: {
                    886:        for ( ; G != []; G = cdr(G) )
                    887:                if ( dp_redble(T,car(G)[1]) )
                    888:                        return car(G);
                    889:        return 0;
                    890: }
                    891:
                    892: def insert(G,A)
                    893: {
                    894:        if ( G == [] )
                    895:                return [A];
                    896:        else if ( dp_ht(car(A)) > dp_ht(car(car(G))) )
                    897:                return cons(A,G);
                    898:        else
                    899:                return cons(car(G),insert(cdr(G),A));
                    900: }
                    901:
                    902: #if 0
                    903: def etom(L) {
                    904:        E = L[0]; W = L[1];
                    905:        LE = length(E); LW = length(W);
                    906:        M = newmat(LE,LW+1);
                    907:        for(J=0;J<LE;J++) {
                    908:                for ( T = E[J]; T && (type(T) == 2); )
                    909:                        for ( V = var(T), I = 0; I < LW; I++ )
                    910:                                if ( V == W[I] ) {
                    911:                                        M[J][I] = coef(T,1,V);
                    912:                                        T = coef(T,0,V);
                    913:                                }
                    914:                M[J][LW] = T;
                    915:        }
                    916:        return M;
                    917: }
                    918: #endif
                    919:
                    920: def etom(L) {
                    921:        E = L[0]; W = L[1];
                    922:        LE = length(E); LW = length(W);
                    923:        M = newmat(LE,LW+1);
                    924:        for(J=0;J<LE;J++) {
                    925:                for ( I = 0, T = E[J]; I < LW; I++ ) {
                    926:                        M[J][I] = coef(T,1,W[I]); T = coef(T,0,W[I]);
                    927:                }
                    928:                M[J][LW] = T;
                    929:        }
                    930:        return M;
                    931: }
                    932:
                    933: def calcb_old(M) {
                    934:        N = 2*M;
                    935:        T = gr_sqrt(N);
                    936:        if ( T^2 <= N && N < (T+1)^2 )
                    937:                return idiv(T,2);
                    938:        else
                    939:                error("afo");
                    940: }
                    941:
                    942: def calcb_special(PK,P,K) { /* PK = P^K */
                    943:        N = 2*PK;
                    944:        T = sqrt_special(N,2,P,K);
                    945:        if ( T^2 <= N && N < (T+1)^2 )
                    946:                return idiv(T,2);
                    947:        else
                    948:        error("afo");
                    949: }
                    950:
                    951: def sqrt_special(A,C,M,K) { /* A = C*M^K */
                    952:        L = idiv(K,2); B = M^L;
                    953:        if ( K % 2 )
                    954:                C *= M;
                    955:        D = 2^K; X = idiv((gr_sqrt(C*D^2)+1)*B,D)+1;
                    956:        while ( 1 )
                    957:                if ( (Y = X^2) <= A )
                    958:                        return X;
                    959:                else
                    960:                        X = idiv(A + Y,2*X);
                    961: }
                    962:
                    963: def gr_sqrt(A) {
                    964:        for ( J = 0, T = A; T >= 2^27; J++ ) {
                    965:                T = idiv(T,2^27)+1;
                    966:        }
                    967:        for ( I = 0; T >= 2; I++ ) {
                    968:                S = idiv(T,2);
                    969:                if ( T = S+S )
                    970:                        T = S;
                    971:                else
                    972:                        T = S+1;
                    973:        }
                    974:        X = (2^27)^idiv(J,2)*2^idiv(I,2);
                    975:        while ( 1 ) {
                    976:                if ( (Y=X^2) < A )
                    977:                        X += X;
                    978:                else if ( Y == A )
                    979:                        return X;
                    980:                else
                    981:                        break;
                    982:        }
                    983:        while ( 1 )
                    984:                if ( (Y = X^2) <= A )
                    985:                        return X;
                    986:                else
                    987:                        X = idiv(A + Y,2*X);
                    988: }
                    989:
                    990: #define ABS(a) ((a)>=0?(a):(-a))
                    991:
                    992: def inttorat_asir(C,M,B)
                    993: {
                    994:        if ( M < 0 )
                    995:                M = -M;
                    996:        C %= M;
                    997:        if ( C < 0 )
                    998:                C += M;
                    999:        U1 = 0; U2 = M; V1 = 1; V2 = C;
                   1000:        while ( V2 >= B ) {
                   1001:                L = iqr(U2,V2); Q = L[0]; R2 = L[1];
                   1002:                R1 = U1 - Q*V1;
                   1003:                U1 = V1; U2 = V2;
                   1004:                V1 = R1; V2 = R2;
                   1005:        }
                   1006:        if ( ABS(V1) >= B )
                   1007:                return 0;
                   1008:        else
                   1009:        if ( V1 < 0 )
                   1010:                return [-V2,-V1];
                   1011:        else
                   1012:                return [V2,V1];
                   1013: }
                   1014:
                   1015: def intvtoratv(V,M,B) {
                   1016:        if ( !B )
                   1017:                B = 1;
                   1018:        N = size(V)[0];
                   1019:        W = newvect(N);
                   1020:        if ( ITOR_FAIL >= 0 ) {
                   1021:                if ( V[ITOR_FAIL] ) {
                   1022:                        T = inttorat(V[ITOR_FAIL],M,B);
                   1023:                        if ( !T ) {
                   1024:                                if ( dp_gr_print() ) {
                   1025:                                        print("F",2);
                   1026:                                }
                   1027:                                return 0;
                   1028:                        }
                   1029:                }
                   1030:        }
                   1031:        for ( I = 0, DN = 1; I < N; I++ )
                   1032:                if ( V[I] ) {
                   1033:                        T = inttorat((V[I]*DN) % M,M,B);
                   1034:                        if ( !T ) {
                   1035:                                ITOR_FAIL = I;
                   1036:                                if ( dp_gr_print() ) {
                   1037: #if 0
                   1038:                                        print("intvtoratv : failed at I = ",0); print(ITOR_FAIL);
                   1039: #endif
                   1040:                                        print("F",2);
                   1041:                                }
                   1042:                                return 0;
                   1043:                        } else {
                   1044:                                for( J = 0; J < I; J++ )
                   1045:                                        W[J] *= T[1];
                   1046:                                W[I] = T[0]; DN *= T[1];
                   1047:                        }
                   1048:                }
                   1049:        return [W,DN];
                   1050: }
                   1051:
                   1052: def nf(B,G,M,PS)
                   1053: {
                   1054:        for ( D = 0; G; ) {
                   1055:                for ( U = 0, L = B; L != []; L = cdr(L) ) {
                   1056:                        if ( dp_redble(G,R=PS[car(L)]) > 0 ) {
                   1057:                                GCD = igcd(dp_hc(G),dp_hc(R));
                   1058:                                CG = idiv(dp_hc(R),GCD); CR = idiv(dp_hc(G),GCD);
                   1059:                                U = CG*G-dp_subd(G,R)*CR*R;
                   1060:                                if ( !U )
                   1061:                                        return [D,M];
                   1062:                                D *= CG; M *= CG;
                   1063:                                break;
                   1064:                        }
                   1065:                }
                   1066:                if ( U )
                   1067:                        G = U;
                   1068:                else {
                   1069:                        D += dp_hm(G); G = dp_rest(G);
                   1070:                }
                   1071:        }
                   1072:        return [D,M];
                   1073: }
                   1074:
                   1075: def remove_cont(L)
                   1076: {
                   1077:        if ( type(L[1]) == 1 ) {
                   1078:                T = remove_cont([L[0],L[1]*<<0>>]);
                   1079:                return [T[0],dp_hc(T[1])];
                   1080:        } else if ( !L[0] )
                   1081:                return [0,dp_ptozp(L[1])];
                   1082:        else if ( !L[1] )
                   1083:                return [dp_ptozp(L[0]),0];
                   1084:        else {
                   1085:                A0 = dp_ptozp(L[0]); A1 = dp_ptozp(L[1]);
                   1086:                C0 = idiv(dp_hc(L[0]),dp_hc(A0)); C1 = idiv(dp_hc(L[1]),dp_hc(A1));
                   1087:                GCD = igcd(C0,C1); M0 = idiv(C0,GCD); M1 = idiv(C1,GCD);
                   1088:                return [M0*A0,M1*A1];
                   1089:        }
                   1090: }
                   1091:
                   1092: def union(A,B)
                   1093: {
                   1094:        for ( T = B; T != []; T = cdr(T) )
                   1095:                A = union1(A,car(T));
                   1096:        return A;
                   1097: }
                   1098:
                   1099: def union1(A,E)
                   1100: {
                   1101:        if ( A == [] )
                   1102:                return [E];
                   1103:        else if ( car(A) == E )
                   1104:                return A;
                   1105:        else
                   1106:                return cons(car(A),union1(cdr(A),E));
                   1107: }
                   1108:
                   1109: def setminus(A,B) {
                   1110:        for ( T = reverse(A), R = []; T != []; T = cdr(T) ) {
                   1111:                for ( S = B, M = car(T); S != []; S = cdr(S) )
                   1112:                        if ( car(S) == M )
                   1113:                                break;
                   1114:                if ( S == [] )
                   1115:                        R = cons(M,R);
                   1116:        }
                   1117:        return R;
                   1118: }
                   1119:
                   1120: def member(A,L) {
                   1121:        for ( ; L != []; L = cdr(L) )
                   1122:                if ( A == car(L) )
                   1123:                        return 1;
                   1124:        return 0;
                   1125: }
                   1126:
                   1127: /* several functions for computation of normal forms etc. */
                   1128:
                   1129: def p_nf(P,B,V,O) {
                   1130:        dp_ord(O); DP = dp_ptod(P,V);
                   1131:        N = length(B); DB = newvect(N);
                   1132:        for ( I = N-1, IL = []; I >= 0; I-- ) {
                   1133:                DB[I] = dp_ptod(B[I],V);
1.26      noro     1134:                if ( DB[I] ) IL = cons(I,IL);
1.1       noro     1135:        }
                   1136:        return dp_dtop(dp_nf(IL,DP,DB,1),V);
                   1137: }
                   1138:
                   1139: def p_true_nf(P,B,V,O) {
                   1140:        dp_ord(O); DP = dp_ptod(P,V);
                   1141:        N = length(B); DB = newvect(N);
                   1142:        for ( I = N-1, IL = []; I >= 0; I-- ) {
                   1143:                DB[I] = dp_ptod(B[I],V);
1.26      noro     1144:                if ( DB[I] ) IL = cons(I,IL);
1.1       noro     1145:        }
                   1146:        L = dp_true_nf(IL,DP,DB,1);
                   1147:        return [dp_dtop(L[0],V),L[1]];
1.12      noro     1148: }
                   1149:
                   1150: def p_nf_mod(P,B,V,O,Mod) {
                   1151:        setmod(Mod);
                   1152:        dp_ord(O); DP = dp_mod(dp_ptod(P,V),Mod,[]);
                   1153:        N = length(B); DB = newvect(N);
                   1154:        for ( I = N-1, IL = []; I >= 0; I-- ) {
                   1155:                DB[I] = dp_mod(dp_ptod(B[I],V),Mod,[]);
                   1156:                IL = cons(I,IL);
                   1157:        }
                   1158:        return dp_dtop(dp_nf_mod(IL,DP,DB,1,Mod),V);
1.1       noro     1159: }
                   1160:
                   1161: def p_terms(D,V,O)
                   1162: {
                   1163:        dp_ord(O);
                   1164:        for ( L = [], T = dp_ptod(D,V); T; T = dp_rest(T) )
                   1165:                L = cons(dp_dtop(dp_ht(T),V),L);
                   1166:        return reverse(L);
                   1167: }
                   1168:
                   1169: def dp_terms(D,V)
                   1170: {
                   1171:        for ( L = [], T = D; T; T = dp_rest(T) )
                   1172:                L = cons(dp_dtop(dp_ht(T),V),L);
                   1173:        return reverse(L);
                   1174: }
                   1175:
                   1176: def gb_comp(A,B)
                   1177: {
1.8       noro     1178:        LA = length(A);
                   1179:        LB = length(B);
                   1180:        if ( LA != LB )
                   1181:                return 0;
1.18      noro     1182:        A = newvect(LA,A);
                   1183:        B = newvect(LB,B);
                   1184:        for ( I = 0; I < LA; I++ )
                   1185:                A[I] *= headsgn(A[I]);
                   1186:        for ( I = 0; I < LB; I++ )
                   1187:                B[I] *= headsgn(B[I]);
                   1188:        A1 = qsort(A);
                   1189:        B1 = qsort(B);
1.8       noro     1190:        for ( I = 0; I < LA; I++ )
                   1191:                if ( A1[I] != B1[I] && A1[I] != -B1[I] )
1.1       noro     1192:                        break;
1.8       noro     1193:        return I == LA ? 1 : 0;
1.1       noro     1194: }
                   1195:
                   1196: def zero_dim(G,V,O) {
                   1197:        dp_ord(O);
                   1198:        HL = map(dp_dtop,map(dp_ht,map(dp_ptod,G,V)),V);
                   1199:        for ( L = []; HL != []; HL = cdr(HL) )
                   1200:                if ( length(vars(car(HL))) == 1 )
                   1201:                        L = cons(car(HL),L);
                   1202:        return length(vars(L)) == length(V) ? 1 : 0;
                   1203: }
                   1204:
                   1205: def hmlist(G,V,O) {
                   1206:        dp_ord(O);
                   1207:        return map(dp_dtop,map(dp_hm,map(dp_ptod,G,V)),V);
                   1208: }
                   1209:
                   1210: def valid_modulus(HL,M) {
                   1211:        V = vars(HL);
                   1212:        for ( T = HL; T != []; T = cdr(T) )
                   1213:                if ( !dp_mod(dp_ptod(car(T),V),M,[]) )
                   1214:                        break;
                   1215:        return T == [] ? 1 : 0;
                   1216: }
                   1217:
                   1218: def npos_check(DL) {
                   1219:        N = size(car(DL))[0];
                   1220:        if ( length(DL) != N )
                   1221:                return [-1,0];
                   1222:        D = newvect(N);
                   1223:        for ( I = 0; I < N; I++ ) {
                   1224:                for ( J = 0; J < N; J++ )
                   1225:                        D[J] = 0;
                   1226:                D[I] = 1;
                   1227:                for ( T = DL; T != []; T = cdr(T) )
                   1228:                        if ( D == car(T) )
                   1229:                                break;
                   1230:                if ( T != [] )
                   1231:                        DL = setminus(DL,[car(T)]);
                   1232:        }
                   1233:        if ( length(DL) != 1 )
                   1234:                return [-1,0];
                   1235:        U = car(DL);
                   1236:        for ( I = 0, J = 0, I0 = -1; I < N; I++ )
                   1237:                if ( U[I] ) {
                   1238:                        I0 = I; J++;
                   1239:                }
                   1240:        if ( J != 1 )
                   1241:                return [-1,0];
                   1242:        else
                   1243:                return [I0,U[I0]];
                   1244: }
                   1245:
                   1246: def mult_mat(L,TAB,MB)
                   1247: {
                   1248:        A = L[0]; DN0 = L[1];
                   1249:        for ( NM = 0, DN = 1, I = 0; A; A = dp_rest(A) ) {
                   1250:                H = dp_ht(A);
                   1251:                for ( ; MB[I] != H; I++ );
                   1252:                NM1 = TAB[I][0]; DN1 = TAB[I][1]; I++;
                   1253:                GCD = igcd(DN,DN1); C = DN1/GCD; C1 = DN/GCD;
                   1254:                NM = C*NM + C1*dp_hc(A)*NM1;
                   1255:                DN *= C;
                   1256:        }
                   1257:        Z=remove_cont([NM,DN*DN0]);
                   1258:        return Z;
                   1259: }
                   1260:
                   1261: def sepm(MAT)
                   1262: {
                   1263:        S = size(MAT); N = S[0]; M = S[1]-1;
                   1264:        A = newmat(N,M); B = newvect(N);
                   1265:        for ( I = 0; I < N; I++ )
                   1266:                for ( J = 0, T1 = MAT[I], T2 = A[I]; J < M; J++ )
                   1267:                        T2[J] = T1[J];
                   1268:        for ( I = 0; I < N; I++ )
                   1269:                B[I] = MAT[I][M];
                   1270:        return [A,B];
                   1271: }
                   1272:
                   1273: def henleq(M,MOD)
                   1274: {
                   1275:        SIZE = size(M); ROW = SIZE[0]; COL = SIZE[1];
                   1276:        W = newvect(COL);
                   1277:        L = sepm(M); A = L[0]; B = L[1];
                   1278:        COUNT = INIT_COUNT?INIT_COUNT:idiv(max_mag(M),54);
                   1279:        if ( !COUNT )
                   1280:                COUNT = 1;
                   1281:
                   1282:        TINV = TC = TR = TS = TM = TDIV = 0;
                   1283:
                   1284:        T0 = time()[0];
                   1285:        L = geninvm_swap(A,MOD); INV = L[0]; INDEX = L[1];
                   1286:        TS += time()[0] - T0;
                   1287:
                   1288:        COL1 = COL - 1;
                   1289:        AA = newmat(COL1,COL1); BB = newvect(COL1);
                   1290:        for ( I = 0; I < COL1; I++ ) {
                   1291:                for ( J = 0, T = AA[I], S = A[INDEX[I]]; J < COL1; J++ )
                   1292:                        T[J] = S[J];
                   1293:                BB[I] = B[INDEX[I]];
                   1294:        }
                   1295:        if ( COL1 != ROW ) {
                   1296:                RESTA = newmat(ROW-COL1,COL1); RESTB = newvect(ROW-COL1);
                   1297:                for ( ; I < ROW; I++ ) {
                   1298:                        for ( J = 0, T = RESTA[I-COL1], S = A[INDEX[I]]; J < COL1; J++ )
                   1299:                                T[J] = S[J];
                   1300:                        RESTB[I-COL1] = B[INDEX[I]];
                   1301:                }
                   1302:        } else
                   1303:                RESTA = RESTB = 0;
                   1304:
                   1305:        MOD2 = idiv(MOD,2);
                   1306:        for ( I = 0, C = BB, X = 0, PK = 1, CCC = 0, ITOR_FAIL = -1; ;
                   1307:                I++, PK *= MOD ) {
                   1308:                if ( COUNT == CCC ) {
                   1309:                        CCC = 0;
                   1310:                        T0 = time()[0];
                   1311:                        ND = intvtoratv(X,PK,ishift(calcb_special(PK,MOD,I),32));
                   1312:                        TR += time()[0]-T0;
                   1313:                        if ( ND ) {
                   1314:                                T0 = time()[0];
                   1315:                                F = ND[0]; LCM = ND[1]; T = AA*F+LCM*BB;
                   1316:                                TM += time()[0]-T0;
                   1317:                                if ( zerovector(T) ) {
                   1318:                                        T0 = time()[0]; T = RESTA*F+LCM*RESTB; TM += time()[0]-T0;
                   1319:                                        if ( zerovector(T) ) {
                   1320: #if 0
                   1321:                                                if ( dp_gr_print() ) print(["init",TS,"pinv",TINV,"c",TC,"div",TDIV,"rat",TR,"mul",TM]);
                   1322: #endif
                   1323:                                                if ( dp_gr_print() ) print("end",2);
                   1324:                                                return [F,LCM];
                   1325:                                        } else
                   1326:                                                return 0;
                   1327:                                }
                   1328:                        } else {
                   1329: #if 0
                   1330:                                if ( dp_gr_print() ) print(I);
                   1331: #endif
                   1332:                        }
                   1333:                } else {
                   1334: #if 0
                   1335:                        if ( dp_gr_print() ) print([I,TINV,TC,TDIV]);
                   1336: #endif
                   1337:                        if ( dp_gr_print() ) print(".",2);
                   1338:                        CCC++;
                   1339:                }
                   1340:                T0 = time()[0];
                   1341:                XT = sremainder(INV*sremainder(-C,MOD),MOD);
                   1342:                XT = map(adj_sgn,XT,MOD,MOD2);
                   1343:                TINV += time()[0] - T0;
                   1344:                X += XT*PK;
                   1345:                T0 = time()[0];
                   1346:                C += mul_mat_vect_int(AA,XT);
                   1347:                TC += time()[0] - T0;
                   1348:                T0 = time()[0]; C = map(idiv,C,MOD); TDIV += time()[0] - T0;
                   1349:        }
                   1350: }
                   1351:
                   1352: def henleq_prep(A,MOD)
                   1353: {
                   1354:        SIZE = size(A); ROW = SIZE[0]; COL = SIZE[1];
                   1355:        L = geninvm_swap(A,MOD); INV = L[0]; INDEX = L[1];
                   1356:        AA = newmat(COL,COL);
                   1357:        for ( I = 0; I < COL; I++ )
                   1358:                for ( J = 0, T = AA[I], S = A[INDEX[I]]; J < COL; J++ )
                   1359:                        T[J] = S[J];
                   1360:        if ( COL != ROW ) {
                   1361:                RESTA = newmat(ROW-COL,COL);
                   1362:                for ( ; I < ROW; I++ )
                   1363:                        for ( J = 0, T = RESTA[I-COL], S = A[INDEX[I]]; J < COL; J++ )
                   1364:                                T[J] = S[J];
                   1365:        } else
                   1366:                RESTA = 0;
                   1367:        return [[A,AA,RESTA],L];
                   1368: }
                   1369:
                   1370: def henleq_gsl(L,B,MOD)
                   1371: {
                   1372:        AL = L[0]; INVL = L[1];
                   1373:        A = AL[0]; AA = AL[1]; RESTA = AL[2];
                   1374:        INV = INVL[0]; INDEX = INVL[1];
                   1375:        SIZE = size(A); ROW = SIZE[0]; COL = SIZE[1];
                   1376:        BB = newvect(COL);
                   1377:        for ( I = 0; I < COL; I++ )
                   1378:                BB[I] = B[INDEX[I]];
                   1379:        if ( COL != ROW ) {
                   1380:                RESTB = newvect(ROW-COL);
                   1381:                for ( ; I < ROW; I++ )
                   1382:                        RESTB[I-COL] = B[INDEX[I]];
                   1383:        } else
                   1384:                RESTB = 0;
                   1385:
                   1386:        COUNT = INIT_COUNT?INIT_COUNT:idiv(MAX(max_mag(A),max_mag_vect(B)),54);
                   1387:        if ( !COUNT )
                   1388:                COUNT = 1;
                   1389:        MOD2 = idiv(MOD,2);
1.3       noro     1390:        X = newvect(size(AA)[0]);
                   1391:        for ( I = 0, C = BB, PK = 1, CCC = 0, ITOR_FAIL = -1; ;
1.1       noro     1392:                I++, PK *= MOD ) {
                   1393:                if ( zerovector(C) )
                   1394:                        if ( zerovector(RESTA*X+RESTB) ) {
                   1395:                                if ( dp_gr_print() ) print("end",0);
                   1396:                                return [X,1];
                   1397:                        } else
                   1398:                                return 0;
                   1399:                else if ( COUNT == CCC ) {
                   1400:                        CCC = 0;
                   1401:                        ND = intvtoratv(X,PK,ishift(calcb_special(PK,MOD,I),32));
                   1402:                        if ( ND ) {
                   1403:                                F = ND[0]; LCM = ND[1]; T = AA*F+LCM*BB;
                   1404:                                if ( zerovector(T) ) {
                   1405:                                        T = RESTA*F+LCM*RESTB;
                   1406:                                        if ( zerovector(T) ) {
                   1407:                                                if ( dp_gr_print() ) print("end",0);
                   1408:                                                return [F,LCM];
                   1409:                                        } else
                   1410:                                                return 0;
                   1411:                                }
                   1412:                        } else {
                   1413:                        }
                   1414:                } else {
                   1415:                        if ( dp_gr_print() ) print(".",2);
                   1416:                        CCC++;
                   1417:                }
                   1418:                XT = sremainder(INV*sremainder(-C,MOD),MOD);
                   1419:                XT = map(adj_sgn,XT,MOD,MOD2);
                   1420:                X += XT*PK;
                   1421:                C += mul_mat_vect_int(AA,XT);
                   1422:                C = map(idiv,C,MOD);
                   1423:        }
                   1424: }
                   1425:
                   1426: def adj_sgn(A,M,M2)
                   1427: {
                   1428:        return A > M2 ? A-M : A;
                   1429: }
                   1430:
                   1431: def zerovector(C)
                   1432: {
                   1433:        if ( !C )
                   1434:                return 1;
                   1435:        for ( I = size(C)[0]-1; I >= 0 && !C[I]; I-- );
                   1436:        if ( I < 0 )
                   1437:                return 1;
                   1438:        else
                   1439:                return 0;
                   1440: }
                   1441:
                   1442: def solvem(INV,COMP,V,MOD)
                   1443: {
                   1444:        T = COMP*V;
                   1445:        N = size(T)[0];
                   1446:        for ( I = 0; I < N; I++ )
                   1447:                if ( T[I] % MOD )
                   1448:                        return 0;
                   1449:        return modvect(INV*V,MOD);
                   1450: }
                   1451:
                   1452: def modmat(A,MOD)
                   1453: {
                   1454:        if ( !A )
                   1455:                return 0;
                   1456:        S = size(A); N = S[0]; M = S[1];
                   1457:        MAT = newmat(N,M);
                   1458:        for ( I = 0, NZ = 0; I < N; I++ )
                   1459:                for ( J = 0, T1 = A[I], T2 = MAT[I]; J < M; J++ ) {
                   1460:                        T2[J] = T1[J] % MOD;
                   1461:                        NZ = NZ || T2[J];
                   1462:                }
                   1463:        return NZ?MAT:0;
                   1464: }
                   1465:
                   1466: def modvect(A,MOD)
                   1467: {
                   1468:        if ( !A )
                   1469:                return 0;
                   1470:        N = size(A)[0];
                   1471:        VECT = newvect(N);
                   1472:        for ( I = 0, NZ = 0; I < N; I++ ) {
                   1473:                VECT[I] = A[I] % MOD;
                   1474:                NZ = NZ || VECT[I];
                   1475:        }
                   1476:        return NZ?VECT:0;
                   1477: }
                   1478:
                   1479: def qrmat(A,MOD)
                   1480: {
                   1481:        if ( !A )
                   1482:                return [0,0];
                   1483:        S = size(A); N = S[0]; M = S[1];
                   1484:        Q = newmat(N,M); R = newmat(N,M);
                   1485:        for ( I = 0, NZQ = 0, NZR = 0; I < N; I++ )
                   1486:                for ( J = 0, TA = A[I], TQ = Q[I], TR = R[I]; J < M; J++ ) {
                   1487:                        L = iqr(TA[J],MOD); TQ[J] = L[0]; TR[J] = L[1];
                   1488:                        NZQ = NZQ || TQ[J]; NZR = NZR || TR[J];
                   1489:                }
                   1490:        return [NZQ?Q:0,NZR?R:0];
                   1491: }
                   1492:
                   1493: def qrvect(A,MOD)
                   1494: {
                   1495:        if ( !A )
                   1496:                return [0,0];
                   1497:        N = size(A)[0];
                   1498:        Q = newvect(N); R = newvect(N);
                   1499:        for ( I = 0, NZQ = 0, NZR = 0; I < N; I++ ) {
                   1500:                L = iqr(A[I],MOD); Q[I] = L[0]; R[I] = L[1];
                   1501:                NZQ = NZQ || Q[I]; NZR = NZR || R[I];
                   1502:        }
                   1503:        return [NZQ?Q:0,NZR?R:0];
                   1504: }
                   1505:
                   1506: def max_mag(M)
                   1507: {
                   1508:        R = size(M)[0];
                   1509:        U = 1;
                   1510:        for ( I = 0; I < R; I++ ) {
                   1511:                A = max_mag_vect(M[I]);
                   1512:                U = MAX(A,U);
                   1513:        }
                   1514:        return U;
                   1515: }
                   1516:
                   1517: def max_mag_vect(V)
                   1518: {
                   1519:        R = size(V)[0];
                   1520:        U = 1;
                   1521:        for ( I = 0; I < R; I++ ) {
                   1522:                A = dp_mag(V[I]*<<0>>);
                   1523:                U = MAX(A,U);
                   1524:        }
                   1525:        return U;
                   1526: }
                   1527:
                   1528: def gsl_check(B,V,S)
                   1529: {
                   1530:        N = length(V);
                   1531:        U = S[N-1]; M = U[1]; D = U[2];
                   1532:        W = setminus(V,[var(M)]);
                   1533:        H = uc(); VH = append(W,[H]);
                   1534:        for ( T = B; T != []; T = cdr(T) ) {
                   1535:                A = car(T);
                   1536:                AH = dp_dtop(dp_homo(dp_ptod(A,W)),VH);
                   1537:                for ( I = 0, Z = S; I < N-1; I++, Z = cdr(Z) ) {
                   1538:                        L = car(Z); AH = ptozp(subst(AH,L[0],L[1]/L[2]));
                   1539:                }
                   1540:                AH = ptozp(subst(AH,H,D));
                   1541:                R = srem(AH,M);
                   1542:                if ( dp_gr_print() )
                   1543:                        if ( !R )
                   1544:                                print([A,"ok"]);
                   1545:                        else
                   1546:                                print([A,"bad"]);
                   1547:                if ( R )
                   1548:                        break;
                   1549:        }
                   1550:        return T == [] ? 1 : 0;
                   1551: }
                   1552:
                   1553: def vs_dim(G,V,O)
                   1554: {
                   1555:        HM = hmlist(G,V,O); ZD = zero_dim(HM,V,O);
                   1556:        if ( ZD ) {
                   1557:                MB = dp_mbase(map(dp_ptod,HM,V));
                   1558:                return length(MB);
                   1559:        } else
                   1560:                error("vs_dim : ideal is not zero-dimensional!");
                   1561: }
                   1562:
1.2       noro     1563: def dgr(G,V,O)
1.1       noro     1564: {
1.2       noro     1565:        P = getopt(proc);
                   1566:        if ( type(P) == -1 )
                   1567:                return gr(G,V,O);
1.1       noro     1568:        P0 = P[0]; P1 = P[1]; P = [P0,P1];
1.2       noro     1569:        map(ox_reset,P);
                   1570:        ox_cmo_rpc(P0,"dp_gr_main",G,V,0,1,O);
                   1571:        ox_cmo_rpc(P1,"dp_gr_main",G,V,1,1,O);
                   1572:        map(ox_push_cmd,P,262); /* 262 = OX_popCMO */
                   1573:        F = ox_select(P);
                   1574:        R = ox_get(F[0]);
                   1575:        if ( F[0] == P0 ) {
                   1576:                Win = "nonhomo";
                   1577:                Lose = P1;
                   1578:        } else {
1.11      noro     1579:                Win = "homo";
                   1580:                Lose = P0;
                   1581:        }
                   1582:        ox_reset(Lose);
                   1583:        return [Win,R];
                   1584: }
                   1585:
                   1586: /* competitive Gbase computation : F4 vs. Bucbberger */
                   1587: /* P : process list */
                   1588:
                   1589: def dgrf4mod(G,V,M,O)
                   1590: {
                   1591:        P = getopt(proc);
                   1592:        if ( type(P) == -1 )
                   1593:                return dp_f4_mod_main(G,V,M,O);
                   1594:        P0 = P[0]; P1 = P[1]; P = [P0,P1];
                   1595:        map(ox_reset,P);
                   1596:        ox_cmo_rpc(P0,"dp_f4_mod_main",G,V,M,O);
                   1597:        ox_cmo_rpc(P1,"dp_gr_mod_main",G,V,0,M,O);
                   1598:        map(ox_push_cmd,P,262); /* 262 = OX_popCMO */
                   1599:        F = ox_select(P);
                   1600:        R = ox_get(F[0]);
                   1601:        if ( F[0] == P0 ) {
                   1602:                Win = "F4";
                   1603:                Lose = P1;
                   1604:        } else {
                   1605:                Win = "Buchberger";
1.2       noro     1606:                Lose = P0;
                   1607:        }
                   1608:        ox_reset(Lose);
                   1609:        return [Win,R];
1.1       noro     1610: }
                   1611:
                   1612: /* functions for rpc */
                   1613:
                   1614: def register_matrix(M)
                   1615: {
                   1616:        REMOTE_MATRIX = M; return 0;
                   1617: }
                   1618:
                   1619: def register_nfv(L)
                   1620: {
                   1621:        REMOTE_NF = L[0]; REMOTE_VARS = L[1]; return 0;
                   1622: }
                   1623:
                   1624: def r_ttob(T,M)
                   1625: {
                   1626:        return hen_ttob(T,REMOTE_NF,0,REMOTE_VARS,M);
                   1627: }
                   1628:
                   1629: def r_ttob_gsl(L,M)
                   1630: {
                   1631:        return cons(L[2],hen_ttob(L[0],REMOTE_NF,L[1],REMOTE_VARS,M));
                   1632: }
                   1633:
                   1634: def get_matrix()
                   1635: {
                   1636:        REMOTE_MATRIX;
1.4       noro     1637: }
                   1638:
                   1639: extern NFArray$
                   1640:
                   1641: /*
                   1642:  * HL = [[c,i,m,d],...]
                   1643:  * if c != 0
                   1644:  *   g = 0
                   1645:  *   g = (c*g + m*gi)/d
                   1646:  *   ...
                   1647:  *   finally compare g with NF
                   1648:  *   if g == NF then NFArray[NFIndex] = g
                   1649:  *
                   1650:  * if c = 0 then HL consists of single history [0,i,0,0],
                   1651:  * which means that dehomogenization of NFArray[i] should be
                   1652:  * eqall to NF.
                   1653:  */
                   1654:
                   1655: def check_trace(NF,NFIndex,HL)
                   1656: {
                   1657:        if ( !car(HL)[0] ) {
                   1658:                /* dehomogenization */
                   1659:                DH = dp_dehomo(NFArray[car(HL)[1]]);
                   1660:                if ( NF == DH ) {
                   1661:                        realloc_NFArray(NFIndex);
                   1662:                        NFArray[NFIndex] = NF;
                   1663:                        return 0;
                   1664:                } else
                   1665:                        error("check_trace(dehomo)");
                   1666:        }
                   1667:
                   1668:        for ( G = 0, T = HL; T != []; T = cdr(T) ) {
                   1669:                H = car(T);
                   1670:
                   1671:                Coeff = H[0];
                   1672:                Index = H[1];
                   1673:                Monomial = H[2];
                   1674:                Denominator = H[3];
                   1675:
                   1676:                Reducer = NFArray[Index];
                   1677:                G = (Coeff*G+Monomial*Reducer)/Denominator;
                   1678:        }
                   1679:        if ( NF == G ) {
                   1680:                realloc_NFArray(NFIndex);
                   1681:                NFArray[NFIndex] = NF;
                   1682:                return 0;
                   1683:        } else
                   1684:                error("check_trace");
1.20      noro     1685: }
                   1686:
                   1687: /*
                   1688:  * Trace = [Input,[[j1,[[c,i,m,d],...]],[j2,[[...],...]],...]]
                   1689:  * if c != 0
                   1690:  *   g = 0
                   1691:  *   g = (c*g + m*gi)/d
                   1692:  *   ...
                   1693:  *   finally fj = g
                   1694:  */
                   1695:
                   1696: def show_trace(Trace,V)
                   1697: {
                   1698:        Input = Trace[0];
                   1699:        for ( I = 0, T = Input; T != []; T = cdr(T), I++ ) {
                   1700:                print("F"+rtostr(I)+"=",0);
                   1701:                print(dp_dtop(car(T),V));
                   1702:        }
                   1703:        Trace = cdr(Trace);
                   1704:        for ( T = Trace; T != []; T = cdr(T) ) {
                   1705:                HL = car(T);
                   1706:                J = car(HL); HL = HL[1];
                   1707:                L = length(HL);
                   1708:                print("F"+rtostr(J)+"=",0);
                   1709:                for ( I = 0; I < L; I++ ) print("(",0);
                   1710:                for ( First = 1, S = HL; S != []; S = cdr(S) ) {
                   1711:                        H = car(S);
                   1712:
                   1713:                        Coeff = H[0];
                   1714:                        Index = H[1];
                   1715:                        Monomial = H[2];
                   1716:                        Denominator = H[3];
                   1717:                        if ( First ) {
                   1718:                                if ( Monomial != 1 ) {
                   1719:                                        print("(",0);
                   1720:                                        print(type(Monomial)==9?dp_dtop(Monomial,V):Monomial,0);
                   1721:                                        print(")*",0);
                   1722:                                }
                   1723:                                print("F"+rtostr(Index)+")",0);
                   1724:                        } else {
                   1725:                                if ( Coeff != 1 ) {
                   1726:                                        print("*(",0); print(Coeff,0); print(")",0);
                   1727:                                }
                   1728:                                print("+",0);
                   1729:                                if ( Monomial != 1 ) {
                   1730:                                        print("(",0);
                   1731:                                        print(type(Monomial)==9?dp_dtop(Monomial,V):Monomial,0);
                   1732:                                        print(")*",0);
                   1733:                                }
                   1734:                                print("F"+rtostr(Index)+")",0);
                   1735:                                if ( Denominator != 1 ) {
                   1736:                                        print("/",0); print(Denominator,0);
                   1737:                                }
                   1738:                        }
                   1739:                        if ( First ) First = 0;
                   1740:                }
                   1741:                print("");
                   1742:        }
1.4       noro     1743: }
                   1744:
1.22      noro     1745: def generating_relation(Trace,V)
                   1746: {
                   1747:        Trace = cdr(Trace);
                   1748:        Tab = [];
                   1749:        for ( T = Trace; T != []; T = cdr(T) ) {
                   1750:                HL = car(T);
                   1751:                J = car(HL); HL = HL[1];
                   1752:                L = length(HL);
                   1753:                LHS = strtov("f"+rtostr(J));
                   1754:                Dn = 1;
                   1755:                for ( First = 1, S = HL; S != []; S = cdr(S) ) {
                   1756:                        H = car(S);
                   1757:
                   1758:                        Coeff = H[0];
                   1759:                        Index = H[1];
                   1760:                        Monomial = type(H[2])==9?dp_dtop(H[2],V):H[2];
                   1761:                        Denominator = H[3];
                   1762:                        F = strtov("f"+rtostr(Index));
                   1763:                        for ( Z = Tab; Z != []; Z = cdr(Z) )
                   1764:                                if ( Z[0][0] == F ) break;
                   1765:                        if ( Z != [] ) Value = Z[0][1];
                   1766:                        else Value = [F,1];
                   1767:                        if ( First ) {
                   1768:                                RHS = Monomial*Value[0];
                   1769:                                Dn *= Value[1];
                   1770:                        } else {
                   1771:                                RHS = RHS*Coeff*Value[1]+Dn*Value[0]*Monomial;
                   1772:                                Dn = Value[1]*Dn*Denominator;
                   1773:                        }
                   1774:                        VVVV = tttttttt;
                   1775:                        P = ptozp(Dn*VVVV+RHS);
                   1776:                        RHS = coef(P,0,VVVV);
                   1777:                        Dn = coef(P,1,VVVV);
                   1778:                        if ( First ) First = 0;
                   1779:                }
                   1780:                Tab = cons([LHS,[RHS,Dn]],Tab);
                   1781:        }
                   1782:        return Tab;
                   1783: }
                   1784:
1.24      noro     1785: def generating_relation_mod(Trace,V,M)
                   1786: {
                   1787:        Trace = cdr(Trace);
                   1788:        Tab = [];
                   1789:        for ( T = Trace; T != []; T = cdr(T) ) {
                   1790:                HL = car(T);
                   1791:                J = car(HL); HL = HL[1];
                   1792:                L = length(HL);
                   1793:                LHS = strtov("f"+rtostr(J));
                   1794:                Dn = 1;
                   1795:                for ( First = 1, S = HL; S != []; S = cdr(S) ) {
                   1796:                        H = car(S);
                   1797:
                   1798:                        Coeff = H[0];
                   1799:                        Index = H[1];
                   1800:                        Monomial = type(H[2])==9?dp_dtop(H[2],V):H[2];
                   1801:                        F = strtov("f"+rtostr(Index));
                   1802:                        for ( Z = Tab; Z != []; Z = cdr(Z) )
                   1803:                                if ( Z[0][0] == F ) break;
                   1804:                        if ( Z != [] ) Value = Z[0][1];
                   1805:                        else Value = F;
                   1806:                        if ( First ) {
                   1807:                                RHS = (Monomial*Value)%M;
                   1808:                        } else {
                   1809:                                RHS = ((RHS*Coeff+Value*Monomial)*inv(H[3],M))%M;
                   1810:                        }
                   1811:                        if ( First ) First = 0;
                   1812:                }
                   1813:                Tab = cons([LHS,RHS],Tab);
                   1814:        }
                   1815:        return Tab;
                   1816: }
1.4       noro     1817: /*
                   1818:  * realloc NFArray so that it can hold * an element as NFArray[Ind].
                   1819:  */
                   1820:
                   1821: def realloc_NFArray(Ind)
                   1822: {
                   1823:        if ( Ind == size(NFArray)[0] ) {
                   1824:                New = newvect(Ind + 100);
                   1825:                for ( I = 0; I < Ind; I++ )
                   1826:                        New[I] = NFArray[I];
                   1827:                NFArray = New;
                   1828:        }
                   1829: }
                   1830:
                   1831: /*
                   1832:  * create NFArray and initialize it by List.
                   1833:  */
                   1834:
                   1835: def register_input(List)
                   1836: {
                   1837:        Len = length(List);
                   1838:        NFArray = newvect(Len+100,List);
1.1       noro     1839: }
1.9       noro     1840:
                   1841: /*
                   1842:        tracetogen(): preliminary version
                   1843:
                   1844:        dp_gr_main() returns  [GB,GBIndex,Trace].
                   1845:        GB : groebner basis
                   1846:        GBIndex : IndexList (corresponding to Trace)
                   1847:        Trace : [InputList,Trace0,Trace1,...]
                   1848:        TraceI : [Index,TraceList]
                   1849:        TraceList : [[Coef,Index,Monomial,Denominator],...]
                   1850:        Poly <- 0
                   1851:        Poly <- (Coef*Poly+Monomial*PolyList[Index])/Denominator
                   1852: */
                   1853:
1.10      noro     1854: def tracetogen(G)
1.9       noro     1855: {
1.10      noro     1856:        GB = G[0]; GBIndex = G[1]; Trace = G[2];
                   1857:
1.9       noro     1858:        InputList = Trace[0];
                   1859:        Trace = cdr(Trace);
                   1860:
                   1861:        /* number of initial basis */
                   1862:        Nini = length(InputList);
                   1863:
                   1864:        /* number of generated basis */
                   1865:        Ngen = length(Trace);
                   1866:
                   1867:        N = Nini + Ngen;
                   1868:
                   1869:        /* stores traces */
                   1870:        Tr = vector(N);
                   1871:
                   1872:        /* stores coeffs */
                   1873:        Coef = vector(N);
                   1874:
1.10      noro     1875:        /* XXX create dp_ptod(1,V) */
                   1876:        HT = dp_ht(InputList[0]);
                   1877:        One = dp_subd(HT,HT);
                   1878:
1.9       noro     1879:        for ( I = 0; I < Nini; I++ ) {
1.10      noro     1880:                Tr[I] = [1,I,One,1];
1.9       noro     1881:                C = vector(Nini);
1.10      noro     1882:                C[I] = One;
1.9       noro     1883:                Coef[I] = C;
                   1884:        }
                   1885:        for ( ; I < N; I++ )
                   1886:                Tr[I] = Trace[I-Nini][1];
                   1887:
                   1888:        for ( T = GBIndex; T != []; T = cdr(T) )
                   1889:                compute_coef_by_trace(car(T),Tr,Coef);
                   1890:        return Coef;
                   1891: }
                   1892:
                   1893: def compute_coef_by_trace(I,Tr,Coef)
                   1894: {
                   1895:        if ( Coef[I] )
                   1896:                return;
                   1897:
                   1898:        /* XXX */
                   1899:        Nini = size(Coef[0])[0];
                   1900:
                   1901:        /* initialize coef vector */
                   1902:        CI = vector(Nini);
                   1903:
                   1904:        for ( T = Tr[I]; T != []; T = cdr(T) ) {
                   1905:                /*      Trace = [Coef,Index,Monomial,Denominator] */
                   1906:                Trace = car(T);
                   1907:                C = Trace[0];
                   1908:                Ind = Trace[1];
                   1909:                Mon = Trace[2];
                   1910:                Den = Trace[3];
                   1911:                if ( !Coef[Ind] )
                   1912:                        compute_coef_by_trace(Ind,Tr,Coef);
                   1913:
                   1914:                /* XXX */
                   1915:                CT = newvect(Nini);
                   1916:                for ( J = 0; J < Nini; J++ )
                   1917:                        CT[J] = (C*CI[J]+Mon*Coef[Ind][J])/Den;
                   1918:                CI = CT;
                   1919:        }
                   1920:        Coef[I] = CI;
1.13      noro     1921: }
                   1922:
                   1923: extern Gbcheck_DP,Gbcheck_IL$
                   1924:
                   1925: def register_data_for_gbcheck(DPL)
                   1926: {
                   1927:        for ( IL = [], I = length(DPL)-1; I >= 0; I-- )
                   1928:                IL = cons(I,IL);
                   1929:        Gbcheck_DP = newvect(length(DPL),DPL);
                   1930:        Gbcheck_IL = IL;
                   1931: }
                   1932:
                   1933: def sp_nf_for_gbcheck(Pair)
                   1934: {
                   1935:        SP = dp_sp(Gbcheck_DP[Pair[0]],Gbcheck_DP[Pair[1]]);
                   1936:        return dp_nf(Gbcheck_IL,SP,Gbcheck_DP,1);
                   1937: }
                   1938:
                   1939: def gbcheck(B,V,O)
                   1940: {
                   1941:        dp_ord(O);
                   1942:        D = map(dp_ptod,B,V);
1.14      noro     1943:        L = dp_gr_checklist(D,length(V));
1.13      noro     1944:        DP = L[0]; Plist = L[1];
                   1945:        for ( IL = [], I = size(DP)[0]-1; I >= 0; I-- )
                   1946:                IL = cons(I,IL);
                   1947:        Procs = getopt(proc);
                   1948:        if ( type(Procs) == 4 ) {
                   1949:                map(ox_reset,Procs);
                   1950:                /* register DP in servers */
                   1951:                map(ox_cmo_rpc,Procs,"register_data_for_gbcheck",vtol(DP));
                   1952:                /* discard return value in stack */
                   1953:                map(ox_pop_cmo,Procs);
                   1954:                Free = Procs;
                   1955:                Busy = [];
                   1956:                T = Plist;
                   1957:                while ( T != [] || Busy != []  ){
                   1958:                        if ( Free == [] || T == [] ) {
                   1959:                                /* someone is working; wait for data */
                   1960:                                Ready = ox_select(Busy);
                   1961:                                Busy = setminus(Busy,Ready);
                   1962:                                Free = append(Ready,Free);
                   1963:                                for ( ; Ready != []; Ready = cdr(Ready) ) {
                   1964:                                        if ( ox_get(car(Ready)) ) {
                   1965:                                                map(ox_reset,Procs);
                   1966:                                                return 0;
                   1967:                                        }
                   1968:                                }
                   1969:                        } else {
                   1970:                                P = car(Free);
                   1971:                                Free = cdr(Free);
                   1972:                                Busy = cons(P,Busy);
                   1973:                                Pair = car(T);
                   1974:                                T = cdr(T);
                   1975:                                ox_cmo_rpc(P,"sp_nf_for_gbcheck",Pair);
                   1976:                                ox_push_cmd(P,262); /* 262 = OX_popCMO */
                   1977:                        }
                   1978:                }
                   1979:                map(ox_reset,Procs);
                   1980:                return 1;
                   1981:        } else {
                   1982:                for ( T = Plist; T != []; T = cdr(T) ) {
                   1983:                        Pair = T[0];
                   1984:                        SP = dp_sp(DP[Pair[0]],DP[Pair[1]]);
                   1985:                        if ( dp_nf(IL,SP,DP,1) )
                   1986:                                return 0;
                   1987:                }
                   1988:                return 1;
                   1989:        }
1.9       noro     1990: }
1.1       noro     1991: end$

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