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

Annotation of OpenXM_contrib2/asir2000/lib/primdec_mod, Revision 1.1

1.1     ! noro        1: extern Hom,GBTime$
        !             2: extern DIVLIST,INTIDEAL,ORIGINAL,ORIGINALDIMENSION,STOP,Trials,REM$
        !             3: extern T_GRF,T_INT,T_PD,T_MP$
        !             4: extern BuchbergerMinipoly,PartialDecompByLex,ParallelMinipoly$
        !             5: extern B_Win,D_Win$
        !             6: extern COMMONCHECK_SF,CID_SF$
        !             7:
        !             8: /*==============================================*/
        !             9: /*  prime decomposition of ideals over                 */
        !            10: /*  finite fields                              */
        !            11: /*        part 1                               */
        !            12: /*     radical computation                     */
        !            13: /*  28/12/2002 for Basic Small Finite Field    */
        !            14: /*   4/1/2003  for Arbitary Small Finite Field */
        !            15: /*==============================================*/
        !            16:
        !            17: /*==============================================*/
        !            18: /*  radical computation of ideals over                 */
        !            19: /*  finite fields by Matsumoto's algorithm     */
        !            20: /*                                             */
        !            21: /* The radical of I is computed as the                 */
        !            22: /* kernel of a power of Frobenius map.         */
        !            23: /*                                             */
        !            24: /*  radical                                    */
        !            25: /*     Input: a list P of polynomials          */
        !            26: /*     Output: a list P1 of polynomials        */
        !            27: /*          such that <P1>=rad(<P>)            */
        !            28: /*                                             */
        !            29: /*  frobeniuskernel_main{2}                    */
        !            30: /*     Input: a list of polynomials P,         */
        !            31: /*            a list of variables VSet,        */
        !            32: /*        and a list of other variables WSet   */
        !            33: /*     Output: a list of polynomials Q         */
        !            34: /*        such that Q is the kernel of         */
        !            35: /*         single Frobenius map: x--> x^q      */
        !            36: /*        where q is the characteristic.       */
        !            37: /*     version 2 uses successive kernel        */
        !            38: /*     computation suggested by Matsumoto      */
        !            39: /*                                             */
        !            40: /*  coefficientfrobeniuskernel                 */
        !            41: /*     Input: a list of polynomials P,         */
        !            42: /*     Output: a list of polynomials Q         */
        !            43: /*        such that Q is the kernel of         */
        !            44: /*         single coefficient Frobenius        */
        !            45: /*        map: a in GF(q) --> a^q              */
        !            46: /*        where q is the characteristic.       */
        !            47: /*                                             */
        !            48: /*  elimination                                        */
        !            49: /*     Input: a list P of polynomials          */
        !            50: /*            a list V of variables            */
        !            51: /*     Output: a list P1 of polynomials        */
        !            52: /*             such that P1={f\in P |          */
        !            53: /*               vars(f)\cap V =\emptyset}     */
        !            54: /*                                             */
        !            55: /*  checkequality                              */
        !            56: /*     Input: a list P of polynomials          */
        !            57: /*            a list Q of polynomials          */
        !            58: /*     Output: 1 if <P>=<Q>                    */
        !            59: /*             0 otherwise                     */
        !            60: /*                                             */
        !            61: /*                                             */
        !            62: /*                                             */
        !            63: /*==============================================*/
        !            64:
        !            65: def radicalideal(P,Choice,VSet)
        !            66:        {
        !            67:
        !            68:        GBTime=0;
        !            69:        Ord=0;
        !            70:
        !            71:        /* VSet=vars(P);*/
        !            72:        WSet=makecounterpart(VSet);
        !            73:
        !            74: T000=time()[0];
        !            75:        P1=dp_gr_f_main(P,VSet,Hom,Ord);
        !            76: T001=time()[0];
        !            77: GBTime +=T001-T000;
        !            78:
        !            79:        if ( Choice == 3 )
        !            80:                {
        !            81:                P2=frobeniuskernel_main3(P1,VSet,WSet);
        !            82:                }
        !            83:        else if ( Choice == 2 )
        !            84:                {
        !            85:                P2=frobeniuskernel_main2(P1,VSet,WSet);
        !            86:                }
        !            87:        else if ( Choice == 4 )
        !            88:                {
        !            89:                P2=frobeniuskernel_main4(P1,VSet,WSet);
        !            90:                }
        !            91:        else
        !            92:                {
        !            93:                P2=frobeniuskernel_main(P1,VSet,WSet);
        !            94:                }
        !            95:
        !            96:        M=checkequality(P1,P2,VSet);
        !            97:
        !            98:        while ( M !=1 )
        !            99:                {
        !           100:                P1=P2;
        !           101:                P2=frobeniuskernel_main2(P2,VSet,WSet);
        !           102:                M=checkequality(P1,P2,VSet);
        !           103:                }
        !           104:
        !           105:        return P1;
        !           106:        }
        !           107:
        !           108:
        !           109: def frobeniuskernel_main(P,VSet,WSet)
        !           110:        {
        !           111:        NV=length(VSet);
        !           112:
        !           113:        NewP=coefficientfrobeniuskernel(P);
        !           114:
        !           115:        NW=length(NewP);
        !           116:
        !           117:        TempP=NewP;
        !           118:
        !           119:        for (K=NW-1;K>=0;K--)
        !           120:                {
        !           121:                Poly=TempP[K];
        !           122:                for (J=0;J<NV;J++)
        !           123:                        {
        !           124:                        Poly=subst(Poly,VSet[J],WSet[J]);
        !           125:                        }
        !           126:                NewP=cons(Poly,NewP);
        !           127:                }
        !           128:
        !           129:        XSet=append(VSet,WSet);
        !           130:        NewOrder=[[0,length(VSet)],[0,length(WSet)]];
        !           131:
        !           132:        Char=setmod_ff()[0];
        !           133:
        !           134:        for (I=0;I<NV;I++)
        !           135:                {
        !           136:                AddPoly=VSet[I]^Char-WSet[I];
        !           137:                NewP=cons(AddPoly,NewP);
        !           138:                }
        !           139:
        !           140:        G=dp_gr_f_main(NewP,XSet,Hom,NewOrder);
        !           141:        PW=elimination(G,WSet);
        !           142:
        !           143:        NW=length(PW);
        !           144:        ANS=[];
        !           145:        for (I=NW-1;I>=0;I--)
        !           146:                {
        !           147:                Poly=PW[I];
        !           148:                for (J=0;J<NV;J++)
        !           149:                        {
        !           150:                        Poly=subst(Poly,WSet[J],VSet[J]);
        !           151:                        }
        !           152:                ANS=cons(Poly,ANS);
        !           153:                }
        !           154:        return ANS;
        !           155:        }
        !           156:
        !           157: def frobeniuskernel_main2(P,VSet,WSet)
        !           158:        {
        !           159:        NV=length(VSet);
        !           160:
        !           161:        NewP=coefficientfrobeniuskernel(P);
        !           162:
        !           163:        XSet=append(VSet,WSet);
        !           164:        NewOrder=[[0,NV],[0,NV]];
        !           165:
        !           166:        Char=setmod_ff()[0];
        !           167:
        !           168:        for (I=0;I<NV;I++)
        !           169:                {
        !           170:                for (J=0;J<NV;J++)
        !           171:                        {
        !           172:                        if ( I == J )
        !           173:                                {
        !           174:                                AddPoly=VSet[J]^Char-WSet[J];
        !           175:                                }
        !           176:                        else
        !           177:                                {
        !           178:                                AddPoly=VSet[J]-WSet[J];
        !           179:                                }
        !           180:                        NewP=cons(AddPoly,NewP);
        !           181:                        }
        !           182:
        !           183: T000=time()[0];
        !           184:                GP=dp_gr_f_main(NewP,XSet,Hom,NewOrder);
        !           185: T001=time()[0];
        !           186: GBTime += T001-T000;
        !           187:
        !           188:                PW=elimination(GP,WSet);
        !           189:                NW=length(PW);
        !           190:                NewP=[];
        !           191:                for (K=NW-1;K>=0;K--)
        !           192:                        {
        !           193:                        Poly=PW[K];
        !           194:                        for (J=0;J<NV;J++)
        !           195:                                {
        !           196:                                Poly=subst(Poly,WSet[J],VSet[J]);
        !           197:                                }
        !           198:                        NewP=cons(Poly,NewP);
        !           199:                        }
        !           200:                }
        !           201:        return NewP;
        !           202:        }
        !           203:
        !           204:
        !           205: def frobeniuskernel_main4(P,VSet,WSet)
        !           206:        {
        !           207:        NV=length(VSet);
        !           208:
        !           209:        NewP=coefficientfrobeniuskernel(P);
        !           210:
        !           211:        XSet=append(VSet,WSet);
        !           212:        NewOrder=[[0,NV],[0,NV]];
        !           213:
        !           214:        Char=setmod_ff()[0];
        !           215:
        !           216:        for (I=0;I<NV;I++)
        !           217:                {
        !           218:                NW=length(NewP);
        !           219:                TempP=NewP;
        !           220:
        !           221:                for (J=0;J<NV;J++)
        !           222:                        {
        !           223:                        if ( I == J )
        !           224:                                {
        !           225:                                AddPoly=VSet[J]^Char-WSet[J];
        !           226:                                }
        !           227:                        else
        !           228:                                {
        !           229:                                AddPoly=VSet[J]-WSet[J];
        !           230:                                }
        !           231:                        NewP=cons(AddPoly,NewP);
        !           232:                        }
        !           233:
        !           234:                /* for (K=NW-1;K>=0;K--)
        !           235:                        {
        !           236:                        Poly=TempP[K];
        !           237:                        for (J=0;J<NV;J++)
        !           238:                                {
        !           239:                                if ( J == I )
        !           240:                                        {
        !           241:                                        Poly=subst(Poly,VSet[J],WSet[J]);
        !           242:                                        }
        !           243:                                else
        !           244:                                        {
        !           245:                                        Poly=subst(Poly,VSet[J],WSet[J]^Char);
        !           246:                                        }
        !           247:                                }
        !           248:                        NewP=cons(Poly,NewP);
        !           249:                        }*/
        !           250: T000=time()[0];
        !           251:                GP=dp_gr_f_main(NewP,XSet,Hom,NewOrder);
        !           252: T001=time()[0];
        !           253: GBTime += T001-T000;
        !           254:
        !           255:                PW=elimination(GP,WSet);
        !           256:                NW=length(PW);
        !           257:                NewP=[];
        !           258:                for (K=NW-1;K>=0;K--)
        !           259:                        {
        !           260:                        Poly=PW[K];
        !           261:                        for (J=0;J<NV;J++)
        !           262:                                {
        !           263:                                Poly=subst(Poly,WSet[J],VSet[J]);
        !           264:                                }
        !           265:                        NewP=cons(Poly,NewP);
        !           266:                        }
        !           267:                }
        !           268:        return NewP;
        !           269:        }
        !           270:
        !           271: def frobeniuskernel_main3(P,VSet,WSet)
        !           272:        {
        !           273:        NV=length(VSet);
        !           274:
        !           275:        NewP=coefficientfrobeniuskernel(P);
        !           276:
        !           277:        Char=setmod_ff()[0];
        !           278:
        !           279:        for (I=0;I<NV;I++)
        !           280:                {
        !           281:                XWSet=[];
        !           282:                for (J=0;J<NV;J++)
        !           283:                        {
        !           284:                        if ( I == J )
        !           285:                                {
        !           286:                                AddPoly=VSet[I]^Char-WSet[I];
        !           287:                                NewP=cons(AddPoly,NewP);
        !           288:                                XWSet=append(XWSet,[WSet[I]]);
        !           289:                                }
        !           290:                        else
        !           291:                                {
        !           292:                                XWSet =append(XWSet,[VSet[J]]);
        !           293:                                }
        !           294:                        }
        !           295:
        !           296:                XSet=cons(VSet[I],XWSet);
        !           297:
        !           298:                NewOrder=[[0,1],[0,NV]];
        !           299: T000=time()[0];
        !           300:                GP=dp_gr_f_main(NewP,XSet,Hom,NewOrder);
        !           301: T001=time()[0];
        !           302: GBTime += T001-T000;
        !           303:
        !           304:                PW=elimination(GP,XWSet);
        !           305:                NW=length(PW);
        !           306:                NewP=[];
        !           307:                for (K=NW-1;K>=0;K--)
        !           308:                        {
        !           309:                        Poly=PW[K];
        !           310:                        Poly=subst(Poly,WSet[I],VSet[I]);
        !           311:                        NewP=cons(Poly,NewP);
        !           312:                        }
        !           313:                }
        !           314:        return NewP;
        !           315:        }
        !           316:
        !           317: def coefficientfrobeniuskernel(P)
        !           318:        {
        !           319:        if ( setmod_ff()[1] == 0 )
        !           320:                {
        !           321:                return P;
        !           322:                }
        !           323:
        !           324:        NP=length(P);
        !           325:        ANS=[];
        !           326:        for (I=0;I<NP;I++)
        !           327:                {
        !           328:                TEST=P[I];
        !           329:                Q=coefficientfrobeniuskernel_main(TEST);
        !           330:                ANS=append(ANS,[Q]);
        !           331:                }
        !           332:        return ANS;
        !           333:        }
        !           334:
        !           335: def coefficientfrobeniuskernel_main(Poly)
        !           336:        {
        !           337:        Vars=vars(Poly);
        !           338:        QP=dp_ptod(Poly,Vars);
        !           339:        ANS=0;
        !           340:        FOrd=deg(setmod_ff()[1],x);
        !           341:        Char=setmod_ff()[0];
        !           342:        Pow=Char^(FOrd-1);
        !           343:
        !           344:        while(QP !=0 )
        !           345:                {
        !           346:                Coef=dp_hc(QP);
        !           347:                HT=dp_ht(QP);
        !           348:
        !           349:                ANS=ANS+Coef^Pow*dp_dtop(HT,Vars);
        !           350:
        !           351:                QP=dp_rest(QP);
        !           352:                }
        !           353:        return ANS;
        !           354:        }
        !           355:
        !           356:
        !           357: def elimination(G,V)
        !           358:        {
        !           359:        ANS=[];
        !           360:        NG=length(G);
        !           361:
        !           362:        for (I=NG-1;I>=0;I--)
        !           363:                {
        !           364:                VSet=vars(G[I]);
        !           365:                DIFF=setminus(VSet,V);
        !           366:
        !           367:                if ( DIFF ==[] )
        !           368:                        {
        !           369:                        ANS=cons(G[I],ANS);
        !           370:                        }
        !           371:                }
        !           372:        return ANS;
        !           373:        }
        !           374:
        !           375: def setminus(A,B)
        !           376:        {
        !           377:        NA=length(A);
        !           378:        NB=length(B);
        !           379:
        !           380:        ANS=[];
        !           381:
        !           382:        for (I=0;I<NA;I++)
        !           383:                {
        !           384:                Flag =0;
        !           385:                for (J=0;J<NB;J++)
        !           386:                        {
        !           387:                        if (A[I] == B[J])
        !           388:                                {
        !           389:                                Flag=1;
        !           390:                                break;
        !           391:                                }
        !           392:                        }
        !           393:
        !           394:                if ( Flag == 0 )
        !           395:                        {
        !           396:                        ANS=append(ANS,[A[I]]);
        !           397:                        }
        !           398:                }
        !           399:        return ANS;
        !           400:        }
        !           401:
        !           402: def makecounterpart(V)
        !           403:        {
        !           404:        NV=length(V);
        !           405:
        !           406:        A="tmp";
        !           407:
        !           408:        ANS=[];
        !           409:        for (I=NV-1;I>=0;I--)
        !           410:                {
        !           411:                T=strtov(A+rtostr(I));
        !           412:                ANS=cons(T,ANS);
        !           413:                }
        !           414:        return ANS;
        !           415:        }
        !           416:
        !           417: def checkequality(P,Q,VSet)
        !           418:        {
        !           419:        QQ=dp_gr_f_main(Q,VSet,Hom,Ord);
        !           420:        PP=dp_gr_f_main(P,VSet,Hom,Ord);
        !           421:
        !           422:        NP=length(PP);
        !           423:        NQ=length(QQ);
        !           424:
        !           425:        VarsP=vars(P);
        !           426:        VarsQ=vars(Q);
        !           427:        if ( NP != NQ || VarsP !=VarsQ )
        !           428:                {
        !           429:                return 0;
        !           430:                }
        !           431:
        !           432:        for (I=0;I<NP;I++)
        !           433:                {
        !           434:                HCP=dp_hc(dp_ptod(PP[I],VSet));
        !           435:                HCQ=dp_hc(dp_ptod(QQ[I],VSet));
        !           436:
        !           437:                if ( HCP*QQ[I]-HCQ*PP[I] != 0 )
        !           438:                        {
        !           439:                        return 0;
        !           440:                        }
        !           441:                }
        !           442:
        !           443:        return 1;
        !           444:        }
        !           445:
        !           446: /*==============================================*/
        !           447: /*  prime decomposition of ideals over          */
        !           448: /*  finite fields                               */
        !           449: /*        part 2                                */
        !           450: /*      ideal dimension                                */
        !           451: /*        3/1/2003                             */
        !           452: /*==============================================*/
        !           453:
        !           454: /*==============================================*/
        !           455: /*  ideal dimension computation                */
        !           456: /*                                              */
        !           457: /* The dimension of I is computed as the               */
        !           458: /* maximal size of MSI sets.                   */
        !           459: /*                                              */
        !           460: /*  idealdimension                              */
        !           461: /*      Input: a list P of polynomials          */
        !           462: /*            a list V of variables            */
        !           463: /*      Output: the dimension of I             */
        !           464: /*           and the MSI with max size         */
        !           465: /*                                              */
        !           466: /*  findmsi                                    */
        !           467: /*      Input: a list of head monomials         */
        !           468: /*         and a list of variables             */
        !           469: /*      Output: a list of all MSI sets         */
        !           470: /*             and SI sets                     */
        !           471: /*                                              */
        !           472: /*  findmsi_main                               */
        !           473: /*      Input: a list P of polynomials          */
        !           474: /*             a list V of variables            */
        !           475: /*      Output: a list P1 of polynomials        */
        !           476: /*              such that P1={f\in P |          */
        !           477: /*                vars(f)\cap V =\emptyset}     */
        !           478: /*                                              */
        !           479: /*  headtermset                                        */
        !           480: /*      Input: a list P of polynomials          */
        !           481: /*             a list V of variables           */
        !           482: /*      Output: a list of head monomials       */
        !           483: /*                                              */
        !           484: /*                                              */
        !           485: /*                                              */
        !           486: /*==============================================*/
        !           487:
        !           488: def idealdimension(P,V,Ord)
        !           489:        {
        !           490:        GP=dp_gr_f_main(P,V,Hom,Ord);
        !           491:        HeadTermset=headtermset(GP,V,Ord);
        !           492:        MSIset=findmsi(HeadTermset,V);
        !           493:        if ( MSIset == [] )
        !           494:                {
        !           495:                return [0,[]];
        !           496:                }
        !           497:        Index=findmaxindex(MSIset);
        !           498:        MSI=MSIset[Index];
        !           499:        Dimension=length(MSI);
        !           500:        return [Dimension, MSI];
        !           501:        }
        !           502:
        !           503: def findmaxindex(S)
        !           504:        {
        !           505:        NS=length(S);
        !           506:        Index=0;
        !           507:        Defaultsize=length(S[0]);
        !           508:        for (I=1;I<NS;I++)
        !           509:                {
        !           510:                Targetsize=length(S[I]);
        !           511:
        !           512:                if ( Targetsize > Defaultsize )
        !           513:                        {
        !           514:                        Index=I;
        !           515:                        }
        !           516:                Defaultsize= Targetsize;
        !           517:                }
        !           518:        return Index;
        !           519:        }
        !           520:
        !           521: def headtermset(P,V,Ord)
        !           522:        {
        !           523:        ANS=[];
        !           524:        NP=length(P);
        !           525:        for ( I=NP-1;I>=0;I--)
        !           526:                {
        !           527:                Head=headterm(P[I],V,Ord);
        !           528:                ANS=cons(Head,ANS);
        !           529:                }
        !           530:        return ANS;
        !           531:        }
        !           532:
        !           533: def headterm(P,V,Ord)
        !           534:        {
        !           535:        dp_ord(Ord);
        !           536:        Q=dp_ptod(P,V);
        !           537:        Headdp=dp_hm(Q);
        !           538:        Head=dp_dtop(Headdp,V);
        !           539:        return Head;
        !           540:        }
        !           541:
        !           542: def findmsi_main(TermsetIndex,MSIsetIndex,Int,N)
        !           543:        {
        !           544:        ANS=[];
        !           545:        BNS=[];
        !           546:        TempMSIsetIndex=MSIsetIndex;
        !           547:
        !           548:        if (Int == 0)
        !           549:                {
        !           550:                for ( I=0;I<N;I++)
        !           551:                        {
        !           552:                        TEST1=[I];
        !           553:                        Check=intersection(TermsetIndex,TEST1);
        !           554:                        if ( Check == 0 )
        !           555:                                {
        !           556:                                ANS=cons(TEST1,ANS);
        !           557:                                }
        !           558:                        }
        !           559:                }
        !           560:
        !           561:        while( Int !=0 && TempMSIsetIndex != [] )
        !           562:                {
        !           563:                TEST=TempMSIsetIndex[0];
        !           564:                Flag=0;
        !           565:                for ( I=TEST[0]+1;I<N;I++)
        !           566:                        {
        !           567:                        TEST1=cons(I,TEST);
        !           568:                        Check=intersection(TermsetIndex,TEST1);
        !           569:                        if ( Check == 0 )
        !           570:                                {
        !           571:                                Flag=1;
        !           572:                                ANS=cons(TEST1,ANS);
        !           573:                                }
        !           574:                        }
        !           575:                if ( Flag == 0 )
        !           576:                        {
        !           577:                        BNS=cons(TEST,BNS);
        !           578:                        }
        !           579:                TempMSIsetIndex=cdr(TempMSIsetIndex);
        !           580:                }
        !           581:        return [ANS,BNS];
        !           582:        }
        !           583:
        !           584: def findmsi(Termset,Vset)
        !           585:        {
        !           586:        ANS=[];
        !           587:        MSIsetIndex=[];
        !           588:        N=length(Vset);
        !           589:        TermsetIndex=makeindex(Termset,Vset);
        !           590:
        !           591:        for (I=0;I<N;I++)
        !           592:                {
        !           593:                Temp=findmsi_main(TermsetIndex,ANS,I,N);
        !           594:                ANS=Temp[0];
        !           595:                BNS=Temp[1];
        !           596:                MSIsetIndex=append(BNS,MSIsetIndex);
        !           597:                }
        !           598:
        !           599:        MSIsetIndex=append(ANS,MSIsetIndex);
        !           600:        MSIset=makevarset(MSIsetIndex,Vset);
        !           601:        return MSIset;
        !           602:        }
        !           603:
        !           604: def makeindex(Termset,Vset)
        !           605:        {
        !           606:        ANS=[];
        !           607:
        !           608:        N=length(Vset);
        !           609:
        !           610:        TempTermset=Termset;
        !           611:        while( TempTermset !=[] )
        !           612:                {
        !           613:                TEST=TempTermset[0];
        !           614:                Index=[];
        !           615:                for (I=0;I<N;I++)
        !           616:                        {
        !           617:                        Q=srem(TEST,Vset[I]);
        !           618:                        if ( Q == 0 )
        !           619:                                {
        !           620:                                Index=cons(I,Index);
        !           621:                                }
        !           622:                        }
        !           623:                ANS=cons(Index,ANS);
        !           624:                TempTermset=cdr(TempTermset);
        !           625:                }
        !           626:        return ANS;
        !           627:        }
        !           628:
        !           629: def makevarset(IndexSet,Vset)
        !           630:        {
        !           631:        ANS=[];
        !           632:        NI=length(IndexSet);
        !           633:
        !           634:        for (I=0;I<NI;I++)
        !           635:                {
        !           636:                TEST=IndexSet[I];
        !           637:
        !           638:                TestV=makevar(TEST,Vset);
        !           639:                ANS=append(ANS,[TestV]);
        !           640:                }
        !           641:        return ANS;
        !           642:        }
        !           643:
        !           644: def makevar(Index,Vset)
        !           645:        {
        !           646:        ANS=[];
        !           647:        TempIndex=Index;
        !           648:
        !           649:        while( TempIndex !=[] )
        !           650:                {
        !           651:                ANS=cons(Vset[TempIndex[0]],ANS);
        !           652:                TempIndex=cdr(TempIndex);
        !           653:                }
        !           654:
        !           655:        return ANS;
        !           656:        }
        !           657:
        !           658: def intersection(IndexSet,TestIndex)
        !           659:        {
        !           660:        TempIndexSet=IndexSet;
        !           661:
        !           662:        while(TempIndexSet !=[] )
        !           663:                {
        !           664:                Sample=TempIndexSet[0];
        !           665:
        !           666:                Inclusion=testinclusion(Sample,TestIndex);
        !           667:
        !           668:                if ( Inclusion == 1 )
        !           669:                        {
        !           670:                        return 1;
        !           671:                        }
        !           672:
        !           673:                TempIndexSet=cdr(TempIndexSet);
        !           674:                }
        !           675:        return 0;
        !           676:        }
        !           677:
        !           678: def testinclusion(Sample,Test)
        !           679:        {
        !           680:        NS=length(Sample);
        !           681:        NT=length(Test);
        !           682:
        !           683:        for (I=0;I<NS;I++)
        !           684:                {
        !           685:                Flag=0;
        !           686:                for (J=0;J<NT;J++)
        !           687:                        {
        !           688:                        if (Sample[I]==Test[J])
        !           689:                                {
        !           690:                                Flag=1;
        !           691:                                break;
        !           692:                                }
        !           693:                        }
        !           694:                if ( Flag == 0 )
        !           695:                        {
        !           696:                        return 0;
        !           697:                        }
        !           698:                }
        !           699:        return 1;
        !           700:        }
        !           701:
        !           702:
        !           703: /*======================================================*/
        !           704: /*  prime decomposition of ideals over                 */
        !           705: /*  small finite fields                                */
        !           706: /*        part 3                                       */
        !           707: /*      prime decomposition                            */
        !           708: /*       9/1/2003  1st Implementation                  */
        !           709: /*       11/1/2003  Divid 3 cases in zeroprime         */
        !           710: /*             decomposition             (3a)          */
        !           711: /*       12/1/2003 Redundant elimination (3e)          */
        !           712: /*       13/1/2003 gr_fctr_sf version    (3f)          */
        !           713: /*       14/1/2003 Flag on Early Termination           */
        !           714: /*       15/1/2002 drl version                         */
        !           715: /*       17/1/2002 depth oriented search               */
        !           716: /*       17/1/2002 dimension oriented search           */
        !           717: /*                                                     */
        !           718: /*  global variables                                   */
        !           719: /*  Hom: used in dp_gr_f_main                          */
        !           720: /*  DIVLIST: the set of prime ideals                   */
        !           721: /*  ORIGINAL: the GB of the original input ideal       */
        !           722: /*  ORIGINALDIMENSION: the dimension                   */
        !           723: /*  STOP: the flag on terminatation                    */
        !           724: /*  Trials: a bound on the number of trials             */
        !           725: /*  REM: the vector list of remaining ideals           */
        !           726: /*                                                     */
        !           727: /*======================================================*/
        !           728:
        !           729: /*======================================================*/
        !           730: /*     prime decomposition                             */
        !           731: /*                                                     */
        !           732: /*                                                     */
        !           733: /*  primedec(P,V,Ord,F)                                */
        !           734: /*      Input: a list P of polynomials                 */
        !           735: /*             a list V of variables                   */
        !           736: /*            a term order Ord                         */
        !           737: /*            a flag F on Early Termination            */
        !           738: /*      Output: 0                                      */
        !           739: /*     DVILIST: the set of prime divisors of <P>       */
        !           740: /*  [subprocedure]                                     */
        !           741: /*      o --gr_fctr_sf    (mplex2)                     */
        !           742: /*      o --primedecomposition                         */
        !           743: /*  Remark: if F = 1, we empoly Early Termination      */
        !           744: /*                                                     */
        !           745: /*                                                     */
        !           746: /*  primedecomposition(P,V,Ord,C,F)                    */
        !           747: /*      Input: a list P of polynomials                 */
        !           748: /*             a list V of variables                   */
        !           749: /*            a term order Ord                         */
        !           750: /*            a level C of recursive call              */
        !           751: /*            a flag F on Early Termination            */
        !           752: /*      Output: 0                                      */
        !           753: /*     DVILIST: the set of prime divisors of <P>^ec    */
        !           754: /*  [subprocedure]                                     */
        !           755: /*      o --idealdimension (part2)                     */
        !           756: /*      o --setminus      (part1)                      */
        !           757: /*      o --zeroprimedecomposition                     */
        !           758: /*      o --extcont                                    */
        !           759: /*      o --checkadd2                                  */
        !           760: /*      o --ideal_intersection_sfrat                   */
        !           761: /*      o --radical_equality                           */
        !           762: /*                                                     */
        !           763: /*  zeroprimedecomposition(P,V,W)                      */
        !           764: /*      Input: a list P of polynomials                 */
        !           765: /*                     lists V,W of variables                  */
        !           766: /*             such that <P> is 0-dimensional          */
        !           767: /*             in K[V] and W is the original set       */
        !           768: /*             of variables                            */
        !           769: /*      Output: the set of prime/primary               */
        !           770: /*             divisors of <P>                         */
        !           771: /*             (P is a GB w.r.t. DRL)                  */
        !           772: /*  [subprocedure]                                     */
        !           773: /*      o --partical_decomp (mplex2)                   */
        !           774: /*      o --checkgeneric                               */
        !           775: /*      o --separableclosure                           */
        !           776: /*      o --zerogenericprimedecomposition              */
        !           777: /*      o --zeroseparableprimedecomposition            */
        !           778: /*      o --convertdivisor                             */
        !           779: /*      o --contraction                                */
        !           780: /*      o --radicalideal (part1)                       */
        !           781: /*                                                     */
        !           782: /*  extcont(P,V,Ord)                                   */
        !           783: /*      Input: a list P of polynomials                 */
        !           784: /*                     a set V of variables                    */
        !           785: /*      Output: a polynomial f                         */
        !           786: /*                     such that \sqrt<P>^c=\sqrt(P:f)         */
        !           787: /*         Then \sqrt<P>=\sqrt(P:f)\cap \sqrt(P+<f>)   */
        !           788: /*                                                     */
        !           789: /*  separableclosure([P,MP],V,W)                       */
        !           790: /*      Input: a pair [P,MP] of a list P of            */
        !           791: /*             polynomials and a list MP of            */
        !           792: /*             minimal polynomials of variables        */
        !           793: /*                     list V,W of variables                   */
        !           794: /*             such that <P> is 0-dimensional          */
        !           795: /*             in K[V] and W is the original set       */
        !           796: /*             of variables                            */
        !           797: /*      Output: [Q,E], a list Q of polynomials         */
        !           798: /*              an exponent vector E                   */
        !           799: /*                      such that <Q> is the separable         */
        !           800: /*              closure of <P>                         */
        !           801: /*  [subprocedure]                                     */
        !           802: /*      o --makecounterpart(part1)                     */
        !           803: /*      o --elimination(part1)                         */
        !           804: /*      o --checkseparable                             */
        !           805: /*                                                     */
        !           806: /*  zeroseparableprimedecomposition(P,V,W)             */
        !           807: /*      Input: a list P of polynomials                 */
        !           808: /*             lists V,W of variables                  */
        !           809: /*             such that <P> is 0-dimensional          */
        !           810: /*             and all minimal polynomial              */
        !           811: /*             are irreducible (i.e. <P> is an         */
        !           812: /*             intermediate ideal in the paper         */
        !           813: /*                     or the output of partial_decomp)        */
        !           814: /*             in K[V] and W is the original set       */
        !           815: /*             of variables                            */
        !           816: /*      Output: the set of prime/primary               */
        !           817: /*              divisors of <P>                        */
        !           818: /*  [subprocedure]                                     */
        !           819: /*      o --findgeneric                                */
        !           820: /*      o --elimination(part1)                         */
        !           821: /*                                                     */
        !           822: /*  zerogenericprimedecomposition([P,MP],M,V,W)        */
        !           823: /*      Input: a pair [P,MP] of a list P of            */
        !           824: /*             polynomials and a list MP of            */
        !           825: /*             minimal polynomials of variables        */
        !           826: /*             such that <P> is 0-dimensional          */
        !           827: /*             and M is a minimal poly of a            */
        !           828: /*             variable in generic position            */
        !           829: /*             in K[V] and W is the original           */
        !           830: /*             set of variables                        */
        !           831: /*      Output: the set of prime/primary               */
        !           832: /*             divisors of <P>                         */
        !           833: /*  [subprocedure]                                     */
        !           834: /*                                                     */
        !           835: /*  convertdivisor(P,V,W,E)                            */
        !           836: /*      Input: a list P of polynomials                 */
        !           837: /*                     list V,W of variables                   */
        !           838: /*             such that <P> is a primary/prime        */
        !           839: /*             0-dimensional ideal in K[V] and         */
        !           840: /*             W is the original set                   */
        !           841: /*             of variables                            */
        !           842: /*             the exponent vector E                   */
        !           843: /*      Output: the corresponding prime ideal          */
        !           844: /*             in K[W]                                 */
        !           845: /*  [subprocedure]                                     */
        !           846: /*      o --elimination(part1)                         */
        !           847: /*                                                     */
        !           848: /*  contraction(P,V,W)                                 */
        !           849: /*      Input: a list P of polynomials                 */
        !           850: /*                     list V,W of variables                   */
        !           851: /*             such that <P> is a primary/prime        */
        !           852: /*             0-dimensional ideal in K[V] and         */
        !           853: /*             W is the original set                   */
        !           854: /*             of variables                            */
        !           855: /*      Output: the contraction <P>^c in K[W]          */
        !           856: /*                                                     */
        !           857: /*  findgeneric(P,V)                                   */
        !           858: /*      Input: a list P of polynomials                 */
        !           859: /*                     a list V of variables                   */
        !           860: /*             such that <P> is a separable            */
        !           861: /*             0-dimensional ideal in K[V]             */
        !           862: /*      Output: [F,Min,X], a polynomial F in           */
        !           863: /*             generic position, its minimal           */
        !           864: /*                     polynomial Min in a new variable        */
        !           865: /*                     X                                       */
        !           866: /*  [subprocedure]                                     */
        !           867: /*      o --lineardimension                            */
        !           868: /*      o --makemagic                                  */
        !           869: /*      o --minipoly_sf (mplex2)                       */
        !           870: /*                                                     */
        !           871: /*======================================================*/
        !           872:
        !           873: def primedec_mod(P,VSet,Ord,Mod,Strategy)
        !           874: {
        !           875:        for ( Q = Mod, E = 1; Q < 2^14; Q *= Mod, E++ );
        !           876:        Q /= Mod;
        !           877:        E--;
        !           878:        if ( !(E%2) ) {
        !           879:                Q /= Mod;
        !           880:                E--;
        !           881:        }
        !           882:        setmod_ff(Mod,E);
        !           883:        Pq = map(simp_ff,P);
        !           884:        primedec_sf(Pq,VSet,Ord,Strategy);
        !           885:        R = convsf(DIVLIST,VSet,0,1);
        !           886:        return R;
        !           887: }
        !           888:
        !           889:
        !           890: def primedec_sf(P,VSet,Ord,Strategy)
        !           891:        {
        !           892:        /* DIVLIST = the set of all computed candidates for iredundant divisors */
        !           893:        /* INTIDEAL = the intersection of all computed candidates               */
        !           894:        /* ORIGINAL = a Groebner basis of the input ideal <P> w.r.t. Ord        */
        !           895:        /* ORIGINALDIMENSION = the dimension of the input ideal <P>             */
        !           896:        /* STOP = the flag on termination                                       */
        !           897:        /* REM = the list of remaining  ideals                                  */
        !           898:
        !           899:        T0 = time();
        !           900:        T_GRF=0;
        !           901:        T_INT=0;
        !           902:        T_PD=0;
        !           903:        T_MP=0;
        !           904:        DIVLIST=[];
        !           905:        INTIDEAL=[];
        !           906:        STOP=0;
        !           907:        B_Win=0;
        !           908:        D_Win=0;
        !           909:
        !           910:        ORIGINAL=dp_gr_f_main(P,VSet,Hom,Ord);
        !           911:
        !           912:        Dimeset=idealdimension(ORIGINAL,VSet,Ord);
        !           913:        ORIGINALDIMENSION=Dimeset[0];
        !           914:
        !           915:        /* REM0=newvect(ORIGINALDIMENSION+1);*/
        !           916:        REM=newvect(ORIGINALDIMENSION+1);
        !           917:
        !           918:        for (I=0;I<ORIGINALDIMENSION+1;I++)
        !           919:                {
        !           920:                /* REM0[I]=[];*/
        !           921:                REM[I]=[];
        !           922:                }
        !           923:
        !           924:        print("The dimension of the ideal is ",2);print(ORIGINALDIMENSION,2);
        !           925:        print(". ");
        !           926:
        !           927:        if ( ORIGINALDIMENSION == 0 )
        !           928:                {
        !           929:                Strategy = 0;
        !           930:                STOP = 0;
        !           931:                }
        !           932:
        !           933:        ANS=gr_fctr_sf([ORIGINAL],VSet,Ord);
        !           934:        NANS=length(ANS);
        !           935:        print("There are ",2);print(NANS,2);print(" partial components. ");
        !           936:
        !           937:        for (I=0;I<NANS;I++)
        !           938:                {
        !           939:                TempI=ANS[I];
        !           940:                DimI=idealdimension(TempI,VSet,Ord)[0];
        !           941:
        !           942:                REM[ORIGINALDIMENSION-DimI]=cons(TempI,REM[ORIGINALDIMENSION-DimI]);
        !           943:                }
        !           944:
        !           945:        REM[0]=ANS;
        !           946:
        !           947:        INDEX=0;
        !           948:
        !           949:        while  ( INDEX != -1 )
        !           950:                {
        !           951:                /* print("We deal with the ",2);print(I,2);print("-th partial component. ");*/
        !           952:
        !           953:                TESTIDEAL=car(REM[INDEX]);
        !           954:                REM[INDEX]=cdr(REM[INDEX]);
        !           955:                primedecomposition(TESTIDEAL,VSet,Ord,INDEX,Strategy);
        !           956:
        !           957:                if (STOP == 1 )
        !           958:                        {
        !           959:                        DIVLIST = prime_irred_sf_by_first(DIVLIST,VSet,0);
        !           960:                        DIVLIST = monic_sf_first(DIVLIST,VSet);
        !           961:                        print("We finish the computation. ");
        !           962:                        T_TOTAL = time()[3]-T0[3];
        !           963:                        print(["T_TOTAL",T_TOTAL,"T_GRF",T_GRF,"T_PD",T_PD,"T_MP",T_MP,"T_INT",T_INT,"B_Win",B_Win,"D_Win",D_Win]);
        !           964:                        return 0;
        !           965:                        }
        !           966:
        !           967:                INDEX=findindex(REM);
        !           968:                }
        !           969:
        !           970:        DIVLIST = prime_irred_sf_by_first(DIVLIST,VSet,0);
        !           971:        DIVLIST = monic_sf_first(DIVLIST,VSet);
        !           972:        T_TOTAL = time()[3]-T0[3];
        !           973:        print(["T_TOTAL",T_TOTAL,"T_GRF",T_GRF,"T_PD",T_PD,"T_MP",T_MP,"T_INT",T_INT,"B_Win",B_Win,"D_Win",D_Win]);
        !           974:        return 0;
        !           975:        }
        !           976:
        !           977:
        !           978:
        !           979:
        !           980:
        !           981: def findindex(VECTORLIST)
        !           982:        {
        !           983:        NL=size(VECTORLIST)[0];
        !           984:
        !           985:        for (I=0;I<NL;I++)
        !           986:                {
        !           987:                if ( VECTORLIST[I] == [] )
        !           988:                        {
        !           989:                        continue;
        !           990:                        }
        !           991:                return I;
        !           992:                }
        !           993:        return -1;
        !           994:        }
        !           995:
        !           996: #if 0
        !           997: def checkadd2(ADD,TESTADDLIST,VSet)
        !           998:        {
        !           999:        /* This function will be used for eliminating redundant divisors        */
        !          1000:
        !          1001:        NTESTADDLIST=length(TESTADDLIST);
        !          1002:        for (I=0;I<NTESTADDLIST;I++)
        !          1003:                {
        !          1004:                TESTLIST=TESTADDLIST[I][0];
        !          1005:
        !          1006:                if ( setminus(TESTLIST,ADD) == [] )
        !          1007:                        {
        !          1008:                        return 1;
        !          1009:                        }
        !          1010:                if ( inclusion_test(TESTLIST,ADD,VSet,Ord) == 1 )
        !          1011:                        {
        !          1012:                        return 1;
        !          1013:                        }
        !          1014:                }
        !          1015:        return 0;
        !          1016:        }
        !          1017: #endif
        !          1018:
        !          1019: def checkadd2a(ADD,DIM,TESTADDLIST,VSet)
        !          1020:        {
        !          1021:        /* This function will be used for eliminating redundant divisors        */
        !          1022:
        !          1023:        NTESTADDLIST=length(TESTADDLIST);
        !          1024:        for (I=0;I<NTESTADDLIST;I++)
        !          1025:                {
        !          1026:                TESTLIST=TESTADDLIST[I][0];
        !          1027:                TESTDIM=TESTADDLIST[I][1];
        !          1028:
        !          1029:                if (DIM > TESTDIM )
        !          1030:                        {
        !          1031:                        continue;
        !          1032:                        }
        !          1033:
        !          1034:                if ( setminus(TESTLIST,ADD) == [] )
        !          1035:                        {
        !          1036:                        return 1;
        !          1037:                        }
        !          1038:                if ( inclusion_test(TESTLIST,ADD,VSet,Ord) == 1 )
        !          1039:                        {
        !          1040:                        return 1;
        !          1041:                        }
        !          1042:                }
        !          1043:        return 0;
        !          1044:        }
        !          1045:
        !          1046: def checkadd3(ADD,TESTADDLIST,VSet)
        !          1047:        {
        !          1048:        /* This function will be used for eliminating redundant divisors        */
        !          1049:
        !          1050:        NTESTADDLIST=length(TESTADDLIST);
        !          1051:        for (I=0;I<NTESTADDLIST;I++)
        !          1052:                {
        !          1053:                TESTLIST=TESTADDLIST[I];
        !          1054:
        !          1055:                if ( setminus(TESTLIST,ADD) == [] )
        !          1056:                        {
        !          1057:                        return 1;
        !          1058:                        }
        !          1059:
        !          1060:
        !          1061:                /* if ( inclusion_test(TESTLIST,ADD,VSet,0) == 1 )
        !          1062:                        {
        !          1063:                        return 1;
        !          1064:                        }*/
        !          1065:                }
        !          1066:        return 0;
        !          1067:        }
        !          1068:
        !          1069: def radical_equality(A,B,VSet,Ord)
        !          1070:        {
        !          1071:        /* This function will be used for checking the termination.     */
        !          1072:
        !          1073:        NA=length(A);
        !          1074:
        !          1075:        Ord1=[[0,1],[0,length(VSet)]];
        !          1076:        Vt=newt;
        !          1077:
        !          1078:        for (I=0;I<NA;I++)
        !          1079:                {
        !          1080:                NewB=cons(1-newt*A[I],B);
        !          1081:                GB = dp_gr_f_main(NewB,cons(Vt,VSet),0,Ord1);
        !          1082:                K=elimination(GB,VSet);
        !          1083:
        !          1084:                if ( vars(K) !=[] )
        !          1085:                        {
        !          1086:                        return 0;
        !          1087:                        }
        !          1088:
        !          1089:                }
        !          1090:
        !          1091:        return 1;
        !          1092:        }
        !          1093:
        !          1094: def primedecomposition(P,VSet,Ord,COUNTER,Strategy)
        !          1095:        {
        !          1096:        /* DIVLIST = the set of all computed candidates for iredundant divisors */
        !          1097:        /* INTIDEAL = the intersection of all computed candidates               */
        !          1098:        /* ORIGINAL = a Groebner basis of the input ideal <P> w.r.t. Ord        */
        !          1099:        /* ORIGINALDIMENSION = the dimension of the input ideal <P>             */
        !          1100:
        !          1101:        RP=P;
        !          1102:        GP=dp_gr_f_main(RP,VSet,Hom,Ord);
        !          1103:
        !          1104:        /* First we compute the MSI and the dimension of the    */
        !          1105:        /* ideal <P> in K[Vset], where K is the ground field.   */
        !          1106:
        !          1107:        Dimeset=idealdimension(GP,VSet,Ord);
        !          1108:        Dimension=Dimeset[0];
        !          1109:        MSI=Dimeset[1];
        !          1110:
        !          1111:        print("The dimension of the ideal is ",2); print(Dimension,2);
        !          1112:        print(".");
        !          1113:
        !          1114:        TargetVSet=setminus(VSet,MSI);
        !          1115:        NewGP=dp_gr_f_main(GP,TargetVSet,Hom,Ord);
        !          1116:
        !          1117:        if ( vars(NewGP) == [] )
        !          1118:                {
        !          1119:                return [];
        !          1120:                }
        !          1121:
        !          1122:        /* Then the ideal is 0-dimension in K[TargetVSet].      */
        !          1123:
        !          1124:        print("We enter Zero-dimension Prime Decomposition. ",2);
        !          1125:
        !          1126:        QP=zeroprimedecomposition(NewGP,TargetVSet,VSet);
        !          1127:
        !          1128:        ANS=[];
        !          1129:        NQP=length(QP);
        !          1130:
        !          1131:        print("The number of the newly found component is ",2);
        !          1132:        print(NQP,2);print(". ",2);
        !          1133:
        !          1134:        for (I=0;I<NQP;I++)
        !          1135:                {
        !          1136:                ZPrimeideal=QP[I];
        !          1137:                Primedivisor=ZPrimeideal;
        !          1138:                CHECKADD=checkadd2a(Primedivisor,Dimension,DIVLIST,VSet);
        !          1139:                if (CHECKADD == 0 )
        !          1140:                        {
        !          1141:                        DIVLIST=append(DIVLIST,[[Primedivisor,Dimension]]);
        !          1142:
        !          1143:                        if (Strategy != 1 )
        !          1144:                                {
        !          1145:                                /* NO-OPERATION */
        !          1146:                                }
        !          1147:                        else if ( COUNTER == 0 && Dimension == 0 && ORIGINALDIMENSION == 0 )
        !          1148:                                {
        !          1149:                                /* NO-OPERATION */
        !          1150:                                }
        !          1151:                        else if ( INTIDEAL == [] )
        !          1152:                                {
        !          1153:                                INTIDEAL=Primedivisor;
        !          1154:                                }
        !          1155:                        else
        !          1156:                                {
        !          1157:                                INTIDEAL=ideal_intersection_sfrat(Primedivisor,INTIDEAL,VSet);
        !          1158:                                }
        !          1159:                        }
        !          1160:                }
        !          1161:
        !          1162:        /* We compute prime decomposition for remaining ideal   */
        !          1163:        /* I+<ExtPoly> by recursive call.                       */
        !          1164:
        !          1165:        if ( Strategy == 1 )
        !          1166:                {
        !          1167:                CHECK=radical_equality(INTIDEAL,ORIGINAL,VSet,Ord);
        !          1168:
        !          1169:                if (CHECK==1)
        !          1170:                        {
        !          1171:                        print("We already obtain all divisor. ");
        !          1172:                        STOP = 1;
        !          1173:                        return 0;
        !          1174:                        }
        !          1175:                }
        !          1176:
        !          1177:
        !          1178:        if ( Dimension == 0 )
        !          1179:                {
        !          1180:                return 0;
        !          1181:                }
        !          1182:
        !          1183:        Ord1 = [[0,length(TargetVSet)],[0,length(MSI)]];
        !          1184:        GP1 = dp_gr_f_main(GP,append(TargetVSet,MSI),Hom,Ord1);
        !          1185:        ExtpolyFactor=extcont_factor(GP1,TargetVSet,0);
        !          1186:
        !          1187:        COUNTER=COUNTER+1;
        !          1188:
        !          1189:        for ( Tmp = ExtpolyFactor; Tmp != []; Tmp = cdr(Tmp) )
        !          1190:                {
        !          1191:                AddPoly=car(Tmp);
        !          1192:
        !          1193:                NewGP=cons(AddPoly,GP);
        !          1194:
        !          1195:                GP1 = dp_gr_f_main(cons(AddPoly,GP),VSet,Hom,Ord);
        !          1196:
        !          1197:                if ( Strategy == 1 )
        !          1198:                        {
        !          1199:                        CHECKADD=radical_equality(INTIDEAL,NewGP,VSet,Ord);
        !          1200:
        !          1201:                        if ( CHECKADD != 0 )
        !          1202:                                {
        !          1203:                                print("Avoid unnecessary computation. ",2);
        !          1204:                                continue;
        !          1205:                                }
        !          1206:                        }
        !          1207:
        !          1208:
        !          1209:                DimI=idealdimension(GP1,VSet,Ord)[0];
        !          1210:
        !          1211:                if ( REM[ORIGINALDIMENSION-DimI] !=[] )
        !          1212:                        {
        !          1213:                        REM[ORIGINALDIMENSION-DimI]=cons(GP1,REM[ORIGINALDIMENSION-DimI]);
        !          1214:                        }
        !          1215:                else
        !          1216:                        {
        !          1217:                        REM[ORIGINALDIMENSION-DimI]=[GP1];
        !          1218:                        }
        !          1219:
        !          1220:                /* primedecomposition(GP1,VSet,Ord,COUNTER,Strategy);
        !          1221:                if ( STOP == 1)
        !          1222:                        {
        !          1223:                        return 0;
        !          1224:                        }*/
        !          1225:                }
        !          1226:        return 0;
        !          1227:        }
        !          1228:
        !          1229: /* returns 1 if Poly is a subset of Id(GB) */
        !          1230: /* we assume GB is a gb wrt (V,Ord)        */
        !          1231:
        !          1232: def inclusion_test(Poly,GB,V,Ord)
        !          1233: {
        !          1234:        Len = length(GB);
        !          1235:        PS = newvect(Len);
        !          1236:        dp_ord(Ord);
        !          1237:        for ( J = 0, T = GB; T != []; T = cdr(T), J++ )
        !          1238:                PS[J] = dp_ptod(car(T),V);
        !          1239:        for ( J = Len-1, Ind = []; J >= 0; J-- )
        !          1240:                Ind = cons(J,Ind);
        !          1241:
        !          1242:        for ( T = Poly; T != []; T = cdr(T) )
        !          1243:                if ( nf_sfrat(Ind,dp_ptod(car(T),V),1,PS)[0] )
        !          1244:                        return 0;
        !          1245:        return 1;
        !          1246: }
        !          1247:
        !          1248:
        !          1249: def zeroprimedecomposition(P,TargetVSet,VSet)
        !          1250:        {
        !          1251:        /* We compute prime decomposition for an ideal <P>      */
        !          1252:        /* such that <P> is 0-dimensional in K[TargetVSet].     */
        !          1253:
        !          1254:        PD=partial_decomp(P,TargetVSet);
        !          1255:
        !          1256:        /* each ideal in PD is an intermediate ideal,           */
        !          1257:        /* i.e., all minimal polynomials are irreducible.       */
        !          1258:        /* Thus, each ideal is very likely a prime ideal.       */
        !          1259:        /* PD=[[P,MP],...], where P is a GB w.r.t. DRL and      */
        !          1260:        /* MP is the set of all minimal polynomials.            */
        !          1261:
        !          1262:        NPD=length(PD);
        !          1263:        ANS=[];
        !          1264:
        !          1265:        for (I=0;I<NPD;I++)
        !          1266:                {
        !          1267:                COMP=PD[I];
        !          1268:
        !          1269:                /* check if the ideal has a variable in generic position*/
        !          1270:
        !          1271:                CHECK=checkgeneric(COMP,TargetVSet,VSet);
        !          1272:
        !          1273:                /* If there is a variable in generic position, then we apply a special  */
        !          1274:                /* procedure (zerogenericprimedecomposition). Otherwise we apply a      */
        !          1275:                /* general procedure (zeroseparableprimedecomposition).                 */
        !          1276:                /*                                                                      */
        !          1277:                /* CHECK=[1,M], where M is the minimal polynomail of a variable x       */
        !          1278:                /* such that x is in generic position, if there is such a variable x.   */
        !          1279:                /* Otherwise, CHECK=0.                                                  */
        !          1280:
        !          1281:                if (CHECK != 0 )
        !          1282:                        {
        !          1283:                        if ( TargetVSet != VSet )
        !          1284:                                {
        !          1285:                                PDiv=contraction(COMP[0],TargetVSet,VSet)[0];
        !          1286:                                }
        !          1287:                        else
        !          1288:                                {
        !          1289:                                PDiv=COMP[0];
        !          1290:                                }
        !          1291:
        !          1292:                        ZDecomp=[PDiv];
        !          1293:
        !          1294:                        print("An intermediate ideal is of generic type. ");
        !          1295:                        }
        !          1296:                else
        !          1297:                        {
        !          1298:                        print("An intermediate ideal is not of generic type. ",2);
        !          1299:
        !          1300:                        /* We compute the separable closure of <P> by using minimal polynomails.*/
        !          1301:                        /* separableclosure outputs                                             */
        !          1302:                        /* [a GB Q of separable closure, the exponent vector].                  */
        !          1303:                        /* If <P> is already separable, then the exponent vector is 0.          */
        !          1304:
        !          1305:                        Sep=separableclosure(COMP,TargetVSet,VSet);
        !          1306:
        !          1307:                        /* Then, we compute prime divisors of the separable closure by using    */
        !          1308:                        /* generic position.                                                    */
        !          1309:                        /* If Sep[1]=0, COMP[0] is already separable ideal, and hence,          */
        !          1310:                        /* we do not apply radicalideal to its divisors.                        */
        !          1311:
        !          1312:                        if ( Sep[1] != 0 )
        !          1313:                                {
        !          1314:                                print("The ideal is inseparable. ",2);
        !          1315:                                CHECK2=checkgeneric2(Sep[2]);
        !          1316:                                }
        !          1317:                        else
        !          1318:                                {
        !          1319:                                print("The ideal is already separable. ",2);
        !          1320:                                }
        !          1321:
        !          1322:                        if ( Sep[1] !=0 && CHECK2 == 1 )
        !          1323:                                {
        !          1324:                                print("The separable closure is of generic type. ",2);
        !          1325:                                print("So, the intermediate ideal is prime or primary. ",2);
        !          1326:
        !          1327:                                PDiv=convertdivisor(Sep[0],TargetVSet,VSet,Sep[1]);
        !          1328:                                if ( TargetVSet != VSet )
        !          1329:                                        {
        !          1330:                                        PDiv=contraction(PDiv,TargetVSet,VSet)[0];
        !          1331:                                        }
        !          1332:                                Divisor=radicalideal(PDiv,2,VSet);
        !          1333:                                ZDecomp=[Divisor];
        !          1334:                                }
        !          1335:                        else
        !          1336:                                {
        !          1337: #if 0
        !          1338:                                ZSDecomp=zeroseparableprimedecomposition(Sep[0],TargetVSet,VSet);
        !          1339: #else
        !          1340:                                ZSDecomp=zerosepdec(Sep[0],TargetVSet,VSet,Ord);
        !          1341: #endif
        !          1342:                                /* We convert a prime separable ideal in K[TargetVSet] to its           */
        !          1343:                                /* corresponding prime ideal in K[VSet].                                */
        !          1344:
        !          1345:                                NComp=length(ZSDecomp);
        !          1346:                                ZDecomp=[];
        !          1347:
        !          1348:                                for (J=0;J<NComp;J++)
        !          1349:                                        {
        !          1350:                                        SDiv=ZSDecomp[J];
        !          1351:
        !          1352:                                /* First we convert a prime separable ideal in K[TargetVSet] to its     */
        !          1353:                                /* corresponding prime/primary ideal in K[TargetVSet] by computing the  */
        !          1354:                                /* image of Frobenius map.                                              */
        !          1355:
        !          1356:                                        PDiv=convertdivisor(SDiv,TargetVSet,VSet,Sep[1]);
        !          1357:
        !          1358:                                /* Then we compute the true prime divisor by contraction and radical    */
        !          1359:                                /* computation.                                                         */
        !          1360:
        !          1361:                                        if ( TargetVSet != VSet )
        !          1362:                                                {
        !          1363:                                                PDiv=contraction(PDiv,TargetVSet,VSet)[0];
        !          1364:                                                }
        !          1365:
        !          1366:                                        if (Sep[1] != 0 )
        !          1367:                                                {
        !          1368:                                                Divisor=radicalideal(PDiv,2,VSet);
        !          1369:                                                }
        !          1370:                                        else
        !          1371:                                                {
        !          1372:                                                Divisor=PDiv;
        !          1373:                                                }
        !          1374:
        !          1375:
        !          1376:                                        ZDecomp=append(ZDecomp,[Divisor]);
        !          1377:                                        }
        !          1378:                                }
        !          1379:                        }
        !          1380:
        !          1381:                ANS=append(ANS, ZDecomp);
        !          1382:                }
        !          1383:        return map(monic_hc,ANS,VSet);
        !          1384:        }
        !          1385:
        !          1386: def monic_hc(Poly,V)
        !          1387: {
        !          1388:        if ( type(Poly) == 4 )
        !          1389:                map(monic_hc,Poly,V);
        !          1390:        else {
        !          1391:                T = dp_ptod(Poly,V);
        !          1392:                return dp_dtop(T/dp_hc(T),V);
        !          1393:        }
        !          1394: }
        !          1395:
        !          1396: def zeroseparableprimedecomposition(P,TargetVSet,VSet)
        !          1397:        {
        !          1398:        /* We compute prime decomposition for a separable       */
        !          1399:        /* 0-dimensional ideal <P> in K[TargetVSet] by using    */
        !          1400:        /* generic position.                                    */
        !          1401:
        !          1402:        ANS=[];
        !          1403:        Ord=0;
        !          1404:
        !          1405:        NVSet=length(TargetVSet);
        !          1406:
        !          1407:        /* The P is already a GB w.r.t. DRL. So, the following  */
        !          1408:        /* must be replaced with  NewP=P.                       */
        !          1409:
        !          1410:        /* NewGP=dp_gr_f_main(P,TargetVSet,Hom,Ord); */
        !          1411:        NewGP = P;
        !          1412:
        !          1413:        /* We search a polynomial f in generic position.        */
        !          1414:        /* Generic=[f, minimal polynomial of f in newt, newt],  */
        !          1415:        /* where newt (X) is a newly introduced variable.       */
        !          1416:
        !          1417:        print("We search for a linear sum of variables in generic position. ",2);
        !          1418:
        !          1419:        Generic=findgeneric(NewGP,TargetVSet,VSet);
        !          1420:
        !          1421:        X=Generic[2]; /* newly introduced variable              */
        !          1422:        Factors=sffctr(Generic[1]);
        !          1423:        NFactors=length(Factors);
        !          1424:        /* irreducible case */
        !          1425:        if ( NFactors == 2 && Factors[1][1] == 1 )
        !          1426:                return [NewGP];
        !          1427: #if 0
        !          1428:        for (J=1;J<NFactors;J++)
        !          1429:                {
        !          1430:                AddPoly=Factors[J][0];
        !          1431:                AddPoly2=X-Generic[0];
        !          1432:
        !          1433:                TestGP=append(NewGP,[AddPoly, AddPoly2]);
        !          1434:                VS=cons(X,TargetVSet);
        !          1435:                Q=dp_gr_f_main(TestGP,VS,Hom,[[0,1],[Ord,NVSet]]);
        !          1436:                QR=elimination(Q,VSet);
        !          1437:                ANS=append(ANS,[QR]);
        !          1438:                }
        !          1439: #else
        !          1440:        /* noro */
        !          1441:        dp_ord([[0,1],[Ord,NVSet]]);
        !          1442:        XVSet = cons(X,TargetVSet);
        !          1443:        PS = newvect(length(NewGP)+1,map(dp_ptod,cons(X-Generic[0],NewGP),XVSet));
        !          1444:        for ( I = length(NewGP), Ind = [];I >= 0; I-- )
        !          1445:                Ind = cons(I,Ind);
        !          1446:        Ind = reverse(Ind);
        !          1447:        YSet = setminus(VSet,TargetVSet);
        !          1448:        NYSet = length(YSet);
        !          1449:        ElimVSet = append(TargetVSet,YSet);
        !          1450:        ElimOrd = [[Ord,NVSet],[0,NYSet]];
        !          1451:        for ( J = 1; J < NFactors; J++ ) {
        !          1452:                dp_ord([[0,1],[Ord,NVSet]]);
        !          1453:                Factor = dp_dtop(nf_sfrat(Ind,dp_ptod(Factors[J][0],XVSet),1,PS)[0],XVSet);
        !          1454: #if 0
        !          1455:                Q = dp_gr_f_main(cons(Factor,NewGP),ElimVSet,Hom,ElimOrd);
        !          1456: #else
        !          1457:                Q0 = dp_gr_f_main(cons(Factor,NewGP),ElimVSet,Hom,0);
        !          1458:                Q = dp_gr_f_main(Q0,ElimVSet,Hom,ElimOrd);
        !          1459: #endif
        !          1460:                Q = dp_gr_f_main(Q,TargetVSet,Hom,Ord);
        !          1461:                ANS = cons(Q,ANS);
        !          1462:        }
        !          1463: #endif
        !          1464:        return ANS;
        !          1465:        }
        !          1466:
        !          1467: /* partial decomposition by sums of variables
        !          1468:    -> zeroseparableprimedecomposition */
        !          1469:
        !          1470: #if 0
        !          1471: def zerosepdec(P,W,V,Ord)
        !          1472: {
        !          1473:        /* P is GB wrt (W,Ord) */
        !          1474:        dp_ord(Ord);
        !          1475:        DIM = length(dp_mbase(map(dp_ptod,P,W)));
        !          1476:        /* preprocessing */
        !          1477:        N = length(W);
        !          1478:        C = newvect(N);
        !          1479:        C[0] = 1;
        !          1480:        Vt = ttttt;
        !          1481:        do {
        !          1482:                for ( I = 0, LF = 0; I < N; I++ )
        !          1483:                        if ( C[I] ) LF += W[I];
        !          1484:                LF = simp_ff(LF);
        !          1485:                MP = minipoly_sf(P,W,Ord,LF,Vt);
        !          1486:                Factors = map(first,cdr(sffctr(MP)));
        !          1487:                if ( deg(MP,Vt) == DIM ) {
        !          1488:                        if ( length(Factors) == 1 )
        !          1489:                                return [P];
        !          1490:                        else
        !          1491:                                return zerosepdec_main(P,W,V,Ord,map(subst,Factors,Vt,LF));
        !          1492:                } else if ( length(Factors) > 1 ) {
        !          1493:                        R =  zerosepdec_main(P,W,V,Ord,map(subst,Factors,Vt,LF));
        !          1494:                        S = [];
        !          1495:                        for ( TR = R; TR != []; TR = cdr(TR) )
        !          1496:                                S = append(zerosepdec(car(TR),W,V,Ord),S);
        !          1497:                        return S;
        !          1498:                }
        !          1499:        } while ( !nextchoice(C) );
        !          1500:        /* we could not find any useful combination */
        !          1501:        R = zeroseparableprimedecomposition(P,W,V);
        !          1502:        return R;
        !          1503: }
        !          1504: #else
        !          1505:
        !          1506: /* we only search for useful poly among v[i]+v[j] */
        !          1507: def zerosepdec(P,W,V,Ord)
        !          1508: {
        !          1509:        /* P is GB wrt (W,Ord) */
        !          1510:        dp_ord(Ord);
        !          1511:        DIM = length(dp_mbase(map(dp_ptod,P,W)));
        !          1512:        /* preprocessing */
        !          1513:        N = length(W);
        !          1514:        C = newvect(N);
        !          1515:        C[0] = 1;
        !          1516:        Vt = ttttt;
        !          1517:        for ( I1 = 0; I1 < N; I1++ )
        !          1518:                for ( I2 = I1+1; I2 < N; I2++ ) {
        !          1519:                        LF = simp_ff(W[I1]+W[I2]);
        !          1520:                        MP = minipoly_sf(P,W,Ord,LF,Vt);
        !          1521:                        Factors = map(first,cdr(sffctr(MP)));
        !          1522:                        if ( deg(MP,Vt) == DIM ) {
        !          1523:                                if ( length(Factors) == 1 )
        !          1524:                                        return [P];
        !          1525:                                else
        !          1526:                                        return zerosepdec_main(P,W,V,Ord,map(subst,Factors,Vt,LF));
        !          1527:                        } else if ( length(Factors) > 1 ) {
        !          1528:                                R =  zerosepdec_main(P,W,V,Ord,map(subst,Factors,Vt,LF));
        !          1529:                                S = [];
        !          1530:                                for ( TR = R; TR != []; TR = cdr(TR) )
        !          1531:                                        S = append(zerosepdec(car(TR),W,V,Ord),S);
        !          1532:                                return S;
        !          1533:                        }
        !          1534:                }
        !          1535:        /* we could not find any useful combination */
        !          1536:        R = zeroseparableprimedecomposition(P,W,V);
        !          1537:        return R;
        !          1538: }
        !          1539: #endif
        !          1540:
        !          1541: def zerosepdec_main(P,W,V,Ord,Factors)
        !          1542: {
        !          1543:        dp_ord(Ord);
        !          1544:        N = length(P);
        !          1545:        NFactors = length(Factors);
        !          1546:        PS = newvect(length(P),map(dp_ptod,P,W));
        !          1547:        for ( I = length(P)-1, Ind = [];I >= 0; I-- )
        !          1548:                Ind = cons(I,Ind);
        !          1549:        Y= setminus(V,W);
        !          1550:        NW = length(W);
        !          1551:        NY = length(Y);
        !          1552:        ElimV = append(W,Y);
        !          1553:        ElimOrd = [[Ord,NW],[0,NY]];
        !          1554:        ANS = [];
        !          1555:        for ( J = 0; J < NFactors; J++ ) {
        !          1556:                Factor = dp_dtop(nf_sfrat(Ind,dp_ptod(Factors[J],W),1,PS)[0],W);
        !          1557:                Q = dp_gr_f_main(cons(Factor,P),ElimV,Hom,ElimOrd);
        !          1558:                Q = dp_gr_f_main(Q,W,Hom,Ord);
        !          1559:                ANS = cons(Q,ANS);
        !          1560:        }
        !          1561:        return ANS;
        !          1562: }
        !          1563:
        !          1564: def nextchoice(C)
        !          1565: {
        !          1566:        N = size(C)[0];
        !          1567:        for ( I = N-1, Carry = 1; I >= 0; I-- ) {
        !          1568:                if ( C[I] ) {
        !          1569:                        C[I] = !Carry;
        !          1570:                        Carry = !C[I];
        !          1571:                } else {
        !          1572:                        C[I] = Carry;
        !          1573:                        Carry = 0;
        !          1574:                }
        !          1575:        }
        !          1576:        return Carry;
        !          1577: }
        !          1578:
        !          1579: def separableclosure(CP,TargetVSet,VSet)
        !          1580:        {
        !          1581:        /* We compute a separable ideal <Q> from <P> by         */
        !          1582:        /* computing inverse Frobenius map.                     */
        !          1583:
        !          1584:        Ord=0;
        !          1585:
        !          1586:        NVSet=length(TargetVSet);
        !          1587:        IndexVector=newvect(NVSet);
        !          1588:
        !          1589:        /* First we check if <P> is already separable.          */
        !          1590:        /* CHECK == 1 if <P> is already separable,              */
        !          1591:        /* Otherwise, CHECK is the list of pairs of             */
        !          1592:        /* the separable closure sc(m) of the minimal polynomial*/
        !          1593:        /* m and the exponent e, i.e. m=sc(m)(t^(q^e)).         */
        !          1594:
        !          1595:        CHECK=checkseparable(CP,TargetVSet,VSet);
        !          1596:
        !          1597:        if ( CHECK == 1 )
        !          1598:                {
        !          1599:                print("This is already a separable ideal.", 2);
        !          1600:                return [CP[0],0];
        !          1601:                }
        !          1602:
        !          1603:        print("This is not a separable ideal, so we make its separable closure.", 2);
        !          1604:
        !          1605:        WSet=makecounterpart(TargetVSet);
        !          1606:        Char=setmod_ff()[0];
        !          1607:
        !          1608:        NewP=CP[0];
        !          1609:        EXPVECTOR=newvect(NVSet);
        !          1610:        CHECKEXPVECTOR=newvect(NVSet);
        !          1611:
        !          1612:        for (I=0;I<NVSet;I++)
        !          1613:                {
        !          1614:                EXPVECTOR[I]=CHECK[NVSet-I-1][0];
        !          1615:                CHECKEXPVECTOR[I]=deg(CHECK[NVSet-I-1][1],TargetVSet[I]);
        !          1616:
        !          1617:                POW=Char^CHECK[NVSet-I-1][0];
        !          1618:
        !          1619:                AddPoly=TargetVSet[I]^POW-WSet[I];
        !          1620:                /*SepClosure=subst(CHECK[I][0],TargetVSet[I],WSet[I]);*/
        !          1621:
        !          1622:                NewP=cons(AddPoly,NewP);
        !          1623:                }
        !          1624:
        !          1625:        NewOrder=[[Ord,NVSet],[Ord,NVSet]];
        !          1626:        XSet=append(TargetVSet,WSet);
        !          1627:        YSet=append(VSet,WSet);
        !          1628:
        !          1629:        NewG=dp_gr_f_main(NewP,XSet,Hom,NewOrder);
        !          1630:
        !          1631:        NWSet=setminus(YSet,TargetVSet);
        !          1632:
        !          1633:        Q=elimination(NewG,NWSet);
        !          1634:
        !          1635:        NQ=length(Q);
        !          1636:
        !          1637:        ANS=[];
        !          1638:        for (I=NQ-1;I>=0;I--)
        !          1639:                {
        !          1640:                Poly=Q[I];
        !          1641:                for (J=0;J<NVSet;J++)
        !          1642:                        {
        !          1643:                        Poly=subst(Poly,WSet[J],TargetVSet[J]);
        !          1644:                        }
        !          1645:                ANS=cons(Poly,ANS);
        !          1646:                }
        !          1647:        return [ANS,EXPVECTOR,CHECKEXPVECTOR];
        !          1648:        }
        !          1649:
        !          1650: def convertdivisor(P,TargetVSet,VSet,ExVector)
        !          1651:        {
        !          1652:        /* We compute a corresponding ideal <Q> from <P> by     */
        !          1653:        /* computing Frobenius map.                             */
        !          1654:
        !          1655:        if (ExVector == 0 )
        !          1656:                {
        !          1657:                return P;
        !          1658:                }
        !          1659:
        !          1660:        NVSet=length(TargetVSet);
        !          1661:        WSet=makecounterpart(TargetVSet);
        !          1662:        Char=setmod_ff()[0];
        !          1663:        Ord=0;
        !          1664:
        !          1665:        NewP=P;
        !          1666:
        !          1667:        for (I=0;I<NVSet;I++)
        !          1668:                {
        !          1669:                POW=Char^ExVector[I];
        !          1670:
        !          1671:                AddPoly=TargetVSet[I]-WSet[I]^POW;
        !          1672:                /*SepClosure=subst(CHECK[I][0],TargetVSet[I],WSet[I]);*/
        !          1673:
        !          1674:                NewP=cons(AddPoly,NewP);
        !          1675:                }
        !          1676:
        !          1677:        NewOrder=[[Ord,NVSet],[Ord,NVSet]];
        !          1678:
        !          1679:        XSet=append(TargetVSet,WSet);
        !          1680:        YSet=append(VSet,WSet);
        !          1681:
        !          1682:        NewG=dp_gr_f_main(NewP,XSet,Hom,NewOrder);
        !          1683:
        !          1684:        NWSet=setminus(YSet,TargetVSet);
        !          1685:
        !          1686:        Q=elimination(NewG,NWSet);
        !          1687:
        !          1688:        NQ=length(Q);
        !          1689:
        !          1690:        ANS=[];
        !          1691:        for (I=NQ-1;I>=0;I--)
        !          1692:                {
        !          1693:                Poly=Q[I];
        !          1694:                for (J=0;J<NVSet;J++)
        !          1695:                        {
        !          1696:                        Poly=subst(Poly,WSet[J],TargetVSet[J]);
        !          1697:                        }
        !          1698:                ANS=cons(Poly,ANS);
        !          1699:                }
        !          1700:        return ANS;
        !          1701:        }
        !          1702:
        !          1703:
        !          1704: def findgeneric(P,TargetVSet,VSet)
        !          1705:        {
        !          1706:        /* The number of trials is set as Trails. */
        !          1707:        NTargetVSet=length(TargetVSet);
        !          1708:        MNumber=0;
        !          1709:        /* Trials=100;*/
        !          1710:
        !          1711:        if ( Trials == 0 )
        !          1712:                Trials = 2;
        !          1713:
        !          1714:        Lineardimension=lineardimension(P,TargetVSet);
        !          1715:        NewVar=newt;
        !          1716:        Count=0;
        !          1717:        Ord=0;
        !          1718:
        !          1719: #if 0
        !          1720:        while(Count < Trials )
        !          1721:                {
        !          1722:                Candidate=0;
        !          1723:                MNumber=MNumber+1;
        !          1724:
        !          1725:                MAGIC=makemagic(TargetVSet,MNumber);
        !          1726:
        !          1727:                for (I=0;I<NTargetVSet;I++)
        !          1728:                        {
        !          1729:                        Candidate=Candidate+MAGIC[I]*TargetVSet[I];
        !          1730:                        }
        !          1731:                MinPoly=minipoly_sf(P,TargetVSet,Ord,Candidate,NewVar);
        !          1732:                Deg=deg(MinPoly,NewVar);
        !          1733:                if ( Deg == Lineardimension )
        !          1734:                        {
        !          1735:                        return [Candidate,MinPoly,NewVar];
        !          1736:                        }
        !          1737:                Count=Count+1;
        !          1738:                }
        !          1739: #else
        !          1740:        YSet = setminus(VSet,TargetVSet);
        !          1741:        NYSet = length(YSet);
        !          1742:        Eval = newvect(NYSet);
        !          1743:        Q1 = field_order_ff()-1;
        !          1744:        HM = hmlist(P,TargetVSet,Ord);
        !          1745:        for ( Count = 0; Count < Trials; Count++ ) {
        !          1746:                Candidate = ptosfp(2)*TargetVSet[0];
        !          1747:                Candidate = 0;
        !          1748:                for ( I = 0; I < NTargetVSet; I++ )
        !          1749:                        Candidate += random_ff()*TargetVSet[I];
        !          1750:                do {
        !          1751:                        for ( I = 0; I < NYSet; I++ )
        !          1752:                                Eval[I] = random()%Q1;
        !          1753:                } while ( !valid_modulus_sfrat(HM,YSet,Eval) );
        !          1754:                P0 = map(eval_sfrat,P,YSet,Eval);
        !          1755:                MinPoly0 = minipoly_sf(P0,TargetVSet,Ord,Candidate,NewVar);
        !          1756:                Deg = deg(MinPoly0,NewVar);
        !          1757:                if ( Deg == Lineardimension ) {
        !          1758:                        MinPoly=minipoly_sf(P,TargetVSet,Ord,Candidate,NewVar);
        !          1759:                        if ( deg(MinPoly,NewVar) != Deg )
        !          1760:                                error("findgeneric : cannot happen");
        !          1761:                        return [Candidate,MinPoly,NewVar];
        !          1762:                }
        !          1763:        }
        !          1764: #endif
        !          1765:        print("Extend the ground field. ",2);
        !          1766:        error();
        !          1767:        }
        !          1768:
        !          1769: def makemagic(VSet,MNumber)
        !          1770:        {
        !          1771:        NVSet=length(VSet);
        !          1772:        MAGIC=[1];
        !          1773:        for (I=1;I<NVSet;I++)
        !          1774:                {
        !          1775:                U=ptosfp(MNumber^I);
        !          1776:                MAGIC=append(MAGIC,[U]);
        !          1777:                }
        !          1778:        return MAGIC;
        !          1779:        }
        !          1780:
        !          1781: #if 0
        !          1782: def zerogenericprimedecomposition(CP,MinP,TargetVSet,VSet)
        !          1783:        {
        !          1784:        P=CP[0];
        !          1785:
        !          1786:        FACTORS=sffctr(MinP);
        !          1787:        NFACTORS=length(FACTORS);
        !          1788:
        !          1789:        if ( NFACTORS == 2 )
        !          1790:                {
        !          1791:                return [P];
        !          1792:                }
        !          1793:
        !          1794:        ANS=[];
        !          1795:
        !          1796:        for (I=1;I<NFACTORS;I++)
        !          1797:                {
        !          1798:                AddPoly=NFACTORS[I][0];
        !          1799:                NewP=cos(AddPoly,P);
        !          1800:                NewG=dp_gr_f_main(NewP,TargetVSet,Hom,Ord);
        !          1801:                ANS=cons(NewG,ANS);
        !          1802:                }
        !          1803:        return ANS;
        !          1804:        }
        !          1805: #endif
        !          1806:
        !          1807:
        !          1808: def lineardimension(P,VSet)
        !          1809:        {
        !          1810:        Ord=0;
        !          1811:
        !          1812:        PP=dp_gr_f_main(P,VSet,Hom,Ord);
        !          1813:        dp_ord(Ord);
        !          1814:        Dimension=length(dp_mbase(map(dp_ptod,PP,VSet)));
        !          1815:        return Dimension;
        !          1816:        }
        !          1817:
        !          1818: def checkgeneric(CP,TargetVSet,VSet)
        !          1819:        {
        !          1820:        Dimension=lineardimension(CP[0],TargetVSet);
        !          1821:        NVSet=length(TargetVSet);
        !          1822:        Flag=0;
        !          1823:
        !          1824:        for (I=0;I<NVSet;I++)
        !          1825:                {
        !          1826:                MinP=CP[1][I];
        !          1827:
        !          1828:                if ( deg(MinP,TargetVSet[NVSet-I-1]) == Dimension )
        !          1829:                        {
        !          1830:                        return [1,MinP];
        !          1831:                        }
        !          1832:                }
        !          1833:        return 0;
        !          1834:        }
        !          1835:
        !          1836: def checkseparable(CP,TargetVSet,VSet)
        !          1837:        {
        !          1838:        NVSet=length(TargetVSet);
        !          1839:        EXPVector=newvect(NVSet);
        !          1840:        Flag=1;
        !          1841:
        !          1842:        for (I=0;I<NVSet;I++)
        !          1843:                {
        !          1844:                MinP=CP[1][I];
        !          1845:                CHECK=checkseparablepoly(MinP,TargetVSet[NVSet-I-1]);
        !          1846:                if ( CHECK[0] != 0 )
        !          1847:                        {
        !          1848:                        Flag = 0;
        !          1849:                        }
        !          1850:                EXPVector[I]=CHECK;
        !          1851:                }
        !          1852:        if ( Flag == 0 )
        !          1853:                {
        !          1854:                return EXPVector;
        !          1855:                }
        !          1856:        return 1;
        !          1857:        }
        !          1858:
        !          1859: def checkseparablepoly(F,V)
        !          1860:        {
        !          1861:        P = characteristic_ff();
        !          1862:        E = 0;
        !          1863:        Vt = newt;
        !          1864:        while ( 1 ) {
        !          1865:                if ( diff(F,V) != 0 )
        !          1866:                        return [E,F];
        !          1867:                T = srem(F,V^P-Vt,V);
        !          1868:                F = subst(T,Vt,V);
        !          1869:                E++;
        !          1870:                }
        !          1871:        }
        !          1872:
        !          1873: def extcont(P,V,Ord)
        !          1874:        {
        !          1875:        /* We assume P is a Groebner Basis w.r.t. Ord.          */
        !          1876:        /* We compute a polynomial f such that                  */
        !          1877:        /* \sqrt{<P>}=\sqrt{<P>+<f>}\cap \sqrt{(<P>)^{ec}}      */
        !          1878:        /* by B.W. Proposition 8.96.                            */
        !          1879:        /* Remark: The square free part of f is also OK.        */
        !          1880:
        !          1881:        dp_ord(Ord);
        !          1882:        HC = map(dp_hc,map(dp_ptod,P,V));
        !          1883:        LCM = car(HC);
        !          1884:        for ( T = cdr(HC); T != []; T = cdr(T) )
        !          1885:                LCM = lcm_sfrat(LCM,car(T));
        !          1886:        return LCM;
        !          1887:        }
        !          1888:
        !          1889: def first(A)
        !          1890: {
        !          1891:        return A[0];
        !          1892: }
        !          1893:
        !          1894: def set_union(A,B)
        !          1895: {
        !          1896:        for ( T = A; T != []; T = cdr(T) )
        !          1897:                B = insert_element(car(T),B);
        !          1898:        return B;
        !          1899: }
        !          1900:
        !          1901: def insert_element(E,A)
        !          1902: {
        !          1903:        for ( T = A; T != []; T = cdr(T) )
        !          1904:                if ( E == car(T) )
        !          1905:                        break;
        !          1906:        if ( T == [] )
        !          1907:                return cons(E,A);
        !          1908:        else
        !          1909:                return A;
        !          1910: }
        !          1911:
        !          1912: def extcont_factor(P,V,Ord)
        !          1913:        {
        !          1914:        /* We assume P is a Groebner Basis w.r.t. Ord.          */
        !          1915:        /* We compute a polynomial f such that                  */
        !          1916:        /* \sqrt{<P>}=\sqrt{<P>+<f>}\cap \sqrt{(<P>)^{ec}}      */
        !          1917:        /* by B.W. Proposition 8.96.                            */
        !          1918:        /* Remark: The square free part of f is also OK.        */
        !          1919:
        !          1920:        dp_ord(Ord);
        !          1921:        HC = map(dp_hc,map(dp_ptod,P,V));
        !          1922:        F = [];
        !          1923:        for ( T = HC; T != []; T = cdr(T) ) {
        !          1924:                F1 = map(first,cdr(sffctr(car(T))));
        !          1925:                F = set_union(F1,F);
        !          1926:        }
        !          1927:        return F;
        !          1928:        }
        !          1929:
        !          1930: def contraction(P,V,W)
        !          1931:        {
        !          1932:        /* We assume P is a Groebner Basis w.r.t. Ord.          */
        !          1933:        /* We compute the contraction <P>^{c} by                */
        !          1934:        /*  <P>^c=(<G>:f^\infty)                                */
        !          1935:        /* by B.W. Proposition 8.91.                            */
        !          1936:        /* This procedure is called by zeroprimedecomposition.  */
        !          1937:        /* So, P is supposed to be a GB w.r.t. DRL.             */
        !          1938:
        !          1939:        Ord=0;
        !          1940:        YSet=setminus(W,V);
        !          1941:
        !          1942:        Ord1 = [[Ord,length(V)],[0,length(YSet)]];
        !          1943:        GP1 = dp_gr_f_main(P,W,Hom,Ord1);
        !          1944:
        !          1945:        Factor = extcont_factor(GP1,V,Ord);
        !          1946:        for ( F = 1, T = Factor; T != []; T = cdr(T) )
        !          1947:                F *= car(T);
        !          1948:        Vt = newt;
        !          1949:
        !          1950:        G = dp_gr_f_main(cons(1-Vt*F,P),cons(Vt,W),0,[[0,1],[Ord,length(W)]]);
        !          1951:        R = [];
        !          1952:        for ( T = G; T != []; T = cdr(T) )
        !          1953:                if ( !member(Vt,vars(car(T))) )
        !          1954:                        R = cons(car(T),R);
        !          1955:        return [R,F];
        !          1956:        }
        !          1957:
        !          1958: def checkgeneric2(LIST)
        !          1959:        {
        !          1960:        NList=size(LIST)[0];
        !          1961:
        !          1962:        FLAG=0;
        !          1963:
        !          1964:        for (I=0;I<NList;I++)
        !          1965:                {
        !          1966:                if ( LIST[I] > 1 )
        !          1967:                        {
        !          1968:                        FLAG=FLAG+1;
        !          1969:                        }
        !          1970:                }
        !          1971:
        !          1972:        if (FLAG < 2 )
        !          1973:                {
        !          1974:                return 1;
        !          1975:                }
        !          1976:        return 0;
        !          1977:        }
        !          1978:
        !          1979: #if 0
        !          1980: def checkseparablepoly(P,V)
        !          1981:        {
        !          1982:        TestP=P;
        !          1983:        CHECK=diff(TestP,V);
        !          1984:        Count=0;
        !          1985:
        !          1986:        while ( CHECK !=0 )
        !          1987:                {
        !          1988:                if  ( deg(TestP,V) != 0 )
        !          1989:                        {
        !          1990:                        break;
        !          1991:                        }
        !          1992:                TestP=pdivide(TestP);
        !          1993:                CHECK=diff(TestP,V);
        !          1994:                Count=Count+1;
        !          1995:                }
        !          1996:
        !          1997:        return [TestP,Count];
        !          1998:        }
        !          1999:
        !          2000: def pdivide(F,V)
        !          2001:        {
        !          2002:        Char=setmod_ff()[0];
        !          2003:        TestP=P;
        !          2004:
        !          2005:        Deg=ideg(TestP,V);
        !          2006:        DegP=idiv(Deg,Char);
        !          2007:
        !          2008:        if ( irem(Deg,Char) != 0 )
        !          2009:                {
        !          2010:                error;
        !          2011:                }
        !          2012:        ANS=0;
        !          2013:
        !          2014:        for (I=O;I<DegP;I++)
        !          2015:                {
        !          2016:                TempDeg=I*Char;
        !          2017:                ANS=ANS+coeff(TestP,V,TempDeg)*X^I;
        !          2018:                }
        !          2019:        return ANS;
        !          2020:        }
        !          2021: #endif
        !          2022:
        !          2023:
        !          2024: def convsf(PP,VSet,Ord,Flag)
        !          2025:        {
        !          2026:        /* Flag = 0 or 1                                */
        !          2027:        /* If Flag = 1, we compute the intersection     */
        !          2028:        /* of the Galois orbit.                         */
        !          2029:
        !          2030:        CHECK=checkgaloisorbit(PP,VSet,Ord,Flag);
        !          2031:
        !          2032:        NewPP=CHECK[0];
        !          2033:
        !          2034:        ANS=[];
        !          2035:
        !          2036:        NPP=length(NewPP);
        !          2037:
        !          2038:        for (I=0;I<NPP;I++)
        !          2039:                {
        !          2040:                NewComp=convertsmallfield(CHECK[Flag][I],VSet,Ord);
        !          2041:                ANS=cons(NewComp,ANS);
        !          2042:                }
        !          2043:        return ANS;
        !          2044:        }
        !          2045:
        !          2046: def convertsmallfield(PP,VSet,Ord)
        !          2047:        {
        !          2048:        dp_ord(Ord);
        !          2049:        NVSet=length(VSet);
        !          2050:        Char=setmod_ff()[0];
        !          2051:        ExtDeg=deg(setmod_ff()[1],x);
        !          2052:
        !          2053:        NewV=pg;
        !          2054:        MPP=map(monic_hc,PP,VSet);
        !          2055:        MPP=map(sfptopsfp,MPP,NewV);
        !          2056:
        !          2057:        MinPoly=subst(setmod_ff()[1],x,NewV);
        !          2058:        XSet=cons(NewV,VSet);
        !          2059:
        !          2060:        Ord1=[[0,1],[Ord,NVSet]];
        !          2061:
        !          2062:        /* setmod_ff(Char,1);*/
        !          2063:
        !          2064:        NewP=dp_gr_mod_main(cons(MinPoly,MPP),XSet,0,Char,Ord1);
        !          2065:
        !          2066:        ANS=elimination(NewP,VSet);
        !          2067:
        !          2068:        /* setmod_ff(Char,ExtDeg);*/
        !          2069:
        !          2070:        return ANS;
        !          2071:        }
        !          2072:
        !          2073: def checkgaloisorbit(PP,VSet,Ord,Flag)
        !          2074:        {
        !          2075:        NPP=length(PP);
        !          2076:        TmpPP=PP;
        !          2077:        ExtDeg=deg(setmod_ff()[1],x);
        !          2078:
        !          2079:        ANS=[];
        !          2080:        BNS=[];
        !          2081:
        !          2082:        while (TmpPP != [] )
        !          2083:                {
        !          2084:                TestP=car(TmpPP);
        !          2085:                Dim=TestP[1];
        !          2086:                TmpPP=cdr(TmpPP);
        !          2087:                NewP=TestP[0];
        !          2088:
        !          2089:                ANS=cons(TestP[0],ANS);
        !          2090:
        !          2091:                for (J=1;J<ExtDeg;J++)
        !          2092:                        {
        !          2093:                        G1=map(sf_galois_action,TestP[0],J);
        !          2094:
        !          2095:                        if ( setminus(G1,TestP[0]) == [] )
        !          2096:                                {
        !          2097:                                break;
        !          2098:                                }
        !          2099:                        if (Flag == 1 )
        !          2100:                                {
        !          2101:                                NewP=ideal_intersection_sfrat(NewP,G1,VSet);
        !          2102:                                }
        !          2103:                        TmpPP=deletecomponent(TmpPP,[G1,Dim]);
        !          2104:                        }
        !          2105:                BNS=cons(NewP,BNS);
        !          2106:
        !          2107:                }
        !          2108:        return [ANS,BNS];
        !          2109:        }
        !          2110:
        !          2111: def deletecomponent(PP,G)
        !          2112:        {
        !          2113:        TmpPP=PP;
        !          2114:
        !          2115:        while( TmpPP !=[] )
        !          2116:                {
        !          2117:                Test=car(TmpPP)[0];
        !          2118:
        !          2119:                if ( setminus(Test,G[0]) == [] )
        !          2120:                        {
        !          2121:                        ANS=setminus(PP,[G]);
        !          2122:                        return ANS;
        !          2123:                        }
        !          2124:
        !          2125:                TmpPP=cdr(TmpPP);
        !          2126:                }
        !          2127:        error();
        !          2128:        }
        !          2129:
        !          2130:
        !          2131: def pfctr(F)
        !          2132: {
        !          2133:        if ( type(F) == 1 )
        !          2134:                return [[F,1]];
        !          2135:        P = characteristic_ff();
        !          2136:        E = extdeg_ff();
        !          2137:        F = sfptop(F);
        !          2138:        check_coef(F,P);
        !          2139:        D = modfctr(F,P);
        !          2140:        setmod_ff(P,E);
        !          2141:        return map(mapsf_first,D);
        !          2142: }
        !          2143:
        !          2144: def check_coef(F,P)
        !          2145: {
        !          2146:        V = vars(F);
        !          2147:        D = dp_ptod(F,V);
        !          2148:        for ( T = D; T; T = dp_rest(T) )
        !          2149:                if ( dp_hc(T) >= P )
        !          2150:                        error("invalid coef");
        !          2151: }
        !          2152:
        !          2153: def mapsf_first(D)
        !          2154: {
        !          2155:        return [ptosfp(D[0]),D[1]];
        !          2156: }
        !          2157:
        !          2158: def partial_decomp(B,V)
        !          2159: {
        !          2160:        T0 = time();
        !          2161:        if ( ParallelMinipoly ) {
        !          2162:                map(ox_cmo_rpc,ParallelMinipoly,"setmod_ff",characteristic_ff(),extdeg_ff());
        !          2163:                map(ox_pop_cmo,ParallelMinipoly);
        !          2164:        }
        !          2165:        B = map(ptosfp,B);
        !          2166:        B = dp_gr_f_main(B,V,0,0);
        !          2167:        R = partial_decomp0(B,V,length(V)-1);
        !          2168:        if ( PartialDecompByLex ) {
        !          2169:                R0 = [];
        !          2170:                for ( TR = R; TR != []; TR = cdr(TR) ) {
        !          2171:                        T = car(TR);
        !          2172:                        S = dp_gr_f_main(T[0],V,0,0);
        !          2173:                        R0 = cons([S,T[1]],R0);
        !          2174:                }
        !          2175:                R = reverse(R0);
        !          2176:        }
        !          2177:        T_PD += time()[3]-T0[3];
        !          2178:        return R;
        !          2179: }
        !          2180:
        !          2181: def setintersection(A,B)
        !          2182: {
        !          2183:        for ( L = []; A != []; A = cdr(A) )
        !          2184:                if ( member(car(A),B) )
        !          2185:                        L = cons(car(A),L);
        !          2186:        return L;
        !          2187: }
        !          2188:
        !          2189: /* returns [[Plist,Mlist],...] */
        !          2190:
        !          2191: def partial_decomp0(B,V,I)
        !          2192: {
        !          2193:        N = length(V);
        !          2194:        if ( I < 0 )
        !          2195:                return [[B,[]]];
        !          2196:        Ord = PartialDecompByLex ? [[0,I],[2,N-I]] : 0;
        !          2197: #if 0
        !          2198:        if ( setminus(vars(B),V) == [] )
        !          2199:                B = fglm_sf_0dim(B,V,Ord0,Ord);
        !          2200:        else
        !          2201: #endif
        !          2202:                B = dp_gr_f_main(B,V,0,Ord);
        !          2203:        if ( type(B[0]) == 1 )
        !          2204:                return [];
        !          2205:        if ( !zero_dim(B,V,Ord) )
        !          2206:                error("non zero-dimensional ideal");
        !          2207:        /* XXX */
        !          2208:        Vt = ttttt;
        !          2209:        VI = V[I];
        !          2210:        if ( PartialDecompByLex ) {
        !          2211:                for ( J = 0, W = V; J < I; J++ )
        !          2212:                        W = cdr(W);
        !          2213:                VW = setminus(V,W);
        !          2214:                for ( Bw = [], T = B; T != []; T = cdr(T) )
        !          2215:                        if ( setintersection(vars(car(T)),VW) == [] )
        !          2216:                                Bw = cons(car(T),Bw);
        !          2217:                MI = minipoly_sf(Bw,W,2,VI,Vt);
        !          2218:        } else
        !          2219:                MI = minipoly_sf(B,V,0,VI,Vt);
        !          2220:        MIF = sffctr(MI);
        !          2221:        /* if MI is irreducible, then process the next variable */
        !          2222:        if ( length(MIF) == 2 && MIF[1][1] == 1 ) {
        !          2223:                L = partial_decomp0(B,V,I-1);
        !          2224:                R = [];
        !          2225:                for ( S = L; S != []; S = cdr(S) ) {
        !          2226:                        L = car(S);
        !          2227:                        R = cons([L[0],cons(subst(MI,Vt,VI),L[1])],R);
        !          2228:                }
        !          2229:                return R;
        !          2230:        }
        !          2231:
        !          2232:        /* for nf computation */
        !          2233:        Ord1 = PartialDecompByLex ? 2 : [[0,1],[0,N]];
        !          2234:        Len = length(B);
        !          2235:        PS = newvect(Len+1);
        !          2236:        dp_ord(Ord1);
        !          2237:        XV = cons(Vt,V);
        !          2238:        for ( J = 0, T = cons(Vt-VI,B); T != []; T = cdr(T), J++ )
        !          2239:                PS[J] = dp_ptod(car(T),XV);
        !          2240:        for ( J = 0, GI = []; J <= Len; J++ )
        !          2241:                GI = cons(J,GI);
        !          2242:        if ( PartialDecompByLex )
        !          2243:                GI = reverse(GI);
        !          2244:
        !          2245:        R = [];
        !          2246:        for ( T = MIF; T != []; T = cdr(T) ) {
        !          2247:                Mt = car(car(T));
        !          2248:                if ( type(Mt) == 1 )
        !          2249:                        continue;
        !          2250:                dp_ord(Ord1);
        !          2251:                NfMt = dp_dtop(nf_sfrat(GI,dp_ptod(Mt,XV),1,PS)[0],XV);
        !          2252:                if ( NfMt )
        !          2253:                        B1 = dp_gr_f_main(cons(NfMt,B),V,0,Ord);
        !          2254:                else
        !          2255:                        B1 = B;
        !          2256:                Rt = partial_decomp0(B1,V,I-1);
        !          2257:                for ( S = Rt; S != []; S = cdr(S) ) {
        !          2258:                        L = car(S);
        !          2259:                        R = cons([L[0],cons(subst(Mt,Vt,VI),L[1])],R);
        !          2260:                }
        !          2261:        }
        !          2262:        return R;
        !          2263: }
        !          2264:
        !          2265:
        !          2266: /* G is a gb wrt (V,O) */
        !          2267:
        !          2268: def minipoly_sf(G,V,O,F,V0)
        !          2269: {
        !          2270:        T0 = time();
        !          2271:        Vc = cons(V0,setminus(vars(G),V));
        !          2272:        if ( ParallelMinipoly ) {
        !          2273:                Proc0 = ParallelMinipoly[0];
        !          2274:                Proc1 = ParallelMinipoly[1];
        !          2275:                if ( length(Vc) == 1 ) {
        !          2276:                        ox_rpc(Proc0,"minipoly_sf_by_buchberger",G,V,O,F,V0,1);
        !          2277:                        ox_rpc(Proc1,"minipoly_sf_0dim",G,V,O,F,V0,1);
        !          2278:                        map(ox_get,ParallelMinipoly);
        !          2279:                        /* 258=SM_popSerializedLocalObject */
        !          2280:                        map(ox_push_cmd,ParallelMinipoly,258);
        !          2281:                        F = ox_select(ParallelMinipoly);
        !          2282:                        MP = ox_get(F[0]);
        !          2283:                        if ( F[0] == Proc0 ) {
        !          2284:                                if ( length(F) == 1 )
        !          2285:                                        B_Win++;
        !          2286:                                else
        !          2287:                                        ox_get(Proc1);
        !          2288:                        } else {
        !          2289:                                if ( length(F) == 1 )
        !          2290:                                        D_Win++;
        !          2291:                                else
        !          2292:                                        ox_get(Proc0);
        !          2293:                        }
        !          2294:                        ox_reset(Proc0);
        !          2295:                        ox_reset(Proc1);
        !          2296:                } else if ( length(Vc) == 2 ) {
        !          2297:                        ox_rpc(Proc0,"minipoly_sf_by_buchberger",G,V,O,F,V0,1);
        !          2298:                        ox_rpc(Proc1,"minipoly_sfrat",G,V,O,F,V0,1);
        !          2299:                        map(ox_get,ParallelMinipoly);
        !          2300:                        /* 258=SM_popSerializedLocalObject */
        !          2301:                        map(ox_push_cmd,ParallelMinipoly,258);
        !          2302:                        F = ox_select(ParallelMinipoly);
        !          2303:                        MP = ox_get(F[0]);
        !          2304:                        if ( F[0] == Proc0 ) {
        !          2305:                                if ( length(F) == 1 )
        !          2306:                                        B_Win++;
        !          2307:                                else
        !          2308:                                        ox_get(Proc1);
        !          2309:                        } else {
        !          2310:                                if ( length(F) == 1 )
        !          2311:                                        D_Win++;
        !          2312:                                else
        !          2313:                                        ox_get(Proc0);
        !          2314:                        }
        !          2315:                        ox_reset(Proc0);
        !          2316:                        ox_reset(Proc1);
        !          2317:                } else
        !          2318:                        MP = minipoly_sf_by_buchberger(G,V,O,F,V0,0);
        !          2319:        } else if ( BuchbergerMinipoly )
        !          2320:                MP = minipoly_sf_by_buchberger(G,V,O,F,V0,0);
        !          2321:        else {
        !          2322:                if ( length(Vc) == 1 )
        !          2323:                        MP = minipoly_sf_0dim(G,V,O,F,V0,0);
        !          2324:                else if ( length(Vc) == 2 )
        !          2325:                        MP = minipoly_sfrat(G,V,O,F,V0,0);
        !          2326:                else
        !          2327:                        MP = minipoly_sf_by_buchberger(G,V,O,F,V0,0);
        !          2328:        }
        !          2329:        T_MP += time()[3]-T0[3];
        !          2330:        return MP;
        !          2331: }
        !          2332:
        !          2333: def minipoly_sf_by_buchberger(G,V,O,F,V0,Server)
        !          2334: {
        !          2335:        if ( Server )
        !          2336:                ox_sync(0);
        !          2337:        Vc = cons(V0,setminus(vars(G),V));
        !          2338:        Gf = cons(ptosfp(V0-F),G);
        !          2339:        Vf = append(V,Vc);
        !          2340:        Gelim = dp_gr_f_main(Gf,Vf,1,[[0,length(V)],[0,length(Vc)]]);
        !          2341:        for ( Gc = [], T = Gelim; T != []; T = cdr(T) ) {
        !          2342:                Vt = setminus(vars(car(T)),Vc);
        !          2343:                if ( Vt == [] )
        !          2344:                        Gc = cons(car(T),Gc);
        !          2345:        }
        !          2346:        Gt = dp_gr_f_main(Gc,Vc,1,[[0,1],[0,length(Vc)-1]]);
        !          2347:        Pmin = car(Gt); Dmin = deg(Pmin,V0);
        !          2348:        for ( T = cdr(Gt); T != []; T = cdr(T) ) {
        !          2349:                Dt = deg(car(T),V0);
        !          2350:                if ( Dt < Dmin ) {
        !          2351:                        Pmin = car(T); Dmin = Dt;
        !          2352:                }
        !          2353:        }
        !          2354:        Cont = sfcont(Pmin,V0);
        !          2355:        return sdiv(Pmin,Cont);
        !          2356: }
        !          2357:
        !          2358: def minipoly_sf_0dim(G,V,O,F,V0,Server)
        !          2359: {
        !          2360:        if ( Server )
        !          2361:                ox_sync(0);
        !          2362:        N = length(V);
        !          2363:        Len = length(G);
        !          2364:        dp_ord(O);
        !          2365:        PS = newvect(Len);
        !          2366:        for ( I = 0, T = G; T != []; T = cdr(T), I++ )
        !          2367:                PS[I] = dp_ptod(car(T),V);
        !          2368:        for ( I = Len-1, HL = []; I >= 0; I-- )
        !          2369:                HL = cons(dp_ht(PS[I]),HL);
        !          2370:        for ( I = Len - 1, GI = []; I >= 0; I-- )
        !          2371:                GI = cons(I,GI);
        !          2372:        MB = dp_mbase(HL); DIM = length(MB); UT = newvect(DIM);
        !          2373:        U = dp_ptod(ptosfp(F),V);
        !          2374:        U = dp_nf_f(GI,U,PS,1);
        !          2375:        for ( I = 0; I < DIM; I++ )
        !          2376:                UT[I] = [MB[I],dp_nf_f(GI,U*MB[I],PS,1)];
        !          2377:
        !          2378:        T = dp_ptod(ptosfp(1),[V0]);
        !          2379:        TT = dp_ptod(ptosfp(1),V);
        !          2380:        G = H = [[TT,T]];
        !          2381:
        !          2382:        for ( I = 1; ; I++ ) {
        !          2383:                if ( dp_gr_print() )
        !          2384:                        print(".",2);
        !          2385:                T = dp_ptod(ptosfp(V0^I),[V0]);
        !          2386:                TT = dp_nf_tab_f(H[0][0],UT);
        !          2387:                H = cons([TT,T],H);
        !          2388:                L = dp_lnf_f([TT,T],G);
        !          2389:                if ( !L[0] ) {
        !          2390:                        if ( dp_gr_print() )
        !          2391:                                print("");
        !          2392:                        return dp_dtop(L[1],[V0]); /* XXX */
        !          2393:                } else
        !          2394:                        G = insert(G,L);
        !          2395:        }
        !          2396: }
        !          2397:
        !          2398: #if 1
        !          2399: def minipoly_sf_rat(G,V,F,V0)
        !          2400: {
        !          2401:        Vc = setminus(vars(G),V);
        !          2402:        Gf = cons(V0-F,G);
        !          2403:        Vf = append(V,[V0]);
        !          2404:        G3 = dp_gr_f_main(map(ptosfp,Gf),Vf,0,3);
        !          2405:        for ( T = G3; T != []; T = cdr(T) ) {
        !          2406:                Vt = setminus(vars(car(T)),Vc);
        !          2407:                if ( Vt == [V0] )
        !          2408:                        return car(T);
        !          2409:        }
        !          2410: }
        !          2411:
        !          2412: def minipoly_mod(G,V,Mod,F,V0)
        !          2413: {
        !          2414:        Vc = setminus(vars(G),V);
        !          2415:        Gf = cons(V0-F,G);
        !          2416:        Vf = append(V,[V0]);
        !          2417:        G3 = dp_gr_mod_main(Gf,Vf,1,Mod,3);
        !          2418:        for ( T = G3; T != []; T = cdr(T) ) {
        !          2419:                Vt = setminus(vars(car(T)),Vc);
        !          2420:                if ( Vt == [V0] )
        !          2421:                        return car(T);
        !          2422:        }
        !          2423: }
        !          2424: #endif
        !          2425:
        !          2426: /* find N/D s.t. F = N/D mod V^(2M), deg(N),deg(D)<M */
        !          2427:
        !          2428: def pade(F,M)
        !          2429: {
        !          2430:        V = var(F);
        !          2431:        A = newvect(M);
        !          2432:        D = 0;
        !          2433:        for ( I = 0; I < M; I++ ) {
        !          2434:                A[I] = strtov("b"+rtostr(I));
        !          2435:                D += A[I]*V^I;
        !          2436:        }
        !          2437:        T = F*D;
        !          2438:        M2 = M*2;
        !          2439:        R = [];
        !          2440:        for ( I = M; I < M2; I++ )
        !          2441:                R = cons(coef(T,I,V),R);
        !          2442: }
        !          2443:
        !          2444: def minipoly_sfrat(G0,V,O,P,V0,Server)
        !          2445: {
        !          2446:        if ( Server )
        !          2447:                ox_sync(0);
        !          2448:        if ( !zero_dim(hmlist(G0,V,O),V,O) )
        !          2449:                error("minipoly_sfrat : ideal is not zero-dimensional!");
        !          2450:
        !          2451:        G1 = cons(V0-P,G0);
        !          2452:        if ( type(O) <= 1 )
        !          2453:                O1 = [[0,1],[O,length(V)]];
        !          2454:        else
        !          2455:                O1 = cons([0,1],O);
        !          2456:        V1 = cons(V0,V);
        !          2457:        W = append(V,[V0]);
        !          2458:        Vc = setminus(vars(G0),V);
        !          2459:
        !          2460:        N = length(V1);
        !          2461:        dp_ord(O1);
        !          2462:        HM = hmlist(G1,V1,O1);
        !          2463:        MB = dp_mbase(map(dp_ptod,HM,V1));
        !          2464:        dp_ord(O);
        !          2465:
        !          2466:        Nc = length(Vc);
        !          2467:        Eval = newvect(Nc);
        !          2468:
        !          2469:        /* heristic lower bound of deg(MP) */
        !          2470:        Q1 = field_order_ff()-1;
        !          2471:        do {
        !          2472:                for ( I = 0; I < Nc; I++ )
        !          2473:                        Eval[I] = random()%Q1;
        !          2474:        } while ( !valid_modulus_sfrat(HM,Vc,Eval) );
        !          2475:        G0E = map(eval_sfrat,G0,Vc,Eval);
        !          2476:        P0 = eval_sfrat(P,Vc,Eval);
        !          2477:        MP = minipoly_sf(G0E,V,O,P0,V0);
        !          2478:        DMP = deg(MP,V0);
        !          2479:
        !          2480:        for ( I = 0; I < Nc; I++ )
        !          2481:                Eval[I] = 0;
        !          2482:        while ( 1 ) {
        !          2483:                if ( valid_modulus_sfrat(HM,Vc,Eval) ) {
        !          2484:                        G0E = map(eval_sfrat,G0,Vc,Eval);
        !          2485:                        P0 = eval_sfrat(P,Vc,Eval);
        !          2486:                        MP = minipoly_sf(G0E,V,O,P0,V0);
        !          2487:                        D = deg(MP,V0);
        !          2488:                        if ( D >= DMP ) {
        !          2489:                                DMP = D;
        !          2490:                                for ( TL = [], MPT = 0, J = 0; J <= D; J++ ) {
        !          2491:                                        TL = cons(V0^J,TL);
        !          2492:                                        MPT += car(TL);
        !          2493:                                }
        !          2494:                                NF = gennf_sfrat(G1,TL,V1,O1,V0,1)[0];
        !          2495:                                R = tolex_sfrat_main(V1,O1,NF,[MPT],Vc,Eval,MB);
        !          2496:                                if ( R )
        !          2497:                                        return sdiv(R[0],sfcont(R[0],V0));
        !          2498:                        }
        !          2499:                }
        !          2500:                next_eval_sfrat(Eval);
        !          2501:        }
        !          2502: }
        !          2503:
        !          2504: def next_eval_sfrat(Eval)
        !          2505: {
        !          2506:        N = size(Eval)[0];
        !          2507:        for ( I = N-1; I >= 0; I-- )
        !          2508:                if ( Eval[I] ) break;
        !          2509:        if ( I < 0 ) Eval[N-1] = 1;
        !          2510:        else if ( I == 0 ) {
        !          2511:                T = Eval[0]; Eval[0] = 0; Eval[N-1] = T+1;
        !          2512:        } else {
        !          2513:                Eval[I-1]++; T = Eval[I];
        !          2514:                for ( J = I; J < N-1; J++ )
        !          2515:                        Eval[J] = 0;
        !          2516:                Eval[N-1] = T-1;
        !          2517:        }
        !          2518: }
        !          2519:
        !          2520: def eval_sfrat(F,V,Eval)
        !          2521: {
        !          2522:        for ( I = 0; V != []; V = cdr(V), I++ )
        !          2523:                F = subst(F,car(V),ptosfp(Eval[I]));
        !          2524:        return F;
        !          2525: }
        !          2526:
        !          2527: def valid_modulus_sfrat(HL,Vc,Eval) {
        !          2528:        for ( T = HL; T != []; T = cdr(T) ) {
        !          2529:                C = car(T);
        !          2530:                for ( S = Vc, I = 0; S != []; S = cdr(S), I++ )
        !          2531:                        C = subst(C,car(S),ptosfp(Eval[I]));
        !          2532:                if ( !C )
        !          2533:                        break;
        !          2534:        }
        !          2535:        return T == [] ? 1 : 0;
        !          2536: }
        !          2537:
        !          2538: def gennf_sfrat(G,TL,V,O,V0,FLAG)
        !          2539: {
        !          2540:        N = length(V); Len = length(G); dp_ord(O); PS = newvect(Len);
        !          2541:        for ( I = 0, T = G, HL = []; T != []; T = cdr(T), I++ ) {
        !          2542:                PS[I] = dp_ptod(car(T),V); HL = cons(dp_ht(PS[I]),HL);
        !          2543:        }
        !          2544:        for ( I = 0, DTL = []; TL != []; TL = cdr(TL) )
        !          2545:                DTL = cons(dp_ptod(car(TL),V),DTL);
        !          2546:        for ( I = Len - 1, GI = []; I >= 0; I-- )
        !          2547:                GI = cons(I,GI);
        !          2548:        T = car(DTL); DTL = cdr(DTL);
        !          2549:        H = [nf_sfrat(GI,T,T,PS)];
        !          2550:
        !          2551:        USE_TAB = (FLAG != 0);
        !          2552:        if ( USE_TAB ) {
        !          2553:                T0 = time()[0];
        !          2554:                MB = dp_mbase(HL); DIM = length(MB);
        !          2555:                U = dp_ptod(V0,V);
        !          2556:                UTAB = newvect(DIM);
        !          2557:                for ( I = 0; I < DIM; I++ ) {
        !          2558:                        UTAB[I] = [MB[I],remove_cont_sfrat(nf_sfrat(GI,U*MB[I],1,PS))];
        !          2559:                        if ( dp_gr_print() )
        !          2560:                                print(".",2);
        !          2561:                }
        !          2562:                if ( dp_gr_print() )
        !          2563:                        print("");
        !          2564:                TTAB = time()[0]-T0;
        !          2565:        }
        !          2566:
        !          2567:        T0 = time()[0];
        !          2568:        for ( LCM = 1; DTL != []; ) {
        !          2569:                if ( dp_gr_print() )
        !          2570:                        print(".",2);
        !          2571:                T = car(DTL); DTL = cdr(DTL);
        !          2572:                if ( L = search_redble(T,H) ) {
        !          2573:                        DD = dp_subd(T,L[1]);
        !          2574:                        if ( USE_TAB && (DD == U) ) {
        !          2575:                                NF = nf_tab_sfrat(L[0],UTAB);
        !          2576:                                NF = [NF[0],dp_hc(L[1])*NF[1]*T];
        !          2577:                        } else
        !          2578:                                NF = nf_sfrat(GI,L[0]*dp_subd(T,L[1]),dp_hc(L[1])*T,PS);
        !          2579:                } else
        !          2580:                        NF = nf_sfrat(GI,T,T,PS);
        !          2581:                NF = remove_cont_sfrat(NF);
        !          2582:                H = cons(NF,H);
        !          2583:                LCM = lcm_sfrat(LCM,dp_hc(NF[1]));
        !          2584:        }
        !          2585:        TNF = time()[0]-T0;
        !          2586:        if ( dp_gr_print() )
        !          2587:                print("gennf(TAB="+rtostr(TTAB)+" NF="+rtostr(TNF)+")");
        !          2588:        return [[map(adj_dn_sfrat,H,LCM),LCM],PS,GI];
        !          2589: }
        !          2590:
        !          2591: def lcm_sfrat(A,B)
        !          2592: {
        !          2593:        G = sfgcd(A,B);
        !          2594:        return sdiv(A,G)*B;
        !          2595: }
        !          2596:
        !          2597: #define REDCONT(f) ((f)/sfcont(f))
        !          2598:
        !          2599: def remove_cont_sfrat(L)
        !          2600: {
        !          2601:        if ( type(L[1]) <= 2 ) {
        !          2602:                T = remove_cont_sfrat([L[0],L[1]*<<0>>]);
        !          2603:                return [T[0],dp_hc(T[1])];
        !          2604:        } else if ( !L[0] )
        !          2605:                return [0,REDCONT(L[1])];
        !          2606:        else if ( !L[1] )
        !          2607:                return [REDCONT(L[0]),0];
        !          2608:        else {
        !          2609:                A0 = REDCONT(L[0]); A1 = REDCONT(L[1]);
        !          2610:                C0 = sdiv(dp_hc(L[0]),dp_hc(A0)); C1 = sdiv(dp_hc(L[1]),dp_hc(A1));
        !          2611:                GCD = sfgcd(C0,C1); M0 = sdiv(C0,GCD); M1 = sdiv(C1,GCD);
        !          2612:                return [M0*A0,M1*A1];
        !          2613:        }
        !          2614: }
        !          2615:
        !          2616: def nf_sfrat(B,G,M,PS)
        !          2617: {
        !          2618:        for ( D = 0; G; ) {
        !          2619:                for ( U = 0, L = B; L != []; L = cdr(L) ) {
        !          2620:                        if ( dp_redble(G,R=PS[car(L)]) > 0 ) {
        !          2621:                                GCD = sfgcd(dp_hc(G),dp_hc(R));
        !          2622:                                CG = sdiv(dp_hc(R),GCD); CR = sdiv(dp_hc(G),GCD);
        !          2623:                                U = CG*G-dp_subd(G,R)*CR*R;
        !          2624:                                if ( !U )
        !          2625:                                        return [D,M];
        !          2626:                                D *= CG; M *= CG;
        !          2627:                                break;
        !          2628:                        }
        !          2629:                }
        !          2630:                if ( U )
        !          2631:                        G = U;
        !          2632:                else {
        !          2633:                        D += dp_hm(G); G = dp_rest(G);
        !          2634:                }
        !          2635:        }
        !          2636:        return [D,M];
        !          2637: }
        !          2638:
        !          2639: def nf_tab_sfrat(F,TAB)
        !          2640: {
        !          2641:        for ( NM = 0, DN = 1, I = 0; F; F = dp_rest(F) ) {
        !          2642:                T = dp_ht(F);
        !          2643:                for ( ; TAB[I][0] != T; I++);
        !          2644:                NF = TAB[I][1]; N = NF[0]; D = NF[1];
        !          2645:                G = sfgcd(DN,D); DN1 = sdiv(DN,G); D1 = sdiv(D,G);
        !          2646:                NM = D1*NM + DN1*dp_hc(F)*N; DN *= D1;
        !          2647:        }
        !          2648:        return [NM,DN];
        !          2649: }
        !          2650:
        !          2651: def adj_dn_sfrat(P,D)
        !          2652: {
        !          2653:        return [(sdiv(D,dp_hc(P[1])))*P[0],dp_ht(P[1])];
        !          2654: }
        !          2655:
        !          2656: def tolex_sfrat_main(V,O,NF,GM,Vc,Eval,MB)
        !          2657: {
        !          2658:        if ( MB ) {
        !          2659:                PosDim = 0;
        !          2660:                DIM = length(MB);
        !          2661:                DV = newvect(DIM);
        !          2662:        } else
        !          2663:                PosDim = 1;
        !          2664:        for ( T = GM, SL = [], LCM = 1; T != []; T = cdr(T) ) {
        !          2665:                S = p_terms(car(T),V,2);
        !          2666:                if ( PosDim ) {
        !          2667:                        MB = gather_nf_terms(S,NF,V,O);
        !          2668:                        DV = newvect(length(MB));
        !          2669:                }
        !          2670:                dp_ord(O); RHS = termstomat_sfrat(NF,map(dp_ptod,cdr(S),V),MB,Vc,Eval);
        !          2671:                dp_ord(O); NHT = nf_tab_gsl_sfrat(dp_ptod(LCM*car(S),V),NF);
        !          2672:                dptov(NHT[0],DV,MB);
        !          2673:                dp_ord(O); B = hen_ttob_gsl_sfrat([DV,NHT[1]],RHS,cdr(S),Vc,Eval);
        !          2674:                if ( !B )
        !          2675:                        return 0;
        !          2676:                Len = length(S);
        !          2677:                LCM *= B[1];
        !          2678:                for ( U = LCM*car(S), I = 1; I < Len; I++  )
        !          2679:                        U += B[0][I-1]*S[I];
        !          2680:                SL = cons(U,SL);
        !          2681:                if ( dp_gr_print() )
        !          2682:                        print(["DN",B[1]]);
        !          2683:        }
        !          2684:        return SL;
        !          2685: }
        !          2686:
        !          2687: def termstomat_sfrat(NF,TERMS,MB,Vc,Eval)
        !          2688: {
        !          2689:        DN = NF[1];
        !          2690:        NF = NF[0];
        !          2691:        N = length(MB);
        !          2692:        M = length(TERMS);
        !          2693:        MAT = newmat(N,M);
        !          2694:        W = newvect(N);
        !          2695:        Len = length(NF);
        !          2696:        for ( I = 0; I < M; I++ ) {
        !          2697:                T = TERMS[I];
        !          2698:                for ( K = 0; K < Len; K++ )
        !          2699:                        if ( T == NF[K][1] )
        !          2700:                                break;
        !          2701:                dptov(NF[K][0],W,MB);
        !          2702:                for ( J = 0; J < N; J++ )
        !          2703:                        MAT[J][I] = W[J];
        !          2704:        }
        !          2705:        return [henleq_prep_sfrat(MAT,Vc,Eval),DN];
        !          2706: }
        !          2707:
        !          2708: def henleq_prep_sfrat(A,Vc,Eval)
        !          2709: {
        !          2710:        SIZE = size(A); ROW = SIZE[0]; COL = SIZE[1];
        !          2711:        L = geninv_sf_swap(map(eval_sfrat,A,Vc,Eval)); INV = L[0]; INDEX = L[1];
        !          2712:        AA = newmat(COL,COL);
        !          2713:        for ( I = 0; I < COL; I++ )
        !          2714:                for ( J = 0, T = AA[I], S = A[INDEX[I]]; J < COL; J++ )
        !          2715:                        T[J] = S[J];
        !          2716:        if ( COL != ROW ) {
        !          2717:                RESTA = newmat(ROW-COL,COL);
        !          2718:                for ( ; I < ROW; I++ )
        !          2719:                        for ( J = 0, T = RESTA[I-COL], S = A[INDEX[I]]; J < COL; J++ )
        !          2720:                                T[J] = S[J];
        !          2721:        } else
        !          2722:                RESTA = 0;
        !          2723:        return [[A,AA,RESTA],L];
        !          2724: }
        !          2725:
        !          2726: def hen_ttob_gsl_sfrat(LHS,RHS,TERMS,Vc,Eval)
        !          2727: {
        !          2728:        LDN = LHS[1]; RDN = RHS[1]; LCM = lcm_sfrat(LDN,RDN);
        !          2729:        L1 = sdiv(LCM,LDN); R1 = sdiv(LCM,RDN);
        !          2730:        T0 = time()[0];
        !          2731:        S = henleq_gsl_sfrat(RHS[0],LHS[0]*L1,Vc,Eval);
        !          2732:        if ( dp_gr_print() )
        !          2733:                print(["henleq_gsl_sfrat",time()[0]-T0]);
        !          2734:        if ( !S )
        !          2735:                return 0;
        !          2736:        N = length(TERMS);
        !          2737:        return [S[0],S[1]*R1];
        !          2738: }
        !          2739:
        !          2740: def nf_tab_gsl_sfrat(A,NF)
        !          2741: {
        !          2742:        DN = NF[1];
        !          2743:        NF = NF[0];
        !          2744:        TLen = length(NF);
        !          2745:        for ( R = 0; A; A = dp_rest(A) ) {
        !          2746:                HM = dp_hm(A); C = dp_hc(HM); T = dp_ht(HM);
        !          2747:                for ( I = 0; I < TLen; I++ )
        !          2748:                        if ( NF[I][1] == T )
        !          2749:                                break;
        !          2750:                R += C*NF[I][0];
        !          2751:        }
        !          2752:        return remove_cont_sfrat([R,DN]);
        !          2753: }
        !          2754:
        !          2755: def henleq_gsl_sfrat(L,B,Vc,Eval)
        !          2756: {
        !          2757:        Nc = length(Vc);
        !          2758:        if ( Nc > 1 )
        !          2759:                return henleq_gsl_sfrat_higher(L,B,Vc,Eval);
        !          2760:
        !          2761:        V0 = Vc[0]; E0 = ptosfp(Eval[0]);
        !          2762:
        !          2763:        AL = L[0]; INVL = L[1];
        !          2764:        A = AL[0]; AA = AL[1]; RESTA = AL[2];
        !          2765:        INV = INVL[0]; INDEX = INVL[1];
        !          2766:
        !          2767:        SIZE = size(A); ROW = SIZE[0]; COL = SIZE[1];
        !          2768:        BB = newvect(COL);
        !          2769:        for ( I = 0; I < COL; I++ )
        !          2770:                BB[I] = B[INDEX[I]];
        !          2771:        if ( COL != ROW ) {
        !          2772:                RESTB = newvect(ROW-COL);
        !          2773:                for ( ; I < ROW; I++ )
        !          2774:                        RESTB[I-COL] = B[INDEX[I]];
        !          2775:        } else
        !          2776:                RESTB = 0;
        !          2777:
        !          2778:        COUNT = 2;
        !          2779:        if ( !COUNT )
        !          2780:                COUNT = 2;
        !          2781:        X = newvect(size(AA)[0]);
        !          2782:        for ( I = 0, C = BB, CCC = 0, ITOR_FAIL = -1; ; I++ ) {
        !          2783:                if ( zerovector(C) ) {
        !          2784:                        X = map(subst,X,V0,V0-E0);
        !          2785:                        if ( zerovector(RESTA*X+RESTB) ) {
        !          2786:                                if ( dp_gr_print() ) print("end",0);
        !          2787:                                return [X,ptosfp(1)];
        !          2788:                        } else
        !          2789:                                return 0;
        !          2790:                } else if ( COUNT == CCC ) {
        !          2791:                        CCC = 0;
        !          2792:                        ND = polyvtoratv(X,V0,I);
        !          2793:                        if ( ND ) {
        !          2794:                                F = map(subst,ND[0],V0,V0-E0);
        !          2795:                                LCM = subst(ND[1],V0,V0-E0);
        !          2796:                                T = AA*F+LCM*BB;
        !          2797:                                if ( zerovector(T) ) {
        !          2798:                                        T = RESTA*F+LCM*RESTB;
        !          2799:                                        if ( zerovector(T) ) {
        !          2800:                                                if ( dp_gr_print() ) print("end",0);
        !          2801:                                                return [F,LCM];
        !          2802:                                        } else
        !          2803:                                                return 0;
        !          2804:                                }
        !          2805:                        } else {
        !          2806:                        }
        !          2807:                } else {
        !          2808:                        if ( dp_gr_print() ) print(".",2);
        !          2809:                        CCC++;
        !          2810:                }
        !          2811:                XT = -INV*map(subst,C,V0,E0);
        !          2812:                X += XT*V0^I;
        !          2813:                C += AA*XT;
        !          2814:                C = map(sdiv,C,V0-E0);
        !          2815:        }
        !          2816: }
        !          2817:
        !          2818: def henleq_gsl_sfrat_higher(L,B,Vc,Eval)
        !          2819: {
        !          2820:        Nc = length(Vc);
        !          2821:        E = map(ptosfp,Eval);
        !          2822:
        !          2823:        AL = L[0]; INVL = L[1];
        !          2824:        A = AL[0]; AA0 = AL[1]; RESTA = AL[2];
        !          2825:        INV = INVL[0]; INDEX = INVL[1];
        !          2826:
        !          2827:        SIZE = size(A); ROW = SIZE[0]; COL = SIZE[1];
        !          2828:
        !          2829:        AA = map(mshift,AA0,Vc,E,1);
        !          2830:        BB = newvect(COL);
        !          2831:        for ( I = 0; I < COL; I++ )
        !          2832:                BB[I] = mshift(B[INDEX[I]],Vc,E,1);
        !          2833:
        !          2834:        if ( COL != ROW ) {
        !          2835:                RESTB = newvect(ROW-COL);
        !          2836:                for ( ; I < ROW; I++ )
        !          2837:                        RESTB[I-COL] = B[INDEX[I]];
        !          2838:        } else
        !          2839:                RESTB = 0;
        !          2840:
        !          2841:        COUNT = 2;
        !          2842:        if ( !COUNT )
        !          2843:                COUNT = 2;
        !          2844:        X = newvect(size(AA)[0]);
        !          2845:        for ( I = 0, R = BB, CCC = 0, ITOR_FAIL = -1; ; I++ ) {
        !          2846:                if ( zerovector(R) ) {
        !          2847:                        X = map(mshift,X,Vc,E,-1);
        !          2848:                        if ( zerovector(RESTA*X+RESTB) ) {
        !          2849:                                if ( dp_gr_print() ) print("end",0);
        !          2850:                                return [X,ptosfp(1)];
        !          2851:                        } else
        !          2852:                                return 0;
        !          2853:                } else if ( COUNT == CCC ) {
        !          2854:                        CCC = 0;
        !          2855:                        ND = polyvtoratv_higher(X,Vc,I);
        !          2856:                        if ( ND ) {
        !          2857:                                F = map(mshift,ND[0],Vc,E,-1);
        !          2858:                                LCM = mshift(ND[1],Vc,E,-1);
        !          2859:                                T = AA*F+LCM*BB;
        !          2860:                                if ( zerovector(T) ) {
        !          2861:                                        T = RESTA*F+LCM*RESTB;
        !          2862:                                        if ( zerovector(T) ) {
        !          2863:                                                if ( dp_gr_print() ) print("end",0);
        !          2864:                                                return [F,LCM];
        !          2865:                                        } else
        !          2866:                                                return 0;
        !          2867:                                }
        !          2868:                        } else {
        !          2869:                        }
        !          2870:                } else {
        !          2871:                        if ( dp_gr_print() ) print(".",2);
        !          2872:                        CCC++;
        !          2873:                }
        !          2874:                RK = map(mtrunc,R,I+1);
        !          2875:                XT = -INV*RK;
        !          2876:                X += XT;
        !          2877:                R += AA*XT;
        !          2878:        }
        !          2879: }
        !          2880:
        !          2881: /* V -> V+Sgn*E */
        !          2882:
        !          2883: def mshift(F,V,E,Sgn)
        !          2884: {
        !          2885:        N = length(V);
        !          2886:        for ( I = 0; I < N; I++ )
        !          2887:                F = subst(F,V[I],V[I]+Sgn*E[I]);
        !          2888:        return F;
        !          2889: }
        !          2890:
        !          2891: /* truncate terms whose degree are higher than or equal to D */
        !          2892:
        !          2893: def mtrunc(F,D)
        !          2894: {
        !          2895:        if ( type(F) <= 1 )
        !          2896:                return F;
        !          2897:        else {
        !          2898:                R = 0;
        !          2899:                V = var(F);
        !          2900:                while ( F ) {
        !          2901:                        K = deg(F,V);
        !          2902:                        C = coef(F,K,V);
        !          2903:                        if ( K < D )
        !          2904:                                R += mtrunc(C,D-K)*V^K;
        !          2905:                        F -= C*V^K;
        !          2906:                }
        !          2907:                return R;
        !          2908:        }
        !          2909: }
        !          2910:
        !          2911: /* for 1-dim case */
        !          2912:
        !          2913: def polyvtoratv(Vect,V,K)
        !          2914: {
        !          2915:        N = size(Vect)[0];
        !          2916:        R = newvect(N);
        !          2917:        K2 = idiv(K,2);
        !          2918:        Mat = newmat(K2,K2);
        !          2919:        for ( I = 0; I < N; I++ ) {
        !          2920:                T = polytorat(Vect[I],V,Mat,K2);
        !          2921:                if ( T )
        !          2922:                        R[I] = T;
        !          2923:                else
        !          2924:                        return 0;
        !          2925:        }
        !          2926:        LCM = R[0][1];
        !          2927:        for ( I = 1; I < N; I++ )
        !          2928:                LCM = lcm_sfrat(LCM,R[I][1]);
        !          2929:        for ( I = 0; I < N; I++ )
        !          2930:                R[I] = R[I][0]*sdiv(LCM,R[I][1]);
        !          2931:        return [R,LCM];
        !          2932: }
        !          2933:
        !          2934: /* for higher dim case */
        !          2935:
        !          2936: def polyvtoratv_higher(Vect,Vc,K)
        !          2937: {
        !          2938:        N = size(Vect)[0];
        !          2939:        R = newvect(N);
        !          2940:        K2 = idiv(K,2);
        !          2941:        for ( I = 0; I < N; I++ ) {
        !          2942:                T = polytorat_higher(Vect[I],Vc,K2);
        !          2943:                if ( T )
        !          2944:                        R[I] = T;
        !          2945:                else
        !          2946:                        return 0;
        !          2947:        }
        !          2948:        LCM = R[0][1];
        !          2949:        for ( I = 1; I < N; I++ )
        !          2950:                LCM = lcm_sfrat(LCM,R[I][1]);
        !          2951:        for ( I = 0; I < N; I++ )
        !          2952:                R[I] = R[I][0]*sdiv(LCM,R[I][1]);
        !          2953:        return [R,LCM];
        !          2954: }
        !          2955:
        !          2956: /* find F = N/D mod V^(2K), deg(N), deg(D) < K */
        !          2957: def polytorat_gcd(F,V,K)
        !          2958: {
        !          2959:        if ( deg(F,V) < K )
        !          2960:                return [F,ptosfp(1)];
        !          2961:        F1 = Mod^(K*2); F2 = F;
        !          2962:        B1 = 0; B2 = 1;
        !          2963:        while ( 1 ) {
        !          2964:                Q = sdiv(F1,F2);
        !          2965:                F3 = F1-F2*Q;
        !          2966:                B3 = B1-B2*Q;
        !          2967:                if ( deg(F3,V) < K ) {
        !          2968:                        if ( deg(B3,V) < K )
        !          2969:                                return [F3,B3];
        !          2970:                        else
        !          2971:                                return 0;
        !          2972:                }
        !          2973:                F1 = F2; F2 = F3;
        !          2974:                B1 = B2; B2 = B3;
        !          2975:        }
        !          2976: }
        !          2977:
        !          2978: /*
        !          2979:  * for 1-dim case
        !          2980:  *
        !          2981:  * solve
        !          2982:  *
        !          2983:  * [fk      ... f1][  a0  ]
        !          2984:  * [f(k+1)  ... f2][  a1  ] = 0
        !          2985:  * [        ...   ][ ...  ]
        !          2986:  * [f(2k-1) ... fk][a(k-1)]
        !          2987:  */
        !          2988:
        !          2989: def polytorat(F,V,Mat,K)
        !          2990: {
        !          2991:        if ( deg(F,V) < K )
        !          2992:                return [F,ptosfp(1)];
        !          2993:        for ( I = 0; I < K; I++ )
        !          2994:                for ( J = 0; J < K; J++ )
        !          2995:                        Mat[I][J] = coef(F,I+K-J);
        !          2996:        S = nullspace_ff(Mat);
        !          2997:        MT = S[0]; IND = S[1];
        !          2998:        for ( I = 0; I < K; I++ )
        !          2999:                if ( IND[I] )
        !          3000:                        break;
        !          3001:        if ( I == K )
        !          3002:                return 0;
        !          3003:        D = null_to_poly_ff(MT,IND,V)[0];
        !          3004:        N = trunc(F*D,K-1);
        !          3005:        return [N,D];
        !          3006: }
        !          3007:
        !          3008: /* find N,D s.t. tdeg(N), tdeg(D) < K, F = N/D mod <V0,...,VM>^(2K) */
        !          3009:
        !          3010: def polytorat_higher(F,V,K)
        !          3011: {
        !          3012:        if ( K < 2 ) return 0;
        !          3013:        if ( homogeneous_deg(F) < K )
        !          3014:                return [F,ptosfp(1)];
        !          3015:        D = create_icpoly(V,K);
        !          3016:        C = extract_coef(D*F,V,K,2*K);
        !          3017:        Vc = vars(C);
        !          3018:        G = dp_gr_f_main(C,Vc,0,2);
        !          3019:        PS = newvect(length(G),map(dp_ptod,G,Vc));
        !          3020:        for ( I = length(G)-1, Ind = [];I >= 0; I-- )
        !          3021:                Ind = cons(I,Ind);
        !          3022:        D = dp_dtop(nf_sfrat(Ind,dp_ptod(D,Vc),1,PS)[0],Vc);
        !          3023:        if ( !D )
        !          3024:                return 0;
        !          3025:        Vp = setminus(vars(D),V);
        !          3026:        D = subst(D,car(Vp),1);
        !          3027:        for ( T = cdr(Vp); T != []; T = cdr(T) )
        !          3028:                D = subst(D,car(T),0);
        !          3029:        N = mtrunc(F*D,K);
        !          3030:        return [N,D];
        !          3031: }
        !          3032:
        !          3033: def create_icpoly(V,K)
        !          3034: {
        !          3035:        if ( V == [] )
        !          3036:                return uc();
        !          3037:        R = 0;
        !          3038:        for ( I = 0; I < K; I++ )
        !          3039:                R += create_icpoly(cdr(V),K-I)*V[0]^I;
        !          3040:        return R;
        !          3041: }
        !          3042:
        !          3043: /* extract terms whose degrees are in [From,To) */
        !          3044:
        !          3045: def extract_coef(F,V,From,To)
        !          3046: {
        !          3047:        if ( V == [] ) {
        !          3048:                if ( From == 0 )
        !          3049:                        return [F];
        !          3050:                else
        !          3051:                        return [];
        !          3052:        }
        !          3053:        R = [];
        !          3054:        V0 = V[0];
        !          3055:        for ( I = 0; I < To; I++ ) {
        !          3056:                C = coef(F,I,V0);
        !          3057:                if ( C ) {
        !          3058:                        C = extract_coef(C,cdr(V),From>=I?From-I:0,To-I);
        !          3059:                        R = append(C,R);
        !          3060:                }
        !          3061:        }
        !          3062:        return R;
        !          3063: }
        !          3064:
        !          3065: def saturation_sfrat(F,G,V,Ord)
        !          3066: {
        !          3067:        Vt = ttttt;
        !          3068:        G0 = dp_gr_f_main(cons(Vt*F-1,G),cons(Vt,V),0,[[0,1],[Ord,length(V)]]);
        !          3069:        return elimination(G0,V);
        !          3070: }
        !          3071:
        !          3072: def ideal_list_intersection_sfrat(L,V)
        !          3073: {
        !          3074:        R = car(L);
        !          3075:        for ( TL = cdr(L); TL != []; TL = cdr(TL) )
        !          3076:                R = ideal_intersection_sfrat(R,car(TL),V);
        !          3077:        return R;
        !          3078: }
        !          3079:
        !          3080: def ideal_intersection_sfrat(A,B,V)
        !          3081: {
        !          3082:        T0 = time();
        !          3083:        Vt = ttttt;
        !          3084:        C = [];
        !          3085:        for ( T = A; T != []; T = cdr(T) )
        !          3086:                C = cons(car(T)*Vt,C);
        !          3087:        for ( T = B; T != []; T = cdr(T) )
        !          3088:                C = cons(car(T)*(1-Vt),C);
        !          3089:        Ord = [[0,1],[0,length(V)]];
        !          3090: #if 0
        !          3091:        G0 = dp_gr_f_main(C,cons(Vt,V),0,0);
        !          3092:        G = dp_gr_f_main(G0,cons(Vt,V),0,Ord);
        !          3093: #else
        !          3094:        G = dp_gr_f_main(C,cons(Vt,V),0,Ord);
        !          3095: #endif
        !          3096:        T_INT += time()[3]-T0[3];
        !          3097:        return elimination(G,V);
        !          3098: }
        !          3099:
        !          3100: /* Shimoyama's gr_fctr */
        !          3101:
        !          3102: def idealsqfr_sf(G)
        !          3103: {
        !          3104:        for(LL=[],I=length(G)-1;I>=0;I--) {
        !          3105:                for(A=1,L=sfsqfr(G[I]),J=1;J<length(L);J++)
        !          3106:                        A*=L[J][0];
        !          3107:                LL=cons(A,LL);
        !          3108:        }
        !          3109:        return LL;
        !          3110: }
        !          3111:
        !          3112: def ideal_uniq(L) /* sub procedure of welldec and normposdec */
        !          3113: {
        !          3114:        for (R = [],I = 0,N=length(L); I < N; I++) {
        !          3115:                if ( R == [] )
        !          3116:                        R = append(R,[L[I]]);
        !          3117:                else {
        !          3118:                        for (J = 0; J < length(R); J++)
        !          3119:                                if ( gb_comp(L[I],R[J]) )
        !          3120:                                        break;
        !          3121:                        if ( J == length(R) )
        !          3122:                                R = append(R,[L[I]]);
        !          3123:                }
        !          3124:        }
        !          3125:        return R;
        !          3126: }
        !          3127:
        !          3128: def ideal_uniq_by_first(L) /* sub procedure of welldec and normposdec */
        !          3129: {
        !          3130:        for (R = [],I = 0,N=length(L); I < N; I++) {
        !          3131:                if ( R == [] )
        !          3132:                        R = append(R,[L[I]]);
        !          3133:                else {
        !          3134:                        for (J = 0; J < length(R); J++)
        !          3135:                                if ( gb_comp(L[I][0],R[J][0]) )
        !          3136:                                        break;
        !          3137:                        if ( J == length(R) )
        !          3138:                                R = append(R,[L[I]]);
        !          3139:                }
        !          3140:        }
        !          3141:        return R;
        !          3142: }
        !          3143:
        !          3144: def prime_irred_sf(TP,VL,Ord)
        !          3145: {
        !          3146:        TP = ideal_uniq(TP);
        !          3147:        N = length(TP);
        !          3148:        for (P = [], I = 0; I < N; I++) {
        !          3149:                for (J = 0; J < N; J++)
        !          3150:                        if ( I != J && inclusion_test(TP[J],TP[I],VL,Ord) )
        !          3151:                                break;
        !          3152:                if (J == N)
        !          3153:                        P = append(P,[TP[I]]);
        !          3154:        }
        !          3155:        return P;
        !          3156: }
        !          3157:
        !          3158: def prime_irred_sf_by_first(TP,VL,Ord)
        !          3159: {
        !          3160:        TP = ideal_uniq_by_first(TP);
        !          3161:        N = length(TP);
        !          3162:        for (P = [], I = 0; I < N; I++) {
        !          3163:                for (J = 0; J < N; J++)
        !          3164:                        if ( I != J && inclusion_test(car(TP[J]),car(TP[I]),VL,Ord) )
        !          3165:                                break;
        !          3166:                if (J == N)
        !          3167:                        P = append(P,[TP[I]]);
        !          3168:        }
        !          3169:        return P;
        !          3170: }
        !          3171:
        !          3172: def monic_sf_first(L,V)
        !          3173: {
        !          3174:        for ( R = [], T = L; T != []; T = cdr(T) )
        !          3175:                R = cons([monic_sf(car(T)[0],V),car(T)[1]],R);
        !          3176:        return reverse(R);
        !          3177: }
        !          3178:
        !          3179: def monic_sf(P,V)
        !          3180: {
        !          3181:        if ( type(P) == 4 )
        !          3182:                return map(monic_sf,P,V);
        !          3183:        else {
        !          3184:                D = dp_ptod(P,V);
        !          3185:                return dp_dtop(D/dp_hc(D),V);
        !          3186:        }
        !          3187: }
        !          3188:
        !          3189: def gr_fctr_sf(FL,VL,Ord)
        !          3190: {
        !          3191:        T0 = time();
        !          3192:        COMMONCHECK_SF = 1;
        !          3193:        for (TP = [],I = 0; I<length(FL); I++ ) {
        !          3194:                F = FL[I];
        !          3195:                SF = idealsqfr_sf(F);
        !          3196:                if ( !gb_comp(F,SF) )
        !          3197:                        F = dp_gr_f_main(SF,VL,0,Ord);
        !          3198:                CID_SF=[1];
        !          3199:                SP = gr_fctr_sub_sf(F,VL,Ord);
        !          3200:                TP = append(TP,SP);
        !          3201:        }
        !          3202:        TP = prime_irred_sf(TP,VL,Ord);
        !          3203:        T_GRF += time()[3]-T0[3];
        !          3204:        return TP;
        !          3205: }
        !          3206:
        !          3207: def gr_fctr_sub_sf(G,VL,Ord)
        !          3208: {
        !          3209:        if ( length(G) == 1 && type(G[0]) == 1 )
        !          3210:                return [G];
        !          3211:        RL = [];
        !          3212:        for (I = 0; I < length(G); I++) {
        !          3213:                FL = sffctr(G[I]); L = length(FL); N = FL[1][1];
        !          3214:                if (L > 2 || N > 1) {
        !          3215:                        TLL = [];
        !          3216:                        for (J = 1; J < L; J++) {
        !          3217:                                W = cons(FL[J][0],G);
        !          3218:                                NG = dp_gr_f_main(W,VL,0,Ord);
        !          3219:                                TNG = idealsqfr_sf(NG);
        !          3220:                                if ( !gb_comp(NG,TNG) )
        !          3221:                                        NG = dp_gr_f_main(TNG,VL,0,Ord);
        !          3222:                                if ( !inclusion_test(CID_SF,NG,VL,Ord) ) {
        !          3223:                                        DG = gr_fctr_sub_sf(NG,VL,Ord);
        !          3224:                                        RL = append(RL,DG);
        !          3225:                                        if ( J <= L-2
        !          3226:                                                && !inclusion_test(CID_SF,NG,VL,Ord)
        !          3227:                                                && COMMONCHECK_SF ) {
        !          3228:                                                CID_SF=ideal_intersection_sfrat(CID_SF,NG,VL);
        !          3229:                                        }
        !          3230:                                }
        !          3231:                        }
        !          3232:                        break;
        !          3233:                }
        !          3234:        }
        !          3235:        if (I == length(G))
        !          3236:                RL = append([G],RL);
        !          3237:        return RL;
        !          3238: }
        !          3239: end$

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