Clingo
Loading...
Searching...
No Matches
ast.hh
1#pragma once
2
3#include <clingo/control.hh>
4#include <clingo/core.hh>
5#include <clingo/detail/ast.hh>
6#include <clingo/symbol.hh>
7
8#include <clingo/ast.h>
9
10#include <cassert>
11#include <cstring>
12#include <utility>
13
14namespace Clingo::AST {
15
20
21namespace UnaryOperator {
22inline constexpr int minus = 0;
23inline constexpr int negation = 1;
24} // namespace UnaryOperator
25
26namespace BinaryOperator {
27inline constexpr int and_ = 0;
28inline constexpr int division = 1;
29inline constexpr int minus = 2;
30inline constexpr int modulo = 3;
31inline constexpr int multiplication = 4;
32inline constexpr int or_ = 5;
33inline constexpr int plus = 6;
34inline constexpr int power = 7;
35inline constexpr int xor_ = 8;
36} // namespace BinaryOperator
37
38namespace Sign {
39inline constexpr int no_sign = 0;
40inline constexpr int single = 1;
41inline constexpr int double_ = 2;
42} // namespace Sign
43
44namespace Relation {
45inline constexpr int equal = 0;
46inline constexpr int not_equal = 1;
47inline constexpr int less = 2;
48inline constexpr int less_equal = 3;
49inline constexpr int greater = 4;
50inline constexpr int greater_equal = 5;
51} // namespace Relation
52
53namespace AggregateFunction {
54inline constexpr int count = 0;
55inline constexpr int sum = 1;
56inline constexpr int sump = 2;
57inline constexpr int min = 3;
58inline constexpr int max = 4;
59} // namespace AggregateFunction
60
61namespace TheoryOperatorType {
62inline constexpr int unary = 0;
63inline constexpr int binary_left = 1;
64inline constexpr int binary_right = 2;
65} // namespace TheoryOperatorType
66
67namespace TheoryTupleType {
68inline constexpr int tuple = 0;
69inline constexpr int set = 1;
70inline constexpr int list = 2;
71} // namespace TheoryTupleType
72
73namespace TheoryAtomType {
74inline constexpr int head = 0;
75inline constexpr int body = 1;
76inline constexpr int any = 2;
77inline constexpr int directive = 3;
78} // namespace TheoryAtomType
79
80namespace OptimizeType {
81inline constexpr int minimize = 0;
82inline constexpr int maximize = 1;
83} // namespace OptimizeType
84
85namespace IncludeType {
86inline constexpr int system = 0;
87inline constexpr int inbuild = 1;
88} // namespace IncludeType
89
90namespace Precedence {
91inline constexpr int default_ = 0;
92inline constexpr int override = 1;
93} // namespace Precedence
94
95namespace CommentType {
96inline constexpr int line = 0;
97inline constexpr int block = 1;
98} // namespace CommentType
99
102 anonymous = clingo_ast_attribute_anonymous,
103 arguments = clingo_ast_attribute_arguments,
104 arity = clingo_ast_attribute_arity,
105 atom = clingo_ast_attribute_atom,
106 atoms = clingo_ast_attribute_atoms,
107 atom_type = clingo_ast_attribute_atom_type,
108 body = clingo_ast_attribute_body,
109 comment_type = clingo_ast_attribute_comment_type,
110 condition = clingo_ast_attribute_condition,
111 precedence = clingo_ast_attribute_precedence,
112 elements = clingo_ast_attribute_elements,
113 external = clingo_ast_attribute_external,
114 external_type = clingo_ast_attribute_external_type,
115 function = clingo_ast_attribute_function,
116 guard = clingo_ast_attribute_guard,
117 head = clingo_ast_attribute_head,
118 include_type = clingo_ast_attribute_include_type,
119 left = clingo_ast_attribute_left,
120 literal = clingo_ast_attribute_literal,
121 location = clingo_ast_attribute_location,
122 modifier = clingo_ast_attribute_modifier,
123 name = clingo_ast_attribute_name,
124 operators = clingo_ast_attribute_operators,
125 operator_type = clingo_ast_attribute_operator_type,
126 optimize_type = clingo_ast_attribute_optimize_type,
127 pool = clingo_ast_attribute_pool,
128 priority = clingo_ast_attribute_priority,
129 relation = clingo_ast_attribute_relation,
130 right = clingo_ast_attribute_right,
131 script_type = clingo_ast_attribute_script_type,
132 sign = clingo_ast_attribute_sign,
133 symbol = clingo_ast_attribute_symbol,
134 term = clingo_ast_attribute_term,
135 terms = clingo_ast_attribute_terms,
136 theory_operator = clingo_ast_attribute_theory_operator,
137 tuple = clingo_ast_attribute_tuple,
138 tuple_type = clingo_ast_attribute_tuple_type,
139 u = clingo_ast_attribute_u,
140 v = clingo_ast_attribute_v,
141 value = clingo_ast_attribute_value,
142 weight = clingo_ast_attribute_weight
143};
144
149 // terms
150 format_field_literal = clingo_ast_type_format_field_literal,
151 format_field_expression = clingo_ast_type_format_field_expression,
152 projection = clingo_ast_type_projection,
153 term_format_string = clingo_ast_type_term_format_string,
154 term_variable = clingo_ast_type_term_variable,
155 term_symbolic = clingo_ast_type_term_symbolic,
156 term_absolute = clingo_ast_type_term_absolute,
157 term_unary_operation = clingo_ast_type_term_unary_operation,
158 term_binary_operation = clingo_ast_type_term_binary_operation,
159 term_tuple = clingo_ast_type_term_tuple,
160 term_function = clingo_ast_type_term_function,
161 argument_tuple = clingo_ast_type_argument_tuple,
162 // theory terms
163 unparsed_element = clingo_ast_type_unparsed_element,
164 theory_term_variable = clingo_ast_type_theory_term_variable,
165 theory_term_symbolic = clingo_ast_type_theory_term_symbolic,
166 theory_term_tuple = clingo_ast_type_theory_term_tuple,
167 theory_term_function = clingo_ast_type_theory_term_function,
168 theory_term_unparsed = clingo_ast_type_theory_term_unparsed,
169 // literals
170 left_guard = clingo_ast_type_left_guard,
171 right_guard = clingo_ast_type_right_guard,
172 literal_boolean = clingo_ast_type_literal_boolean,
173 literal_comparison = clingo_ast_type_literal_comparison,
174 literal_symbolic = clingo_ast_type_literal_symbolic,
175 // set aggregates and theory atoms
176 set_aggregate_element = clingo_ast_type_set_aggregate_element,
177 theory_atom_element = clingo_ast_type_theory_atom_element,
178 theory_right_guard = clingo_ast_type_theory_right_guard,
179 // body literals
180 body_simple_literal = clingo_ast_type_body_simple_literal,
181 body_aggregate_element = clingo_ast_type_body_aggregate_element,
182 body_aggregate = clingo_ast_type_body_aggregate,
183 body_set_aggregate = clingo_ast_type_body_set_aggregate,
184 body_theory_atom = clingo_ast_type_body_theory_atom,
185 body_conditional_literal = clingo_ast_type_body_conditional_literal,
186 body_sort = clingo_ast_type_body_sort,
187 // head literals
188 head_simple_literal = clingo_ast_type_head_simple_literal,
189 head_aggregate_element = clingo_ast_type_head_aggregate_element,
190 head_aggregate = clingo_ast_type_head_aggregate,
191 head_set_aggregate = clingo_ast_type_head_set_aggregate,
192 head_theory_atom = clingo_ast_type_head_theory_atom,
193 head_conditional_literal = clingo_ast_type_head_conditional_literal,
194 head_disjunction = clingo_ast_type_head_disjunction,
195 // theory definition
196 theory_operator_definition = clingo_ast_type_theory_operator_definition,
197 theory_term_definition = clingo_ast_type_theory_term_definition,
198 theory_guard_definition = clingo_ast_type_theory_guard_definition,
199 theory_atom_definition = clingo_ast_type_theory_atom_definition,
200 // elements
201 optimize_tuple = clingo_ast_type_optimize_tuple,
202 optimize_element = clingo_ast_type_optimize_element,
203 edge = clingo_ast_type_edge,
204 program_part = clingo_ast_type_program_part,
205 // statements
206 statement_rule = clingo_ast_type_statement_rule,
207 statement_theory = clingo_ast_type_statement_theory,
208 statement_optimize = clingo_ast_type_statement_optimize,
209 statement_weak_constraint = clingo_ast_type_statement_weak_constraint,
210 statement_show = clingo_ast_type_statement_show,
211 statement_show_nothing = clingo_ast_type_statement_show_nothing,
212 statement_show_signature = clingo_ast_type_statement_show_signature,
213 statement_project = clingo_ast_type_statement_project,
214 statement_project_signature = clingo_ast_type_statement_project_signature,
215 statement_defined = clingo_ast_type_statement_defined,
216 statement_external = clingo_ast_type_statement_external,
217 statement_edge = clingo_ast_type_statement_edge,
218 statement_heuristic = clingo_ast_type_statement_heuristic,
219 statement_script = clingo_ast_type_statement_script,
220 statement_program = clingo_ast_type_statement_program,
221 statement_include = clingo_ast_type_statement_include,
222 statement_const = clingo_ast_type_statement_const,
223 statement_parts = clingo_ast_type_statement_parts,
224 statement_comment = clingo_ast_type_statement_comment
225};
226
227class Node;
228
230using Visitor = std::function<void(Node const &)>;
237void visit(Visitor const &fun, Node const &node);
242void visit(Visitor const &fun, std::optional<Node> const &node);
247void visit(Visitor const &fun, std::span<Node const> nodes);
248
253using Transformer = std::function<std::optional<Node>(Node const &)>;
260auto transform(Transformer const &fun, Node const &node) -> std::optional<Node>;
265auto transform(Transformer const &fun, std::optional<Node> const &node) -> std::optional<std::optional<Node>>;
270auto transform(Transformer const &fun, std::vector<Node> nodes) -> std::optional<std::vector<Node>>;
271
277class Node {
278 public:
288 explicit Node(clingo_ast_t *ast, bool copy = false) : ast_{ast, copy} {}
289
291 [[nodiscard]] friend auto c_cast(Node const &x) -> clingo_ast_t * { return x.ast_.get(); }
292
299 template <NodeType Type, class... Args>
300 [[nodiscard]] static auto create(Library const &lib, Args const &...args) -> Node {
301 constexpr auto type = static_cast<size_t>(Type);
302 static_assert(type < Detail::cons.size(), "invalid type");
303 static_assert(sizeof...(Args) == Detail::cons.at(type).size(), "wrong number of arguments");
304 return Node{create_<type>(lib, std::make_index_sequence<Detail::cons.at(type).size()>(), args...)};
305 }
306
318 template <NodeType Type, class Updater>
319 [[nodiscard]] auto update(Library const &lib, Updater const &fun) const -> Node {
320 assert(Type == type());
321 constexpr auto type = static_cast<size_t>(Type);
322 static_assert(type < Detail::cons.size(), "invalid type");
323 return Node{update_<type>(lib, fun, std::make_index_sequence<Detail::cons.at(type).size()>())};
324 }
325
332 void accept(Visitor const &fun) const {
333 auto t = type();
334 for (auto const [attr, type] : Detail::cons.at(static_cast<size_t>(t))) {
335 if (type == Detail::Arg::node) {
336 visit(fun, node(static_cast<Attribute>(attr)));
337 } else if (type == Detail::Arg::optional_node) {
338 visit(fun, optional_node(static_cast<Attribute>(attr)));
339 } else if (type == Detail::Arg::node_array) {
340 visit(fun, nodes(static_cast<Attribute>(attr)));
341 }
342 }
343 }
344
349 [[nodiscard]] auto accept(Library const &lib, Transformer const &fun) const -> std::optional<Node> {
350 return dispatch_(lib, static_cast<size_t>(type()), fun, std::make_index_sequence<Detail::cons.size()>());
351 }
352
356 [[nodiscard]] auto type() const -> NodeType {
357 return static_cast<NodeType>(Detail::call<clingo_ast_get_type>(ast_.get()));
358 }
359
364 [[nodiscard]] auto number(Attribute attribute) const -> int {
365 return Detail::call<clingo_ast_attribute_get_number>(ast_.get(),
366 static_cast<clingo_ast_attribute_t>(attribute));
367 }
368
373 [[nodiscard]] auto symbol(Attribute attribute) const -> Symbol {
374 return Symbol{
375 Detail::call<clingo_ast_attribute_get_symbol>(ast_.get(), static_cast<clingo_ast_attribute_t>(attribute)),
376 true};
377 }
378
383 [[nodiscard]] auto symbols(Attribute attribute) const -> SymbolVector {
384 clingo_symbol_t const *value = nullptr;
385 size_t size = 0;
386 Detail::handle_error(clingo_ast_attribute_get_symbol_array(
387 ast_.get(), static_cast<clingo_ast_attribute_t>(attribute), &value, &size));
388 return Detail::transform(std::span{value, size}, [](auto x) { return Symbol{x, true}; });
389 }
390
395 [[nodiscard]] auto location(Attribute attribute) const -> Location {
396 return Location{Detail::call<clingo_ast_attribute_get_location>(
397 ast_.get(), static_cast<clingo_ast_attribute_t>(attribute))};
398 }
399
404 [[nodiscard]] auto string(Attribute attribute) const -> std::string_view {
405 auto [data, size] =
406 Detail::call<clingo_ast_attribute_get_string>(ast_.get(), static_cast<clingo_ast_attribute_t>(attribute));
407 return {data, size};
408 }
409
414 [[nodiscard]] auto strings(Attribute attribute) const -> std::vector<std::string_view> {
415 clingo_string_t const *value = nullptr;
416 size_t size = 0;
417 Detail::handle_error(clingo_ast_attribute_get_string_array(
418 ast_.get(), static_cast<clingo_ast_attribute_t>(attribute), &value, &size));
419 return Detail::transform(std::span{value, size}, [](auto x) { return std::string_view{x.data, x.size}; });
420 }
421
426 [[nodiscard]] auto node(Attribute attribute) const -> Node {
427 clingo_ast_t *value =
428 Detail::call<clingo_ast_attribute_get_ast>(ast_.get(), static_cast<clingo_ast_attribute_t>(attribute));
429 if (value == nullptr) {
430 throw std::runtime_error("invalid attribute");
431 }
432 return Node{value};
433 }
434
439 [[nodiscard]] auto optional_node(Attribute attribute) const -> std::optional<Node> {
440 clingo_ast_t *value =
441 Detail::call<clingo_ast_attribute_get_ast>(ast_.get(), static_cast<clingo_ast_attribute_t>(attribute));
442 return value != nullptr ? std::make_optional<Node>(value) : std::nullopt;
443 }
444
449 [[nodiscard]] auto nodes(Attribute attribute) const -> std::vector<Node> {
450 auto arr = Detail::Array{};
451 Detail::handle_error(clingo_ast_attribute_get_ast_array(
452 ast_.get(), static_cast<clingo_ast_attribute_t>(attribute), &arr.value, &arr.size));
453 return Detail::transform(std::span{arr.value, arr.size},
454 [](auto *&node) { return Node{std::exchange(node, nullptr)}; });
455 }
456
462 [[nodiscard]] auto to_string() const -> std::string {
463 auto bld = StringBuilder{};
464 Detail::handle_error(clingo_ast_to_string(ast_.get(), c_cast(bld)));
465 return std::string{bld.str()};
466 }
467
474 [[nodiscard]] auto hash() const noexcept -> size_t { return clingo_ast_hash(ast_.get()); }
475
481 friend auto operator==(Node const &a, Node const &b) noexcept -> bool {
482 return clingo_ast_equal(a.ast_.get(), b.ast_.get());
483 }
484
490 friend auto operator<=>(Node const &a, Node const &b) noexcept -> std::strong_ordering {
491 return clingo_ast_compare(a.ast_.get(), b.ast_.get()) <=> 0;
492 }
493
494 private:
495 // Convert strings and string arrays into mappable types.
496 template <class Arg> [[nodiscard]] static auto convert_(Arg const &arg) -> decltype(auto) {
497 if constexpr (Detail::is_contiguous_range_over<Arg, char> || std::is_same_v<Arg, char const *>) {
498 return std::string_view{arg};
499 } else if constexpr (Detail::is_range_over<Arg, char const *>) {
500 return Detail::transform(arg, [](auto str) { return clingo_string_t{str, std::strlen(str)}; });
501 } else if constexpr (Detail::is_range_over<Arg, std::string_view>) {
502 return Detail::transform(arg, [](auto str) { return clingo_string_t{str.data(), str.size()}; });
503 } else if constexpr (std::is_same_v<Arg, bool>) {
504 return static_cast<int>(arg);
505 } else {
506 return arg;
507 }
508 }
509
510 // Map arguments to their C representation.
511 template <Detail::Arg::Type Type, class Arg> [[nodiscard]] static auto map_(Arg const &arg) {
512 if constexpr (Detail::is_contiguous_range_over<Arg, Symbol>) {
513 static_assert(Type == Detail::Arg::symbol_array);
514 return std::make_tuple(std::ranges::data(arg), std::ranges::size(arg));
515 } else if constexpr (Detail::is_contiguous_range_over<Arg, Node>) {
516 static_assert(Type == Detail::Arg::node_array);
517 return std::make_tuple(std::ranges::data(arg), std::ranges::size(arg));
518 } else if constexpr (std::is_same_v<Arg, std::string_view>) {
519 static_assert(Type == Detail::Arg::string);
520 return std::make_tuple(std::ranges::data(arg), std::ranges::size(arg));
521 } else if constexpr (Detail::is_range_over<Arg, clingo_string_t>) {
522 static_assert(Type == Detail::Arg::string_array);
523 return std::make_tuple(std::ranges::data(arg), std::ranges::size(arg));
524 } else if constexpr (std::is_same_v<Arg, Node>) {
525 static_assert(Type == Detail::Arg::node || Type == Detail::Arg::optional_node);
526 return std::make_tuple(c_cast(arg));
527 } else if constexpr (std::is_same_v<Arg, std::nullopt_t>) {
528 static_assert(Type == Detail::Arg::optional_node);
529 return std::make_tuple(nullptr);
530 } else if constexpr (std::is_same_v<Arg, std::optional<Node>>) {
531 static_assert(Type == Detail::Arg::optional_node);
532 return std::make_tuple(arg ? c_cast(*arg) : nullptr);
533 } else if constexpr (std::is_same_v<Arg, Symbol>) {
534 static_assert(Type == Detail::Arg::symbol);
535 return std::make_tuple(c_cast(arg));
536 } else if constexpr (std::is_same_v<Arg, Location>) {
537 static_assert(Type == Detail::Arg::location);
538 return std::make_tuple(c_cast(arg));
539 } else if constexpr (std::is_same_v<Arg, int>) {
540 static_assert(Type == Detail::Arg::integer);
541 return std::make_tuple(arg);
542 } else {
543 static_assert(Detail::always_false<Arg>, "unsupported argument type");
544 }
545 }
546
548 template <size_t Type, size_t... Is, class... Args>
549 [[nodiscard]] static auto create_(Library const &lib, [[maybe_unused]] std::index_sequence<Is...> seq,
550 Args const &...args) -> clingo_ast_t * {
551 constexpr auto const &cons = Detail::cons.at(Type);
552 clingo_ast_t *ast = nullptr;
553 Detail::handle_error(
554 std::apply(clingo_ast_construct,
555 std::tuple_cat(std::make_tuple(c_cast(lib), static_cast<clingo_ast_type_t>(Type), &ast),
556 map_<cons[Is].type>(convert_(args))...)));
557 return ast;
558 }
559
561 template <size_t Type, size_t I> [[nodiscard]] auto get_() const {
562 constexpr auto const &cons = Detail::cons.at(Type);
563 constexpr auto attr = static_cast<Attribute>(cons[I].attr);
564 if constexpr (cons[I].type == Detail::Arg::integer) {
565 return number(attr);
566 } else if constexpr (cons[I].type == Detail::Arg::location) {
567 return location(attr);
568 } else if constexpr (cons[I].type == Detail::Arg::string) {
569 return string(attr);
570 } else if constexpr (cons[I].type == Detail::Arg::string_array) {
571 return strings(attr);
572 } else if constexpr (cons[I].type == Detail::Arg::symbol) {
573 return symbol(attr);
574 } else if constexpr (cons[I].type == Detail::Arg::symbol_array) {
575 return symbols(attr);
576 } else if constexpr (cons[I].type == Detail::Arg::node) {
577 return node(attr);
578 } else if constexpr (cons[I].type == Detail::Arg::optional_node) {
579 return optional_node(attr);
580 } else if constexpr (cons[I].type == Detail::Arg::node_array) {
581 return nodes(attr);
582 }
583 }
584
586 template <size_t Type, size_t I, typename F> [[nodiscard]] auto update_child_(F const &fun) const {
587 constexpr auto const &cons = Detail::cons.at(Type);
588 constexpr auto attr = static_cast<Attribute>(cons[I].attr);
589 if constexpr (Detail::invokable<F, attr>) {
590 return fun.template operator()<attr>();
591 } else {
592 return get_<Type, I>();
593 }
594 }
595
597 template <size_t Type, typename F, size_t... Is>
598 [[nodiscard]] auto update_(Library const &lib, F const &fun, std::index_sequence<Is...> seq) const
599 -> clingo_ast_t * {
600 return create_<Type>(lib, seq, update_child_<Type, Is>(fun)...);
601 }
602
604 template <size_t... Type>
605 [[nodiscard]] auto dispatch_(Library const &lib, size_t type, Transformer const &fun,
606 [[maybe_unused]] std::index_sequence<Type...> seq) const -> std::optional<Node> {
607 std::optional<Node> ret;
608 std::ignore =
609 (((type == Type)
610 ? (ret = apply_<Type>(lib, fun, std::make_index_sequence<Detail::cons.at(Type).size()>{}), true)
611 : false) ||
612 ...);
613 return ret;
614 }
615
617 template <typename Arg> [[nodiscard]] static auto has_value_(std::optional<Arg> const &arg) {
618 return arg.has_value();
619 }
621 [[nodiscard]] static auto has_value_([[maybe_unused]] std::nullopt_t null) { return false; }
622
624 template <size_t Type, size_t I, typename Arg> [[nodiscard]] auto get_value_(std::optional<Arg> arg) const {
625 return arg ? *std::move(arg) : get_<Type, I>();
626 }
627
629 template <size_t Type, size_t I> [[nodiscard]] auto get_value_([[maybe_unused]] std::nullopt_t null) const {
630 return get_<Type, I>();
631 }
632
634 template <size_t Type, size_t I> [[nodiscard]] auto transform_child_(Transformer const &fun) const {
635 constexpr auto const &cons = Detail::cons.at(Type);
636 constexpr auto attr = static_cast<Attribute>(cons[I].attr);
637 if constexpr (cons[I].type == Detail::Arg::node) {
638 return transform(fun, node(attr));
639 } else if constexpr (cons[I].type == Detail::Arg::optional_node) {
640 return transform(fun, optional_node(attr));
641 } else if constexpr (cons[I].type == Detail::Arg::node_array) {
642 return transform(fun, nodes(attr));
643 } else {
644 return std::nullopt;
645 }
646 }
647
649 template <size_t Type, size_t... Is>
650 [[nodiscard]] auto apply_(Library const &lib, Transformer const &fun, std::index_sequence<Is...> seq) const
651 -> std::optional<Node> {
652 return transform_<Type, Is...>(lib, seq, transform_child_<Type, Is>(fun)...);
653 }
654
656 template <size_t Type, size_t... Is, typename... Args>
657 [[nodiscard]] auto transform_(Library const &lib, std::index_sequence<Is...> seq, Args &&...args) const
658 -> std::optional<Node> {
659 if ((has_value_(args) || ...)) {
660 return Node{create_<Type>(lib, seq, get_value_<Type, Is>(std::forward<Args>(args))...)};
661 }
662 return std::nullopt;
663 }
664
665 using Traits = Detail::value_handle_traits<clingo_ast_copy, clingo_ast_free>;
666 Detail::value_handle<Traits> ast_;
667};
668
669inline void visit(Visitor const &fun, Node const &node) {
670 fun(node);
671}
672
673inline void visit(Visitor const &fun, std::optional<Node> const &node) {
674 if (node) {
675 fun(*node);
676 }
677}
678
679inline void visit(Visitor const &fun, std::span<Node const> nodes) {
680 for (auto const &node : nodes) {
681 fun(node);
682 }
683}
684
685inline auto transform(Transformer const &fun, Node const &node) -> std::optional<Node> {
686 return fun(node);
687}
688
689inline auto transform(Transformer const &fun, std::optional<Node> const &node) -> std::optional<std::optional<Node>> {
690 auto res = std::optional<std::optional<Node>>();
691 if (node) {
692 if (auto trans = fun(*node)) {
693 res.emplace(std::move(trans));
694 }
695 }
696 return res;
697}
698
699inline auto transform(Transformer const &fun, std::vector<Node> nodes) -> std::optional<std::vector<Node>> {
700 bool changed = false;
701 for (auto &node : nodes) {
702 if (auto trans = fun(node)) {
703 changed = true;
704 node = *std::move(trans);
705 }
706 }
707 return changed ? std::make_optional(std::move(nodes)) : std::nullopt;
708}
709
713 term = clingo_ast_parse_type_term,
715 theory_term = clingo_ast_parse_type_theory_term,
717 literal = clingo_ast_parse_type_literal,
719 body_literal = clingo_ast_parse_type_body_literal,
721 head_literal = clingo_ast_parse_type_head_literal,
723 statement = clingo_ast_parse_type_statement,
724};
725
735
738 public:
742 explicit RewriteContext(Library const &lib) : ctx_{Detail::call<clingo_ast_rewrite_context_create>(c_cast(lib))} {}
743
745 friend auto c_cast(RewriteContext const &x) -> clingo_ast_rewrite_context_t * { return x.ctx_.get(); }
746
753
758 return static_cast<ProjectionMode>(clingo_ast_rewrite_context_get_project_mode(ctx_.get()));
759 }
760
768
772 auto project_anonymous() -> bool { return clingo_ast_rewrite_context_get_project_mode(ctx_.get()) != 0; }
773
780 void add_param(std::string_view name) {
781 Detail::handle_error(clingo_ast_rewrite_context_add_param(ctx_.get(), name.data(), name.size()));
782 }
783
786
790 void add_theory(Node const &stm) {
791 Detail::handle_error(clingo_ast_rewrite_context_add_theory(ctx_.get(), c_cast(stm)));
792 }
793
794 private:
795 Detail::unique_handle<clingo_ast_rewrite_context_t, clingo_ast_rewrite_context_free> ctx_;
796};
797
805inline auto rewrite(RewriteContext &ctx, Node const &stm) -> std::vector<Node> {
806 auto arr = Detail::Array{};
807 Detail::handle_error(clingo_ast_rewrite(c_cast(ctx), c_cast(stm), &arr.value, &arr.size));
808 return Detail::transform(std::span{arr.value, arr.size},
809 [](auto *&ast) { return Node{std::exchange(ast, nullptr)}; });
810}
811
813class Program {
814 public:
818 Program(Library const &lib) : prg_{Detail::call<clingo_program_new>(c_cast(lib))} {}
819
823 void add(Node const &stm) const { Detail::handle_error(clingo_program_add(prg_.get(), c_cast(stm))); }
824
829 friend auto c_cast(Program const &x) -> clingo_program_t * { return x.prg_.get(); }
830
831 private:
832 Detail::unique_handle<clingo_program_t, clingo_program_free> prg_;
833};
834
841inline auto parse(Library const &lib, std::string_view string, ParseType type = ParseType::statement) -> Node {
842 return Node{Detail::call<clingo_ast_parse_expression>(c_cast(lib), static_cast<clingo_ast_parse_type_t>(type),
843 string.data(), string.size())};
844}
845
852template <class Callback>
853// NOLINTNEXTLINE
854inline void parse(Library const &lib, std::string_view program, Callback &&callback,
855 Clingo::Control const *control = nullptr) {
857 c_cast(lib), program.data(), program.size(), control != nullptr ? c_cast(*control) : nullptr,
858 [](clingo_ast_t *ast, void *data) {
859 auto &callback = *static_cast<Callback *>(data);
860 CLINGO_TRY {
861 callback(Node{ast, true});
862 }
863 CLINGO_CATCH;
864 },
865 &callback);
866}
867
874template <class Callback>
875// NOLINTNEXTLINE
876inline void parse(Library const &lib, std::span<std::string_view const> files, Callback &&callback,
877 Clingo::Control const *control = nullptr) {
878 auto cfiles = Detail::transform(files, [](auto const &x) { return clingo_string_t{x.data(), x.size()}; });
880 c_cast(lib), cfiles.data(), cfiles.size(), control != nullptr ? c_cast(*control) : nullptr,
881 [](clingo_ast_t *ast, void *data) {
882 CLINGO_TRY {
883 auto &callback = *static_cast<Callback *>(data);
884 std::invoke(callback, Node{ast, true});
885 }
886 CLINGO_CATCH;
887 },
888 &callback);
889}
890
897template <class Callback>
898inline void parse(Library const &lib, std::initializer_list<std::string_view> files, Callback &&callback,
899 Clingo::Control const *control = nullptr) {
900 parse(lib, std::span{files.begin(), files.end()}, std::forward<Callback>(callback), control);
901}
903
904} // namespace Clingo::AST
905
906namespace std {
907
909template <> struct hash<Clingo::AST::Node> {
911 auto operator()(Clingo::AST::Node const &x) const noexcept -> size_t { return x.hash(); }
912};
913
914} // namespace std
Node capturing expressions in logic programs.
Definition ast.hh:277
auto symbol(Attribute attribute) const -> Symbol
Get the symbolic value of the given attribute.
Definition ast.hh:373
auto type() const -> NodeType
Get the type of the node.
Definition ast.hh:356
auto strings(Attribute attribute) const -> std::vector< std::string_view >
Get the string values of the given attribute.
Definition ast.hh:414
auto to_string() const -> std::string
Get a string representation of the node.
Definition ast.hh:462
friend auto operator<=>(Node const &a, Node const &b) noexcept -> std::strong_ordering
Compare two nodes.
Definition ast.hh:490
friend auto operator==(Node const &a, Node const &b) noexcept -> bool
Equality compare two nodes.
Definition ast.hh:481
auto location(Attribute attribute) const -> Location
Get the location value of the given attribute.
Definition ast.hh:395
auto update(Library const &lib, Updater const &fun) const -> Node
Visit a node of the given type.
Definition ast.hh:319
auto node(Attribute attribute) const -> Node
Get the node value of the given attribute.
Definition ast.hh:426
void accept(Visitor const &fun) const
Visit the direct children of the node with the given visitor.
Definition ast.hh:332
auto accept(Library const &lib, Transformer const &fun) const -> std::optional< Node >
Transform the direct children of the node with the given transformer.
Definition ast.hh:349
Node(clingo_ast_t *ast, bool copy=false)
Construct a node form its C representation.
Definition ast.hh:288
friend auto c_cast(Node const &x) -> clingo_ast_t *
Cast the node to its underlying C representation.
Definition ast.hh:291
auto string(Attribute attribute) const -> std::string_view
Get the string value of the given attribute.
Definition ast.hh:404
static auto create(Library const &lib, Args const &...args) -> Node
Construct a node of the given type.
Definition ast.hh:300
auto optional_node(Attribute attribute) const -> std::optional< Node >
Get the optional node value of the given attribute.
Definition ast.hh:439
auto number(Attribute attribute) const -> int
Get the numeric value of the given attribute.
Definition ast.hh:364
auto hash() const noexcept -> size_t
Get a hash for the node.
Definition ast.hh:474
auto symbols(Attribute attribute) const -> SymbolVector
Get the symbolic values of the given attribute.
Definition ast.hh:383
auto nodes(Attribute attribute) const -> std::vector< Node >
Get the node values of the given attribute.
Definition ast.hh:449
A program to add statements to.
Definition ast.hh:813
void add(Node const &stm) const
Add a statemente node to the program.
Definition ast.hh:823
Program(Library const &lib)
Construct an empty program.
Definition ast.hh:818
friend auto c_cast(Program const &x) -> clingo_program_t *
Convert the program to its underlying C representation.
Definition ast.hh:829
A context object for rewriting.
Definition ast.hh:737
auto project_mode() -> ProjectionMode
Get the projection mode.
Definition ast.hh:757
void clear_params()
Clear previously protected parameters.
Definition ast.hh:785
void add_theory(Node const &stm)
Add a theory node that is used to rewrite theory atoms in statements.
Definition ast.hh:790
RewriteContext(Library const &lib)
Construct the context.
Definition ast.hh:742
friend auto c_cast(RewriteContext const &x) -> clingo_ast_rewrite_context_t *
Convert the context to its underlying C object.
Definition ast.hh:745
void project_mode(ProjectionMode value)
Set the projection mode.
Definition ast.hh:750
auto project_anonymous() -> bool
Check whether projection in negative literals is enabled.
Definition ast.hh:772
void add_param(std::string_view name)
Protect a parameter from simplification.
Definition ast.hh:780
void project_anonymous(bool value)
Enable projection of anonymous variables in negated literals.
Definition ast.hh:767
The main control class for grounding and solving logic programs.
Definition control.hh:160
The main library class for managing global information and logging.
Definition core.hh:566
Class representing a range in a file.
Definition core.hh:751
A string builder for constructing strings.
Definition core.hh:619
Class modeling a symbol in Clingo.
Definition symbol.hh:68
CLINGO_VISIBILITY_DEFAULT bool clingo_ast_rewrite_context_add_param(clingo_ast_rewrite_context_t *context, char const *param, size_t size)
Protect the given parameter from simplifications.
CLINGO_VISIBILITY_DEFAULT bool clingo_ast_parse_files(clingo_lib_t *lib, clingo_string_t const *files, size_t size, clingo_control_t *control, clingo_ast_callback_t callback, void *data)
Parse a program from the given files.
CLINGO_VISIBILITY_DEFAULT bool clingo_ast_attribute_get_symbol_array(clingo_ast_t *ast, clingo_ast_attribute_t attribute, clingo_symbol_t const **value, size_t *size)
Get the value of a symbol array attribute.
struct clingo_ast clingo_ast_t
This struct provides a view to nodes in the AST.
Definition ast.h:161
struct clingo_program clingo_program_t
Object to store.
Definition ast.h:505
CLINGO_VISIBILITY_DEFAULT bool clingo_ast_attribute_get_string_array(clingo_ast_t *ast, clingo_ast_attribute_t attribute, clingo_string_t const **value, size_t *size)
Get the value of a string array attribute.
int clingo_ast_type_t
Corresponding type to clingo_ast_type_e.
Definition ast.h:110
CLINGO_VISIBILITY_DEFAULT bool clingo_program_new(clingo_lib_t *lib, clingo_program_t **program)
Create an empty non-ground program.
CLINGO_VISIBILITY_DEFAULT void clingo_ast_rewrite_context_set_project_mode(clingo_ast_rewrite_context_t *context, clingo_projection_mode_t value)
Configure the projection mode.
int clingo_ast_attribute_t
Corresponding type to clingo_ast_attribute_e.
Definition ast.h:158
CLINGO_VISIBILITY_DEFAULT bool clingo_ast_to_string(clingo_ast_t *ast, clingo_string_builder_t *builder)
Get the string representation of an AST node.
int clingo_ast_parse_type_t
Corresponding type to clingo_ast_parse_type_e.
Definition ast.h:191
struct clingo_ast_rewrite_context clingo_ast_rewrite_context_t
Context object to rewrite statements.
Definition ast.h:418
CLINGO_VISIBILITY_DEFAULT bool clingo_program_add(clingo_program_t *program, clingo_ast_t *statement)
Adds a statement to the program.
CLINGO_VISIBILITY_DEFAULT bool clingo_ast_equal(clingo_ast_t *a, clingo_ast_t *b)
Equality compare two AST nodes.
int clingo_projection_mode_t
Corresponding type to clingo_projection_mode_e.
Definition ast.h:415
CLINGO_VISIBILITY_DEFAULT int clingo_ast_compare(clingo_ast_t *a, clingo_ast_t *b)
Less than compare two AST nodes.
CLINGO_VISIBILITY_DEFAULT void clingo_ast_rewrite_context_clear_params(clingo_ast_rewrite_context_t *context)
Remove all previously added parameters.
CLINGO_VISIBILITY_DEFAULT bool clingo_ast_rewrite_context_create(clingo_lib_t *lib, clingo_ast_rewrite_context_t **context)
Create a new rewrite context.
CLINGO_VISIBILITY_DEFAULT clingo_projection_mode_t clingo_ast_rewrite_context_get_project_mode(clingo_ast_rewrite_context_t *context)
Get the configured projection mode.
CLINGO_VISIBILITY_DEFAULT bool clingo_ast_attribute_get_ast_array(clingo_ast_t *ast, clingo_ast_attribute_t attribute, clingo_ast_t ***value, size_t *size)
Get the value of an ast array attribute.
CLINGO_VISIBILITY_DEFAULT void clingo_ast_rewrite_context_set_project_anonymous(clingo_ast_rewrite_context_t *context, bool value)
Configure whether anonymous variables in negative literals are projected.
CLINGO_VISIBILITY_DEFAULT bool clingo_ast_rewrite_context_add_theory(clingo_ast_rewrite_context_t *context, clingo_ast_t const *theory)
Add a theory definition to the rewrite context.
CLINGO_VISIBILITY_DEFAULT bool clingo_ast_construct(clingo_lib_t *lib, clingo_ast_type_t type, clingo_ast_t **ast,...)
Construct an AST of the given type.
CLINGO_VISIBILITY_DEFAULT bool clingo_ast_rewrite(clingo_ast_rewrite_context_t *context, clingo_ast_t *statement, clingo_ast_t ***result, size_t *result_size)
Rewrite the given statement.
CLINGO_VISIBILITY_DEFAULT bool clingo_ast_parse_string(clingo_lib_t *lib, char const *program, size_t size, clingo_control_t *control, clingo_ast_callback_t callback, void *data)
Parse a program from a string.
CLINGO_VISIBILITY_DEFAULT size_t clingo_ast_hash(clingo_ast_t *ast)
Compute a hash for an AST node.
@ clingo_projection_mode_disabled
Disable projection.
Definition ast.h:410
@ clingo_projection_mode_pure
Project pure variables.
Definition ast.h:412
@ clingo_projection_mode_anonymous
Only project anonymous variables.
Definition ast.h:411
uint64_t clingo_symbol_t
Type to represent a symbol.
Definition symbol.h:51
Relation
Enumeration of supported relations.
Definition core.hh:35
Sign
Enumeration of signs (default negation).
Definition core.hh:16
AggregateFunction
Enumeration of aggregate functions.
Definition core.hh:87
Attribute
Enumeration of available ast attributes.
Definition ast.hh:101
auto transform(Transformer const &fun, Node const &node) -> std::optional< Node >
Transform the given node with the transformer.
Definition ast.hh:685
ProjectionMode
The available projection modes.
Definition ast.hh:727
std::function< std::optional< Node >(Node const &)> Transformer
Function to transform ast nodes.
Definition ast.hh:253
std::function< void(Node const &)> Visitor
Function to visit ast nodes.
Definition ast.hh:230
ParseType
Enumeration of expression types that can be parsed.
Definition ast.hh:711
void visit(Visitor const &fun, Node const &node)
Visit the given node with the visitor.
Definition ast.hh:669
NodeType
Enumeration of available ast node types.
Definition ast.hh:148
@ disabled
Do not project.
@ pure
Project pure variables (includes anonymous variables).
@ theory_term
Parse a theory term.
@ statement
Parse a statement.
@ head_literal
Parse a head literal.
@ body_literal
Parse a body literal.
@ number
a number term, e.g., 42
@ symbols
Whether to write symbols in a structured format.
@ parse
Parse only.
@ rewrite
Parse and rewrite.
std::vector< Symbol > SymbolVector
A vector of symbols.
Definition symbol.hh:42
@ string
The symbol is a string.
Precedence
Enumeration of constant statement types.
Definition statement.hh:723
TheoryAtomType
Enumeration of theory atom types.
Definition statement.hh:117
IncludeType
Enumeration of include types.
Definition statement.hh:658
OptimizeType
Enumeration of optimization statement types.
Definition statement.hh:225
CommentType
Enumeration of comment types.
Definition statement.hh:796
BinaryOperator
Enumeration of available binary operators.
Definition term.hh:343
UnaryOperator
Enumeration of available unary operators.
Definition term.hh:311
Struct to capture strings that are not null-terminated.
Definition core.h:86
char const * data
pointer to the beginning of the string
Definition core.h:87