int main(int argc, char const **argv) { char const *error_message; int ret = 0; size_t offset; clingo_solve_result_bitset_t solve_ret; clingo_control_t *ctl; clingo_symbolic_atoms_t *atoms; clingo_backend_t *backend; clingo_atom_t atom_ids[4]; char const *atom_strings[] = {"a", "b", "c"}; clingo_literal_t body[2]; clingo_part_t parts[] = {{ "base", NULL, 0 }}; // create a control object and pass command line arguments if (!clingo_control_new(argv+1, argc-1, NULL, NULL, 20, &ctl) != 0) { goto error; } // add a logic program to the base part if (!clingo_control_add(ctl, "base", NULL, 0, "{a; b; c}.")) { goto error; } // ground the base part if (!clingo_control_ground(ctl, parts, 1, NULL, NULL)) { goto error; } // get the container for symbolic atoms if (!clingo_control_symbolic_atoms(ctl, &atoms)) { goto error; } // get the ids of atoms a, b, and c offset = 0; for (char const **it = atom_strings, **ie = it + sizeof(atom_strings) / sizeof(*atom_strings); it != ie; ++it) { clingo_symbol_t sym; clingo_symbolic_atom_iterator_t atom_it, atom_ie; clingo_literal_t lit; bool equal; // lookup the atom if (!clingo_symbol_create_id(*it, true, &sym)) { goto error; } if (!clingo_symbolic_atoms_find(atoms, sym, &atom_it)) { goto error; } if (!clingo_symbolic_atoms_end(atoms, &atom_ie)) { goto error; } if (!clingo_symbolic_atoms_iterator_is_equal_to(atoms, atom_it, atom_ie, &equal)) { goto error; } assert(!equal); (void)equal; // get the atom's id if (!clingo_symbolic_atoms_literal(atoms, atom_it, &lit)) { goto error; } atom_ids[offset++] = lit; } // get the backend if (!clingo_control_backend(ctl, &backend)) { goto error; } // prepare the backend for adding rules if (!clingo_backend_begin(backend)) { goto error; } // add an additional atom (called d below) if (!clingo_backend_add_atom(backend, NULL, &atom_ids[3])) { goto error; } // add rule: d :- a, b. body[0] = atom_ids[0]; body[1] = atom_ids[1]; if (!clingo_backend_rule(backend, false, &atom_ids[3], 1, body, sizeof(body)/sizeof(*body))) { goto error; } // add rule: :- not d, c. body[0] = -(clingo_literal_t)atom_ids[3]; body[1] = atom_ids[2]; if (!clingo_backend_rule(backend, false, NULL, 0, body, sizeof(body)/sizeof(*body))) { goto error; } // finalize the backend if (!clingo_backend_end(backend)) { goto error; } // solve if (!solve(ctl, &solve_ret)) { goto error; } goto out; error: if (!(error_message = clingo_error_message())) { error_message = "error"; } printf("%s\n", error_message); ret = clingo_error_code(); out: if (ctl) { clingo_control_free(ctl); } return ret; }
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; } }