Clingo
Loading...
Searching...
No Matches
core.hh
1#pragma once
2
3#include <clingo/core.h>
4#include <clingo/shared.h>
5
6#include <algorithm>
7#include <cassert>
8#include <functional>
9#include <iterator>
10#include <memory>
11#include <span>
12#include <stdexcept>
13#include <string>
14#include <string_view>
15#include <utility>
16#include <vector>
17
18namespace Clingo {
19
20namespace Detail {
21
22template <typename> inline constexpr bool always_false = false;
23
24#ifndef __clang_analyzer__
25#define CLINGO_ENABLE_BITSET_ENUM(E, ...) \
26 [[nodiscard]] CLINGO_ENUM_OP(~, (E a), __VA_ARGS__)->E { \
27 return static_cast<E>(~static_cast<std::underlying_type_t<E>>(a)); \
28 } \
29 [[nodiscard]] CLINGO_ENUM_OP(|, (E a, E b), __VA_ARGS__)->E { \
30 return static_cast<E>(static_cast<std::underlying_type_t<E>>(a) | static_cast<std::underlying_type_t<E>>(b)); \
31 } \
32 CLINGO_ENUM_OP(|=, (E & a, E b), __VA_ARGS__)->E & { \
33 return a = a | b; \
34 } \
35 [[nodiscard]] CLINGO_ENUM_OP(&, (E a, E b), __VA_ARGS__)->E { \
36 return static_cast<E>(static_cast<std::underlying_type_t<E>>(a) & static_cast<std::underlying_type_t<E>>(b)); \
37 } \
38 CLINGO_ENUM_OP(&=, (E & a, E b), __VA_ARGS__)->E & { \
39 return a = a & b; \
40 } \
41 [[nodiscard]] CLINGO_ENUM_OP(-, (E a, E b), __VA_ARGS__)->E { \
42 return static_cast<E>(static_cast<std::underlying_type_t<E>>(a) & static_cast<std::underlying_type_t<E>>(~b)); \
43 } \
44 CLINGO_ENUM_OP(-=, (E & a, E b), __VA_ARGS__)->E & { \
45 return a = a - b; \
46 } \
47 [[nodiscard]] CLINGO_ENUM_OP(^, (E a, E b), __VA_ARGS__)->E { \
48 return static_cast<E>(static_cast<std::underlying_type_t<E>>(a) ^ static_cast<std::underlying_type_t<E>>(b)); \
49 } \
50 CLINGO_ENUM_OP(^=, (E & a, E b), __VA_ARGS__)->E & { \
51 return a = a ^ b; \
52 } \
53 [[nodiscard]] [[maybe_unused]] inline __VA_ARGS__ constexpr auto intersects(E a, E b) -> bool { \
54 return static_cast<std::underlying_type_t<E>>(a & b) != 0; \
55 } \
56 static_assert(std::is_enum_v<E>)
57#define CLINGO_ENUM_OP(op, arg, ...) [[maybe_unused]] inline __VA_ARGS__ constexpr auto operator op arg noexcept
58#else
59#define CLINGO_ENABLE_BITSET_ENUM(E, ...) \
60 [[nodiscard]] CLINGO_ENUM_OP(~, (E a), __VA_ARGS__)->E; \
61 [[nodiscard]] CLINGO_ENUM_OP(|, (E a, E b), __VA_ARGS__)->E; \
62 CLINGO_ENUM_OP(|=, (E & a, E b), __VA_ARGS__)->E &; \
63 [[nodiscard]] CLINGO_ENUM_OP(&, (E a, E b), __VA_ARGS__)->E; \
64 CLINGO_ENUM_OP(&=, (E & a, E b), __VA_ARGS__)->E &; \
65 [[nodiscard]] CLINGO_ENUM_OP(-, (E a, E b), __VA_ARGS__)->E; \
66 CLINGO_ENUM_OP(-=, (E & a, E b), __VA_ARGS__)->E &; \
67 [[nodiscard]] CLINGO_ENUM_OP(^, (E a, E b), __VA_ARGS__)->E; \
68 CLINGO_ENUM_OP(^=, (E & a, E b), __VA_ARGS__)->E &; \
69 [[nodiscard]] [[maybe_unused]] __VA_ARGS__ auto intersects(E a, E b) -> bool; \
70 static_assert(std::is_enum_v<E>)
71#define CLINGO_ENUM_OP(op, arg, ...) [[maybe_unused]] __VA_ARGS__ auto operator op arg noexcept
72#endif
73
74#define CLINGO_TRY try
75#define CLINGO_CATCH \
76 catch (...) { \
77 return Clingo::Detail::store_error(); \
78 } \
79 return true
80
82inline auto store_error() -> bool {
83 try {
84 throw;
85 } catch (std::out_of_range const &e) {
86 auto msg = std::string_view{e.what()};
87 return clingo_set_error(clingo_result_range, msg.data(), msg.size());
88 } catch (std::invalid_argument const &e) {
89 auto msg = std::string_view{e.what()};
90 return clingo_set_error(clingo_result_invalid, msg.data(), msg.size());
91 } catch (std::bad_alloc const &e) {
92 auto msg = std::string_view{e.what()};
93 return clingo_set_error(clingo_result_bad_alloc, msg.data(), msg.size());
94 } catch (std::logic_error const &e) {
95 auto msg = std::string_view{e.what()};
96 return clingo_set_error(clingo_result_logic, msg.data(), msg.size());
97 } catch (std::exception const &e) {
98 auto msg = std::string_view{e.what()};
99 return clingo_set_error(clingo_result_runtime, msg.data(), msg.size());
100 } catch (...) {
101 auto msg = std::string_view{"no message"};
102 return clingo_set_error(clingo_result_runtime, msg.data(), msg.size());
103 }
104}
105
107inline void raise_error() {
108 clingo_string_t str;
110 clingo_get_error(&rc, &str);
111 switch (rc) {
113 throw std::bad_alloc{};
114 }
115 case clingo_result_logic: {
116 throw std::logic_error{std::string{str.data, str.size}};
117 }
119 throw std::invalid_argument{std::string{str.data, str.size}};
120 }
121 case clingo_result_range: {
122 throw std::out_of_range{std::string{str.data, str.size}};
123 }
124 default: {
125 throw std::runtime_error{std::string{str.data, str.size}};
126 }
127 }
128}
129
133inline void handle_error(bool res) {
134 if (!res) {
135 raise_error();
136 }
137}
138
139// Similar to handle_error but also reraises if the code is success.
140inline void handle_error_no_code(bool res, int code) {
141 if (!res) {
142 raise_error();
143 }
144 if ((code & 65) == 65 || (code & 33) == 33) { // NOLINT
145 clingo_string_t str;
147 clingo_get_error(&rc, &str);
148 if (rc != clingo_result_success) {
149 raise_error();
150 }
151 }
152}
153
154template <typename> struct funptr_traits;
155
156template <typename R, typename... As> struct funptr_traits<R (*)(As...)> {
157 using return_type = R;
158 using args_tuple = std::tuple<As...>;
159 template <std::size_t N> using arg = std::tuple_element_t<N, args_tuple>;
160
161 static constexpr std::size_t arity = sizeof...(As);
162 using last = arg<arity - 1>;
163};
164
165template <auto F, class... As> auto call(As &&...args) {
166 using Traits = funptr_traits<decltype(F)>;
167 auto res = std::remove_pointer_t<typename Traits::last>{};
168 if constexpr (std::is_same_v<typename Traits::return_type, void>) {
169 F(std::forward<As>(args)..., &res);
170 } else {
171 handle_error(F(std::forward<As>(args)..., &res));
172 }
173 return res;
174}
175
176template <auto F> struct Free {
177 template <typename Ptr> void operator()(Ptr p) const noexcept { F(p); }
178};
179
180template <class T> struct value_handle {
181 public:
182 using pointer = typename T::pointer;
183
184 value_handle() = default;
185
186 value_handle(const value_handle &other) : ptr_{other ? T::copy(other.ptr_) : nullptr} {}
187
188 value_handle(value_handle &&other) noexcept : ptr_{std::exchange(other.ptr_, nullptr)} {}
189
190 explicit value_handle(pointer ptr, bool copy) : ptr_{copy && ptr != nullptr ? T::copy(ptr) : ptr} {}
191
192 ~value_handle() {
193 if (*this) {
194 T::free(ptr_);
195 }
196 }
197
198 auto operator=(const value_handle &other) -> value_handle & {
199 if (this != &other) {
200 if (*this) {
201 T::free(ptr_);
202 }
203 ptr_ = other ? T::copy(other.ptr_) : nullptr;
204 }
205 return *this;
206 }
207
208 auto operator=(value_handle &&other) noexcept -> value_handle & {
209 if (this != &other) {
210 if (*this) {
211 T::free(ptr_);
212 }
213 ptr_ = std::exchange(other.ptr_, nullptr);
214 }
215 return *this;
216 }
217
218 [[nodiscard]] auto get() const -> pointer { return ptr_; }
219 explicit operator bool() const { return ptr_ != nullptr; }
220
221 private:
222 pointer ptr_ = nullptr;
223};
224
225template <auto Copy, auto Free> struct value_handle_traits {
226 using pointer = std::remove_pointer_t<typename funptr_traits<decltype(Copy)>::template arg<1>>;
227 using const_pointer = typename funptr_traits<decltype(Copy)>::template arg<0>;
228 static auto copy(pointer p) -> pointer {
229 auto res = pointer{};
230 handle_error(Copy(p, &res));
231 return res;
232 }
233 static void free(const_pointer p) noexcept { Free(p); }
234};
235
236template <class T, auto F> using unique_handle = std::unique_ptr<T, Free<F>>;
237
239template <std::input_iterator It, std::sentinel_for<It> S, class Pred> auto transform(It begin, S end, Pred pred) {
240 auto p = std::vector<std::invoke_result_t<Pred, std::iter_reference_t<It>>>{};
241 p.reserve(std::distance(begin, end));
242 std::transform(begin, end, std::back_inserter(p), pred);
243 return p;
244}
245
247template <std::ranges::input_range Rng, class Pred> auto transform(Rng &&rng, Pred pred) { // NOLINT
248 return transform(std::ranges::begin(rng), std::ranges::end(rng), pred);
249}
250
254template <class T> auto hash_value(T const &x) {
255 return std::hash<T>{}(x);
256}
257
259inline auto hash_combine(size_t a, size_t b) -> size_t {
260 // NOLINTBEGIN
261 auto p = std::make_pair(a, b);
262 return std::hash<std::string_view>{}(std::string_view(reinterpret_cast<char const *>(&p), sizeof(decltype(p))));
263 // NOLINTEND
264}
265
266template <class T, class P> class intrusive_handle {
267 public:
268 intrusive_handle() = default;
269 explicit intrusive_handle(P *ptr, bool inc = true) : ptr_{ptr} {
270 if (inc) {
271 T::acquire(ptr);
272 }
273 }
274 intrusive_handle(intrusive_handle const &other) : intrusive_handle{other.ptr_} {}
275 intrusive_handle(intrusive_handle &&other) noexcept : ptr_{std::exchange(other.ptr_, nullptr)} {}
276 ~intrusive_handle() noexcept { T::release(ptr_); }
277 auto operator=(intrusive_handle const &other) -> intrusive_handle & {
278 T::acquire(other.ptr_);
279 T::release(ptr_);
280 ptr_ = other.ptr_;
281 return *this;
282 }
283 auto operator=(intrusive_handle &&other) noexcept -> intrusive_handle & {
284 T::release(ptr_);
285 ptr_ = std::exchange(other.ptr_, nullptr);
286 return *this;
287 }
288 [[nodiscard]] auto get() const noexcept -> P * { return ptr_; }
289 void reset(std::nullptr_t = nullptr) noexcept {
290 T::release(ptr_);
291 ptr_ = nullptr;
292 }
293 void reset(P *ptr, bool inc = true) {
294 T::release(ptr_);
295 ptr_ = ptr;
296 if (inc) {
297 T::acquire(ptr_);
298 }
299 }
300 friend auto operator==(intrusive_handle const &p, std::nullptr_t) noexcept -> bool { return p.ptr_ == nullptr; }
301 friend auto operator!=(intrusive_handle const &p, std::nullptr_t) noexcept -> bool { return p.ptr_ != nullptr; }
302 friend auto operator==(std::nullptr_t, intrusive_handle const &p) noexcept -> bool { return p.ptr_ == nullptr; }
303 friend auto operator!=(std::nullptr_t, intrusive_handle const &p) noexcept -> bool { return p.ptr_ != nullptr; }
304
305 private:
306 P *ptr_ = nullptr;
307};
308
309template <typename HT, typename PT> struct UserDataStorageTypes {
310 using HolderType = HT;
311 using PtrType = PT;
312};
313template <typename T> struct UserDataStorageTraits : UserDataStorageTypes<std::unique_ptr<T>, T *> {
314 using ValueType = T;
315 using is_holder = void;
316};
317template <typename T> struct UserDataStorageTraits<std::reference_wrapper<T>> : UserDataStorageTypes<T *, T *> {
318 using is_ref = void;
319};
320template <typename T> struct UserDataStorageTraits<std::unique_ptr<T>> : UserDataStorageTypes<std::unique_ptr<T>, T *> {
321 using is_holder = void;
322};
323template <> struct UserDataStorageTraits<std::nullptr_t> : UserDataStorageTypes<std::nullptr_t, std::nullptr_t> {
324 using is_null = void;
325};
326
334template <typename T> struct UserDataTraits {
335 using StorageTraits = UserDataStorageTraits<std::remove_cvref_t<T>>;
336 using PointerType = typename StorageTraits::PtrType;
337 using ValueType = std::remove_pointer_t<PointerType>;
338 using ReferenceType = std::add_lvalue_reference_t<PointerType>;
339
341 static constexpr auto has_data = !requires { typename StorageTraits::is_null; };
342
344 template <typename U> static auto create(U &&data) -> StorageTraits::HolderType {
345 if constexpr (requires { typename StorageTraits::ValueType; }) {
346 return std::make_unique<typename StorageTraits::ValueType>(std::forward<U>(data));
347 } else if constexpr (requires { typename StorageTraits::is_ref; }) {
348 return &data.get();
349 } else {
350 return data;
351 }
352 }
354 static auto get(StorageTraits::HolderType &holder) -> PointerType {
355 if constexpr (requires { typename StorageTraits::is_holder; }) {
356 return holder.get();
357 } else {
358 return holder;
359 }
360 }
362 static auto has_value(StorageTraits::HolderType &holder) -> bool { return get(holder) != nullptr; }
364 static auto release(StorageTraits::HolderType &holder) -> StorageTraits::PtrType {
365 if constexpr (requires { typename StorageTraits::is_holder; }) {
366 return holder.release();
367 } else {
368 return holder;
369 }
370 }
372 static auto cast(void *ptr) -> StorageTraits::PtrType { return static_cast<StorageTraits::PtrType>(ptr); }
374 static void free(void *ptr) {
375 if constexpr (requires { typename StorageTraits::is_holder; }) {
376 typename StorageTraits::HolderType{cast(ptr)};
377 }
378 }
379};
380
381template <typename Value, typename Base, bool Null> struct IsUserData : std::is_base_of<Base, Value> {};
382
383template <typename T, typename Base, bool Null>
384struct IsUserData<std::reference_wrapper<T>, Base, Null> : std::is_base_of<Base, T> {};
385
386template <typename T, typename Base, bool Null>
387struct IsUserData<std::unique_ptr<T>, Base, Null> : std::is_base_of<Base, T> {};
388
389template <typename Base, bool Null>
390struct IsUserData<std::nullptr_t, Base, Null> : std::conditional_t<Null, std::true_type, std::false_type> {};
391
397template <typename Value, typename Base, bool Null = true>
398concept UserData = IsUserData<std::remove_cvref_t<Value>, Base, Null>::value;
399
400template <typename T> class ArrowProxy {
401 public:
402 constexpr ArrowProxy(T value) : value_(std::move(value)) {}
403 constexpr auto operator->() -> T * { return &value_; }
404
405 private:
406 T value_;
407};
408
409template <class Seq> class RandomAccessIterator {
410 public:
411 using iterator_category = std::random_access_iterator_tag;
412 using value_type = typename Seq::value_type;
413 using size_type = typename Seq::size_type;
414 using difference_type = typename Seq::difference_type;
415 using pointer = typename Seq::pointer;
416 using reference = typename Seq::reference;
417
418 // NOTE: Added to fulfill the sentinel_for concept; should not be used.
419 constexpr RandomAccessIterator() : view_{throw std::logic_error("invalid iterator")}, index_{0} {}
420 constexpr RandomAccessIterator(Seq container, size_t index) noexcept : view_{std::move(container)}, index_{index} {}
421 constexpr auto operator*() const -> reference { return view_.at(index_); }
422 constexpr auto operator->() const -> pointer { return view_.at(index_); }
423 constexpr auto operator++() -> RandomAccessIterator & {
424 ++index_;
425 return *this;
426 }
427 constexpr auto operator++(int) -> RandomAccessIterator {
428 auto tmp = *this;
429 ++index_;
430 return tmp;
431 }
432 constexpr auto operator--() -> RandomAccessIterator & {
433 --index_;
434 return *this;
435 }
436 constexpr auto operator--(int) -> RandomAccessIterator {
437 auto tmp = *this;
438 --index_;
439 return tmp;
440 }
441 constexpr auto operator-(const RandomAccessIterator &other) const -> difference_type {
442 return static_cast<difference_type>(index_) - static_cast<difference_type>(other.index_);
443 }
444 constexpr auto operator+(difference_type n) const -> RandomAccessIterator {
445 return RandomAccessIterator(view_, index_ + n);
446 }
447 friend constexpr auto operator+(difference_type n, RandomAccessIterator it) -> RandomAccessIterator {
448 return RandomAccessIterator(it.view_, it.index_ + n);
449 }
450 constexpr auto operator-(difference_type n) const -> RandomAccessIterator {
451 return RandomAccessIterator(view_, index_ - n);
452 }
453 constexpr auto operator+=(difference_type n) -> RandomAccessIterator & {
454 index_ += n;
455 return *this;
456 }
457 constexpr auto operator-=(difference_type n) -> RandomAccessIterator & {
458 index_ -= n;
459 return *this;
460 }
461 constexpr auto operator==(const RandomAccessIterator &other) const -> bool { return index_ == other.index_; }
462 constexpr auto operator<=>(const RandomAccessIterator &other) const { return index_ <=> other.index_; }
463 constexpr auto operator[](difference_type n) const -> reference { return view_.at(index_ + n); }
464
465 private:
466 Seq view_;
467 size_t index_;
468};
469
470} // namespace Detail
471
475
479using ProgramIdSpan = std::span<ProgramId const>;
480
484using ProgramAtomSpan = std::span<ProgramAtom const>;
485
489using ProgramLiteralSpan = std::span<ProgramLiteral const>;
491using ProgramLiteralVector = std::vector<ProgramLiteral>;
492
496using SolverLiteralSpan = std::span<SolverLiteral const>;
498using SolverLiteralList = std::initializer_list<SolverLiteral const>;
500using SolverLiteralVector = std::vector<SolverLiteral>;
501
505using WeightSpan = std::span<clingo_weight_t const>;
506
510using WeightedLiteralSpan = std::span<WeightedLiteral const>;
511
513using Sum = int64_t;
515using SumSpan = std::span<Sum const>;
516
518using StringSpan = std::span<std::string_view const>;
520using StringList = std::initializer_list<std::string_view const>;
521
534
543
553
555inline constexpr size_t default_message_limit = 25;
556
560using Logger = std::function<void(MessageCode, std::string_view)>;
561
566class Library {
567 public:
575 size_t limit = default_message_limit) {
576 auto log = logger ? std::make_unique<Logger>(std::move(logger)) : nullptr;
577 auto has_log = static_cast<bool>(log);
578 rep_.reset(Detail::call<clingo_lib_new>(static_cast<clingo_lib_flags_t>(flags),
579 static_cast<clingo_log_level_t>(level), has_log ? &c_logger : nullptr,
580 log.release(), limit),
581 false);
582 }
589 explicit Library(clingo_lib_t *rep, bool acquire) : rep_{rep, acquire} {}
590
595 [[nodiscard]] friend auto c_cast(Library const &lib) -> clingo_lib_t * { return lib.rep_.get(); }
596
597 private:
598 friend class Detail::intrusive_handle<Library, clingo_lib_t>;
599
600 static constexpr clingo_logger_t c_logger = {
601 [](clingo_message_t code, char const *message, size_t size, void *data) {
602 (*static_cast<Logger *>(data))(static_cast<MessageCode>(code), {message, size});
603 },
604 [](void *data) noexcept { std::unique_ptr<Logger>(static_cast<Logger *>(data)); },
605 };
606
607 static auto acquire(clingo_lib_t *ptr) { clingo_lib_acquire(ptr); }
608 static auto release(clingo_lib_t *ptr) { clingo_lib_release(ptr); }
609
610 Detail::intrusive_handle<Library, clingo_lib_t> rep_;
611};
612
620 public:
622 explicit StringBuilder() : bld_{Detail::call<clingo_string_builder_new>(), false} {}
623
628 [[nodiscard]] friend auto c_cast(StringBuilder &bld) -> clingo_string_builder_t * { return bld.bld_.get(); }
629
633 [[nodiscard]] auto str() const -> std::string_view {
634 auto [data, size] = Detail::call<clingo_string_builder_string>(bld_.get());
635 return {data, size};
636 }
637
639 void clear() noexcept { clingo_string_builder_clear(bld_.get()); }
640
641 private:
642 using Traits = Detail::value_handle_traits<clingo_string_builder_copy, clingo_string_builder_free>;
643 Detail::value_handle<Traits> bld_;
644};
645
653
663
667class Position {
668 public:
674 explicit Position(clingo_position_t const *pos) : pos_{pos, true} {}
675
682 explicit Position(Library const &lib, std::string_view file, size_t line, size_t column)
683 : pos_{Detail::call<clingo_position_new>(c_cast(lib), file.data(), file.size(), line, column), false} {}
684
689 friend auto c_cast(Position const &x) -> clingo_position_t const * { return x.pos_.get(); }
690
694 [[nodiscard]] auto file() const -> std::string_view {
695 auto [data, size] = Detail::call<clingo_position_file>(pos_.get());
696 return {data, size};
697 }
698
702 [[nodiscard]] auto line() const -> size_t { return clingo_position_line(pos_.get()); }
703
707 [[nodiscard]] auto column() const -> size_t { return clingo_position_column(pos_.get()); }
708
712 [[nodiscard]] auto to_string() const -> std::string {
713 auto bld = StringBuilder{};
714 Detail::handle_error(clingo_position_to_string(pos_.get(), c_cast(bld)));
715 return std::string{bld.str()};
716 }
717
723 [[nodiscard]] auto hash() const noexcept -> size_t { return clingo_position_hash(pos_.get()); }
724
730 friend auto operator==(Position const &a, Position const &b) noexcept -> bool {
731 return clingo_position_equal(a.pos_.get(), b.pos_.get());
732 }
733
739 friend auto operator<=>(Position const &a, Position const &b) noexcept -> std::strong_ordering {
740 return clingo_position_compare(a.pos_.get(), b.pos_.get()) <=> 0;
741 }
742
743 private:
744 using Traits = Detail::value_handle_traits<clingo_position_copy, clingo_position_free>;
745 Detail::value_handle<Traits> pos_;
746};
747
751class Location {
752 public:
754 explicit Location(clingo_location_t const *loc) : loc_{loc, true} {}
755
760 explicit Location(Position const &begin, Position const &end)
761 : loc_{Detail::call<clingo_location_new>(c_cast(begin), c_cast(end)), false} {}
762
766 friend auto c_cast(Location const &x) -> clingo_location_t const * { return x.loc_.get(); }
767
771 [[nodiscard]] auto begin() const -> Position { return Position{clingo_location_begin(loc_.get())}; }
772
776 [[nodiscard]] auto end() const -> Position { return Position{clingo_location_end(loc_.get())}; }
777
781 [[nodiscard]] auto to_string() const -> std::string {
782 auto bld = StringBuilder{};
783 Detail::handle_error(clingo_location_to_string(loc_.get(), c_cast(bld)));
784 return std::string{bld.str()};
785 }
786
788 [[nodiscard]] auto hash() const noexcept -> size_t { return clingo_location_hash(loc_.get()); }
789
795 friend auto operator==(Location const &a, Location const &b) noexcept -> bool {
796 return clingo_location_equal(a.loc_.get(), b.loc_.get());
797 }
798
804 friend auto operator<=>(Location const &a, Location const &b) noexcept -> std::strong_ordering {
805 return clingo_location_compare(a.loc_.get(), b.loc_.get()) <=> 0;
806 }
807
808 private:
809 using Traits = Detail::value_handle_traits<clingo_location_copy, clingo_location_free>;
810 Detail::value_handle<Traits> loc_;
811};
812
813namespace Version {
815inline constexpr int major = CLINGO_VERSION_MAJOR;
817inline constexpr int minor = CLINGO_VERSION_MINOR;
819inline constexpr int revision = CLINGO_VERSION_REVISION;
820} // namespace Version
821
825inline auto version() -> std::tuple<int, int, int> {
826 int major = 0;
827 int minor = 0;
828 int revision = 0;
829 clingo_version(&major, &minor, &revision);
830 return {major, minor, revision};
831}
832
834
835} // namespace Clingo
The main library class for managing global information and logging.
Definition core.hh:566
Library(LibraryFlags flags=LibraryFlags::none, Logger logger=nullptr, LogLevel level=LogLevel::info, size_t limit=default_message_limit)
Constructs a library object.
Definition core.hh:574
friend auto c_cast(Library const &lib) -> clingo_lib_t *
Casts the library object to its C representation.
Definition core.hh:595
Library(clingo_lib_t *rep, bool acquire)
Constructs a library object from an existing C representation.
Definition core.hh:589
Class representing a range in a file.
Definition core.hh:751
auto begin() const -> Position
Get the position marking the beginning of the location.
Definition core.hh:771
friend auto operator==(Location const &a, Location const &b) noexcept -> bool
Compare two locations for equality.
Definition core.hh:795
friend auto operator<=>(Location const &a, Location const &b) noexcept -> std::strong_ordering
Compare two locations.
Definition core.hh:804
friend auto c_cast(Location const &x) -> clingo_location_t const *
Cast the location to its C representation.
Definition core.hh:766
auto end() const -> Position
Get the position marking the end of the location.
Definition core.hh:776
Location(clingo_location_t const *loc)
Constructs a location from an existing C representation.
Definition core.hh:754
auto to_string() const -> std::string
Convert the location to a string representation.
Definition core.hh:781
auto hash() const noexcept -> size_t
Get a hash value for the location.
Definition core.hh:788
Location(Position const &begin, Position const &end)
Constructs a location from a begin and end position.
Definition core.hh:760
Class representing a position in a file.
Definition core.hh:667
Position(Library const &lib, std::string_view file, size_t line, size_t column)
Constructs a position from a file, line, and column.
Definition core.hh:682
friend auto operator==(Position const &a, Position const &b) noexcept -> bool
Compare two positions for equality.
Definition core.hh:730
friend auto c_cast(Position const &x) -> clingo_position_t const *
Cast a position to its C representation.
Definition core.hh:689
friend auto operator<=>(Position const &a, Position const &b) noexcept -> std::strong_ordering
Compare two positions.
Definition core.hh:739
Position(clingo_position_t const *pos)
Constructs a position from an existing C representation.
Definition core.hh:674
auto to_string() const -> std::string
Convert the position to a string representation.
Definition core.hh:712
auto file() const -> std::string_view
Get the file name of the position.
Definition core.hh:694
auto line() const -> size_t
Get the line number of the position.
Definition core.hh:702
auto hash() const noexcept -> size_t
Compute the hash of the position.
Definition core.hh:723
auto column() const -> size_t
Get the column number of the position.
Definition core.hh:707
A string builder for constructing strings.
Definition core.hh:619
StringBuilder()
Construct an empty string builder.
Definition core.hh:622
auto str() const -> std::string_view
Get a view of the string built by the string builder.
Definition core.hh:633
friend auto c_cast(StringBuilder &bld) -> clingo_string_builder_t *
Cast the string builder to its C representation.
Definition core.hh:628
void clear() noexcept
Clear the string builder, removing all content.
Definition core.hh:639
CLINGO_VISIBILITY_DEFAULT clingo_position_t const * clingo_location_end(clingo_location_t const *loc)
Get the end of the location.
CLINGO_VISIBILITY_DEFAULT void clingo_lib_release(clingo_lib_t *lib)
Release a library object created with clingo_lib_new().
CLINGO_VISIBILITY_DEFAULT int clingo_position_compare(clingo_position_t const *a, clingo_position_t const *b)
Compare two positions.
CLINGO_VISIBILITY_DEFAULT bool clingo_position_new(clingo_lib_t *lib, char const *file, size_t size, size_t line, size_t column, clingo_position_t const **pos)
Create a new source position object.
CLINGO_VISIBILITY_DEFAULT void clingo_version(int *major, int *minor, int *revision)
Obtain the clingo version.
CLINGO_VISIBILITY_DEFAULT bool clingo_set_error(clingo_result_t code, char const *message, size_t size)
Set an error in the current thread.
struct clingo_weighted_literal clingo_weighted_literal_t
A literal with an associated weight.
CLINGO_VISIBILITY_DEFAULT bool clingo_location_new(clingo_position_t const *begin, clingo_position_t const *end, clingo_location_t const **loc)
Create a new source location object.
CLINGO_VISIBILITY_DEFAULT bool clingo_position_to_string(clingo_position_t const *pos, clingo_string_builder_t *str)
Convert the given position into a string.
CLINGO_VISIBILITY_DEFAULT size_t clingo_position_column(clingo_position_t const *pos)
Get the column number of the position.
CLINGO_VISIBILITY_DEFAULT void clingo_string_builder_clear(clingo_string_builder_t *bld)
Clear the string in the builder.
int clingo_log_level_t
Corresponding type to clingo_log_level_e.
Definition core.h:149
struct clingo_lib clingo_lib_t
A library object storing global information.
Definition core.h:171
struct clingo_location clingo_location_t
Represents a source code location marking its beginning and end.
Definition core.h:354
CLINGO_VISIBILITY_DEFAULT void clingo_get_error(clingo_result_t *code, clingo_string_t *message)
Get the error set in the current thread.
uint32_t clingo_atom_t
Unsigned integer type used for aspif atoms.
Definition core.h:75
CLINGO_VISIBILITY_DEFAULT int clingo_location_compare(clingo_location_t const *a, clingo_location_t const *b)
Compare two locations.
struct clingo_string_builder clingo_string_builder_t
A builder for strings.
Definition core.h:252
CLINGO_VISIBILITY_DEFAULT size_t clingo_position_line(clingo_position_t const *pos)
Get the line number of the position.
#define CLINGO_VERSION_MINOR
Minor version number.
Definition core.h:64
#define CLINGO_VERSION_MAJOR
Major version number.
Definition core.h:62
CLINGO_VISIBILITY_DEFAULT bool clingo_position_equal(clingo_position_t const *a, clingo_position_t const *b)
Check if two positions are equal.
CLINGO_VISIBILITY_DEFAULT bool clingo_location_to_string(clingo_location_t const *loc, clingo_string_builder_t *str)
Convert the given location into a string.
CLINGO_VISIBILITY_DEFAULT size_t clingo_position_hash(clingo_position_t const *pos)
Compute a hash of the position.
int32_t clingo_literal_t
Signed integer type used for aspif and solver literals.
Definition core.h:73
CLINGO_VISIBILITY_DEFAULT clingo_position_t const * clingo_location_begin(clingo_location_t const *loc)
Get the beginning of the location.
int clingo_message_t
Corresponding type to clingo_message_e.
Definition core.h:138
uint32_t clingo_id_t
Unsigned integer type used in various places.
Definition core.h:77
int clingo_result_t
Corresponding type to clingo_result_e.
Definition core.h:106
uint32_t clingo_lib_flags_t
Bitset of clingo_lib_flags_e.
Definition core.h:180
#define CLINGO_VERSION_REVISION
Revision number.
Definition core.h:66
struct clingo_position clingo_position_t
Represents a cursor position in source code.
Definition core.h:286
CLINGO_VISIBILITY_DEFAULT bool clingo_string_builder_new(clingo_string_builder_t **bld)
Create a new string builder.
CLINGO_VISIBILITY_DEFAULT bool clingo_location_equal(clingo_location_t const *a, clingo_location_t const *b)
Check if two locations are equal.
int32_t clingo_weight_t
Signed integer type for weights in sum aggregates and minimize constraints.
Definition core.h:79
CLINGO_VISIBILITY_DEFAULT size_t clingo_location_hash(clingo_location_t const *loc)
Compute a hash of the location.
CLINGO_VISIBILITY_DEFAULT void clingo_lib_acquire(clingo_lib_t *lib)
Increment the reference count of the given library.
@ clingo_message_file_included
same file included multiple times
Definition core.h:132
@ clingo_message_error
to report multiple errors; a corresponding runtime error is raised later
Definition core.h:135
@ clingo_message_info
an info message
Definition core.h:129
@ clingo_message_atom_undefined
undefined atom in program
Definition core.h:131
@ clingo_message_global_variable
global variable in tuple of aggregate element
Definition core.h:133
@ clingo_message_operation_undefined
undefined operation in program
Definition core.h:130
@ clingo_message_trace
a trace message
Definition core.h:127
@ clingo_message_debug
a debug message
Definition core.h:128
@ clingo_message_warn
a warning message
Definition core.h:134
@ clingo_log_level_warn
the warning level
Definition core.h:145
@ clingo_log_level_debug
the debug level
Definition core.h:143
@ clingo_log_level_info
the info level
Definition core.h:144
@ clingo_log_level_error
the error level (least verbose)
Definition core.h:146
@ clingo_log_level_trace
the trace level (most verbose)
Definition core.h:142
@ clingo_result_range
result out of range
Definition core.h:103
@ clingo_result_runtime
errors only detectable at runtime like invalid input
Definition core.h:99
@ clingo_result_success
successful API calls
Definition core.h:98
@ clingo_result_invalid
invalid arguments passed to function
Definition core.h:102
@ clingo_result_bad_alloc
memory could not be allocated
Definition core.h:101
@ clingo_result_logic
wrong usage of the clingo API
Definition core.h:100
@ clingo_lib_flags_shared
create symbols in a thread-safe manner
Definition core.h:176
@ clingo_lib_flags_slotted
use custom allocator for storing symbols
Definition core.h:175
@ clingo_lib_flags_fast_release
whether to enable fast release of libraries
Definition core.h:177
int clingo_external_type_t
Corresponding type to clingo_external_type_e.
Definition shared.h:32
int clingo_heuristic_type_t
Corresponding type to clingo_heuristic_type_e.
Definition shared.h:22
@ clingo_heuristic_type_false
set the level of an atom and choose a negative sign
Definition shared.h:19
@ clingo_heuristic_type_init
modify the initial VSIDS score of an atom
Definition shared.h:17
@ clingo_heuristic_type_true
set the level of an atom and choose a positive sign
Definition shared.h:18
@ clingo_heuristic_type_factor
modify VSIDS factor of an atom
Definition shared.h:16
@ clingo_heuristic_type_level
set the level of an atom
Definition shared.h:14
@ clingo_heuristic_type_sign
configure which sign to chose for an atom
Definition shared.h:15
@ clingo_external_type_free
allow an external to be assigned freely
Definition shared.h:26
@ clingo_external_type_true
assign an external to true
Definition shared.h:27
@ clingo_external_type_false
assign an external to false
Definition shared.h:28
@ clingo_external_type_release
no longer treat an atom as external
Definition shared.h:29
Base
The base of a number.
Definition number.hh:17
auto operator+(Sign a, Sign b) -> Sign
Combine two signs.
auto operator+=(Sign &a, Sign b) -> Sign &
Combine two signs.
auto operator-(Sign a) -> Sign
Negate the sign.
@ value
The configuration entry is a double value.
std::span< std::string_view const > StringSpan
A span of string views.
Definition core.hh:518
clingo_literal_t SolverLiteral
A solver literal.
Definition core.hh:494
std::initializer_list< std::string_view const > StringList
A list of string views.
Definition core.hh:520
constexpr size_t default_message_limit
The default message limit for the logger.
Definition core.hh:555
std::vector< SolverLiteral > SolverLiteralVector
A vector of solver literals.
Definition core.hh:500
LibraryFlags
Flags to create library objects.
Definition core.hh:545
std::function< void(MessageCode, std::string_view)> Logger
A callback function type for logging messages.
Definition core.hh:560
std::span< Sum const > SumSpan
A span of sums.
Definition core.hh:515
clingo_atom_t ProgramAtom
A program atom.
Definition core.hh:482
std::span< ProgramId const > ProgramIdSpan
A span of program ids.
Definition core.hh:479
std::initializer_list< SolverLiteral const > SolverLiteralList
A list of solver literals.
Definition core.hh:498
HeuristicType
Enumeration of heuristic types.
Definition core.hh:655
std::span< ProgramAtom const > ProgramAtomSpan
A span of program atoms.
Definition core.hh:484
auto version() -> std::tuple< int, int, int >
Get the version of the Clingo library as a tuple.
Definition core.hh:825
int64_t Sum
A sum representing the sum of weights.
Definition core.hh:513
MessageCode
Enumeration of message codes.
Definition core.hh:523
std::vector< ProgramLiteral > ProgramLiteralVector
A vector of program literals.
Definition core.hh:491
clingo_weight_t Weight
A weight used in sum aggregates and minimize constraints.
Definition core.hh:503
clingo_literal_t ProgramLiteral
A program literal.
Definition core.hh:487
std::span< SolverLiteral const > SolverLiteralSpan
A span of solver literals.
Definition core.hh:496
std::span< WeightedLiteral const > WeightedLiteralSpan
A span of weighted literals.
Definition core.hh:510
clingo_id_t ProgramId
A program id used for various kinds of indices.
Definition core.hh:477
std::span< ProgramLiteral const > ProgramLiteralSpan
A span of program literals.
Definition core.hh:489
ExternalType
Enumeration of control modes.
Definition core.hh:647
std::span< clingo_weight_t const > WeightSpan
A span of weights.
Definition core.hh:505
LogLevel
Enumeration of log levels.
Definition core.hh:536
@ none
no flags set
@ fast_release
whether to enable fast release of libraries
@ shared
create symbols in a thread-safe manner
@ slotted
use custom allocator for storing symbols
@ sign
Configure which sign to chose for an atom.
@ factor
Modify VSIDS factor of an atom.
@ level
Set the level of an atom.
@ init
Modify the initial VSIDS score of an atom.
@ trace
a trace message
@ global_variable
global variable in tuple of aggregate element
@ warn
a warning message
@ file_included
same file included multiple times
@ atom_undefined
undefined atom in program
@ operation_undefined
undefined operation in program
@ debug
a debug message
@ info
an info message
@ error
to report multiple errors; a corresponding runtime error is raised later
@ release
No longer treat an atom as external.
@ true_
Assign an external to true.
@ free
Allow an external to be assigned freely.
@ false_
Assign an external to false.
@ info
the info level
@ wart
the warning level
#define CLINGO_ENABLE_BITSET_ENUM(E,...)
Opt-in macro for enabling bit operations for a given enum type.
Definition enum.hh:18
auto hash_combine(T... a) -> size_t
Combine the given hashes.
Definition hash.hh:242
constexpr auto transform(std::optional< T > &x, F &&f) -> Detail::transform_result< T &, F >
Implemenatation of std::optional<T>::transform.
Definition optional.hh:28
The clingo logger.
Definition core.h:152
Struct to capture strings that are not null-terminated.
Definition core.h:86
size_t size
the length of the string
Definition core.h:88
char const * data
pointer to the beginning of the string
Definition core.h:87
A literal with an associated weight.
Definition core.h:81