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 // head literals
187 head_simple_literal = clingo_ast_type_head_simple_literal,
188 head_aggregate_element = clingo_ast_type_head_aggregate_element,
189 head_aggregate = clingo_ast_type_head_aggregate,
190 head_set_aggregate = clingo_ast_type_head_set_aggregate,
191 head_theory_atom = clingo_ast_type_head_theory_atom,
192 head_conditional_literal = clingo_ast_type_head_conditional_literal,
193 head_disjunction = clingo_ast_type_head_disjunction,
194 // theory definition
195 theory_operator_definition = clingo_ast_type_theory_operator_definition,
196 theory_term_definition = clingo_ast_type_theory_term_definition,
197 theory_guard_definition = clingo_ast_type_theory_guard_definition,
198 theory_atom_definition = clingo_ast_type_theory_atom_definition,
199 // elements
200 optimize_tuple = clingo_ast_type_optimize_tuple,
201 optimize_element = clingo_ast_type_optimize_element,
202 edge = clingo_ast_type_edge,
203 program_part = clingo_ast_type_program_part,
204 // statements
205 statement_rule = clingo_ast_type_statement_rule,
206 statement_theory = clingo_ast_type_statement_theory,
207 statement_optimize = clingo_ast_type_statement_optimize,
208 statement_weak_constraint = clingo_ast_type_statement_weak_constraint,
209 statement_show = clingo_ast_type_statement_show,
210 statement_show_nothing = clingo_ast_type_statement_show_nothing,
211 statement_show_signature = clingo_ast_type_statement_show_signature,
212 statement_project = clingo_ast_type_statement_project,
213 statement_project_signature = clingo_ast_type_statement_project_signature,
214 statement_defined = clingo_ast_type_statement_defined,
215 statement_external = clingo_ast_type_statement_external,
216 statement_edge = clingo_ast_type_statement_edge,
217 statement_heuristic = clingo_ast_type_statement_heuristic,
218 statement_script = clingo_ast_type_statement_script,
219 statement_program = clingo_ast_type_statement_program,
220 statement_include = clingo_ast_type_statement_include,
221 statement_const = clingo_ast_type_statement_const,
222 statement_parts = clingo_ast_type_statement_parts,
223 statement_comment = clingo_ast_type_statement_comment
224};
225
226class Node;
227
229using Visitor = std::function<void(Node const &)>;
236void visit(Visitor const &fun, Node const &node);
241void visit(Visitor const &fun, std::optional<Node> const &node);
246void visit(Visitor const &fun, std::span<Node const> nodes);
247
252using Transformer = std::function<std::optional<Node>(Node const &)>;
259auto transform(Transformer const &fun, Node const &node) -> std::optional<Node>;
264auto transform(Transformer const &fun, std::optional<Node> const &node) -> std::optional<std::optional<Node>>;
269auto transform(Transformer const &fun, std::vector<Node> nodes) -> std::optional<std::vector<Node>>;
270
276class Node {
277 public:
287 explicit Node(clingo_ast_t *ast, bool copy = false) : ast_{ast, copy} {}
288
290 [[nodiscard]] friend auto c_cast(Node const &x) -> clingo_ast_t * { return x.ast_.get(); }
291
298 template <NodeType Type, class... Args>
299 [[nodiscard]] static auto create(Library const &lib, Args const &...args) -> Node {
300 constexpr auto type = static_cast<size_t>(Type);
301 static_assert(type < Detail::cons.size(), "invalid type");
302 static_assert(sizeof...(Args) == Detail::cons.at(type).size(), "wrong number of arguments");
303 return Node{create_<type>(lib, std::make_index_sequence<Detail::cons.at(type).size()>(), args...)};
304 }
305
317 template <NodeType Type, class Updater>
318 [[nodiscard]] auto update(Library const &lib, Updater const &fun) const -> Node {
319 assert(Type == type());
320 constexpr auto type = static_cast<size_t>(Type);
321 static_assert(type < Detail::cons.size(), "invalid type");
322 return Node{update_<type>(lib, fun, std::make_index_sequence<Detail::cons.at(type).size()>())};
323 }
324
331 void accept(Visitor const &fun) const {
332 auto t = type();
333 for (auto const [attr, type] : Detail::cons.at(static_cast<size_t>(t))) {
334 if (type == Detail::Arg::node) {
335 visit(fun, node(static_cast<Attribute>(attr)));
336 } else if (type == Detail::Arg::optional_node) {
337 visit(fun, optional_node(static_cast<Attribute>(attr)));
338 } else if (type == Detail::Arg::node_array) {
339 visit(fun, nodes(static_cast<Attribute>(attr)));
340 }
341 }
342 }
343
348 [[nodiscard]] auto accept(Library const &lib, Transformer const &fun) const -> std::optional<Node> {
349 return dispatch_(lib, static_cast<size_t>(type()), fun, std::make_index_sequence<Detail::cons.size()>());
350 }
351
355 [[nodiscard]] auto type() const -> NodeType {
356 return static_cast<NodeType>(Detail::call<clingo_ast_get_type>(ast_.get()));
357 }
358
363 [[nodiscard]] auto number(Attribute attribute) const -> int {
364 return Detail::call<clingo_ast_attribute_get_number>(ast_.get(),
365 static_cast<clingo_ast_attribute_t>(attribute));
366 }
367
372 [[nodiscard]] auto symbol(Attribute attribute) const -> Symbol {
373 return Symbol{
374 Detail::call<clingo_ast_attribute_get_symbol>(ast_.get(), static_cast<clingo_ast_attribute_t>(attribute)),
375 true};
376 }
377
382 [[nodiscard]] auto symbols(Attribute attribute) const -> SymbolVector {
383 clingo_symbol_t const *value = nullptr;
384 size_t size = 0;
385 Detail::handle_error(clingo_ast_attribute_get_symbol_array(
386 ast_.get(), static_cast<clingo_ast_attribute_t>(attribute), &value, &size));
387 return Detail::transform(std::span{value, size}, [](auto x) { return Symbol{x, true}; });
388 }
389
394 [[nodiscard]] auto location(Attribute attribute) const -> Location {
395 return Location{Detail::call<clingo_ast_attribute_get_location>(
396 ast_.get(), static_cast<clingo_ast_attribute_t>(attribute))};
397 }
398
403 [[nodiscard]] auto string(Attribute attribute) const -> std::string_view {
404 auto [data, size] =
405 Detail::call<clingo_ast_attribute_get_string>(ast_.get(), static_cast<clingo_ast_attribute_t>(attribute));
406 return {data, size};
407 }
408
413 [[nodiscard]] auto strings(Attribute attribute) const -> std::vector<std::string_view> {
414 clingo_string_t const *value = nullptr;
415 size_t size = 0;
416 Detail::handle_error(clingo_ast_attribute_get_string_array(
417 ast_.get(), static_cast<clingo_ast_attribute_t>(attribute), &value, &size));
418 return Detail::transform(std::span{value, size}, [](auto x) { return std::string_view{x.data, x.size}; });
419 }
420
425 [[nodiscard]] auto node(Attribute attribute) const -> Node {
426 clingo_ast_t *value =
427 Detail::call<clingo_ast_attribute_get_ast>(ast_.get(), static_cast<clingo_ast_attribute_t>(attribute));
428 if (value == nullptr) {
429 throw std::runtime_error("invalid attribute");
430 }
431 return Node{value};
432 }
433
438 [[nodiscard]] auto optional_node(Attribute attribute) const -> std::optional<Node> {
439 clingo_ast_t *value =
440 Detail::call<clingo_ast_attribute_get_ast>(ast_.get(), static_cast<clingo_ast_attribute_t>(attribute));
441 return value != nullptr ? std::make_optional<Node>(value) : std::nullopt;
442 }
443
448 [[nodiscard]] auto nodes(Attribute attribute) const -> std::vector<Node> {
449 auto arr = Detail::Array{};
450 Detail::handle_error(clingo_ast_attribute_get_ast_array(
451 ast_.get(), static_cast<clingo_ast_attribute_t>(attribute), &arr.value, &arr.size));
452 return Detail::transform(std::span{arr.value, arr.size},
453 [](auto *&node) { return Node{std::exchange(node, nullptr)}; });
454 }
455
461 [[nodiscard]] auto to_string() const -> std::string {
462 auto bld = StringBuilder{};
463 Detail::handle_error(clingo_ast_to_string(ast_.get(), c_cast(bld)));
464 return std::string{bld.str()};
465 }
466
473 [[nodiscard]] auto hash() const noexcept -> size_t { return clingo_ast_hash(ast_.get()); }
474
480 friend auto operator==(Node const &a, Node const &b) noexcept -> bool {
481 return clingo_ast_equal(a.ast_.get(), b.ast_.get());
482 }
483
489 friend auto operator<=>(Node const &a, Node const &b) noexcept -> std::strong_ordering {
490 return clingo_ast_compare(a.ast_.get(), b.ast_.get()) <=> 0;
491 }
492
493 private:
494 // Convert strings and string arrays into mappable types.
495 template <class Arg> [[nodiscard]] static auto convert_(Arg const &arg) -> decltype(auto) {
496 if constexpr (Detail::is_contiguous_range_over<Arg, char> || std::is_same_v<Arg, char const *>) {
497 return std::string_view{arg};
498 } else if constexpr (Detail::is_range_over<Arg, char const *>) {
499 return Detail::transform(arg, [](auto str) { return clingo_string_t{str, std::strlen(str)}; });
500 } else if constexpr (Detail::is_range_over<Arg, std::string_view>) {
501 return Detail::transform(arg, [](auto str) { return clingo_string_t{str.data(), str.size()}; });
502 } else if constexpr (std::is_same_v<Arg, bool>) {
503 return static_cast<int>(arg);
504 } else {
505 return arg;
506 }
507 }
508
509 // Map arguments to their C representation.
510 template <Detail::Arg::Type Type, class Arg> [[nodiscard]] static auto map_(Arg const &arg) {
511 if constexpr (Detail::is_contiguous_range_over<Arg, Symbol>) {
512 static_assert(Type == Detail::Arg::symbol_array);
513 return std::make_tuple(std::ranges::data(arg), std::ranges::size(arg));
514 } else if constexpr (Detail::is_contiguous_range_over<Arg, Node>) {
515 static_assert(Type == Detail::Arg::node_array);
516 return std::make_tuple(std::ranges::data(arg), std::ranges::size(arg));
517 } else if constexpr (std::is_same_v<Arg, std::string_view>) {
518 static_assert(Type == Detail::Arg::string);
519 return std::make_tuple(std::ranges::data(arg), std::ranges::size(arg));
520 } else if constexpr (Detail::is_range_over<Arg, clingo_string_t>) {
521 static_assert(Type == Detail::Arg::string_array);
522 return std::make_tuple(std::ranges::data(arg), std::ranges::size(arg));
523 } else if constexpr (std::is_same_v<Arg, Node>) {
524 static_assert(Type == Detail::Arg::node || Type == Detail::Arg::optional_node);
525 return std::make_tuple(c_cast(arg));
526 } else if constexpr (std::is_same_v<Arg, std::nullopt_t>) {
527 static_assert(Type == Detail::Arg::optional_node);
528 return std::make_tuple(nullptr);
529 } else if constexpr (std::is_same_v<Arg, std::optional<Node>>) {
530 static_assert(Type == Detail::Arg::optional_node);
531 return std::make_tuple(arg ? c_cast(*arg) : nullptr);
532 } else if constexpr (std::is_same_v<Arg, Symbol>) {
533 static_assert(Type == Detail::Arg::symbol);
534 return std::make_tuple(c_cast(arg));
535 } else if constexpr (std::is_same_v<Arg, Location>) {
536 static_assert(Type == Detail::Arg::location);
537 return std::make_tuple(c_cast(arg));
538 } else if constexpr (std::is_same_v<Arg, int>) {
539 static_assert(Type == Detail::Arg::integer);
540 return std::make_tuple(arg);
541 } else {
542 static_assert(Detail::always_false<Arg>, "unsupported argument type");
543 }
544 }
545
547 template <size_t Type, size_t... Is, class... Args>
548 [[nodiscard]] static auto create_(Library const &lib, [[maybe_unused]] std::index_sequence<Is...> seq,
549 Args const &...args) -> clingo_ast_t * {
550 constexpr auto const &cons = Detail::cons.at(Type);
551 clingo_ast_t *ast = nullptr;
552 Detail::handle_error(
553 std::apply(clingo_ast_construct,
554 std::tuple_cat(std::make_tuple(c_cast(lib), static_cast<clingo_ast_type_t>(Type), &ast),
555 map_<cons[Is].type>(convert_(args))...)));
556 return ast;
557 }
558
560 template <size_t Type, size_t I> [[nodiscard]] auto get_() const {
561 constexpr auto const &cons = Detail::cons.at(Type);
562 constexpr auto attr = static_cast<Attribute>(cons[I].attr);
563 if constexpr (cons[I].type == Detail::Arg::integer) {
564 return number(attr);
565 } else if constexpr (cons[I].type == Detail::Arg::location) {
566 return location(attr);
567 } else if constexpr (cons[I].type == Detail::Arg::string) {
568 return string(attr);
569 } else if constexpr (cons[I].type == Detail::Arg::string_array) {
570 return strings(attr);
571 } else if constexpr (cons[I].type == Detail::Arg::symbol) {
572 return symbol(attr);
573 } else if constexpr (cons[I].type == Detail::Arg::symbol_array) {
574 return symbols(attr);
575 } else if constexpr (cons[I].type == Detail::Arg::node) {
576 return node(attr);
577 } else if constexpr (cons[I].type == Detail::Arg::optional_node) {
578 return optional_node(attr);
579 } else if constexpr (cons[I].type == Detail::Arg::node_array) {
580 return nodes(attr);
581 }
582 }
583
585 template <size_t Type, size_t I, typename F> [[nodiscard]] auto update_child_(F const &fun) const {
586 constexpr auto const &cons = Detail::cons.at(Type);
587 constexpr auto attr = static_cast<Attribute>(cons[I].attr);
588 if constexpr (Detail::invokable<F, attr>) {
589 return fun.template operator()<attr>();
590 } else {
591 return get_<Type, I>();
592 }
593 }
594
596 template <size_t Type, typename F, size_t... Is>
597 [[nodiscard]] auto update_(Library const &lib, F const &fun, std::index_sequence<Is...> seq) const
598 -> clingo_ast_t * {
599 return create_<Type>(lib, seq, update_child_<Type, Is>(fun)...);
600 }
601
603 template <size_t... Type>
604 [[nodiscard]] auto dispatch_(Library const &lib, size_t type, Transformer const &fun,
605 [[maybe_unused]] std::index_sequence<Type...> seq) const -> std::optional<Node> {
606 std::optional<Node> ret;
607 std::ignore =
608 (((type == Type)
609 ? (ret = apply_<Type>(lib, fun, std::make_index_sequence<Detail::cons.at(Type).size()>{}), true)
610 : false) ||
611 ...);
612 return ret;
613 }
614
616 template <typename Arg> [[nodiscard]] static auto has_value_(std::optional<Arg> const &arg) {
617 return arg.has_value();
618 }
620 [[nodiscard]] static auto has_value_([[maybe_unused]] std::nullopt_t null) { return false; }
621
623 template <size_t Type, size_t I, typename Arg> [[nodiscard]] auto get_value_(std::optional<Arg> arg) const {
624 return arg ? *std::move(arg) : get_<Type, I>();
625 }
626
628 template <size_t Type, size_t I> [[nodiscard]] auto get_value_([[maybe_unused]] std::nullopt_t null) const {
629 return get_<Type, I>();
630 }
631
633 template <size_t Type, size_t I> [[nodiscard]] auto transform_child_(Transformer const &fun) const {
634 constexpr auto const &cons = Detail::cons.at(Type);
635 constexpr auto attr = static_cast<Attribute>(cons[I].attr);
636 if constexpr (cons[I].type == Detail::Arg::node) {
637 return transform(fun, node(attr));
638 } else if constexpr (cons[I].type == Detail::Arg::optional_node) {
639 return transform(fun, optional_node(attr));
640 } else if constexpr (cons[I].type == Detail::Arg::node_array) {
641 return transform(fun, nodes(attr));
642 } else {
643 return std::nullopt;
644 }
645 }
646
648 template <size_t Type, size_t... Is>
649 [[nodiscard]] auto apply_(Library const &lib, Transformer const &fun, std::index_sequence<Is...> seq) const
650 -> std::optional<Node> {
651 return transform_<Type, Is...>(lib, seq, transform_child_<Type, Is>(fun)...);
652 }
653
655 template <size_t Type, size_t... Is, typename... Args>
656 [[nodiscard]] auto transform_(Library const &lib, std::index_sequence<Is...> seq, Args &&...args) const
657 -> std::optional<Node> {
658 if ((has_value_(args) || ...)) {
659 return Node{create_<Type>(lib, seq, get_value_<Type, Is>(std::forward<Args>(args))...)};
660 }
661 return std::nullopt;
662 }
663
664 using Traits = Detail::value_handle_traits<clingo_ast_copy, clingo_ast_free>;
665 Detail::value_handle<Traits> ast_;
666};
667
668inline void visit(Visitor const &fun, Node const &node) {
669 fun(node);
670}
671
672inline void visit(Visitor const &fun, std::optional<Node> const &node) {
673 if (node) {
674 fun(*node);
675 }
676}
677
678inline void visit(Visitor const &fun, std::span<Node const> nodes) {
679 for (auto const &node : nodes) {
680 fun(node);
681 }
682}
683
684inline auto transform(Transformer const &fun, Node const &node) -> std::optional<Node> {
685 return fun(node);
686}
687
688inline auto transform(Transformer const &fun, std::optional<Node> const &node) -> std::optional<std::optional<Node>> {
689 auto res = std::optional<std::optional<Node>>();
690 if (node) {
691 if (auto trans = fun(*node)) {
692 res.emplace(std::move(trans));
693 }
694 }
695 return res;
696}
697
698inline auto transform(Transformer const &fun, std::vector<Node> nodes) -> std::optional<std::vector<Node>> {
699 bool changed = false;
700 for (auto &node : nodes) {
701 if (auto trans = fun(node)) {
702 changed = true;
703 node = *std::move(trans);
704 }
705 }
706 return changed ? std::make_optional(std::move(nodes)) : std::nullopt;
707}
708
712 term = clingo_ast_parse_type_term,
714 theory_term = clingo_ast_parse_type_theory_term,
716 literal = clingo_ast_parse_type_literal,
718 body_literal = clingo_ast_parse_type_body_literal,
720 head_literal = clingo_ast_parse_type_head_literal,
722 statement = clingo_ast_parse_type_statement,
723};
724
734
737 public:
741 explicit RewriteContext(Library const &lib) : ctx_{Detail::call<clingo_ast_rewrite_context_create>(c_cast(lib))} {}
742
744 friend auto c_cast(RewriteContext const &x) -> clingo_ast_rewrite_context_t * { return x.ctx_.get(); }
745
752
757 return static_cast<ProjectionMode>(clingo_ast_rewrite_context_get_project_mode(ctx_.get()));
758 }
759
767
771 auto project_anonymous() -> bool { return clingo_ast_rewrite_context_get_project_mode(ctx_.get()) != 0; }
772
779 void add_param(std::string_view name) {
780 Detail::handle_error(clingo_ast_rewrite_context_add_param(ctx_.get(), name.data(), name.size()));
781 }
782
785
789 void add_theory(Node const &stm) {
790 Detail::handle_error(clingo_ast_rewrite_context_add_theory(ctx_.get(), c_cast(stm)));
791 }
792
793 private:
794 Detail::unique_handle<clingo_ast_rewrite_context_t, clingo_ast_rewrite_context_free> ctx_;
795};
796
804inline auto rewrite(RewriteContext &ctx, Node const &stm) -> std::vector<Node> {
805 auto arr = Detail::Array{};
806 Detail::handle_error(clingo_ast_rewrite(c_cast(ctx), c_cast(stm), &arr.value, &arr.size));
807 return Detail::transform(std::span{arr.value, arr.size},
808 [](auto *&ast) { return Node{std::exchange(ast, nullptr)}; });
809}
810
812class Program {
813 public:
817 Program(Library const &lib) : prg_{Detail::call<clingo_program_new>(c_cast(lib))} {}
818
822 void add(Node const &stm) const { Detail::handle_error(clingo_program_add(prg_.get(), c_cast(stm))); }
823
828 friend auto c_cast(Program const &x) -> clingo_program_t * { return x.prg_.get(); }
829
830 private:
831 Detail::unique_handle<clingo_program_t, clingo_program_free> prg_;
832};
833
840inline auto parse(Library const &lib, std::string_view string, ParseType type = ParseType::statement) -> Node {
841 return Node{Detail::call<clingo_ast_parse_expression>(c_cast(lib), static_cast<clingo_ast_parse_type_t>(type),
842 string.data(), string.size())};
843}
844
851template <class Callback>
852// NOLINTNEXTLINE
853inline void parse(Library const &lib, std::string_view program, Callback &&callback,
854 Clingo::Control const *control = nullptr) {
856 c_cast(lib), program.data(), program.size(), control != nullptr ? c_cast(*control) : nullptr,
857 [](clingo_ast_t *ast, void *data) {
858 auto &callback = *static_cast<Callback *>(data);
859 CLINGO_TRY {
860 callback(Node{ast, true});
861 }
862 CLINGO_CATCH;
863 },
864 &callback);
865}
866
873template <class Callback>
874// NOLINTNEXTLINE
875inline void parse(Library const &lib, std::span<std::string_view const> files, Callback &&callback,
876 Clingo::Control const *control = nullptr) {
877 auto cfiles = Detail::transform(files, [](auto const &x) { return clingo_string_t{x.data(), x.size()}; });
879 c_cast(lib), cfiles.data(), cfiles.size(), control != nullptr ? c_cast(*control) : nullptr,
880 [](clingo_ast_t *ast, void *data) {
881 CLINGO_TRY {
882 auto &callback = *static_cast<Callback *>(data);
883 std::invoke(callback, Node{ast, true});
884 }
885 CLINGO_CATCH;
886 },
887 &callback);
888}
889
896template <class Callback>
897inline void parse(Library const &lib, std::initializer_list<std::string_view> files, Callback &&callback,
898 Clingo::Control const *control = nullptr) {
899 parse(lib, std::span{files.begin(), files.end()}, std::forward<Callback>(callback), control);
900}
902
903} // namespace Clingo::AST
904
905namespace std {
906
908template <> struct hash<Clingo::AST::Node> {
910 auto operator()(Clingo::AST::Node const &x) const noexcept -> size_t { return x.hash(); }
911};
912
913} // namespace std
Node capturing expressions in logic programs.
Definition ast.hh:276
auto symbol(Attribute attribute) const -> Symbol
Get the symbolic value of the given attribute.
Definition ast.hh:372
auto type() const -> NodeType
Get the type of the node.
Definition ast.hh:355
auto strings(Attribute attribute) const -> std::vector< std::string_view >
Get the string values of the given attribute.
Definition ast.hh:413
auto to_string() const -> std::string
Get a string representation of the node.
Definition ast.hh:461
friend auto operator<=>(Node const &a, Node const &b) noexcept -> std::strong_ordering
Compare two nodes.
Definition ast.hh:489
friend auto operator==(Node const &a, Node const &b) noexcept -> bool
Equality compare two nodes.
Definition ast.hh:480
auto location(Attribute attribute) const -> Location
Get the location value of the given attribute.
Definition ast.hh:394
auto update(Library const &lib, Updater const &fun) const -> Node
Visit a node of the given type.
Definition ast.hh:318
auto node(Attribute attribute) const -> Node
Get the node value of the given attribute.
Definition ast.hh:425
void accept(Visitor const &fun) const
Visit the direct children of the node with the given visitor.
Definition ast.hh:331
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:348
Node(clingo_ast_t *ast, bool copy=false)
Construct a node form its C representation.
Definition ast.hh:287
friend auto c_cast(Node const &x) -> clingo_ast_t *
Cast the node to its underlying C representation.
Definition ast.hh:290
auto string(Attribute attribute) const -> std::string_view
Get the string value of the given attribute.
Definition ast.hh:403
static auto create(Library const &lib, Args const &...args) -> Node
Construct a node of the given type.
Definition ast.hh:299
auto optional_node(Attribute attribute) const -> std::optional< Node >
Get the optional node value of the given attribute.
Definition ast.hh:438
auto number(Attribute attribute) const -> int
Get the numeric value of the given attribute.
Definition ast.hh:363
auto hash() const noexcept -> size_t
Get a hash for the node.
Definition ast.hh:473
auto symbols(Attribute attribute) const -> SymbolVector
Get the symbolic values of the given attribute.
Definition ast.hh:382
auto nodes(Attribute attribute) const -> std::vector< Node >
Get the node values of the given attribute.
Definition ast.hh:448
A program to add statements to.
Definition ast.hh:812
void add(Node const &stm) const
Add a statemente node to the program.
Definition ast.hh:822
Program(Library const &lib)
Construct an empty program.
Definition ast.hh:817
friend auto c_cast(Program const &x) -> clingo_program_t *
Convert the program to its underlying C representation.
Definition ast.hh:828
A context object for rewriting.
Definition ast.hh:736
auto project_mode() -> ProjectionMode
Get the projection mode.
Definition ast.hh:756
void clear_params()
Clear previously protected parameters.
Definition ast.hh:784
void add_theory(Node const &stm)
Add a theory node that is used to rewrite theory atoms in statements.
Definition ast.hh:789
RewriteContext(Library const &lib)
Construct the context.
Definition ast.hh:741
friend auto c_cast(RewriteContext const &x) -> clingo_ast_rewrite_context_t *
Convert the context to its underlying C object.
Definition ast.hh:744
void project_mode(ProjectionMode value)
Set the projection mode.
Definition ast.hh:749
auto project_anonymous() -> bool
Check whether projection in negative literals is enabled.
Definition ast.hh:771
void add_param(std::string_view name)
Protect a parameter from simplification.
Definition ast.hh:779
void project_anonymous(bool value)
Enable projection of anonymous variables in negated literals.
Definition ast.hh:766
The main control class for grounding and solving logic programs.
Definition control.hh:228
The main library class for managing global information and logging.
Definition core.hh:473
Class representing a range in a file.
Definition core.hh:658
A string builder for constructing strings.
Definition core.hh:526
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:160
struct clingo_program clingo_program_t
Object to store.
Definition ast.h:496
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:109
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:157
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:190
struct clingo_ast_rewrite_context clingo_ast_rewrite_context_t
Context object to rewrite statements.
Definition ast.h:409
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:406
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:401
@ clingo_projection_mode_pure
Project pure variables.
Definition ast.h:403
@ clingo_projection_mode_anonymous
Only project anonymous variables.
Definition ast.h:402
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:684
ProjectionMode
The available projection modes.
Definition ast.hh:726
std::function< std::optional< Node >(Node const &)> Transformer
Function to transform ast nodes.
Definition ast.hh:252
std::function< void(Node const &)> Visitor
Function to visit ast nodes.
Definition ast.hh:229
ParseType
Enumeration of expression types that can be parsed.
Definition ast.hh:710
void visit(Visitor const &fun, Node const &node)
Visit the given node with the visitor.
Definition ast.hh:668
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:720
TheoryAtomType
Enumeration of theory atom types.
Definition statement.hh:117
IncludeType
Enumeration of include types.
Definition statement.hh:655
OptimizeType
Enumeration of optimization statement types.
Definition statement.hh:225
CommentType
Enumeration of comment types.
Definition statement.hh:793
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