コード例 #1
0
ファイル: backend.c プロジェクト: potassco/clingo
bool print_model(clingo_model_t const *model) {
  bool ret = true;
  clingo_symbol_t *atoms = NULL;
  size_t atoms_n;
  clingo_symbol_t const *it, *ie;
  char *str = NULL;
  size_t str_n = 0;

  // determine the number of (shown) symbols in the model
  if (!clingo_model_symbols_size(model, clingo_show_type_shown, &atoms_n)) { goto error; }

  // allocate required memory to hold all the symbols
  if (!(atoms = (clingo_symbol_t*)malloc(sizeof(*atoms) * atoms_n))) {
    clingo_set_error(clingo_error_bad_alloc, "could not allocate memory for atoms");
    goto error;
  }

  // retrieve the symbols in the model
  if (!clingo_model_symbols(model, clingo_show_type_shown, atoms, atoms_n)) { goto error; }

  printf("Model:");

  for (it = atoms, ie = atoms + atoms_n; it != ie; ++it) {
    size_t n;
    char *str_new;

    // determine size of the string representation of the next symbol in the model
    if (!clingo_symbol_to_string_size(*it, &n)) { goto error; }

    if (str_n < n) {
      // allocate required memory to hold the symbol's string
      if (!(str_new = (char*)realloc(str, sizeof(*str) * n))) {
        clingo_set_error(clingo_error_bad_alloc, "could not allocate memory for symbol's string");
        goto error;
      }

      str = str_new;
      str_n = n;
    }

    // retrieve the symbol's string
    if (!clingo_symbol_to_string(*it, str, n)) { goto error; }

    printf(" %s", str);
  }

  printf("\n");
  goto out;

error:
  ret = false;

out:
  if (atoms) { free(atoms); }
  if (str)   { free(str); }

  return ret;
}
コード例 #2
0
ファイル: clingo.c プロジェクト: JanWielemaker/clingo
static bool call_function(clingo_location_t loc, char const *name,
                          clingo_symbol_t const *in, size_t ilen, void *closure,
                          clingo_symbol_callback_t *cb, void *cb_closure) {
    (void)loc;
    (void)closure;
    static predicate_t pred = 0;
    fid_t fid = 0;
    qid_t qid = 0;
    term_t av;
    bool rc = true;

    if (!pred) {
        pred = PL_predicate("inject_values", 3, "clingo");
    }

    if (!(fid = PL_open_foreign_frame())) {
        rc = false;
        clingo_set_error(clingo_error_runtime, "prolog error");
        goto out;
    }

    av = PL_new_term_refs(3);

    PL_put_atom_chars(av + 0, name);
    if (!(rc = unify_list_from_span(av + 1, in, ilen))) {
        clingo_set_error(clingo_error_runtime, "prolog error");
        goto out;
    }
    if ((qid = PL_open_query(NULL, PL_Q_PASS_EXCEPTION, pred, av))) {
        while (PL_next_solution(qid)) {
            clingo_symbol_t value;
            if (!(rc = get_value(av + 2, &value, FALSE))) {
                goto out;
            }
            if (!(rc = cb(&value, 1, cb_closure))) {
                goto out;
            }
        }
        if (PL_exception(0)) {
            rc = false;
            clingo_set_error(clingo_error_runtime, "prolog error");
            goto out;
        }
    }

out:
    if (qid) {
        PL_close_query(qid);
    }
    if (fid) {
        PL_close_foreign_frame(fid);
    }

    return rc;
}
コード例 #3
0
ファイル: clingo.c プロジェクト: JanWielemaker/clingo
static bool get_value(term_t t, clingo_symbol_t *val, int minus) {
    switch (PL_term_type(t)) {
    case PL_INTEGER: {
        int i;

        if (PL_get_integer(t, &i)) {
            clingo_symbol_create_number(i, val);
            return true;
        }
        return false;
    }
    case PL_ATOM: {
        char *s;
        size_t len;

        if (PL_get_nchars(t, &len, &s, CVT_ATOM | REP_UTF8 | CVT_EXCEPTION)) {
            return clingo_symbol_create_id(s, !minus, val); /* no sign */
        }
        return false;
    }
    case PL_STRING: {
        char *s;
        size_t len;

        if (PL_get_nchars(t, &len, &s, CVT_STRING | REP_UTF8 | CVT_EXCEPTION)) {
            return clingo_symbol_create_string(s, val);
        }
        return false;
    }
    case PL_TERM: {
        bool rc;
        term_t arg;
        atom_t name;
        size_t arity; /* TBD: -atom, #const */
        clingo_symbol_t *values = NULL;

        if (!(rc = get_name_arity(t, &name, &arity))) {
            clingo_set_error(clingo_error_runtime, "prolog error");
            goto out_term;
        }
        arg = PL_new_term_ref();

        if (name == ATOM_minus && arity == 1) {
            if (!(rc = get_value(arg, val, TRUE))) {
                goto out_term;
            }
        } else if (name == ATOM_hash && arity == 1) {
            atom_t a;

            _PL_get_arg(1, t, arg);
            if (!(rc = PL_get_atom_ex(arg, &a))) {
                clingo_set_error(clingo_error_runtime, "prolog error");
                goto out_term;
            }

            if (a == ATOM_inf) {
                clingo_symbol_create_infimum(val);
            } else if (a == ATOM_sup) {
                clingo_symbol_create_supremum(val);
            } else {
                rc = false;
                clingo_set_error(clingo_error_runtime, "bad value");
                goto out_term;
            }
        } else {
            const char *id = PL_atom_chars(name); /* TBD: errors */
            size_t i;

            if (!(values = malloc(sizeof(*values) * arity))) {
                rc = false;
                clingo_set_error(clingo_error_bad_alloc, "memory");
                goto out_term;
            }

            for (i = 0; i < arity; i++) {
                _PL_get_arg(i + 1, t, arg);
                if (!(rc = get_value(arg, &values[i], FALSE))) {
                    goto out_term;
                }
            }
            PL_reset_term_refs(arg);

            if (!(rc = clingo_symbol_create_function(id, values, arity, !minus,
                                                     val))) {
                goto out_term;
            }
        }
    out_term:
        if (values) {
            free(values);
        }
        return rc;
    }
    default:
        clingo_set_error(clingo_error_runtime, "bad value");
        return false;
    }
}