1 /*
2 * formula.c
3 *
4 * This file has routines to input and output quantified formulas and
5 * to convert them to lists of clauses (Skolemization and CNF translation).
6 *
7 */
8
9 #include "header.h"
10
11 static int Sk_func_num, Sk_const_num; /* for creating new skolem symbols */
12
13 /*************
14 *
15 * print_formula(fp, t) -- print a formula to a file.
16 *
17 *************/
18
print_formula(FILE * fp,struct formula * f)19 void print_formula(FILE *fp,
20 struct formula *f)
21 {
22 #if 1
23 struct term *t;
24
25 t = formula_to_term(f);
26 t = term_fixup_2(t);
27 print_term(fp, t);
28 zap_term(t);
29 #else
30 char op[MAX_NAME];
31 struct formula *f1;
32
33 if (f == NULL)
34 fprintf(fp, "(nil)");
35 else if (f->type == ATOM_FORM) {
36
37 print_term(fp, f->t);
38 }
39 else if (f->type == NOT_FORM) {
40 fprintf(fp, "-");
41 print_formula(fp, f->first_child);
42 }
43 else if (f->type == AND_FORM && f->first_child == NULL)
44 fprintf(fp, "TRUE");
45 else if (f->type == OR_FORM && f->first_child == NULL)
46 fprintf(fp, "FALSE");
47 else if (f->type == QUANT_FORM) {
48 fprintf(fp, "(");
49 if (f->quant_type == ALL_QUANT)
50 fprintf(fp, "all ");
51 else
52 fprintf(fp, "exists ");
53 print_term(fp, f->t);
54 fprintf(fp, " ");
55 print_formula(fp, f->first_child);
56 fprintf(fp, ")");
57 }
58 else {
59 if (f->type == AND_FORM)
60 strcpy(op, "& ");
61 else if (f->type == OR_FORM)
62 strcpy(op, "| ");
63 else if (f->type == IMP_FORM)
64 strcpy(op, "-> ");
65 else if (f->type == IFF_FORM)
66 strcpy(op, "<-> ");
67 else
68 op[0] = '\0';
69
70 fprintf(fp, "(");
71 for (f1 = f->first_child; f1; f1 = f1->next) {
72 print_formula(fp, f1);
73 if (f1->next)
74 fprintf(fp, " %s", op);
75 }
76 fprintf(fp, ")");
77 }
78 #endif
79 } /* print_formula */
80
81 /*************
82 *
83 * p_formula(f) -- print formula to standard output
84 *
85 *************/
86
p_formula(struct formula * f)87 void p_formula(struct formula *f)
88 {
89 print_formula(stdout, f);
90 } /* p_formula */
91
92 /*************
93 *
94 * struct term *formula_args_to_term(f, type)
95 *
96 * Conver list of formulas to right-associated term.
97 * Works for AND_FORM, OR_FORM, IMP_FORM, IFF_FORM.
98 *
99 *************/
100
formula_args_to_term(struct formula * f,int type)101 static struct term *formula_args_to_term(struct formula *f,
102 int type)
103 {
104 struct term *t, *t1, *t2;
105 struct rel *r1, *r2;
106
107 if (!f) { /* empty disjunction or conjunction */
108 t = get_term();
109 t->type = NAME;
110 if (type == AND_FORM)
111 t->sym_num = str_to_sn("TRUE", 0);
112 else
113 t->sym_num = str_to_sn("FALSE", 0);
114 }
115 else {
116 t1 = formula_to_term(f);
117 if (f->next) {
118 t2 = formula_args_to_term(f->next, type);
119 t = get_term(); r1 = get_rel(); r2 = get_rel();
120 t->farg = r1; r1->narg = r2;
121 r1->argval = t1; r2->argval = t2;
122 t->type = COMPLEX;
123 switch (type) {
124 case AND_FORM: t->sym_num = str_to_sn("&", 2); break;
125 case OR_FORM: t->sym_num = str_to_sn("|", 2); break;
126 case IMP_FORM: t->sym_num = str_to_sn("->", 2); break;
127 case IFF_FORM: t->sym_num = str_to_sn("<->", 2); break;
128 }
129 }
130 else
131 t = t1;
132 }
133 return(t);
134 } /* formula_args_to_term */
135
136 /*************
137 *
138 * struct term *formula_to_term(f)
139 *
140 *************/
141
formula_to_term(struct formula * f)142 struct term *formula_to_term(struct formula *f)
143 {
144 struct term *t, *t1;
145 struct rel *r, *r1, *prev_r;
146 int prev_q, i;
147 struct formula *f1;
148
149 switch (f->type) {
150 case ATOM_FORM: t = copy_term(f->t); break;
151 case IMP_FORM:
152 case IFF_FORM:
153 case AND_FORM:
154 case OR_FORM: t = formula_args_to_term(f->first_child, f->type); break;
155 case NOT_FORM:
156 t = get_term();
157 t->type = COMPLEX;
158 t->sym_num = str_to_sn("-", 1);
159 r = get_rel();
160 t->farg = r;
161 r->argval = formula_to_term(f->first_child);
162 break;
163 case QUANT_FORM:
164 t = get_term();
165 t->type = COMPLEX;
166 i = 0; prev_q = MAX_INT; prev_r = NULL;
167 for (f1 = f; f1->type == QUANT_FORM; f1 = f1->first_child) {
168 if (f1->quant_type != prev_q) {
169 i++;
170 t1 = get_term();
171 r1 = get_rel();
172 r1->argval = t1;
173 if (!t->farg)
174 t->farg = r1;
175 else
176 prev_r->narg = r1;
177 prev_r = r1;
178 t1->type = NAME;
179 if (f1->quant_type == ALL_QUANT)
180 t1->sym_num = str_to_sn("all", 0);
181 else
182 t1->sym_num = str_to_sn("exists", 0);
183 prev_q = f1->quant_type;
184 }
185 i++;
186 r1 = get_rel();
187 r1->argval = copy_term(f1->t); /* variable */
188 prev_r->narg = r1;
189 prev_r = r1;
190 }
191 t->sym_num = str_to_sn("$Quantified", i);
192 r1 = get_rel();
193 prev_r->narg = r1;
194 r1->argval = formula_to_term(f1);
195 break;
196 default: t = NULL;
197 }
198 return(t);
199 } /* formula_to_term */
200
201 /*************
202 *
203 * struct formula *term_to_formula(t)
204 *
205 *************/
206
term_to_formula(struct term * t)207 struct formula *term_to_formula(struct term *t)
208 {
209 struct formula *f1, *f2, *f3;
210 struct rel *r;
211 int type;
212
213 type = MAX_INT;
214
215 if (is_symbol(t, "&", 2))
216 type = AND_FORM;
217 else if (is_symbol(t, "|", 2))
218 type = OR_FORM;
219 else if (is_symbol(t, "->", 2))
220 type = IMP_FORM;
221 else if (is_symbol(t, "<->", 2))
222 type = IFF_FORM;
223
224 if (type != MAX_INT) {
225 f1 = get_formula();
226 f1->type = type;
227 f1->first_child = term_to_formula(t->farg->argval);
228 f1->first_child->next = term_to_formula(t->farg->narg->argval);
229 if (type == AND_FORM || type == OR_FORM)
230 flatten_top(f1);
231 }
232 else if (is_symbol(t, "-", 1)) {
233 f1 = get_formula();
234 f1->type = NOT_FORM;
235 f1->first_child = term_to_formula(t->farg->argval);
236 }
237 else if (t->type == COMPLEX &&
238 str_ident(sn_to_str(t->sym_num), "$Quantified")) {
239 f3 = f1 = NULL;
240 for (r = t->farg; r->narg; r = r->narg) {
241 if (is_symbol(r->argval, "all", 0))
242 type = ALL_QUANT;
243 else if (is_symbol(r->argval, "exists", 0))
244 type = EXISTS_QUANT;
245 else {
246 f2 = get_formula();
247 if (f3)
248 f3->first_child = f2;
249 else
250 f1 = f2;
251 f2->type = QUANT_FORM;
252 f2->quant_type = type;
253 f2->t = copy_term(r->argval);
254 f3 = f2;
255 }
256 }
257 f3->first_child = term_to_formula(r->argval);
258 }
259 else { /* assume atomic formula */
260 f1 = get_formula();
261 f1->type = ATOM_FORM;
262 f1->t = copy_term(t);
263 }
264 return(f1);
265
266 } /* term_to_formula */
267
268 /*************
269 *
270 * struct formula *read_formula(fp, rcp) -- read a formula from a file
271 *
272 * The return code *rcp:
273 * 0 - an error was encountered and reported; NULL is returned.
274 * 1 - OK; if EOF was found instead of a formula, NULL is returned.
275 *
276 *************/
277
read_formula(FILE * fp,int * rcp)278 struct formula *read_formula(FILE *fp,
279 int *rcp)
280 {
281 int rc;
282 struct formula *f;
283 struct term *t;
284
285 t = read_term(fp, &rc);
286 if (!rc) {
287 *rcp = 0;
288 return(NULL);
289 }
290 else if (t == NULL) {
291 *rcp = 1;
292 return(NULL);
293 }
294 else {
295 if (contains_skolem_symbol(t)) {
296 fprintf(stdout, "\nERROR, input formula contains Skolem symbol:\n");
297 print_term(stdout, t); printf(".\n\n");
298 zap_term(t);
299 *rcp = 0;
300 return(NULL);
301 }
302 else {
303 f = term_to_formula(t);
304 zap_term(t);
305 *rcp = 1;
306 return(f);
307 }
308 }
309 } /* read_formula */
310
311 /*************
312 *
313 * struct term_ptr *read_formula_list(file_ptr, errors_ptr)
314 *
315 * Read and return a list of quantified formulas.
316 *
317 * The list must be terminated either with the term `end_of_list.'
318 * or with an actual EOF.
319 * Set errors_ptr to point to the number of errors found.
320 *
321 *************/
322
read_formula_list(FILE * fp,int * ep)323 struct formula_ptr *read_formula_list(FILE *fp,
324 int *ep)
325 {
326 struct formula_ptr *p1, *p2, *p3;
327 struct formula *f;
328 int rc;
329
330 Internal_flags[REALLY_CHECK_ARITY] = 1;
331
332 *ep = 0;
333 p3 = NULL;
334 p2 = NULL;
335 f = read_formula(fp, &rc);
336 while (rc == 0) {
337 (*ep)++;
338 f = read_formula(fp, &rc);
339 }
340
341 /* keep going until f == NULL || f is end marker */
342
343 while (f && !(f->type == ATOM_FORM &&
344 is_symbol(f->t, "end_of_list", 0))) {
345 p1 = get_formula_ptr();
346 p1->f = f;
347 if (p2 == NULL)
348 p3 = p1;
349 else
350 p2->next = p1;
351 p2 = p1;
352 f = read_formula(fp, &rc);
353 while (rc == 0) {
354 (*ep)++;
355 f = read_formula(fp, &rc);
356 }
357 }
358 if (f != NULL)
359 zap_formula(f);
360
361 Internal_flags[REALLY_CHECK_ARITY] = 0;
362
363 return(p3);
364 } /* read_formula_list */
365
366 /*************
367 *
368 * print_formula_list(file_ptr, term_ptr)
369 *
370 * Print a list of quantified formulas.
371 *
372 * The list is printed with periods after each quantified formula, and
373 * the list is terminated with `end_of_list.' so that it can
374 * be read with read_formula_list.
375 *
376 *************/
377
print_formula_list(FILE * fp,struct formula_ptr * p)378 void print_formula_list(FILE *fp,
379 struct formula_ptr *p)
380 {
381 while (p != NULL) {
382 print_formula(fp, p->f); fprintf(fp, ".\n");
383 p = p->next;
384 }
385 fprintf(fp, "end_of_list.\n");
386 } /* print_formula_list */
387
388 /*************
389 *
390 * struct formula *copy_formula(f)
391 *
392 * Copy a formula. copy_term is used to copy atoms and quantified vars.
393 *
394 *************/
395
copy_formula(struct formula * f)396 struct formula *copy_formula(struct formula *f)
397 {
398 struct formula *f_new, *f_sub, *f_prev, *f3;
399
400 f_new = get_formula();
401 f_new->type = f->type;
402
403 if (f->type == ATOM_FORM)
404 f_new->t = copy_term(f->t);
405 else if (f->type == QUANT_FORM) {
406 f_new->quant_type = f->quant_type;
407 f_new->t = copy_term(f->t);
408 f_new->first_child = copy_formula(f->first_child);
409 }
410 else {
411 f_prev = NULL;
412 for (f_sub = f->first_child; f_sub; f_sub = f_sub->next) {
413 f3 = copy_formula(f_sub);
414 if (f_prev)
415 f_prev->next = f3;
416 else
417 f_new->first_child = f3;
418 f_prev = f3;
419 }
420 }
421 return(f_new);
422
423 } /* copy_formula */
424
425 /*************
426 *
427 * void zap_formula(f)
428 *
429 * Free a formula and all of its subformulas and subterms.
430 *
431 *************/
432
zap_formula(struct formula * f)433 void zap_formula(struct formula *f)
434 {
435 struct formula *f1, *f2;
436
437 if (f->type == ATOM_FORM)
438 zap_term(f->t);
439 else {
440 f1 = f->first_child;
441 while (f1) {
442 f2 = f1;
443 f1 = f1->next;
444 zap_formula(f2);
445 }
446 if (f->type == QUANT_FORM)
447 zap_term(f->t);
448 }
449 free_formula(f);
450 } /* zap_formula */
451
452 /*************
453 *
454 * struct formula *negate_formula(f)
455 *
456 * f is changed to its negation. (Do not move negation signs inward.)
457 *
458 *************/
459
negate_formula(struct formula * f)460 struct formula *negate_formula(struct formula *f)
461 {
462 struct formula *f1, *f_save;
463
464 /* save next pointer */
465 f_save = f->next; f->next = NULL;
466
467 if (f->type == NOT_FORM) {
468 f1 = f->first_child;
469 free_formula(f);
470 }
471 else {
472 f1 = get_formula();
473 f1->type = NOT_FORM;
474 f1->first_child = f;
475 }
476 /* restore next pointer */
477 f1->next = f_save;
478 return(f1);
479 } /* negate_formula */
480
481 /*************
482 *
483 * struct formula *nnf(f)
484 *
485 * f is changed into its negation normal form (NNF) by removing
486 * -> and <-> and moving negation signs all the way in.
487 *
488 * (A <-> B) (not negated) rewrites to ((-a | b) & (-b | a)).
489 * -(A <-> B) rewrites to ((a | b) & (-a | -b)).
490 *
491 * because conjunctions are favored.
492 *
493 *************/
494
nnf(struct formula * f)495 struct formula *nnf(struct formula *f)
496 {
497 struct formula *f1, *f2, *next, *prev, *fn;
498
499 switch (f->type) {
500 case ATOM_FORM:
501 return(f); /* f is atomic */
502 case IFF_FORM:
503 f1 = get_formula();
504 f1->type = AND_FORM;
505 f1->first_child = f;
506 f1->next = f->next;
507
508 f2 = copy_formula(f);
509 f2->type = OR_FORM;
510 f2->first_child->next = negate_formula(f2->first_child->next);
511
512 f->type = OR_FORM;
513 f->first_child = negate_formula(f->first_child);
514 f->next = f2;
515 return(nnf(f1));
516 case IMP_FORM:
517 f->type = OR_FORM;
518 f->first_child = negate_formula(f->first_child);
519 return(nnf(f));
520 case QUANT_FORM:
521 f->first_child = nnf(f->first_child);
522 return(f);
523 case AND_FORM:
524 case OR_FORM:
525 prev = NULL;
526 f1 = f->first_child;
527 while(f1) {
528 next = f1->next; f1->next = NULL;
529 f2 = nnf(f1);
530 if (prev)
531 prev->next = f2;
532 else
533 f->first_child = f2;
534 prev = f2;
535 f1 = next;
536 }
537 return(f);
538
539 case NOT_FORM:
540 fn = f->first_child;
541 switch (fn->type) {
542 case ATOM_FORM:
543 return(f);
544 case IFF_FORM:
545 f2 = copy_formula(fn);
546 f2->type = OR_FORM;
547 fn->type = OR_FORM;
548 f2->first_child = negate_formula(f2->first_child);
549 f2->first_child->next = negate_formula(f2->first_child->next);
550 fn->next = f2;
551 f->type = AND_FORM;
552 f->first_child = fn;
553 return(nnf(f));
554 case IMP_FORM:
555 fn->type = OR_FORM;
556 fn->first_child = negate_formula(fn->first_child);
557 return(nnf(f));
558 case QUANT_FORM:
559 fn->quant_type = (fn->quant_type == ALL_QUANT ? EXISTS_QUANT : ALL_QUANT);
560 fn->first_child = nnf(negate_formula(fn->first_child));
561 fn->next = f->next;
562 free_formula(f);
563 return(fn);
564 case AND_FORM:
565 case OR_FORM:
566 prev = NULL;
567 f1 = fn->first_child;
568 while(f1) {
569 next = f1->next; f1->next = NULL;
570 f2 = nnf(negate_formula(f1));
571 if (prev)
572 prev->next = f2;
573 else
574 fn->first_child = f2;
575 prev = f2;
576 f1 = next;
577 }
578 fn->type = (fn->type == AND_FORM ? OR_FORM : AND_FORM);
579 fn->next = f->next;
580 free_formula(f);
581 return(fn);
582
583 case NOT_FORM: /* double negation */
584 f1 = fn->first_child;
585 f1->next = f->next;
586 free_formula(f);
587 free_formula(fn);
588 return(nnf(f1));
589 }
590 }
591 return(NULL); /* ERROR */
592 } /* nnf */
593
594 /*************
595 *
596 * static void rename_free_formula(f, old_sn, new_sn)
597 *
598 * Rename free occurrences of old_sn in NAMEs to new_sn.
599 * Recall that variables in formulas are really NAMEs.
600 *
601 *************/
602
rename_free_formula(struct formula * f,int old_sn,int new_sn)603 static void rename_free_formula(struct formula *f,
604 int old_sn,
605 int new_sn)
606 {
607 struct formula *f1;
608
609 if (f->type == ATOM_FORM)
610 subst_sn_term(old_sn, f->t, new_sn, NAME);
611 else if (f->type == QUANT_FORM) {
612 if (old_sn != f->t->sym_num)
613 rename_free_formula(f->first_child, old_sn, new_sn);
614 }
615 else {
616 for (f1 = f->first_child; f1; f1 = f1->next)
617 rename_free_formula(f1, old_sn, new_sn);
618 }
619
620 } /* rename_free_formula */
621
622 /*************
623 *
624 * static struct formula *skolem(f, vars)
625 *
626 * Skolemize f w.r.t universally quantified vars.
627 * Called by skolemize.
628 *
629 *************/
630
skolem(struct formula * f,struct term * vars)631 static struct formula *skolem(struct formula *f,
632 struct term *vars)
633 {
634 struct formula *f1, *f2, *prev, *next;
635 struct rel *end, *r2;
636 int sn;
637
638 if (f->type == NOT_FORM && f->first_child->type != ATOM_FORM) {
639 printf("ERROR, skolem gets negated non-atom: ");
640 print_formula(stdout, f);
641 printf("\n");
642 }
643 else if (f->type == IMP_FORM || f->type == IFF_FORM) {
644 printf("ERROR, skolem gets: ");
645 print_formula(stdout, f);
646 printf("\n");
647 }
648 else if (f->type == AND_FORM || f->type == OR_FORM) {
649 prev = NULL;
650 f1 = f->first_child;
651 while(f1) {
652 next = f1->next; f1->next = NULL;
653 f2 = skolem(f1, vars);
654 if (prev)
655 prev->next = f2;
656 else
657 f->first_child = f2;
658 prev = f2;
659 f1 = next;
660 }
661 }
662 else if (f->type == QUANT_FORM) {
663 if (f->quant_type == ALL_QUANT) {
664 if (occurs_in(f->t, vars)) {
665 /*
666 rename current variable, because we are already in the
667 scope of a universally quantified var with that name.
668 */
669 sn = new_var_name();
670 rename_free_formula(f->first_child, f->t->sym_num, sn);
671 f->t->sym_num = sn;
672 }
673 r2 = get_rel();
674 r2->argval = f->t;
675
676 /* Install variable at end of vars. */
677 for (end = vars->farg; end && end->narg; end = end->narg);
678 if (end)
679 end->narg = r2;
680 else
681 vars->farg = r2;
682
683 f->first_child = skolem(f->first_child, vars);
684
685 /* Remove variable from vars. */
686
687 free_rel(r2);
688 if (end)
689 end->narg = NULL;
690 else
691 vars->farg = NULL;
692 }
693 else { /* existential quantifier */
694 /*
695 must skolemize subformula first to avoid problem in
696 Ax...Ey...Ex F(x,y).
697 */
698 f->first_child = skolem(f->first_child, vars);
699
700 gen_sk_sym(vars); /* fills in sym_num and assigns type */
701 subst_free_formula(f->t, f->first_child, vars);
702 vars->type = COMPLEX; /* so that occurs_in above works */
703
704 f1 = f->first_child;
705 zap_term(f->t);
706 free_formula(f);
707 f = f1;
708 }
709 }
710 return(f);
711 } /* skolem */
712
713 /*************
714 *
715 * struct formula *skolemize(f) -- Skolemize a formula
716 *
717 * This routine assumes that f is in negation normal form.
718 * The existential quantifiers are deleted.
719 *
720 *************/
721
skolemize(struct formula * f)722 struct formula *skolemize(struct formula *f)
723 {
724 struct term *vars;
725
726 vars = get_term();
727 vars->type = COMPLEX;
728 f = skolem(f, vars);
729 free_term(vars);
730 return(f);
731
732 } /* skolemize */
733
734 /*************
735 *
736 * struct formula *anti_skolemize(f) -- Anti-Skolemize a formula
737 *
738 * The dual of skolemize: universal quantifiers are removed.
739 *
740 *************/
741
anti_skolemize(struct formula * f)742 struct formula *anti_skolemize(struct formula *f)
743 {
744 return(nnf(negate_formula(skolemize(nnf(negate_formula(f))))));
745 } /* anti_skolemize */
746
747 /*************
748 *
749 * static void subst_free_term(var, t, sk)
750 *
751 * Substitute free occurrences of var in t with copies of sk.
752 *
753 *************/
754
subst_free_term(struct term * var,struct term * t,struct term * sk)755 static void subst_free_term(struct term *var,
756 struct term *t,
757 struct term *sk)
758 {
759 struct rel *r;
760
761 if (t->type != COMPLEX)
762 return;
763 else {
764 r = t->farg;
765 for (r = t->farg; r; r = r->narg) {
766 if (term_ident(var, r->argval)) {
767 zap_term(r->argval);
768 r->argval = copy_term(sk);
769 }
770 else
771 subst_free_term(var, r->argval, sk);
772 }
773 }
774 } /* subst_free_term */
775
776 /*************
777 *
778 * void subst_free_formula(var, f, sk)
779
780 * Substitute free occurrences of var in f with copies of sk.
781 *
782 *************/
783
subst_free_formula(struct term * var,struct formula * f,struct term * sk)784 void subst_free_formula(struct term *var,
785 struct formula *f,
786 struct term *sk)
787 {
788 struct formula *f1;
789
790 if (f->type == ATOM_FORM)
791 subst_free_term(var, f->t, sk);
792 else if (f->type == QUANT_FORM) {
793 if (!term_ident(f->t, var))
794 subst_free_formula(var, f->first_child, sk);
795 }
796 else {
797 for (f1 = f->first_child; f1; f1 = f1->next)
798 subst_free_formula(var, f1, sk);
799 }
800
801 } /* subst_free_formula */
802
803 /*************
804 *
805 * gen_sk_sym(t) -- generate a fresh skolem symbol for term t.
806 *
807 * Assign type field as well as sym_num field to term t.
808 *
809 *************/
810
gen_sk_sym(struct term * t)811 void gen_sk_sym(struct term *t)
812 {
813 int arity;
814 struct rel *r;
815 char s1[MAX_NAME], s2[MAX_NAME];
816
817 arity = 0;
818 r = t->farg;
819 while (r != NULL) {
820 arity++;
821 r = r->narg;
822 }
823
824 if (arity == 0) {
825 t->type = NAME;
826 int_str(++Sk_const_num, s1);
827 cat_str("$c", s1, s2);
828 }
829 else {
830 t->type = COMPLEX;
831 int_str(++Sk_func_num, s1);
832 cat_str("$f", s1, s2);
833 }
834
835 t->sym_num = str_to_sn(s2, arity);
836 mark_as_skolem(t->sym_num);
837
838 } /* gen_sk_sym */
839
840 /*************
841 *
842 * int skolem_symbol(sn) -- Is sn the symbol number of a skolem symbol?
843 *
844 * Check if it is "$cn" or "$fn" for integer n.
845 * Do not check the skolem flag in the symbol node.
846 *
847 *************/
848
skolem_symbol(int sn)849 int skolem_symbol(int sn)
850 {
851 char *s;
852 int dummy;
853
854 s = sn_to_str(sn);
855 return(*s == '$' &&
856 (*(s+1) == 'c' || *(s+1) == 'f') &&
857 str_int(s+2,&dummy));
858 } /* skolem_symbol */
859
860 /*************
861 *
862 * int contains_skolem_symbol(t)
863 *
864 * Check if any of the NAMEs in t are "$cn" or "$fn", for integer n.
865 *
866 *************/
867
contains_skolem_symbol(struct term * t)868 int contains_skolem_symbol(struct term *t)
869 {
870 struct rel *r;
871
872 if (t->type == VARIABLE)
873 return(0);
874 else if (t->type == NAME)
875 return(skolem_symbol(t->sym_num));
876 else { /* COMPLEX */
877 if (skolem_symbol(t->sym_num))
878 return(1);
879 else {
880 for (r = t->farg; r; r = r->narg)
881 if (contains_skolem_symbol(r->argval))
882 return(1);
883 return(0);
884 }
885 }
886 } /* contains_skolem_symbol */
887
888 /*************
889 *
890 * int new_var_name() -- return a sym_num for a new VARIABLE symbol
891 *
892 * Check and make sure that the new symbol does not occur in the
893 * symbol table.
894 *
895 *************/
896
new_var_name(void)897 int new_var_name(void)
898 {
899 char s1[MAX_NAME], s2[MAX_NAME];
900
901 static int var_num;
902 char c[2];
903
904 c[0] = (Flags[PROLOG_STYLE_VARIABLES].val ? 'X' : 'x');
905 c[1] = '\0';
906
907 int_str(++var_num, s1);
908 cat_str(c, s1, s2);
909 while (in_sym_tab(s2)) {
910 int_str(++var_num, s1);
911 cat_str(c, s1, s2);
912 }
913
914 return(str_to_sn(s2, 0));
915
916 } /* new_var_name */
917
918 /*************
919 *
920 * int new_functor_name(arity) -- return a sym_num for a new symbol.
921 *
922 * Check and make sure that the new symbol does not occur in the symbol table.
923 *
924 *************/
925
new_functor_name(int arity)926 int new_functor_name(int arity)
927 {
928 char s1[MAX_NAME], s2[MAX_NAME];
929
930 static int functor_num;
931
932 int_str(++functor_num, s1);
933 cat_str("k", s1, s2);
934 while (in_sym_tab(s2)) {
935 int_str(++functor_num, s1);
936 cat_str("k", s1, s2);
937 }
938
939 return(str_to_sn(s2, arity));
940
941 } /* new_functor_name */
942
943 /*************
944 *
945 * static void uq_all(f, vars) -- called by unique_all
946 *
947 *************/
948
uq_all(struct formula * f,struct term * vars)949 static void uq_all(struct formula *f,
950 struct term *vars)
951 {
952 struct rel *r1;
953 struct formula *f1;
954 int sn;
955
956 switch (f->type) {
957 case ATOM_FORM: break;
958 case NOT_FORM:
959 case AND_FORM:
960 case OR_FORM:
961 for (f1 = f->first_child; f1; f1 = f1->next)
962 uq_all(f1, vars);
963 break;
964 case QUANT_FORM:
965 if (occurs_in(f->t, vars)) {
966 /*
967 rename current variable, because already have
968 a quantified var with that name.
969 */
970 sn = new_var_name();
971 rename_free_formula(f->first_child, f->t->sym_num, sn);
972 f->t->sym_num = sn;
973 }
974 else {
975 r1 = get_rel();
976 r1->argval = f->t;
977 r1->narg = vars->farg;
978 vars->farg = r1;
979 }
980
981 /* recursive call on quantified formula */
982 uq_all(f->first_child, vars);
983 break;
984 }
985 } /* uq_all */
986
987 /*************
988 *
989 * void unique_all(f) -- make all universally quantified variables unique
990 *
991 * It is assumed that f is in negation normal form and is Skolemized (no
992 * existential quantifiers).
993 *
994 *************/
995
unique_all(struct formula * f)996 void unique_all(struct formula *f)
997 {
998 struct term *vars;
999 struct rel *r1, *r2;
1000
1001 vars = get_term();
1002 vars->type = COMPLEX;
1003 uq_all(f, vars);
1004 r1 = vars->farg;
1005 while (r1 != NULL) {
1006 r2 = r1;
1007 r1 = r1->narg;
1008 free_rel(r2);
1009 }
1010 free_term(vars);
1011 } /* unique_all */
1012
1013 /*************
1014 *
1015 * static mark_free_var_term(v, t) -- mark free occurrences of v in t
1016 *
1017 * Each free NAME in t with sym_num == v->sym_num is marked as
1018 * a VARIABLE by setting the type field to VARIABLE.
1019 *
1020 *************/
1021
mark_free_var_term(struct term * v,struct term * t)1022 static void mark_free_var_term(struct term *v,
1023 struct term *t)
1024 {
1025 struct rel *r;
1026 struct term *t1;
1027
1028 if (t->type != COMPLEX)
1029 return;
1030 else {
1031 r = t->farg;
1032 for (r = t->farg; r; r = r->narg) {
1033 t1 = r->argval;
1034 if (t1->type == NAME) {
1035 if (t1->sym_num == v->sym_num) {
1036 t1->type = VARIABLE;
1037 /*
1038 bug fix 31-Jan-91. WWM. The following line was added
1039 because term-ident (called if simplify_fol) does not
1040 check sym_num field for vars. It is a trick.
1041 */
1042 t1->varnum = t1->sym_num;
1043 }
1044 }
1045 else
1046 mark_free_var_term(v, t1);
1047 }
1048 }
1049 } /* mark_free_var_term */
1050
1051 /*************
1052 *
1053 * static void mark_free_var_formula(v, f)
1054 *
1055 *************/
1056
mark_free_var_formula(struct term * v,struct formula * f)1057 static void mark_free_var_formula(struct term *v,
1058 struct formula *f)
1059 {
1060 struct formula *f1;
1061
1062 if (f->type == ATOM_FORM)
1063 mark_free_var_term(v, f->t);
1064 else {
1065 for (f1 = f->first_child; f1; f1 = f1->next)
1066 mark_free_var_formula(v, f1);
1067 }
1068 } /* mark_free_var_formula */
1069
1070 /*************
1071 *
1072 * struct term *zap_quant(f)
1073 *
1074 * Delete quantifiers and mark quantified variables.
1075 *
1076 * It is assumed that f is skolemized nnf with unique universally
1077 * quantified variables. For each universal quantifier,
1078 * mark all occurrences of the quantified variable by setting the type field
1079 * to VARIABLE, then delete the quantifier.
1080 * All QUANT_FORM nodes are deleted as well.
1081 *
1082 *************/
1083
zap_quant(struct formula * f)1084 struct formula *zap_quant(struct formula *f)
1085 {
1086
1087 struct formula *f1, *f2, *prev, *next;
1088
1089 switch (f->type) {
1090 case ATOM_FORM:
1091 break;
1092 case NOT_FORM:
1093 case AND_FORM:
1094 case OR_FORM:
1095 prev = NULL;
1096 f1 = f->first_child;
1097 while(f1) {
1098 next = f1->next; f1->next = NULL;
1099 f2 = zap_quant(f1);
1100 if (prev)
1101 prev->next = f2;
1102 else
1103 f->first_child = f2;
1104 prev = f2;
1105 f1 = next;
1106 }
1107 break;
1108 case QUANT_FORM:
1109 mark_free_var_formula(f->t, f->first_child);
1110 f1 = f->first_child;
1111 f1->next = f->next;
1112 free_formula(f);
1113 f = zap_quant(f1);
1114 break;
1115 }
1116 return(f);
1117 } /* zap_quant */
1118
1119 /*************
1120 *
1121 * static void flatten_top_2(f, start, end_p) -- called by flatten_top.
1122 *
1123 *************/
1124
flatten_top_2(struct formula * f,struct formula * start,struct formula ** end_p)1125 static void flatten_top_2(struct formula *f,
1126 struct formula *start,
1127 struct formula **end_p)
1128 {
1129 struct formula *f1, *f2;
1130
1131 f1 = f->first_child;
1132 while (f1) {
1133 f2 = f1;
1134 f1 = f1->next;
1135 if (f2->type == f->type) {
1136 flatten_top_2(f2, start, end_p);
1137 free_formula(f2);
1138 }
1139 else {
1140 if (*end_p)
1141 (*end_p)->next = f2;
1142 else
1143 start->first_child = f2;
1144 *end_p = f2;
1145 }
1146 }
1147 } /* flatten_top_2 */
1148
1149 /*************
1150 *
1151 * void flatten_top(f) -- flatten conjunctions or disjunctions
1152 *
1153 * The top part of f is flattened. Subtrees below
1154 * a node of the oppposite type are not flattened. For example, in
1155 * (a or (b and (c or (d or e)))), the formula (c or (d or e)) is never
1156 * flattened.
1157 *
1158 *************/
1159
flatten_top(struct formula * f)1160 void flatten_top(struct formula *f)
1161 {
1162 struct formula *end;
1163
1164 if (f->type == AND_FORM || f->type == OR_FORM) {
1165 end = NULL;
1166 flatten_top_2(f, f, &end);
1167 if (end)
1168 end->next = NULL;
1169 else
1170 f->first_child = NULL;
1171 }
1172 } /* flatten_top */
1173
1174 /*************
1175 *
1176 * static struct formula *distribute(f) -- distribute OR over AND.
1177 *
1178 * f is an OR node whose subterms are in CNF. This routine returns
1179 * a CNF of f.
1180 *
1181 *************/
1182
distribute(struct formula * f)1183 static struct formula *distribute(struct formula *f)
1184 {
1185 struct formula *f_new, *f1, *f2, *f3, *f4, *f_prev, *f_save;
1186 int i, j;
1187
1188 f_save = f->next; f->next = NULL;
1189
1190 if (f->type != OR_FORM)
1191 return(f);
1192 else {
1193
1194 flatten_top(f);
1195 if (Flags[SIMPLIFY_FOL].val) {
1196 conflict_tautology(f);
1197 f = subsume_disj(f);
1198 }
1199 if (f->type != OR_FORM)
1200 return(f);
1201 else {
1202
1203 /* find first AND subformula */
1204 i = 1;
1205 f_prev = NULL;
1206 for (f1 = f->first_child; f1 && f1->type != AND_FORM; f1 = f1->next) {
1207 i++;
1208 f_prev = f1;
1209 }
1210 if (f1 == NULL)
1211 return(f); /* nothing to distribute */
1212 else {
1213 /* unhook AND */
1214 if (f_prev)
1215 f_prev->next = f1->next;
1216 else
1217 f->first_child = f1->next;
1218 f2 = f1->first_child;
1219 f_new = f1;
1220 f_prev = NULL;
1221 while (f2) {
1222 f3 = f2->next;
1223 if (f3)
1224 f1 = copy_formula(f);
1225 else
1226 f1 = f;
1227 if (i == 1) {
1228 f2->next = f1->first_child;
1229 f1->first_child = f2;
1230 }
1231 else {
1232 j = 1;
1233 for (f4 = f1->first_child; j < i-1; f4 = f4->next)
1234 j++;
1235 f2->next = f4->next;
1236 f4->next = f2;
1237 }
1238 f1 = distribute(f1);
1239 if (f_prev)
1240 f_prev->next = f1;
1241 else
1242 f_new->first_child = f1;
1243 f_prev = f1;
1244 f2 = f3;
1245 }
1246 f_new->next = f_save;
1247 flatten_top(f_new);
1248 if (Flags[SIMPLIFY_FOL].val) {
1249 conflict_tautology(f_new);
1250 f_new = subsume_conj(f_new);
1251 }
1252 return(f_new);
1253 }
1254 }
1255 }
1256 } /* distribute */
1257
1258 /*************
1259 *
1260 * struct formula *cnf(f) -- convert nnf f to conjunctive normal form.
1261 *
1262 *************/
1263
cnf(struct formula * f)1264 struct formula *cnf(struct formula *f)
1265 {
1266 struct formula *f1, *f2, *f_prev, *f_next, *f_save;
1267
1268 f_save = f->next; f->next = NULL;
1269
1270 if (f->type == AND_FORM || f->type == OR_FORM) {
1271 /* first convert subterms to CNF */
1272 f_prev = NULL;
1273 f1 = f->first_child;
1274 while(f1) {
1275 f_next = f1->next;
1276 f2 = cnf(f1);
1277 if (f_prev)
1278 f_prev->next = f2;
1279 else
1280 f->first_child = f2;
1281 f_prev = f2;
1282 f1 = f_next;
1283 }
1284
1285 if (f->type == AND_FORM) {
1286 flatten_top(f);
1287 if (Flags[SIMPLIFY_FOL].val) {
1288 conflict_tautology(f);
1289 f = subsume_conj(f);
1290 }
1291 }
1292 else
1293 f = distribute(f); /* flatten and simplify in distribute */
1294 }
1295
1296 f->next = f_save;
1297 return(f);
1298
1299 } /* cnf */
1300
1301 /*************
1302 *
1303 * struct formula *dnf(f) -- convert f to disjunctive normal form.
1304 *
1305 *************/
1306
dnf(struct formula * f)1307 struct formula *dnf(struct formula *f)
1308 {
1309 return(nnf(negate_formula(cnf(nnf(negate_formula(f))))));
1310 } /* dnf */
1311
1312 /*************
1313 *
1314 * static void rename_syms_term(t, fr)
1315 *
1316 * Called from rename_syms_formula.
1317 *
1318 *************/
1319
rename_syms_term(struct term * t,struct formula * fr)1320 static void rename_syms_term(struct term *t,
1321 struct formula *fr)
1322 {
1323 struct rel *r;
1324 int sn;
1325
1326 if (t->type == NAME) {
1327 if (var_name(sn_to_str(t->sym_num))) {
1328 fprintf(stderr,"\nWARNING, the following formula has constant '%s', whose\nname may be misinterpreted by the user as a variable.\n", sn_to_str(t->sym_num));
1329 print_formula(stderr, fr); fprintf(stderr, "\n");
1330 #if 0 /* replaced 18 June 91 WWM */
1331 sn = new_functor_name(0); /* with arity 0 */
1332 subst_sn_formula(t->sym_num, fr, sn, NAME);
1333 #endif
1334 }
1335 }
1336 else if (t->type == VARIABLE) {
1337 if (!var_name(sn_to_str(t->sym_num))) {
1338 sn = new_var_name();
1339 subst_sn_formula(t->sym_num, fr, sn, VARIABLE);
1340 }
1341 }
1342 else {
1343 r = t->farg;
1344 while(r != NULL) {
1345 rename_syms_term(r->argval, fr);
1346 r = r->narg;
1347 }
1348 }
1349 } /* rename_syms_term */
1350
1351 /*************
1352 *
1353 * void rename_syms_formula(f, fr)
1354 *
1355 * Rename VARIABLEs so that they conform to the rule for clauses.
1356 *
1357 *************/
1358
rename_syms_formula(struct formula * f,struct formula * fr)1359 void rename_syms_formula(struct formula *f,
1360 struct formula *fr)
1361 {
1362 struct formula *f1;
1363
1364 if (f->type == ATOM_FORM)
1365 rename_syms_term(f->t, fr);
1366 else {
1367 for (f1 = f->first_child; f1; f1 = f1->next)
1368 rename_syms_formula(f1, fr);
1369 }
1370 } /* rename_syms_formula */
1371
1372 /*************
1373 *
1374 * void subst_sn_term(old_sn, t, new_sn, type)
1375 *
1376 *************/
1377
subst_sn_term(int old_sn,struct term * t,int new_sn,int type)1378 void subst_sn_term(int old_sn,
1379 struct term *t,
1380 int new_sn,
1381 int type)
1382 {
1383 struct rel *r;
1384
1385 if (t->type == NAME) {
1386 if (type == NAME && t->sym_num == old_sn)
1387 t->sym_num = new_sn;
1388 }
1389 else if (t->type == VARIABLE) {
1390 if (type == VARIABLE && t->sym_num == old_sn)
1391 t->sym_num = new_sn;
1392 }
1393 else {
1394 for (r = t->farg; r; r = r->narg)
1395 subst_sn_term(old_sn, r->argval, new_sn, type);
1396 }
1397 } /* subst_sn_term */
1398
1399 /*************
1400 *
1401 * void subst_sn_formula(old_sn, f, new_sn, type)
1402 *
1403 *************/
1404
subst_sn_formula(int old_sn,struct formula * f,int new_sn,int type)1405 void subst_sn_formula(int old_sn,
1406 struct formula *f,
1407 int new_sn,
1408 int type)
1409 {
1410 struct formula *f1;
1411
1412 if (f->type == ATOM_FORM)
1413 subst_sn_term(old_sn, f->t, new_sn, type);
1414 else {
1415 for (f1 = f->first_child; f1; f1 = f1->next)
1416 subst_sn_formula(old_sn, f1, new_sn, type);
1417 }
1418 } /* subst_sn_formula */
1419
1420 /*************
1421 *
1422 * int gen_subsume_prop(c, d) -- does c gen_subsume_prop d?
1423 *
1424 * This is generalized propositional subsumption. If given
1425 * quantified formulas, they are treated as atoms (formula_ident
1426 * determines outcome).
1427 *
1428 *************/
1429
gen_subsume_prop(struct formula * c,struct formula * d)1430 int gen_subsume_prop(struct formula *c,
1431 struct formula *d)
1432 {
1433 struct formula *f;
1434
1435 /* The order of these tests is important. For example, if */
1436 /* the last test is moved to the front, c=(p|q) will not */
1437 /* subsume d=(p|q|r). */
1438
1439 if (c->type == OR_FORM) { /* return(each c_i subsumes d) */
1440 for (f = c->first_child; f && gen_subsume_prop(f, d); f = f->next);
1441 return(f == NULL);
1442 }
1443 else if (d->type == AND_FORM) { /* return(c subsumes each d_i) */
1444 for (f = d->first_child; f && gen_subsume_prop(c, f); f = f->next);
1445 return(f == NULL);
1446 }
1447 else if (c->type == AND_FORM) { /* return(one c_i subsumes d) */
1448 for (f = c->first_child; f && ! gen_subsume_prop(f, d); f = f->next);
1449 return(f != NULL);
1450 }
1451 else if (d->type == OR_FORM) { /* return(c subsumes one d_i) */
1452 for (f = d->first_child; f && ! gen_subsume_prop(c, f); f = f->next);
1453 return(f != NULL);
1454 }
1455 else /* c and d are NOT, ATOM, or QUANT */
1456 return(formula_ident(c, d));
1457
1458 } /* gen_subsume_prop */
1459
1460 /*************
1461 *
1462 * struct formula *subsume_conj(c)
1463 *
1464 * Given a conjunction, discard weaker conjuncts.
1465 * This is like deleting subsumed clauses.
1466 * The result is equivalent.
1467 *
1468 *************/
1469
subsume_conj(struct formula * c)1470 struct formula *subsume_conj(struct formula *c)
1471 {
1472 struct formula *f1, *f2, *f3, *prev;
1473
1474 if (c->type != AND_FORM || c->first_child == NULL)
1475 return(c);
1476 else {
1477 /* start with second child */
1478 prev = c->first_child;
1479 f1 = prev->next;
1480 while (f1) {
1481 /* first do forward subsumption of part already processed */
1482 f2 = c->first_child;
1483 while (f2 != f1 && ! gen_subsume_prop(f2, f1))
1484 f2 = f2->next;;
1485 if (f2 != f1) { /* delete f1 */
1486 prev->next = f1->next;
1487 zap_formula(f1);
1488 f1 = prev;
1489 }
1490 else {
1491 /* back subsumption on part already processed */
1492 /* delete all previous that are subsumed by f1 */
1493 f2 = c->first_child;
1494 prev = NULL;
1495 while (f2 != f1) {
1496 if (gen_subsume_prop(f1, f2)) {
1497 if (prev == NULL)
1498 c->first_child = f2->next;
1499 else
1500 prev->next = f2->next;
1501 f3 = f2;
1502 f2 = f2->next;
1503 zap_formula(f3);
1504 }
1505 else {
1506 prev = f2;
1507 f2 = f2->next;
1508 }
1509 }
1510 }
1511 prev = f1;
1512 f1 = f1->next;
1513 }
1514 /* If just one child left, replace input formula with child. */
1515 if (c->first_child->next == NULL) {
1516 f1 = c->first_child;
1517 f1->next = c->next;
1518 free_formula(c);
1519 return(f1);
1520 }
1521 else
1522 return(c);
1523 }
1524 } /* subsume_conj */
1525
1526 /*************
1527 *
1528 * struct formula *subsume_disj(c)
1529 *
1530 * Given a disjunction, discard stronger disjuncts.
1531 * The result is equivalent. This the dual of
1532 * normal clause subsumption.
1533 *
1534 *************/
1535
subsume_disj(struct formula * c)1536 struct formula *subsume_disj(struct formula *c)
1537 {
1538 struct formula *f1, *f2, *f3, *prev;
1539
1540 if (c->type != OR_FORM || c->first_child == NULL)
1541 return(c);
1542 else {
1543 /* start with second child */
1544 prev = c->first_child;
1545 f1 = prev->next;
1546 while (f1) {
1547 /* delete f1 if it subsumes anything previous */
1548 f2 = c->first_child;
1549 while (f2 != f1 && ! gen_subsume_prop(f1, f2))
1550 f2 = f2->next;;
1551 if (f2 != f1) { /* delete f1 */
1552 prev->next = f1->next;
1553 zap_formula(f1);
1554 f1 = prev;
1555 }
1556 else {
1557 /* delete all previous that subsume f1 */
1558 f2 = c->first_child;
1559 prev = NULL;
1560 while (f2 != f1) {
1561 if (gen_subsume_prop(f2, f1)) {
1562 if (prev == NULL)
1563 c->first_child = f2->next;
1564 else
1565 prev->next = f2->next;
1566 f3 = f2;
1567 f2 = f2->next;
1568 zap_formula(f3);
1569 }
1570 else {
1571 prev = f2;
1572 f2 = f2->next;
1573 }
1574 }
1575 }
1576 prev = f1;
1577 f1 = f1->next;
1578 }
1579 /* If just one child left, replace input formula with child. */
1580 if (c->first_child->next == NULL) {
1581 f1 = c->first_child;
1582 f1->next = c->next;
1583 free_formula(c);
1584 return(f1);
1585 }
1586 else
1587 return(c);
1588 }
1589 } /* subsume_disj */
1590
1591 /*************
1592 *
1593 * int formula_ident(f1, f2)
1594 *
1595 * Do not permute ANDs, ORs, or like quantifiers.
1596 *
1597 *************/
1598
formula_ident(struct formula * f,struct formula * g)1599 int formula_ident(struct formula *f,
1600 struct formula *g)
1601 {
1602 struct formula *f1, *g1;
1603
1604 if (f->type != g->type)
1605 return(0);
1606 else if (f->type == ATOM_FORM)
1607 return(term_ident(f->t, g->t));
1608 else if (f->type == QUANT_FORM) {
1609 if (f->quant_type != g->quant_type || ! term_ident(f->t, g->t))
1610 return(0);
1611 else
1612 return(formula_ident(f->first_child, g->first_child));
1613 }
1614 else { /* AND_FORM || OR_FORM || IFF_FORM || IMP_FORM || NOT_FORM */
1615 for (f1 = f->first_child, g1 = g->first_child; f1 && g1;
1616 f1 = f1->next, g1 = g1->next)
1617 if (! formula_ident(f1, g1))
1618 return(0);
1619 return(f1 == NULL && g1 == NULL);
1620 }
1621 } /* formula_ident */
1622
1623 /*************
1624 *
1625 * conflict_tautology(f)
1626 *
1627 * If f is an AND_FORM, reduce to empty disjunction (FALSE)
1628 * if conflicting conjuncts occur.
1629 * If f is an OR_FORM, reduce to empty conjunction (TRUE)
1630 * if conflicting disjuncts occur.
1631 *
1632 *************/
1633
conflict_tautology(struct formula * f)1634 void conflict_tautology(struct formula *f)
1635 {
1636 struct formula *f1, *f2, *a1, *a2;
1637 int f1_sign, f2_sign;
1638
1639 /* note possible return from inner loop */
1640
1641 if (f->type == AND_FORM || f->type == OR_FORM) {
1642 for (f1 = f->first_child; f1; f1 = f1->next) {
1643 f1_sign = (f1->type != NOT_FORM);
1644 a1 = (f1_sign ? f1 : f1->first_child);
1645 for (f2 = f1->next; f2; f2 = f2->next) {
1646 f2_sign = (f2->type != NOT_FORM);
1647 if (f1_sign != f2_sign) {
1648 a2 = (f2_sign ? f2 : f2->first_child);
1649 if (formula_ident(a1, a2)) {
1650 f1 = f->first_child;
1651 while (f1) {
1652 f2 = f1;
1653 f1 = f1->next;
1654 zap_formula(f2);
1655 }
1656 f->first_child = NULL;
1657 /* switch types */
1658 f->type = (f->type == AND_FORM ? OR_FORM : AND_FORM);
1659 return;
1660 }
1661 }
1662 }
1663 }
1664 }
1665 } /* conflict_tautology */
1666
1667 /*************
1668 *
1669 * void ts_and_fs(f)
1670 *
1671 * Simplify if f is AND or OR, and an immediate subformula is
1672 * TRUE (empty AND) or FALSE (empty OR).
1673 *
1674 *************/
1675
ts_and_fs(struct formula * f)1676 void ts_and_fs(struct formula *f)
1677 {
1678 struct formula *f1, *f2, *f_prev;
1679 int f_type;
1680
1681 f_type = f->type;
1682 if (f_type != AND_FORM && f_type != OR_FORM)
1683 return;
1684 else {
1685 f_prev = NULL;
1686 f1 = f->first_child;
1687 while (f1 != NULL) {
1688 if ((f1->type == AND_FORM || f1->type == OR_FORM) &&
1689 f1->first_child == NULL) {
1690 if (f_type != f1->type) {
1691 f->type = f1->type;
1692 f1 = f->first_child;
1693 while (f1) {
1694 f2 = f1;
1695 f1 = f1->next;
1696 zap_formula(f2);
1697 }
1698 f->first_child = NULL;
1699 /* switch types */
1700 f->type = (f->type == AND_FORM ? OR_FORM : AND_FORM);
1701 return;
1702 }
1703 else {
1704 if (f_prev == NULL)
1705 f->first_child = f1->next;
1706 else
1707 f_prev->next = f1->next;
1708
1709 f2 = f1;
1710 f1 = f1->next;
1711 free_formula(f2);
1712 }
1713 }
1714 else {
1715 f_prev = f1;
1716 f1 = f1->next;
1717 }
1718 }
1719 }
1720 } /* ts_and_fs */
1721
1722 /*************
1723 *
1724 * static int set_vars_term_2(term, sn)
1725 *
1726 * Called from set_vars_cl_2.
1727 *
1728 *************/
1729
set_vars_term_2(struct term * t,int * sn)1730 static int set_vars_term_2(struct term *t,
1731 int *sn)
1732 {
1733 struct rel *r;
1734 int i, rc;
1735
1736 if (t->type == COMPLEX) {
1737 r = t->farg;
1738 rc = 1;
1739 while (rc && r != NULL) {
1740 rc = set_vars_term_2(r->argval, sn);
1741 r = r->narg;
1742 }
1743 return(rc);
1744 }
1745 else if (t->type == NAME)
1746 return(1);
1747 else {
1748 i = 0;
1749 while (i < MAX_VARS && sn[i] != -1 && sn[i] != t->sym_num)
1750 i++;
1751 if (i == MAX_VARS)
1752 return(0);
1753 else {
1754 if (sn[i] == -1)
1755 sn[i] = t->sym_num;
1756 t->varnum = i;
1757 /* include following to destroy input variable names
1758 t->sym_num = 0;
1759 */
1760 return(1);
1761 }
1762 }
1763 } /* set_vars_term_2 */
1764
1765 /*************
1766 *
1767 * static int set_vars_cl_2(cl) -- give variables var_nums
1768 *
1769 * This is different from set_vars_cl bacause variables have
1770 * already been identified: type==VARIABLE. Identical
1771 * variables have same sym_num.
1772 *
1773 *************/
1774
set_vars_cl_2(struct clause * cl)1775 static int set_vars_cl_2(struct clause *cl)
1776 {
1777 struct literal *lit;
1778 int sn[MAX_VARS];
1779 int i;
1780
1781 for (i=0; i<MAX_VARS; i++)
1782 sn[i] = -1;
1783 lit = cl->first_lit;
1784 while (lit != NULL) {
1785 if (set_vars_term_2(lit->atom, sn))
1786 lit = lit->next_lit;
1787 else
1788 return(0);
1789 }
1790 return(1);
1791 } /* set_vars_cl_2 */
1792
1793 /*************
1794 *
1795 * static struct clause *disj_to_clause(f)
1796 *
1797 *************/
1798
disj_to_clause(struct formula * f)1799 static struct clause *disj_to_clause(struct formula *f)
1800 {
1801 struct formula *f1, *f2;
1802 struct clause *c;
1803 struct literal *lit, *prev;
1804
1805 c = get_clause();
1806 if (f->type == ATOM_FORM || f->type == NOT_FORM) {
1807 lit = get_literal();
1808 lit->sign = (f->type == ATOM_FORM);
1809 lit->atom = (f->type == ATOM_FORM ? f->t : f->first_child->t);
1810 if (f->type == NOT_FORM)
1811 free_formula(f->first_child);
1812 free_formula(f);
1813 lit->atom->occ.lit = lit;
1814 lit->container = c;
1815 mark_literal(lit); /* atoms have varnum > 0 */
1816 c->first_lit = lit;
1817 }
1818 else { /* OR_FORM */
1819 prev = NULL;
1820 f1 = f->first_child;
1821 while (f1) {
1822 f2 = f1;
1823 f1 = f1->next;
1824
1825 lit = get_literal();
1826 lit->sign = (f2->type == ATOM_FORM);
1827 lit->atom = (f2->type == ATOM_FORM ? f2->t : f2->first_child->t);
1828 if (f2->type == NOT_FORM)
1829 free_formula(f2->first_child);
1830 free_formula(f2);
1831 lit->atom->occ.lit = lit;
1832 lit->container = c;
1833 mark_literal(lit); /* atoms have varnum > 0 */
1834
1835 if (prev == NULL)
1836 c->first_lit = lit;
1837 else
1838 prev->next_lit = lit;
1839 prev = lit;
1840 }
1841 free_formula(f);
1842 }
1843
1844 if (set_vars_cl_2(c) == 0) {
1845 char s[500];
1846 print_clause(stdout, c);
1847 sprintf(s, "disj_to_clause, too many variables in clause, max is %d.", MAX_VARS);
1848 abend(s);
1849 }
1850 cl_merge(c); /* merge identical literals */
1851 return(c);
1852 } /* disj_to_clause */
1853
1854 /*************
1855 *
1856 * static struct list *cnf_to_list(f)
1857 *
1858 * Convert a CNF formula to a list of clauses.
1859 * This includes assigning variable numbers to the varnum fileds of VARIABLES.
1860 * An ABEND occurs if a clause has too many variables.
1861 *
1862 *************/
1863
cnf_to_list(struct formula * f)1864 static struct list *cnf_to_list(struct formula *f)
1865 {
1866 struct formula *f1, *f2;
1867 struct list *l;
1868 struct clause *c;
1869
1870 l = get_list();
1871 if (f->type != AND_FORM) {
1872 c = disj_to_clause(f);
1873 append_cl(l, c);
1874 }
1875 else { /* OR_FORM || ATOM_FORM || NOT_FORM */
1876 f1 = f->first_child;
1877 while (f1) {
1878 f2 = f1;
1879 f1 = f1->next;
1880 c = disj_to_clause(f2); /* zaps f2 */
1881 append_cl(l, c);
1882 }
1883 free_formula(f);
1884 }
1885 return(l);
1886 } /* cnf_to_list */
1887
1888 /*************
1889 *
1890 * struct list *clausify(f) -- Skolem/CNF tranformation.
1891 *
1892 * Convert a quantified formula to a list of clauses.
1893 *
1894 *************/
1895
clausify(struct formula * f)1896 struct list *clausify(struct formula *f)
1897 {
1898 struct list *l;
1899
1900 f = nnf(f);
1901 f = skolemize(f);
1902 unique_all(f);
1903 f = zap_quant(f);
1904 rename_syms_formula(f, f);
1905 f = cnf(f);
1906 l = cnf_to_list(f);
1907 return(l);
1908
1909 } /* clausify */
1910
1911 /*************
1912 *
1913 * struct list *clausify_formula_list(fp)
1914 *
1915 * Clausify a set of formulas, and return a list of clauses.
1916 * The set of formulas is deallocated.
1917 *
1918 *************/
1919
clausify_formula_list(struct formula_ptr * fp)1920 struct list *clausify_formula_list(struct formula_ptr *fp)
1921 {
1922 struct list *l, *l1;
1923 struct formula_ptr *fp1, *fp2;
1924
1925 l = get_list();
1926 fp1 = fp;
1927 while (fp1 != NULL) {
1928 if (Flags[FORMULA_HISTORY].val) {
1929 int f_id;
1930 struct clause *c = get_clause();
1931 struct literal *lit = get_literal();
1932 struct ilist *ip1 = get_ilist();
1933 struct ilist *ip2 = get_ilist();
1934 c->first_lit = lit;
1935 lit->sign = 1;
1936 lit->atom = formula_to_term(fp1->f);
1937 assign_cl_id(c);
1938 f_id = c->id;
1939 hide_clause(c);
1940
1941 l1 = clausify(fp1->f);
1942
1943 for (c = l1->first_cl; c; c = c->next_cl) {
1944 ip1 = get_ilist();
1945 ip2 = get_ilist();
1946 c->parents = ip1;
1947 ip1->next = ip2;
1948 ip1->i = CLAUSIFY_RULE;
1949 ip2->i = f_id;
1950 }
1951 }
1952 else
1953 l1 = clausify(fp1->f);
1954
1955 append_lists(l, l1);
1956 fp2 = fp1;
1957 fp1 = fp1->next;
1958 free_formula_ptr(fp2);
1959 }
1960 return(l);
1961 } /* clausify_formula_list */
1962
1963 /*************
1964 *
1965 * struct formula *negation_inward(f)
1966 *
1967 * If f is a negated conjunction, disjunction, or quantified formula,
1968 * move the negation sign in one level.
1969 *
1970 *************/
1971
negation_inward(struct formula * f)1972 struct formula *negation_inward(struct formula *f)
1973 {
1974 struct formula *f1, *f2, *prev, *f_save;
1975
1976 if (f->type == NOT_FORM) {
1977 f1 = f->first_child;
1978 if (f1->type == AND_FORM || f1->type == OR_FORM || f1->type == QUANT_FORM) {
1979 f_save = f->next;
1980 f = negate_formula(f);
1981 f->next = f_save;
1982
1983 if (f->type == AND_FORM || f->type == OR_FORM) {
1984 /* apply DeMorgan's laws */
1985 f->type = (f->type == AND_FORM ? OR_FORM : AND_FORM);
1986 f1 = f->first_child;
1987 prev = NULL;
1988 while (f1) {
1989 f2 = f1;
1990 f1 = f1->next;
1991 f2 = negate_formula(f2);
1992 if (prev)
1993 prev->next = f2;
1994 else
1995 f->first_child = f2;
1996 prev = f2;
1997 }
1998 }
1999 else { /* QUANT_FORM */
2000 f->quant_type = (f->quant_type==ALL_QUANT ? EXISTS_QUANT : ALL_QUANT);
2001 f->first_child = negate_formula(f->first_child);
2002 }
2003
2004 }
2005 }
2006 return(f);
2007 } /* negation_inward */
2008
2009 /*************
2010 *
2011 * struct formula *expand_imp(f)
2012 *
2013 * Change (P -> Q) to (-P | Q).
2014 *
2015 *************/
2016
expand_imp(struct formula * f)2017 struct formula *expand_imp(struct formula *f)
2018 {
2019 if (f->type != IMP_FORM)
2020 return(f);
2021 else {
2022 f->type = OR_FORM;
2023 f->first_child = negate_formula(f->first_child);
2024 return(f);
2025 }
2026 } /* expand_imp */
2027
2028 /*************
2029 *
2030 * struct formula *iff_to_conj(f)
2031 *
2032 * Change (P <-> Q) to ((P -> Q) & (Q -> P)).
2033 *
2034 *************/
2035
iff_to_conj(struct formula * f)2036 struct formula *iff_to_conj(struct formula *f)
2037 {
2038 struct formula *f1, *f2, *f_save;
2039
2040 if (f->type != IFF_FORM)
2041 return(f);
2042 else {
2043 f_save = f->next;
2044
2045 f1 = copy_formula(f);
2046 f->type = f1->type = IMP_FORM;
2047
2048 /* flip args of f1 */
2049
2050 f2 = f1->first_child;
2051 f1->first_child = f2->next;
2052 f2->next = NULL;
2053 f1->first_child->next = f2;
2054
2055 f->next = f1;
2056 f1->next = NULL;
2057
2058 /* build conjunction */
2059 f2 = get_formula();
2060 f2->type = AND_FORM;
2061 f2->first_child = f;
2062
2063 f2->next = f_save;
2064 return(f2);
2065 }
2066 } /* iff_to_conj */
2067
2068 /*************
2069 *
2070 * struct formula *iff_to_disj(f)
2071 *
2072 * Change (P <-> Q) to ((P & Q) | (-Q & -P)).
2073 *
2074 *************/
2075
iff_to_disj(struct formula * f)2076 struct formula *iff_to_disj(struct formula *f)
2077 {
2078 struct formula *f1, *f2, *f_save;
2079
2080 if (f->type != IFF_FORM)
2081 return(f);
2082 else {
2083 f_save = f->next;
2084
2085 f1 = copy_formula(f);
2086 f->type = f1->type = AND_FORM;
2087 f1->first_child->next = negate_formula(f1->first_child->next);
2088 f1->first_child = negate_formula(f1->first_child);
2089
2090 f->next = f1;
2091 f1->next = NULL;
2092
2093 /* build disjunction */
2094 f2 = get_formula();
2095 f2->type = OR_FORM;
2096 f2->first_child = f;
2097
2098 f2->next = f_save;
2099 return(f2);
2100 }
2101 } /* iff_to_disj */
2102
2103 /*************
2104 *
2105 * struct formula *nnf_cnf(f)
2106 *
2107 *************/
2108
nnf_cnf(struct formula * f)2109 struct formula *nnf_cnf(struct formula *f)
2110 {
2111 return(cnf(nnf(f)));
2112 } /* nnf_cnf */
2113
2114 /*************
2115 *
2116 * struct formula *nnf_dnf(f)
2117 *
2118 *************/
2119
nnf_dnf(struct formula * f)2120 struct formula *nnf_dnf(struct formula *f)
2121 {
2122 return(dnf(nnf(f)));
2123 } /* nnf_dnf */
2124
2125 /*************
2126 *
2127 * struct formula *nnf_skolemize(f)
2128 *
2129 *************/
2130
nnf_skolemize(struct formula * f)2131 struct formula *nnf_skolemize(struct formula *f)
2132 {
2133 return(skolemize(nnf(f)));
2134 } /* nnf_skolemize */
2135
2136 /*************
2137 *
2138 * struct formula *clausify_formed(f)
2139 *
2140 *************/
2141
clausify_formed(struct formula * f)2142 struct formula *clausify_formed(struct formula *f)
2143 {
2144 f = nnf(f);
2145 f = skolemize(f);
2146 unique_all(f);
2147 f = zap_quant(f);
2148 rename_syms_formula(f, f);
2149 f = cnf(f);
2150 return(f);
2151 } /* clausify_formed */
2152
2153 /*************
2154 *
2155 * rms_conflict_tautology(f)
2156 *
2157 * If f is an AND_FORM, reduce to empty disjunction (FALSE)
2158 * if conflicting conjuncts occur.
2159 * If f is an OR_FORM, reduce to empty conjunction (TRUE)
2160 * if conflicting disjuncts occur.
2161 *
2162 *************/
2163
rms_conflict_tautology(struct formula * f)2164 void rms_conflict_tautology(struct formula *f)
2165 {
2166 struct formula *f1, *f2;
2167
2168 /* note possible return from inner loop */
2169
2170 if (f->type == AND_FORM) {
2171 for (f1 = f->first_child; f1; f1 = f1->next) {
2172 for (f2 = f1->next; f2; f2 = f2->next) {
2173 if (gen_conflict(f1, f2)) {
2174 f1 = f->first_child;
2175 while (f1) {
2176 f2 = f1;
2177 f1 = f1->next;
2178 zap_formula(f2);
2179 }
2180 f->first_child = NULL;
2181 /* switch types */
2182 f->type = OR_FORM;
2183 return;
2184 }
2185 }
2186 }
2187 }
2188
2189 else if (f->type == OR_FORM) {
2190 for (f1 = f->first_child; f1; f1 = f1->next) {
2191 for (f2 = f1->next; f2; f2 = f2->next) {
2192 if (gen_tautology(f1, f2)) {
2193 f1 = f->first_child;
2194 while (f1) {
2195 f2 = f1;
2196 f1 = f1->next;
2197 zap_formula(f2);
2198 }
2199 f->first_child = NULL;
2200 /* switch types */
2201 f->type = AND_FORM;
2202 return;
2203 }
2204 }
2205 }
2206 }
2207 } /* rms_conflict_tautology */
2208
2209 /*************
2210 *
2211 * struct formula *rms_subsume_conj(c)
2212 *
2213 * Given a conjunction, discard weaker conjuncts.
2214 * This is like deleting subsumed clauses.
2215 * The result is equivalent.
2216 *
2217 *************/
2218
rms_subsume_conj(struct formula * c)2219 struct formula *rms_subsume_conj(struct formula *c)
2220 {
2221 struct formula *f1, *f2, *f3, *prev;
2222
2223 if (c->type != AND_FORM || c->first_child == NULL)
2224 return(c);
2225 else {
2226 /* start with second child */
2227 prev = c->first_child;
2228 f1 = prev->next;
2229 while (f1) {
2230 /* first do forward subsumption of part already processed */
2231 f2 = c->first_child;
2232 while (f2 != f1 && ! gen_subsume(f2, f1))
2233 f2 = f2->next;;
2234 if (f2 != f1) { /* delete f1 */
2235 prev->next = f1->next;
2236 zap_formula(f1);
2237 f1 = prev;
2238 }
2239 else {
2240 /* back subsumption on part already processed */
2241 /* delete all previous that are subsumed by f1 */
2242 f2 = c->first_child;
2243 prev = NULL;
2244 while (f2 != f1) {
2245 if (gen_subsume(f1, f2)) {
2246 if (prev == NULL)
2247 c->first_child = f2->next;
2248 else
2249 prev->next = f2->next;
2250 f3 = f2;
2251 f2 = f2->next;
2252 zap_formula(f3);
2253 }
2254 else {
2255 prev = f2;
2256 f2 = f2->next;
2257 }
2258 }
2259 }
2260 prev = f1;
2261 f1 = f1->next;
2262 }
2263 /* If just one child left, replace input formula with child. */
2264 if (c->first_child->next == NULL) {
2265 f1 = c->first_child;
2266 f1->next = c->next;
2267 free_formula(c);
2268 return(f1);
2269 }
2270 else
2271 return(c);
2272 }
2273 } /* rms_subsume_conj */
2274
2275 /*************
2276 *
2277 * struct formula *rms_subsume_disj(c)
2278 *
2279 * Given a disjunction, discard stronger disjuncts.
2280 * The result is equivalent. This the dual of
2281 * normal clause subsumption.
2282 *
2283 *************/
2284
rms_subsume_disj(struct formula * c)2285 struct formula *rms_subsume_disj(struct formula *c)
2286 {
2287 struct formula *f1, *f2, *f3, *prev;
2288
2289 if (c->type != OR_FORM || c->first_child == NULL)
2290 return(c);
2291 else {
2292 /* start with second child */
2293 prev = c->first_child;
2294 f1 = prev->next;
2295 while (f1) {
2296 /* delete f1 if it subsumes anything previous */
2297 f2 = c->first_child;
2298 while (f2 != f1 && ! gen_subsume(f1, f2))
2299 f2 = f2->next;;
2300 if (f2 != f1) { /* delete f1 */
2301 prev->next = f1->next;
2302 zap_formula(f1);
2303 f1 = prev;
2304 }
2305 else {
2306 /* delete all previous that subsume f1 */
2307 f2 = c->first_child;
2308 prev = NULL;
2309 while (f2 != f1) {
2310 if (gen_subsume(f2, f1)) {
2311 if (prev == NULL)
2312 c->first_child = f2->next;
2313 else
2314 prev->next = f2->next;
2315 f3 = f2;
2316 f2 = f2->next;
2317 zap_formula(f3);
2318 }
2319 else {
2320 prev = f2;
2321 f2 = f2->next;
2322 }
2323 }
2324 }
2325 prev = f1;
2326 f1 = f1->next;
2327 }
2328 /* If just one child left, replace input formula with child. */
2329 if (c->first_child->next == NULL) {
2330 f1 = c->first_child;
2331 f1->next = c->next;
2332 free_formula(c);
2333 return(f1);
2334 }
2335 else
2336 return(c);
2337 }
2338 } /* rms_subsume_disj */
2339
2340 /*************
2341 *
2342 * int free_occurrence(v, f)
2343 *
2344 * Does v have a free occurrence in f?
2345 *
2346 *************/
2347
free_occurrence(struct term * v,struct formula * f)2348 int free_occurrence(struct term *v,
2349 struct formula *f)
2350 {
2351 struct formula *f1;
2352 int free;
2353
2354 switch (f->type) {
2355 case ATOM_FORM:
2356 free = occurs_in(v, f->t);
2357 break;
2358 case NOT_FORM:
2359 case AND_FORM:
2360 case OR_FORM:
2361 case IMP_FORM:
2362 case IFF_FORM:
2363 for (free = 0, f1 = f->first_child; f1 && ! free; f1 = f1->next)
2364 free = free_occurrence(v, f1);
2365 break;
2366 case QUANT_FORM:
2367 if (term_ident(v, f->t))
2368 free = 0;
2369 else
2370 free = free_occurrence(v, f->first_child);
2371 break;
2372 default: free = 0;
2373 }
2374 return(free);
2375
2376 } /* free_occurrence */
2377
2378 /*************
2379 *
2380 * struct formula *rms_distribute_quants(f)
2381 *
2382 * f is universally quantified formula.
2383 * Child is conjunction in RMS.
2384 * Distribute quantifier to conjuncts.
2385 * Return a RMS of f.
2386 *
2387 *************/
2388
rms_distribute_quants(struct formula * f_quant)2389 struct formula *rms_distribute_quants(struct formula *f_quant)
2390 {
2391 struct formula *f_conj, *f1, *f2, *f3;
2392
2393 f_conj = f_quant->first_child;
2394 f3 = NULL;
2395 f1 = f_conj->first_child;
2396 while (f1) {
2397 f2 = get_formula();
2398 f2->type = QUANT_FORM;
2399 f2->quant_type = ALL_QUANT;
2400 f2->first_child = f1;
2401 f2->t = copy_term(f_quant->t);
2402 f1 = f1->next;
2403 f2->first_child->next = NULL;
2404 f2 = rms_quantifiers(f2); /* indirect recursive call */
2405 if (f3)
2406 f3->next = f2;
2407 else
2408 f_conj->first_child = f2;
2409 f3 = f2;
2410 }
2411
2412 zap_term(f_quant->t);
2413 free_formula(f_quant);
2414
2415 flatten_top(f_conj);
2416 rms_conflict_tautology(f_conj);
2417 f_conj = rms_subsume_conj(f_conj);
2418 return(f_conj);
2419
2420 } /* rms_distribute_quants */
2421
2422 /*************
2423 *
2424 * void separate_free(v, f, free, not_free)
2425 *
2426 *************/
2427
separate_free(struct term * v,struct formula * f,struct formula ** p_free,struct formula ** p_not_free)2428 static void separate_free(struct term *v,
2429 struct formula *f,
2430 struct formula **p_free,
2431 struct formula **p_not_free)
2432 {
2433 struct formula *f1, *not_free, *f2, *f3, *prev;
2434
2435 not_free = f2 = f3 = prev = NULL;
2436 f1 = f->first_child;
2437 while (f1) {
2438 f2 = f1;
2439 f1 = f1->next;
2440
2441 if (!free_occurrence(v, f2)) {
2442 f2->next = NULL;
2443 if (not_free)
2444 f3->next = f2;
2445 else
2446 not_free = f2;
2447 f3 = f2;
2448
2449 if (prev == NULL)
2450 f->first_child = f1;
2451 else
2452 prev->next = f1;
2453 }
2454 else
2455 prev = f2;
2456 }
2457
2458 if (f->first_child == NULL) {
2459 *p_free = NULL;
2460 free_formula(f);
2461 }
2462 else if (f->first_child->next == NULL) {
2463 *p_free = f->first_child;
2464 free_formula(f);
2465 }
2466 else
2467 *p_free = f;
2468
2469 if (not_free == NULL)
2470 *p_not_free = NULL;
2471 else if (not_free->next == NULL)
2472 *p_not_free = not_free;
2473 else {
2474 f1 = get_formula();
2475 f1->type = OR_FORM;
2476 f1->first_child = not_free;
2477 *p_not_free = f1;
2478 }
2479 } /* separate_free */
2480
2481 /*************
2482 *
2483 * struct formula *rms_push_free(f)
2484 *
2485 * f is universally quantifierd formula.
2486 * The child of f is a (simple) disjunction in RMS.
2487 * Reduce scopes based on free variables.
2488 * Result is in RMS, either a quantified formula or a disjunction.
2489 *
2490 *************/
2491
rms_push_free(struct formula * f)2492 struct formula *rms_push_free(struct formula *f)
2493 {
2494 struct formula *f2, *free, *not_free;
2495
2496 separate_free(f->t, f->first_child, &free, ¬_free);
2497
2498 if (!free) { /* var doesn't occur free in any subformula. */
2499 abend("rms_push_free has extra quantifier.");
2500 }
2501
2502 if (not_free) {
2503
2504 f->first_child = free;
2505 f = rms_quantifiers(f);
2506 f->next = NULL;
2507 if (not_free->type == OR_FORM) {
2508 /* Install f as last disjunct. */
2509 for (f2 = not_free->first_child; f2->next; f2 = f2->next);
2510 f2->next = f;
2511 f2 = not_free;
2512 }
2513 else {
2514 f2 = get_formula();
2515 f2->type = OR_FORM;
2516 f2->first_child = not_free;
2517 not_free->next = f;
2518 }
2519 /* f2 is disjunction */
2520 rms_conflict_tautology(f2);
2521 f2 = rms_subsume_disj(f2);
2522 return(f2);
2523 }
2524 else
2525 return(f);
2526
2527 } /* rms_push_free */
2528
2529 /*************
2530 *
2531 * struct formula *rms_quantifiers(f)
2532 *
2533 * f is a quantified formula whose child is in RMS.
2534 * This function returns a RMS of f.
2535 *
2536 *************/
2537
rms_quantifiers(struct formula * f)2538 struct formula *rms_quantifiers(struct formula *f)
2539 {
2540 struct formula *f1, *f2, *f_save;
2541 int negate_flag;
2542
2543 f_save = f->next;
2544 f->next = NULL;
2545
2546 if (!free_occurrence(f->t, f->first_child)) {
2547 f1 = f->first_child;
2548 zap_term(f->t);
2549 free_formula(f);
2550 f1->next = f_save;
2551 return(f1);
2552 }
2553
2554 if (f->quant_type == EXISTS_QUANT) {
2555 f = nnf(negate_formula(f));
2556 negate_flag = 1;
2557 /* If f is an OR with and AND child, call rms to make conjunction. */
2558 if (f->first_child->type == OR_FORM) {
2559 for(f1 = f->first_child->first_child;
2560 f1 && f1->type != AND_FORM;
2561 f1 = f1->next);
2562 if (f1)
2563 f->first_child = rms(f->first_child);
2564 }
2565 }
2566 else
2567 negate_flag = 0;
2568
2569 /* Now, "all" is the quantifier, and child is RMS. */
2570
2571 if (f->first_child->type == AND_FORM)
2572 f = rms_distribute_quants(f);
2573 else if (f->first_child->type == OR_FORM)
2574 f = rms_push_free(f);
2575
2576 /* else atomic or negated atomic, so do nothing */
2577
2578 /* f is now not necessarily QUANT_FORM. */
2579
2580 if (negate_flag) {
2581 f = nnf(negate_formula(f));
2582 if (f->type == QUANT_FORM)
2583 f2 = f->first_child;
2584 else
2585 f2 = f;
2586 /* If f2 is an OR with and AND child, call rms to make conjunction. */
2587 if (f2->type == OR_FORM) {
2588 for(f1 = f2->first_child;
2589 f1 && f1->type != AND_FORM;
2590 f1 = f1->next);
2591 if (f1) {
2592 if (f == f2)
2593 f = rms(f2);
2594 else
2595 f->first_child = rms(f2);
2596 }
2597 }
2598 }
2599
2600 f->next= f_save;
2601 return(f);
2602
2603 } /* rms_quantifiers */
2604
2605 /*************
2606 *
2607 * static struct formula *rms_distribute(f) -- rms_distribute OR over AND.
2608 *
2609 * f is an OR node whose subterms are in Reduced MiniScope (RMS).
2610 * This routine returns a RMS of f.
2611 *
2612 *************/
2613
rms_distribute(struct formula * f)2614 static struct formula *rms_distribute(struct formula *f)
2615 {
2616 struct formula *f_new, *f1, *f2, *f3, *f4, *f_prev, *f_save;
2617 int i, j;
2618
2619 f_save = f->next; f->next = NULL;
2620
2621 if (f->type != OR_FORM)
2622 return(f);
2623 else {
2624
2625 flatten_top(f);
2626 rms_conflict_tautology(f);
2627 f = rms_subsume_disj(f);
2628 if (f->type != OR_FORM)
2629 return(f);
2630 else {
2631
2632 /* find first AND subformula */
2633 i = 1;
2634 f_prev = NULL;
2635 for (f1 = f->first_child; f1 && f1->type != AND_FORM; f1 = f1->next) {
2636 i++;
2637 f_prev = f1;
2638 }
2639 if (f1 == NULL)
2640 return(f); /* nothing to rms_distribute */
2641 else {
2642 /* unhook AND */
2643 if (f_prev)
2644 f_prev->next = f1->next;
2645 else
2646 f->first_child = f1->next;
2647 f2 = f1->first_child;
2648 f_new = f1;
2649 f_prev = NULL;
2650 while (f2) {
2651 f3 = f2->next;
2652 if (f3)
2653 f1 = copy_formula(f);
2654 else
2655 f1 = f;
2656 if (i == 1) {
2657 f2->next = f1->first_child;
2658 f1->first_child = f2;
2659 }
2660 else {
2661 j = 1;
2662 for (f4 = f1->first_child; j < i-1; f4 = f4->next)
2663 j++;
2664 f2->next = f4->next;
2665 f4->next = f2;
2666 }
2667 f1 = rms_distribute(f1);
2668 if (f_prev)
2669 f_prev->next = f1;
2670 else
2671 f_new->first_child = f1;
2672 f_prev = f1;
2673 f2 = f3;
2674 }
2675 f_new->next = f_save;
2676 flatten_top(f_new);
2677 rms_conflict_tautology(f_new);
2678 f_new = rms_subsume_conj(f_new);
2679 return(f_new);
2680 }
2681 }
2682 }
2683 } /* rms_distribute */
2684
2685 /*************
2686 *
2687 * struct formula *rms(f) -- convert f to Reduced MiniScope (RMS)
2688 *
2689 *************/
2690
rms(struct formula * f)2691 struct formula *rms(struct formula *f)
2692 {
2693 struct formula *f1, *f2, *f_prev, *f_next, *f_save;
2694
2695 f_save = f->next; f->next = NULL;
2696
2697 if (f->type == AND_FORM || f->type == OR_FORM) {
2698 /* first convert subterms to RMS */
2699 f_prev = NULL;
2700 f1 = f->first_child;
2701 while(f1) {
2702 f_next = f1->next;
2703 f2 = rms(f1);
2704 if (f_prev)
2705 f_prev->next = f2;
2706 else
2707 f->first_child = f2;
2708 f_prev = f2;
2709 f1 = f_next;
2710 }
2711
2712 if (f->type == AND_FORM) {
2713 flatten_top(f);
2714 rms_conflict_tautology(f);
2715 f = rms_subsume_conj(f);
2716 }
2717 else
2718 f = rms_distribute(f); /* flatten and simplify in distribute */
2719 }
2720
2721 else if (f->type == QUANT_FORM) {
2722 f->first_child = rms(f->first_child);
2723 f = rms_quantifiers(f);
2724 }
2725
2726 /* else f is atomic or negated atomic, so do nothing; */
2727
2728 f->next = f_save;
2729 return(f);
2730
2731 } /* rms */
2732
2733 /*************
2734 *
2735 * static void introduce_var_term(t, v, vnum)
2736 *
2737 *************/
2738
introduce_var_term(struct term * t,struct term * v,int vnum)2739 static void introduce_var_term(struct term *t,
2740 struct term *v,
2741 int vnum)
2742 {
2743 struct rel *r;
2744
2745 switch (t->type) {
2746 case NAME:
2747 if (term_ident(t,v)) {
2748 t->type = VARIABLE;
2749 t->varnum = vnum;
2750 t->sym_num = 0;
2751 }
2752 break;
2753 case VARIABLE:
2754 break;
2755 case COMPLEX:
2756 for (r = t->farg; r; r = r->narg)
2757 introduce_var_term(r->argval, v, vnum);
2758 break;
2759 }
2760
2761 } /* introduce_var_term */
2762
2763 /*************
2764 *
2765 * static void introduce_var(f, t, vnum)
2766 *
2767 * In formula f, replace all free occurrences of t with a variable
2768 * (set type to VARIABLE) with number vnum.
2769 *
2770 *************/
2771
introduce_var(struct formula * f,struct term * t,int vnum)2772 static void introduce_var(struct formula *f,
2773 struct term *t,
2774 int vnum)
2775 {
2776 struct formula *f1;
2777
2778 switch (f->type) {
2779 case ATOM_FORM:
2780 introduce_var_term(f->t, t, vnum);
2781 break;
2782 case AND_FORM:
2783 case OR_FORM:
2784 case NOT_FORM:
2785 for (f1 = f->first_child; f1; f1 = f1->next)
2786 introduce_var(f1, t, vnum);
2787 break;
2788 case QUANT_FORM:
2789 if (!term_ident(t, f->t))
2790 introduce_var(f->first_child, t, vnum);
2791 break;
2792 default:
2793 abend("introduce_var, bad formula.");
2794 }
2795
2796 } /* introduce_var */
2797
2798 /*************
2799 *
2800 * struct formula *renumber_unique(f, vnum)
2801 *
2802 * f is NNF, and all quantifiers are unique.
2803 * This function renumbers variables, starting with *vnum_p and
2804 * removes quantifiers.
2805 *
2806 *************/
2807
renumber_unique(struct formula * f,int * vnum_p)2808 struct formula *renumber_unique(struct formula *f,
2809 int *vnum_p)
2810 {
2811 struct formula *f1, *f2, *f_prev, *f_next;
2812
2813 switch (f->type) {
2814 case ATOM_FORM:
2815 return(f);
2816 case AND_FORM:
2817 case OR_FORM:
2818 case NOT_FORM:
2819 f_prev = NULL;
2820 f1 = f->first_child;
2821 while(f1) {
2822 f_next = f1->next;
2823 f2 = renumber_unique(f1, vnum_p);
2824 if (f_prev)
2825 f_prev->next = f2;
2826 else
2827 f->first_child = f2;
2828 f_prev = f2;
2829 f1 = f_next;
2830 }
2831 return(f);
2832 case QUANT_FORM:
2833 f1 = f->first_child;
2834 introduce_var(f1, f->t, *vnum_p);
2835 (*vnum_p)++;
2836 if (*vnum_p == MAX_VARS) {
2837 abend("renumber_unique, too many vars.");
2838 }
2839 f1->next = f->next;
2840 f->first_child = NULL;
2841 zap_formula(f);
2842 return(renumber_unique(f1, vnum_p));
2843 }
2844
2845 abend("renumber_unique, bad formula.");
2846 return(f); /* to quiet lint */
2847 } /* renumber_unique */
2848
2849 /*************
2850 *
2851 * int gen_subsume_rec(c, cs, d, ds, tr_p) -- does c gen_subsume_rec d?
2852 *
2853 * This is generalized subsumption on quantified formulas. It is
2854 * not as complete as the Prolog version, because there is no
2855 * backtracking to try alternatives in cases 3 and 4 below.
2856 *
2857 *************/
2858
gen_subsume_rec(struct formula * c,struct context * cs,struct formula * d,struct context * ds,struct trail ** tr_p)2859 int gen_subsume_rec(struct formula *c,
2860 struct context *cs,
2861 struct formula *d,
2862 struct context *ds,
2863 struct trail **tr_p)
2864 {
2865 struct formula *f;
2866
2867 /* The order of these tests is important. For example, if */
2868 /* the last test is moved to the front, c=(p|q) will not */
2869 /* subsume d=(p|q|r). */
2870
2871 if (c->type == OR_FORM) { /* return(each c_i subsumes d) */
2872 for (f = c->first_child; f && gen_subsume_rec(f, cs, d, ds, tr_p); f = f->next);
2873 return(f == NULL);
2874 }
2875 else if (d->type == AND_FORM) { /* return(c subsumes each d_i) */
2876 for (f = d->first_child; f && gen_subsume_rec(c, cs, f, ds, tr_p); f = f->next);
2877 return(f == NULL);
2878 }
2879 else if (c->type == AND_FORM) { /* return(one c_i subsumes d) */
2880 for (f = c->first_child; f && ! gen_subsume_rec(f, cs, d, ds, tr_p); f = f->next);
2881 return(f != NULL);
2882 }
2883 else if (d->type == OR_FORM) { /* return(c subsumes one d_i) */
2884 for (f = d->first_child; f && ! gen_subsume_rec(c, cs, f, ds, tr_p); f = f->next);
2885 return(f != NULL);
2886 }
2887 else if (c->type != d->type)
2888 return(0);
2889 else if (c->type == NOT_FORM)
2890 return(unify(c->first_child->t, cs, d->first_child->t, ds, tr_p));
2891 else /* both ATOMs */
2892 return(unify(c->t, cs, d->t, ds, tr_p));
2893
2894 } /* gen_subsume_rec */
2895
2896 /*************
2897 *
2898 * int gen_subsume(c, d) -- generalized subsumption on RMS formulas.
2899 *
2900 * If 1 is returned, (c -> d) holds.
2901 *
2902 *************/
2903
gen_subsume(struct formula * c,struct formula * d)2904 int gen_subsume(struct formula *c,
2905 struct formula *d)
2906 {
2907 struct formula *c1, *d1;
2908 int result, i;
2909 struct context *cs, *ds;
2910 struct trail *tr;
2911
2912 Sk_const_num = Sk_func_num = 0;
2913 i = 6;
2914 c1 = renumber_unique(skolemize(copy_formula(c)),&i);
2915 i = 6;
2916 d1 = renumber_unique(anti_skolemize(copy_formula(d)),&i);
2917
2918 cs = get_context();
2919 ds = get_context();
2920 tr = NULL;
2921
2922 result = gen_subsume_rec(c1, cs, d1, ds, &tr);
2923 clear_subst_1(tr);
2924 free_context(cs);
2925 free_context(ds);
2926 zap_formula(c1);
2927 zap_formula(d1);
2928 return(result);
2929 } /* gen_subsume */
2930
2931 /*************
2932 *
2933 * int gen_conflict(c, d)
2934 *
2935 * Try to show (c & d) inconsistent by showing (c -> -d).
2936 *
2937 * If 1 is returned, (c & d) is inconsistent.
2938 *
2939 *************/
2940
gen_conflict(struct formula * c,struct formula * d)2941 int gen_conflict(struct formula *c,
2942 struct formula *d)
2943 {
2944 struct formula *c1, *d1;
2945 int result, i;
2946 struct context *cs, *ds;
2947 struct trail *tr;
2948
2949 Sk_const_num = Sk_func_num = 0;
2950 i = 6;
2951 c1 = renumber_unique(skolemize(copy_formula(c)),&i);
2952 i = 6;
2953 /* can skip nnf of negate_formula, because anti-skolemize re-negates */
2954 d1 = renumber_unique(anti_skolemize(negate_formula(copy_formula(d))),&i);
2955
2956 cs = get_context();
2957 ds = get_context();
2958 tr = NULL;
2959
2960 result = gen_subsume_rec(c1, cs, d1, ds, &tr);
2961 clear_subst_1(tr);
2962 free_context(cs);
2963 free_context(ds);
2964 zap_formula(c1);
2965 zap_formula(d1);
2966 return(result);
2967 } /* gen_conflict */
2968
2969 /*************
2970 *
2971 * int gen_tautology(c, d)
2972 *
2973 * Try to show (c | d) a tautology by showing (-c -> d).
2974 *
2975 * If 1 is returned, (c | d) is a tautology.
2976 *
2977 *************/
2978
gen_tautology(struct formula * c,struct formula * d)2979 int gen_tautology(struct formula *c,
2980 struct formula *d)
2981 {
2982 struct formula *c1, *d1;
2983 int result, i;
2984 struct context *cs, *ds;
2985 struct trail *tr;
2986
2987 Sk_const_num = Sk_func_num = 0;
2988 i = 6;
2989 c1 = renumber_unique(skolemize(nnf(negate_formula(copy_formula(c)))),&i);
2990 i = 6;
2991 d1 = renumber_unique(anti_skolemize(copy_formula(d)),&i);
2992
2993 cs = get_context();
2994 ds = get_context();
2995 tr = NULL;
2996
2997 result = gen_subsume_rec(c1, cs, d1, ds, &tr);
2998 clear_subst_1(tr);
2999 free_context(cs);
3000 free_context(ds);
3001 zap_formula(c1);
3002 zap_formula(d1);
3003 return(result);
3004 } /* gen_tautology */
3005
3006 /*************
3007 *
3008 * struct formula *rms_cnf(f)
3009 *
3010 *************/
3011
rms_cnf(struct formula * f)3012 struct formula *rms_cnf(struct formula *f)
3013 {
3014 return(rms(nnf(f)));
3015 } /* rms_cnf */
3016
3017 /*************
3018 *
3019 * struct formula *rms_dnf(f)
3020 *
3021 *************/
3022
rms_dnf(struct formula * f)3023 struct formula *rms_dnf(struct formula *f)
3024 {
3025 return(nnf(negate_formula(rms(nnf(negate_formula(f))))));
3026 } /* rms_dnf */
3027
3028 /*************
3029 *
3030 * struct formula *push_free(f)
3031 *
3032 * f is universally quantifierd formula
3033 * The child of f is a disjunction.
3034 * Reduce scopes 1 level based on free variables.
3035 * Result is either a quantified formula or a disjunction.
3036 *
3037 *************/
3038
push_free(struct formula * f)3039 static struct formula *push_free(struct formula *f)
3040 {
3041 struct formula *f2, *free, *not_free;
3042
3043 separate_free(f->t, f->first_child, &free, ¬_free);
3044
3045 if (!free) { /* var doesn't occur free in any subformula. */
3046 not_free->next = f->next;
3047 free_term(f->t);
3048 free_formula(f);
3049 return(not_free);
3050 }
3051
3052 else if (!not_free) /* var occurs free in all subformulas */
3053 return(f);
3054
3055 else { /* at least one of each */
3056
3057 f->first_child = free;
3058 f->next = NULL;
3059 if (not_free->type == OR_FORM) {
3060 /* Install f as last disjunct. */
3061 for (f2 = not_free->first_child; f2->next; f2 = f2->next);
3062 f2->next = f;
3063 f2 = not_free;
3064 }
3065 else {
3066 f2 = get_formula();
3067 f2->type = OR_FORM;
3068 f2->first_child = not_free;
3069 not_free->next = f;
3070 }
3071 /* f2 is disjunction */
3072 return(f2);
3073 }
3074
3075 } /* push_free */
3076
3077 /*************
3078 *
3079 * struct formula *distribute_quantifier(f)
3080 *
3081 * If f is (all x (f1 & ...)) or (exists x (f1 | ...)),
3082 * distribute the quantifier to the subformulas (and delete
3083 * the quantifier if the subformula has no free occurrences
3084 * of the variable.
3085 *
3086 *************/
3087
distribute_quantifier(struct formula * f)3088 struct formula *distribute_quantifier(struct formula *f)
3089 {
3090 struct formula *f1, *f2, *f3, *prev, *save_next;
3091
3092 if (f->type == QUANT_FORM) {
3093 save_next = f->next;
3094 f->next = NULL;
3095 f1 = f->first_child;
3096 if ((f->quant_type == ALL_QUANT && f1->type == AND_FORM) ||
3097 (f->quant_type == EXISTS_QUANT && f1->type == OR_FORM)) {
3098
3099 for (f2=f1->first_child, prev=NULL; f2; prev=f2, f2=f2->next) {
3100 if (free_occurrence(f->t, f2)) {
3101 f3 = get_formula();
3102 f3->type = QUANT_FORM;
3103 f3->quant_type = f->quant_type;
3104 f3->t = copy_term(f->t); /* variable */
3105 f3->next = f2->next;
3106 f3->first_child = f2;
3107 f2->next = NULL;
3108 if (prev)
3109 prev->next = f3;
3110 else
3111 f1->first_child = f3;
3112 f2 = f3;
3113 }
3114 }
3115 free_term(f->t);
3116 free_formula(f);
3117 f = f1;
3118 }
3119 else if (f->quant_type == ALL_QUANT && f1->type == OR_FORM) {
3120 f = push_free(f);
3121 }
3122 else if (f->quant_type == EXISTS_QUANT && f1->type == AND_FORM) {
3123 f = nnf(negate_formula(f));
3124 f = push_free(f);
3125 f = nnf(negate_formula(f));
3126 }
3127
3128 f->next = save_next;
3129 }
3130 return(f);
3131 } /* distribute_quantifier */
3132
3133