1 // {{{ MIT License
2
3 // Copyright 2017 Roland Kaminski
4
5 // Permission is hereby granted, free of charge, to any person obtaining a copy
6 // of this software and associated documentation files (the "Software"), to
7 // deal in the Software without restriction, including without limitation the
8 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 // sell copies of the Software, and to permit persons to whom the Software is
10 // furnished to do so, subject to the following conditions:
11
12 // The above copyright notice and this permission notice shall be included in
13 // all copies or substantial portions of the Software.
14
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 // IN THE SOFTWARE.
22
23 // }}}
24
25 #if defined(__GNUC__) && !defined(__clang__)
26 #pragma GCC diagnostic push
27 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
28 #elif defined(_MSC_VER)
29 #pragma warning (disable : 4996) // 'strcpy' may be unsafe
30 #endif
31
32 #include <clingo/clingo_app.hh>
33 #include <clingo/clingocontrol.hh>
34 #include <gringo/input/groundtermparser.hh>
35 #include <gringo/input/programbuilder.hh>
36 #include <gringo/input/nongroundparser.hh>
37 #include <clingo/astv2.hh>
38 #include <cstdarg>
39
40 #if defined CLINGO_NO_THREAD_LOCAL && ! defined EMSCRIPTEN
41 # include <thread>
42 # include <mutex>
43 #endif
44
45 // {{{1 error handling
46
47 using namespace Gringo;
48
49 namespace {
50
51 // {{{1 declaration of ClingoError
52
53 struct ClingoError : std::exception {
ClingoError__anonb1f002eb0111::ClingoError54 ClingoError()
55 : code(clingo_error_code()) {
56 try {
57 char const *msg = clingo_error_message();
58 message = msg ? msg : "no message";
59 }
60 catch (...) { }
61 }
what__anonb1f002eb0111::ClingoError62 char const *what() const noexcept {
63 return message.c_str();
64 }
65 std::string message;
66 clingo_error_t code;
67 };
68
clingo_expect(bool expr)69 void inline clingo_expect(bool expr) {
70 if (!expr) { throw std::runtime_error("unexpected"); }
71 }
72
73 void handleError();
74
75 #define GRINGO_CLINGO_TRY try
76 #define GRINGO_CLINGO_CATCH catch (...) { handleError(); return false; } return true
77
78 #define GRINGO_CALLBACK_TRY try
79 #define GRINGO_CALLBACK_CATCH(ref) catch (...){ (ref) = std::current_exception(); return false; } return true
80
81 template <class F>
print_size(F f)82 size_t print_size(F f) {
83 CountStream cs;
84 f(cs);
85 cs.flush();
86 return cs.count() + 1;
87 }
88
89 template <class F>
print(char * ret,size_t n,F f)90 void print(char *ret, size_t n, F f) {
91 ArrayStream as(ret, n);
92 f(as);
93 as << '\0';
94 as.flush();
95 }
96
97 #ifdef EMSCRIPTEN
98 std::exception_ptr g_lastException;
99 std::string g_lastMessage;
100 clingo_error_t g_lastCode;
101 #elif ! defined CLINGO_NO_THREAD_LOCAL
102 thread_local std::exception_ptr g_lastException;
103 thread_local std::string g_lastMessage;
104 thread_local clingo_error_t g_lastCode;
105 #else
106 struct TLData {
107 std::exception_ptr lastException;
108 std::string lastMessage;
109 clingo_error_t lastCode;
110 };
111 std::mutex g_tLMut;
112 std::unordered_map<std::thread::id, TLData> g_tLData;
tLlastException()113 std::exception_ptr &tLlastException() {
114 std::lock_guard<std::mutex> lock(g_tLMut);
115 return g_tLData[std::this_thread::get_id()].lastException;
116 }
tLlastMessage()117 std::string &tLlastMessage() {
118 std::lock_guard<std::mutex> lock(g_tLMut);
119 return g_tLData[std::this_thread::get_id()].lastMessage;
120 }
tLlastCode()121 clingo_error_t &tLlastCode() {
122 std::lock_guard<std::mutex> lock(g_tLMut);
123 return g_tLData[std::this_thread::get_id()].lastCode;
124 }
125 #define g_lastException (tLlastException())
126 #define g_lastMessage (tLlastMessage())
127 #define g_lastCode (tLlastCode())
128 #endif
129
forwardError(bool ret,std::exception_ptr * exc=nullptr)130 void forwardError(bool ret, std::exception_ptr *exc=nullptr) {
131 if (!ret) {
132 if (exc && *exc) { std::rethrow_exception(*exc); }
133 else { throw ClingoError(); }
134 }
135 }
136
handleError()137 void handleError() {
138 try { throw; }
139 // Note: a ClingoError is throw after an exception is set or a user error is thrown so either
140 // - g_lastException is already set, or
141 // - there was a user error (currently not associated to an error message)
142 catch (ClingoError const &e) { g_lastException = std::current_exception(); g_lastCode = e.code; }
143 catch (std::bad_alloc const &) { g_lastException = std::current_exception(); g_lastCode = clingo_error_bad_alloc; }
144 catch (std::logic_error) { g_lastException = std::current_exception(); g_lastCode = clingo_error_logic; }
145 catch (...) { g_lastException = std::current_exception(); g_lastCode = clingo_error_runtime; }
146 }
147
148
clingo_terminate(char const * loc)149 void clingo_terminate(char const *loc) {
150 fprintf(stderr, "%s:\n %s\n", loc, clingo_error_message());
151 fflush(stderr);
152 std::_Exit(1);
153 }
154
155 // }}}1
156 // {{{1
157
conv(Location const & loc)158 clingo_location_t conv(Location const &loc) {
159 return {loc.beginFilename.c_str(), loc.endFilename.c_str(), loc.beginLine, loc.endLine, loc.beginColumn, loc.endColumn};
160 }
161
conv(clingo_location_t const & loc)162 Location conv(clingo_location_t const &loc) {
163 return { loc.begin_file,
164 static_cast<unsigned int>(loc.begin_line),
165 static_cast<unsigned int>(loc.begin_column),
166 loc.end_file,
167 static_cast<unsigned int>(loc.end_line),
168 static_cast<unsigned int>(loc.end_column)};
169 }
170
171 // 1}}}
172 } // namespace
173
174 // c interface
175
176 // {{{1 error handling
177
clingo_set_error(clingo_error_t code,char const * message)178 extern "C" void clingo_set_error(clingo_error_t code, char const *message) {
179 g_lastCode = code;
180 try { g_lastException = std::make_exception_ptr(std::runtime_error(message)); }
181 catch (...) { g_lastException = nullptr; }
182 }
clingo_error_message()183 extern "C" char const *clingo_error_message() {
184 if (g_lastException) {
185 try { std::rethrow_exception(g_lastException); }
186 catch (std::bad_alloc const &) { return "bad_alloc"; }
187 catch (std::exception const &e) {
188 g_lastMessage = e.what();
189 return g_lastMessage.c_str();
190 }
191 }
192 return nullptr;
193 }
194
clingo_error_code()195 extern "C" clingo_error_t clingo_error_code() {
196 return g_lastCode;
197 }
198
clingo_error_string(clingo_error_t code)199 extern "C" char const *clingo_error_string(clingo_error_t code) {
200 switch (static_cast<clingo_error_e>(code)) {
201 case clingo_error_success: { return "success"; }
202 case clingo_error_runtime: { return "runtime error"; }
203 case clingo_error_bad_alloc: { return "bad allocation"; }
204 case clingo_error_logic: { return "logic error"; }
205 case clingo_error_unknown: { return "unknown error"; }
206 }
207 return nullptr;
208 }
209
clingo_warning_string(clingo_warning_t code)210 extern "C" char const *clingo_warning_string(clingo_warning_t code) {
211 switch (static_cast<clingo_warning_e>(code)) {
212 case clingo_warning_operation_undefined: { return "operation undefined"; }
213 case clingo_warning_runtime_error: { return "runtime error"; }
214 case clingo_warning_atom_undefined: { return "atom undefined"; }
215 case clingo_warning_file_included: { return "file included"; }
216 case clingo_warning_variable_unbounded: { return "variable unbounded"; }
217 case clingo_warning_global_variable: { return "global variable"; }
218 case clingo_warning_other: { return "other"; }
219 }
220 return "unknown message code";
221 }
222
223 // {{{1 signature
224
clingo_signature_create(char const * name,uint32_t arity,bool positive,clingo_signature_t * ret)225 extern "C" bool clingo_signature_create(char const *name, uint32_t arity, bool positive, clingo_signature_t *ret) {
226 GRINGO_CLINGO_TRY {
227 *ret = Sig(name, arity, !positive).rep();
228 } GRINGO_CLINGO_CATCH;
229 }
230
clingo_signature_name(clingo_signature_t sig)231 extern "C" char const *clingo_signature_name(clingo_signature_t sig) {
232 return Sig(sig).name().c_str();
233 }
234
clingo_signature_arity(clingo_signature_t sig)235 extern "C" uint32_t clingo_signature_arity(clingo_signature_t sig) {
236 return Sig(sig).arity();
237 }
238
clingo_signature_is_negative(clingo_signature_t sig)239 extern "C" bool clingo_signature_is_negative(clingo_signature_t sig) {
240 return Sig(sig).sign();
241 }
242
clingo_signature_is_positive(clingo_signature_t sig)243 extern "C" bool clingo_signature_is_positive(clingo_signature_t sig) {
244 return !Sig(sig).sign();
245 }
246
clingo_signature_hash(clingo_signature_t sig)247 extern "C" size_t clingo_signature_hash(clingo_signature_t sig) {
248 return Sig(sig).hash();
249 }
250
clingo_signature_is_equal_to(clingo_signature_t a,clingo_signature_t b)251 extern "C" bool clingo_signature_is_equal_to(clingo_signature_t a, clingo_signature_t b) {
252 return Sig(a) == Sig(b);
253 }
254
clingo_signature_is_less_than(clingo_signature_t a,clingo_signature_t b)255 extern "C" bool clingo_signature_is_less_than(clingo_signature_t a, clingo_signature_t b) {
256 return Sig(a) < Sig(b);
257 }
258
259
260 // {{{1 value
261
clingo_symbol_create_number(int num,clingo_symbol_t * val)262 extern "C" void clingo_symbol_create_number(int num, clingo_symbol_t *val) {
263 *val = Symbol::createNum(num).rep();
264 }
265
clingo_symbol_create_supremum(clingo_symbol_t * val)266 extern "C" void clingo_symbol_create_supremum(clingo_symbol_t *val) {
267 *val = Symbol::createSup().rep();
268 }
269
clingo_symbol_create_infimum(clingo_symbol_t * val)270 extern "C" void clingo_symbol_create_infimum(clingo_symbol_t *val) {
271 *val = Symbol::createInf().rep();
272 }
273
clingo_symbol_create_string(char const * str,clingo_symbol_t * val)274 extern "C" bool clingo_symbol_create_string(char const *str, clingo_symbol_t *val) {
275 GRINGO_CLINGO_TRY {
276 *val = Symbol::createStr(str).rep();
277 } GRINGO_CLINGO_CATCH;
278 }
279
clingo_symbol_create_id(char const * id,bool positive,clingo_symbol_t * val)280 extern "C" bool clingo_symbol_create_id(char const *id, bool positive, clingo_symbol_t *val) {
281 GRINGO_CLINGO_TRY {
282 *val = Symbol::createId(id, !positive).rep();
283 } GRINGO_CLINGO_CATCH;
284 }
285
clingo_symbol_create_function(char const * name,clingo_symbol_t const * args,size_t n,bool positive,clingo_symbol_t * val)286 extern "C" bool clingo_symbol_create_function(char const *name, clingo_symbol_t const *args, size_t n, bool positive, clingo_symbol_t *val) {
287 GRINGO_CLINGO_TRY {
288 *val = Symbol::createFun(name, SymSpan{reinterpret_cast<Symbol const *>(args), n}, !positive).rep();
289 } GRINGO_CLINGO_CATCH;
290 }
291
clingo_symbol_number(clingo_symbol_t val,int * num)292 extern "C" bool clingo_symbol_number(clingo_symbol_t val, int *num) {
293 GRINGO_CLINGO_TRY {
294 clingo_expect(Symbol(val).type() == SymbolType::Num);
295 *num = Symbol(val).num();
296 } GRINGO_CLINGO_CATCH;
297 }
298
clingo_symbol_name(clingo_symbol_t val,char const ** name)299 extern "C" bool clingo_symbol_name(clingo_symbol_t val, char const **name) {
300 GRINGO_CLINGO_TRY {
301 clingo_expect(Symbol(val).type() == SymbolType::Fun);
302 *name = Symbol(val).name().c_str();
303 } GRINGO_CLINGO_CATCH;
304 }
305
clingo_symbol_string(clingo_symbol_t val,char const ** str)306 extern "C" bool clingo_symbol_string(clingo_symbol_t val, char const **str) {
307 GRINGO_CLINGO_TRY {
308 clingo_expect(Symbol(val).type() == SymbolType::Str);
309 *str = Symbol(val).string().c_str();
310 } GRINGO_CLINGO_CATCH;
311 }
312
clingo_symbol_is_negative(clingo_symbol_t val,bool * sign)313 extern "C" bool clingo_symbol_is_negative(clingo_symbol_t val, bool *sign) {
314 GRINGO_CLINGO_TRY {
315 clingo_expect(Symbol(val).type() == SymbolType::Fun);
316 *sign = Symbol(val).sign();
317 } GRINGO_CLINGO_CATCH;
318 }
319
clingo_symbol_is_positive(clingo_symbol_t val,bool * sign)320 extern "C" bool clingo_symbol_is_positive(clingo_symbol_t val, bool *sign) {
321 GRINGO_CLINGO_TRY {
322 clingo_expect(Symbol(val).type() == SymbolType::Fun);
323 *sign = !Symbol(val).sign();
324 } GRINGO_CLINGO_CATCH;
325 }
326
clingo_symbol_arguments(clingo_symbol_t val,clingo_symbol_t const ** args,size_t * n)327 extern "C" bool clingo_symbol_arguments(clingo_symbol_t val, clingo_symbol_t const **args, size_t *n) {
328 GRINGO_CLINGO_TRY {
329 clingo_expect(Symbol(val).type() == SymbolType::Fun);
330 auto ret = Symbol(val).args();
331 *args = reinterpret_cast<clingo_symbol_t const *>(ret.first);
332 *n = ret.size;
333 } GRINGO_CLINGO_CATCH;
334 }
335
clingo_symbol_type(clingo_symbol_t val)336 extern "C" clingo_symbol_type_t clingo_symbol_type(clingo_symbol_t val) {
337 return static_cast<clingo_symbol_type_t>(Symbol(val).type());
338 }
339
clingo_symbol_to_string_size(clingo_symbol_t val,size_t * n)340 extern "C" bool clingo_symbol_to_string_size(clingo_symbol_t val, size_t *n) {
341 GRINGO_CLINGO_TRY { *n = print_size([&val](std::ostream &out) { Symbol(val).print(out); }); }
342 GRINGO_CLINGO_CATCH;
343 }
344
clingo_symbol_to_string(clingo_symbol_t val,char * ret,size_t n)345 extern "C" bool clingo_symbol_to_string(clingo_symbol_t val, char *ret, size_t n) {
346 GRINGO_CLINGO_TRY { print(ret, n, [&val](std::ostream &out) { Symbol(val).print(out); }); }
347 GRINGO_CLINGO_CATCH;
348 }
349
clingo_symbol_is_equal_to(clingo_symbol_t a,clingo_symbol_t b)350 extern "C" bool clingo_symbol_is_equal_to(clingo_symbol_t a, clingo_symbol_t b) {
351 return Symbol(a) == Symbol(b);
352 }
353
clingo_symbol_is_less_than(clingo_symbol_t a,clingo_symbol_t b)354 extern "C" bool clingo_symbol_is_less_than(clingo_symbol_t a, clingo_symbol_t b) {
355 return Symbol(a) < Symbol(b);
356 }
357
clingo_symbol_hash(clingo_symbol_t sym)358 extern "C" size_t clingo_symbol_hash(clingo_symbol_t sym) {
359 return Symbol(sym).hash();
360 }
361
362 // {{{1 symbolic atoms
363
clingo_symbolic_atoms_begin(clingo_symbolic_atoms_t const * dom,clingo_signature_t const * sig,clingo_symbolic_atom_iterator_t * ret)364 extern "C" bool clingo_symbolic_atoms_begin(clingo_symbolic_atoms_t const *dom, clingo_signature_t const *sig, clingo_symbolic_atom_iterator_t *ret) {
365 GRINGO_CLINGO_TRY { *ret = sig ? dom->begin(Sig(*sig)) : dom->begin(); }
366 GRINGO_CLINGO_CATCH;
367 }
368
clingo_symbolic_atoms_end(clingo_symbolic_atoms_t const * dom,clingo_symbolic_atom_iterator_t * ret)369 extern "C" bool clingo_symbolic_atoms_end(clingo_symbolic_atoms_t const *dom, clingo_symbolic_atom_iterator_t *ret) {
370 GRINGO_CLINGO_TRY { *ret = dom->end(); }
371 GRINGO_CLINGO_CATCH;
372 }
373
clingo_symbolic_atoms_find(clingo_symbolic_atoms_t const * dom,clingo_symbol_t atom,clingo_symbolic_atom_iterator_t * ret)374 extern "C" bool clingo_symbolic_atoms_find(clingo_symbolic_atoms_t const *dom, clingo_symbol_t atom, clingo_symbolic_atom_iterator_t *ret) {
375 GRINGO_CLINGO_TRY { *ret = dom->lookup(Symbol(atom)); }
376 GRINGO_CLINGO_CATCH;
377 }
378
clingo_symbolic_atoms_iterator_is_equal_to(clingo_symbolic_atoms_t const * dom,clingo_symbolic_atom_iterator_t it,clingo_symbolic_atom_iterator_t jt,bool * ret)379 extern "C" bool clingo_symbolic_atoms_iterator_is_equal_to(clingo_symbolic_atoms_t const *dom, clingo_symbolic_atom_iterator_t it, clingo_symbolic_atom_iterator_t jt, bool *ret) {
380 GRINGO_CLINGO_TRY { *ret = dom->eq(it, jt); }
381 GRINGO_CLINGO_CATCH;
382 }
383
clingo_symbolic_atoms_signatures_size(clingo_symbolic_atoms_t const * dom,size_t * n)384 extern "C" bool clingo_symbolic_atoms_signatures_size(clingo_symbolic_atoms_t const *dom, size_t *n) {
385 GRINGO_CLINGO_TRY {
386 // TODO: implement matching C++ functions ...
387 auto sigs = dom->signatures();
388 *n = sigs.size();
389 }
390 GRINGO_CLINGO_CATCH;
391 }
392
clingo_symbolic_atoms_signatures(clingo_symbolic_atoms_t const * dom,clingo_signature_t * ret,size_t n)393 extern "C" bool clingo_symbolic_atoms_signatures(clingo_symbolic_atoms_t const *dom, clingo_signature_t *ret, size_t n) {
394 GRINGO_CLINGO_TRY {
395 // TODO: implement matching C++ functions ...
396 auto sigs = dom->signatures();
397 if (n < sigs.size()) { throw std::length_error("not enough space"); }
398 for (auto &sig : sigs) { *ret++ = sig.rep(); }
399 }
400 GRINGO_CLINGO_CATCH;
401 }
402
clingo_symbolic_atoms_size(clingo_symbolic_atoms_t const * dom,size_t * size)403 extern "C" bool clingo_symbolic_atoms_size(clingo_symbolic_atoms_t const *dom, size_t *size) {
404 GRINGO_CLINGO_TRY { *size = dom->length(); }
405 GRINGO_CLINGO_CATCH;
406 }
407
clingo_symbolic_atoms_symbol(clingo_symbolic_atoms_t const * dom,clingo_symbolic_atom_iterator_t atm,clingo_symbol_t * sym)408 extern "C" bool clingo_symbolic_atoms_symbol(clingo_symbolic_atoms_t const *dom, clingo_symbolic_atom_iterator_t atm, clingo_symbol_t *sym) {
409 GRINGO_CLINGO_TRY { *sym = dom->atom(atm).rep(); }
410 GRINGO_CLINGO_CATCH;
411 }
412
clingo_symbolic_atoms_literal(clingo_symbolic_atoms_t const * dom,clingo_symbolic_atom_iterator_t atm,clingo_literal_t * lit)413 extern "C" bool clingo_symbolic_atoms_literal(clingo_symbolic_atoms_t const *dom, clingo_symbolic_atom_iterator_t atm, clingo_literal_t *lit) {
414 GRINGO_CLINGO_TRY { *lit = dom->literal(atm); }
415 GRINGO_CLINGO_CATCH;
416 }
417
clingo_symbolic_atoms_is_fact(clingo_symbolic_atoms_t const * dom,clingo_symbolic_atom_iterator_t atm,bool * fact)418 extern "C" bool clingo_symbolic_atoms_is_fact(clingo_symbolic_atoms_t const *dom, clingo_symbolic_atom_iterator_t atm, bool *fact) {
419 GRINGO_CLINGO_TRY { *fact = dom->fact(atm); }
420 GRINGO_CLINGO_CATCH;
421 }
422
clingo_symbolic_atoms_is_external(clingo_symbolic_atoms_t const * dom,clingo_symbolic_atom_iterator_t atm,bool * external)423 extern "C" bool clingo_symbolic_atoms_is_external(clingo_symbolic_atoms_t const *dom, clingo_symbolic_atom_iterator_t atm, bool *external) {
424 GRINGO_CLINGO_TRY { *external = dom->external(atm); }
425 GRINGO_CLINGO_CATCH;
426 }
427
clingo_symbolic_atoms_next(clingo_symbolic_atoms_t const * dom,clingo_symbolic_atom_iterator_t atm,clingo_symbolic_atom_iterator_t * next)428 extern "C" bool clingo_symbolic_atoms_next(clingo_symbolic_atoms_t const *dom, clingo_symbolic_atom_iterator_t atm, clingo_symbolic_atom_iterator_t *next) {
429 GRINGO_CLINGO_TRY { *next = dom->next(atm); }
430 GRINGO_CLINGO_CATCH;
431 }
432
clingo_symbolic_atoms_is_valid(clingo_symbolic_atoms_t const * dom,clingo_symbolic_atom_iterator_t atm,bool * valid)433 extern "C" bool clingo_symbolic_atoms_is_valid(clingo_symbolic_atoms_t const *dom, clingo_symbolic_atom_iterator_t atm, bool *valid) {
434 GRINGO_CLINGO_TRY { *valid = dom->valid(atm); }
435 GRINGO_CLINGO_CATCH;
436 }
437
438 // {{{1 theory atoms
439
440 struct clingo_theory_atoms : Gringo::Output::DomainData { };
441
clingo_theory_atoms_term_type(clingo_theory_atoms_t const * atoms,clingo_id_t value,clingo_theory_term_type_t * ret)442 extern "C" bool clingo_theory_atoms_term_type(clingo_theory_atoms_t const *atoms, clingo_id_t value, clingo_theory_term_type_t *ret) {
443 GRINGO_CLINGO_TRY { *ret = static_cast<clingo_theory_term_type_t>(atoms->termType(value)); }
444 GRINGO_CLINGO_CATCH;
445 }
446
clingo_theory_atoms_term_number(clingo_theory_atoms_t const * atoms,clingo_id_t value,int * ret)447 extern "C" bool clingo_theory_atoms_term_number(clingo_theory_atoms_t const *atoms, clingo_id_t value, int *ret) {
448 GRINGO_CLINGO_TRY { *ret = atoms->termNum(value); }
449 GRINGO_CLINGO_CATCH;
450 }
451
clingo_theory_atoms_term_name(clingo_theory_atoms_t const * atoms,clingo_id_t value,char const ** ret)452 extern "C" bool clingo_theory_atoms_term_name(clingo_theory_atoms_t const *atoms, clingo_id_t value, char const **ret) {
453 GRINGO_CLINGO_TRY { *ret = atoms->termName(value); }
454 GRINGO_CLINGO_CATCH;
455 }
456
clingo_theory_atoms_term_arguments(clingo_theory_atoms_t const * atoms,clingo_id_t value,clingo_id_t const ** ret,size_t * n)457 extern "C" bool clingo_theory_atoms_term_arguments(clingo_theory_atoms_t const *atoms, clingo_id_t value, clingo_id_t const **ret, size_t *n) {
458 GRINGO_CLINGO_TRY {
459 auto span = atoms->termArgs(value);
460 *ret = span.first;
461 *n = span.size;
462 }
463 GRINGO_CLINGO_CATCH;
464 }
465
clingo_theory_atoms_element_tuple(clingo_theory_atoms_t const * atoms,clingo_id_t value,clingo_id_t const ** ret,size_t * n)466 extern "C" bool clingo_theory_atoms_element_tuple(clingo_theory_atoms_t const *atoms, clingo_id_t value, clingo_id_t const **ret, size_t *n) {
467 GRINGO_CLINGO_TRY {
468 auto span = atoms->elemTuple(value);
469 *ret = span.first;
470 *n = span.size;
471 }
472 GRINGO_CLINGO_CATCH;
473 }
474
clingo_theory_atoms_element_condition(clingo_theory_atoms_t const * atoms,clingo_id_t value,clingo_literal_t const ** ret,size_t * n)475 extern "C" bool clingo_theory_atoms_element_condition(clingo_theory_atoms_t const *atoms, clingo_id_t value, clingo_literal_t const **ret, size_t *n) {
476 GRINGO_CLINGO_TRY {
477 auto span = atoms->elemCond(value);
478 *ret = span.first;
479 *n = span.size;
480 }
481 GRINGO_CLINGO_CATCH;
482 }
483
clingo_theory_atoms_element_condition_id(clingo_theory_atoms_t const * atoms,clingo_id_t value,clingo_literal_t * ret)484 extern "C" bool clingo_theory_atoms_element_condition_id(clingo_theory_atoms_t const *atoms, clingo_id_t value, clingo_literal_t *ret) {
485 GRINGO_CLINGO_TRY { *ret = atoms->elemCondLit(value); }
486 GRINGO_CLINGO_CATCH;
487 }
488
clingo_theory_atoms_atom_elements(clingo_theory_atoms_t const * atoms,clingo_id_t value,clingo_id_t const ** ret,size_t * n)489 extern "C" bool clingo_theory_atoms_atom_elements(clingo_theory_atoms_t const *atoms, clingo_id_t value, clingo_id_t const **ret, size_t *n) {
490 GRINGO_CLINGO_TRY {
491 auto span = atoms->atomElems(value);
492 *ret = span.first;
493 *n = span.size;
494 }
495 GRINGO_CLINGO_CATCH;
496 }
497
clingo_theory_atoms_atom_term(clingo_theory_atoms_t const * atoms,clingo_id_t value,clingo_id_t * ret)498 extern "C" bool clingo_theory_atoms_atom_term(clingo_theory_atoms_t const *atoms, clingo_id_t value, clingo_id_t *ret) {
499 GRINGO_CLINGO_TRY { *ret = atoms->atomTerm(value); }
500 GRINGO_CLINGO_CATCH;
501 }
502
clingo_theory_atoms_atom_has_guard(clingo_theory_atoms_t const * atoms,clingo_id_t value,bool * ret)503 extern "C" bool clingo_theory_atoms_atom_has_guard(clingo_theory_atoms_t const *atoms, clingo_id_t value, bool *ret) {
504 GRINGO_CLINGO_TRY { *ret = atoms->atomHasGuard(value); }
505 GRINGO_CLINGO_CATCH;
506 }
507
clingo_theory_atoms_atom_literal(clingo_theory_atoms_t const * atoms,clingo_id_t value,clingo_literal_t * ret)508 extern "C" bool clingo_theory_atoms_atom_literal(clingo_theory_atoms_t const *atoms, clingo_id_t value, clingo_literal_t *ret) {
509 GRINGO_CLINGO_TRY { *ret = atoms->atomLit(value); }
510 GRINGO_CLINGO_CATCH;
511 }
512
clingo_theory_atoms_atom_guard(clingo_theory_atoms_t const * atoms,clingo_id_t value,char const ** ret_op,clingo_id_t * ret_term)513 extern "C" bool clingo_theory_atoms_atom_guard(clingo_theory_atoms_t const *atoms, clingo_id_t value, char const **ret_op, clingo_id_t *ret_term) {
514 GRINGO_CLINGO_TRY {
515 auto guard = atoms->atomGuard(value);
516 *ret_op = guard.first;
517 *ret_term = guard.second;
518 }
519 GRINGO_CLINGO_CATCH;
520 }
521
clingo_theory_atoms_size(clingo_theory_atoms_t const * atoms,size_t * ret)522 extern "C" bool clingo_theory_atoms_size(clingo_theory_atoms_t const *atoms, size_t *ret) {
523 GRINGO_CLINGO_TRY { *ret = atoms->numAtoms(); }
524 GRINGO_CLINGO_CATCH;
525 }
526
clingo_theory_atoms_term_to_string_size(clingo_theory_atoms_t const * atoms,clingo_id_t value,size_t * n)527 extern "C" bool clingo_theory_atoms_term_to_string_size(clingo_theory_atoms_t const *atoms, clingo_id_t value, size_t *n) {
528 GRINGO_CLINGO_TRY { *n = print_size([atoms, value](std::ostream &out) { out << atoms->termStr(value); }); }
529 GRINGO_CLINGO_CATCH;
530 }
531
clingo_theory_atoms_term_to_string(clingo_theory_atoms_t const * atoms,clingo_id_t value,char * ret,size_t n)532 extern "C" bool clingo_theory_atoms_term_to_string(clingo_theory_atoms_t const *atoms, clingo_id_t value, char *ret, size_t n) {
533 GRINGO_CLINGO_TRY { print(ret, n, [atoms, value](std::ostream &out) { out << atoms->termStr(value); }); }
534 GRINGO_CLINGO_CATCH;
535 }
536
clingo_theory_atoms_element_to_string_size(clingo_theory_atoms_t const * atoms,clingo_id_t value,size_t * n)537 extern "C" bool clingo_theory_atoms_element_to_string_size(clingo_theory_atoms_t const *atoms, clingo_id_t value, size_t *n) {
538 GRINGO_CLINGO_TRY { *n = print_size([atoms, value](std::ostream &out) { out << atoms->elemStr(value); }); }
539 GRINGO_CLINGO_CATCH;
540 }
541
clingo_theory_atoms_element_to_string(clingo_theory_atoms_t const * atoms,clingo_id_t value,char * ret,size_t n)542 extern "C" bool clingo_theory_atoms_element_to_string(clingo_theory_atoms_t const *atoms, clingo_id_t value, char *ret, size_t n) {
543 GRINGO_CLINGO_TRY { print(ret, n, [atoms, value](std::ostream &out) { out << atoms->elemStr(value); }); }
544 GRINGO_CLINGO_CATCH;
545 }
546
clingo_theory_atoms_atom_to_string_size(clingo_theory_atoms_t const * atoms,clingo_id_t value,size_t * n)547 extern "C" bool clingo_theory_atoms_atom_to_string_size(clingo_theory_atoms_t const *atoms, clingo_id_t value, size_t *n) {
548 GRINGO_CLINGO_TRY { *n = print_size([atoms, value](std::ostream &out) { out << atoms->atomStr(value); }); }
549 GRINGO_CLINGO_CATCH;
550 }
551
clingo_theory_atoms_atom_to_string(clingo_theory_atoms_t const * atoms,clingo_id_t value,char * ret,size_t n)552 extern "C" bool clingo_theory_atoms_atom_to_string(clingo_theory_atoms_t const *atoms, clingo_id_t value, char *ret, size_t n) {
553 GRINGO_CLINGO_TRY { print(ret, n, [atoms, value](std::ostream &out) { out << atoms->atomStr(value); }); }
554 GRINGO_CLINGO_CATCH;
555 }
556
557 // {{{1 assignment
558
559 struct clingo_assignment : public Potassco::AbstractAssignment { };
560
clingo_assignment_has_conflict(clingo_assignment_t const * ass)561 extern "C" bool clingo_assignment_has_conflict(clingo_assignment_t const *ass) {
562 return ass->hasConflict();
563 }
564
clingo_assignment_decision_level(clingo_assignment_t const * ass)565 extern "C" uint32_t clingo_assignment_decision_level(clingo_assignment_t const *ass) {
566 return ass->level();
567 }
568
clingo_assignment_root_level(clingo_assignment_t const * ass)569 extern "C" uint32_t clingo_assignment_root_level(clingo_assignment_t const *ass) {
570 return ass->rootLevel();
571 }
572
clingo_assignment_has_literal(clingo_assignment_t const * ass,clingo_literal_t lit)573 extern "C" bool clingo_assignment_has_literal(clingo_assignment_t const *ass, clingo_literal_t lit) {
574 return ass->hasLit(lit);
575 }
576
clingo_assignment_truth_value(clingo_assignment_t const * ass,clingo_literal_t lit,clingo_truth_value_t * ret)577 extern "C" bool clingo_assignment_truth_value(clingo_assignment_t const *ass, clingo_literal_t lit, clingo_truth_value_t *ret) {
578 GRINGO_CLINGO_TRY { *ret = ass->value(lit); }
579 GRINGO_CLINGO_CATCH;
580 }
581
clingo_assignment_level(clingo_assignment_t const * ass,clingo_literal_t lit,uint32_t * ret)582 extern "C" bool clingo_assignment_level(clingo_assignment_t const *ass, clingo_literal_t lit, uint32_t *ret) {
583 GRINGO_CLINGO_TRY { *ret = ass->level(lit); }
584 GRINGO_CLINGO_CATCH;
585 }
586
clingo_assignment_decision(clingo_assignment_t const * ass,uint32_t level,clingo_literal_t * ret)587 extern "C" bool clingo_assignment_decision(clingo_assignment_t const *ass, uint32_t level, clingo_literal_t *ret) {
588 GRINGO_CLINGO_TRY { *ret = ass->decision(level); }
589 GRINGO_CLINGO_CATCH;
590 }
591
clingo_assignment_is_fixed(clingo_assignment_t const * ass,clingo_literal_t lit,bool * ret)592 extern "C" bool clingo_assignment_is_fixed(clingo_assignment_t const *ass, clingo_literal_t lit, bool *ret) {
593 GRINGO_CLINGO_TRY { *ret = ass->isFixed(lit); }
594 GRINGO_CLINGO_CATCH;
595 }
596
clingo_assignment_is_true(clingo_assignment_t const * ass,clingo_literal_t lit,bool * ret)597 extern "C" bool clingo_assignment_is_true(clingo_assignment_t const *ass, clingo_literal_t lit, bool *ret) {
598 GRINGO_CLINGO_TRY { *ret = ass->isTrue(lit); }
599 GRINGO_CLINGO_CATCH;
600 }
601
clingo_assignment_is_false(clingo_assignment_t const * ass,clingo_literal_t lit,bool * ret)602 extern "C" bool clingo_assignment_is_false(clingo_assignment_t const *ass, clingo_literal_t lit, bool *ret) {
603 GRINGO_CLINGO_TRY { *ret = ass->isFalse(lit); }
604 GRINGO_CLINGO_CATCH;
605 }
606
clingo_assignment_size(clingo_assignment_t const * assignment)607 extern "C" size_t clingo_assignment_size(clingo_assignment_t const *assignment) {
608 return assignment->size();
609 }
610
clingo_assignment_is_total(clingo_assignment_t const * assignment)611 extern "C" bool clingo_assignment_is_total(clingo_assignment_t const *assignment) {
612 return assignment->isTotal();
613 }
614
clingo_assignment_at(clingo_assignment_t const * assignment,size_t offset,clingo_literal_t * literal)615 extern "C" bool clingo_assignment_at(clingo_assignment_t const *assignment, size_t offset, clingo_literal_t *literal) {
616 GRINGO_CLINGO_TRY {
617 if (offset >= assignment->size()) {
618 throw std::runtime_error("invalid offset");
619 }
620 *literal = numeric_cast<clingo_literal_t>(offset + 1);
621 }
622 GRINGO_CLINGO_CATCH;
623 }
624
clingo_assignment_trail_size(clingo_assignment_t const * assignment,uint32_t * ret)625 extern "C" bool clingo_assignment_trail_size(clingo_assignment_t const *assignment, uint32_t *ret) {
626 GRINGO_CLINGO_TRY { *ret = assignment->trailSize(); }
627 GRINGO_CLINGO_CATCH;
628 }
629
clingo_assignment_trail_begin(clingo_assignment_t const * assignment,uint32_t level,uint32_t * ret)630 extern "C" bool clingo_assignment_trail_begin(clingo_assignment_t const *assignment, uint32_t level, uint32_t *ret) {
631 GRINGO_CLINGO_TRY { *ret = assignment->trailBegin(level); }
632 GRINGO_CLINGO_CATCH;
633 }
634
clingo_assignment_trail_end(clingo_assignment_t const * assignment,uint32_t level,uint32_t * ret)635 extern "C" bool clingo_assignment_trail_end(clingo_assignment_t const *assignment, uint32_t level, uint32_t *ret) {
636 GRINGO_CLINGO_TRY { *ret = assignment->trailEnd(level); }
637 GRINGO_CLINGO_CATCH;
638 }
639
clingo_assignment_trail_at(clingo_assignment_t const * assignment,uint32_t offset,clingo_literal_t * ret)640 extern "C" bool clingo_assignment_trail_at(clingo_assignment_t const *assignment, uint32_t offset, clingo_literal_t *ret) {
641 GRINGO_CLINGO_TRY { *ret = assignment->trailAt(offset); }
642 GRINGO_CLINGO_CATCH;
643 }
644
645 // {{{1 propagate init
646
clingo_propagate_init_solver_literal(clingo_propagate_init_t const * init,clingo_literal_t lit,clingo_literal_t * ret)647 extern "C" bool clingo_propagate_init_solver_literal(clingo_propagate_init_t const *init, clingo_literal_t lit, clingo_literal_t *ret) {
648 GRINGO_CLINGO_TRY { *ret = init->mapLit(lit); }
649 GRINGO_CLINGO_CATCH;
650 }
651
clingo_propagate_init_add_watch(clingo_propagate_init_t * init,clingo_literal_t lit)652 extern "C" bool clingo_propagate_init_add_watch(clingo_propagate_init_t *init, clingo_literal_t lit) {
653 GRINGO_CLINGO_TRY { init->addWatch(lit); }
654 GRINGO_CLINGO_CATCH;
655 }
656
clingo_propagate_init_add_watch_to_thread(clingo_propagate_init_t * init,clingo_literal_t lit,uint32_t thread_id)657 extern "C" bool clingo_propagate_init_add_watch_to_thread(clingo_propagate_init_t *init, clingo_literal_t lit, uint32_t thread_id) {
658 GRINGO_CLINGO_TRY { init->addWatch(thread_id, lit); }
659 GRINGO_CLINGO_CATCH;
660 }
661
clingo_propagate_init_remove_watch(clingo_propagate_init_t * init,clingo_literal_t lit)662 extern "C" bool clingo_propagate_init_remove_watch(clingo_propagate_init_t *init, clingo_literal_t lit) {
663 GRINGO_CLINGO_TRY { init->removeWatch(lit); }
664 GRINGO_CLINGO_CATCH;
665 }
666
clingo_propagate_init_remove_watch_from_thread(clingo_propagate_init_t * init,clingo_literal_t lit,uint32_t thread_id)667 extern "C" bool clingo_propagate_init_remove_watch_from_thread(clingo_propagate_init_t *init, clingo_literal_t lit, uint32_t thread_id) {
668 GRINGO_CLINGO_TRY { init->removeWatch(thread_id, lit); }
669 GRINGO_CLINGO_CATCH;
670 }
671
clingo_propagate_init_freeze_literal(clingo_propagate_init_t * init,clingo_literal_t lit)672 extern "C" bool clingo_propagate_init_freeze_literal(clingo_propagate_init_t *init, clingo_literal_t lit) {
673 GRINGO_CLINGO_TRY { init->freezeLiteral(lit); }
674 GRINGO_CLINGO_CATCH;
675 }
676
clingo_propagate_init_number_of_threads(clingo_propagate_init_t const * init)677 extern "C" int clingo_propagate_init_number_of_threads(clingo_propagate_init_t const *init) {
678 return init->threads();
679 }
680
clingo_propagate_init_symbolic_atoms(clingo_propagate_init_t const * init,clingo_symbolic_atoms_t const ** ret)681 extern "C" bool clingo_propagate_init_symbolic_atoms(clingo_propagate_init_t const *init, clingo_symbolic_atoms_t const **ret) {
682 GRINGO_CLINGO_TRY { *ret = &init->getDomain(); }
683 GRINGO_CLINGO_CATCH;
684 }
685
clingo_propagate_init_theory_atoms(clingo_propagate_init_t const * init,clingo_theory_atoms_t const ** ret)686 extern "C" bool clingo_propagate_init_theory_atoms(clingo_propagate_init_t const *init, clingo_theory_atoms_t const **ret) {
687 GRINGO_CLINGO_TRY { *ret = static_cast<clingo_theory_atoms const*>(&init->theory()); }
688 GRINGO_CLINGO_CATCH;
689 }
690
clingo_propagate_init_set_check_mode(clingo_propagate_init_t * init,clingo_propagator_check_mode_t mode)691 extern "C" void clingo_propagate_init_set_check_mode(clingo_propagate_init_t *init, clingo_propagator_check_mode_t mode) {
692 init->setCheckMode(mode);
693 }
694
clingo_propagate_init_get_check_mode(clingo_propagate_init_t const * init)695 extern "C" clingo_propagator_check_mode_t clingo_propagate_init_get_check_mode(clingo_propagate_init_t const *init) {
696 return init->getCheckMode();
697 }
698
clingo_propagate_init_assignment(clingo_propagate_init_t const * init)699 extern "C" clingo_assignment_t const *clingo_propagate_init_assignment(clingo_propagate_init_t const *init) {
700 return static_cast<clingo_assignment_t const *>(&init->assignment());
701 }
702
clingo_propagate_init_add_literal(clingo_propagate_init_t * init,bool freeze,clingo_literal_t * ret)703 extern "C" bool clingo_propagate_init_add_literal(clingo_propagate_init_t *init, bool freeze, clingo_literal_t *ret) {
704 GRINGO_CLINGO_TRY { *ret = init->addLiteral(freeze); }
705 GRINGO_CLINGO_CATCH;
706 }
707
clingo_propagate_init_add_clause(clingo_propagate_init_t * init,clingo_literal_t const * literals,size_t size,bool * ret)708 extern "C" bool clingo_propagate_init_add_clause(clingo_propagate_init_t *init, clingo_literal_t const *literals, size_t size, bool *ret) {
709 GRINGO_CLINGO_TRY { *ret = init->addClause(Potassco::LitSpan{literals, size}); }
710 GRINGO_CLINGO_CATCH;
711 }
712
clingo_propagate_init_add_weight_constraint(clingo_propagate_init_t * init,clingo_literal_t literal,clingo_weighted_literal_t const * literals,size_t size,clingo_weight_t bound,clingo_weight_constraint_type_t type,bool compare_equal,bool * ret)713 extern "C" bool clingo_propagate_init_add_weight_constraint(clingo_propagate_init_t *init, clingo_literal_t literal, clingo_weighted_literal_t const *literals, size_t size, clingo_weight_t bound, clingo_weight_constraint_type_t type, bool compare_equal, bool *ret) {
714 GRINGO_CLINGO_TRY { *ret = init->addWeightConstraint(literal, Potassco::WeightLitSpan{reinterpret_cast<Potassco::WeightLit_t const *>(literals), size}, bound, type, compare_equal); }
715 GRINGO_CLINGO_CATCH;
716 }
717
clingo_propagate_init_add_minimize(clingo_propagate_init_t * init,clingo_literal_t literal,clingo_weight_t weight,clingo_weight_t priority)718 extern "C" bool clingo_propagate_init_add_minimize(clingo_propagate_init_t *init, clingo_literal_t literal, clingo_weight_t weight, clingo_weight_t priority) {
719 GRINGO_CLINGO_TRY { init->addMinimize(literal, weight, priority); }
720 GRINGO_CLINGO_CATCH;
721 }
722
clingo_propagate_init_propagate(clingo_propagate_init_t * init,bool * ret)723 extern "C" bool clingo_propagate_init_propagate(clingo_propagate_init_t *init, bool *ret) {
724 GRINGO_CLINGO_TRY { *ret = init->propagate(); }
725 GRINGO_CLINGO_CATCH;
726 }
727
728 // {{{1 propagate control
729
730 struct clingo_propagate_control : Potassco::AbstractSolver { };
731
clingo_propagate_control_thread_id(clingo_propagate_control_t const * ctl)732 extern "C" clingo_id_t clingo_propagate_control_thread_id(clingo_propagate_control_t const *ctl) {
733 return ctl->id();
734 }
735
clingo_propagate_control_assignment(clingo_propagate_control_t const * ctl)736 extern "C" clingo_assignment_t const *clingo_propagate_control_assignment(clingo_propagate_control_t const *ctl) {
737 return static_cast<clingo_assignment_t const *>(&ctl->assignment());
738 }
739
clingo_propagate_control_add_clause(clingo_propagate_control_t * ctl,clingo_literal_t const * clause,size_t n,clingo_clause_type_t prop,bool * ret)740 extern "C" bool clingo_propagate_control_add_clause(clingo_propagate_control_t *ctl, clingo_literal_t const *clause, size_t n, clingo_clause_type_t prop, bool *ret) {
741 GRINGO_CLINGO_TRY { *ret = ctl->addClause({clause, n}, Potassco::Clause_t(prop)); }
742 GRINGO_CLINGO_CATCH;
743 }
744
clingo_propagate_control_propagate(clingo_propagate_control_t * ctl,bool * ret)745 extern "C" bool clingo_propagate_control_propagate(clingo_propagate_control_t *ctl, bool *ret) {
746 GRINGO_CLINGO_TRY { *ret = ctl->propagate(); }
747 GRINGO_CLINGO_CATCH;
748 }
749
clingo_propagate_control_add_literal(clingo_propagate_control_t * control,clingo_literal_t * result)750 extern "C" bool clingo_propagate_control_add_literal(clingo_propagate_control_t *control, clingo_literal_t *result) {
751 GRINGO_CLINGO_TRY { *result = control->addVariable(); }
752 GRINGO_CLINGO_CATCH;
753 }
754
clingo_propagate_control_add_watch(clingo_propagate_control_t * control,clingo_literal_t literal)755 extern "C" bool clingo_propagate_control_add_watch(clingo_propagate_control_t *control, clingo_literal_t literal) {
756 GRINGO_CLINGO_TRY { control->addWatch(literal); }
757 GRINGO_CLINGO_CATCH;
758 }
759
clingo_propagate_control_has_watch(clingo_propagate_control_t const * control,clingo_literal_t literal)760 extern "C" bool clingo_propagate_control_has_watch(clingo_propagate_control_t const *control, clingo_literal_t literal) {
761 return control->hasWatch(literal);
762 }
763
clingo_propagate_control_remove_watch(clingo_propagate_control_t * control,clingo_literal_t literal)764 extern "C" void clingo_propagate_control_remove_watch(clingo_propagate_control_t *control, clingo_literal_t literal) {
765 control->removeWatch(literal);
766 }
767
768 // {{{1 model
769
770 struct clingo_solve_control : clingo_model { };
771
clingo_model_thread_id(clingo_model_t const * ctl,clingo_id_t * ret)772 extern "C" bool clingo_model_thread_id(clingo_model_t const *ctl, clingo_id_t *ret) {
773 GRINGO_CLINGO_TRY { *ret = ctl->threadId(); }
774 GRINGO_CLINGO_CATCH;
775 }
776
clingo_solve_control_add_clause(clingo_solve_control_t * ctl,clingo_literal_t const * clause,size_t n)777 extern "C" bool clingo_solve_control_add_clause(clingo_solve_control_t *ctl, clingo_literal_t const *clause, size_t n) {
778 GRINGO_CLINGO_TRY { ctl->addClause(Potassco::toSpan(clause, n)); }
779 GRINGO_CLINGO_CATCH;
780 }
781
clingo_solve_control_symbolic_atoms(clingo_solve_control_t const * control,clingo_symbolic_atoms_t const ** atoms)782 extern "C" bool clingo_solve_control_symbolic_atoms(clingo_solve_control_t const *control, clingo_symbolic_atoms_t const **atoms) {
783 GRINGO_CLINGO_TRY { *atoms = &control->getDomain(); }
784 GRINGO_CLINGO_CATCH;
785 }
clingo_model_contains(clingo_model_t const * m,clingo_symbol_t atom,bool * ret)786 extern "C" bool clingo_model_contains(clingo_model_t const *m, clingo_symbol_t atom, bool *ret) {
787 GRINGO_CLINGO_TRY { *ret = m->contains(Symbol(atom)); }
788 GRINGO_CLINGO_CATCH;
789 }
790
clingo_model_symbols_size(clingo_model_t const * m,clingo_show_type_bitset_t show,size_t * n)791 extern "C" bool clingo_model_symbols_size(clingo_model_t const *m, clingo_show_type_bitset_t show, size_t *n) {
792 GRINGO_CLINGO_TRY {
793 // TODO: implement matching C++ functions ...
794 SymSpan atoms = m->atoms(show);
795 *n = atoms.size;
796 }
797 GRINGO_CLINGO_CATCH;
798 }
799
clingo_model_symbols(clingo_model_t const * m,clingo_show_type_bitset_t show,clingo_symbol_t * ret,size_t n)800 extern "C" bool clingo_model_symbols(clingo_model_t const *m, clingo_show_type_bitset_t show, clingo_symbol_t *ret, size_t n) {
801 GRINGO_CLINGO_TRY {
802 // TODO: implement matching C++ functions ...
803 SymSpan atoms = m->atoms(show);
804 if (n < atoms.size) { throw std::length_error("not enough space"); }
805 for (auto it = atoms.first, ie = it + atoms.size; it != ie; ++it) { *ret++ = it->rep(); }
806 }
807 GRINGO_CLINGO_CATCH;
808 }
809
clingo_model_optimality_proven(clingo_model_t const * m,bool * proven)810 extern "C" bool clingo_model_optimality_proven(clingo_model_t const *m, bool *proven) {
811 GRINGO_CLINGO_TRY { *proven = m->optimality_proven(); }
812 GRINGO_CLINGO_CATCH;
813 }
814
clingo_model_cost_size(clingo_model_t const * m,size_t * n)815 extern "C" bool clingo_model_cost_size(clingo_model_t const *m, size_t *n) {
816 GRINGO_CLINGO_TRY {
817 // TODO: implement matching C++ functions ...
818 auto opt = m->optimization();
819 *n = opt.size();
820 }
821 GRINGO_CLINGO_CATCH;
822 }
823
clingo_model_cost(clingo_model_t const * m,int64_t * ret,size_t n)824 extern "C" bool clingo_model_cost(clingo_model_t const *m, int64_t *ret, size_t n) {
825 GRINGO_CLINGO_TRY {
826 // TODO: implement matching C++ functions ...
827 auto opt = m->optimization();
828 if (n < opt.size()) { throw std::length_error("not enough space"); }
829 std::copy(opt.begin(), opt.end(), ret);
830 }
831 GRINGO_CLINGO_CATCH;
832 }
833
clingo_model_extend(clingo_model_t * model,clingo_symbol_t const * symbols,size_t size)834 extern "C" bool clingo_model_extend(clingo_model_t *model, clingo_symbol_t const *symbols, size_t size) {
835 GRINGO_CLINGO_TRY { model->add({reinterpret_cast<Symbol const *>(symbols), size}); }
836 GRINGO_CLINGO_CATCH;
837 }
838
clingo_model_context(clingo_model_t const * m,clingo_solve_control_t ** ret)839 extern "C" bool clingo_model_context(clingo_model_t const *m, clingo_solve_control_t **ret) {
840 GRINGO_CLINGO_TRY { *ret = static_cast<clingo_solve_control_t*>(const_cast<clingo_model_t *>(m)); }
841 GRINGO_CLINGO_CATCH;
842 }
843
clingo_model_number(clingo_model_t const * m,uint64_t * n)844 extern "C" bool clingo_model_number(clingo_model_t const *m, uint64_t *n) {
845 GRINGO_CLINGO_TRY { *n = m->number(); }
846 GRINGO_CLINGO_CATCH;
847 }
848
clingo_model_type(clingo_model_t const * m,clingo_model_type_t * ret)849 extern "C" bool clingo_model_type(clingo_model_t const *m, clingo_model_type_t *ret) {
850 GRINGO_CLINGO_TRY { *ret = static_cast<clingo_model_type_t>(m->type()); }
851 GRINGO_CLINGO_CATCH;
852 }
853
clingo_model_is_true(clingo_model_t const * m,clingo_literal_t lit,bool * result)854 extern "C" bool clingo_model_is_true(clingo_model_t const *m, clingo_literal_t lit, bool *result) {
855 GRINGO_CLINGO_TRY { *result = static_cast<clingo_model_type_t>(m->isTrue(lit)); }
856 GRINGO_CLINGO_CATCH;
857 }
858
859 // {{{1 configuration
860
861 struct clingo_configuration : ConfigProxy { };
862
clingo_configuration_type(clingo_configuration_t const * conf,clingo_id_t key,clingo_configuration_type_bitset_t * ret)863 extern "C" bool clingo_configuration_type(clingo_configuration_t const *conf, clingo_id_t key, clingo_configuration_type_bitset_t *ret) {
864 GRINGO_CLINGO_TRY {
865 int map_size, array_size, value_size;
866 conf->getKeyInfo(key, &map_size, &array_size, nullptr, &value_size);
867 *ret = 0;
868 if (map_size > 0) { *ret |= clingo_configuration_type_map; }
869 if (array_size >= 0) { *ret |= clingo_configuration_type_array; }
870 if (value_size >= 0) { *ret |= clingo_configuration_type_value; }
871 }
872 GRINGO_CLINGO_CATCH;
873 }
874
clingo_configuration_map_at(clingo_configuration_t const * conf,clingo_id_t key,char const * name,clingo_id_t * subkey)875 extern "C" bool clingo_configuration_map_at(clingo_configuration_t const *conf, clingo_id_t key, char const *name, clingo_id_t* subkey) {
876 GRINGO_CLINGO_TRY { *subkey = conf->getSubKey(key, name); }
877 GRINGO_CLINGO_CATCH;
878 }
879
clingo_configuration_map_has_subkey(clingo_configuration_t const * conf,clingo_id_t key,char const * name,bool * result)880 extern "C" bool clingo_configuration_map_has_subkey(clingo_configuration_t const *conf, clingo_id_t key, char const *name, bool *result) {
881 GRINGO_CLINGO_TRY { *result = conf->hasSubKey(key, name); }
882 GRINGO_CLINGO_CATCH;
883 }
884
clingo_configuration_map_subkey_name(clingo_configuration_t const * conf,clingo_id_t key,size_t index,char const ** name)885 extern "C" bool clingo_configuration_map_subkey_name(clingo_configuration_t const *conf, clingo_id_t key, size_t index, char const **name) {
886 GRINGO_CLINGO_TRY { *name = conf->getSubKeyName(key, numeric_cast<unsigned>(index)); }
887 GRINGO_CLINGO_CATCH;
888 }
889
clingo_configuration_map_size(clingo_configuration_t const * conf,clingo_id_t key,size_t * ret)890 extern "C" bool clingo_configuration_map_size(clingo_configuration_t const *conf, clingo_id_t key, size_t* ret) {
891 GRINGO_CLINGO_TRY {
892 int n;
893 conf->getKeyInfo(key, &n, nullptr, nullptr, nullptr);
894 if (n < 0) { throw std::runtime_error("not an array"); }
895 *ret = n;
896 }
897 GRINGO_CLINGO_CATCH;
898 }
899
clingo_configuration_array_at(clingo_configuration_t const * conf,clingo_id_t key,size_t idx,clingo_id_t * ret)900 extern "C" bool clingo_configuration_array_at(clingo_configuration_t const *conf, clingo_id_t key, size_t idx, clingo_id_t *ret) {
901 GRINGO_CLINGO_TRY { *ret = conf->getArrKey(key, numeric_cast<unsigned>(idx)); }
902 GRINGO_CLINGO_CATCH;
903 }
904
clingo_configuration_array_size(clingo_configuration_t const * conf,clingo_id_t key,size_t * ret)905 extern "C" bool clingo_configuration_array_size(clingo_configuration_t const *conf, clingo_id_t key, size_t *ret) {
906 GRINGO_CLINGO_TRY {
907 int n;
908 conf->getKeyInfo(key, nullptr, &n, nullptr, nullptr);
909 if (n < 0) { throw std::runtime_error("not an array"); }
910 *ret = n;
911 }
912 GRINGO_CLINGO_CATCH;
913 }
914
clingo_configuration_root(clingo_configuration_t const * conf,clingo_id_t * ret)915 extern "C" bool clingo_configuration_root(clingo_configuration_t const *conf, clingo_id_t *ret) {
916 GRINGO_CLINGO_TRY { *ret = conf->getRootKey(); }
917 GRINGO_CLINGO_CATCH;
918 }
919
clingo_configuration_description(clingo_configuration_t const * conf,clingo_id_t key,char const ** ret)920 extern "C" bool clingo_configuration_description(clingo_configuration_t const *conf, clingo_id_t key, char const **ret) {
921 GRINGO_CLINGO_TRY {
922 conf->getKeyInfo(key, nullptr, nullptr, ret, nullptr);
923 if (!ret) { throw std::runtime_error("no description"); }
924 }
925 GRINGO_CLINGO_CATCH;
926 }
927
clingo_configuration_value_get_size(clingo_configuration_t const * conf,clingo_id_t key,size_t * n)928 extern "C" bool clingo_configuration_value_get_size(clingo_configuration_t const *conf, clingo_id_t key, size_t *n) {
929 GRINGO_CLINGO_TRY {
930 std::string value;
931 conf->getKeyValue(key, value);
932 *n = value.size() + 1;
933 }
934 GRINGO_CLINGO_CATCH;
935 }
936
clingo_configuration_value_get(clingo_configuration_t const * conf,clingo_id_t key,char * ret,size_t n)937 extern "C" bool clingo_configuration_value_get(clingo_configuration_t const *conf, clingo_id_t key, char *ret, size_t n) {
938 GRINGO_CLINGO_TRY {
939 std::string value;
940 conf->getKeyValue(key, value);
941 if (n < value.size() + 1) { throw std::length_error("not enough space"); }
942 std::strcpy(ret, value.c_str());
943 }
944 GRINGO_CLINGO_CATCH;
945 }
946
clingo_configuration_value_set(clingo_configuration_t * conf,clingo_id_t key,char const * val)947 extern "C" bool clingo_configuration_value_set(clingo_configuration_t *conf, clingo_id_t key, char const *val) {
948 GRINGO_CLINGO_TRY { conf->setKeyValue(key, val); }
949 GRINGO_CLINGO_CATCH;
950 }
951
clingo_configuration_value_is_assigned(clingo_configuration_t const * conf,clingo_id_t key,bool * ret)952 extern "C" bool clingo_configuration_value_is_assigned(clingo_configuration_t const *conf, clingo_id_t key, bool *ret) {
953 GRINGO_CLINGO_TRY {
954 int n = 0;
955 conf->getKeyInfo(key, nullptr, nullptr, nullptr, &n);
956 if (n < 0) { throw std::runtime_error("not a value"); }
957 *ret = n > 0;
958 }
959 GRINGO_CLINGO_CATCH;
960 }
961
962 // {{{1 statistics
963
964 struct clingo_statistic : public Potassco::AbstractStatistics { };
965
clingo_statistics_root(clingo_statistics_t const * stats,uint64_t * ret)966 extern "C" bool clingo_statistics_root(clingo_statistics_t const *stats, uint64_t *ret) {
967 GRINGO_CLINGO_TRY { *ret = stats->root(); }
968 GRINGO_CLINGO_CATCH;
969 }
970
clingo_statistics_type(clingo_statistics_t const * stats,uint64_t key,clingo_statistics_type_t * ret)971 extern "C" bool clingo_statistics_type(clingo_statistics_t const *stats, uint64_t key, clingo_statistics_type_t *ret) {
972 GRINGO_CLINGO_TRY { *ret = stats->type(key); }
973 GRINGO_CLINGO_CATCH;
974 }
975
clingo_statistics_array_size(clingo_statistics_t const * stats,uint64_t key,size_t * ret)976 extern "C" bool clingo_statistics_array_size(clingo_statistics_t const *stats, uint64_t key, size_t *ret) {
977 GRINGO_CLINGO_TRY { *ret = stats->size(key); }
978 GRINGO_CLINGO_CATCH;
979 }
980
clingo_statistics_array_at(clingo_statistics_t const * stats,uint64_t key,size_t index,uint64_t * ret)981 extern "C" bool clingo_statistics_array_at(clingo_statistics_t const *stats, uint64_t key, size_t index, uint64_t *ret) {
982 GRINGO_CLINGO_TRY { *ret = stats->at(key, index); }
983 GRINGO_CLINGO_CATCH;
984 }
985
clingo_statistics_array_push(clingo_statistics_t * stats,uint64_t key,clingo_statistics_type_t type,uint64_t * ret)986 extern "C" bool clingo_statistics_array_push(clingo_statistics_t *stats, uint64_t key, clingo_statistics_type_t type, uint64_t *ret) {
987 GRINGO_CLINGO_TRY { *ret = stats->push(key, static_cast<Potassco::Statistics_t>(type)); }
988 GRINGO_CLINGO_CATCH;
989 }
990
clingo_statistics_map_size(clingo_statistics_t const * stats,uint64_t key,size_t * n)991 extern "C" bool clingo_statistics_map_size(clingo_statistics_t const *stats, uint64_t key, size_t *n) {
992 GRINGO_CLINGO_TRY { *n = stats->size(key); }
993 GRINGO_CLINGO_CATCH;
994 }
995
clingo_statistics_map_has_subkey(clingo_statistics_t const * stats,uint64_t key,char const * name,bool * result)996 extern "C" bool clingo_statistics_map_has_subkey(clingo_statistics_t const *stats, uint64_t key, char const *name, bool* result) {
997 GRINGO_CLINGO_TRY { uint64_t temp; *result = stats->find(key, name, &temp); }
998 GRINGO_CLINGO_CATCH;
999 }
1000
clingo_statistics_map_subkey_name(clingo_statistics_t const * stats,uint64_t key,size_t index,char const ** name)1001 extern "C" bool clingo_statistics_map_subkey_name(clingo_statistics_t const *stats, uint64_t key, size_t index, char const **name) {
1002 GRINGO_CLINGO_TRY { *name = stats->key(key, index); }
1003 GRINGO_CLINGO_CATCH;
1004 }
1005
clingo_statistics_map_at(clingo_statistics_t const * stats,uint64_t key,char const * name,uint64_t * ret)1006 extern "C" bool clingo_statistics_map_at(clingo_statistics_t const *stats, uint64_t key, char const *name, uint64_t *ret) {
1007 GRINGO_CLINGO_TRY { *ret = stats->get(key, name); }
1008 GRINGO_CLINGO_CATCH;
1009 }
1010
clingo_statistics_map_add_subkey(clingo_statistics_t * stats,uint64_t key,char const * name,clingo_statistics_type_t type,uint64_t * ret)1011 extern "C" bool clingo_statistics_map_add_subkey(clingo_statistics_t *stats, uint64_t key, char const *name, clingo_statistics_type_t type, uint64_t *ret) {
1012 GRINGO_CLINGO_TRY { *ret = stats->add(key, name, static_cast<Potassco::Statistics_t>(type)); }
1013 GRINGO_CLINGO_CATCH;
1014 }
1015
clingo_statistics_value_get(clingo_statistics_t const * stats,uint64_t key,double * value)1016 extern "C" bool clingo_statistics_value_get(clingo_statistics_t const *stats, uint64_t key, double *value) {
1017 GRINGO_CLINGO_TRY { *value = stats->value(key); }
1018 GRINGO_CLINGO_CATCH;
1019 }
1020
clingo_statistics_value_set(clingo_statistics_t * stats,uint64_t key,double value)1021 extern "C" bool clingo_statistics_value_set(clingo_statistics_t *stats, uint64_t key, double value) {
1022 GRINGO_CLINGO_TRY { stats->set(key, value); }
1023 GRINGO_CLINGO_CATCH;
1024 }
1025
1026
1027 // {{{1 global functions
1028
clingo_parse_term(char const * str,clingo_logger_t logger,void * data,unsigned message_limit,clingo_symbol_t * ret)1029 extern "C" bool clingo_parse_term(char const *str, clingo_logger_t logger, void *data, unsigned message_limit, clingo_symbol_t *ret) {
1030 GRINGO_CLINGO_TRY {
1031 Input::GroundTermParser parser;
1032 Logger::Printer printer;
1033 if (logger) {
1034 printer = [logger, data](Warnings code, char const *msg) { logger(static_cast<clingo_warning_t>(code), msg, data); };
1035 }
1036 Logger log(printer, message_limit);
1037 Symbol sym = parser.parse(str, log);
1038 if (sym.type() == SymbolType::Special) { throw std::runtime_error("parsing failed"); }
1039 *ret = sym.rep();
1040 }
1041 GRINGO_CLINGO_CATCH;
1042 }
1043
clingo_add_string(char const * str,char const ** ret)1044 extern "C" bool clingo_add_string(char const *str, char const **ret) {
1045 GRINGO_CLINGO_TRY { *ret = String(str).c_str(); }
1046 GRINGO_CLINGO_CATCH;
1047 }
1048
clingo_version(int * major,int * minor,int * revision)1049 extern "C" void clingo_version(int *major, int *minor, int *revision) {
1050 *major = CLINGO_VERSION_MAJOR;
1051 *minor = CLINGO_VERSION_MINOR;
1052 *revision = CLINGO_VERSION_REVISION;
1053 }
1054
1055 // {{{1 backend
1056
1057 struct clingo_backend : clingo_control_t { };
1058
clingo_backend_begin(clingo_backend_t * backend)1059 extern "C" bool clingo_backend_begin(clingo_backend_t *backend) {
1060 GRINGO_CLINGO_TRY {
1061 if (!backend->beginAddBackend()) { throw std::runtime_error("backend not available"); }
1062 }
1063 GRINGO_CLINGO_CATCH;
1064 }
1065
clingo_backend_end(clingo_backend_t * backend)1066 extern "C" bool clingo_backend_end(clingo_backend_t *backend) {
1067 GRINGO_CLINGO_TRY { backend->endAddBackend(); }
1068 GRINGO_CLINGO_CATCH;
1069 }
1070
clingo_backend_rule(clingo_backend_t * backend,bool choice,clingo_atom_t const * head,size_t head_n,clingo_literal_t const * body,size_t body_n)1071 extern "C" bool clingo_backend_rule(clingo_backend_t *backend, bool choice, clingo_atom_t const *head, size_t head_n, clingo_literal_t const *body, size_t body_n) {
1072 GRINGO_CLINGO_TRY {
1073 if (body_n == 0 && head_n == 1 && !choice) { backend->addFact(*head); }
1074 outputRule(*backend->getBackend(), choice, {head, head_n}, {body, body_n});
1075 }
1076 GRINGO_CLINGO_CATCH;
1077 }
1078
clingo_backend_weight_rule(clingo_backend_t * backend,bool choice,clingo_atom_t const * head,size_t head_n,clingo_weight_t lower,clingo_weighted_literal_t const * body,size_t body_n)1079 extern "C" bool clingo_backend_weight_rule(clingo_backend_t *backend, bool choice, clingo_atom_t const *head, size_t head_n, clingo_weight_t lower, clingo_weighted_literal_t const *body, size_t body_n) {
1080 GRINGO_CLINGO_TRY { outputRule(*backend->getBackend(), choice, {head, head_n}, lower, {reinterpret_cast<Potassco::WeightLit_t const *>(body), body_n}); }
1081 GRINGO_CLINGO_CATCH;
1082 }
1083
clingo_backend_minimize(clingo_backend_t * backend,clingo_weight_t prio,clingo_weighted_literal_t const * lits,size_t lits_n)1084 extern "C" bool clingo_backend_minimize(clingo_backend_t *backend, clingo_weight_t prio, clingo_weighted_literal_t const* lits, size_t lits_n) {
1085 GRINGO_CLINGO_TRY { backend->getBackend()->minimize(prio, {reinterpret_cast<Potassco::WeightLit_t const *>(lits), lits_n}); }
1086 GRINGO_CLINGO_CATCH;
1087 }
1088
clingo_backend_project(clingo_backend_t * backend,clingo_atom_t const * atoms,size_t n)1089 extern "C" bool clingo_backend_project(clingo_backend_t *backend, clingo_atom_t const *atoms, size_t n) {
1090 GRINGO_CLINGO_TRY { backend->getBackend()->project({atoms, n}); }
1091 GRINGO_CLINGO_CATCH;
1092 }
1093
clingo_backend_external(clingo_backend_t * backend,clingo_atom_t atom,clingo_external_type_t v)1094 extern "C" bool clingo_backend_external(clingo_backend_t *backend, clingo_atom_t atom, clingo_external_type_t v) {
1095 GRINGO_CLINGO_TRY { backend->getBackend()->external(atom, Potassco::Value_t(v)); }
1096 GRINGO_CLINGO_CATCH;
1097 }
1098
clingo_backend_assume(clingo_backend_t * backend,clingo_literal_t const * literals,size_t n)1099 extern "C" bool clingo_backend_assume(clingo_backend_t *backend, clingo_literal_t const *literals, size_t n) {
1100 GRINGO_CLINGO_TRY { backend->getBackend()->assume({literals, n}); }
1101 GRINGO_CLINGO_CATCH;
1102 }
1103
clingo_backend_heuristic(clingo_backend_t * backend,clingo_atom_t atom,clingo_heuristic_type_t type,int bias,unsigned priority,clingo_literal_t const * condition,size_t condition_n)1104 extern "C" bool clingo_backend_heuristic(clingo_backend_t *backend, clingo_atom_t atom, clingo_heuristic_type_t type, int bias, unsigned priority, clingo_literal_t const *condition, size_t condition_n) {
1105 GRINGO_CLINGO_TRY { backend->getBackend()->heuristic(atom, Potassco::Heuristic_t(type), bias, priority, {condition, condition_n}); }
1106 GRINGO_CLINGO_CATCH;
1107 }
1108
clingo_backend_acyc_edge(clingo_backend_t * backend,int node_u,int node_v,clingo_literal_t const * condition,size_t condition_n)1109 extern "C" bool clingo_backend_acyc_edge(clingo_backend_t *backend, int node_u, int node_v, clingo_literal_t const *condition, size_t condition_n) {
1110 GRINGO_CLINGO_TRY { backend->getBackend()->acycEdge(node_u, node_v, {condition, condition_n}); }
1111 GRINGO_CLINGO_CATCH;
1112 }
1113
clingo_backend_add_atom(clingo_backend_t * backend,clingo_symbol_t * symbol,clingo_atom_t * ret)1114 extern "C" bool clingo_backend_add_atom(clingo_backend_t *backend, clingo_symbol_t *symbol, clingo_atom_t *ret) {
1115 GRINGO_CLINGO_TRY {
1116 if (symbol) {
1117 if (Symbol{*symbol}.type() != SymbolType::Fun) {
1118 throw std::runtime_error("function expected");
1119 }
1120 *ret = backend->addAtom(Symbol{*symbol});
1121 }
1122 else { *ret = backend->addProgramAtom(); }
1123 }
1124 GRINGO_CLINGO_CATCH;
1125 }
1126
1127 // {{{1 solve handle
1128
1129 struct clingo_solve_handle : public Gringo::SolveFuture { };
1130
clingo_solve_handle_get(clingo_solve_handle_t * handle,clingo_solve_result_bitset_t * result)1131 extern "C" bool clingo_solve_handle_get(clingo_solve_handle_t *handle, clingo_solve_result_bitset_t *result) {
1132 GRINGO_CLINGO_TRY { *result = handle->get(); }
1133 GRINGO_CLINGO_CATCH;
1134 }
1135
clingo_solve_handle_wait(clingo_solve_handle_t * handle,double timeout,bool * result)1136 extern "C" void clingo_solve_handle_wait(clingo_solve_handle_t *handle, double timeout, bool *result) {
1137 try { *result = handle->wait(timeout); }
1138 catch (...) { std::terminate(); }
1139 }
clingo_solve_handle_cancel(clingo_solve_handle_t * handle)1140 extern "C" bool clingo_solve_handle_cancel(clingo_solve_handle_t *handle) {
1141 GRINGO_CLINGO_TRY { handle->cancel(); }
1142 GRINGO_CLINGO_CATCH;
1143 }
clingo_solve_handle_close(clingo_solve_handle_t * handle)1144 extern "C" bool clingo_solve_handle_close(clingo_solve_handle_t *handle) {
1145 GRINGO_CLINGO_TRY { if (handle) { delete handle; } }
1146 GRINGO_CLINGO_CATCH;
1147 }
clingo_solve_handle_model(clingo_solve_handle_t * handle,clingo_model_t const ** model)1148 extern "C" bool clingo_solve_handle_model(clingo_solve_handle_t *handle, clingo_model_t const **model) {
1149 GRINGO_CLINGO_TRY {
1150 *model = handle->model();
1151 }
1152 GRINGO_CLINGO_CATCH;
1153 }
clingo_solve_handle_core(clingo_solve_handle_t * handle,clingo_literal_t const ** core,size_t * size)1154 extern "C" bool clingo_solve_handle_core(clingo_solve_handle_t *handle, clingo_literal_t const **core, size_t *size) {
1155 GRINGO_CLINGO_TRY {
1156 auto core_span = handle->unsatCore();
1157 *core = core_span.first;
1158 *size = core_span.size;
1159 }
1160 GRINGO_CLINGO_CATCH;
1161 }
clingo_solve_handle_resume(clingo_solve_handle_t * handle)1162 extern "C" bool clingo_solve_handle_resume(clingo_solve_handle_t *handle) {
1163 GRINGO_CLINGO_TRY { handle->resume(); }
1164 GRINGO_CLINGO_CATCH;
1165 }
1166
1167 // {{{1 ast
1168
1169 #define C(name) \
1170 static_assert(clingo_ast_type_##name >= 0, "no matching type existis"); \
1171 clingo_ast_argument clingo_ast_argument_##name[] =
1172 #define A(name, type) { clingo_ast_attribute_##name, clingo_ast_attribute_type_##type }
1173 #define E(name) { #name, clingo_ast_argument_##name, sizeof(clingo_ast_argument_##name) / sizeof(clingo_ast_argument_t) }
1174
1175 // terms
C(id)1176 C(id) { A(location, location), A(name, string) };
C(variable)1177 C(variable) { A(location, location), A(name, string) };
C(symbolic_term)1178 C(symbolic_term) { A(location, location), A(symbol, symbol) };
C(unary_operation)1179 C(unary_operation) { A(location, location), A(operator_type, number), A(argument, ast) };
C(binary_operation)1180 C(binary_operation) { A(location, location), A(operator_type, number), A(left, ast), A(right, ast) };
C(interval)1181 C(interval) { A(location, location), A(left, ast), A(right, ast) };
C(function)1182 C(function) { A(location, location), A(name, string), A(arguments, ast_array), A(external, number) };
C(pool)1183 C(pool) { A(location, location), A(arguments, ast_array) };
1184 // csp terms
C(csp_product)1185 C(csp_product) { A(location, location), A(coefficient, ast), A(variable, optional_ast) };
C(csp_sum)1186 C(csp_sum) { A(location, location), A(terms, ast_array) };
C(csp_guard)1187 C(csp_guard) { A(comparison, number), A(term, ast) };
1188 // simple atoms
C(boolean_constant)1189 C(boolean_constant) { A(value, number) };
C(symbolic_atom)1190 C(symbolic_atom) { A(symbol, ast) };
C(comparison)1191 C(comparison) { A(comparison, number), A(left, ast), A(right, ast) };
C(csp_literal)1192 C(csp_literal) { A(location, location), A(term, ast), A(guards, ast_array) };
1193 // aggregates
C(aggregate_guard)1194 C(aggregate_guard) { A(comparison, number), A(term, ast) };
C(conditional_literal)1195 C(conditional_literal) { A(location, location), A(literal, ast), A(condition, ast_array) };
C(aggregate)1196 C(aggregate) { A(location, location), A(left_guard, optional_ast), A(elements, ast_array), A(right_guard, optional_ast) };
C(body_aggregate_element)1197 C(body_aggregate_element) { A(terms, ast_array), A(condition, ast_array) };
C(body_aggregate)1198 C(body_aggregate) { A(location, location), A(left_guard, optional_ast), A(function, number), A(elements, ast_array), A(right_guard, optional_ast) };
C(head_aggregate_element)1199 C(head_aggregate_element) { A(terms, ast_array), A(condition, ast) };
C(head_aggregate)1200 C(head_aggregate) { A(location, location), A(left_guard, optional_ast), A(function, number), A(elements, ast_array), A(right_guard, optional_ast) };
C(disjunction)1201 C(disjunction) { A(location, location), A(elements, ast_array) };
C(disjoint_element)1202 C(disjoint_element) { A(location, location), A(terms, ast_array), A(term, ast), A(condition, ast_array) };
C(disjoint)1203 C(disjoint) { A(location, location), A(elements, ast_array) };
1204 // theory atoms
C(theory_sequence)1205 C(theory_sequence) { A(location, location), A(sequence_type, number), A(terms, ast_array) };
C(theory_function)1206 C(theory_function) { A(location, location), A(name, string), A(arguments, ast_array) };
C(theory_unparsed_term_element)1207 C(theory_unparsed_term_element) { A(operators, string_array), A(term, ast) };
C(theory_unparsed_term)1208 C(theory_unparsed_term) { A(location, location), A(elements, ast_array) };
C(theory_guard)1209 C(theory_guard) { A(operator_name, string), A(term, ast) };
C(theory_atom_element)1210 C(theory_atom_element) { A(terms, ast_array), A(condition, ast_array) };
C(theory_atom)1211 C(theory_atom) { A(location, location), A(term, ast), A(elements, ast_array), A(guard, optional_ast) };
1212 // literals
C(literal)1213 C(literal) { A(location, location), A(sign, number), A(atom, ast) };
1214 // theory definition
C(theory_operator_definition)1215 C(theory_operator_definition) { A(location, location), A(name, string), A(priority, number), A(operator_type, number) };
C(theory_term_definition)1216 C(theory_term_definition) { A(location, location), A(name, string), A(operators, ast_array) };
C(theory_guard_definition)1217 C(theory_guard_definition) { A(operators, string_array), A(term, string) };
C(theory_atom_definition)1218 C(theory_atom_definition) { A(location, location), A(atom_type, number), A(name, string), A(arity, number), A(term, string), A(guard, optional_ast) };
1219 // statemets
C(rule)1220 C(rule) { A(location, location), A(head, ast), A(body, ast_array) };
C(definition)1221 C(definition) { A(location, location), A(name, string), A(value, ast), A(is_default, number) };
C(show_signature)1222 C(show_signature) { A(location, location), A(name, string), A(arity, number), A(positive, number), A(csp, number) };
C(show_term)1223 C(show_term) { A(location, location), A(term, ast), A(body, ast_array), A(csp, number) };
C(minimize)1224 C(minimize) { A(location, location), A(weight, ast), A(priority, ast), A(terms, ast_array), A(body, ast_array) };
C(script)1225 C(script) { A(location, location), A(name, string), A(code, string) };
C(program)1226 C(program) { A(location, location), A(name, string), A(parameters, ast_array) };
C(external)1227 C(external) { A(location, location), A(atom, ast), A(body, ast_array), A(external_type, ast) };
C(edge)1228 C(edge) { A(location, location), A(node_u, ast), A(node_v, ast), A(body, ast_array) };
C(heuristic)1229 C(heuristic) { A(location, location), A(atom, ast), A(body, ast_array), A(bias, ast), A(priority, ast), A(modifier, ast) };
C(project_atom)1230 C(project_atom) { A(location, location), A(atom, ast), A(body, ast_array) };
C(project_signature)1231 C(project_signature) { A(location, location), A(name, string), A(arity, number), A(positive, number) };
C(defined)1232 C(defined) { A(location, location), A(name, string), A(arity, number), A(positive, number) };
C(theory_definition)1233 C(theory_definition) { A(location, location), A(name, string), A(terms, ast_array), A(atoms, ast_array) };
1234
1235 clingo_ast_constructor_t const clingo_ast_constructor_list[] = {
1236 // terms
1237 E(id),
1238 E(variable),
1239 E(symbolic_term),
1240 E(unary_operation),
1241 E(binary_operation),
1242 E(interval),
1243 E(function),
1244 E(pool),
1245 // csp terms
1246 E(csp_product),
1247 E(csp_sum),
1248 E(csp_guard),
1249 // simple atoms
1250 E(boolean_constant),
1251 E(symbolic_atom),
1252 E(comparison),
1253 E(csp_literal),
1254 // aggregates
1255 E(aggregate_guard),
1256 E(conditional_literal),
1257 E(aggregate),
1258 E(body_aggregate_element),
1259 E(body_aggregate),
1260 E(head_aggregate_element),
1261 E(head_aggregate),
1262 E(disjunction),
1263 E(disjoint_element),
1264 E(disjoint),
1265 // theory atoms
1266 E(theory_sequence),
1267 E(theory_function),
1268 E(theory_unparsed_term_element),
1269 E(theory_unparsed_term),
1270 E(theory_guard),
1271 E(theory_atom_element),
1272 E(theory_atom),
1273 // literals
1274 E(literal),
1275 // theory definition
1276 E(theory_operator_definition),
1277 E(theory_term_definition),
1278 E(theory_guard_definition),
1279 E(theory_atom_definition),
1280 // statemets
1281 E(rule),
1282 E(definition),
1283 E(show_signature),
1284 E(show_term),
1285 E(minimize),
1286 E(script),
1287 E(program),
1288 E(external),
1289 E(edge),
1290 E(heuristic),
1291 E(project_atom),
1292 E(project_signature),
1293 E(defined),
1294 E(theory_definition)
1295 };
1296
1297 clingo_ast_constructors_t g_clingo_ast_constructors = {
1298 clingo_ast_constructor_list, sizeof(clingo_ast_constructor_list) / sizeof(clingo_ast_constructor_t)
1299 };
1300
1301 char const * attribute_list[] = {
1302 "argument",
1303 "arguments",
1304 "arity",
1305 "atom",
1306 "atoms",
1307 "atom_type",
1308 "bias",
1309 "body",
1310 "code",
1311 "coefficient",
1312 "comparison",
1313 "condition",
1314 "csp",
1315 "elements",
1316 "external",
1317 "external_type",
1318 "function",
1319 "guard",
1320 "guards",
1321 "head",
1322 "is_default",
1323 "left",
1324 "left_guard",
1325 "literal",
1326 "location",
1327 "modifier",
1328 "name",
1329 "node_u",
1330 "node_v",
1331 "operator_name",
1332 "operator_type",
1333 "operators",
1334 "parameters",
1335 "positive",
1336 "priority",
1337 "right",
1338 "right_guard",
1339 "sequence_type",
1340 "sign",
1341 "symbol",
1342 "term",
1343 "terms",
1344 "value",
1345 "variable",
1346 "weight",
1347 };
1348
1349 clingo_ast_attribute_names_t g_clingo_ast_attribute_names = {
1350 attribute_list,
1351 sizeof(attribute_list) / sizeof(char const *)
1352 };
1353
1354 #undef E
1355 #undef A
1356 #undef C
1357
clingo_ast_build(clingo_ast_type_t type,clingo_ast_t ** ast,...)1358 extern "C" bool clingo_ast_build(clingo_ast_type_t type, clingo_ast_t **ast, ...) {
1359 GRINGO_CLINGO_TRY {
1360 va_list args;
1361 va_start(args, ast);
1362
1363 Input::SAST sast{static_cast<clingo_ast_type_e>(type)};
1364
1365 auto const &cons = g_clingo_ast_constructors.constructors[type];
1366 for (auto it = cons.arguments, ie = it + cons.size; it != ie; ++it) {
1367 auto attribute = static_cast<clingo_ast_attribute_e>(it->attribute);
1368 switch (static_cast<clingo_ast_attribute_type_e>(it->type)) {
1369 case clingo_ast_attribute_type_number: {
1370 sast->value(attribute, va_arg(args, int));
1371 break;
1372 }
1373 case clingo_ast_attribute_type_symbol: {
1374 sast->value(attribute, Symbol{va_arg(args, clingo_symbol_t)});
1375 break;
1376 }
1377 case clingo_ast_attribute_type_location: {
1378 sast->value(attribute, conv(*va_arg(args, clingo_location_t*)));
1379 break;
1380 }
1381 case clingo_ast_attribute_type_string: {
1382 sast->value(attribute, String{va_arg(args, char const*)});
1383 break;
1384 }
1385 case clingo_ast_attribute_type_ast: {
1386 sast->value(attribute, Input::SAST{va_arg(args, Input::AST*)});
1387 break;
1388 }
1389 case clingo_ast_attribute_type_optional_ast: {
1390 sast->value(attribute, Input::OAST{Input::SAST{va_arg(args, Input::AST*)}});
1391 break;
1392 }
1393 case clingo_ast_attribute_type_string_array: {
1394 auto *data = va_arg(args, char const**);
1395 sast->value(attribute, Input::AST::StrVec{data, data + va_arg(args, size_t)});
1396 break;
1397 }
1398 case clingo_ast_attribute_type_ast_array: {
1399 auto *data = va_arg(args, Input::AST**);
1400 sast->value(attribute, Input::AST::ASTVec{data, data + va_arg(args, size_t)});
1401 break;
1402 }
1403 }
1404 }
1405
1406 *ast = reinterpret_cast<clingo_ast_t*>(sast.release());
1407 }
1408 GRINGO_CLINGO_CATCH;
1409 }
1410
clingo_ast_get_type(clingo_ast_t * ast,clingo_ast_type_t * type)1411 extern "C" bool clingo_ast_get_type(clingo_ast_t *ast, clingo_ast_type_t *type) {
1412 GRINGO_CLINGO_TRY {
1413 *type = ast->ast.type();
1414 }
1415 GRINGO_CLINGO_CATCH;
1416 }
1417
clingo_ast_copy(clingo_ast_t * ast,clingo_ast_t ** copy)1418 extern "C" bool clingo_ast_copy(clingo_ast_t *ast, clingo_ast_t **copy) {
1419 GRINGO_CLINGO_TRY {
1420 *copy = reinterpret_cast<clingo_ast_t*>(ast->ast.copy().release());
1421 }
1422 GRINGO_CLINGO_CATCH;
1423 }
1424
clingo_ast_deep_copy(clingo_ast_t * ast,clingo_ast_t ** copy)1425 extern "C" bool clingo_ast_deep_copy(clingo_ast_t *ast, clingo_ast_t **copy) {
1426 GRINGO_CLINGO_TRY {
1427 *copy = reinterpret_cast<clingo_ast_t*>(ast->ast.deepcopy().release());
1428 }
1429 GRINGO_CLINGO_CATCH;
1430 }
1431
clingo_ast_less_than(clingo_ast_t * a,clingo_ast_t * b)1432 extern "C" bool clingo_ast_less_than(clingo_ast_t *a, clingo_ast_t *b) {
1433 return a->ast < b->ast;
1434 }
1435
clingo_ast_equal(clingo_ast_t * a,clingo_ast_t * b)1436 extern "C" bool clingo_ast_equal(clingo_ast_t *a, clingo_ast_t *b) {
1437 return a->ast == b->ast;
1438 }
1439
clingo_ast_hash(clingo_ast_t * a)1440 extern "C" size_t clingo_ast_hash(clingo_ast_t *a) {
1441 return a->ast.hash();
1442 }
1443
clingo_ast_to_string_size(clingo_ast_t * ast,size_t * size)1444 extern "C" bool clingo_ast_to_string_size(clingo_ast_t *ast, size_t *size) {
1445 GRINGO_CLINGO_TRY { *size = print_size([&ast](std::ostream &out) { out << ast->ast; }); }
1446 GRINGO_CLINGO_CATCH;
1447 }
1448
clingo_ast_to_string(clingo_ast_t * ast,char * string,size_t size)1449 extern "C" bool clingo_ast_to_string(clingo_ast_t *ast, char *string, size_t size) {
1450 GRINGO_CLINGO_TRY { print(string, size, [&ast](std::ostream &out) { out << ast->ast; }); }
1451 GRINGO_CLINGO_CATCH;
1452 }
1453
clingo_ast_acquire(clingo_ast_t * ast)1454 extern "C" void clingo_ast_acquire(clingo_ast_t *ast) {
1455 ast->ast.incRef();
1456 }
1457
clingo_ast_release(clingo_ast_t * ast)1458 extern "C" void clingo_ast_release(clingo_ast_t *ast) {
1459 ast->ast.decRef();
1460 if (ast->ast.refCount() == 0) {
1461 delete ast;
1462 }
1463 }
1464
1465 template <class T>
get_attr(clingo_ast_t * ast,clingo_ast_attribute_t attribute)1466 T &get_attr(clingo_ast_t *ast, clingo_ast_attribute_t attribute) {
1467 return mpark::get<T>(ast->ast.value(static_cast<clingo_ast_attribute_e>(attribute)));
1468 }
1469
clingo_ast_has_attribute(clingo_ast_t * ast,clingo_ast_attribute_t attribute,bool * has_attribute)1470 extern "C" bool clingo_ast_has_attribute(clingo_ast_t *ast, clingo_ast_attribute_t attribute, bool *has_attribute) {
1471 GRINGO_CLINGO_TRY {
1472 *has_attribute = ast->ast.hasValue(static_cast<clingo_ast_attribute_e>(attribute));
1473 }
1474 GRINGO_CLINGO_CATCH;
1475 }
1476
clingo_ast_attribute_type(clingo_ast_t * ast,clingo_ast_attribute_t attribute,clingo_ast_attribute_type_t * type)1477 extern "C" bool clingo_ast_attribute_type(clingo_ast_t *ast, clingo_ast_attribute_t attribute, clingo_ast_attribute_type_t *type) {
1478 GRINGO_CLINGO_TRY {
1479 *type = static_cast<clingo_ast_attribute_type_t>(ast->ast.value(static_cast<clingo_ast_attribute_e>(attribute)).index());
1480 }
1481 GRINGO_CLINGO_CATCH;
1482 }
1483
clingo_ast_attribute_get_number(clingo_ast_t * ast,clingo_ast_attribute_t attribute,int * value)1484 extern "C" bool clingo_ast_attribute_get_number(clingo_ast_t *ast, clingo_ast_attribute_t attribute, int *value) {
1485 GRINGO_CLINGO_TRY {
1486 *value = get_attr<int>(ast, attribute);
1487 }
1488 GRINGO_CLINGO_CATCH;
1489 }
1490
clingo_ast_attribute_set_number(clingo_ast_t * ast,clingo_ast_attribute_t attribute,int value)1491 extern "C" bool clingo_ast_attribute_set_number(clingo_ast_t *ast, clingo_ast_attribute_t attribute, int value) {
1492 GRINGO_CLINGO_TRY {
1493 get_attr<int>(ast, attribute) = value;
1494 }
1495 GRINGO_CLINGO_CATCH;
1496 }
1497
clingo_ast_attribute_get_symbol(clingo_ast_t * ast,clingo_ast_attribute_t attribute,clingo_symbol_t * value)1498 extern "C" bool clingo_ast_attribute_get_symbol(clingo_ast_t *ast, clingo_ast_attribute_t attribute, clingo_symbol_t *value) {
1499 GRINGO_CLINGO_TRY {
1500 *value = get_attr<Symbol>(ast, attribute).rep();
1501 }
1502 GRINGO_CLINGO_CATCH;
1503 }
1504
clingo_ast_attribute_set_symbol(clingo_ast_t * ast,clingo_ast_attribute_t attribute,clingo_symbol_t value)1505 extern "C" bool clingo_ast_attribute_set_symbol(clingo_ast_t *ast, clingo_ast_attribute_t attribute, clingo_symbol_t value) {
1506 GRINGO_CLINGO_TRY {
1507 get_attr<Symbol>(ast, attribute) = Symbol{value};
1508 }
1509 GRINGO_CLINGO_CATCH;
1510 }
1511
clingo_ast_attribute_get_location(clingo_ast_t * ast,clingo_ast_attribute_t attribute,clingo_location_t * value)1512 extern "C" bool clingo_ast_attribute_get_location(clingo_ast_t *ast, clingo_ast_attribute_t attribute, clingo_location_t *value) {
1513 GRINGO_CLINGO_TRY {
1514 *value = conv(get_attr<Location>(ast, attribute));
1515 }
1516 GRINGO_CLINGO_CATCH;
1517 }
1518
clingo_ast_attribute_set_location(clingo_ast_t * ast,clingo_ast_attribute_t attribute,clingo_location_t const * value)1519 extern "C" bool clingo_ast_attribute_set_location(clingo_ast_t *ast, clingo_ast_attribute_t attribute, clingo_location_t const *value) {
1520 GRINGO_CLINGO_TRY {
1521 get_attr<Location>(ast, attribute) = conv(*value);
1522 }
1523 GRINGO_CLINGO_CATCH;
1524 }
1525
clingo_ast_attribute_get_string(clingo_ast_t * ast,clingo_ast_attribute_t attribute,char const ** value)1526 extern "C" bool clingo_ast_attribute_get_string(clingo_ast_t *ast, clingo_ast_attribute_t attribute, char const **value) {
1527 GRINGO_CLINGO_TRY {
1528 *value = get_attr<String>(ast, attribute).c_str();
1529 }
1530 GRINGO_CLINGO_CATCH;
1531 }
1532
clingo_ast_attribute_set_string(clingo_ast_t * ast,clingo_ast_attribute_t attribute,char const * value)1533 extern "C" bool clingo_ast_attribute_set_string(clingo_ast_t *ast, clingo_ast_attribute_t attribute, char const *value) {
1534 GRINGO_CLINGO_TRY {
1535 get_attr<String>(ast, attribute) = value;
1536 }
1537 GRINGO_CLINGO_CATCH;
1538 }
1539
clingo_ast_attribute_get_optional_ast(clingo_ast_t * ast,clingo_ast_attribute_t attribute,clingo_ast_t ** value)1540 extern "C" bool clingo_ast_attribute_get_optional_ast(clingo_ast_t *ast, clingo_ast_attribute_t attribute, clingo_ast_t **value) {
1541 GRINGO_CLINGO_TRY {
1542 *value = reinterpret_cast<clingo_ast_t*>(get_attr<Input::OAST>(ast, attribute).ast.get());
1543 if (*value != nullptr) {
1544 (*value)->ast.incRef();
1545 }
1546 }
1547 GRINGO_CLINGO_CATCH;
1548 }
1549
clingo_ast_attribute_set_optional_ast(clingo_ast_t * ast,clingo_ast_attribute_t attribute,clingo_ast_t * value)1550 extern "C" bool clingo_ast_attribute_set_optional_ast(clingo_ast_t *ast, clingo_ast_attribute_t attribute, clingo_ast_t *value) {
1551 GRINGO_CLINGO_TRY {
1552 get_attr<Input::OAST>(ast, attribute).ast = Input::SAST{reinterpret_cast<Input::AST*>(value)};
1553 }
1554 GRINGO_CLINGO_CATCH;
1555 }
1556
clingo_ast_attribute_get_ast(clingo_ast_t * ast,clingo_ast_attribute_t attribute,clingo_ast_t ** value)1557 extern "C" bool clingo_ast_attribute_get_ast(clingo_ast_t *ast, clingo_ast_attribute_t attribute, clingo_ast_t **value) {
1558 GRINGO_CLINGO_TRY {
1559 *value = reinterpret_cast<clingo_ast_t*>(get_attr<Input::SAST>(ast, attribute).get());
1560 (*value)->ast.incRef();
1561 }
1562 GRINGO_CLINGO_CATCH;
1563 }
1564
clingo_ast_attribute_set_ast(clingo_ast_t * ast,clingo_ast_attribute_t attribute,clingo_ast_t * value)1565 extern "C" bool clingo_ast_attribute_set_ast(clingo_ast_t *ast, clingo_ast_attribute_t attribute, clingo_ast_t *value) {
1566 GRINGO_CLINGO_TRY {
1567 if (value == nullptr) {
1568 throw std::runtime_error("ast must not be null");
1569 }
1570 get_attr<Input::SAST>(ast, attribute) = Input::SAST{reinterpret_cast<Input::AST*>(value)};
1571 }
1572 GRINGO_CLINGO_CATCH;
1573 }
1574
clingo_ast_attribute_get_string_at(clingo_ast_t * ast,clingo_ast_attribute_t attribute,size_t index,char const ** value)1575 extern "C" bool clingo_ast_attribute_get_string_at(clingo_ast_t *ast, clingo_ast_attribute_t attribute, size_t index, char const **value) {
1576 GRINGO_CLINGO_TRY {
1577 *value = get_attr<Input::AST::StrVec>(ast, attribute).at(index).c_str();
1578 }
1579 GRINGO_CLINGO_CATCH;
1580 }
1581
clingo_ast_attribute_set_string_at(clingo_ast_t * ast,clingo_ast_attribute_t attribute,size_t index,char const * value)1582 extern "C" bool clingo_ast_attribute_set_string_at(clingo_ast_t *ast, clingo_ast_attribute_t attribute, size_t index, char const *value) {
1583 GRINGO_CLINGO_TRY {
1584 get_attr<Input::AST::StrVec>(ast, attribute)[index] = value;
1585 }
1586 GRINGO_CLINGO_CATCH;
1587 }
1588
clingo_ast_attribute_delete_string_at(clingo_ast_t * ast,clingo_ast_attribute_t attribute,size_t index)1589 extern "C" bool clingo_ast_attribute_delete_string_at(clingo_ast_t *ast, clingo_ast_attribute_t attribute, size_t index) {
1590 GRINGO_CLINGO_TRY {
1591 auto &arr = get_attr<Input::AST::StrVec>(ast, attribute);
1592 arr.erase(arr.begin() + index);
1593 }
1594 GRINGO_CLINGO_CATCH;
1595 }
1596
clingo_ast_attribute_size_string_array(clingo_ast_t * ast,clingo_ast_attribute_t attribute,size_t * size)1597 extern "C" bool clingo_ast_attribute_size_string_array(clingo_ast_t *ast, clingo_ast_attribute_t attribute, size_t *size) {
1598 GRINGO_CLINGO_TRY {
1599 *size = get_attr<Input::AST::StrVec>(ast, attribute).size();
1600 }
1601 GRINGO_CLINGO_CATCH;
1602 }
1603
clingo_ast_attribute_insert_string_at(clingo_ast_t * ast,clingo_ast_attribute_t attribute,size_t index,char const * value)1604 extern "C" bool clingo_ast_attribute_insert_string_at(clingo_ast_t *ast, clingo_ast_attribute_t attribute, size_t index, char const *value) {
1605 GRINGO_CLINGO_TRY {
1606 auto &arr = get_attr<Input::AST::StrVec>(ast, attribute);
1607 arr.insert(arr.begin() + index, value);
1608 }
1609 GRINGO_CLINGO_CATCH;
1610 }
1611
clingo_ast_attribute_get_ast_at(clingo_ast_t * ast,clingo_ast_attribute_t attribute,size_t index,clingo_ast_t ** value)1612 extern "C" bool clingo_ast_attribute_get_ast_at(clingo_ast_t *ast, clingo_ast_attribute_t attribute, size_t index, clingo_ast_t **value) {
1613 GRINGO_CLINGO_TRY {
1614 *value = reinterpret_cast<clingo_ast_t*>(get_attr<Input::AST::ASTVec>(ast, attribute).at(index).get());
1615 (*value)->ast.incRef();
1616 }
1617 GRINGO_CLINGO_CATCH;
1618 }
1619
clingo_ast_attribute_set_ast_at(clingo_ast_t * ast,clingo_ast_attribute_t attribute,size_t index,clingo_ast_t * value)1620 extern "C" bool clingo_ast_attribute_set_ast_at(clingo_ast_t *ast, clingo_ast_attribute_t attribute, size_t index, clingo_ast_t *value) {
1621 GRINGO_CLINGO_TRY {
1622 if (value == nullptr) {
1623 throw std::runtime_error("ast must not be null");
1624 }
1625 get_attr<Input::AST::ASTVec>(ast, attribute)[index] = Input::SAST{reinterpret_cast<Input::AST*>(value)};
1626 }
1627 GRINGO_CLINGO_CATCH;
1628 }
1629
clingo_ast_attribute_delete_ast_at(clingo_ast_t * ast,clingo_ast_attribute_t attribute,size_t index)1630 extern "C" bool clingo_ast_attribute_delete_ast_at(clingo_ast_t *ast, clingo_ast_attribute_t attribute, size_t index) {
1631 GRINGO_CLINGO_TRY {
1632 auto &arr = get_attr<Input::AST::ASTVec>(ast, attribute);
1633 arr.erase(arr.begin() + index);
1634 }
1635 GRINGO_CLINGO_CATCH;
1636 }
1637
clingo_ast_attribute_size_ast_array(clingo_ast_t * ast,clingo_ast_attribute_t attribute,size_t * size)1638 extern "C" bool clingo_ast_attribute_size_ast_array(clingo_ast_t *ast, clingo_ast_attribute_t attribute, size_t *size) {
1639 GRINGO_CLINGO_TRY {
1640 *size = get_attr<Input::AST::ASTVec>(ast, attribute).size();
1641 }
1642 GRINGO_CLINGO_CATCH;
1643 }
1644
clingo_ast_attribute_insert_ast_at(clingo_ast_t * ast,clingo_ast_attribute_t attribute,size_t index,clingo_ast_t * value)1645 extern "C" bool clingo_ast_attribute_insert_ast_at(clingo_ast_t *ast, clingo_ast_attribute_t attribute, size_t index, clingo_ast_t *value) {
1646 GRINGO_CLINGO_TRY {
1647 if (value == nullptr) {
1648 throw std::runtime_error("ast must not be null");
1649 }
1650 auto &arr = get_attr<Input::AST::ASTVec>(ast, attribute);
1651 arr.insert(arr.begin() + index, Input::SAST{reinterpret_cast<Input::AST*>(value)});
1652 }
1653 GRINGO_CLINGO_CATCH;
1654 }
1655
clingo_ast_parse_string(char const * program,clingo_ast_callback_t cb,void * cb_data,clingo_logger_t logger,void * logger_data,unsigned message_limit)1656 extern "C" bool clingo_ast_parse_string(char const *program, clingo_ast_callback_t cb, void *cb_data, clingo_logger_t logger, void *logger_data, unsigned message_limit) {
1657 GRINGO_CLINGO_TRY {
1658 auto builder = Input::build([cb, cb_data](Input::SAST ast) {
1659 forwardError(cb(reinterpret_cast<clingo_ast_t*>(ast.get()), cb_data));
1660 });
1661 bool incmode = false;
1662 Input::NonGroundParser parser{*builder, incmode};
1663 Logger::Printer printer;
1664 if (logger != nullptr) { printer = [logger, logger_data](Warnings code, char const *msg) { logger(static_cast<clingo_warning_t>(code), msg, logger_data); }; }
1665 Logger log(printer, message_limit);
1666 parser.pushStream("<string>", gringo_make_unique<std::istringstream>(program), log);
1667 parser.parse(log);
1668 if (log.hasError()) { throw std::runtime_error("syntax error"); }
1669 }
1670 GRINGO_CLINGO_CATCH;
1671 }
1672
clingo_ast_parse_files(char const * const * file,size_t n,clingo_ast_callback_t cb,void * cb_data,clingo_logger_t logger,void * logger_data,unsigned message_limit)1673 extern "C" bool clingo_ast_parse_files(char const * const *file, size_t n, clingo_ast_callback_t cb, void *cb_data, clingo_logger_t logger, void *logger_data, unsigned message_limit) {
1674 GRINGO_CLINGO_TRY {
1675 auto builder = Input::build([cb, cb_data](Input::SAST ast) {
1676 forwardError(cb(reinterpret_cast<clingo_ast_t*>(ast.get()), cb_data));
1677 });
1678 bool incmode = false;
1679 Input::NonGroundParser parser(*builder, incmode);
1680 Logger::Printer printer;
1681 if (logger != nullptr) { printer = [logger, logger_data](Warnings code, char const *msg) { logger(static_cast<clingo_warning_t>(code), msg, logger_data); }; }
1682 Logger log(printer, message_limit);
1683 for (auto it = file, ie = file + n; it != ie; ++it) {
1684 parser.pushFile(std::string{*it}, log);
1685 }
1686 if (n == 0) {
1687 parser.pushFile("-", log);
1688 }
1689 parser.parse(log);
1690 if (log.hasError()) { throw std::runtime_error("syntax error"); }
1691 }
1692 GRINGO_CLINGO_CATCH;
1693 }
1694
clingo_ast_unpool(clingo_ast_t * ast,clingo_ast_unpool_type_bitset_t unpool_type,clingo_ast_callback_t callback,void * callback_data)1695 extern "C" bool clingo_ast_unpool(clingo_ast_t *ast, clingo_ast_unpool_type_bitset_t unpool_type, clingo_ast_callback_t callback, void *callback_data) {
1696 GRINGO_CLINGO_TRY {
1697 Input::SAST sast{&ast->ast};
1698 auto pool = Input::unpool(sast, unpool_type);
1699 if (pool.has_value()) {
1700 for (auto &unpooled : *pool) {
1701 forwardError(callback(reinterpret_cast<clingo_ast_t*>(unpooled.get()), callback_data));
1702 }
1703 }
1704 else {
1705 forwardError(callback(ast, callback_data));
1706 }
1707 }
1708 GRINGO_CLINGO_CATCH;
1709 }
1710
1711 // {{{1 control
1712
1713 struct clingo_program_builder : clingo_control_t { };
clingo_program_builder_begin(clingo_program_builder_t * bld)1714 extern "C" bool clingo_program_builder_begin(clingo_program_builder_t *bld) {
1715 GRINGO_CLINGO_TRY { bld->beginAdd(); }
1716 GRINGO_CLINGO_CATCH;
1717 }
1718
clingo_program_builder_add(clingo_program_builder_t * bld,clingo_ast_t * ast)1719 extern "C" bool clingo_program_builder_add(clingo_program_builder_t *bld, clingo_ast_t *ast) {
1720 GRINGO_CLINGO_TRY { bld->add(*ast); }
1721 GRINGO_CLINGO_CATCH;
1722 }
1723
clingo_program_builder_end(clingo_program_builder_t * bld)1724 extern "C" bool clingo_program_builder_end(clingo_program_builder_t *bld) {
1725 GRINGO_CLINGO_TRY { bld->endAdd(); }
1726 GRINGO_CLINGO_CATCH;
1727 }
1728
clingo_control_free(clingo_control_t * ctl)1729 extern "C" void clingo_control_free(clingo_control_t *ctl) {
1730 delete ctl;
1731 }
1732
clingo_control_add(clingo_control_t * ctl,char const * name,char const * const * params,size_t n,char const * part)1733 extern "C" bool clingo_control_add(clingo_control_t *ctl, char const *name, char const * const *params, size_t n, char const *part) {
1734 GRINGO_CLINGO_TRY {
1735 StringVec p;
1736 for (char const * const *it = params, * const *ie = it + n; it != ie; ++it) {
1737 p.emplace_back(*it);
1738 }
1739 ctl->add(name, p, part);
1740 }
1741 GRINGO_CLINGO_CATCH;
1742 }
1743
1744 namespace {
1745
1746 struct ClingoContext : Context {
ClingoContext__anonb1f002eb1111::ClingoContext1747 ClingoContext(clingo_control_t *ctl, clingo_ground_callback_t cb, void *data)
1748 : ctl(ctl)
1749 , cb(cb)
1750 , data(data) {}
1751
callable__anonb1f002eb1111::ClingoContext1752 bool callable(String) override {
1753 return cb != nullptr;
1754 }
1755
call__anonb1f002eb1111::ClingoContext1756 SymVec call(Location const &loc, String name, SymSpan args, Logger &) override {
1757 assert(cb);
1758 clingo_location_t loc_c{loc.beginFilename.c_str(), loc.endFilename.c_str(), loc.beginLine, loc.endLine, loc.beginColumn, loc.endColumn};
1759 auto ret = cb(&loc_c, name.c_str(), reinterpret_cast<clingo_symbol_t const *>(args.first), args.size, data, [](clingo_symbol_t const * ret_c, size_t n, void *data) -> bool {
1760 auto t = static_cast<ClingoContext*>(data);
1761 GRINGO_CLINGO_TRY {
1762 for (auto it = ret_c, ie = it + n; it != ie; ++it) {
1763 t->ret.emplace_back(Symbol(*it));
1764 }
1765 } GRINGO_CLINGO_CATCH;
1766 }, this);
1767 if (!ret) { throw ClingoError(); }
1768 return std::move(this->ret);
1769 }
exec__anonb1f002eb1111::ClingoContext1770 void exec(String, Location, String) override {
1771 throw std::logic_error("Context::exec: not supported");
1772 }
1773 ~ClingoContext() noexcept = default;
1774
1775 clingo_control_t *ctl;
1776 clingo_ground_callback_t cb;
1777 void *data;
1778 SymVec ret;
1779 };
1780
1781 }
1782
clingo_control_ground(clingo_control_t * ctl,clingo_part_t const * vec,size_t n,clingo_ground_callback_t cb,void * data)1783 extern "C" bool clingo_control_ground(clingo_control_t *ctl, clingo_part_t const * vec, size_t n, clingo_ground_callback_t cb, void *data) {
1784 GRINGO_CLINGO_TRY {
1785 Control::GroundVec gv;
1786 gv.reserve(n);
1787 for (auto it = vec, ie = it + n; it != ie; ++it) {
1788 SymVec params;
1789 params.reserve(it->size);
1790 for (auto jt = it->params, je = jt + it->size; jt != je; ++jt) {
1791 params.emplace_back(Symbol(*jt));
1792 }
1793 gv.emplace_back(it->name, params);
1794 }
1795 ClingoContext cctx(ctl, cb, data);
1796 ctl->ground(gv, cb ? &cctx : nullptr);
1797 } GRINGO_CLINGO_CATCH;
1798 }
1799
1800 namespace {
1801
1802 class ClingoSolveEventHandler : public SolveEventHandler {
1803 public:
ClingoSolveEventHandler(clingo_solve_event_callback_t cb,void * data)1804 ClingoSolveEventHandler(clingo_solve_event_callback_t cb, void *data)
1805 : cb_(cb)
1806 , data_(data) { }
1807 private:
on_model(Model & model)1808 bool on_model(Model &model) override {
1809 bool goon = true;
1810 if (!cb_(clingo_solve_event_type_model, &model, data_, &goon)) { throw ClingoError(); }
1811 return goon;
1812 }
on_unsat(Potassco::Span<int64_t> optimization)1813 bool on_unsat(Potassco::Span<int64_t> optimization) override {
1814 bool goon = true;
1815 if (!cb_(clingo_solve_event_type_unsat, &optimization, data_, &goon)) {
1816 clingo_terminate("error in SolveEventHandler::on_unsat going to terminate");
1817 }
1818 return goon;
1819 }
on_finish(SolveResult ret,Potassco::AbstractStatistics * step,Potassco::AbstractStatistics * accu)1820 void on_finish(SolveResult ret, Potassco::AbstractStatistics *step, Potassco::AbstractStatistics *accu) override {
1821 bool goon = true;
1822 clingo_statistics_t *stats[] = {static_cast<clingo_statistics_t*>(step), static_cast<clingo_statistics_t*>(accu)};
1823 if (step && accu && !cb_(clingo_solve_event_type_statistics, &stats, data_, &goon)) {
1824 clingo_terminate("error in SolveEventHandler::on_statistics going to terminate");
1825 }
1826 if (!cb_(clingo_solve_event_type_finish, &ret, data_, &goon)) {
1827 clingo_terminate("error in SolveEventHandler::on_finish going to terminate");
1828 }
1829 }
1830 private:
1831 clingo_solve_event_callback_t cb_;
1832 void *data_;
1833 };
1834
1835 } // namespace
1836
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)1837 extern "C" 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) {
1838 GRINGO_CLINGO_TRY { *handle = static_cast<clingo_solve_handle_t*>(control->solve(
1839 Potassco::toSpan(assumptions, assumptions_size),
1840 mode,
1841 notify ? gringo_make_unique<ClingoSolveEventHandler>(notify, data) : nullptr
1842 ).release()); }
1843 GRINGO_CLINGO_CATCH;
1844 }
1845
clingo_control_assign_external(clingo_control_t * ctl,clingo_literal_t literal,clingo_truth_value_t value)1846 extern "C" bool clingo_control_assign_external(clingo_control_t *ctl, clingo_literal_t literal, clingo_truth_value_t value) {
1847 GRINGO_CLINGO_TRY {
1848 if (literal < 0) {
1849 literal = -literal;
1850 if (value == Potassco::Value_t::True) { value = Potassco::Value_t::False; }
1851 else if (value == Potassco::Value_t::False) { value = Potassco::Value_t::True; }
1852 }
1853 ctl->assignExternal(literal, static_cast<Potassco::Value_t>(value));
1854 }
1855 GRINGO_CLINGO_CATCH;
1856 }
1857
clingo_control_release_external(clingo_control_t * ctl,clingo_literal_t literal)1858 extern "C" bool clingo_control_release_external(clingo_control_t *ctl, clingo_literal_t literal) {
1859 GRINGO_CLINGO_TRY { ctl->assignExternal(std::abs(literal), Potassco::Value_t::Release); }
1860 GRINGO_CLINGO_CATCH;
1861 }
1862
clingo_control_program_builder(clingo_control_t * ctl,clingo_program_builder_t ** ret)1863 extern "C" bool clingo_control_program_builder(clingo_control_t *ctl, clingo_program_builder_t **ret) {
1864 GRINGO_CLINGO_TRY { *ret = static_cast<clingo_program_builder_t*>(ctl); }
1865 GRINGO_CLINGO_CATCH;
1866 }
1867
clingo_control_symbolic_atoms(clingo_control_t const * ctl,clingo_symbolic_atoms_t const ** ret)1868 extern "C" bool clingo_control_symbolic_atoms(clingo_control_t const *ctl, clingo_symbolic_atoms_t const **ret) {
1869 GRINGO_CLINGO_TRY { *ret = &ctl->getDomain(); }
1870 GRINGO_CLINGO_CATCH;
1871 }
1872
clingo_control_theory_atoms(clingo_control_t const * ctl,clingo_theory_atoms_t const ** ret)1873 extern "C" bool clingo_control_theory_atoms(clingo_control_t const *ctl, clingo_theory_atoms_t const **ret) {
1874 GRINGO_CLINGO_TRY { *ret = static_cast<clingo_theory_atoms const *>(&ctl->theory()); }
1875 GRINGO_CLINGO_CATCH;
1876 }
1877
1878 namespace {
1879
1880 class ClingoPropagator : public Propagator {
1881 public:
ClingoPropagator(clingo_propagator_t prop,void * data)1882 ClingoPropagator(clingo_propagator_t prop, void *data)
1883 : prop_(prop)
1884 , data_(data) { }
init(PropagateInit & init)1885 void init(PropagateInit &init) override {
1886 if (prop_.init && !prop_.init(&init, data_)) { throw ClingoError(); }
1887 }
1888
propagate(Potassco::AbstractSolver & solver,ChangeList const & changes)1889 void propagate(Potassco::AbstractSolver& solver, ChangeList const &changes) override {
1890 if (prop_.propagate && !prop_.propagate(static_cast<clingo_propagate_control_t*>(&solver), changes.first, changes.size, data_)) { throw ClingoError(); }
1891 }
1892
undo(Potassco::AbstractSolver const & solver,ChangeList const & undo)1893 void undo(Potassco::AbstractSolver const &solver, ChangeList const &undo) override {
1894 if (prop_.undo) { prop_.undo(static_cast<clingo_propagate_control_t const *>(&solver), undo.first, undo.size, data_); }
1895 }
1896
check(Potassco::AbstractSolver & solver)1897 void check(Potassco::AbstractSolver& solver) override {
1898 if (prop_.check && !prop_.check(static_cast<clingo_propagate_control_t*>(&solver), data_)) { throw ClingoError(); }
1899 }
1900
hasHeuristic() const1901 bool hasHeuristic() const override {
1902 return prop_.decide;
1903 }
1904
decide(Id_t solverId,Potassco::AbstractAssignment const & assignment,Lit fallback)1905 Lit decide(Id_t solverId, Potassco::AbstractAssignment const &assignment, Lit fallback) override {
1906 clingo_literal_t decision = 0;
1907 if (prop_.decide && !prop_.decide(solverId, const_cast<clingo_assignment_t*>(static_cast<clingo_assignment_t const*>(&assignment)), fallback, data_, &decision)) { throw ClingoError(); }
1908 return decision;
1909 }
1910 private:
1911 clingo_propagator_t prop_;
1912 void *data_;
1913 };
1914
1915 } // namespace
1916
clingo_control_register_propagator(clingo_control_t * ctl,clingo_propagator_t const * propagator,void * data,bool sequential)1917 extern "C" bool clingo_control_register_propagator(clingo_control_t *ctl, clingo_propagator_t const *propagator, void *data, bool sequential) {
1918 GRINGO_CLINGO_TRY { ctl->registerPropagator(gringo_make_unique<ClingoPropagator>(*propagator, data), sequential); }
1919 GRINGO_CLINGO_CATCH;
1920 }
1921
clingo_control_has_const(clingo_control_t const * ctl,char const * name,bool * ret)1922 extern "C" bool clingo_control_has_const(clingo_control_t const *ctl, char const *name, bool *ret) {
1923 GRINGO_CLINGO_TRY {
1924 auto sym = ctl->getConst(name);
1925 *ret = sym.type() != SymbolType::Special;
1926 }
1927 GRINGO_CLINGO_CATCH;
1928 }
1929
clingo_control_get_const(clingo_control_t const * ctl,char const * name,clingo_symbol_t * ret)1930 extern "C" bool clingo_control_get_const(clingo_control_t const *ctl, char const *name, clingo_symbol_t *ret) {
1931 GRINGO_CLINGO_TRY {
1932 auto sym = ctl->getConst(name);
1933 *ret = sym.type() != SymbolType::Special ? sym.rep() : Symbol::createId(name).rep();
1934 }
1935 GRINGO_CLINGO_CATCH;
1936 }
1937
clingo_control_interrupt(clingo_control_t * ctl)1938 extern "C" void clingo_control_interrupt(clingo_control_t *ctl) {
1939 ctl->interrupt();
1940 }
1941
clingo_control_load(clingo_control_t * ctl,char const * file)1942 extern "C" bool clingo_control_load(clingo_control_t *ctl, char const *file) {
1943 GRINGO_CLINGO_TRY { ctl->load(file); }
1944 GRINGO_CLINGO_CATCH;
1945 }
1946
clingo_control_set_enable_enumeration_assumption(clingo_control_t * ctl,bool value)1947 extern "C" bool clingo_control_set_enable_enumeration_assumption(clingo_control_t *ctl, bool value) {
1948 GRINGO_CLINGO_TRY { ctl->useEnumAssumption(value); }
1949 GRINGO_CLINGO_CATCH;
1950 }
1951
clingo_control_get_enable_enumeration_assumption(clingo_control_t * ctl)1952 extern "C" bool clingo_control_get_enable_enumeration_assumption(clingo_control_t *ctl) {
1953 return ctl->useEnumAssumption();
1954 }
1955
clingo_control_cleanup(clingo_control_t * ctl)1956 extern "C" bool clingo_control_cleanup(clingo_control_t *ctl) {
1957 GRINGO_CLINGO_TRY { ctl->cleanup(); }
1958 GRINGO_CLINGO_CATCH;
1959 }
1960
clingo_control_set_enable_cleanup(clingo_control_t * ctl,bool value)1961 extern "C" bool clingo_control_set_enable_cleanup(clingo_control_t *ctl, bool value) {
1962 GRINGO_CLINGO_TRY { ctl->enableCleanup(value); }
1963 GRINGO_CLINGO_CATCH;
1964 }
1965
clingo_control_get_enable_cleanup(clingo_control_t * ctl)1966 extern "C" bool clingo_control_get_enable_cleanup(clingo_control_t *ctl) {
1967 return ctl->enableCleanup();
1968 }
1969
clingo_control_backend(clingo_control_t * ctl,clingo_backend_t ** ret)1970 extern "C" bool clingo_control_backend(clingo_control_t *ctl, clingo_backend_t **ret) {
1971 GRINGO_CLINGO_TRY { *ret = static_cast<clingo_backend_t*>(ctl); }
1972 GRINGO_CLINGO_CATCH;
1973 }
1974
clingo_control_configuration(clingo_control_t * ctl,clingo_configuration_t ** conf)1975 extern "C" bool clingo_control_configuration(clingo_control_t *ctl, clingo_configuration_t **conf) {
1976 GRINGO_CLINGO_TRY { *conf = static_cast<clingo_configuration_t*>(&ctl->getConf()); }
1977 GRINGO_CLINGO_CATCH;
1978 }
1979
clingo_control_is_conflicting(clingo_control_t const * control)1980 extern "C" bool clingo_control_is_conflicting(clingo_control_t const *control) {
1981 return control->isConflicting();
1982 }
1983
clingo_control_statistics(clingo_control_t const * ctl,clingo_statistics_t const ** stats)1984 extern "C" bool clingo_control_statistics(clingo_control_t const *ctl, clingo_statistics_t const **stats) {
1985 GRINGO_CLINGO_TRY { *stats = static_cast<clingo_statistics_t const *>(ctl->statistics()); }
1986 GRINGO_CLINGO_CATCH;
1987 }
1988
clingo_control_clasp_facade(clingo_control_t * ctl,void ** clasp)1989 extern "C" bool clingo_control_clasp_facade(clingo_control_t *ctl, void **clasp) {
1990 GRINGO_CLINGO_TRY { *clasp = ctl->claspFacade(); }
1991 GRINGO_CLINGO_CATCH;
1992 }
1993
1994 namespace {
1995
1996 class Observer : public Backend {
1997 public:
Observer(clingo_ground_program_observer_t obs,void * data)1998 Observer(clingo_ground_program_observer_t obs, void *data) : obs_(obs), data_(data) { }
1999 ~Observer() override = default;
2000
initProgram(bool incremental)2001 void initProgram(bool incremental) override {
2002 call(obs_.init_program, incremental);
2003 }
beginStep()2004 void beginStep() override {
2005 call(obs_.begin_step);
2006 }
endStep()2007 void endStep() override {
2008 call(obs_.end_step);
2009 }
2010
rule(Potassco::Head_t ht,Potassco::AtomSpan const & head,Potassco::LitSpan const & body)2011 void rule(Potassco::Head_t ht, Potassco::AtomSpan const& head,Potassco::LitSpan const &body) override {
2012 call(obs_.rule, ht == Potassco::Head_t::Choice, head.first, head.size, body.first, body.size);
2013 }
rule(Potassco::Head_t ht,Potassco::AtomSpan const & head,Weight_t bound,Potassco::WeightLitSpan const & body)2014 void rule(Potassco::Head_t ht, Potassco::AtomSpan const &head, Weight_t bound,Potassco::WeightLitSpan const &body) override {
2015 call(obs_.weight_rule, ht == Potassco::Head_t::Choice, head.first, head.size, bound, reinterpret_cast<clingo_weighted_literal_t const *>(body.first), body.size);
2016 }
minimize(Weight_t prio,Potassco::WeightLitSpan const & lits)2017 void minimize(Weight_t prio, Potassco::WeightLitSpan const &lits) override {
2018 call(obs_.minimize, prio, reinterpret_cast<clingo_weighted_literal_t const *>(lits.first), lits.size);
2019 }
project(Potassco::AtomSpan const & atoms)2020 void project(Potassco::AtomSpan const &atoms) override {
2021 call(obs_.project, atoms.first, atoms.size);
2022 }
output(Symbol sym,Potassco::Atom_t atom)2023 void output(Symbol sym, Potassco::Atom_t atom) override {
2024 call(obs_.output_atom, sym.rep(), atom);
2025 }
output(Symbol sym,Potassco::LitSpan const & condition)2026 void output(Symbol sym, Potassco::LitSpan const& condition) override {
2027 call(obs_.output_term, sym.rep(), condition.first, condition.size);
2028 }
output(Symbol sym,int value,Potassco::LitSpan const & condition)2029 void output(Symbol sym, int value, Potassco::LitSpan const& condition) override {
2030 call(obs_.output_csp, sym.rep(), value, condition.first, condition.size);
2031 }
external(Atom_t a,Potassco::Value_t v)2032 void external(Atom_t a, Potassco::Value_t v) override {
2033 call(obs_.external, a, v);
2034 }
assume(Potassco::LitSpan const & lits)2035 void assume(Potassco::LitSpan const &lits) override {
2036 call(obs_.assume, lits.first, lits.size);
2037 }
heuristic(Atom_t a,Potassco::Heuristic_t t,int bias,unsigned prio,Potassco::LitSpan const & condition)2038 void heuristic(Atom_t a, Potassco::Heuristic_t t, int bias, unsigned prio, Potassco::LitSpan const &condition) override {
2039 call(obs_.heuristic, a, t, bias, prio, condition.first, condition.size);
2040 }
acycEdge(int s,int t,Potassco::LitSpan const & condition)2041 void acycEdge(int s, int t, Potassco::LitSpan const &condition) override {
2042 call(obs_.acyc_edge, s, t, condition.first, condition.size);
2043 }
2044
theoryTerm(Id_t termId,int number)2045 void theoryTerm(Id_t termId, int number) override {
2046 call(obs_.theory_term_number, termId, number);
2047 }
theoryTerm(Id_t termId,StringSpan const & name)2048 void theoryTerm(Id_t termId, StringSpan const &name) override {
2049 std::string s{name.first, name.size};
2050 call(obs_.theory_term_string, termId, s.c_str());
2051 }
theoryTerm(Id_t termId,int cId,Potassco::IdSpan const & args)2052 void theoryTerm(Id_t termId, int cId, Potassco::IdSpan const &args) override {
2053 call(obs_.theory_term_compound, termId, cId, args.first, args.size);
2054 }
theoryElement(Id_t elementId,Potassco::IdSpan const & terms,Potassco::LitSpan const & cond)2055 void theoryElement(Id_t elementId, Potassco::IdSpan const &terms, Potassco::LitSpan const &cond) override {
2056 call(obs_.theory_element, elementId, terms.first, terms.size, cond.first, cond.size);
2057 }
theoryAtom(Id_t atomOrZero,Id_t termId,Potassco::IdSpan const & elements)2058 void theoryAtom(Id_t atomOrZero, Id_t termId, Potassco::IdSpan const &elements) override {
2059 call(obs_.theory_atom, atomOrZero, termId, elements.first, elements.size);
2060 }
theoryAtom(Id_t atomOrZero,Id_t termId,Potassco::IdSpan const & elements,Id_t op,Id_t rhs)2061 void theoryAtom(Id_t atomOrZero, Id_t termId, Potassco::IdSpan const &elements, Id_t op, Id_t rhs) override {
2062 call(obs_.theory_atom_with_guard, atomOrZero, termId, elements.first, elements.size, op, rhs);
2063 }
2064 private:
2065 template <class CB, class... Args>
call(CB * cb,Args &&...args)2066 void call(CB *cb, Args&&... args) {
2067 if (cb && !(*cb)(std::forward<Args>(args)..., data_)) { throw ClingoError(); }
2068 }
2069 private:
2070 clingo_ground_program_observer_t obs_;
2071 void *data_;
2072 };
2073
2074 } // namespace
2075
clingo_control_register_observer(clingo_control_t * control,clingo_ground_program_observer_t const * observer,bool replace,void * data)2076 extern "C" bool clingo_control_register_observer(clingo_control_t *control, clingo_ground_program_observer_t const *observer, bool replace, void *data) {
2077 GRINGO_CLINGO_TRY { control->registerObserver(gringo_make_unique<Observer>(*observer, data), replace); }
2078 GRINGO_CLINGO_CATCH;
2079 }
2080
clingo_control_new(char const * const * args,size_t n,clingo_logger_t logger,void * data,unsigned message_limit,clingo_control_t ** ctl)2081 extern "C" bool clingo_control_new(char const *const * args, size_t n, clingo_logger_t logger, void *data, unsigned message_limit, clingo_control_t **ctl) {
2082 GRINGO_CLINGO_TRY {
2083 static std::mutex mut;
2084 std::lock_guard<std::mutex> grd(mut);
2085 *ctl = new ClingoLib(g_scripts(), numeric_cast<int>(n), args, logger ? [logger, data](Warnings code, char const *msg) { logger(static_cast<clingo_warning_t>(code), msg, data); } : Logger::Printer(nullptr), message_limit);
2086 }
2087 GRINGO_CLINGO_CATCH;
2088 }
2089
2090 namespace {
2091
2092 class CScript : public Script {
2093 public:
CScript(clingo_script_t script,void * data)2094 CScript(clingo_script_t script, void *data) : script_(script), data_(data) { }
~CScript()2095 ~CScript() noexcept override {
2096 if (script_.free) { script_.free(data_); }
2097 }
2098 private:
exec(String,Location loc,String code)2099 void exec(String, Location loc, String code) override {
2100 if (script_.execute) {
2101 auto l = conv(loc);
2102 forwardError(script_.execute(&l, code.c_str(), data_));
2103 }
2104 }
call(Location const & loc,String name,SymSpan args,Logger &)2105 SymVec call(Location const &loc, String name, SymSpan args, Logger &) override {
2106 using Data = std::pair<SymVec, std::exception_ptr>;
2107 Data data;
2108 auto l = conv(loc);
2109 forwardError(script_.call(
2110 &l, name.c_str(), reinterpret_cast<clingo_symbol_t const *>(args.first), args.size,
2111 [](clingo_symbol_t const *symbols, size_t symbols_size, void *pdata) {
2112 auto &data = *static_cast<Data*>(pdata);
2113 GRINGO_CALLBACK_TRY {
2114 for (auto it = symbols, ie = it + symbols_size; it != ie; ++it) {
2115 data.first.emplace_back(Symbol{*it});
2116 }
2117 }
2118 GRINGO_CALLBACK_CATCH(data.second);
2119 },
2120 &data, data_), &data.second);
2121 return data.first;
2122 }
callable(String name)2123 bool callable(String name) override {
2124 bool ret;
2125 forwardError(script_.callable(name.c_str(), &ret, data_));
2126 return ret;
2127 }
main(Control & ctl)2128 void main(Control &ctl) override {
2129 forwardError(script_.main(&ctl, data_));
2130 }
version()2131 char const *version() override {
2132 return script_.version;
2133 }
2134 private:
2135 clingo_script_t script_;
2136 void *data_;
2137 };
2138
2139 } // namespace
2140
clingo_register_script(char const * type,clingo_script_t const * script,void * data)2141 extern "C" CLINGO_VISIBILITY_DEFAULT bool clingo_register_script(char const *type, clingo_script_t const *script, void *data) {
2142 GRINGO_CLINGO_TRY { g_scripts().registerScript(type, gringo_make_unique<CScript>(*script, data)); }
2143 GRINGO_CLINGO_CATCH;
2144 }
2145
clingo_script_version(char const * type)2146 extern "C" CLINGO_VISIBILITY_DEFAULT char const *clingo_script_version(char const *type) {
2147 return g_scripts().version(type);
2148 }
2149
clingo_main_(int argc,char * argv[])2150 extern "C" CLINGO_VISIBILITY_DEFAULT int clingo_main_(int argc, char *argv[]) {
2151 Gringo::ClingoApp app;
2152 return app.main(argc, argv);
2153 }
2154
str_duplicate(char const * str)2155 char *str_duplicate(char const *str) {
2156 char *ret = new char[strlen(str) + 1];
2157 std::strcpy(ret, str);
2158 return ret;
2159 }
2160
2161 struct clingo_options : ClingoApp {};
2162
2163 namespace {
2164
2165 class CClingoApp : public IClingoApp {
2166 public:
CClingoApp(clingo_application_t app,void * data)2167 CClingoApp(clingo_application_t app, void *data)
2168 : app_(app)
2169 , data_{data} {
2170 name_ = app_.program_name ? app_.program_name(data_) : IClingoApp::program_name();
2171 version_ = app_.version ? app_.version(data_) : IClingoApp::version();
2172 }
message_limit() const2173 unsigned message_limit() const override {
2174 if (app_.message_limit) {
2175 return app_.message_limit(data_);
2176 }
2177 else {
2178 return IClingoApp::message_limit();
2179 }
2180 }
program_name() const2181 char const *program_name() const override {
2182 return name_;
2183 }
version() const2184 char const *version() const override {
2185 return version_;
2186 }
has_main() const2187 bool has_main() const override {
2188 return app_.main;
2189 }
main(ClingoControl & ctl,std::vector<std::string> const & files)2190 void main(ClingoControl &ctl, std::vector<std::string> const &files) override {
2191 assert(has_main());
2192 std::vector<char const *> c_files;
2193 for (auto &x : files) {
2194 c_files.emplace_back(x.c_str());
2195 }
2196 forwardError(app_.main(&ctl, c_files.data(), c_files.size(), data_));
2197 }
has_log() const2198 bool has_log() const override { return app_.logger; }
log(Gringo::Warnings code,char const * message)2199 void log(Gringo::Warnings code, char const *message) noexcept override {
2200 assert(has_log());
2201 app_.logger(static_cast<clingo_warning_t>(code), message, data_);
2202 }
has_printer() const2203 bool has_printer() const override { return app_.printer; }
print_model(Model * model,std::function<void ()> printer)2204 void print_model(Model *model, std::function<void()> printer) override {
2205 forwardError(app_.printer(model, [](void *data) {
2206 GRINGO_CLINGO_TRY {
2207 (*static_cast<std::function<void()>*>(data))();
2208 }
2209 GRINGO_CLINGO_CATCH;
2210 }, &printer, data_));
2211 }
2212
register_options(ClingoApp & app)2213 void register_options(ClingoApp &app) override {
2214 if (app_.register_options) {
2215 forwardError(app_.register_options(static_cast<clingo_options_t*>(&app), data_));
2216 }
2217 }
validate_options()2218 void validate_options() override {
2219 if (app_.validate_options) {
2220 forwardError(app_.validate_options(data_));
2221 }
2222 }
2223 private:
2224 clingo_application_t app_;
2225 void *data_;
2226 char const *name_;
2227 char const *version_;
2228 };
2229
2230 } // namespace
2231
clingo_options_add(clingo_options_t * options,char const * group,char const * option,char const * description,bool (* parse)(char const * value,void * data),void * data,bool multi,char const * argument)2232 extern "C" CLINGO_VISIBILITY_DEFAULT bool clingo_options_add(clingo_options_t *options, char const *group, char const *option, char const *description, bool (*parse) (char const *value, void *data), void *data, bool multi, char const *argument) {
2233 GRINGO_CLINGO_TRY {
2234 options->addOption(group, option, description, [parse, data](char const *value) { return parse(value, data); }, argument, multi);
2235 }
2236 GRINGO_CLINGO_CATCH;
2237 }
2238
clingo_options_add_flag(clingo_options_t * options,char const * group,char const * option,char const * description,bool * target)2239 extern "C" CLINGO_VISIBILITY_DEFAULT bool clingo_options_add_flag(clingo_options_t *options, char const *group, char const *option, char const *description, bool *target) {
2240 GRINGO_CLINGO_TRY { options->addFlag(group, option, description, *target); }
2241 GRINGO_CLINGO_CATCH;
2242 }
2243
clingo_main(clingo_application * application,char const * const * arguments,size_t size,void * data)2244 extern "C" CLINGO_VISIBILITY_DEFAULT int clingo_main(clingo_application *application, char const *const * arguments, size_t size, void *data) {
2245 try {
2246 UIClingoApp app = gringo_make_unique<CClingoApp>(*application, data);
2247 std::vector<std::unique_ptr<char[]>> args_buf;
2248 std::vector<char *> args;
2249 args_buf.emplace_back(str_duplicate(app->program_name()));
2250 for (auto arg = arguments, end = arguments + size; arg != end; ++arg) {
2251 args_buf.emplace_back(str_duplicate(*arg));
2252 }
2253 args_buf.emplace_back(nullptr);
2254 for (auto &x : args_buf) { args.emplace_back(x.get()); }
2255 return Gringo::ClingoApp{std::move(app)}.main(args.size() - 1, args.data());
2256 }
2257 catch (...) {
2258 handleError();
2259 std::cerr << "error during initialization: going to terminate:\n" << clingo_error_message() << std::endl;
2260 std::terminate();
2261 }
2262 }
2263
2264 // }}}1
2265
2266 #if defined(__GNUC__) && !defined(__clang__)
2267 #pragma GCC diagnostic pop
2268 #endif
2269
2270