1 /*
2  *  case.c - case splitting
3  *
4  */
5 
6 #include "header.h"
7 
8 #ifdef TP_FORK  /* for calls to fork() and wait() */
9 #  include <sys/types.h>
10 #  include <sys/wait.h>
11 #  include <unistd.h>
12 #endif
13 
14 #define MAX_SPLIT_DEPTH  255  /* see SPLIT_DEPTH in options.c */
15 
16 #define POS_CLAUSE 1
17 #define NEG_CLAUSE 2
18 #define MIX_CLAUSE 3
19 
20 #define FORK_FAIL  0
21 #define PARENT     1
22 #define CHILD      2
23 #define CHILD_FAIL 3
24 
25 /* Current_case is a sequence of integers, e.g., Case [2.1.3.2]. */
26 
27 struct ilist *Current_case = NULL;
28 
29 /* The literal_data structure is used for atom splitting.  When
30  * deciding which atom to split, all ground literal occurrences
31  * are considered, and for each, the data in the structure is
32  * collected.  See routines get_literal_data(), compare_literal_data(),
33  * find_atom_to_split().
34  */
35 
36 struct literal_data {
37   struct term *atom;
38   int sign;
39   int equality;
40   int atom_weight;
41   int clause_id;
42   int clause_weight;
43   int clause_type;
44   int clause_variables;
45   int pos_occurrences;
46   int neg_occurrences;
47   int pos_binary_occurrences;
48   int neg_binary_occurrences;
49 };
50 
51 /* These are file descriptors (from pipe()), which are used to
52  * communicate with child and parent processes.  The main use is
53  * for a child to tell its parent what case assumptions were
54  * used for a refutation, which allows ancestors to sometimes
55  * skip further cases.  See assumps_to_parent(), prover_forks().
56  */
57 
58 int To_parent,   From_parent;    /* pipe for communicating with parent */
59 int To_children, From_children;  /* pipe for communicating with children */
60 
61 /*************
62  *
63  *   splitting() -- Is slitting enabled?
64  *
65  *************/
66 
splitting(void)67 int splitting(void)
68 {
69   return(Flags[SPLIT_CLAUSE].val ||
70 	 Flags[SPLIT_ATOM].val ||
71 	 Flags[SPLIT_WHEN_GIVEN].val);
72 }  /* splitting */
73 
74 /*************
75  *
76  *   max_split_depth() -- Return the maximum depth allowed for splitting.
77  *
78  *************/
79 
max_split_depth(void)80 int max_split_depth(void)
81 {
82   return(MAX_SPLIT_DEPTH);
83 }  /* max_split_depth */
84 
85 /*************
86  *
87  *   splitable_literal(clause, lit) -- Is the atom splittable?
88  *
89  *   The test is done on an occurrence of a literal.
90  *
91  *************/
92 
splitable_literal(struct clause * c,struct literal * l)93 int splitable_literal(struct clause *c,
94 		      struct literal *l)
95 {
96   if (num_literals(c) < 2 || !ground(l->atom))
97     return 0;
98   else {
99     int ok = 1;
100     if (ok && Flags[SPLIT_POS].val)
101       ok = pos_clause(c);
102     if (ok && Flags[SPLIT_NEG].val)
103       ok = neg_clause(c);
104     if (ok && Flags[SPLIT_NONHORN].val)
105       ok = l->sign && !horn_clause(c);
106     return ok;
107   }
108 }  /* splitable_literal */
109 
110 /*************
111  *
112  *   compare_literal_data(d1, d2) -- Compare two splittable literal occurrences.
113  *
114  *   Return the better literal_data.  If neither is better, return d1.
115  *
116  *************/
117 
compare_literal_data(struct literal_data d1,struct literal_data d2)118 static struct literal_data compare_literal_data(struct literal_data d1,
119 					 struct literal_data d2)
120 {
121   if (d1.atom == NULL)
122     return d2;
123   else if (d2.atom == NULL)
124     return d1;
125   else if (Flags[SPLIT_POPULAR].val) {
126     if (d2.pos_occurrences + d2.neg_occurrences >
127 	d1.pos_occurrences + d1.neg_occurrences)
128       return d2;
129     else
130       return d1;
131   }
132   else {
133     if (d2.clause_weight < d1.clause_weight)
134       return d2;
135     else if (d1.clause_weight < d2.clause_weight)
136       return d1;
137     else if (d2.atom_weight < d1.atom_weight)
138       return d2;
139     else
140       return d1;
141   }
142 }  /* compare_literal_data */
143 
144 /*************
145  *
146  *   splitable_clause(c) -- Is this clause splittable?
147  *
148  *************/
149 
splitable_clause(struct clause * c)150 int splitable_clause(struct clause *c)
151 {
152   if (!ground_clause(c))
153     return 0;
154   else if (num_literals(c) < 2)
155     return 0;
156   else {
157     int ok = 1;
158     if (ok && Flags[SPLIT_POS].val)
159       ok = pos_clause(c);
160     if (ok && Flags[SPLIT_NEG].val)
161       ok = neg_clause(c);
162     if (ok && Flags[SPLIT_NONHORN].val)
163       ok = !horn_clause(c);
164     return ok;
165   }
166 }  /* splitable_clause */
167 
168 /*************
169  *
170  *   compare_splitable_clauses(c, d) -- Compare two splittable clauses.
171  *
172  *   Return the better clause.  If neither is better, return c.
173  *
174  *************/
175 
compare_splitable_clauses(struct clause * c,struct clause * d)176 struct clause *compare_splitable_clauses(struct clause *c,
177 					 struct clause *d)
178 {
179   if (c == NULL)
180     return d;
181   else if (d == NULL)
182     return c;
183   else if (Flags[SPLIT_MIN_MAX].val) {
184 
185     /* Return the clause with the smaller maximum literal.
186      * If maxes are the same, return the smaller clause
187      * if clauses are the same weight, return c.
188      */
189 
190     int cm = max_literal_weight(c, Weight_pick_given_index);
191     int dm = max_literal_weight(c, Weight_pick_given_index);
192     /* printf("maxes: %4d=%4d, %4d=%4d\n", c->id, cm, d->id, dm); */
193     if (cm < dm) {
194       return c;
195     }
196     else if (dm < cm) {
197       return d;
198     }
199     else
200       return (d->pick_weight < c->pick_weight ? d : c);
201   }
202   else {
203     /* Return smaller clause; if clauses are the same weight, return c. */
204     return (d->pick_weight < c->pick_weight ? d : c);
205   }
206 }  /* compare_splitable_clauses */
207 
208 /*************
209  *
210  *   init_literal_data(p) -- Initialize a literal_data structure.
211  *
212  *************/
213 
init_literal_data(struct literal_data * p)214 static void init_literal_data(struct literal_data *p)
215 {
216   p->atom = NULL;
217 }  /* init_literal_data */
218 
219 /*************
220  *
221  *   p_literal_data(data) -- Print a literal_data structure to stdout.
222  *
223  *************/
224 
p_literal_data(struct literal_data data)225 static void p_literal_data(struct literal_data data)
226 {
227   printf("Atom: "); print_term(stdout, data.atom);
228   printf(" sign=%d, equality=%d, atom_wt=%d, cl_id=%d, cl_wt=%d, cl_type=%d, variables=%d, pos=%d, neg=%d, pos_binary=%d, neg_binary=%d\n",
229 	 data.sign,data.equality,data.atom_weight,data.clause_id,
230 	 data.clause_weight,
231 	 data.clause_type,data.clause_variables,
232 	 data.pos_occurrences,data.neg_occurrences,
233 	 data.pos_binary_occurrences,data.neg_binary_occurrences);
234 }  /* p_literal_data */
235 
236 /*************
237  *
238  *   get_literal_data(lit, p)
239  *
240  *   Given a ground literal occurrence, fill in the data.
241  *
242  *************/
243 
get_literal_data(struct literal * lit,struct literal_data * p)244 static void get_literal_data(struct literal *lit,
245 		      struct literal_data *p)
246 {
247   struct clause *c = lit->container;
248   struct term *a;
249   struct fpa_tree *ut;
250   int n, m;
251 
252   p->atom = lit->atom;
253   p->sign = lit->sign;
254   p->equality = is_eq(lit->atom->sym_num);
255   p->atom_weight = weight(lit->atom, Weight_pick_given_index);
256 
257   p->clause_id = c->id;
258   p->clause_weight = weight_cl(c, Weight_pick_given_index);
259   p->clause_variables = distinct_vars(c);
260   if (pos_clause(c))
261     p->clause_type = POS_CLAUSE;
262   else if (neg_clause(c))
263     p->clause_type = NEG_CLAUSE;
264   else
265     p->clause_type = MIX_CLAUSE;
266 
267   if (!Flags[SPLIT_POPULAR].val) {
268     p->pos_occurrences = 0;
269     p->neg_occurrences = 0;
270     p->pos_binary_occurrences = 0;
271     p->neg_binary_occurrences = 0;
272   }
273   else {
274     ut = build_tree(lit->atom, INSTANCE, Parms[FPA_LITERALS].val, Fpa_pos_lits);
275     n = 0; m = 0;
276     a = next_term(ut, 0);
277     while (a != NULL) {
278       n++;
279       if (num_literals(a->occ.lit->container) == 2)
280 	m++;
281       a = next_term(ut, 0);
282     }
283     p->pos_occurrences = n;
284     p->pos_binary_occurrences = m;
285 
286     ut = build_tree(lit->atom, INSTANCE, Parms[FPA_LITERALS].val, Fpa_neg_lits);
287     n = 0; m = 0;
288     a = next_term(ut, 0);
289     while (a != NULL) {
290       n++;
291       if (num_literals(a->occ.lit->container) == 2)
292 	m++;
293       a = next_term(ut, 0);
294     }
295     p->neg_occurrences = n;
296     p->neg_binary_occurrences = m;
297   }
298 }  /* get_literal_data */
299 
300 /*************
301  *
302  *   print_case() -- print the current case, e.g., [2.1.3], to a file
303  *
304  *************/
305 
print_case(FILE * fp)306 void print_case(FILE *fp)
307 {
308   struct ilist *ip;
309   fprintf(fp, "[");
310   for (ip = Current_case; ip; ip = ip->next)
311     fprintf(fp, "%d%s", ip->i, ip->next == NULL ? "" : ".");
312   fprintf(fp, "]");
313 }  /* print_case */
314 
315 /*************
316  *
317  *   p_case()
318  *
319  *************/
320 
p_case(void)321 void p_case(void)
322 {
323   print_case(stdout);
324 }  /* p_case */
325 
326 /*************
327  *
328  *   print_case_n() -- Like print_case, but add the argument.
329  *
330  *************/
331 
print_case_n(FILE * fp,int n)332 void print_case_n(FILE *fp,
333 		  int n)
334 {
335   struct ilist *ip;
336   fprintf(fp, "[");
337   for (ip = Current_case; ip; ip = ip->next)
338     fprintf(fp, "%d.", ip->i);
339   fprintf(fp, "%d]", n);
340 }  /* print_case_n */
341 
342 /*************
343  *
344  *   p_case_n()
345  *
346  *************/
347 
p_case_n(int n)348 void p_case_n(int n)
349 {
350   print_case_n(stdout, n);
351 }  /* p_case_n */
352 
353 /*************
354  *
355  *   p_assumption_depths()
356  *
357  *************/
358 
p_assumption_depths(char assumptions[])359 void p_assumption_depths(char assumptions[])
360 {
361 #if 0
362   int i;
363   printf("Assumptions at the following depths were used to refute this branch:");
364   for (i = 0; i <= MAX_SPLIT_DEPTH; i++) {
365     if (assumptions[i])
366       printf("  %d", i);
367   }
368   printf(".\n");
369 #endif
370 }  /* p_assumption_depths */
371 
372 /*************
373  *
374  *   current_case() -- Return Current_case.
375  *
376  *************/
377 
current_case(void)378 struct ilist *current_case(void)
379 {
380   return(Current_case);
381 }  /* current_case */
382 
383 /*************
384  *
385  *   add_subcase(i) -- Append an integer to Current_case.
386  *
387  *************/
388 
add_subcase(int i)389 void add_subcase(int i)
390 {
391   struct ilist *p1, *p2;
392 
393   p1 = get_ilist();
394   p1->i = i;
395   if (Current_case == NULL)
396     Current_case = p1;
397   else {
398     for (p2 = Current_case; p2->next != NULL; p2 = p2->next);
399     p2->next = p1;
400   }
401 }  /* add_subcase */
402 
403 /*************
404  *
405  *   case_depth() -- What is the depth of the current case?
406  *
407  *************/
408 
case_depth(void)409 int case_depth(void)
410 {
411   return ilist_length(Current_case);
412 }  /* case_depth */
413 
414 /*************
415  *
416  *   find_clause_to_split()
417  *
418  *   Go through Usable, then Sos, and find the best splittable clause.
419  *
420  *************/
421 
find_clause_to_split(void)422 struct clause *find_clause_to_split(void)
423 {
424   struct clause *c;
425   struct clause *best_so_far = NULL;
426 
427   for (c = Usable->first_cl; c != NULL; c = c->next_cl) {
428     if (splitable_clause(c)) {
429       best_so_far = compare_splitable_clauses(best_so_far, c);
430     }
431   }
432 
433   for (c = Sos->first_cl; c != NULL; c = c->next_cl) {
434     if (splitable_clause(c)) {
435       best_so_far = compare_splitable_clauses(best_so_far, c);
436     }
437   }
438 
439   return(best_so_far);  /* may be NULL */
440 
441 }  /* find_clause_to_split */
442 
443 /*************
444  *
445  *   find_atom_to_split()
446  *
447  *   Go through all literal occurrences in Usable+Sos, and return
448  *   the atom of the best splittable literal occurrence.
449  *
450  *************/
451 
find_atom_to_split(void)452 struct term *find_atom_to_split(void)
453 {
454   if (Split_atoms != NULL) {
455     int i;
456     struct term *t;
457 
458     /* Split_atoms is a proper list.  If the case_depth is n,
459      * return the n-th member of split_atoms.
460      */
461     for (t = Split_atoms, i = 0;
462 	 t->sym_num != Nil_sym_num && i < case_depth();
463 	 t = t->farg->narg->argval, i++);
464     return (t->sym_num == Nil_sym_num ? NULL : t->farg->argval);
465   }
466   else {
467     struct clause *c;
468     struct literal *lit;
469     struct literal_data min, curr;
470 
471     init_literal_data(&min);
472 
473     for (c = Usable->first_cl; c != NULL; c = c->next_cl) {
474       for (lit = c->first_lit; lit != NULL; lit = lit->next_lit) {
475 	if (splitable_literal(c, lit)) {
476 	  get_literal_data(lit, &curr);
477 	  min = compare_literal_data(min, curr);
478 	}
479       }
480     }
481 
482     for (c = Sos->first_cl; c != NULL; c = c->next_cl) {
483       for (lit = c->first_lit; lit != NULL; lit = lit->next_lit) {
484 	if (splitable_literal(c, lit)) {
485 	  get_literal_data(lit, &curr);
486 	  min = compare_literal_data(min, curr);
487 	}
488       }
489     }
490     return min.atom;  /* NULL if no ground lits found */
491   }
492 }  /* find_atom_to_split */
493 
494 /*************
495  *
496  *   prover_forks(int n, int *ip, char assumptions[])
497  *
498  *   This is the guts of the splitting.  It is used for both clause
499  *   splitting and atom splitting.  Parameter n tells how many cases
500  *   to do.  This routine also takes care of skipping redundant cases
501  *   when assumptions are not used.  For example, if we split on
502  *   clause p|q, and the p case is refuted without using p, then we
503  *   skip the q case.
504  *
505  *   This routine does not return when a child returns without
506  *   a proof.  When this happens, we just exit,
507  *   sending the same exit code to the parent.
508  *
509  *   When this routine does return to its caller, the return value is:
510  *
511  *     CHILD       Return as child process ready to do its case.
512  *                 Also, integer *ip is set to the case number.
513  *     PARENT      Return as parent process---all children succeeded.
514  *                 Also, fill in the Boolean array assumptions, which
515  *                 tells which ancestor case assumptions were used to
516  *                 refute the child cases.
517  *     FORK_FAIL   Operating system would not allow process to fork.
518  *     CHILD_FAIL  A child did not exit normally (WIFEXITED(status) nonzero).
519  *
520  *************/
521 
prover_forks(int n,int * ip,char assumptions[])522 int prover_forks(int n,
523 		 int *ip,
524 		 char assumptions[])
525 {
526 #ifndef TP_FORK
527   return FORK_FAIL;
528 #else
529   int child_status, rc;
530   int parent = 1;
531   int i = 1;
532   int fd[2];
533   char assumptions_descendents[MAX_SPLIT_DEPTH+1];
534   int j;
535 
536   for (j = 0; j <= MAX_SPLIT_DEPTH; j++)
537     assumptions[j] = 0;
538 
539   /* Set up pipe for communicating with children.  The child processes
540    * will inherit these values and immediately use them to set up a
541    * pipe to the parent (that is, copy them to To_parent and From_parent).
542    */
543 
544   rc = pipe(fd); From_children = fd[0]; To_children = fd[1];
545   if (rc != 0) {
546     return FORK_FAIL;
547   }
548 
549   while (i <= n && parent) {
550     fflush(stdout); fflush(stderr);
551     rc = fork();
552     if (rc < 0) {
553       return FORK_FAIL;
554     }
555     else if (rc > 0) {
556       /* This is the parent process */
557       int depth = case_depth();
558 
559       wait(&child_status);
560       if (WIFEXITED(child_status)) {
561 	int child_exit_code = WEXITSTATUS(child_status);
562 
563 	if (child_exit_code==PROOF_EXIT) {
564 	  /* all is well---the child proved its case */
565 	  printf("Refuted case ");
566 	  p_case_n(i);
567 	  printf(".\n");
568 	  fflush(stdout);
569 
570 	  if (Flags[REALLY_DELETE_CLAUSES].val) {
571 	    /* Really_delete_clauses is incompatable with the assumption
572 	       redundancy check.  We'll just go on to the next case
573 	       in stead of checking if the assumption for the previous
574 	       case was used for the refutation.
575 	    */
576 	    i++;
577 	  }
578 	  else {
579 	    rc = read(From_children, assumptions_descendents,MAX_SPLIT_DEPTH+1);
580 	    if (assumptions_descendents[depth+1])
581 	      i++;
582 	    else if (i == n)
583 	      i++;  /* assumption for last case was not used */
584 
585 	    else {
586 
587 	      printf("\nThe Assumption for case ");
588 	      p_case_n(i);
589 	      printf(" was not used;\n");
590 	      printf("therefore we skip case%s", (i == n-1 ? ": " : "s:"));
591 	      for (j = i+1; j <= n; j++) {
592 		printf(" ");
593 		p_case_n(j);
594 	      }
595 	      printf(".\n");
596 
597 	      i = n+1;
598 	    }
599 
600 	    /* "or" in the assumptions used. */
601 	    for (j = 0; j <= depth; j++)
602 	      assumptions[j] = (assumptions[j] | assumptions_descendents[j]);
603 	  }
604 	}  /* child found proof */
605 	else {
606 	  /* Child exited without a proof.  Exit with same code to parent. */
607 	  output_stats(stdout, Parms[STATS_LEVEL].val);
608 	  printf("\nProcess %d finished %s", my_process_id(), get_time());
609 	  exit(child_exit_code);
610 	}
611       }  /* WIFEXITED */
612       else {
613 	/* Child fails for some other reason. */
614 	return CHILD_FAIL;
615       }
616     }  /* if parent */
617 
618     else {
619       /* This is the child process. */
620       /* Set up pipe to parent. */
621       To_parent = To_children; From_parent = From_children;
622       /* Exit loop and do the case. */
623       parent = 0;
624     }
625   } /* while */
626 
627   *ip = i;
628   return (parent ? PARENT : CHILD);
629 #endif
630 }  /* prover_forks */
631 
632 /*************
633  *
634  *   split_clause(c)
635  *
636  *   If (c == NULL), look for a clause to split.
637  *   If (c != NULL), split on c.
638  *
639  *   If success (i.e., split, and each child refutes its case), exit process.
640  *
641  *   Return value:
642  *        0: no split
643  *        1: split, child returns
644  *        2: split, parent returns failure (this might not be used)
645  *
646  *************/
647 
split_clause(struct clause * giv_cl)648 int split_clause(struct clause *giv_cl)
649 {
650 #ifndef TP_FORK
651   return 0;
652 #else
653   struct clause *c;
654   char assumptions[MAX_SPLIT_DEPTH+1];
655 
656   if (giv_cl == NULL)
657     c = find_clause_to_split();
658   else
659     c = giv_cl;
660 
661   if (c == NULL) {
662     printf("\nI tried to split, but I could not find a suitable clause.\n");
663     return 0;
664   }
665   else {
666     int rc, n, case_number;
667 
668     printf("\nSplitting on clause "); p_clause(c);
669     n = num_literals(c);
670     rc = prover_forks(n, &case_number, assumptions);
671 
672     if (rc == FORK_FAIL) {
673       printf("Case splitting (fork) failed.  Returning to search.\n");
674       return 0;
675     }
676     else if (rc == PARENT) {
677       if (Current_case == NULL) {
678 	printf("\nThat finishes the proof of the theorem.\n");
679 	fprintf(stderr, "%c\nThat finishes the proof of the theorem.\n", Bell);
680       }
681       else {
682 	/* Tell the parent the assumptions used to refute this
683 	 * branch.  We don't send the actual assumptions; instead,
684 	 * we send a set of integers giving the depths of the
685 	 * assumptions.  This is implemented as a Boolean array
686 	 * indexed by depth.
687 	 */
688 
689 	rc = write(To_parent, assumptions, MAX_SPLIT_DEPTH+1);
690 	p_assumption_depths(assumptions);
691       }
692       output_stats(stdout, Parms[STATS_LEVEL].val);
693       printf("\nProcess %d finished %s", my_process_id(), get_time());
694       exit(PROOF_EXIT);
695     }
696     else if (rc == CHILD) {
697       /* We are the child. Assert units for this case, then continue search. */
698       int j;
699       struct literal *c_lit, *d_lit;
700       struct clause *d, *sos_pos;
701 
702       clock_init();    /* reset all clocks to 0 */
703       add_subcase(case_number);  /* Update the case vector. */
704       printf("\nCase "); p_case();
705       printf("   (process %d):\n", my_process_id());
706 
707       /* Disable the clause being split. */
708 
709       un_index_lits_all(c);
710       if (c->container == Usable)
711 	un_index_lits_clash(c);
712       rem_from_list(c);
713       hide_clause(c);
714 
715       /* Add negated units for cases already done. */
716       /* Then add the unit for this case. */
717 
718       sos_pos = Sos->last_cl;  /* save position for post processing */
719 
720       for (j = 1; j <= case_number; j++) {
721 	c_lit = ith_literal(c, j);
722 	d = get_clause();
723 	d_lit = get_literal();
724 	d->first_lit = d_lit;
725 	d_lit->container = d;
726 	d_lit->atom = copy_term(c_lit->atom);
727 	d_lit->atom->occ.lit = d_lit;
728 	d_lit->sign = c_lit->sign;
729 	d_lit->atom->varnum = c_lit->atom->varnum;  /* copy type of atom */
730 	if (j != case_number) {
731 	  /* negate literal */
732 	  d_lit->sign = !d_lit->sign;
733 	  if (d_lit->atom->varnum == POS_EQ)
734 	    d_lit->atom->varnum = NEG_EQ;
735 	  else if (d_lit->atom->varnum == NEG_EQ)
736 	    d_lit->atom->varnum = POS_EQ;
737 	}
738 
739 	d->parents = get_ilist();
740 	d->parents->i = c->id;
741 
742 	d->parents->next = get_ilist();
743 	d->parents->next->i = (j == case_number ? SPLIT_RULE : SPLIT_NEG_RULE);
744 	d->parents->next->next = get_ilist();
745 	d->parents->next->next->i = LIST_RULE - ilist_length(Current_case);;
746 	d->parents->next->next->next = copy_ilist(Current_case);
747 
748 	pre_process(d, 0, Sos);
749 	if (j == case_number && d->container == Sos) {
750 	  printf("Assumption: ");
751 	  p_clause(d);
752 	}
753       }
754       post_proc_all(sos_pos, 0, Sos);
755       return 1;
756     }
757     else {  /* rc == CHILD_FAIL */
758       abend("case failure");
759       return -1;
760     }
761   }
762 #endif
763 }  /* split_clause */
764 
765 /*************
766  *
767  *   split_atom()
768  *
769  *   If success (i.e., split, and each child refutes its case), exit process.
770  *
771  *   Return value:
772  *        0: no split
773  *        1: split, child returns
774  *        2: split, parent returns failure (this might not be used)
775  *
776  *************/
777 
split_atom(void)778 int split_atom(void)
779 {
780 #ifndef TP_FORK
781   return 0;
782 #else
783   struct term *atom;
784   char assumptions[MAX_SPLIT_DEPTH+1];
785 
786   atom = find_atom_to_split();
787 
788   if (atom == NULL) {
789     printf("\nI tried to split, but I could not find a suitable atom.\n");
790     return 0;
791   }
792   else {
793     int rc, case_number;
794 
795     printf("\nSplitting on atom "); p_term(atom);
796 
797     rc = prover_forks(2, &case_number, assumptions);
798 
799     if (rc == FORK_FAIL) {
800       printf("Case splitting (fork) failed.  Returning to search.\n");
801       return 0;
802     }
803     else if (rc == PARENT) {
804       if (Current_case == NULL) {
805 	printf("\nThat finishes the proof of the theorem.\n");
806 	fprintf(stderr, "%c\nThat finishes the proof of the theorem.\n", Bell);
807       }
808       else {
809 	rc = write(To_parent, assumptions, MAX_SPLIT_DEPTH+1);
810 	p_assumption_depths(assumptions);
811       }
812       output_stats(stdout, Parms[STATS_LEVEL].val);
813       printf("\nProcess %d finished %s", my_process_id(), get_time());
814       exit(PROOF_EXIT);
815     }  /* parent */
816     else if (rc == CHILD) {
817       /* We are the child. Assert units for this case, then continue search. */
818       struct literal *d_lit;
819       struct clause *d, *sos_pos;
820 
821       clock_init();    /* reset all clocks to 0 */
822       add_subcase(case_number);  /* Update the case vector. */
823       printf("\nCase "); p_case();
824       printf("   (process %d):\n", my_process_id());
825 
826       sos_pos = Sos->last_cl;  /* save position for post processing */
827 
828       d = get_clause();
829       d_lit = get_literal();
830       d->first_lit = d_lit;
831       d_lit->container = d;
832       d_lit->atom = copy_term(atom);
833       d_lit->atom->occ.lit = d_lit;
834       d_lit->sign = (case_number == 1 ? 1 : 0);
835       if (is_eq(atom->sym_num))
836 	d_lit->atom->varnum = d_lit->sign ? POS_EQ : NEG_EQ;
837       else
838 	d_lit->atom->varnum = NORM_ATOM;
839 
840       d->parents = get_ilist();
841       d->parents->i = SPLIT_RULE;
842       d->parents->next = get_ilist();
843       d->parents->next->i = LIST_RULE - ilist_length(Current_case);
844       d->parents->next->next = copy_ilist(Current_case);
845 
846       pre_process(d, 0, Sos);
847       if (d->container == Sos) {
848 	printf("Assumption: ");
849 	p_clause(d);
850       }
851       post_proc_all(sos_pos, 0, Sos);
852       return 1;
853     }  /* child */
854     else {  /* rc == CHILD_FAIL */
855       abend("case failure");
856       return -1;
857     }
858   }
859 #endif
860 }  /* split_atom */
861 
862 /*************
863  *
864  *   possible_split()
865  *
866  *   Check if it is time to split, and if so, try to split.
867  *
868  *   If a split occurs, children return to continue searching.
869  *   If all children find proofs, parent calls exit(PROOF_EXIT).
870  *   If any child fails, parent abends.  (This may change.)
871  *
872  *************/
873 
possible_split(void)874 void possible_split(void)
875 {
876   static int next_attempt = 0;
877   int ok = 0;
878 
879 #ifndef TP_FORK
880   abend("case splitting is not compiled into this Otter");
881 #endif
882 
883   if (Flags[SPLIT_CLAUSE].val || Flags[SPLIT_ATOM].val) {
884     if (Parms[SPLIT_SECONDS].val != -1) {
885       int runtime = run_time() / 1000;
886       if (next_attempt == 0)
887 	next_attempt = Parms[SPLIT_SECONDS].val;
888       if (runtime >= next_attempt) {
889 	ok = 1;
890 	next_attempt += Parms[SPLIT_SECONDS].val;
891       }
892     }
893     else if (Parms[SPLIT_GIVEN].val != -1) {
894       int n = Parms[SPLIT_GIVEN].val;
895       if (n == 0 || Stats[CL_GIVEN] % n == 0) {
896 	ok = 1;
897       }
898     }
899 
900     if (ok) {
901       int rc;
902       if (case_depth() < Parms[SPLIT_DEPTH].val) {
903 	if (Flags[SPLIT_ATOM].val)
904 	  rc = split_atom();
905 	else
906 	  rc = split_clause((struct clause *) NULL);
907       }
908     }
909   }
910 }  /* possible_split */
911 
912 /*************
913  *
914  *   always_split()
915  *
916  *   Unconditional splitting, and keep splitting as long as possible.
917  *
918  *************/
919 
always_split(void)920 void always_split(void)
921 {
922   int rc;
923 
924 #ifndef TP_FORK
925   abend("case splitting is not compiled into this Otter");
926 #endif
927 
928   if (Flags[SPLIT_ATOM].val)
929     rc = split_atom();
930   else
931     rc = split_clause((struct clause *) NULL);
932 
933   if (rc == 1)
934     always_split();  /* We are the child; all is well; split again. */
935   else {
936     printf("\nalways_split: returning because no splitting is possible at this time.\n");
937     return;
938   }
939 }  /* always_split */
940 
941 /*************
942  *
943  *   possible_given_split(c)
944  *
945  *   c has just been selected as the given clause.
946  *
947  *************/
948 
possible_given_split(struct clause * c)949 void possible_given_split(struct clause *c)
950 {
951 #ifndef TP_FORK
952   abend("case splitting is not compiled into this Otter");
953 #endif
954 
955   if (Flags[SPLIT_WHEN_GIVEN].val && ground_clause(c) && num_literals(c) > 1) {
956     int ok = 1;
957 
958     if (ok && Flags[SPLIT_POS].val)
959       ok = pos_clause(c);
960     if (ok && Flags[SPLIT_NEG].val)
961       ok = neg_clause(c);
962     if (ok && Flags[SPLIT_NONHORN].val)
963       ok = !horn_clause(c);
964 
965     if (ok) {
966       int rc;
967       if (case_depth() < Parms[SPLIT_DEPTH].val) {
968 	if (Flags[SPLIT_ATOM].val) {
969 	  /* This is a little strange.  We're allowing splitting on an
970 	     atom.  We'll first move the clause back to Sos.
971 	  */
972 	  un_index_lits_clash(c);
973 	  rem_from_list(c);
974 	  append_cl(Sos, c);
975 	  rc = split_atom();
976 	}
977 	else
978 	  rc = split_clause(c);
979       }
980     }
981   }
982 }  /* possible_given_split */
983 
984 /*************
985  *
986  *   assumps_to_parent()
987  *
988  *   This routine is called when a proof is found during case splitting.
989  *
990  *   Tell the parent the assumptions used to refute this
991  *   leaf.  We don't send the actual assumptions; instead,
992  *   we send a set of integers giving the depths of the
993  *   assumptions.  This is implemented as a Boolean array
994  *   indexed by depth.
995  *
996  *************/
997 
assumps_to_parent(struct clause * e)998 void assumps_to_parent(struct clause *e)
999 {
1000   struct clause_ptr *p, *q;
1001   struct ilist *r;
1002   int i;
1003   char assumptions[MAX_SPLIT_DEPTH+1];
1004 
1005   p = NULL;
1006   i = get_ancestors(e, &p, &r);  /* i (level), r (level list) won't be used */
1007 
1008   for (i = 0; i <= MAX_SPLIT_DEPTH; i++)
1009     assumptions[i] = 0;
1010 
1011   for (q = p; q != NULL; q = q->next) {
1012     r = q->c->parents;
1013     /* SPLIT_RULE code is either first (atom split) or second (clause split) */
1014     if (r != NULL && r->i == SPLIT_RULE) {
1015       i = LIST_RULE - r->next->i;
1016     }
1017     else if (r!= NULL && r->next != NULL && r->next->i == SPLIT_RULE) {
1018       i = LIST_RULE - r->next->next->i;
1019     }
1020     else
1021       i = 0;
1022     if (i != 0) {
1023       /* The current clause is a split assumption, and i is the
1024        * depth.  This does not include SPLIT_NEG assumptions from
1025        * previous sibling cases.
1026        */
1027       assumptions[i] = 1;
1028     }
1029   }
1030   i = write(To_parent, assumptions, MAX_SPLIT_DEPTH+1);
1031   printf("\n\n"); p_assumption_depths(assumptions);
1032 }  /* assumps_to_parent */
1033 
1034 /*************
1035  *
1036  *   exit_with_possible_model()
1037  *
1038  *************/
1039 
exit_with_possible_model(void)1040 void exit_with_possible_model(void)
1041 {
1042   printf("\nPossible model detected on branch ");
1043   p_case();  printf(".\n");
1044   fprintf(stderr, "\n%cPossible model detected on branch ", Bell);
1045   print_case(stderr);    fprintf(stderr, ".\n");
1046 
1047   printf("\nHere are the clauses in Usable and SoS.  It seems that no more\n");
1048   printf("inferences or splitting can be done.  If the search strategy is\n");
1049   printf("complete, these clauses should lead to a model of the input.\n");
1050 
1051   printf("\nlist(usable).\n");
1052   print_cl_list(stdout, Usable);
1053   printf("\nlist(sos).\n");
1054   print_cl_list(stdout, Sos);
1055 
1056   output_stats(stdout, Parms[STATS_LEVEL].val);
1057 
1058   printf("\nProcess %d finished %s", my_process_id(), get_time());
1059   exit(POSSIBLE_MODEL_EXIT);
1060 }  /* exit_with_possible_model */
1061 
1062 /*************************************************************************/
1063 /* The rest of this file is some documentation on the code in this file. */
1064 /*************************************************************************/
1065 
1066 /*
1067 
1068 CASE SPLITTING IN OTTER
1069 
1070 William McCune, Dale Myers, Rusty Lusk, Mohammed Alumlla
1071 December 1997
1072 
1073 This implementation uses the UNIX fork() command to make copies of the
1074 current state of the process for the cases.  This avoids having to
1075 explicitly save the state and restore it for the next case.  (That is,
1076 it was easy to implement.)
1077 
1078 When enabled, splitting occurs periodically during the search.  The
1079 default is to split after every 5 given clauses.  This can be changed
1080 to some other number of given clauses, say 10, with the command
1081 
1082   assign(split_given, 10).    % default 5
1083 
1084 Instead, one can split after a specified number of seconds, with
1085 a command such as
1086 
1087   assign(split_seconds, 10).    % default infinity
1088 
1089 which asks Otter to attempt a split every (approximately) 10 seconds.
1090 (Jobs that use split_seconds are usually not repeatable.)
1091 
1092 A third method is to split when a nonunit ground clause is selected
1093 as the given clause.  This option is specified with the command
1094 
1095   set(split_when_given).
1096 
1097 which causes splitting on the given clause if (1) it is ground, (2) it
1098 is within the split_depth bound (see below), and (3) it satisfies the
1099 split_pos and split_neg flags (see below).
1100 
1101 If you wish to limit the depth of splitting, use a command such as
1102 
1103   assign(split_depth, 3).   % default 256 (which is also the maximum)
1104 
1105 which will not allow a case such as "Case [1.1.1.1]".
1106 
1107 There are two kinds of splitting: on ground clauses and on ground
1108 atoms.  Clause splitting constructs one case for each literal, and
1109 atom splitting, say on p, constructs two cases: p is true; p is false
1110 (or, as Larry Wos says, splitting on a tautology).
1111 
1112 Sequence of Splitting Processes
1113 
1114 Say Otter decides to split the search into n cases.  For each case,
1115 the fork() command creates a child process for the case, then the
1116 parent process waits for the child to exit.  If any child fails to
1117 refute its case, the parent exits in failure (causing all
1118 ancestor processes to fail as well).  If each child refutes its case,
1119 the parent exits with success.
1120 
1121 The Output File
1122 
1123 Various messages about the splitting events are sent to the output file.
1124 To get an overview of the search from an output file, say problem.out,
1125 one can use the following command.
1126 
1127   egrep "Splitting|Assumption|Refuted|skip|That" problem.out
1128 
1129 Splitting Clauses
1130 
1131 The following commands enables splitting on clauses after some number
1132 of given clauses have been used (see split_given), or after some
1133 number of seconds (see split_seconds).
1134 
1135   set(split_clause).     % default clear
1136 
1137 The following command simply asks Otter to split on ground given clauses.
1138 
1139   set(split_when_given). % default clear
1140 
1141 (I suppose one could use both of the preceding commands at the same
1142 time---I haven't tried it.)
1143 
1144 If Otter finds a suitable (see flags below) nonunit ground clause
1145 for splitting, say "p | q | r", the assumptions for three cases
1146 are
1147 
1148   Case 1: p.
1149   Case 2: -p & q.
1150   Case 3: -p & -q & r.
1151 
1152 Eligible Clauses for Splitting
1153 
1154 Otter splits on ground nonunit clauses only.  They can
1155 occur in Usable or in Sos.  The following commands can be used
1156 to specify the type of clause to split.
1157 
1158   set(split_pos).     % split on positive clauses only (default clear)
1159   set(split_neg).     % split on negative clauses only (default clear)
1160   set(split_nonhorn). % split on nonhorn clauses only (default clear)
1161 
1162 If none of the preceding flags are set, all ground clauses are eligible.
1163 
1164 Selecting the Best Eligible Clause
1165 
1166 The default method for selecting the best eligible clause for
1167 splitting is simply to take the first, lowest weight (using the
1168 pick_given scale) clause from Usable+Sos.
1169 
1170 Instead, one can use The command
1171 
1172   set(split_min_max).  % default clear
1173 
1174 which says to use the following method to compare two eligible clauses
1175 C and D.  Prefer the clause with the lighter heaviest literal
1176 (pick_given scale);  if the heaviest literals have the same
1177 weight, use the lighter clause;  if the clauses have the same
1178 weight, use the first in Usable+Sos.
1179 
1180 Splitting Atoms
1181 
1182 The following commands enables splitting on atoms after some number
1183 of given clauses have been used (see split_given), or after some
1184 number of seconds (see split_seconds).
1185 
1186   set(split_atom).
1187 
1188 (For propositional problems with assign(split_given, 0), this will
1189 cause Otter to perform a (not very speedy) Davis-Putnam search.)
1190 To select an atom for splitting, we consider OCCURRENCES of
1191 atoms within clauses.
1192 
1193 Eligible Atoms
1194 
1195 Otter splits on atoms that occur in nonunit ground clauses.
1196 The command
1197 
1198   set(split_pos).   % default clear
1199 
1200 says to split on atoms the occur only in positive clauses,
1201 
1202   set(split_neg).   % default clear
1203 
1204 says to split on atoms the occur only in negative clauses, and
1205 
1206   set(split_nonhorn).   % default clear
1207 
1208 says to split on atoms that occur positively in nonHorn clauses.
1209 
1210 Selecting the Best Eligible Atom
1211 
1212 Default method for comparing two eligible atom-occurrences:
1213 Prefer the atom that occurs in the lower weight clause.
1214 If the clauses have the same weight, prefer the atom
1215 with the lower weight.
1216 
1217 An optional method for selecting an atom considers the number
1218 of occurrences of the atom.  The command
1219 
1220   set(split_popular).  % default clear
1221 
1222 says to prefer the atom that occurs in the greatest number
1223 of clauses.  All clauses in Usable+Sos containing the atom
1224 are counted.
1225 
1226 Another Way to Split Atoms
1227 
1228 If the user has an idea of how atom splitting should occur, he/she
1229 can give a sequence of atoms in the input file, and Otter will
1230 split accordingly.  (As above, the TIME of splitting is determined
1231 as above with the split_given and split_seconds parameters.)
1232 
1233 For example, with the commands
1234 
1235   set(split_atom).
1236   split_atoms([P, a=b, R]).
1237   assign(split_given, 0).
1238 
1239 Otter will immediately (because of split_given) split the
1240 search into 8 cases (because there are 3 atoms), then do no
1241 more splitting.
1242 
1243 Problems With This Implementation
1244 
1245 Splitting is permanent.  That is, if a case fails, the whole
1246 search fails (no backing up to try a different split).
1247 
1248 If Otter fails to find a proof for a particular case (e.g., the Sos
1249 empties or some limit is reached), the whole attempt fails.  If
1250 the search strategy is complete, then an empty Sos indicates
1251 satisfiability, and the set of assumptions introduced by splitting
1252 give you a partial model; however, it is up to the user to figure this
1253 out.
1254 
1255 When splitting is enabled, max_seconds (for the initial process and
1256 all descendent processes) is checked against the wall clock (from the
1257 start of the initial process) instead of against the process clock.
1258 This is problematic if the computer is busy with other processes.
1259 
1260 Getting the Total Process Time
1261 
1262 The process clock ("user CPU" statistic) is initialized at the
1263 start of the process, and each process prints statistics once at the
1264 end of its life.  Therefore, one can get the total process by
1265 summing all of the "user CPU" times in the output file.  The command
1266 
1267   grep "user CPU" problem.out | awk '{sum += $4}END{print sum}'
1268 
1269 can be used to get the approximate total process time from an
1270 output file problem.out.
1271 
1272 Advice on Using Otter's Splitting (from McCune)
1273 
1274 At this time, we don't have much data.  A general strategy
1275 for nonground problems is the following.
1276 
1277   set(split_when_given).
1278   set(split_pos).            % Also try it without this command.
1279   assign(split_depth, 10).
1280 
1281 For ground (propositional) problems, try the following, which
1282 is essentially a Davis-Putnam procedure.
1283 
1284   set(split_atom).
1285   set(split_pos).
1286   assign(split_given, 0).
1287 
1288 */
1289