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

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

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

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