/* PUBLIC */
Literals formula_to_literals(Formula f)
{
  Literals lits = NULL;
  if (f->type == ATOM_FORM || f->type == NOT_FORM)
    lits = append_literal(lits, formula_to_literal(f));
  else if (f->type == OR_FORM) {
    int i;
    for (i = 0; i < f->arity; i++)
      lits = append_literal(lits,formula_to_literal(f->kids[i]));
  }
  else {
    fatal_error("formula_to_literals, formula not ATOM, NOT, or OR");
  }
  return lits;
}  /* formula_to_literals */
static
Clause resolve(Clash first, Just_type rule)
{
  Clause r = get_clause();
  Clause nuc =  first->nuc_lit->atom->container;
  Ilist j = ilist_append(NULL, nuc->id);
  Clash p;
  int n;

  /* First, include literals in the nucleus. */
  for (p = first; p != NULL; p = p->next, n++) {
    if (!p->clashed)
      append_literal(r, apply_lit(p->nuc_lit, p->nuc_subst));
  }

  r->attributes = cat_att(r->attributes,
			  inheritable_att_instances(nuc->attributes,
						    first->nuc_subst));

  /* Next, include literals in the satellites. */

  n = 1;  /* n-th nucleus literal, starting with 1 */
  for (p = first; p != NULL; p = p->next, n++) {
    if (p->clashed) {
      Literal lit;
      Clause sat = p->sat_lit->atom->container;
      j = ilist_append(j, n);
      j = ilist_append(j, sat->id);
      j = ilist_append(j, lit_position(sat, p->sat_lit));
      for (lit = sat->literals; lit != NULL; lit = lit->next) {
	if (lit != p->sat_lit)
	  append_literal(r, apply_lit(lit,  p->sat_subst));
      }
      r->attributes = cat_att(r->attributes,
			      inheritable_att_instances(sat->attributes,
							p->sat_subst));
    }
  }
  r->justification = resolve_just(j, rule);
  upward_clause_links(r);
  return r;
}  /* resolve */
static
Clause cd(Clause maj, Clause min)
{
  if (!unit_clause(maj) || !unit_clause(min))
    return NULL;
  else if (!maj->literals->sign || !min->literals->sign)
    return NULL;
  else {
    Term a = ARG(maj->literals->atom,0);
    Term b = ARG(min->literals->atom,0);
    if (ARITY(a) != 2)
      return NULL;
    else {
      Clause resolvent = NULL;
      Term a0 = ARG(a,0);
      Term a1 = ARG(a,1);
      Context ca = get_context();
      Context cb = get_context();
      Trail tr = NULL;
      if (unify(a0, ca, b, cb, &tr)) {
	Term r = apply(a1, ca);
	Term r_atom = build_unary_term(SYMNUM(maj->literals->atom), r);
	Literal r_literal = get_literal();
	Ilist j = NULL;
	r_literal->sign = TRUE;
	r_literal->atom = r_atom;
	resolvent = get_clause();
	append_literal(resolvent, r_literal);
	
	j = ilist_append(j, maj->id);
	j = ilist_append(j, 1);
	j = ilist_append(j, min->id);
	j = ilist_append(j, 1);

	resolvent->justification = resolve_just(j, BINARY_RES_JUST);
	upward_clause_links(resolvent);
	renumber_variables(resolvent, MAX_VARS);

	undo_subst(tr);
      }
      free_context(ca);
      free_context(cb);
      return resolvent;
    }
  }
}  /* cd */
示例#4
0
文件: printf.c 项目: tavianator/bfs
struct bfs_printf *parse_bfs_printf(const char *format, struct cmdline *cmdline) {
	struct bfs_printf *head = NULL;
	struct bfs_printf **tail = &head;

	struct bfs_printf *literal = new_directive(bfs_printf_literal);
	if (!literal) {
		goto error;
	}

	for (const char *i = format; *i; ++i) {
		char c = *i;

		if (c == '\\') {
			c = *++i;

			if (c >= '0' && c < '8') {
				c = 0;
				for (int j = 0; j < 3 && *i >= '0' && *i < '8'; ++i, ++j) {
					c *= 8;
					c += *i - '0';
				}
				--i;
				goto one_char;
			}

			switch (c) {
			case 'a':  c = '\a'; break;
			case 'b':  c = '\b'; break;
			case 'f':  c = '\f'; break;
			case 'n':  c = '\n'; break;
			case 'r':  c = '\r'; break;
			case 't':  c = '\t'; break;
			case 'v':  c = '\v'; break;
			case '\\': c = '\\'; break;

			case 'c':
				tail = append_literal(tail, &literal);
				struct bfs_printf *directive = new_directive(bfs_printf_flush);
				if (!directive) {
					goto error;
				}
				tail = append_directive(tail, directive);
				goto done;

			case '\0':
				bfs_error(cmdline, "'%s': Incomplete escape sequence '\\'.\n", format);
				goto error;

			default:
				bfs_error(cmdline, "'%s': Unrecognized escape sequence '\\%c'.\n", format, c);
				goto error;
			}
		} else if (c == '%') {
			if (i[1] == '%') {
				c = *++i;
				goto one_char;
			}

			struct bfs_printf *directive = new_directive(NULL);
			if (!directive) {
				goto directive_error;
			}
			if (dstrapp(&directive->str, c) != 0) {
				perror("dstrapp()");
				goto directive_error;
			}

			const char *specifier = "s";

			// Parse any flags
			bool must_be_numeric = false;
			while (true) {
				c = *++i;

				switch (c) {
				case '#':
				case '0':
				case '+':
					must_be_numeric = true;
					// Fallthrough
				case ' ':
				case '-':
					if (strchr(directive->str, c)) {
						bfs_error(cmdline, "'%s': Duplicate flag '%c'.\n", format, c);
						goto directive_error;
					}
					if (dstrapp(&directive->str, c) != 0) {
						perror("dstrapp()");
						goto directive_error;
					}
					continue;
				}

				break;
			}

			// Parse the field width
			while (c >= '0' && c <= '9') {
				if (dstrapp(&directive->str, c) != 0) {
					perror("dstrapp()");
					goto directive_error;
				}
				c = *++i;
			}

			// Parse the precision
			if (c == '.') {
				do {
					if (dstrapp(&directive->str, c) != 0) {
						perror("dstrapp()");
						goto directive_error;
					}
					c = *++i;
				} while (c >= '0' && c <= '9');
			}

			switch (c) {
			case 'a':
				directive->fn = bfs_printf_ctime;
				directive->stat_field = BFS_STAT_ATIME;
				break;
			case 'b':
				directive->fn = bfs_printf_b;
				break;
			case 'c':
				directive->fn = bfs_printf_ctime;
				directive->stat_field = BFS_STAT_CTIME;
				break;
			case 'd':
				directive->fn = bfs_printf_d;
				specifier = "jd";
				break;
			case 'D':
				directive->fn = bfs_printf_D;
				break;
			case 'f':
				directive->fn = bfs_printf_f;
				break;
			case 'F':
				if (!cmdline->mtab) {
					bfs_error(cmdline, "Couldn't parse the mount table: %s.\n", strerror(cmdline->mtab_error));
					goto directive_error;
				}
				directive->fn = bfs_printf_F;
				directive->mtab = cmdline->mtab;
				break;
			case 'g':
				directive->fn = bfs_printf_g;
				break;
			case 'G':
				directive->fn = bfs_printf_G;
				break;
			case 'h':
				directive->fn = bfs_printf_h;
				break;
			case 'H':
				directive->fn = bfs_printf_H;
				break;
			case 'i':
				directive->fn = bfs_printf_i;
				break;
			case 'k':
				directive->fn = bfs_printf_k;
				break;
			case 'l':
				directive->fn = bfs_printf_l;
				break;
			case 'm':
				directive->fn = bfs_printf_m;
				specifier = "o";
				break;
			case 'M':
				directive->fn = bfs_printf_M;
				break;
			case 'n':
				directive->fn = bfs_printf_n;
				break;
			case 'p':
				directive->fn = bfs_printf_p;
				break;
			case 'P':
				directive->fn = bfs_printf_P;
				break;
			case 's':
				directive->fn = bfs_printf_s;
				break;
			case 'S':
				directive->fn = bfs_printf_S;
				specifier = "g";
				break;
			case 't':
				directive->fn = bfs_printf_ctime;
				directive->stat_field = BFS_STAT_MTIME;
				break;
			case 'u':
				directive->fn = bfs_printf_u;
				break;
			case 'U':
				directive->fn = bfs_printf_U;
				break;
			case 'w':
				directive->fn = bfs_printf_ctime;
				directive->stat_field = BFS_STAT_BTIME;
				break;
			case 'y':
				directive->fn = bfs_printf_y;
				break;
			case 'Y':
				directive->fn = bfs_printf_Y;
				break;

			case 'A':
				directive->stat_field = BFS_STAT_ATIME;
				goto directive_strftime;
			case 'B':
			case 'W':
				directive->stat_field = BFS_STAT_BTIME;
				goto directive_strftime;
			case 'C':
				directive->stat_field = BFS_STAT_CTIME;
				goto directive_strftime;
			case 'T':
				directive->stat_field = BFS_STAT_MTIME;
				goto directive_strftime;

			directive_strftime:
				directive->fn = bfs_printf_strftime;
				c = *++i;
				if (!c) {
					bfs_error(cmdline, "'%s': Incomplete time specifier '%s%c'.\n", format, directive->str, i[-1]);
					goto directive_error;
				} else if (strchr("%+@aAbBcCdDeFgGhHIjklmMnprRsStTuUVwWxXyYzZ", c)) {
					directive->c = c;
				} else {
					bfs_error(cmdline, "'%s': Unrecognized time specifier '%%%c%c'.\n", format, i[-1], c);
					goto directive_error;
				}
				break;

			case '\0':
				bfs_error(cmdline, "'%s': Incomplete format specifier '%s'.\n", format, directive->str);
				goto directive_error;

			default:
				bfs_error(cmdline, "'%s': Unrecognized format specifier '%%%c'.\n", format, c);
				goto directive_error;
			}

			if (must_be_numeric && strcmp(specifier, "s") == 0) {
				bfs_error(cmdline, "'%s': Invalid flags '%s' for string format '%%%c'.\n", format, directive->str + 1, c);
				goto directive_error;
			}

			if (dstrcat(&directive->str, specifier) != 0) {
				perror("dstrcat()");
				goto directive_error;
			}

			tail = append_literal(tail, &literal);
			tail = append_directive(tail, directive);

			if (!literal) {
				literal = new_directive(bfs_printf_literal);
				if (!literal) {
					goto error;
				}
			}

			continue;

		directive_error:
			free_directive(directive);
			goto error;
		}

	one_char:
		if (dstrapp(&literal->str, c) != 0) {
			perror("dstrapp()");
			goto error;
		}
	}

done:
	tail = append_literal(tail, &literal);
	if (head) {
		free_directive(literal);
		return head;
	} else {
		return literal;
	}

error:
	free_directive(literal);
	free_bfs_printf(head);
	return NULL;
}