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