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

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

1.1     ! noro        1: /* $OpenXM: OpenXM/src/asir99/builtin/al.c,v 1.2 1999/11/18 05:42:01 noro Exp $ */
        !             2: /* ----------------------------------------------------------------------
        !             3:    $Id: al.c,v 1.3 1998/12/08 16:23:00 sturm Exp $
        !             4:    ----------------------------------------------------------------------
        !             5:    File al.c: Real quantifier elimination code for RISA/ASIR
        !             6:
        !             7:    Copyright (c) 1996, 1997, 1998 by
        !             8:    Andreas Dolzmann and Thomas Sturm, University of Passau, Germany
        !             9:    dolzmann@uni-passau.de, sturm@uni-passau.de
        !            10:    ----------------------------------------------------------------------
        !            11: */
        !            12:
        !            13: #include <ca.h>
        !            14: #include <parse.h>
        !            15: #include <al.h>
        !            16:
        !            17: void Phugo();
        !            18: void Pex();
        !            19: void Pall();
        !            20: void constrq();
        !            21: void Pfop();
        !            22: void Pfargs();
        !            23: void Pfopargs();
        !            24: void Pcompf();
        !            25: void Patnum();
        !            26: int compf();
        !            27: void Patl();
        !            28: void Pqevar();
        !            29: void Pqe();
        !            30: void Psimpl();
        !            31: void Psubf();
        !            32: void Pnnf();
        !            33: void smkjf();
        !            34: void simpl();
        !            35: void simpl1();
        !            36: void simpl_gand();
        !            37: void simpl_th2atl();
        !            38: int simpl_gand_udnargls();
        !            39: int simpl_gand_thupd();
        !            40: int simpl_gand_thprsism();
        !            41: void lbc();
        !            42: void replaceq();
        !            43: void deleteq();
        !            44: void simpl_gand_insert_a();
        !            45: void simpl_gand_insert_c();
        !            46: int compaf();
        !            47: int comprel();
        !            48: int synequalf();
        !            49: void simpl_impl();
        !            50: void simpl_equiv();
        !            51: void simpl_a();
        !            52: void simpl_a_o();
        !            53: void simpl_a_no();
        !            54: void qe();
        !            55: void blocksplit();
        !            56: void qeblock();
        !            57: int qeblock_verbose1a();
        !            58: void qeblock_verbose1b();
        !            59: void qeblock_verbose2();
        !            60: void qeblock_verbose0();
        !            61: int getmodulus();
        !            62: int qevar();
        !            63: int gausselim();
        !            64: int translate();
        !            65: int translate_a();
        !            66: void translate_a1();
        !            67: void mklgp();
        !            68: void translate_a2();
        !            69: void mkqgp();
        !            70: void getqcoeffs();
        !            71: void mkdiscr();
        !            72: int al_reorder();
        !            73: int indices();
        !            74: void mkeset();
        !            75: int selectside();
        !            76: int cmp2n();
        !            77: void add2eset();
        !            78: void sp_add2eset();
        !            79: void subgpf();
        !            80: void subref();
        !            81: void subref_a();
        !            82: void substd_a();
        !            83: void substd_a1();
        !            84: void substd_a2();
        !            85: void substd_a21();
        !            86: void substd_a21_equal();
        !            87: void substd_a21_leq();
        !            88: void substd_a21_lessp();
        !            89: void getrecoeffs();
        !            90: void subinf_a();
        !            91: void subinf_a_o();
        !            92: void subinf_a_o1();
        !            93: void subtrans_a_no();
        !            94: void subpme_a();
        !            95: void subpme_a_o();
        !            96: void subpme_a_o1();
        !            97: int comember();
        !            98: void coadd();
        !            99: int coget();
        !           100: int colen();
        !           101: void apply2ats();
        !           102: void atl();
        !           103: void atl1();
        !           104: void atnum();
        !           105: void atnum1();
        !           106: void pnegate();
        !           107: void subf();
        !           108: void subf_a();
        !           109: void nnf();
        !           110: void nnf1();
        !           111: void ap();
        !           112: void freevars();
        !           113: void freevars1();
        !           114: void freevars1_a();
        !           115: void rep();
        !           116: void gpp();
        !           117: void esetp();
        !           118: void nodep();
        !           119:
        !           120: extern Verbose;
        !           121:
        !           122: struct oRE {
        !           123:        P p;
        !           124:        P discr;
        !           125:        int itype;
        !           126: };
        !           127:
        !           128: typedef struct oRE *RE;
        !           129:
        !           130: struct oGP {
        !           131:        F g;
        !           132:        RE p;
        !           133: };
        !           134:
        !           135: typedef struct oGP *GP;
        !           136:
        !           137: struct oCEL {
        !           138:        VL vl;
        !           139:        F mat;
        !           140: };
        !           141:
        !           142: typedef struct oCEL *CEL;
        !           143:
        !           144: struct oCONT {
        !           145:        NODE first;
        !           146:        NODE last;
        !           147: };
        !           148:
        !           149: typedef struct oCONT *CONT;
        !           150:
        !           151: struct oQVL {
        !           152:        oFOP q;
        !           153:        VL vl;
        !           154: };
        !           155:
        !           156: typedef struct oQVL *QVL;
        !           157:
        !           158: #define GUARD(x) ((x)->g)
        !           159: #define POINT(x) ((x)->p)
        !           160: #define NEWGP(x) ((x)=(GP)MALLOC(sizeof(struct oGP)))
        !           161: #define MKGP(x,g,p) (NEWGP(x),GUARD(x)=g,POINT(x)=p)
        !           162:
        !           163: #define NEWRE(x) ((x)=(RE)MALLOC(sizeof(struct oRE)))
        !           164: #define MKRE(x,pp,d,i) \
        !           165: (NEWRE(x),(x)->p=pp,(x)->discr=d,(x)->itype=i)
        !           166: #define DISC(re) ((re)->discr)
        !           167: #define ITYPE(re) ((re)->itype)
        !           168:
        !           169: #define STD 0
        !           170: #define EPS 1
        !           171: #define PEPS 2
        !           172: #define MEPS -2
        !           173: #define PINF 3
        !           174: #define MINF -3
        !           175:
        !           176: #define NEWQVL(x) ((x)=(QVL)MALLOC(sizeof(struct oQVL)))
        !           177: #define MKQVL(x,qq,vvl) (NEWQVL(x),(x)->q=qq,(x)->vl=vvl)
        !           178: #define VARL(x) (x)->vl
        !           179: #define QUANT(x) (x)->q
        !           180:
        !           181: #define NUMBER(p) (p==0 || NUM(p))
        !           182: #define NZNUMBER(p) (p && NUM(p))
        !           183:
        !           184: #define MKVL(a,b,c) \
        !           185: (NEWVL(a),(a)->v=(V)b,NEXT(a)=(VL)(c))
        !           186: #define NEXTVL(r,c) \
        !           187: if(!(r)){NEWVL(r);(c)=(r);}else{NEWVL(NEXT(c));(c)=NEXT(c);}
        !           188:
        !           189: #define NEWCEL(x) ((x)=(CEL)MALLOC(sizeof(struct oCEL)))
        !           190: #define MKCEL(x,vvl,mmat) (NEWCEL(x),(x)->vl=vvl,(x)->mat=mmat)
        !           191: #define VRL(x) ((x)->vl)
        !           192:
        !           193: #define FIRST(x) ((x)->first)
        !           194: #define LAST(x) ((x)->last)
        !           195: #define MKCONT(x) ((x)=(CONT)MALLOC(sizeof(struct oCONT)),FIRST(x)=LAST(x)=NULL)
        !           196:
        !           197: struct ftab al_tab[] = {
        !           198:        {"simpl",Psimpl,-2},
        !           199:        {"ex",Pex,-2},
        !           200:        {"all",Pall,-2},
        !           201:        {"fop",Pfop,1},
        !           202:        {"fargs",Pfargs,1},
        !           203:        {"fopargs",Pfopargs,1},
        !           204:        {"compf",Pcompf,2},
        !           205:        {"atl",Patl,1},
        !           206:        {"qevar",Pqevar,2},
        !           207:        {"qe",Pqe,1},
        !           208:        {"atnum",Patnum,1},
        !           209:        {"subf",Psubf,3},
        !           210:        {"nnf",Pnnf,1},
        !           211:        {"hugo",Phugo,4},
        !           212:        {0,0,0}
        !           213: };
        !           214:
        !           215: void Phugo(arg,rp)
        !           216: NODE arg;
        !           217: F *rp;
        !           218: {
        !           219:        substd_a21_equal(BDY(arg),BDY(NEXT(arg)),BDY(NEXT(NEXT(arg))),BDY(NEXT(NEXT(NEXT(arg)))),rp);
        !           220:        ap(*rp);
        !           221:        substd_a21_leq(BDY(arg),BDY(NEXT(arg)),BDY(NEXT(NEXT(arg))),BDY(NEXT(NEXT(NEXT(arg)))),rp);
        !           222:        ap(*rp);
        !           223:        substd_a21_lessp(BDY(arg),BDY(NEXT(arg)),BDY(NEXT(NEXT(arg))),BDY(NEXT(NEXT(NEXT(arg)))),rp);
        !           224:        ap(*rp);
        !           225: }
        !           226:
        !           227: void Pex(arg,rp)
        !           228: NODE arg;
        !           229: F *rp;
        !           230: {
        !           231:        if (argc(arg) == 1)
        !           232:                constrq(AL_EX,0,(F)BDY(arg),rp);
        !           233:        else
        !           234:                constrq(AL_EX,BDY(arg),(F)BDY(NEXT(arg)),rp);
        !           235: }
        !           236:
        !           237: void Pall(arg,rp)
        !           238: NODE arg;
        !           239: F *rp;
        !           240: {
        !           241:        if (argc(arg) == 1)
        !           242:                constrq(AL_ALL,0,(F)BDY(arg),rp);
        !           243:        else
        !           244:                constrq(AL_ALL,BDY(arg),(F)BDY(NEXT(arg)),rp);
        !           245: }
        !           246:
        !           247: void constrq(q,vars,m,rp)
        !           248: oFOP q;
        !           249: Obj vars;
        !           250: F m,*rp;
        !           251: {
        !           252:        VL sc;
        !           253:        NODE varl=NULL,varlc,arg;
        !           254:        P p;
        !           255:
        !           256:        if (!vars) {
        !           257:                for (freevars(m,&sc); sc; sc=NEXT(sc)) {
        !           258:                        NEXTNODE(varl,varlc);
        !           259:                        MKV(VR(sc),p);
        !           260:                        BDY(varlc) = (pointer)p;
        !           261:                }
        !           262:        } else if (OID(vars) == O_LIST) {
        !           263:                MKNODE(arg,vars,NULL);
        !           264:                Preverse(arg,&vars);
        !           265:                varl = BDY((LIST)vars);
        !           266:        } else
        !           267:                MKNODE(varl,vars,NULL);
        !           268:        for (; varl; varl=NEXT(varl)) {
        !           269:                MKQF(*rp,q,VR((P)BDY(varl)),m);
        !           270:                m = *rp;
        !           271:        }
        !           272: }
        !           273:
        !           274: void Pfop(arg,rp)
        !           275: NODE arg;
        !           276: Q *rp;
        !           277: {
        !           278:        oFOP op;
        !           279:
        !           280:        op = FOP((F)ARG0(arg));
        !           281:        STOQ((int)op,*rp);
        !           282: }
        !           283:
        !           284: void Pfargs(arg,rp)
        !           285: NODE arg;
        !           286: LIST *rp;
        !           287: {
        !           288:        oFOP op;
        !           289:        LIST l;
        !           290:        NODE n1,n2;
        !           291:        F f;
        !           292:        P x;
        !           293:
        !           294:        f = (F)ARG0(arg);
        !           295:        op = FOP(f);
        !           296:        if ( AL_TVAL(op) )
        !           297:                n1 = 0;
        !           298:        else if ( AL_JUNCT(op) )
        !           299:                n1 = FJARG(f);
        !           300:        else if ( AL_QUANT(op) ) {
        !           301:                MKV(FQVR(f),x);
        !           302:                MKNODE(n2,FQMAT(f),0); MKNODE(n1,x,n2);
        !           303:        } else if (AL_ATOMIC(op) )
        !           304:                MKNODE(n1,FPL(f),0);
        !           305:        else if ( AL_UNI(op) )
        !           306:                MKNODE(n1,FARG(f),0);
        !           307:        else if ( AL_EXT(op) ) {
        !           308:                MKNODE(n2,FRHS(f),0); MKNODE(n1,FLHS(f),n2);
        !           309:        }
        !           310:        MKLIST(l,n1);
        !           311:        *rp = l;
        !           312: }
        !           313:
        !           314: void Pfopargs(arg,rp)
        !           315: NODE arg;
        !           316: LIST *rp;
        !           317: {
        !           318:        oFOP op;
        !           319:        LIST l;
        !           320:        NODE n0,n1,n2;
        !           321:        F f;
        !           322:        P x;
        !           323:        Q op1;
        !           324:
        !           325:        f = (F)ARG0(arg);
        !           326:        op = FOP(f);
        !           327:        STOQ((int)op,op1);
        !           328:        if ( AL_TVAL(op) )
        !           329:                n1 = 0;
        !           330:        else if ( AL_JUNCT(op) )
        !           331:                n1 = FJARG(f);
        !           332:        else if ( AL_QUANT(op) ) {
        !           333:                MKV(FQVR(f),x);
        !           334:                MKNODE(n2,FQMAT(f),0); MKNODE(n1,x,n2);
        !           335:        } else if (AL_ATOMIC(op) )
        !           336:                MKNODE(n1,FPL(f),0);
        !           337:        else if ( AL_UNI(op) )
        !           338:                MKNODE(n1,FARG(f),0);
        !           339:        else if ( AL_EXT(op) ) {
        !           340:                MKNODE(n2,FRHS(f),0); MKNODE(n1,FLHS(f),n2);
        !           341:        }
        !           342:        MKNODE(n0,op1,n1);
        !           343:        MKLIST(l,n0);
        !           344:        *rp = l;
        !           345: }
        !           346:
        !           347: void Pcompf(arg,rp)
        !           348: NODE arg;
        !           349: Q *rp;
        !           350: {
        !           351:        STOQ(compf(CO,BDY(arg),BDY(NEXT(arg))),*rp);
        !           352: }
        !           353:
        !           354: void Patnum(arg,rp)
        !           355: NODE arg;
        !           356: Q *rp;
        !           357: {
        !           358:        atnum(BDY(arg),rp);
        !           359: }
        !           360:
        !           361: void Patl(arg,rp)
        !           362: NODE arg;
        !           363: LIST *rp;
        !           364: {
        !           365:        NODE h;
        !           366:
        !           367:        atl(BDY(arg),&h);
        !           368:        MKLIST(*rp,h);
        !           369: }
        !           370:
        !           371: void Pqevar(arg,rp)
        !           372: NODE arg;
        !           373: F *rp;
        !           374: {
        !           375:        qevar(BDY(arg),VR((P)BDY(NEXT(arg))),rp);
        !           376: }
        !           377:
        !           378: void Pqe(arg,rp)
        !           379: NODE arg;
        !           380: F *rp;
        !           381: {
        !           382:        qe(BDY(arg),rp);
        !           383: }
        !           384:
        !           385: void Psubf(arg,rp)
        !           386: NODE arg;
        !           387: F *rp;
        !           388: {
        !           389:        subf(CO,(F)BDY(arg),VR((P)BDY(NEXT(arg))),(P)BDY(NEXT(NEXT(arg))),rp);
        !           390: }
        !           391:
        !           392: void Pnnf(arg,rp)
        !           393: NODE arg;
        !           394: F *rp;
        !           395: {
        !           396:        nnf((F)BDY(arg),rp);
        !           397: }
        !           398:
        !           399: /* Simplification */
        !           400:
        !           401: /* Return values of simpl_gand_udnargls() */
        !           402: #define GINCONSISTENT 0
        !           403: #define OK 1
        !           404: #define NEWAT 2
        !           405:
        !           406: /* Return values of THPRSISM() */
        !           407: #define CONTINUE 10
        !           408: #define DROP 11
        !           409: #define REPLACE 12
        !           410: #define KILL 13
        !           411:
        !           412: void Psimpl(argl,rp)
        !           413: NODE argl;
        !           414: F *rp;
        !           415: {
        !           416:   if (argc(argl) == 1)
        !           417:     simpl(BDY(argl),(NODE)NULL,rp);
        !           418:   else
        !           419:     simpl(BDY(argl),BDY((LIST)BDY(NEXT(argl))),rp);
        !           420: }
        !           421:
        !           422: void smkjf(pf,j,argl)
        !           423: F *pf;
        !           424: oFOP j;
        !           425: NODE argl;
        !           426: {
        !           427:        if (!argl)
        !           428:                MKTV(*pf,AL_NEUTRAL(j));
        !           429:        else if (!NEXT(argl))
        !           430:                *pf = (F)BDY(argl);
        !           431:        else
        !           432:                MKJF(*pf,j,argl);
        !           433: }
        !           434:
        !           435: void simpl(f,th,pnf)
        !           436: F f,*pnf;
        !           437: NODE th;
        !           438: {
        !           439:   simpl1(f,th,0,pnf);
        !           440: }
        !           441:
        !           442: void simpl1(f,th,n,pnf)
        !           443: F f,*pnf;
        !           444: NODE th;
        !           445: int n;
        !           446: {
        !           447:        F h,hh;
        !           448:        oFOP op=FOP(f);
        !           449:
        !           450:        if (AL_ATOMIC(op)) {
        !           451:                simpl_a(f,pnf);
        !           452:                return;
        !           453:        }
        !           454:        if (AL_JUNCT(op)) {
        !           455:                simpl_gand(op,AL_NEUTRAL(op),AL_OMNIPOT(op),FJARG(f),th,n,pnf);
        !           456:                return;
        !           457:        }
        !           458:        if (AL_TVAL(op)) {
        !           459:                *pnf = f;
        !           460:                return;
        !           461:        }
        !           462:        if (AL_QUANT(op)) {
        !           463:                simpl1(FQMAT(f),(NODE)NULL,n+1,&h);
        !           464:                MKQF(*pnf,op,FQVR(f),h);
        !           465:                return;
        !           466:        }
        !           467:        if (op == AL_NOT) {
        !           468:                simpl1(FARG(f),th,n+1,&h);
        !           469:                switch (FOP(h)) {
        !           470:                case AL_TRUE:
        !           471:                        *pnf = F_FALSE;
        !           472:                        break;
        !           473:                case AL_FALSE:
        !           474:                        *pnf = F_TRUE;
        !           475:                        break;
        !           476:                default:
        !           477:                        MKUF(*pnf,AL_NOT,h);
        !           478:                }
        !           479:                return;
        !           480:        }
        !           481:        if (op == AL_IMPL) {
        !           482:                simpl_impl(AL_IMPL,FLHS(f),FRHS(f),th,n,pnf);
        !           483:                return;
        !           484:        }
        !           485:        if (op == AL_REPL) {
        !           486:                simpl_impl(AL_REPL,FRHS(f),FLHS(f),th,n,pnf);
        !           487:                return;
        !           488:        }
        !           489:        if (op == AL_EQUIV) {
        !           490:                simpl_equiv(FLHS(f),FRHS(f),th,n,pnf);
        !           491:                return;
        !           492:        }
        !           493:        else
        !           494:          error("unknown operator in simpl1");
        !           495: }
        !           496:
        !           497: void simpl_gand(gand,gtrue,gfalse,argl,oth,n,pnf)
        !           498: oFOP gand,gtrue,gfalse;
        !           499: NODE argl,oth;
        !           500: int n;
        !           501: F *pnf;
        !           502: {
        !           503:   NODE cnargl=NULL,cc=NULL,cnargl2=NULL,cc2=NULL,th=NULL,thc=NULL,nargl,narglc;
        !           504:   F fgfalse,h;
        !           505:   int st;
        !           506:
        !           507:   for (; oth; oth = NEXT(oth)) {
        !           508:         NEXTNODE(th,thc);
        !           509:         BDY(thc) = BDY(oth);
        !           510:   }
        !           511:   for (; argl; argl = NEXT(argl)) {
        !           512:     if (FOP((F)BDY(argl)) == gfalse) {
        !           513:                *pnf = (F)BDY(argl);
        !           514:       return;
        !           515:         }
        !           516:     if (AL_ATOMIC(FOP((F)BDY(argl)))) {
        !           517:       simpl_a((F)BDY(argl),&h);
        !           518:       if (FOP(h) == gfalse) {
        !           519:                  *pnf = h;
        !           520:                  return;
        !           521:                }
        !           522:       st = simpl_gand_udnargls(gand,gtrue,h,n,&th,&thc,&cnargl,&cc);
        !           523:       if (st == GINCONSISTENT) {
        !           524:                  MKTV(fgfalse,gfalse);
        !           525:                  *pnf = fgfalse;
        !           526:                  return;
        !           527:                }
        !           528:     } else
        !           529:                simpl_gand_insert_c((F)BDY(argl),&cnargl,&cc);
        !           530:   }
        !           531:   for (; cnargl != NULL; cnargl = NEXT(cnargl)) {
        !           532:     simpl1((F)BDY(cnargl),th,n+1,&h);
        !           533:     if (FOP(h) == gfalse) {
        !           534:                *pnf = h;
        !           535:       return;
        !           536:         }
        !           537:     st = simpl_gand_udnargls(gand,gtrue,h,n,&th,&thc,&cnargl2,&cc2);
        !           538:     switch (st) {
        !           539:     case GINCONSISTENT:
        !           540:                MKTV(fgfalse,gfalse);
        !           541:                *pnf = fgfalse;
        !           542:                return;
        !           543:     case NEWAT:
        !           544:       if (cnargl2 != NULL) {
        !           545:                  if (cnargl != NULL)
        !           546:                         NEXT(cc) = cnargl2;
        !           547:                  else
        !           548:                         cnargl = cnargl2;
        !           549:                  cc = cc2;
        !           550:                  cnargl2 = cc2 = NULL;
        !           551:                }
        !           552:       break;
        !           553:     }
        !           554:   }
        !           555:   simpl_th2atl(gand,th,n,&nargl,&narglc);
        !           556:   if (nargl == NULL)
        !           557:         nargl = cnargl2;
        !           558:   else
        !           559:         NEXT(narglc) = cnargl2;
        !           560:   smkjf(pnf,gand,nargl);
        !           561: }
        !           562:
        !           563: void simpl_th2atl(gand,th,n,patl,patlc)
        !           564: oFOP gand;
        !           565: NODE th,*patl,*patlc;
        !           566: int n;
        !           567: {
        !           568:   NODE atl=NULL,atlc=NULL;
        !           569:   LBF h;
        !           570:   F at,negat;
        !           571:
        !           572:   switch (gand) {
        !           573:   case AL_AND:
        !           574:         for (; th; th = NEXT(th)) {
        !           575:                if (LBFLB((LBF)BDY(th)) == n) {
        !           576:                  NEXTNODE(atl,atlc);
        !           577:                  BDY(atlc) = (pointer)LBFF((LBF)BDY(th));
        !           578:                }
        !           579:         }
        !           580:         break;
        !           581:   case AL_OR:
        !           582:         for (; th; th = NEXT(th)) {
        !           583:                if (LBFLB((LBF)BDY(th)) == n) {
        !           584:                  at = LBFF((LBF)BDY(th));
        !           585:                  MKAF(negat,AL_LNEGOP(FOP(at)),FPL(at));
        !           586:                  NEXTNODE(atl,atlc);
        !           587:                  BDY(atlc) = (pointer)negat;
        !           588:                }
        !           589:         }
        !           590:         break;
        !           591:   }
        !           592:   *patl = atl;
        !           593:   *patlc = atlc;
        !           594: }
        !           595:
        !           596: int simpl_gand_udnargls(gand,gtrue,narg,n,pth,pthc,pcnargl,pcc)
        !           597: oFOP gand,gtrue;
        !           598: F narg;
        !           599: int n;
        !           600: NODE *pth,*pthc,*pcnargl,*pcc;
        !           601: {
        !           602:   NODE sargl;
        !           603:   F h;
        !           604:   oFOP op;
        !           605:   int st,found=OK;
        !           606:
        !           607:   op = FOP(narg);
        !           608:   if (op == gtrue)
        !           609:     return(OK);
        !           610:   if (AL_ATOMIC(op))
        !           611:     return(simpl_gand_thupd(gand,narg,n,pth,pthc));
        !           612:   if (op == gand) {
        !           613:     sargl = FJARG(narg);
        !           614:         for (; sargl; sargl = NEXT(sargl)) {
        !           615:                h = (F)BDY(sargl);
        !           616:       if (AL_ATOMIC(FOP(h))) {
        !           617:                  st = simpl_gand_thupd(gand,h,n,pth,pthc);
        !           618:                  switch (st) {
        !           619:                  case NEWAT:
        !           620:                         found = NEWAT;
        !           621:                         break;
        !           622:                  case GINCONSISTENT:
        !           623:                         return(GINCONSISTENT);
        !           624:                  }
        !           625:       } else
        !           626:                  simpl_gand_insert_c(h,pcnargl,pcc);
        !           627:     }
        !           628:     return(found);
        !           629:   }
        !           630:   simpl_gand_insert_c(narg,pcnargl,pcc);
        !           631:   return(OK);
        !           632: }
        !           633:
        !           634: int simpl_gand_thupd(top,at,n,pth,pthc)
        !           635: oFOP top;
        !           636: F at;
        !           637: int n;
        !           638: NODE *pth,*pthc;
        !           639: {
        !           640:   LBF atpr,thpr;
        !           641:   NODE scth;
        !           642:   int st;
        !           643:   F h;
        !           644:
        !           645:   if (top == AL_OR) {
        !           646:     MKAF(h,AL_LNEGOP(FOP(at)),FPL(at));
        !           647:     at = h;
        !           648:   }
        !           649:   MKLBF(atpr,at,n);
        !           650:   for (scth = *pth; scth; scth = NEXT(scth)) {
        !           651:     thpr = (LBF)BDY(scth);
        !           652:     st = simpl_gand_thprsism(thpr,&atpr);
        !           653:     switch (st) {
        !           654:     case GINCONSISTENT:
        !           655:       return(GINCONSISTENT);
        !           656:     case DROP:
        !           657:       return(OK);
        !           658:     case REPLACE:
        !           659: /*      replaceq(*pth,(pointer)thpr,(pointer)atpr,pth,pthc); */
        !           660: /*      return(NEWAT); */
        !           661:     case KILL:
        !           662:       deleteq(*pth,(pointer)thpr,(pointer)pth,pthc);
        !           663:     }
        !           664:   }
        !           665:   NEXTNODE(*pth,*pthc);
        !           666:   BDY(*pthc) = (pointer)atpr;
        !           667:   return(NEWAT);
        !           668: }
        !           669:
        !           670: int simpl_gand_thprsism(thpr,patpr)
        !           671: LBF thpr,*patpr;
        !           672: {
        !           673:   P thlbc,atlbc,thlhs1,atlhs1,difference;
        !           674:   oFOP natfop;
        !           675:   F nat;
        !           676:   LBF natpr;
        !           677:   int st;
        !           678:
        !           679:   lbc(FPL(LBFF(*patpr)),&atlbc);
        !           680:   mulp(CO,FPL(LBFF(thpr)),atlbc,&thlhs1);
        !           681:   lbc(FPL(LBFF(thpr)),&thlbc);
        !           682:   mulp(CO,FPL(LBFF(*patpr)),thlbc,&atlhs1);
        !           683:   subp(CO,thlhs1,atlhs1,&difference);
        !           684:   if (!NUMBER(difference))
        !           685:     return(CONTINUE);
        !           686:   if (difference == NULL) {
        !           687:     st = simpl_gand_smtbelhs(FOP(LBFF(thpr)),FOP(LBFF(*patpr)),&natfop);
        !           688:     if (st == REPLACE) {
        !           689:       MKAF(nat,natfop,FPL(LBFF(*patpr)));
        !           690:       MKLBF(natpr,nat,LBFLB(*patpr));
        !           691:       *patpr = natpr;
        !           692:     };
        !           693:     return(st);
        !           694:   }
        !           695:   return(simpl_gand_smtbdlhs(FOP(LBFF(thpr)),FOP(LBFF(*patpr)),difference));
        !           696: }
        !           697:
        !           698: int simpl_gand_smtbelhs(thop,atop,pnatop)
        !           699:      oFOP thop,atop,*pnatop;
        !           700: {
        !           701:   if (atop == thop)
        !           702:     return(DROP);
        !           703:
        !           704:   switch (thop) {
        !           705:   case AL_EQUAL:
        !           706:     switch (atop) {
        !           707:     case AL_NEQ:
        !           708:     case AL_LESSP:
        !           709:     case AL_GREATERP:
        !           710:       return(GINCONSISTENT);
        !           711:     case AL_LEQ:
        !           712:     case AL_GEQ:
        !           713:       return(DROP);
        !           714:     }
        !           715:   case AL_NEQ:
        !           716:     switch (atop) {
        !           717:     case AL_EQUAL:
        !           718:       return(GINCONSISTENT);
        !           719:     case AL_LEQ:
        !           720:       *pnatop = AL_LESSP;
        !           721:       return(REPLACE);
        !           722:     case AL_GEQ:
        !           723:       *pnatop = AL_GREATERP;
        !           724:       return(REPLACE);
        !           725:     case AL_LESSP:
        !           726:     case AL_GREATERP:
        !           727:       *pnatop = atop;
        !           728:       return(REPLACE);
        !           729:     }
        !           730:   case AL_LEQ:
        !           731:     switch (atop) {
        !           732:     case AL_EQUAL:
        !           733:     case AL_GEQ:
        !           734:       *pnatop = AL_EQUAL;
        !           735:       return(REPLACE);
        !           736:     case AL_NEQ:
        !           737:     case AL_LESSP:
        !           738:       *pnatop = AL_LESSP;
        !           739:       return(REPLACE);
        !           740:     case AL_GREATERP:
        !           741:       return(GINCONSISTENT);
        !           742:     }
        !           743:   case AL_GEQ:
        !           744:     switch (atop) {
        !           745:     case AL_EQUAL:
        !           746:     case AL_LEQ:
        !           747:       *pnatop = AL_EQUAL;
        !           748:       return(REPLACE);
        !           749:     case AL_NEQ:
        !           750:     case AL_GREATERP:
        !           751:       *pnatop = AL_GREATERP;
        !           752:       return(REPLACE);
        !           753:     case AL_LESSP:
        !           754:       return(GINCONSISTENT);
        !           755:     }
        !           756:   case AL_LESSP:
        !           757:     switch (atop) {
        !           758:     case AL_EQUAL:
        !           759:     case AL_GEQ:
        !           760:     case AL_GREATERP:
        !           761:       return(GINCONSISTENT);
        !           762:     case AL_NEQ:
        !           763:     case AL_LEQ:
        !           764:       return(DROP);
        !           765:     }
        !           766:   case AL_GREATERP:
        !           767:     switch (atop) {
        !           768:     case AL_EQUAL:
        !           769:     case AL_LEQ:
        !           770:     case AL_LESSP:
        !           771:       return(GINCONSISTENT);
        !           772:     case AL_NEQ:
        !           773:     case AL_GEQ:
        !           774:       return(DROP);
        !           775:     }
        !           776:   }
        !           777: }
        !           778:
        !           779: int simpl_gand_smtbdlhs(thop,atop,difference)
        !           780:      oFOP thop,atop;
        !           781:      P difference;
        !           782: {
        !           783:   oFOP op1,op2;
        !           784:   int drop1,drop2;
        !           785:
        !           786:   if (cmpq((Q)difference,0) == 1) {  /* good luck with the next compiler */
        !           787:     op1 = atop;
        !           788:     op2 = thop;
        !           789:     drop1 = DROP;
        !           790:     drop2 = KILL;
        !           791:   } else {
        !           792:     op1 = thop;
        !           793:     op2 = atop;
        !           794:     drop1 = KILL;
        !           795:     drop2 = DROP;
        !           796:   }
        !           797:   switch (op1) {
        !           798:   case AL_EQUAL:
        !           799:     switch (op2) {
        !           800:     case AL_EQUAL:
        !           801:     case AL_LEQ:
        !           802:     case AL_LESSP:
        !           803:       return(GINCONSISTENT);
        !           804:     default:
        !           805:       return(drop2);
        !           806:     }
        !           807:   case AL_NEQ:
        !           808:   case AL_LEQ:
        !           809:   case AL_LESSP:
        !           810:     switch (op2) {
        !           811:     case AL_EQUAL:
        !           812:     case AL_LEQ:
        !           813:     case AL_LESSP:
        !           814:       return(drop1);
        !           815:     default:
        !           816:       return(CONTINUE);
        !           817:     }
        !           818:   case AL_GEQ:
        !           819:     switch(op2) {
        !           820:     case AL_EQUAL:
        !           821:     case AL_LEQ:
        !           822:     case AL_LESSP:
        !           823:       return(GINCONSISTENT);
        !           824:     default:
        !           825:       return(drop2);
        !           826:     }
        !           827:   case AL_GREATERP:
        !           828:     switch (op2) {
        !           829:     case AL_EQUAL:
        !           830:     case AL_LEQ:
        !           831:     case AL_LESSP:
        !           832:       return(GINCONSISTENT);
        !           833:     default:
        !           834:       return(drop2);
        !           835:     }
        !           836:   }
        !           837: }
        !           838:
        !           839: void lbc(f,pc)
        !           840: P f,*pc;
        !           841: {
        !           842:   for (*pc = f; !NUM(*pc); *pc = COEF(DC(*pc)))
        !           843:     ;
        !           844: }
        !           845:
        !           846: void replaceq(l,old,new,pnl,pnlc)
        !           847: NODE l,*pnl,*pnlc;
        !           848: pointer old,new;
        !           849: {
        !           850:   *pnl = NULL;
        !           851:   for (; l; l = NEXT(l)) {
        !           852:         NEXTNODE(*pnl,*pnlc);
        !           853:         if(BDY(l) == old)
        !           854:                BDY(*pnlc) = new;
        !           855:         else
        !           856:                BDY(*pnlc) = BDY(l);
        !           857:   }
        !           858: }
        !           859:
        !           860: void deleteq(l,obj,pnl,pnlc)
        !           861: NODE l,*pnl,*pnlc;
        !           862: pointer obj;
        !           863: {
        !           864:   *pnl = NULL;
        !           865:   for (; l; l = NEXT(l))
        !           866:         if(BDY(l) != obj) {
        !           867:                NEXTNODE(*pnl,*pnlc);
        !           868:                BDY(*pnlc) = BDY(l);
        !           869:         }
        !           870: }
        !           871:
        !           872: void simpl_gand_insert_a(f,paargl,pac)
        !           873: F f;
        !           874: NODE *paargl,*pac;
        !           875: {
        !           876:        int w;
        !           877:        NODE n,sc,prev;
        !           878:
        !           879:        if (*paargl == 0) {
        !           880:                NEXTNODE(*paargl,*pac);
        !           881:                BDY(*pac) = (pointer)f;
        !           882:                return;
        !           883:        }
        !           884:        w = compaf(CO,BDY(*pac),f);
        !           885:        if (w == 1) {
        !           886:                NEXTNODE(*paargl,*pac);
        !           887:                BDY(*pac) = (pointer)f;
        !           888:                return;
        !           889:        }
        !           890:        if (w == 0)
        !           891:                return;
        !           892:        w = compaf(CO,f,BDY(*paargl));
        !           893:        if (w == 1) {
        !           894:                MKNODE(n,f,*paargl);
        !           895:                *paargl = n;
        !           896:                return;
        !           897:        }
        !           898:        if (w == 0)
        !           899:                return;
        !           900:        /* f belongs strictly inside the existing list */
        !           901:        for (sc=*paargl; (w=compaf(CO,BDY(sc),f))==1; sc=NEXT(sc))
        !           902:                prev = sc;
        !           903:        if (w == 0)
        !           904:                return;
        !           905:        MKNODE(n,f,sc);
        !           906:        NEXT(prev) = n;
        !           907: }
        !           908:
        !           909: void simpl_gand_insert_c(f,pcargl,pcc)
        !           910: F f;
        !           911: NODE *pcargl,*pcc;
        !           912: {
        !           913:        NODE sc;
        !           914:
        !           915:        for (sc=*pcargl; sc; sc=NEXT(sc))
        !           916:                if (synequalf(f,(F)BDY(sc)))
        !           917:                        return;
        !           918:        NEXTNODE(*pcargl,*pcc);
        !           919:        BDY(*pcc) = (pointer)f;
        !           920: }
        !           921:
        !           922: int compaf(vl,f1,f2)
        !           923: VL vl;
        !           924: F f1,f2;
        !           925: {
        !           926:        int w;
        !           927:
        !           928:        w = compp(vl,FPL(f1),FPL(f2));
        !           929:        if (w)
        !           930:                return w;
        !           931:        return comprel(FOP(f1),FOP(f2));
        !           932: }
        !           933:
        !           934: int comprel(op1,op2)
        !           935: oFOP op1,op2;
        !           936: /* implement order: =, <>, <=, <, >=, > */
        !           937: {
        !           938:        if (op1 == op2)
        !           939:                return 0;
        !           940:        switch (op1) {
        !           941:        case AL_EQUAL:
        !           942:                return 1;
        !           943:        case AL_NEQ:
        !           944:                switch (op2) {
        !           945:                case AL_EQUAL:
        !           946:                        return -1;
        !           947:                default:
        !           948:                        return 1;
        !           949:                }
        !           950:        case AL_LEQ:
        !           951:                switch (op2) {
        !           952:                case AL_EQUAL:
        !           953:                        return -1;
        !           954:                case AL_NEQ:
        !           955:                        return -1;
        !           956:                default:
        !           957:                        return 1;
        !           958:                }
        !           959:        case AL_LESSP:
        !           960:                switch (op2) {
        !           961:                case AL_GEQ:
        !           962:                        return 1;
        !           963:                case AL_GREATERP:
        !           964:                        return 1;
        !           965:                default:
        !           966:                        return -1;
        !           967:                }
        !           968:        case AL_GEQ:
        !           969:                switch (op2) {
        !           970:                case AL_GREATERP:
        !           971:                        return 1;
        !           972:                default:
        !           973:                        return -1;
        !           974:                }
        !           975:        case AL_GREATERP:
        !           976:                return -1;
        !           977:        }
        !           978:        error("unknown relation in comprel");
        !           979: }
        !           980:
        !           981: int synequalf(f1,f2)
        !           982: F f1,f2;
        !           983: {
        !           984:        oFOP op=FOP(f1);
        !           985:
        !           986:        if (op != FOP(f2))
        !           987:                return 0;
        !           988:        if (AL_ATOMIC(op))
        !           989:                return (compp(CO,FPL(f1),FPL(f2)) == 0);
        !           990:        if (AL_JUNCT(op)) {
        !           991:                NODE sc1,sc2;
        !           992:                for (sc1=FJARG(f1),sc2=FJARG(f2); sc1 && sc2; sc1=NEXT(sc1),sc2=NEXT(sc2))
        !           993:                        if (! synequalf(BDY(sc1),BDY(sc2)))
        !           994:                                return 0;
        !           995:                if (sc1 || sc2)
        !           996:                        return 0;
        !           997:                return 1;
        !           998:        }
        !           999: }
        !          1000:
        !          1001: void simpl_impl(op,prem,concl,th,n,pf)
        !          1002: oFOP op;
        !          1003: F prem,concl,*pf;
        !          1004: NODE th;
        !          1005: int n;
        !          1006: {
        !          1007:        F h,hh;
        !          1008:
        !          1009:        simpl1(prem,th,n+1,&h);
        !          1010:        if (FOP(h) == AL_FALSE) {
        !          1011:                *pf = F_TRUE;
        !          1012:                return;
        !          1013:        }
        !          1014:        simpl1(concl,th,n+1,&hh);
        !          1015:        if (FOP(hh) == AL_TRUE) {
        !          1016:                *pf = F_TRUE;
        !          1017:                return;
        !          1018:        }
        !          1019:        if (FOP(h) == AL_TRUE) {
        !          1020:                *pf = hh;
        !          1021:                return;
        !          1022:        }
        !          1023:        if (FOP(hh) == AL_FALSE) {
        !          1024:                pnegate(h,pf);
        !          1025:                return;
        !          1026:        }
        !          1027:        if (op == AL_IMPL) {
        !          1028:                MKBF(*pf,AL_IMPL,h,hh);
        !          1029:                return;
        !          1030:        }
        !          1031:        MKBF(*pf,AL_REPL,hh,h);
        !          1032: }
        !          1033:
        !          1034: void simpl_equiv(lhs,rhs,th,n,pf)
        !          1035: F lhs,rhs,*pf;
        !          1036: NODE th;
        !          1037: int n;
        !          1038: {
        !          1039:        F h,hh;
        !          1040:
        !          1041:        simpl1(lhs,th,n+1,&h);
        !          1042:        simpl1(rhs,th,n+1,&hh);
        !          1043:        if (FOP(h) == AL_TRUE) {
        !          1044:                *pf = hh;
        !          1045:                return;
        !          1046:        }
        !          1047:        if (FOP(hh) == AL_TRUE) {
        !          1048:                *pf = h;
        !          1049:                return;
        !          1050:        }
        !          1051:        if (FOP(h) == AL_FALSE) {
        !          1052:                pnegate(hh,pf);
        !          1053:                return;
        !          1054:        }
        !          1055:        if (FOP(hh) == AL_FALSE) {
        !          1056:                pnegate(h,pf);
        !          1057:                return;
        !          1058:        }
        !          1059:        MKBF(*pf,AL_EQUIV,h,hh);
        !          1060: }
        !          1061:
        !          1062: void simpl_a(f,pnf)
        !          1063: F f,*pnf;
        !          1064: {
        !          1065:        oFOP r=FOP(f);
        !          1066:        P lhs=(P)FPL(f);
        !          1067:
        !          1068:        if (NUMBER(lhs)) {
        !          1069: #if 0
        !          1070:           lhs = (Q)lhs; /* good luck with the next compiler */
        !          1071: #endif
        !          1072:                switch (r) {
        !          1073:                case AL_EQUAL:
        !          1074:                        *pnf = (lhs == 0) ? F_TRUE : F_FALSE;
        !          1075:                        return;
        !          1076:                case AL_NEQ:
        !          1077:                        *pnf = (lhs != 0) ? F_TRUE : F_FALSE;
        !          1078:                        return;
        !          1079:                case AL_LESSP:
        !          1080:                        *pnf = (cmpq((Q)lhs,0) == -1) ? F_TRUE : F_FALSE;
        !          1081:                        return;
        !          1082:                case AL_GREATERP:
        !          1083:                        *pnf = (cmpq((Q)lhs,0) == 1) ? F_TRUE : F_FALSE;
        !          1084:                        return;
        !          1085:                case AL_LEQ:
        !          1086:                        *pnf = (cmpq((Q)lhs,0) != 1) ? F_TRUE : F_FALSE;
        !          1087:                        return;
        !          1088:                case AL_GEQ:
        !          1089:                        *pnf = (cmpq((Q)lhs,0) != -1) ? F_TRUE : F_FALSE;
        !          1090:                        return;
        !          1091:                default:
        !          1092:                        error("unknown operator in simpl_a");
        !          1093:                }
        !          1094:        }
        !          1095:        if (AL_ORDER(r))
        !          1096:                simpl_a_o(&r,&lhs);
        !          1097:        else
        !          1098:                simpl_a_no(&lhs);
        !          1099:        MKAF(*pnf,r,lhs);
        !          1100: }
        !          1101:
        !          1102: void simpl_a_o(ar,alhs)
        !          1103: oFOP *ar;
        !          1104: P *alhs;
        !          1105: {
        !          1106:        DCP dec;
        !          1107:
        !          1108:        sqfrp(CO,*alhs,&dec);
        !          1109:        if (SGN((Q)COEF(dec)) == -1)
        !          1110:                *ar = AL_ANEGREL(*ar);
        !          1111:        *alhs=(P)ONE;
        !          1112:        for (dec = NEXT(dec); dec; dec = NEXT(dec)) {
        !          1113:                mulp(CO,*alhs,COEF(dec),alhs);
        !          1114:                if (EVENN(NM(DEG(dec))))
        !          1115:                        mulp(CO,*alhs,COEF(dec),alhs);
        !          1116:        }
        !          1117: }
        !          1118:
        !          1119: void simpl_a_no(alhs)
        !          1120: P *alhs;
        !          1121: {
        !          1122:        DCP dec;
        !          1123:
        !          1124:        sqfrp(CO,*alhs,&dec);
        !          1125:        *alhs=(P)ONE;
        !          1126:        for (dec = NEXT(dec); dec; dec = NEXT(dec))
        !          1127:                mulp(CO,*alhs,COEF(dec),alhs);
        !          1128: }
        !          1129:
        !          1130: /* QE */
        !          1131:
        !          1132: #define BTMIN 0
        !          1133: #define BTEQUAL 0
        !          1134: #define BTWO 1
        !          1135: #define BTLEQ 2
        !          1136: #define BTGEQ 3
        !          1137: #define BTSO 4
        !          1138: #define BTLESSP 5
        !          1139: #define BTGREATERP 6
        !          1140: #define BTNEQ 7
        !          1141: #define BTMAX 7
        !          1142:
        !          1143: #define IPURE 0
        !          1144: #define IPE 1
        !          1145: #define IME 2
        !          1146: #define II 3
        !          1147:
        !          1148: void qe(f,pnf)
        !          1149: F f,*pnf;
        !          1150: {
        !          1151:        NODE bl,sc;
        !          1152:        F h;
        !          1153:
        !          1154:        simpl(f,(NODE)NULL,&h);
        !          1155:        nnf(h,&h);
        !          1156:        blocksplit(h,&bl,&h);
        !          1157:        for (sc=bl; sc; sc=NEXT(sc)) {
        !          1158:                if (QUANT(((QVL)BDY(sc))) == AL_EX)
        !          1159:                        qeblock(VARL(((QVL)BDY(sc))),h,&h);
        !          1160:                else {
        !          1161:                        pnegate(h,&h);
        !          1162:                        qeblock(VARL(((QVL)BDY(sc))),h,&h);
        !          1163:                        pnegate(h,&h);
        !          1164:                }
        !          1165:        }
        !          1166:        *pnf = h;
        !          1167: }
        !          1168:
        !          1169: void blocksplit(f,pbl,pmat)
        !          1170: F f,*pmat;
        !          1171: NODE *pbl;
        !          1172: {
        !          1173:        oFOP cq;
        !          1174:        NODE bl=NULL,blh;
        !          1175:        VL vl,vlh;
        !          1176:        QVL qvl;
        !          1177:
        !          1178:        while (AL_QUANT(cq=FOP(f))) {
        !          1179:                NEWNODE(blh);
        !          1180:                vl = NULL;
        !          1181:                while (FOP(f) == cq) {
        !          1182:                        NEWVL(vlh);
        !          1183:                        VR(vlh) = FQVR(f);
        !          1184:                        NEXT(vlh) = vl;
        !          1185:                        vl = vlh;
        !          1186:                        f = FQMAT(f);
        !          1187:                }
        !          1188:                MKQVL(qvl,cq,vl);
        !          1189:                BDY(blh) = (pointer)qvl;
        !          1190:                NEXT(blh) = bl;
        !          1191:                bl = blh;
        !          1192:        }
        !          1193:        *pbl = bl;
        !          1194:        *pmat = f;
        !          1195: }
        !          1196:
        !          1197: void qeblock(vl,f,pnf)
        !          1198: VL vl;
        !          1199: F f,*pnf;
        !          1200: {
        !          1201:        CONT co;
        !          1202:        CEL cel;
        !          1203:        VL cvl;
        !          1204:        NODE n,sc;
        !          1205:        NODE nargl=NULL,narglc;
        !          1206:        int w,pr;
        !          1207:        int left=0,modulus;
        !          1208:
        !          1209:        qeblock_verbose0(vl);
        !          1210:        simpl(f,(NODE)NULL,&f);
        !          1211:        MKCONT(co);
        !          1212:        MKCEL(cel,vl,f);
        !          1213:        coadd(co,cel);
        !          1214:        while (coget(co,&cel)) {
        !          1215:                cvl = VRL(cel);
        !          1216:                pr = qeblock_verbose1a(co,cvl,&left,&modulus);
        !          1217:                w = qevar(MAT(cel),&cvl,&n);
        !          1218:                qeblock_verbose1b(w,pr);
        !          1219:                for (sc=n; sc; sc=NEXT(sc))
        !          1220:                        if ((F)BDY(sc) != F_FALSE)
        !          1221:                                if (cvl) {
        !          1222:                                        MKCEL(cel,cvl,(F)BDY(sc));
        !          1223:                                        if (!comember(co,cel))
        !          1224:                                                coadd(co,cel);
        !          1225:                                } else {
        !          1226:                                        NEXTNODE(nargl,narglc);
        !          1227:                                        BDY(narglc) = BDY(sc);
        !          1228:                                }
        !          1229:        }
        !          1230:        qeblock_verbose2();
        !          1231:        smkjf(pnf,AL_OR,nargl);
        !          1232:        simpl(*pnf,(NODE)NULL,pnf);
        !          1233: }
        !          1234:
        !          1235: void qeblock_verbose0(vl)
        !          1236: VL vl;
        !          1237: {
        !          1238:        if (!Verbose)
        !          1239:                return;
        !          1240:        printf("eliminating");
        !          1241:        for (; vl; vl=NEXT(vl))
        !          1242:                printf(" %s",NAME(VR(vl)));
        !          1243: }
        !          1244:
        !          1245: int qeblock_verbose1a(co,cvl,pleft,pmodulus)
        !          1246: CONT co;
        !          1247: VL cvl;
        !          1248: int *pleft,*pmodulus;
        !          1249: {
        !          1250:        int i=0;
        !          1251:
        !          1252:        if (!Verbose)
        !          1253:                return;
        !          1254:        if (*pleft == 0) {
        !          1255:                for (; cvl; cvl=NEXT(cvl))
        !          1256:                        i++;
        !          1257:                printf("\nleft %d\n",i);
        !          1258:                *pleft = colen(co) + 1;
        !          1259:                *pmodulus = getmodulus(*pleft);
        !          1260:                printf("(%d",(*pleft)--);
        !          1261:                fflush(asir_out);
        !          1262:                return 1;
        !          1263:        } else if (*pleft % *pmodulus == 0) {
        !          1264:                printf("(%d",(*pleft)--);
        !          1265:                fflush(asir_out);
        !          1266:                return 1;
        !          1267:        }
        !          1268:        (*pleft)--;
        !          1269:        return 0;
        !          1270: }
        !          1271:
        !          1272: void qeblock_verbose1b(g,print)
        !          1273: int g,print;
        !          1274: {
        !          1275:        if (!(Verbose && print))
        !          1276:                return;
        !          1277:        printf("%s) ",g ? (g==2) ? "qg" : "lg" : "e");
        !          1278:        fflush(asir_out);
        !          1279: }
        !          1280:
        !          1281: void qeblock_verbose2()
        !          1282: {
        !          1283:        if (!Verbose)
        !          1284:                return;
        !          1285:        printf("\n");
        !          1286: }
        !          1287:
        !          1288: int getmodulus(n)
        !          1289: int n;
        !          1290: {
        !          1291:        int pow=1;
        !          1292:
        !          1293:        while (n >= pow*100) {
        !          1294:                pow *= 10;
        !          1295:        }
        !          1296:        return pow;
        !          1297: }
        !          1298:
        !          1299:
        !          1300: int qevar(f,pcvl,pfl)
        !          1301: F f;
        !          1302: VL *pcvl;
        !          1303: NODE *pfl;
        !          1304: {
        !          1305:        int w;
        !          1306:        V x;
        !          1307:        F h;
        !          1308:        NODE trans[8],eset,sc,r=NULL,rc;
        !          1309:
        !          1310:        w = gausselim(f,pcvl,&x,&eset);
        !          1311:        if (!w) {
        !          1312:                x = VR(*pcvl);
        !          1313:                *pcvl = NEXT(*pcvl);
        !          1314:                translate(f,x,trans);
        !          1315:                mkeset(trans,x,&eset);
        !          1316:        }
        !          1317:        for (sc=eset; sc; sc=NEXT(sc)) {
        !          1318:                NEXTNODE(r,rc);
        !          1319:                subgpf(f,x,BDY(sc),&h);
        !          1320:                simpl(h,(NODE)NULL,&BDY(rc));
        !          1321:        }
        !          1322:        *pfl = r;
        !          1323:        return w;
        !          1324: }
        !          1325:
        !          1326: int gausselim(f,pvl,px,peset)
        !          1327: F f;
        !          1328: VL *pvl;
        !          1329: V *px;
        !          1330: NODE *peset;
        !          1331: {
        !          1332:        Q deg,two;
        !          1333:        P rlhs,a,b,c;
        !          1334:        V v;
        !          1335:        VL scvl;
        !          1336:        NODE sc;
        !          1337:        int w;
        !          1338:
        !          1339:        if (FOP(f) != AL_AND)
        !          1340:                return 0;
        !          1341:        STOQ(2,two);
        !          1342:        for (deg=ONE; cmpq(two,deg) >= 0; addq(deg,ONE,&deg))
        !          1343:                for (scvl=*pvl; scvl; scvl=NEXT(scvl)) {
        !          1344:                        v = VR(scvl);
        !          1345:                        for (sc=FJARG(f); sc; sc=NEXT(sc)) {
        !          1346:                                if (FOP((F)BDY(sc)) != AL_EQUAL)
        !          1347:                                        continue;
        !          1348:                                al_reorder(FPL((F)BDY(sc)),v,&rlhs);
        !          1349:                                if (VR(rlhs) != v)
        !          1350:                                        continue;
        !          1351:                                w = gauss_abc(rlhs,v,deg,&a,&b,&c);
        !          1352:                                if (!w)
        !          1353:                                        continue;
        !          1354:                                *px = v;
        !          1355:                                delvip(v,pvl);
        !          1356:                                if (a) {
        !          1357:                                        gauss_mkeset2(rlhs,a,b,c,peset);
        !          1358:                                        return 2;
        !          1359:                                }
        !          1360:                                gauss_mkeset1(rlhs,b,peset);
        !          1361:                                return 1;
        !          1362:                        }
        !          1363:                }
        !          1364:        return 0;
        !          1365: }
        !          1366:
        !          1367: int gauss_abc(rlhs,v,deg,pa,pb,pc)
        !          1368: P rlhs,*pa,*pb,*pc;
        !          1369: V v;
        !          1370: Q deg;
        !          1371: {
        !          1372:        Q two;
        !          1373:        DCP rld;
        !          1374:
        !          1375:        rld = DC(rlhs);
        !          1376:        if (cmpq(DEG(rld),deg) != 0)
        !          1377:                return 0;
        !          1378:        STOQ(2,two);
        !          1379:        if (cmpq(deg,two) == 0) {
        !          1380:                *pa = COEF(rld);
        !          1381:                rld = NEXT(rld);
        !          1382:        } else
        !          1383:                *pa = 0;
        !          1384:        if (rld && cmpq(DEG(rld),ONE) == 0) {
        !          1385:                *pb = COEF(rld);
        !          1386:                rld = NEXT(rld);
        !          1387:        } else
        !          1388:                *pb = 0;
        !          1389:        if (rld)
        !          1390:                *pc = COEF(rld);
        !          1391:        else
        !          1392:                *pc = 0;
        !          1393:        return (NZNUMBER(*pa) || NZNUMBER(*pb) || NZNUMBER(*pc));
        !          1394: }
        !          1395:
        !          1396: gauss_mkeset1(rlhs,b,peset)
        !          1397: P rlhs,b;
        !          1398: NODE *peset;
        !          1399: {
        !          1400:        GP hgp;
        !          1401:
        !          1402:        mklgp(rlhs,b,STD,&hgp);
        !          1403:        MKNODE(*peset,hgp,NULL);
        !          1404: }
        !          1405:
        !          1406: gauss_mkeset2(rlhs,a,b,c,peset)
        !          1407: P rlhs,a,b,c;
        !          1408: NODE *peset;
        !          1409: {
        !          1410:        RE hre;
        !          1411:        F hf;
        !          1412:        GP hgp;
        !          1413:        P discr;
        !          1414:        NODE esetc;
        !          1415:
        !          1416:        *peset = NULL;
        !          1417:        if (!NUM(a)) {
        !          1418:                NEXTNODE(*peset,esetc);
        !          1419:                mklgp(rlhs,b,STD,&hgp);
        !          1420:                BDY(esetc) = (pointer)hgp;
        !          1421:        }
        !          1422:        NEXTNODE(*peset,esetc);
        !          1423:        mkqgp(rlhs,a,b,c,STD,&hgp);
        !          1424:        BDY(esetc) = (pointer)hgp;
        !          1425: }
        !          1426:
        !          1427: int delvip(v,pvl)
        !          1428: V v;
        !          1429: VL *pvl;
        !          1430: {
        !          1431:        VL prev;
        !          1432:
        !          1433:        if (v == VR(*pvl)) {
        !          1434:                *pvl = NEXT(*pvl);
        !          1435:                return 1;
        !          1436:        }
        !          1437:        for (prev=*pvl; NEXT(prev); prev=NEXT(prev))
        !          1438:                if (VR(NEXT(prev)) == v) {
        !          1439:                        NEXT(prev) = NEXT(NEXT(prev));
        !          1440:                        return 1;
        !          1441:                }
        !          1442:        return 0;
        !          1443: }
        !          1444:
        !          1445: int translate(f,x,trans)
        !          1446: F f;
        !          1447: V x;
        !          1448: NODE trans[];
        !          1449: {
        !          1450:        NODE sc,transc[8];
        !          1451:        RE hre;
        !          1452:        GP hgp;
        !          1453:        int bt,w=0;
        !          1454:        P h;
        !          1455:
        !          1456:        for (bt=BTMIN; bt<=BTMAX; bt++)
        !          1457:                trans[bt] = NULL;
        !          1458:        for (atl(f,&sc); sc; sc=NEXT(sc))
        !          1459:                w = (translate_a(BDY(sc),x,trans,transc) || w);
        !          1460:        return w;
        !          1461: }
        !          1462:
        !          1463: int translate_a(at,v,trans,transc)
        !          1464: F at;
        !          1465: V v;
        !          1466: NODE trans[],transc[];
        !          1467: {
        !          1468:        P mp;
        !          1469:        Q two;
        !          1470:        int w;
        !          1471:
        !          1472:        w = al_reorder(FPL(at),v,&mp);
        !          1473:        if (w == 0)
        !          1474:                return 0;
        !          1475:        if (cmpq(ONE,DEG(DC(mp))) == 0) {
        !          1476:                translate_a1(FOP(at),mp,trans,transc);
        !          1477:                return 1;
        !          1478:        };
        !          1479:        STOQ(2,two);
        !          1480:        if (cmpq(two,DEG(DC(mp))) == 0) {
        !          1481:                translate_a2(FOP(at),mp,trans,transc);
        !          1482:                return 1;
        !          1483:        };
        !          1484:        error("degree violation in translate_a");
        !          1485: }
        !          1486:
        !          1487: void translate_a1(op,mp,trans,transc)
        !          1488: oFOP op;
        !          1489: P mp;
        !          1490: NODE trans[],transc[];
        !          1491: {
        !          1492:        P b;
        !          1493:        int itype,btype;
        !          1494:        GP hgp;
        !          1495:
        !          1496:        b = COEF(DC(mp));
        !          1497:        indices(op,NUM(b) ? SGN((Q)b) : 0,&itype,&btype);
        !          1498:        NEXTNODE(trans[btype],transc[btype]);
        !          1499:        mklgp(mp,b,itype,&hgp);
        !          1500:        BDY(transc[btype]) = (pointer)hgp;
        !          1501: }
        !          1502:
        !          1503: void mklgp(mp,b,itype,pgp)
        !          1504: P mp,b;
        !          1505: int itype;
        !          1506: GP *pgp;
        !          1507: {
        !          1508:        RE hre;
        !          1509:        F hf;
        !          1510:
        !          1511:        MKRE(hre,mp,(P)ONE,itype);
        !          1512:        MKAF(hf,AL_NEQ,b);
        !          1513:        MKGP(*pgp,hf,hre);
        !          1514: }
        !          1515:
        !          1516: void translate_a2(op,mp,trans,transc)
        !          1517: oFOP op;
        !          1518: P mp;
        !          1519: NODE trans[],transc[];
        !          1520: {
        !          1521:        P a,b,c,linred;
        !          1522:        int itype,btype;
        !          1523:        GP hgp;
        !          1524:
        !          1525:        getqcoeffs(mp,&a,&b,&c);
        !          1526:        if (!NUM(a) && b) {
        !          1527:                MKP(VR(mp),NEXT(DC(mp)),linred);
        !          1528:                translate_a1(op,linred,trans,transc);
        !          1529:        }
        !          1530:        indices(op,0,&itype,&btype);
        !          1531:        NEXTNODE(trans[btype],transc[btype]);
        !          1532:        mkqgp(mp,a,b,c,itype,&hgp);
        !          1533:        BDY(transc[btype]) = (pointer)hgp;
        !          1534: }
        !          1535:
        !          1536: void mkqgp(mp,a,b,c,itype,pgp)
        !          1537: P mp,a,b,c;
        !          1538: int itype;
        !          1539: GP *pgp;
        !          1540: {
        !          1541:        P discr;
        !          1542:        RE hre;
        !          1543:        F hf;
        !          1544:        NODE n=NULL,nc;
        !          1545:
        !          1546:        mkdiscr(a,b,c,&discr);
        !          1547:        MKRE(hre,mp,discr,itype);
        !          1548:        NEXTNODE(n,nc);
        !          1549:        MKAF(hf,AL_NEQ,a);
        !          1550:        BDY(nc) = (pointer)hf;
        !          1551:        NEXTNODE(n,nc);
        !          1552:        MKAF(hf,AL_GEQ,discr);
        !          1553:        BDY(nc) = (pointer)hf;
        !          1554:        MKJF(hf,AL_AND,n);
        !          1555:        MKGP(*pgp,hf,hre);
        !          1556: }
        !          1557:
        !          1558: void getqcoeffs(mp,pa,pb,pc)
        !          1559: P mp,*pa,*pb,*pc;
        !          1560: {
        !          1561:        DCP hdcp;
        !          1562:
        !          1563:        *pa = COEF(DC(mp));
        !          1564:        hdcp = NEXT(DC(mp));
        !          1565:        if (hdcp && cmpq(DEG(hdcp),ONE) == 0) {
        !          1566:                *pb = COEF(hdcp);
        !          1567:                hdcp = NEXT(hdcp);
        !          1568:        } else
        !          1569:                *pb = 0;
        !          1570:        if (hdcp && DEG(hdcp) == 0) {
        !          1571:                *pc = COEF(hdcp);
        !          1572:        } else
        !          1573:                *pc = 0;
        !          1574: }
        !          1575:
        !          1576: void mkdiscr(a,b,c,pd)
        !          1577: P a,b,c,*pd;
        !          1578: {
        !          1579:        P h1,h2;
        !          1580:        Q four;
        !          1581:
        !          1582:        mulp(CO,a,c,&h1);
        !          1583:        STOQ(4,four);
        !          1584:        mulp(CO,(P)four,h1,&h2);
        !          1585:        mulp(CO,b,b,&h1);
        !          1586:        subp(CO,h1,h2,pd);
        !          1587: }
        !          1588:
        !          1589: int al_reorder(p,v,pnp)
        !          1590: P p,*pnp;
        !          1591: V v;
        !          1592: {
        !          1593:        VL tvl;
        !          1594:
        !          1595:        reordvar(CO,v,&tvl);
        !          1596:        reorderp(tvl,CO,p,pnp);
        !          1597:        if (*pnp && !NUM(*pnp) && strcmp(NAME(VR(*pnp)),NAME(v)) == 0)
        !          1598:                return 1;
        !          1599:        else
        !          1600:                return 0;
        !          1601: }
        !          1602:
        !          1603: int indices(op,s,pit,pbt)
        !          1604: oFOP op;
        !          1605: int s,*pit,*pbt;
        !          1606: {
        !          1607:        switch (op) {
        !          1608:        case AL_EQUAL:
        !          1609:                *pit = STD; *pbt = BTEQUAL; return;
        !          1610:        case AL_NEQ:
        !          1611:                *pit = EPS; *pbt = BTNEQ; return;
        !          1612:        case AL_LEQ:
        !          1613:                *pit = STD;
        !          1614:                switch (s) {
        !          1615:                case 1:
        !          1616:                        *pbt = BTLEQ; return;
        !          1617:                case -1:
        !          1618:                        *pbt = BTGEQ; return;
        !          1619:                case 0:
        !          1620:                        *pbt = BTWO; return;
        !          1621:                }
        !          1622:        case AL_GEQ:
        !          1623:                *pit = STD;
        !          1624:                switch (s) {
        !          1625:                case 1:
        !          1626:                        *pbt = BTGEQ; return;
        !          1627:                case -1:
        !          1628:                        *pbt = BTLEQ; return;
        !          1629:                case 0:
        !          1630:                        *pbt = BTWO; return;
        !          1631:                }
        !          1632:        case AL_LESSP:
        !          1633:                switch (s) {
        !          1634:                case 1:
        !          1635:                        *pit = MEPS; *pbt = BTLESSP; return;
        !          1636:                case -1:
        !          1637:                        *pit = PEPS; *pbt = BTGREATERP; return;
        !          1638:                case 0:
        !          1639:                        *pit = EPS; *pbt = BTSO; return;
        !          1640:                }
        !          1641:        case AL_GREATERP:
        !          1642:                switch (s) {
        !          1643:                case 1:
        !          1644:                        *pit = PEPS; *pbt = BTGREATERP; return;
        !          1645:                case -1:
        !          1646:                        *pit = MEPS; *pbt = BTLESSP; return;
        !          1647:                case 0:
        !          1648:                        *pit = EPS; *pbt = BTSO; return;
        !          1649:                }
        !          1650:        default:
        !          1651:                error("unknown relation or sign in indices");
        !          1652:        }
        !          1653: }
        !          1654:
        !          1655: void mkeset(trans,x,peset)
        !          1656: NODE trans[],*peset;
        !          1657: V x;
        !          1658: {
        !          1659:        NODE esetc;
        !          1660:        P h;
        !          1661:        RE hre;
        !          1662:        GP hgp;
        !          1663:        int cw,cs,deps,dinf,ord;
        !          1664:
        !          1665:        *peset = NULL;
        !          1666:        ord = selectside(trans,&cw,&cs,&deps,&dinf);
        !          1667:        if (ord) {
        !          1668:                add2eset(trans[cw],peset,&esetc);
        !          1669:                add2eset(trans[BTWO],peset,&esetc);
        !          1670:                add2eset(trans[cs],peset,&esetc);
        !          1671:                sp_add2eset(trans[BTSO],deps,peset,&esetc);
        !          1672:                NEXTNODE(*peset,esetc);
        !          1673:                MKRE(hre,0,0,dinf);
        !          1674:                MKGP(hgp,F_TRUE,hre);
        !          1675:                BDY(esetc) = (pointer)hgp;
        !          1676:        } else {
        !          1677:                NEXTNODE(*peset,esetc);
        !          1678:                MKV(x,h);
        !          1679:                MKRE(hre,h,(P)ONE,STD);
        !          1680:                MKGP(hgp,F_TRUE,hre);
        !          1681:                BDY(esetc) = (pointer)hgp;
        !          1682:        }
        !          1683:        add2eset(trans[BTEQUAL],peset,&esetc);
        !          1684:        sp_add2eset(trans[BTNEQ],deps,peset,&esetc);
        !          1685: }
        !          1686:
        !          1687: int selectside(trans,pcw,pcs,pdeps,pdinf)
        !          1688: NODE trans[];
        !          1689: int *pcw,*pcs,*pdeps,*pdinf;
        !          1690: {
        !          1691:        if (cmp2n(trans[BTLEQ],trans[BTLESSP],trans[BTGEQ],trans[BTGREATERP])==1) {
        !          1692:                *pcw = BTGEQ;
        !          1693:                *pcs = BTGREATERP;
        !          1694:                *pdeps = PEPS;
        !          1695:                *pdinf = MINF;
        !          1696:        } else {
        !          1697:                *pcw = BTLEQ;
        !          1698:                *pcs = BTLESSP;
        !          1699:                *pdeps = MEPS;
        !          1700:                *pdinf = PINF;
        !          1701:        }
        !          1702:        if (!(trans[BTLEQ] || trans[BTLESSP] || trans[BTGEQ] ||
        !          1703:                        trans[BTGREATERP] || trans[BTWO] || trans[BTSO]))
        !          1704:                return 0;
        !          1705:        return 1;
        !          1706: }
        !          1707:
        !          1708: int cmp2n(n1a,n1b,n2a,n2b)
        !          1709: NODE n1a,n1b,n2a,n2b;
        !          1710: {
        !          1711:        NODE n1,n2;
        !          1712:        int n1bleft=1,n2bleft=1;
        !          1713:
        !          1714:        n1 = n1a;
        !          1715:        n2 = n2a;
        !          1716:        while (n1 && n2) {
        !          1717:                n1 = NEXT(n1);
        !          1718:                if (n1 == NULL && n1bleft) {
        !          1719:                        n1 = n1b;
        !          1720:                        n1bleft = 0;
        !          1721:                }
        !          1722:                n2 = NEXT(n2);
        !          1723:                if (n2 == NULL && n2bleft) {
        !          1724:                        n2 = n2b;
        !          1725:                        n2bleft = 0;
        !          1726:                }
        !          1727:        }
        !          1728:        if (n1 || n2)
        !          1729:                return n1 ? 1 : -1;
        !          1730:        return 0;
        !          1731: }
        !          1732:
        !          1733: void add2eset(trfield,peset,pesetc)
        !          1734: NODE trfield,*peset,*pesetc;
        !          1735: {
        !          1736:        if (trfield == NULL)
        !          1737:                return;
        !          1738:        if (*peset == NULL)
        !          1739:                *peset = *pesetc = trfield;
        !          1740:        else
        !          1741:                NEXT(*pesetc) = trfield;
        !          1742:        while (NEXT(*pesetc))
        !          1743:                *pesetc = NEXT(*pesetc);
        !          1744: }
        !          1745:
        !          1746: void sp_add2eset(trfield,itype,peset,pesetc)
        !          1747: NODE trfield,*peset,*pesetc;
        !          1748: int itype;
        !          1749: {
        !          1750:        NODE sc;
        !          1751:        GP hgp;
        !          1752:
        !          1753:        for (sc=trfield; sc; sc=NEXT(sc)) {
        !          1754:                hgp = (GP)BDY(sc);
        !          1755:                ITYPE(POINT(hgp)) = itype;
        !          1756:        }
        !          1757:        add2eset(trfield,peset,pesetc);
        !          1758: }
        !          1759:
        !          1760: void subgpf(f,v,gp,pnf)
        !          1761: F f,*pnf;
        !          1762: V v;
        !          1763: GP gp;
        !          1764: {
        !          1765:        NODE argl=NULL,arglc;
        !          1766:
        !          1767:        NEXTNODE(argl,arglc);
        !          1768:        BDY(arglc) = (pointer)GUARD(gp);
        !          1769:        NEXTNODE(argl,arglc);
        !          1770:        subref(f,v,POINT(gp),&BDY(arglc));
        !          1771:        MKJF(*pnf,AL_AND,argl);
        !          1772: }
        !          1773:
        !          1774: void subref(f,v,r,pnf)
        !          1775: F f,*pnf;
        !          1776: V v;
        !          1777: RE r;
        !          1778: {
        !          1779:        pointer argv[2];
        !          1780:
        !          1781:        argv[0] = (pointer)v;
        !          1782:        argv[1] = (pointer)r;
        !          1783:        apply2ats(f,subref_a,argv,pnf);
        !          1784: }
        !          1785:
        !          1786: void subref_a(at,argv,pnat)
        !          1787: F at,*pnat;
        !          1788: pointer argv[];
        !          1789: {
        !          1790:        switch (ITYPE((RE)argv[1])) {
        !          1791:        case STD:
        !          1792:                substd_a(at,argv[0],argv[1],pnat);
        !          1793:                return;
        !          1794:        case EPS:
        !          1795:                error("unspecified RE in subref_a()");
        !          1796:        case PEPS:
        !          1797:        case MEPS:
        !          1798:                subpme_a(at,argv[0],argv[1],pnat);
        !          1799:                return;
        !          1800:        case PINF:
        !          1801:        case MINF:
        !          1802:                subinf_a(at,argv[0],argv[1],pnat);
        !          1803:                return;
        !          1804:        default:
        !          1805:                error("unknown itype in subref_a()");
        !          1806:        }
        !          1807: }
        !          1808:
        !          1809: void substd_a(at,v,re,pnf)
        !          1810: F at,*pnf;
        !          1811: V v;
        !          1812: RE re;
        !          1813: {
        !          1814:        VL no;
        !          1815:        P rlhs,prem,bdn,nlhs;
        !          1816:        Q dd,dndeg;
        !          1817:
        !          1818:        reordvar(CO,v,&no);
        !          1819:        reorderp(no,CO,FPL(at),&rlhs);
        !          1820:        if (!rlhs || NUM(rlhs) || VR(rlhs) != v) {
        !          1821:                *pnf = at;
        !          1822:                return;
        !          1823:        }
        !          1824:        premp(no,rlhs,PL(re),&prem);
        !          1825:        if (prem && !NUM(prem) && VR(prem) == v) {
        !          1826:                /* quadratic case */
        !          1827:                substd_a2(FOP(at),prem,DEG(DC(rlhs)),re,pnf);
        !          1828:                return;
        !          1829:        }
        !          1830:        subq(DEG(DC(rlhs)),DEG(DC(PL(re))),&dd);
        !          1831:        addq(dd,ONE,&dndeg);
        !          1832:        if (AL_ORDER(FOP(at)) && (!EVENN(NM(dndeg))))
        !          1833:                mulp(CO,prem,COEF(DC(PL(re))),&nlhs);
        !          1834:        else
        !          1835:                nlhs = prem;
        !          1836:        MKAF(*pnf,FOP(at),nlhs);
        !          1837: }
        !          1838:
        !          1839: void substd_a2(op,prem,fdeg,re,pf)
        !          1840: oFOP op;
        !          1841: F prem;
        !          1842: Q fdeg;
        !          1843: RE re;
        !          1844: F *pf;
        !          1845: {
        !          1846:        P a,b,c,ld;
        !          1847:        F hf;
        !          1848:        NODE d=NULL,dc;
        !          1849:
        !          1850:        getrecoeffs(prem,fdeg,re,&a,&b,&c,&ld);
        !          1851:        NEXTNODE(d,dc);
        !          1852:        substd_a21(op,a,b,c,ld,&hf);
        !          1853:        BDY(dc) = (pointer)hf;
        !          1854:        NEXTNODE(d,dc);
        !          1855:        chsgnp(b,&b);
        !          1856:        substd_a21(op,a,b,c,ld,&hf);
        !          1857:        BDY(dc) = (pointer)hf;
        !          1858:        MKJF(*pf,AL_OR,d);
        !          1859: }
        !          1860:
        !          1861: void substd_a21(op,a,b,c,d,pf)
        !          1862: oFOP op;
        !          1863: P a,b,c,d;
        !          1864: F *pf;
        !          1865: {
        !          1866:        switch (op) {
        !          1867:        case AL_EQUAL:
        !          1868:                substd_a21_equal(a,b,c,d,pf);
        !          1869:                return;
        !          1870:        case AL_NEQ:
        !          1871:                substd_a21_equal(a,b,c,d,pf);
        !          1872:                pnegate(*pf,pf);
        !          1873:                return;
        !          1874:        case AL_LEQ:
        !          1875:                substd_a21_leq(a,b,c,d,pf);
        !          1876:                return;
        !          1877:        case AL_LESSP:
        !          1878:                substd_a21_lessp(a,b,c,d,pf);
        !          1879:                return;
        !          1880:        case AL_GEQ:
        !          1881:                substd_a21_lessp(a,b,c,d,pf);
        !          1882:                pnegate(*pf,pf);
        !          1883:                return;
        !          1884:        case AL_GREATERP:
        !          1885:                substd_a21_leq(a,b,c,d,pf);
        !          1886:                pnegate(*pf,pf);
        !          1887:                return;
        !          1888:        default:
        !          1889:                error("unknown operator in substd_a21");
        !          1890:        }
        !          1891: }
        !          1892:
        !          1893: void substd_a21_equal(a,b,c,d,pf)
        !          1894: P a,b,c,d;
        !          1895: F *pf;
        !          1896: {
        !          1897:        F hf;
        !          1898:        NODE cj=NULL,cjc;
        !          1899:        P hp1,hp2;
        !          1900:
        !          1901:        NEXTNODE(cj,cjc);
        !          1902:        mulp(CO,a,a,&hp1);
        !          1903:        mulp(CO,b,b,&hp2);
        !          1904:        mulp(CO,hp2,c,&hp2);
        !          1905:        subp(CO,hp1,hp2,&hp1);
        !          1906:        MKAF(hf,AL_EQUAL,hp1);
        !          1907:        BDY(cjc) = (pointer)hf;
        !          1908:        NEXTNODE(cj,cjc);
        !          1909:        mulp(CO,a,b,&hp1);
        !          1910:        MKAF(hf,AL_LEQ,hp1);
        !          1911:        BDY(cjc) = (pointer)hf;
        !          1912:        MKJF(*pf,AL_AND,cj);
        !          1913: }
        !          1914:
        !          1915: void substd_a21_leq(a,b,c,d,pf)
        !          1916: P a,b,c,d;
        !          1917: F *pf;
        !          1918: {
        !          1919:        F hf;
        !          1920:        NODE cj=NULL,cjc,dj=NULL,djc;
        !          1921:        P hp1,hp2;
        !          1922:
        !          1923:        NEXTNODE(dj,djc);
        !          1924:        NEXTNODE(cj,cjc);
        !          1925:        mulp(CO,a,d,&hp1);
        !          1926:        MKAF(hf,AL_LEQ,hp1);
        !          1927:        BDY(cjc) = (pointer)hf;
        !          1928:        NEXTNODE(cj,cjc);
        !          1929:        mulp(CO,a,a,&hp1);
        !          1930:        mulp(CO,b,b,&hp2);
        !          1931:        mulp(CO,hp2,c,&hp2);
        !          1932:        subp(CO,hp1,hp2,&hp1);
        !          1933:        MKAF(hf,AL_GEQ,hp1);
        !          1934:        BDY(cjc) = (pointer)hf;
        !          1935:        MKJF(hf,AL_AND,cj);
        !          1936:        BDY(djc) = (pointer)hf;
        !          1937:        NEXTNODE(dj,djc);
        !          1938:        cj = NULL;
        !          1939:        NEXTNODE(cj,cjc);
        !          1940:        MKAF(hf,AL_LEQ,hp1);
        !          1941:        BDY(cjc) = (pointer)hf;
        !          1942:        NEXTNODE(cj,cjc);
        !          1943:        mulp(CO,b,d,&hp1);
        !          1944:        MKAF(hf,AL_LEQ,hp1);
        !          1945:        BDY(cjc) = (pointer)hf;
        !          1946:        MKJF(hf,AL_AND,cj);
        !          1947:        BDY(djc) = (pointer)hf;
        !          1948:        MKJF(*pf,AL_OR,dj);
        !          1949: }
        !          1950:
        !          1951: void substd_a21_lessp(a,b,c,d,pf)
        !          1952: P a,b,c,d;
        !          1953: F *pf;
        !          1954: {
        !          1955:        F hf,hf0;
        !          1956:        NODE cj=NULL,cjc,d1=NULL,d1c,d2=NULL,d2c;
        !          1957:        P hp1,hp2;
        !          1958:
        !          1959:        NEXTNODE(d1,d1c);
        !          1960:        NEXTNODE(cj,cjc);
        !          1961:        mulp(CO,a,d,&hp1);
        !          1962:        MKAF(hf0,AL_LESSP,hp1);
        !          1963:        BDY(cjc) = (pointer)hf0;
        !          1964:        NEXTNODE(cj,cjc);
        !          1965:        mulp(CO,a,a,&hp1);
        !          1966:        mulp(CO,b,b,&hp2);
        !          1967:        mulp(CO,hp2,c,&hp2);
        !          1968:        subp(CO,hp1,hp2,&hp1);
        !          1969:        MKAF(hf,AL_GREATERP,hp1);
        !          1970:        BDY(cjc) = (pointer)hf;
        !          1971:        MKJF(hf,AL_AND,cj);
        !          1972:        BDY(d1c) = (pointer)hf;
        !          1973:        NEXTNODE(d1,d1c);
        !          1974:        cj = NULL;
        !          1975:        NEXTNODE(cj,cjc);
        !          1976:        NEXTNODE(d2,d2c);
        !          1977:        MKAF(hf,AL_LESSP,hp1);
        !          1978:        BDY(d2c) = (pointer)hf;
        !          1979:        NEXTNODE(d2,d2c);
        !          1980:        BDY(d2c) = (pointer)hf0;
        !          1981:        MKJF(hf,AL_OR,d2);
        !          1982:        BDY(cjc) = (pointer)hf;
        !          1983:        NEXTNODE(cj,cjc);
        !          1984:        mulp(CO,b,d,&hp1);
        !          1985:        MKAF(hf,AL_LEQ,hp1);
        !          1986:        BDY(cjc) = (pointer)hf;
        !          1987:        MKJF(hf,AL_AND,cj);
        !          1988:        BDY(d1c) = (pointer)hf;
        !          1989:        MKJF(*pf,AL_OR,d1);
        !          1990: }
        !          1991:
        !          1992: void getrecoeffs(prem,fdeg,re,pa,pb,pc,pld)
        !          1993: P prem,*pa,*pb,*pc,*pld;
        !          1994: Q fdeg;
        !          1995: RE re;
        !          1996: {
        !          1997:        P a,b,c,alpha,beta,h1,h2,h3;
        !          1998:        Q two;
        !          1999:
        !          2000:        alpha = COEF(DC(prem));
        !          2001:        beta = (NEXT(DC(prem))) ? COEF(NEXT(DC(prem))) : 0;
        !          2002:        getqcoeffs(PL(re),&a,&b,&c);
        !          2003:        STOQ(2,two);
        !          2004:        mulp(CO,(P)two,a,&h1);
        !          2005:        mulp(CO,h1,beta,&h2);
        !          2006:        mulp(CO,b,alpha,&h1);
        !          2007:        subp(CO,h2,h1,pa);
        !          2008:        *pb = alpha;
        !          2009:        *pc = DISC(re);
        !          2010:        *pld = (EVENN(NM(fdeg))) ? (P)ONE : a;
        !          2011: }
        !          2012:
        !          2013: void subinf_a(f,v,re,pnf)
        !          2014: F f,*pnf;
        !          2015: V v;
        !          2016: RE re;
        !          2017: {
        !          2018:        if (AL_ORDER(FOP(f)))
        !          2019:                subinf_a_o(f,v,re,pnf);
        !          2020:        else
        !          2021:                subtrans_a_no(f,v,pnf);
        !          2022: }
        !          2023:
        !          2024: void subinf_a_o(f,v,ire,pnf)
        !          2025: F f,*pnf;
        !          2026: V v;
        !          2027: RE ire;
        !          2028: {
        !          2029:        P rlhs;
        !          2030:
        !          2031:        if (!al_reorder(FPL(f),v,&rlhs))
        !          2032:                *pnf = f;
        !          2033:        else
        !          2034:                subinf_a_o1(FOP(f),DC(rlhs),ire,pnf);
        !          2035: }
        !          2036:
        !          2037: void subinf_a_o1(op,lhsdcp,ire,pnf)
        !          2038: oFOP op;
        !          2039: DCP lhsdcp;
        !          2040: RE ire;
        !          2041: F *pnf;
        !          2042: {
        !          2043:        P an;
        !          2044:        F h;
        !          2045:        NODE c=NULL,cc,d=NULL,dc;
        !          2046:
        !          2047:        if (lhsdcp == 0) {
        !          2048:                MKAF(*pnf,op,0);
        !          2049:                return;
        !          2050:        }
        !          2051:        if (DEG(lhsdcp) == 0) {
        !          2052:                MKAF(*pnf,op,COEF(lhsdcp));
        !          2053:                return;
        !          2054:        }
        !          2055:        if (ITYPE(ire) == MINF && !EVENN(NM(DEG(lhsdcp))))
        !          2056:                chsgnp(COEF(lhsdcp),&an);
        !          2057:        else
        !          2058:                an = COEF(lhsdcp);
        !          2059:        NEXTNODE(d,dc);
        !          2060:        MKAF(h,AL_MKSTRICT(op),an);
        !          2061:        BDY(dc) = (pointer)h;
        !          2062:        NEXTNODE(d,dc);
        !          2063:        NEXTNODE(c,cc);
        !          2064:        MKAF(h,AL_EQUAL,an);
        !          2065:        BDY(cc) = (pointer)h;
        !          2066:        NEXTNODE(c,cc);
        !          2067:        subinf_a_o1(op,NEXT(lhsdcp),ire,&h);
        !          2068:        BDY(cc) = (pointer)h;
        !          2069:        MKJF(h,AL_AND,c);
        !          2070:        BDY(dc) = (pointer)h;
        !          2071:        MKJF(*pnf,AL_OR,d);
        !          2072: }
        !          2073:
        !          2074: void subtrans_a_no(f,v,pnf)
        !          2075: F f,*pnf;
        !          2076: V v;
        !          2077: {
        !          2078:        P rlhs;
        !          2079:        DCP sc;
        !          2080:        F h;
        !          2081:        NODE nargl=NULL,narglc;
        !          2082:        oFOP op=FOP(f);
        !          2083:
        !          2084:        if (!al_reorder(FPL(f),v,&rlhs)) {
        !          2085:                *pnf = f;
        !          2086:                return;
        !          2087:        }
        !          2088:        for (sc=DC(rlhs); sc; sc=NEXT(sc)) {
        !          2089:                NEXTNODE(nargl,narglc);
        !          2090:                MKAF(h,op,COEF(sc));
        !          2091:                BDY(narglc) = (pointer)h;
        !          2092:        }
        !          2093:        smkjf(pnf,AL_TRSUBEXP(op),nargl);
        !          2094: }
        !          2095:
        !          2096: void subpme_a(af,v,re,pnf)
        !          2097: F af,*pnf;
        !          2098: V v;
        !          2099: RE re;
        !          2100: {
        !          2101:        if (AL_ORDER(FOP(af)))
        !          2102:                subpme_a_o(af,v,re,pnf);
        !          2103:        else
        !          2104:                subtrans_a_no(af,v,pnf);
        !          2105: }
        !          2106:
        !          2107: void subpme_a_o(af,v,r,pnf)
        !          2108: F af,*pnf;
        !          2109: V v;
        !          2110: RE r;
        !          2111: {
        !          2112:        F h;
        !          2113:        RE stdre;
        !          2114:
        !          2115:        subpme_a_o1(FOP(af),FPL(af),v,ITYPE(r)==MEPS,&h);
        !          2116:        MKRE(stdre,PL(r),DISC(r),STD);
        !          2117:        subref(h,v,stdre,pnf);
        !          2118: }
        !          2119:
        !          2120: void subpme_a_o1(op,lhs,v,minus,pnf)
        !          2121: oFOP op;
        !          2122: P lhs;
        !          2123: V v;
        !          2124: int minus;
        !          2125: F *pnf;
        !          2126: {
        !          2127:        Q deg;
        !          2128:        F h;
        !          2129:        NODE c=NULL,cc,d=NULL,dc;
        !          2130:        P df;
        !          2131:
        !          2132:        degp(v,lhs,&deg);
        !          2133:        if (deg == 0) {
        !          2134:                MKAF(*pnf,op,lhs);
        !          2135:                return;
        !          2136:        };
        !          2137:        NEXTNODE(d,dc);
        !          2138:        MKAF(h,AL_MKSTRICT(op),lhs);
        !          2139:        BDY(dc) = (pointer)h;
        !          2140:        NEXTNODE(d,dc);
        !          2141:        NEXTNODE(c,cc);
        !          2142:        MKAF(h,AL_EQUAL,lhs);
        !          2143:        BDY(cc) = (pointer)h;
        !          2144:        NEXTNODE(c,cc);
        !          2145:        diffp(CO,lhs,v,&df);
        !          2146:        if (minus)
        !          2147:                chsgnp(df,&df);
        !          2148:        subpme_a_o1(op,df,v,minus,&h);
        !          2149:        BDY(cc) = (pointer)h;
        !          2150:        MKJF(h,AL_AND,c);
        !          2151:        BDY(dc) = (pointer)h;
        !          2152:        MKJF(*pnf,AL_OR,d);
        !          2153: }
        !          2154:
        !          2155: int comember(co,x)
        !          2156: CONT co;
        !          2157: CEL x;
        !          2158: {
        !          2159:        NODE sc;
        !          2160:
        !          2161:        for (sc=FIRST(co); sc; sc=NEXT(sc))
        !          2162:                if (synequalf(MAT(x),MAT((CEL)BDY(sc))))
        !          2163:                        return 1;
        !          2164:        return 0;
        !          2165: }
        !          2166:
        !          2167: void coadd(co,x)
        !          2168: CONT co;
        !          2169: CEL x;
        !          2170: {
        !          2171:        NEXTNODE(FIRST(co),LAST(co));
        !          2172:        BDY(LAST(co)) = (pointer)x;
        !          2173: }
        !          2174:
        !          2175: int coget(co,px)
        !          2176: CONT co;
        !          2177: CEL *px;
        !          2178: {
        !          2179:        if (FIRST(co) == 0)
        !          2180:                return 0;
        !          2181:        *px = (CEL)BDY(FIRST(co));
        !          2182:        FIRST(co) = NEXT(FIRST(co));
        !          2183:        return 1;
        !          2184: }
        !          2185:
        !          2186: int colen(co)
        !          2187: CONT co;
        !          2188: {
        !          2189:        NODE sc;
        !          2190:        int n=0;
        !          2191:
        !          2192:        for (sc=FIRST(co); sc; sc=NEXT(sc))
        !          2193:                n++;
        !          2194:        return n;
        !          2195: }
        !          2196:
        !          2197: /* Misc */
        !          2198:
        !          2199: void apply2ats(f,client,argv,pnf)
        !          2200: F f,*pnf;
        !          2201: void (*client)();
        !          2202: pointer argv[];
        !          2203: {
        !          2204:        if (AL_ATOMIC(FOP(f)))
        !          2205:                (*client)(f,argv,pnf);
        !          2206:        else if (AL_JUNCT(FOP(f))) {
        !          2207:                NODE sc,n=NULL,c;
        !          2208:                for (sc=FJARG(f); sc; sc=NEXT(sc)) {
        !          2209:                        NEXTNODE(n,c);
        !          2210:                        apply2ats(BDY(sc),client,argv,&BDY(c));
        !          2211:                }
        !          2212:                MKJF(*pnf,FOP(f),n);
        !          2213:        }
        !          2214:        else if (AL_TVAL(FOP(f)))
        !          2215:                *pnf = f;
        !          2216:        else if (AL_QUANT(FOP(f))) {
        !          2217:                F h;
        !          2218:                apply2ats(FQMAT(f),client,argv,&h);
        !          2219:                MKQF(*pnf,FOP(f),FQVR(f),h);
        !          2220:        } else
        !          2221:                error("unknown operator in apply2ats");
        !          2222: }
        !          2223:
        !          2224: void atl(f,pn)
        !          2225: F f;
        !          2226: NODE *pn;
        !          2227: {
        !          2228:        NODE c;
        !          2229:
        !          2230:        *pn = NULL;
        !          2231:        atl1(f,pn,&c);
        !          2232: }
        !          2233:
        !          2234: void atl1(f,pn,pc)
        !          2235: F f;
        !          2236: NODE *pn,*pc;
        !          2237: {
        !          2238:        NODE sc;
        !          2239:
        !          2240:        if (AL_ATOMIC(FOP(f))) {
        !          2241:                simpl_gand_insert_a(f,pn,pc);
        !          2242:                return;
        !          2243:        }
        !          2244:        if (AL_JUNCT(FOP(f)))
        !          2245:                for (sc=FJARG(f); sc; sc=NEXT(sc))
        !          2246:                        atl1(BDY(sc),pn,pc);
        !          2247: }
        !          2248:
        !          2249: void atnum(f,pn)
        !          2250: F f;
        !          2251: Q *pn;
        !          2252: {
        !          2253:        *pn = 0;
        !          2254:        atnum1(f,pn);
        !          2255: }
        !          2256:
        !          2257: void atnum1(f,pn)
        !          2258: F f;
        !          2259: Q *pn;
        !          2260: {
        !          2261:        NODE sc;
        !          2262:
        !          2263:        if (AL_ATOMIC(FOP(f)))
        !          2264:                addq(*pn,ONE,pn);
        !          2265:        else if (AL_JUNCT(FOP(f)))
        !          2266:                for (sc=FJARG(f); sc; sc=NEXT(sc))
        !          2267:                        atnum1(BDY(sc),pn);
        !          2268: }
        !          2269:
        !          2270: void pnegate(f,pnf)
        !          2271: F f,*pnf;
        !          2272: {
        !          2273:        F h;
        !          2274:        NODE sc,n=NULL,c;
        !          2275:        oFOP op=FOP(f);
        !          2276:
        !          2277:        if (AL_QUANT(op)) {
        !          2278:                pnegate(FQMAT(f),&h);
        !          2279:                MKQF(*pnf,AL_LNEGOP(op),FQVR(f),h);
        !          2280:                return;
        !          2281:        }
        !          2282:        if (AL_JUNCT(op)) {
        !          2283:                for (sc=FJARG(f); sc; sc=NEXT(sc)) {
        !          2284:                        NEXTNODE(n,c);
        !          2285:                        pnegate((F)BDY(sc),(F*)&BDY(c));
        !          2286:                }
        !          2287:                MKJF(*pnf,AL_LNEGOP(op),n);
        !          2288:                return;
        !          2289:        }
        !          2290:        if (AL_ATOMIC(op)) {
        !          2291:                MKAF(*pnf,AL_LNEGOP(op),FPL(f));
        !          2292:                return;
        !          2293:        }
        !          2294:        if (op == AL_TRUE) {
        !          2295:                *pnf = F_FALSE;
        !          2296:                return;
        !          2297:        }
        !          2298:        if (op == AL_FALSE) {
        !          2299:                *pnf = F_TRUE;
        !          2300:                return;
        !          2301:        }
        !          2302:        error("unknown operator in pnegate()");
        !          2303: }
        !          2304:
        !          2305: void subf(o,f,v,p,pf)
        !          2306: VL o;
        !          2307: F f,*pf;
        !          2308: V v;
        !          2309: P p;
        !          2310: {
        !          2311:        pointer argv[3];
        !          2312:
        !          2313:        argv[0] = (pointer)o;
        !          2314:        argv[1] = (pointer)v;
        !          2315:        argv[2] = (pointer)p;
        !          2316:        apply2ats(f,subf_a,argv,pf);
        !          2317: }
        !          2318:
        !          2319: void subf_a(at,argv,pat)
        !          2320: F at,*pat;
        !          2321: pointer argv[];
        !          2322: {
        !          2323:        P nlhs;
        !          2324:
        !          2325:        substp((VL)argv[0],FPL(at),(V)argv[1],(P)argv[2],&nlhs);
        !          2326:        MKAF(*pat,FOP(at),nlhs);
        !          2327: }
        !          2328:
        !          2329: void nnf(f,pf)
        !          2330: F f,*pf;
        !          2331: {
        !          2332:        nnf1(f,0,0,pf);
        !          2333: }
        !          2334:
        !          2335: void nnf1(f,neg,disj,pf)
        !          2336: F f,*pf;
        !          2337: int neg,disj;
        !          2338: {
        !          2339:        F h;
        !          2340:        NODE sc,nargl=NULL,narglc;
        !          2341:        oFOP op=FOP(f);
        !          2342:
        !          2343:        if (AL_ATOMIC(op) || AL_TVAL(op)) {
        !          2344:                if (neg)
        !          2345:                        pnegate(f,pf);
        !          2346:                else
        !          2347:                        *pf = f;
        !          2348:                return;
        !          2349:        }
        !          2350:        if (AL_JUNCT(op)) {
        !          2351:                if (neg)
        !          2352:                        op = AL_LNEGOP(op);
        !          2353:                for (sc=FJARG(f); sc; sc=NEXT(sc)) {
        !          2354:                        NEXTNODE(nargl,narglc);
        !          2355:                        nnf1((F)BDY(sc),neg,op==AL_OR,(F*)&BDY(narglc));
        !          2356:                }
        !          2357:                MKJF(*pf,op,nargl);
        !          2358:                return;
        !          2359:        }
        !          2360:        if (op == AL_IMPL) {
        !          2361:                op = neg ? AL_AND : AL_OR;
        !          2362:                NEXTNODE(nargl,narglc);
        !          2363:                nnf1(FLHS(f),!neg,op==AL_OR,(F*)&BDY(narglc));
        !          2364:                NEXTNODE(nargl,narglc);
        !          2365:                nnf1(FRHS(f),neg,op==AL_OR,(F*)&BDY(narglc));
        !          2366:                MKJF(*pf,op,nargl);
        !          2367:                return;
        !          2368:        }
        !          2369:        if (op == AL_REPL) {
        !          2370:                op = neg ? AL_AND : AL_OR;
        !          2371:                NEXTNODE(nargl,narglc);
        !          2372:                nnf1(FLHS(f),neg,op==AL_OR,(F*)&BDY(narglc));
        !          2373:                NEXTNODE(nargl,narglc);
        !          2374:                nnf1(FRHS(f),!neg,op==AL_OR,(F*)&BDY(narglc));
        !          2375:                MKJF(*pf,op,nargl);
        !          2376:                return;
        !          2377:        }
        !          2378:        if (op == AL_EQUIV) {
        !          2379:                /* should consider disj and its arguments ops */
        !          2380:                NEXTNODE(nargl,narglc);
        !          2381:                MKBF(h,AL_IMPL,FLHS(f),FRHS(f));
        !          2382:                BDY(narglc) = (pointer)h;
        !          2383:                NEXTNODE(nargl,narglc);
        !          2384:                MKBF(h,AL_REPL,FLHS(f),FRHS(f));
        !          2385:                BDY(narglc) = (pointer)h;
        !          2386:                MKJF(h,AL_AND,nargl);
        !          2387:                nnf1(h,neg,disj,pf);
        !          2388:                return;
        !          2389:        }
        !          2390:        if (AL_QUANT(op)) {
        !          2391:                nnf1(FQMAT(f),neg,0,&h);
        !          2392:                MKQF(*pf,neg ? AL_LNEGOP(op) : op,FQVR(f),h);
        !          2393:                return;
        !          2394:        }
        !          2395:        if (op == AL_NOT) {
        !          2396:                nnf1(FARG(f),!neg,disj,pf);
        !          2397:                return;
        !          2398:        }
        !          2399:        error("unknown operator in nnf1()");
        !          2400: }
        !          2401:
        !          2402: void freevars(f,pvl)
        !          2403: F f;
        !          2404: VL *pvl;
        !          2405: {
        !          2406:        *pvl = NULL;
        !          2407:        freevars1(f,pvl,NULL);
        !          2408: }
        !          2409:
        !          2410: void freevars1(f,pvl,cbvl)
        !          2411: F f;
        !          2412: VL *pvl,cbvl;
        !          2413: {
        !          2414:        VL hvl;
        !          2415:        NODE sc;
        !          2416:        oFOP op=FOP(f);
        !          2417:
        !          2418:        if (AL_ATOMIC(op)) {
        !          2419:                freevars1_a(f,pvl,cbvl);
        !          2420:                return;
        !          2421:        }
        !          2422:        if (AL_JUNCT(op)) {
        !          2423:                for (sc=FJARG(f); sc; sc=NEXT(sc))
        !          2424:                        freevars1((F)BDY(sc),pvl,cbvl);
        !          2425:                return;
        !          2426:        }
        !          2427:        if (AL_QUANT(op)) {
        !          2428:                MKVL(hvl,FQVR(f),cbvl);
        !          2429:                freevars1(FQMAT(f),pvl,hvl);
        !          2430:                return;
        !          2431:        }
        !          2432:        if (AL_UNI(op)) {
        !          2433:                freevars1(FARG(f),pvl,cbvl);
        !          2434:                return;
        !          2435:        }
        !          2436:        if (AL_EXT(op)) {
        !          2437:                freevars1(FLHS(f),pvl,cbvl);
        !          2438:                freevars1(FRHS(f),pvl,cbvl);
        !          2439:                return;
        !          2440:        }
        !          2441:        if (AL_TVAL(op))
        !          2442:                return;
        !          2443:        error("unknown operator in freevars1()");
        !          2444: }
        !          2445:
        !          2446: void freevars1_a(f,pvl,cbvl)
        !          2447: F f;
        !          2448: VL *pvl,cbvl;
        !          2449: {
        !          2450:        VL sc,sc2,last;
        !          2451:
        !          2452:        for (get_vars((Obj)FPL(f),&sc); sc; sc=NEXT(sc)) {
        !          2453:                for(sc2=cbvl; sc2; sc2=NEXT(sc2))
        !          2454:                        if (VR(sc) == VR(sc2))
        !          2455:                                break;
        !          2456:                if (sc2)
        !          2457:                        continue;
        !          2458:                if (!*pvl) {
        !          2459:                        MKVL(*pvl,VR(sc),NULL);
        !          2460:                        continue;
        !          2461:                }
        !          2462:                for (sc2=*pvl; sc2; sc2=NEXT(sc2)) {
        !          2463:                        if (VR(sc) == VR(sc2))
        !          2464:                                break;
        !          2465:                        last = sc2;
        !          2466:                }
        !          2467:                if (sc2)
        !          2468:                        continue;
        !          2469:                MKVL(NEXT(last),VR(sc),NULL);
        !          2470:        }
        !          2471: }
        !          2472:
        !          2473: int compf(vl,f1,f2)
        !          2474: VL vl;
        !          2475: F f1,f2;
        !          2476: {
        !          2477:        if (AL_ATOMIC(FOP(f1)) && AL_ATOMIC(FOP(f2)))
        !          2478:                return compaf(vl,f1,f2);
        !          2479:        if (AL_ATOMIC(FOP(f1)))
        !          2480:                return 1;
        !          2481:        if (AL_ATOMIC(FOP(f2)))
        !          2482:                return -1;
        !          2483:        if (synequalf(f1,f2))
        !          2484:                return 0;
        !          2485:        return 2;
        !          2486: }
        !          2487:
        !          2488: /* Debug */
        !          2489:
        !          2490: void ap(x)
        !          2491: pointer *x;
        !          2492: {
        !          2493:        printexpr(CO,(Obj)x);
        !          2494:        printf("\n");
        !          2495: }
        !          2496:
        !          2497: void rep(re)
        !          2498: RE re;
        !          2499: {
        !          2500:        printf("(");
        !          2501:        printexpr(CO,(Obj)PL(re));
        !          2502:        printf(",");
        !          2503:        printexpr(CO,(Obj)DISC(re));
        !          2504:        printf(",");
        !          2505:        printf("%d)\n",re->itype);
        !          2506: }
        !          2507:
        !          2508: void gpp(gp)
        !          2509: GP gp;
        !          2510: {
        !          2511:        ap(gp->g);
        !          2512:        rep(gp->p);
        !          2513: }
        !          2514:
        !          2515: void esetp(eset)
        !          2516: NODE eset;
        !          2517: {
        !          2518:        NODE sc;
        !          2519:
        !          2520:        for (sc=eset; sc; sc=NEXT(sc))
        !          2521:                gpp(BDY(sc));
        !          2522: }
        !          2523:
        !          2524: void nodep(n)
        !          2525: NODE n;
        !          2526: {
        !          2527:        NODE sc;
        !          2528:
        !          2529:        for (sc=n; sc; sc=NEXT(sc))
        !          2530:                ap(BDY(sc));
        !          2531: }
        !          2532:
        !          2533: void lbfp(x)
        !          2534: LBF x;
        !          2535: {
        !          2536:   printf("(%d,",LBFLB(x));
        !          2537:   printexpr(CO,(Obj)LBFF(x));
        !          2538:   printf(")");
        !          2539: }
        !          2540:
        !          2541: void thp(x)
        !          2542: NODE x;
        !          2543: {
        !          2544:   if (x == NULL) {
        !          2545:         printf("[]\n");
        !          2546:         return;
        !          2547:   }
        !          2548:   printf("[");
        !          2549:   lbfp((LBF)BDY(x));
        !          2550:   x = NEXT(x);
        !          2551:   for (; x != NULL; x = NEXT(x)) {
        !          2552:         printf(",");
        !          2553:         lbfp((LBF)BDY(x));
        !          2554:   }
        !          2555:   printf("]\n");
        !          2556: }

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