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 projection = clingo_ast_type_projection,
151 term_variable = clingo_ast_type_term_variable,
152 term_symbolic = clingo_ast_type_term_symbolic,
153 term_absolute = clingo_ast_type_term_absolute,
154 term_unary_operation = clingo_ast_type_term_unary_operation,
155 term_binary_operation = clingo_ast_type_term_binary_operation,
156 term_tuple = clingo_ast_type_term_tuple,
157 term_function = clingo_ast_type_term_function,
158 argument_tuple = clingo_ast_type_argument_tuple,
159 // theory terms
160 unparsed_element = clingo_ast_type_unparsed_element,
161 theory_term_variable = clingo_ast_type_theory_term_variable,
162 theory_term_symbolic = clingo_ast_type_theory_term_symbolic,
163 theory_term_tuple = clingo_ast_type_theory_term_tuple,
164 theory_term_function = clingo_ast_type_theory_term_function,
165 theory_term_unparsed = clingo_ast_type_theory_term_unparsed,
166 // literals
167 left_guard = clingo_ast_type_left_guard,
168 right_guard = clingo_ast_type_right_guard,
169 literal_boolean = clingo_ast_type_literal_boolean,
170 literal_comparison = clingo_ast_type_literal_comparison,
171 literal_symbolic = clingo_ast_type_literal_symbolic,
172 // set aggregates and theory atoms
173 set_aggregate_element = clingo_ast_type_set_aggregate_element,
174 theory_atom_element = clingo_ast_type_theory_atom_element,
175 theory_right_guard = clingo_ast_type_theory_right_guard,
176 // body literals
177 body_simple_literal = clingo_ast_type_body_simple_literal,
178 body_aggregate_element = clingo_ast_type_body_aggregate_element,
179 body_aggregate = clingo_ast_type_body_aggregate,
180 body_set_aggregate = clingo_ast_type_body_set_aggregate,
181 body_theory_atom = clingo_ast_type_body_theory_atom,
182 body_conditional_literal = clingo_ast_type_body_conditional_literal,
183 // head literals
184 head_simple_literal = clingo_ast_type_head_simple_literal,
185 head_aggregate_element = clingo_ast_type_head_aggregate_element,
186 head_aggregate = clingo_ast_type_head_aggregate,
187 head_set_aggregate = clingo_ast_type_head_set_aggregate,
188 head_theory_atom = clingo_ast_type_head_theory_atom,
189 head_conditional_literal = clingo_ast_type_head_conditional_literal,
190 head_disjunction = clingo_ast_type_head_disjunction,
191 // theory definition
192 theory_operator_definition = clingo_ast_type_theory_operator_definition,
193 theory_term_definition = clingo_ast_type_theory_term_definition,
194 theory_guard_definition = clingo_ast_type_theory_guard_definition,
195 theory_atom_definition = clingo_ast_type_theory_atom_definition,
196 // elements
197 optimize_tuple = clingo_ast_type_optimize_tuple,
198 optimize_element = clingo_ast_type_optimize_element,
199 edge = clingo_ast_type_edge,
200 program_part = clingo_ast_type_program_part,
201 // statements
202 statement_rule = clingo_ast_type_statement_rule,
203 statement_theory = clingo_ast_type_statement_theory,
204 statement_optimize = clingo_ast_type_statement_optimize,
205 statement_weak_constraint = clingo_ast_type_statement_weak_constraint,
206 statement_show = clingo_ast_type_statement_show,
207 statement_show_nothing = clingo_ast_type_statement_show_nothing,
208 statement_show_signature = clingo_ast_type_statement_show_signature,
209 statement_project = clingo_ast_type_statement_project,
210 statement_project_signature = clingo_ast_type_statement_project_signature,
211 statement_defined = clingo_ast_type_statement_defined,
212 statement_external = clingo_ast_type_statement_external,
213 statement_edge = clingo_ast_type_statement_edge,
214 statement_heuristic = clingo_ast_type_statement_heuristic,
215 statement_script = clingo_ast_type_statement_script,
216 statement_program = clingo_ast_type_statement_program,
217 statement_include = clingo_ast_type_statement_include,
218 statement_const = clingo_ast_type_statement_const,
219 statement_parts = clingo_ast_type_statement_parts,
220 statement_comment = clingo_ast_type_statement_comment
221};
222
223class Node;
224
226using Visitor = std::function<void(Node const &)>;
233void visit(Visitor const &fun, Node const &node);
238void visit(Visitor const &fun, std::optional<Node> const &node);
243void visit(Visitor const &fun, std::span<Node const> nodes);
244
249using Transformer = std::function<std::optional<Node>(Node const &)>;
256auto transform(Transformer const &fun, Node const &node) -> std::optional<Node>;
261auto transform(Transformer const &fun, std::optional<Node> const &node) -> std::optional<std::optional<Node>>;
266auto transform(Transformer const &fun, std::vector<Node> nodes) -> std::optional<std::vector<Node>>;
267
273class Node {
274 public:
284 explicit Node(clingo_ast_t *ast, bool copy = false) : ast_{ast, copy} {}
285
287 [[nodiscard]] friend auto c_cast(Node const &x) -> clingo_ast_t * { return x.ast_.get(); }
288
295 template <NodeType Type, class... Args>
296 [[nodiscard]] static auto create(Library const &lib, Args const &...args) -> Node {
297 constexpr auto type = static_cast<size_t>(Type);
298 static_assert(type < Detail::cons.size(), "invalid type");
299 static_assert(sizeof...(Args) == Detail::cons.at(type).size(), "wrong number of arguments");
300 return Node{create_<type>(lib, std::make_index_sequence<Detail::cons.at(type).size()>(), args...)};
301 }
302
314 template <NodeType Type, class Updater>
315 [[nodiscard]] auto update(Library const &lib, Updater const &fun) const -> Node {
316 assert(Type == type());
317 constexpr auto type = static_cast<size_t>(Type);
318 static_assert(type < Detail::cons.size(), "invalid type");
319 return Node{update_<type>(lib, fun, std::make_index_sequence<Detail::cons.at(type).size()>())};
320 }
321
328 void accept(Visitor const &fun) const {
329 auto t = type();
330 for (auto const [attr, type] : Detail::cons.at(static_cast<size_t>(t))) {
331 if (type == Detail::Arg::node) {
332 visit(fun, node(static_cast<Attribute>(attr)));
333 } else if (type == Detail::Arg::optional_node) {
334 visit(fun, optional_node(static_cast<Attribute>(attr)));
335 } else if (type == Detail::Arg::node_array) {
336 visit(fun, nodes(static_cast<Attribute>(attr)));
337 }
338 }
339 }
340
345 [[nodiscard]] auto accept(Library const &lib, Transformer const &fun) const -> std::optional<Node> {
346 return dispatch_(lib, static_cast<size_t>(type()), fun, std::make_index_sequence<Detail::cons.size()>());
347 }
348
352 [[nodiscard]] auto type() const -> NodeType {
353 return static_cast<NodeType>(Detail::call<clingo_ast_get_type>(ast_.get()));
354 }
355
360 [[nodiscard]] auto number(Attribute attribute) const -> int {
361 return Detail::call<clingo_ast_attribute_get_number>(ast_.get(),
362 static_cast<clingo_ast_attribute_t>(attribute));
363 }
364
369 [[nodiscard]] auto symbol(Attribute attribute) const -> Symbol {
370 return Symbol{
371 Detail::call<clingo_ast_attribute_get_symbol>(ast_.get(), static_cast<clingo_ast_attribute_t>(attribute)),
372 true};
373 }
374
379 [[nodiscard]] auto symbols(Attribute attribute) const -> SymbolVector {
380 clingo_symbol_t const *value = nullptr;
381 size_t size = 0;
382 Detail::handle_error(clingo_ast_attribute_get_symbol_array(
383 ast_.get(), static_cast<clingo_ast_attribute_t>(attribute), &value, &size));
384 return Detail::transform(std::span{value, size}, [](auto x) { return Symbol{x, true}; });
385 }
386
391 [[nodiscard]] auto location(Attribute attribute) const -> Location {
392 return Location{Detail::call<clingo_ast_attribute_get_location>(
393 ast_.get(), static_cast<clingo_ast_attribute_t>(attribute))};
394 }
395
400 [[nodiscard]] auto string(Attribute attribute) const -> std::string_view {
401 auto [data, size] =
402 Detail::call<clingo_ast_attribute_get_string>(ast_.get(), static_cast<clingo_ast_attribute_t>(attribute));
403 return {data, size};
404 }
405
410 [[nodiscard]] auto strings(Attribute attribute) const -> std::vector<std::string_view> {
411 clingo_string_t const *value = nullptr;
412 size_t size = 0;
413 Detail::handle_error(clingo_ast_attribute_get_string_array(
414 ast_.get(), static_cast<clingo_ast_attribute_t>(attribute), &value, &size));
415 return Detail::transform(std::span{value, size}, [](auto x) { return std::string_view{x.data, x.size}; });
416 }
417
422 [[nodiscard]] auto node(Attribute attribute) const -> Node {
423 clingo_ast_t *value =
424 Detail::call<clingo_ast_attribute_get_ast>(ast_.get(), static_cast<clingo_ast_attribute_t>(attribute));
425 if (value == nullptr) {
426 throw std::runtime_error("invalid attribute");
427 }
428 return Node{value};
429 }
430
435 [[nodiscard]] auto optional_node(Attribute attribute) const -> std::optional<Node> {
436 clingo_ast_t *value =
437 Detail::call<clingo_ast_attribute_get_ast>(ast_.get(), static_cast<clingo_ast_attribute_t>(attribute));
438 return value != nullptr ? std::make_optional<Node>(value) : std::nullopt;
439 }
440
445 [[nodiscard]] auto nodes(Attribute attribute) const -> std::vector<Node> {
446 auto arr = Detail::Array{};
447 Detail::handle_error(clingo_ast_attribute_get_ast_array(
448 ast_.get(), static_cast<clingo_ast_attribute_t>(attribute), &arr.value, &arr.size));
449 return Detail::transform(std::span{arr.value, arr.size},
450 [](auto *&node) { return Node{std::exchange(node, nullptr)}; });
451 }
452
458 [[nodiscard]] auto to_string() const -> std::string {
459 auto bld = StringBuilder{};
460 Detail::handle_error(clingo_ast_to_string(ast_.get(), c_cast(bld)));
461 return std::string{bld.str()};
462 }
463
470 [[nodiscard]] auto hash() const noexcept -> size_t { return clingo_ast_hash(ast_.get()); }
471
477 friend auto operator==(Node const &a, Node const &b) noexcept -> bool {
478 return clingo_ast_equal(a.ast_.get(), b.ast_.get());
479 }
480
486 friend auto operator<=>(Node const &a, Node const &b) noexcept -> std::strong_ordering {
487 return clingo_ast_compare(a.ast_.get(), b.ast_.get()) <=> 0;
488 }
489
490 private:
491 // Convert strings and string arrays into mappable types.
492 template <class Arg> [[nodiscard]] static auto convert_(Arg const &arg) -> decltype(auto) {
493 if constexpr (Detail::is_contiguous_range_over<Arg, char> || std::is_same_v<Arg, char const *>) {
494 return std::string_view{arg};
495 } else if constexpr (Detail::is_range_over<Arg, char const *>) {
496 return Detail::transform(arg, [](auto str) { return clingo_string_t{str, std::strlen(str)}; });
497 } else if constexpr (Detail::is_range_over<Arg, std::string_view>) {
498 return Detail::transform(arg, [](auto str) { return clingo_string_t{str.data(), str.size()}; });
499 } else if constexpr (std::is_same_v<Arg, bool>) {
500 return static_cast<int>(arg);
501 } else {
502 return arg;
503 }
504 }
505
506 // Map arguments to their C representation.
507 template <Detail::Arg::Type Type, class Arg> [[nodiscard]] static auto map_(Arg const &arg) {
508 if constexpr (Detail::is_contiguous_range_over<Arg, Symbol>) {
509 static_assert(Type == Detail::Arg::symbol_array);
510 return std::make_tuple(std::ranges::data(arg), std::ranges::size(arg));
511 } else if constexpr (Detail::is_contiguous_range_over<Arg, Node>) {
512 static_assert(Type == Detail::Arg::node_array);
513 return std::make_tuple(std::ranges::data(arg), std::ranges::size(arg));
514 } else if constexpr (std::is_same_v<Arg, std::string_view>) {
515 static_assert(Type == Detail::Arg::string);
516 return std::make_tuple(std::ranges::data(arg), std::ranges::size(arg));
517 } else if constexpr (Detail::is_range_over<Arg, clingo_string_t>) {
518 static_assert(Type == Detail::Arg::string_array);
519 return std::make_tuple(std::ranges::data(arg), std::ranges::size(arg));
520 } else if constexpr (std::is_same_v<Arg, Node>) {
521 static_assert(Type == Detail::Arg::node || Type == Detail::Arg::optional_node);
522 return std::make_tuple(c_cast(arg));
523 } else if constexpr (std::is_same_v<Arg, std::nullopt_t>) {
524 static_assert(Type == Detail::Arg::optional_node);
525 return std::make_tuple(nullptr);
526 } else if constexpr (std::is_same_v<Arg, std::optional<Node>>) {
527 static_assert(Type == Detail::Arg::optional_node);
528 return std::make_tuple(arg ? c_cast(*arg) : nullptr);
529 } else if constexpr (std::is_same_v<Arg, Symbol>) {
530 static_assert(Type == Detail::Arg::symbol);
531 return std::make_tuple(c_cast(arg));
532 } else if constexpr (std::is_same_v<Arg, Location>) {
533 static_assert(Type == Detail::Arg::location);
534 return std::make_tuple(c_cast(arg));
535 } else if constexpr (std::is_same_v<Arg, int>) {
536 static_assert(Type == Detail::Arg::integer);
537 return std::make_tuple(arg);
538 } else {
539 static_assert(Detail::always_false<Arg>, "unsupported argument type");
540 }
541 }
542
544 template <size_t Type, size_t... Is, class... Args>
545 [[nodiscard]] static auto create_(Library const &lib, [[maybe_unused]] std::index_sequence<Is...> seq,
546 Args const &...args) -> clingo_ast_t * {
547 constexpr auto const &cons = Detail::cons.at(Type);
548 clingo_ast_t *ast = nullptr;
549 Detail::handle_error(
550 std::apply(clingo_ast_construct,
551 std::tuple_cat(std::make_tuple(c_cast(lib), static_cast<clingo_ast_type_t>(Type), &ast),
552 map_<cons[Is].type>(convert_(args))...)));
553 return ast;
554 }
555
557 template <size_t Type, size_t I> [[nodiscard]] auto get_() const {
558 constexpr auto const &cons = Detail::cons.at(Type);
559 constexpr auto attr = static_cast<Attribute>(cons[I].attr);
560 if constexpr (cons[I].type == Detail::Arg::integer) {
561 return number(attr);
562 } else if constexpr (cons[I].type == Detail::Arg::location) {
563 return location(attr);
564 } else if constexpr (cons[I].type == Detail::Arg::string) {
565 return string(attr);
566 } else if constexpr (cons[I].type == Detail::Arg::string_array) {
567 return strings(attr);
568 } else if constexpr (cons[I].type == Detail::Arg::symbol) {
569 return symbol(attr);
570 } else if constexpr (cons[I].type == Detail::Arg::symbol_array) {
571 return symbols(attr);
572 } else if constexpr (cons[I].type == Detail::Arg::node) {
573 return node(attr);
574 } else if constexpr (cons[I].type == Detail::Arg::optional_node) {
575 return optional_node(attr);
576 } else if constexpr (cons[I].type == Detail::Arg::node_array) {
577 return nodes(attr);
578 }
579 }
580
582 template <size_t Type, size_t I, typename F> [[nodiscard]] auto update_child_(F const &fun) const {
583 constexpr auto const &cons = Detail::cons.at(Type);
584 constexpr auto attr = static_cast<Attribute>(cons[I].attr);
585 if constexpr (Detail::invokable<F, attr>) {
586 return fun.template operator()<attr>();
587 } else {
588 return get_<Type, I>();
589 }
590 }
591
593 template <size_t Type, typename F, size_t... Is>
594 [[nodiscard]] auto update_(Library const &lib, F const &fun, std::index_sequence<Is...> seq) const
595 -> clingo_ast_t * {
596 return create_<Type>(lib, seq, update_child_<Type, Is>(fun)...);
597 }
598
600 template <size_t... Type>
601 [[nodiscard]] auto dispatch_(Library const &lib, size_t type, Transformer const &fun,
602 [[maybe_unused]] std::index_sequence<Type...> seq) const -> std::optional<Node> {
603 std::optional<Node> ret;
604 std::ignore =
605 (((type == Type)
606 ? (ret = apply_<Type>(lib, fun, std::make_index_sequence<Detail::cons.at(Type).size()>{}), true)
607 : false) ||
608 ...);
609 return ret;
610 }
611
613 template <typename Arg> [[nodiscard]] static auto has_value_(std::optional<Arg> const &arg) {
614 return arg.has_value();
615 }
617 [[nodiscard]] static auto has_value_([[maybe_unused]] std::nullopt_t null) { return false; }
618
620 template <size_t Type, size_t I, typename Arg> [[nodiscard]] auto get_value_(std::optional<Arg> arg) const {
621 return arg ? *std::move(arg) : get_<Type, I>();
622 }
623
625 template <size_t Type, size_t I> [[nodiscard]] auto get_value_([[maybe_unused]] std::nullopt_t null) const {
626 return get_<Type, I>();
627 }
628
630 template <size_t Type, size_t I> [[nodiscard]] auto transform_child_(Transformer const &fun) const {
631 constexpr auto const &cons = Detail::cons.at(Type);
632 constexpr auto attr = static_cast<Attribute>(cons[I].attr);
633 if constexpr (cons[I].type == Detail::Arg::node) {
634 return transform(fun, node(attr));
635 } else if constexpr (cons[I].type == Detail::Arg::optional_node) {
636 return transform(fun, optional_node(attr));
637 } else if constexpr (cons[I].type == Detail::Arg::node_array) {
638 return transform(fun, nodes(attr));
639 } else {
640 return std::nullopt;
641 }
642 }
643
645 template <size_t Type, size_t... Is>
646 [[nodiscard]] auto apply_(Library const &lib, Transformer const &fun, std::index_sequence<Is...> seq) const
647 -> std::optional<Node> {
648 return transform_<Type, Is...>(lib, seq, transform_child_<Type, Is>(fun)...);
649 }
650
652 template <size_t Type, size_t... Is, typename... Args>
653 [[nodiscard]] auto transform_(Library const &lib, std::index_sequence<Is...> seq, Args &&...args) const
654 -> std::optional<Node> {
655 if ((has_value_(args) || ...)) {
656 return Node{create_<Type>(lib, seq, get_value_<Type, Is>(std::forward<Args>(args))...)};
657 }
658 return std::nullopt;
659 }
660
661 using Traits = Detail::value_handle_traits<clingo_ast_copy, clingo_ast_free>;
662 Detail::value_handle<Traits> ast_;
663};
664
665inline void visit(Visitor const &fun, Node const &node) {
666 fun(node);
667}
668
669inline void visit(Visitor const &fun, std::optional<Node> const &node) {
670 if (node) {
671 fun(*node);
672 }
673}
674
675inline void visit(Visitor const &fun, std::span<Node const> nodes) {
676 for (auto const &node : nodes) {
677 fun(node);
678 }
679}
680
681inline auto transform(Transformer const &fun, Node const &node) -> std::optional<Node> {
682 return fun(node);
683}
684
685inline auto transform(Transformer const &fun, std::optional<Node> const &node) -> std::optional<std::optional<Node>> {
686 auto res = std::optional<std::optional<Node>>();
687 if (node) {
688 if (auto trans = fun(*node)) {
689 res.emplace(std::move(trans));
690 }
691 }
692 return res;
693}
694
695inline auto transform(Transformer const &fun, std::vector<Node> nodes) -> std::optional<std::vector<Node>> {
696 bool changed = false;
697 for (auto &node : nodes) {
698 if (auto trans = fun(node)) {
699 changed = true;
700 node = *std::move(trans);
701 }
702 }
703 return changed ? std::make_optional(std::move(nodes)) : std::nullopt;
704}
705
709 term = clingo_ast_parse_type_term,
711 theory_term = clingo_ast_parse_type_theory_term,
713 literal = clingo_ast_parse_type_literal,
715 body_literal = clingo_ast_parse_type_body_literal,
717 head_literal = clingo_ast_parse_type_head_literal,
719 statement = clingo_ast_parse_type_statement,
720};
721
731
734 public:
738 explicit RewriteContext(Library const &lib) : ctx_{Detail::call<clingo_ast_rewrite_context_create>(c_cast(lib))} {}
739
741 friend auto c_cast(RewriteContext const &x) -> clingo_ast_rewrite_context_t * { return x.ctx_.get(); }
742
749
754 return static_cast<ProjectionMode>(clingo_ast_rewrite_context_get_project_mode(ctx_.get()));
755 }
756
764
768 auto project_anonymous() -> bool { return clingo_ast_rewrite_context_get_project_mode(ctx_.get()) != 0; }
769
776 void add_param(std::string_view name) {
777 Detail::handle_error(clingo_ast_rewrite_context_add_param(ctx_.get(), name.data(), name.size()));
778 }
779
782
786 void add_theory(Node const &stm) {
787 Detail::handle_error(clingo_ast_rewrite_context_add_theory(ctx_.get(), c_cast(stm)));
788 }
789
790 private:
791 Detail::unique_handle<clingo_ast_rewrite_context_t, clingo_ast_rewrite_context_free> ctx_;
792};
793
801inline auto rewrite(RewriteContext &ctx, Node const &stm) -> std::vector<Node> {
802 auto arr = Detail::Array{};
803 Detail::handle_error(clingo_ast_rewrite(c_cast(ctx), c_cast(stm), &arr.value, &arr.size));
804 return Detail::transform(std::span{arr.value, arr.size},
805 [](auto *&ast) { return Node{std::exchange(ast, nullptr)}; });
806}
807
809class Program {
810 public:
814 Program(Library const &lib) : prg_{Detail::call<clingo_program_new>(c_cast(lib))} {}
815
819 void add(Node const &stm) const { Detail::handle_error(clingo_program_add(prg_.get(), c_cast(stm))); }
820
825 friend auto c_cast(Program const &x) -> clingo_program_t * { return x.prg_.get(); }
826
827 private:
828 Detail::unique_handle<clingo_program_t, clingo_program_free> prg_;
829};
830
837inline auto parse(Library const &lib, std::string_view string, ParseType type = ParseType::statement) -> Node {
838 return Node{Detail::call<clingo_ast_parse_expression>(c_cast(lib), static_cast<clingo_ast_parse_type_t>(type),
839 string.data(), string.size())};
840}
841
848template <class Callback>
849// NOLINTNEXTLINE
850inline void parse(Library const &lib, std::string_view program, Callback &&callback,
851 Clingo::Control const *control = nullptr) {
853 c_cast(lib), program.data(), program.size(), control != nullptr ? c_cast(*control) : nullptr,
854 [](clingo_ast_t *ast, void *data) {
855 auto &callback = *static_cast<Callback *>(data);
856 CLINGO_TRY {
857 callback(Node{ast, true});
858 }
859 CLINGO_CATCH;
860 },
861 &callback);
862}
863
870template <class Callback>
871// NOLINTNEXTLINE
872inline void parse(Library const &lib, std::span<std::string_view const> files, Callback &&callback,
873 Clingo::Control const *control = nullptr) {
874 auto cfiles = Detail::transform(files, [](auto const &x) { return clingo_string_t{x.data(), x.size()}; });
876 c_cast(lib), cfiles.data(), cfiles.size(), control != nullptr ? c_cast(*control) : nullptr,
877 [](clingo_ast_t *ast, void *data) {
878 CLINGO_TRY {
879 auto &callback = *static_cast<Callback *>(data);
880 std::invoke(callback, Node{ast, true});
881 }
882 CLINGO_CATCH;
883 },
884 &callback);
885}
886
893template <class Callback>
894inline void parse(Library const &lib, std::initializer_list<std::string_view> files, Callback &&callback,
895 Clingo::Control const *control = nullptr) {
896 parse(lib, std::span{files.begin(), files.end()}, std::forward<Callback>(callback), control);
897}
899
900} // namespace Clingo::AST
901
902namespace std {
903
904template <> struct hash<Clingo::AST::Node> {
905 auto operator()(Clingo::AST::Node const &x) const noexcept -> size_t { return x.hash(); }
906};
907
908} // namespace std
Node capturing expressions in logic programs.
Definition ast.hh:273
auto symbol(Attribute attribute) const -> Symbol
Get the symbolic value of the given attribute.
Definition ast.hh:369
auto type() const -> NodeType
Get the type of the node.
Definition ast.hh:352
auto strings(Attribute attribute) const -> std::vector< std::string_view >
Get the string values of the given attribute.
Definition ast.hh:410
auto to_string() const -> std::string
Get a string representation of the node.
Definition ast.hh:458
friend auto operator<=>(Node const &a, Node const &b) noexcept -> std::strong_ordering
Compare two nodes.
Definition ast.hh:486
friend auto operator==(Node const &a, Node const &b) noexcept -> bool
Equality compare two nodes.
Definition ast.hh:477
auto location(Attribute attribute) const -> Location
Get the location value of the given attribute.
Definition ast.hh:391
auto update(Library const &lib, Updater const &fun) const -> Node
Visit a node of the given type.
Definition ast.hh:315
auto node(Attribute attribute) const -> Node
Get the node value of the given attribute.
Definition ast.hh:422
void accept(Visitor const &fun) const
Visit the direct children of the node with the given visitor.
Definition ast.hh:328
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:345
Node(clingo_ast_t *ast, bool copy=false)
Construct a node form its C representation.
Definition ast.hh:284
friend auto c_cast(Node const &x) -> clingo_ast_t *
Cast the node to its underlying C representation.
Definition ast.hh:287
auto string(Attribute attribute) const -> std::string_view
Get the string value of the given attribute.
Definition ast.hh:400
static auto create(Library const &lib, Args const &...args) -> Node
Construct a node of the given type.
Definition ast.hh:296
auto optional_node(Attribute attribute) const -> std::optional< Node >
Get the optional node value of the given attribute.
Definition ast.hh:435
auto number(Attribute attribute) const -> int
Get the numeric value of the given attribute.
Definition ast.hh:360
auto hash() const noexcept -> size_t
Get a hash for the node.
Definition ast.hh:470
auto symbols(Attribute attribute) const -> SymbolVector
Get the symbolic values of the given attribute.
Definition ast.hh:379
auto nodes(Attribute attribute) const -> std::vector< Node >
Get the node values of the given attribute.
Definition ast.hh:445
A program to add statements to.
Definition ast.hh:809
void add(Node const &stm) const
Add a statemente node to the program.
Definition ast.hh:819
Program(Library const &lib)
Construct an empty program.
Definition ast.hh:814
friend auto c_cast(Program const &x) -> clingo_program_t *
Convert the program to its underlying C representation.
Definition ast.hh:825
A context object for rewriting.
Definition ast.hh:733
auto project_mode() -> ProjectionMode
Get the projection mode.
Definition ast.hh:753
void clear_params()
Clear previously protected parameters.
Definition ast.hh:781
void add_theory(Node const &stm)
Add a theory node that is used to rewrite theory atoms in statements.
Definition ast.hh:786
RewriteContext(Library const &lib)
Construct the context.
Definition ast.hh:738
friend auto c_cast(RewriteContext const &x) -> clingo_ast_rewrite_context_t *
Convert the context to its underlying C object.
Definition ast.hh:741
void project_mode(ProjectionMode value)
Set the projection mode.
Definition ast.hh:746
auto project_anonymous() -> bool
Check whether projection in negative literals is enabled.
Definition ast.hh:768
void add_param(std::string_view name)
Protect a parameter from simplification.
Definition ast.hh:776
void project_anonymous(bool value)
Enable projection of anonymous variables in negated literals.
Definition ast.hh:763
The main control class for grounding and solving logic programs.
Definition control.hh:179
The main library class for managing global information and logging.
Definition core.hh:471
Class representing a range in a file.
Definition core.hh:656
A string builder for constructing strings.
Definition core.hh:524
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:163
struct clingo_program clingo_program_t
Object to store.
Definition ast.h:499
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:112
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:160
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:193
struct clingo_ast_rewrite_context clingo_ast_rewrite_context_t
Context object to rewrite statements.
Definition ast.h:412
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:409
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:404
@ clingo_projection_mode_pure
Project pure variables.
Definition ast.h:406
@ clingo_projection_mode_anonymous
Only project anonymous variables.
Definition ast.h:405
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:681
ProjectionMode
The available projection modes.
Definition ast.hh:723
std::function< std::optional< Node >(Node const &)> Transformer
Function to transform ast nodes.
Definition ast.hh:249
std::function< void(Node const &)> Visitor
Function to visit ast nodes.
Definition ast.hh:226
ParseType
Enumeration of expression types that can be parsed.
Definition ast.hh:707
void visit(Visitor const &fun, Node const &node)
Visit the given node with the visitor.
Definition ast.hh:665
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:258
UnaryOperator
Enumeration of available unary operators.
Definition term.hh:226
Struct to capture strings that are not null-terminated.
Definition core.h:91
char const * data
pointer to the beginning of the string
Definition core.h:92