Clingo
Loading...
Searching...
No Matches
backend.c

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

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

Output

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

Code

#include <clingo.h>
#include <clingo/backend.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define CHECK(label, call) \
do { \
if (!(call)) { \
status = false; \
goto label; \
} \
} while (0)
#define ERROR(label, cond, type, msg) \
do { \
if (cond) { \
clingo_set_error(clingo_result_##type, msg, strlen(msg)); \
status = false; \
goto label; \
} \
} while (0)
bool print_symbols(clingo_symbol_t const *symbols, size_t size, void *data) {
bool status = true;
for (size_t i = 0; i < size; ++i) {
CHECK(out, clingo_symbol_to_string(symbols[i], bld));
clingo_string_t str = {NULL, 0};
CHECK(out, clingo_string_builder_string(bld, &str));
printf(" %.*s", (int)str.size, str.data);
}
out:
return status;
}
bool on_model(clingo_model_t *model, void *data, bool *goon) {
bool status = true;
*goon = true;
printf("Answer:");
CHECK(out, clingo_model_symbols(model, clingo_show_type_shown, &print_symbols, data));
printf("\n");
out:
return status;
}
bool solve(clingo_control_t *ctl, clingo_solve_result_bitset_t *result) {
bool status = true;
clingo_solve_handle_t *handle = NULL;
clingo_solve_event_handler_t seh = {&on_model, NULL, NULL, NULL, NULL};
CHECK(out, clingo_string_builder_new(&bld));
CHECK(out, clingo_control_solve(ctl, clingo_solve_mode_default, NULL, 0, &seh, bld, &handle));
CHECK(out, clingo_solve_handle_get(handle, result));
out:
return status;
}
bool init(int argc, char const **argv, clingo_lib_t **lib, clingo_control_t **ctl, char const *prg) {
bool status = true;
size_t const limit = 20;
char const *part_name = "base";
clingo_part_t part = {part_name, strlen(part_name), NULL, 0};
clingo_string_t *clingo_argv = malloc((argc - 1) * sizeof(clingo_string_t));
ERROR(out, clingo_argv == NULL, bad_alloc, "failed to allocate memory for arguments");
for (int i = 1; i < argc; ++i) {
clingo_argv[i - 1].data = argv[i];
clingo_argv[i - 1].size = strlen(argv[i]);
}
CHECK(out, clingo_lib_new(flags, level, NULL, NULL, limit, lib));
CHECK(out, clingo_control_new(*lib, clingo_argv, argc - 1, ctl));
CHECK(out, clingo_control_parse_string(*ctl, prg, strlen(prg)));
CHECK(out, clingo_control_ground(*ctl, &part, 1, NULL, NULL));
out:
free(clingo_argv);
return status;
}
int main(int argc, char const **argv) {
bool status = true;
clingo_lib_t *lib = NULL;
clingo_control_t *ctl = NULL;
clingo_base_t const *base = NULL;
clingo_backend_t *backend = NULL;
clingo_atom_t atom_ids[] = {0, 0, 0, 0};
char const *atom_strings[] = {"a", "b", "c"};
clingo_literal_t body[] = {0, 0};
CHECK(out, init(argc, argv, &lib, &ctl, "{a; b; c}."));
// get the container for symbolic atoms
CHECK(out, clingo_control_base(ctl, &base));
// get the ids of atoms a, b, and c
for (size_t i = 0, n = (sizeof(atom_strings) / sizeof(*atom_strings)); i != n; ++i) {
char const *name = atom_strings[i];
clingo_symbol_t sym = 0;
clingo_atom_base_t const *atom_base = NULL;
clingo_signature_t sig = {name, strlen(name), 0, true};
size_t index = 0;
size_t size = 0;
bool found = false;
// lookup the atom
CHECK(loop_out, clingo_symbol_create_id(lib, name, strlen(name), true, &sym));
CHECK(loop_out, clingo_base_atoms_find(base, &sig, &atom_base, &found));
ERROR(loop_out, !found, logic, "atom not found in base");
CHECK(loop_out, clingo_atom_base_find(atom_base, sym, &index));
CHECK(loop_out, clingo_atom_base_size(atom_base, &size));
ERROR(loop_out, index >= size, logic, "index out of range");
CHECK(loop_out, clingo_atom_base_literal(atom_base, index, &lit));
atom_ids[i] = lit;
loop_out:
}
// prepare the backend for adding rules
CHECK(out, clingo_control_backend(ctl, &backend));
// add an additional atom (referred to as d below)
CHECK(out, clingo_backend_add_atom(backend, NULL, atom_ids + 3));
// add rule: d :- a, b.
body[0] = (clingo_literal_t)atom_ids[0];
body[1] = (clingo_literal_t)atom_ids[1];
CHECK(out, clingo_backend_rule(backend, false, atom_ids + 3, 1, body, 2));
// add rule: :- not d, c.
body[0] = -(clingo_literal_t)atom_ids[3];
body[1] = (clingo_literal_t)atom_ids[2];
CHECK(out, clingo_backend_rule(backend, false, NULL, 0, body, 2));
// finalize the backend
CHECK(out, clingo_backend_close(backend));
CHECK(out, solve(ctl, &solve_ret));
out:
if (!status) {
clingo_string_t err_msg = {NULL, 0};
clingo_result_t code = 0;
clingo_get_error(&code, &err_msg);
fprintf(stderr, "Error: %.*s\n", (int)err_msg.size, err_msg.data);
}
return status ? EXIT_SUCCESS : EXIT_FAILURE;
}
struct clingo_backend clingo_backend_t
Handle to the backend to add directives in aspif format.
Definition backend.h:47
CLINGO_VISIBILITY_DEFAULT bool clingo_control_backend(clingo_control_t *control, clingo_backend_t **backend)
Get a backend object to extend the ground program.
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_VISIBILITY_DEFAULT bool clingo_backend_add_atom(clingo_backend_t *backend, clingo_symbol_t const *symbol, clingo_atom_t *atom)
Get a fresh atom to be used in aspif directives.
CLINGO_VISIBILITY_DEFAULT bool clingo_backend_close(clingo_backend_t *backend)
Finalize the backend after using it.
struct clingo_atom_base clingo_atom_base_t
Object to inspect the symbolic atoms in a program.
Definition base.h:75
CLINGO_VISIBILITY_DEFAULT bool clingo_atom_base_find(clingo_atom_base_t const *atoms, clingo_symbol_t symbol, size_t *index)
Find the index of the atom with the given symbol in the atom base.
CLINGO_VISIBILITY_DEFAULT bool clingo_base_atoms_find(clingo_base_t const *base, clingo_signature_t const *signature, clingo_atom_base_t const **atoms, bool *found)
Find the atom base wit the given signature.
CLINGO_VISIBILITY_DEFAULT bool clingo_atom_base_size(clingo_atom_base_t const *atoms, size_t *size)
Get the size of the given atom base.
CLINGO_VISIBILITY_DEFAULT bool clingo_control_base(clingo_control_t const *control, clingo_base_t const **base)
Get the base associated with the control object.
CLINGO_VISIBILITY_DEFAULT bool clingo_atom_base_literal(clingo_atom_base_t const *atoms, size_t index, clingo_literal_t *literal)
Returns the (numeric) program literal corresponding to the given symbolic atom.
struct clingo_base clingo_base_t
Object to inspect symbolic atoms in a program—the relevant Herbrand base gringo uses to instantiate p...
Definition base.h:70
CLINGO_VISIBILITY_DEFAULT bool clingo_control_parse_string(clingo_control_t *control, char const *program, size_t size)
Extend the logic program with the given non-ground logic program in string form.
CLINGO_VISIBILITY_DEFAULT bool clingo_control_ground(clingo_control_t *control, clingo_part_t const *parts, size_t size, clingo_ground_callback_t ground_callback, void *data)
Ground the selected parts of the current (non-ground) logic program.
CLINGO_VISIBILITY_DEFAULT bool clingo_control_new(clingo_lib_t *lib, clingo_string_t const *arguments, size_t size, clingo_control_t **control)
Create a new control object.
CLINGO_VISIBILITY_DEFAULT void clingo_control_release(clingo_control_t *control)
Decrement the reference count of the given control object and destroy if zero.
CLINGO_VISIBILITY_DEFAULT void clingo_lib_release(clingo_lib_t *lib)
Release a library object created with clingo_lib_new().
CLINGO_VISIBILITY_DEFAULT void clingo_string_builder_free(clingo_string_builder_t const *bld)
Free the string builder.
CLINGO_VISIBILITY_DEFAULT void clingo_string_builder_clear(clingo_string_builder_t *bld)
Clear the string in the builder.
CLINGO_VISIBILITY_DEFAULT bool clingo_lib_new(clingo_lib_flags_t flags, clingo_log_level_t level, clingo_logger_t const *logger, void *data, size_t limit, clingo_lib_t **lib)
Create a library object.
int clingo_log_level_t
Corresponding type to clingo_log_level_e.
Definition core.h:149
struct clingo_lib clingo_lib_t
A library object storing global information.
Definition core.h:171
CLINGO_VISIBILITY_DEFAULT void clingo_get_error(clingo_result_t *code, clingo_string_t *message)
Get the error set in the current thread.
uint32_t clingo_atom_t
Unsigned integer type used for aspif atoms.
Definition core.h:75
struct clingo_string_builder clingo_string_builder_t
A builder for strings.
Definition core.h:252
CLINGO_VISIBILITY_DEFAULT bool clingo_string_builder_string(clingo_string_builder_t const *bld, clingo_string_t *value)
Get the (zero-terminated) string in the builder.
int32_t clingo_literal_t
Signed integer type used for aspif and solver literals.
Definition core.h:73
int clingo_result_t
Corresponding type to clingo_result_e.
Definition core.h:106
uint32_t clingo_lib_flags_t
Bitset of clingo_lib_flags_e.
Definition core.h:180
CLINGO_VISIBILITY_DEFAULT bool clingo_string_builder_new(clingo_string_builder_t **bld)
Create a new string builder.
@ clingo_log_level_info
the info level
Definition core.h:144
@ clingo_lib_flags_slotted
use custom allocator for storing symbols
Definition core.h:175
@ clingo_lib_flags_fast_release
whether to enable fast release of libraries
Definition core.h:177
CLINGO_VISIBILITY_DEFAULT bool clingo_model_symbols(clingo_model_t const *model, clingo_show_type_bitset_t show, clingo_symbol_callback_t callback, void *data)
Get the symbols of the selected types in the model.
struct clingo_model clingo_model_t
Object representing a model.
Definition model.h:43
@ clingo_show_type_shown
Select shown atoms and terms.
Definition model.h:56
struct clingo_solve_handle clingo_solve_handle_t
Search handle to a solve call.
Definition solve.h:112
CLINGO_VISIBILITY_DEFAULT bool clingo_solve_handle_close(clingo_solve_handle_t *handle)
Stops the running search and releases the handle.
unsigned clingo_solve_result_bitset_t
Corresponding type to clingo_solve_result_e.
Definition solve.h:61
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_handler_t const *handler, void *data, clingo_solve_handle_t **handle)
Solve the currently grounded logic program enumerating its models.
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_solve_result_empty
An uninitialized solve result.
Definition solve.h:54
@ clingo_solve_mode_default
The defalut solve mode.
Definition solve.h:65
CLINGO_VISIBILITY_DEFAULT bool clingo_symbol_to_string(clingo_symbol_t symbol, clingo_string_builder_t *builder)
Get the string representation of a symbol.
CLINGO_VISIBILITY_DEFAULT bool clingo_symbol_create_id(clingo_lib_t *lib, char const *name, size_t size, bool is_positive, clingo_symbol_t *symbol)
Construct a symbol representing an id.
uint64_t clingo_symbol_t
Type to represent a symbol.
Definition symbol.h:51
CLINGO_VISIBILITY_DEFAULT void clingo_symbol_release(clingo_symbol_t symbol)
Release ownership of the given symbol.
@ solve
Stop processing after solving.
auto main(Library &lib, std::span< std::string_view const > arguments={}, App *app=nullptr, bool raise_errors=false) -> int
Run a clingo based application with the given arguments.
Definition app.hh:221
@ lit
Conditional literals derived during grounding.
@ sig
Check if term is a signature.
Struct used to specify the program parts that have to be grounded.
Definition control.h:57
Represents a predicate signature.
Definition base.h:58
The solve event handler interface.
Definition solve.h:74
Struct to capture strings that are not null-terminated.
Definition core.h:86
size_t size
the length of the string
Definition core.h:88
char const * data
pointer to the beginning of the string
Definition core.h:87