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; }
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; }
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; } }