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

The example shows how to configure the solver.

Note
It is also possible to loop over all configuration entries. This can be done in a similar fashion as in the statistics.c example. But note that, unlike with statistics entries, a configuration entry can have more than one type.

Output

./configuration
Model: a
Model: b

Code

#include <clingo.h>
#include <stdlib.h>
#include <stdio.h>
bool on_model(clingo_model_t *model, void *data, bool *goon) {
(void)data;
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");
*goon = true;
goto out;
error:
ret = false;
out:
if (atoms) { free(atoms); }
if (str) { free(str); }
return ret;
}
int main(int argc, char const **argv) {
char const *error_message;
int ret = 0;
clingo_control_t *ctl = NULL;
clingo_part_t parts[] = {{ "base", NULL, 0 }};
clingo_id_t root_key, sub_key;
// create a control object and pass command line arguments
if (!clingo_control_new(argv+1, argc-1, NULL, NULL, 20, &ctl) != 0) { goto error; }
// get the configuration object and its root key
if (!clingo_control_configuration(ctl, &conf)) { goto error; }
if (!clingo_configuration_root(conf, &root_key)) { goto error; }
// configure to enumerate all models
if (!clingo_configuration_map_at(conf, root_key, "solve.models", &sub_key)) { goto error; }
if (!clingo_configuration_value_set(conf, sub_key, "0")) { goto error; }
// configure the first solver to use the berkmin heuristic
if (!clingo_configuration_map_at(conf, root_key, "solver", &sub_key)) { goto error; }
if (!clingo_configuration_array_at(conf, sub_key, 0, &sub_key)) { goto error; }
if (!clingo_configuration_map_at(conf, sub_key, "heuristic", &sub_key)) { goto error; }
if (!clingo_configuration_value_set(conf, sub_key, "berkmin")) { goto error; }
// note that the solver entry can be used both as an array and a map
// if used as a map, this simply sets the configuration of the first solver and
// is equivalent to the code above
// add a logic program to the base part
if (!clingo_control_add(ctl, "base", NULL, 0, "a :- not b. b :- not a.")) { goto error; }
// ground the base part
if (!clingo_control_ground(ctl, parts, 1, NULL, NULL)) { goto error; }
// solve using a model callback
if (!clingo_control_solve(ctl, on_model, NULL, NULL, 0, &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;
}