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