gboolean plgi_term_to_gbytes(term_t t, GBytes **bytes) { GBytes *bytes0; term_t list = PL_copy_term_ref(t); term_t head = PL_new_term_ref(); guint8 *data; gsize len; gint i = 0; if ( PL_skip_list(list, 0, &len) != PL_LIST ) { return PL_type_error("list", t); } data = g_malloc0(len); while ( PL_get_list(list, head, list) ) { guint8 byte; if ( !plgi_term_to_guint8(head, &byte) ) { g_free(data); return FALSE; } data[i++] = byte; } bytes0 = g_bytes_new_take(data, len); PLGI_debug(" term: 0x%lx ---> GBytes: %p", t, bytes0); *bytes = bytes0; return TRUE; }
/** assign a tuple to something: */ static foreign_t python_assign_tuple(term_t t_lhs, term_t t_rhs) { PyObject *e; Py_ssize_t sz; functor_t f; e = term_to_python(t_rhs, true); if (!e || !PyTuple_Check(e)) { return -1; } sz = PyTuple_Size(e); switch (PL_term_type(t_lhs)) { case PL_VARIABLE: return PL_unify(t_lhs, t_rhs); case PL_ATOM: return assign_python(py_Main, t_rhs, e); case PL_TERM: if (PL_get_functor(t_lhs, &f)) { term_t targ = PL_new_term_ref(); // assign a tuple to a tuple if (PL_functor_name(f) == ATOM_t && ((sz = PL_functor_arity(f)))) { Py_ssize_t i; for (i = 0; i < sz; i++) { PL_get_arg(i + 1, t_lhs, targ); assign_python(py_Main, targ, PyTuple_GetItem(e, i)); } } else if (PL_functor_name(f) == ATOM_comma) { int n = conj_size(t_lhs); if (n != sz) return -1; return conj_copy(t_lhs, e, 0); } else if (PL_functor_name(f) == ATOM_dot) { // vectors size_t len; term_t tail = PL_new_term_ref(); PL_skip_list(t_lhs, tail, &len); if (!PL_get_nil(tail)) return -1; term_t arg = tail; size_t i; for (i = 0; i < len; i++) { if (!PL_get_list(t_rhs, arg, t_rhs)) { return -1; } if (assign_python(py_Main, arg, PyTuple_GetItem(e, i)) < 0) return -1; } } } } return -1; }
static foreign_t pl_clingo_ground(term_t ccontrol, term_t parts) { clingo_env *ctl; clingo_part_t *part_vec = NULL; size_t plen = 0; int rc; if (!(rc = get_clingo(ccontrol, &ctl))) { goto out; } switch (PL_skip_list(parts, 0, &plen)) { case PL_LIST: { term_t tail = PL_copy_term_ref(parts); term_t head = PL_new_term_ref(); if (!(part_vec = malloc(sizeof(*part_vec) * plen))) { rc = PL_resource_error("memory"); goto out; } memset(part_vec, 0, sizeof(*part_vec) * plen); for (size_t i = 0; PL_get_list(tail, head, tail); i++) { if (!(rc = get_params(head, &part_vec[i]))) { goto out; } } break; } default: { rc = PL_type_error("list", parts); goto out; } } if (!(rc = clingo_status(clingo_control_ground(ctl->control, part_vec, plen, call_function, ctl)))) { goto out; } out: if (part_vec) { for (size_t i = 0; i < plen; i++) { if (part_vec[i].params) { free((void *)part_vec[i].params); } } free(part_vec); } return rc; }
static foreign_t pl_clingo_solve(term_t ccontrol, term_t assumptions, term_t Show, term_t Model, control_t h) { int rc = TRUE; solve_state *state = NULL; clingo_symbolic_literal_t *assump_vec = NULL; int control = PL_foreign_control(h); if (control == PL_FIRST_CALL) { size_t alen = 0; if (!(state = malloc(sizeof(*state)))) { rc = PL_resource_error("memory"); goto out; } memset(state, 0, sizeof(*state)); if (!(rc = get_clingo(ccontrol, &state->ctl))) { goto out; } if (PL_skip_list(assumptions, 0, &alen) != PL_LIST) { rc = PL_type_error("list", assumptions); goto out; } term_t tail = PL_copy_term_ref(assumptions); term_t head = PL_new_term_ref(); if (!(assump_vec = malloc(sizeof(*assump_vec) * alen))) { rc = PL_resource_error("memory"); goto out; } memset(assump_vec, 0, sizeof(*assump_vec) * alen); for (size_t i = 0; PL_get_list(tail, head, tail); i++) { if (!(rc = clingo_status(get_assumption(head, &assump_vec[i])))) { goto out; } } if (!(rc = clingo_status(clingo_control_solve_iteratively( state->ctl->control, assump_vec, alen, &state->it)))) { goto out; } } else { state = PL_foreign_context_address(h); } while (control != PL_PRUNED) { clingo_model_t *model; if (!(rc = clingo_status( clingo_solve_iteratively_next(state->it, &model)))) { goto out; } if (model) { int show; if (!(rc = get_show_map(Show, &show))) { goto out; } if (!(rc = unify_model(Model, show, model))) { if (PL_exception(0)) { goto out; } } else { PL_retry_address(state); state = NULL; break; } } else { rc = FALSE; break; } } out: if (assump_vec) { free(assump_vec); } if (state) { if (state->it) { clingo_solve_iteratively_close(state->it); } free(state); } return rc; }