Clingo C API
C API for clingo providing high level functions to control grounding and solving.
backend.c

The example shows how to used the backend to extend a grounded program.

Output

./backend 0
Model: a b
Model: a b c
Model:
Model: a
Model: b

Code

#include <clingo.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
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;
}
bool ret = true;
clingo_model_t const *model;
// get a solve handle
if (!clingo_control_solve(ctl, clingo_solve_mode_yield, NULL, 0, NULL, NULL, &handle)) { goto error; }
// loop over all models
while (true) {
if (!clingo_solve_handle_resume(handle)) { goto error; }
if (!clingo_solve_handle_model(handle, &model)) { goto error; }
// print the model
if (model) { print_model(model); }
// stop if there are no more models
else { break; }
}
// close the solve handle
if (!clingo_solve_handle_get(handle, result)) { goto error; }
goto out;
error:
ret = false;
out:
// free the solve handle
return clingo_solve_handle_close(handle) && ret;
}
int main(int argc, char const **argv) {
char const *error_message;
int ret = 0;
size_t offset;
clingo_backend_t *backend;
clingo_atom_t atom_ids[4];
char const *atom_strings[] = {"a", "b", "c"};
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) {
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);
out:
if (ctl) { clingo_control_free(ctl); }
return ret;
}
clingo_solve_mode_yield
@ clingo_solve_mode_yield
Yield models in calls to clingo_solve_handle_model.
Definition: clingo.h:2288
clingo_show_type_shown
@ clingo_show_type_shown
Select shown atoms and terms.
Definition: clingo.h:2098
clingo_control_t
struct clingo_control clingo_control_t
Control object holding grounding and solving state.
Definition: clingo.h:2693
clingo_control_new
CLINGO_VISIBILITY_DEFAULT bool clingo_control_new(char const *const *arguments, size_t arguments_size, clingo_logger_t logger, void *logger_data, unsigned message_limit, clingo_control_t **control)
Create a new control object.
clingo_backend_begin
CLINGO_VISIBILITY_DEFAULT bool clingo_backend_begin(clingo_backend_t *backend)
Prepare the backend for usage.
clingo_symbolic_atoms_literal
CLINGO_VISIBILITY_DEFAULT bool clingo_symbolic_atoms_literal(clingo_symbolic_atoms_t const *atoms, clingo_symbolic_atom_iterator_t iterator, clingo_literal_t *literal)
Returns the (numeric) aspif literal corresponding to the given symbolic atom.
clingo_control_symbolic_atoms
CLINGO_VISIBILITY_DEFAULT bool clingo_control_symbolic_atoms(clingo_control_t const *control, clingo_symbolic_atoms_t const **atoms)
Get an object to inspect symbolic atoms (the relevant Herbrand base) used for grounding.
clingo_symbolic_atoms_iterator_is_equal_to
CLINGO_VISIBILITY_DEFAULT bool clingo_symbolic_atoms_iterator_is_equal_to(clingo_symbolic_atoms_t const *atoms, clingo_symbolic_atom_iterator_t a, clingo_symbolic_atom_iterator_t b, bool *equal)
Check if two iterators point to the same element (or end of the sequence).
clingo_control_free
CLINGO_VISIBILITY_DEFAULT void clingo_control_free(clingo_control_t *control)
Free a control object created with clingo_control_new().
clingo_symbolic_atoms_t
struct clingo_symbolic_atoms clingo_symbolic_atoms_t
Object to inspect symbolic atoms in a program—the relevant Herbrand base gringo uses to instantiate p...
Definition: clingo.h:542
clingo_literal_t
int32_t clingo_literal_t
Signed integer type used for aspif and solver literals.
Definition: clingo.h:121
clingo.h
clingo_backend_t
struct clingo_backend clingo_backend_t
Handle to the backend to add directives in aspif format.
Definition: clingo.h:1520
clingo_part
Struct used to specify the program parts that have to be grounded.
Definition: clingo.h:2645
clingo_solve_handle_close
CLINGO_VISIBILITY_DEFAULT bool clingo_solve_handle_close(clingo_solve_handle_t *handle)
Stops the running search and releases the handle.
clingo_symbol_to_string
CLINGO_VISIBILITY_DEFAULT bool clingo_symbol_to_string(clingo_symbol_t symbol, char *string, size_t size)
Get the string representation of a symbol.
clingo_symbol_create_id
CLINGO_VISIBILITY_DEFAULT bool clingo_symbol_create_id(char const *name, bool positive, clingo_symbol_t *symbol)
Construct a symbol representing an id.
clingo_control_ground
CLINGO_VISIBILITY_DEFAULT bool clingo_control_ground(clingo_control_t *control, clingo_part_t const *parts, size_t parts_size, clingo_ground_callback_t ground_callback, void *ground_callback_data)
Ground the selected parts of the current (non-ground) logic program.
clingo_control_add
CLINGO_VISIBILITY_DEFAULT bool clingo_control_add(clingo_control_t *control, char const *name, char const *const *parameters, size_t parameters_size, char const *program)
Extend the logic program with the given non-ground logic program in string form.
clingo_solve_handle_get
CLINGO_VISIBILITY_DEFAULT bool clingo_solve_handle_get(clingo_solve_handle_t *handle, clingo_solve_result_bitset_t *result)
Get the next solve result.
clingo_atom_t
uint32_t clingo_atom_t
Unsigned integer type used for aspif atoms.
Definition: clingo.h:123
clingo_control_backend
CLINGO_VISIBILITY_DEFAULT bool clingo_control_backend(clingo_control_t *control, clingo_backend_t **backend)
Get an object to add ground directives to the program.
clingo_control_solve
CLINGO_VISIBILITY_DEFAULT bool clingo_control_solve(clingo_control_t *control, clingo_solve_mode_bitset_t mode, clingo_literal_t const *assumptions, size_t assumptions_size, clingo_solve_event_callback_t notify, void *data, clingo_solve_handle_t **handle)
Solve the currently grounded logic program enumerating its models.
clingo_model_t
struct clingo_model clingo_model_t
Object representing a model.
Definition: clingo.h:2085
clingo_solve_handle_resume
CLINGO_VISIBILITY_DEFAULT bool clingo_solve_handle_resume(clingo_solve_handle_t *handle)
Discards the last model and starts the search for the next one.
clingo_symbol_to_string_size
CLINGO_VISIBILITY_DEFAULT bool clingo_symbol_to_string_size(clingo_symbol_t symbol, size_t *size)
Get the size of the string representation of a symbol (including the terminating 0).
clingo_symbolic_atoms_end
CLINGO_VISIBILITY_DEFAULT bool clingo_symbolic_atoms_end(clingo_symbolic_atoms_t const *atoms, clingo_symbolic_atom_iterator_t *iterator)
Iterator pointing to the end of the sequence of symbolic atoms.
clingo_model_symbols_size
CLINGO_VISIBILITY_DEFAULT bool clingo_model_symbols_size(clingo_model_t const *model, clingo_show_type_bitset_t show, size_t *size)
Get the number of symbols of the selected types in the model.
clingo_solve_handle_t
struct clingo_solve_handle clingo_solve_handle_t
Search handle to a solve call.
Definition: clingo.h:2322
clingo_solve_result_bitset_t
unsigned clingo_solve_result_bitset_t
Definition: clingo.h:2248
clingo_solve_handle_model
CLINGO_VISIBILITY_DEFAULT bool clingo_solve_handle_model(clingo_solve_handle_t *handle, clingo_model_t const **model)
Get the next model (or zero if there are no more models).
clingo_error_code
CLINGO_VISIBILITY_DEFAULT clingo_error_t clingo_error_code()
Get the last error code set by a clingo API call.
clingo_error_message
CLINGO_VISIBILITY_DEFAULT const char * clingo_error_message()
Get the last error message set if an API call fails.
clingo_symbol_t
uint64_t clingo_symbol_t
Represents a symbol.
Definition: clingo.h:330
clingo_backend_rule
CLINGO_VISIBILITY_DEFAULT bool clingo_backend_rule(clingo_backend_t *backend, bool choice, clingo_atom_t const *head, size_t head_size, clingo_literal_t const *body, size_t body_size)
Add a rule to the program.
clingo_backend_end
CLINGO_VISIBILITY_DEFAULT bool clingo_backend_end(clingo_backend_t *backend)
Finalize the backend after using it.
clingo_symbolic_atom_iterator_t
uint64_t clingo_symbolic_atom_iterator_t
Object to iterate over symbolic atoms.
Definition: clingo.h:552
clingo_error_bad_alloc
@ clingo_error_bad_alloc
memory could not be allocated
Definition: clingo.h:145
clingo_symbolic_atoms_find
CLINGO_VISIBILITY_DEFAULT bool clingo_symbolic_atoms_find(clingo_symbolic_atoms_t const *atoms, clingo_symbol_t symbol, clingo_symbolic_atom_iterator_t *iterator)
Find a symbolic atom given its symbolic representation.
clingo_set_error
CLINGO_VISIBILITY_DEFAULT void clingo_set_error(clingo_error_t code, char const *message)
Set a custom error code and message in the active thread.
clingo_model_symbols
CLINGO_VISIBILITY_DEFAULT bool clingo_model_symbols(clingo_model_t const *model, clingo_show_type_bitset_t show, clingo_symbol_t *symbols, size_t size)
Get the symbols of the selected types in the model.
clingo_backend_add_atom
CLINGO_VISIBILITY_DEFAULT bool clingo_backend_add_atom(clingo_backend_t *backend, clingo_symbol_t *symbol, clingo_atom_t *atom)
Get a fresh atom to be used in aspif directives.