Clingo
Loading...
Searching...
No Matches
body_aggregate.hh
1#pragma once
2
3#include <clingo/ground/literal.hh>
4#include <clingo/ground/matcher.hh>
5#include <clingo/ground/statement.hh>
6
7#include <clingo/util/small_vector.hh>
8
9#include <memory_resource>
10#include <ostream>
11
12namespace CppClingo::Ground {
13
16
18enum class AtomBdAggrState : uint8_t {
19 unknown = 0,
20 derived = 1,
21 fact = 2,
22};
23
26 public:
31 using Bound = std::variant<std::pair<Number, Number>, std::pair<Symbol, Symbol>>;
32
34 AtomBdAggr(AggregateFunction fun) : bound_{init_(fun)} {}
35
38
44 auto propagate(GuardVec const &guards, Symbol const *vals) -> std::pair<bool, bool>;
45
49 [[nodiscard]] auto derived_idx() const -> size_t;
53 void derived_idx(size_t idx);
54
56 [[nodiscard]] auto state() const -> AtomBdAggrState;
61
63 auto enqueue() -> bool;
67 void dequeue();
68
70 void add_elem(size_t idx);
72 [[nodiscard]] auto elems() const -> std::span<size_t const>;
74 [[nodiscard]] auto todo() -> std::span<size_t const>;
75
77 [[nodiscard]] auto uid() const -> std::optional<size_t>;
78
80 void uid(size_t uid);
81
82 private:
83 static auto init_(AggregateFunction fun) -> Bound;
84
85 std::vector<size_t> elems_;
86 std::variant<std::pair<Number, Number>, std::pair<Symbol, Symbol>> bound_;
87 size_t propagated_ = 0;
88 size_t derived_idx_ = 0;
89 size_t uid_ = invalid_offset;
91 bool enqueued_ = false;
92};
93
95class BaseBdAggr : public BaseImpl<Symbol const *, BaseBdAggr> {
96 public:
100
102 BaseBdAggr(size_t size) : atoms_{0, size, size} {}
103
108 auto is_fact(Symbol const *sym) const -> bool;
112 void add(AtomMap::iterator it);
113
115 [[nodiscard]] auto size() const -> size_t;
116
120 auto index(Symbol const *sym) const -> size_t;
122 auto nth(size_t i) const -> AtomMap::const_iterator;
124 auto nth(size_t i) -> AtomMap::iterator;
125
127 [[nodiscard]] auto atoms() -> AtomMap &;
128
129 private:
130 AtomMap atoms_;
131 Util::index_sequence<size_t> derived_;
132};
133
134// see node in head_aggregate.h
135class StmBdAggrElem;
136
138class StateBdAggr : public State {
139 public:
140 class AtomKey;
145 private:
146 struct priv_tag {};
147
148 public:
150 ElementKey(priv_tag tag, EvalContext const &ctx, AggregateFunction fun, size_t atom_idx, StmBdAggrElem &elem,
151 bool &res);
153 ElementKey(ElementKey const &other) = delete;
155 [[nodiscard]] static auto construct(auto &mbr, EvalContext const &ctx, AggregateFunction fun, size_t atom_idx,
156 StmBdAggrElem &elem) -> bool;
157
159 [[nodiscard]] auto span() const -> SymbolSpan;
161 [[nodiscard]] auto hash() const -> size_t;
163 friend auto operator==(ElementKey const &a, ElementKey const &b) -> bool;
164
165 private:
166 // Note that these two could be combined to save a little bit of memory.
167 size_t n_;
168 size_t atom_idx_;
169 // NOLINTBEGIN
170 CLINGO_IGNORE_ZERO_SIZED_ARRAY_B
171 Symbol syms_[0];
172 CLINGO_IGNORE_ZERO_SIZED_ARRAY_E
173 // NOLINTEND
174 };
175
184 using ElementMap = Util::ordered_map<ElementKey *, Util::small_vector<size_t>>;
185
187 StateBdAggr(std::pmr::monotonic_buffer_resource &mbr, VariableVec global, GuardVec guards, AggregateFunction fun,
188 size_t index, bool domain, bool monotone, bool single_pass_elems)
189 : base_{global.size()}, global_{std::move(global)}, guards_{std::move(guards)}, mbr_{&mbr}, index_{index},
190 fun_{fun}, domain_{domain}, monotone_{monotone}, single_pass_elems_{single_pass_elems} {}
191
193 [[nodiscard]] auto global() const -> VariableVec const &;
195 [[nodiscard]] auto symbols() -> SymbolVec &;
197 [[nodiscard]] auto guards() const -> GuardVec const &;
199 [[nodiscard]] auto fun() const -> AggregateFunction;
206 [[nodiscard]] auto domain() const -> bool;
210 [[nodiscard]] auto monotone() const -> bool;
215 [[nodiscard]] auto single_pass_elems() const -> bool;
217 [[nodiscard]] auto index() const -> size_t;
218
220 auto propagate() -> bool;
221
226 auto insert_atom(EvalContext const &ctx) -> std::optional<std::pair<AtomMap::iterator, bool>>;
227
231 auto insert_atom(Symbol const *tuple) -> AtomMap::iterator;
232
234 void insert_elem(EvalContext const &ctx, AtomMap::iterator it, StmBdAggrElem &elem);
235
237 void print(std::ostream &out, bool print_index);
238
240 [[nodiscard]] auto base() -> BaseBdAggr &;
241
243 void output(Logger &log, SymbolStore &store, OutputStm &out) override;
244
245 private:
247 void enqueue_(AtomMap::iterator it);
248
252 auto atom_index_(AtomMap::iterator it) -> size_t;
253
254 BaseBdAggr base_;
255 ElementMap tuples_;
256 VariableVec global_;
257 SymbolVec symbols_;
258 GuardVec guards_;
259 std::vector<size_t> queue_;
260 std::pmr::monotonic_buffer_resource *mbr_;
261 AtomKey *atom_key_ = nullptr;
262 size_t index_;
264 bool domain_;
265 bool monotone_;
266 bool single_pass_elems_;
267};
268
271 public:
273 using Key = Symbol const *;
274
276 MatchBdAggr(StateBdAggr &state) : state_{&state} {
277 eval_.reserve(state_->global().size() + state_->guards().size());
278 }
279
281 [[nodiscard]] auto vars() const -> VariableSet;
282
284 [[nodiscard]] auto signature(VariableSet const &bound, [[maybe_unused]] VariableSet const &bind) const
285 -> VariableVec;
286
288 [[nodiscard]] auto match(EvalContext const &ctx, Symbol const *sym) const -> bool;
289
291 [[nodiscard]] auto eval(EvalContext const &ctx) const -> std::optional<Symbol const *>;
292
294 friend auto operator<<(std::ostream &out, MatchBdAggr const &m) -> std::ostream &;
295
297 [[nodiscard]] auto state() const -> StateBdAggr &;
298
299 private:
300 std::vector<Symbol> mutable eval_;
301 StateBdAggr *state_;
302};
303
305class LitBdAggr : public Lit, private MatchBdAggr {
306 public:
308 LitBdAggr(StateBdAggr &state, Sign sign) : MatchBdAggr{state}, sign_{sign} {}
309
310 private:
311 void do_vars(VariableSet &vars, VarSelectMode mode) const override;
312
321 [[nodiscard]] auto do_domain() const -> bool override;
322
324 [[nodiscard]] auto do_single_pass() const -> bool override;
325
326 [[nodiscard]] auto do_matcher(std::pmr::monotonic_buffer_resource &mbr, MatcherType type,
327 std::vector<bool> const &bound)
328 -> std::pair<UMatcher, std::optional<size_t>> override;
329
330 [[nodiscard]] auto do_score([[maybe_unused]] std::vector<bool> const &bound) const -> double override;
331
332 void do_print(std::ostream &out) const override;
333
334 auto do_output([[maybe_unused]] EvalContext const &ctx, OutputLit &out) const -> bool override;
335
336 [[nodiscard]] auto do_copy() const -> ULit override;
337
338 [[nodiscard]] auto do_hash() const -> size_t override;
339
340 [[nodiscard]] auto do_equal_to(Lit const &other) const -> bool override;
341
342 [[nodiscard]] auto do_compare_to(Lit const &other) const -> std::weak_ordering override;
343
344 size_t offset_ = invalid_offset;
345 Symbol const *symbol_ = nullptr;
346 Sign sign_;
347};
348
355class StmBdAggrElem : public Stm {
356 public:
362 StmBdAggrElem(StateBdAggr &state, Location loc_weight, UTermVec tuple, ULitVec body, size_t num_cond,
363 size_t priority)
364 : state_{&state}, loc_weight_{std::move(loc_weight)}, tuple_{std::move(tuple)}, body_{std::move(body)},
365 num_cond_{num_cond}, priority_{priority} {}
366
369 : state_{other.state_}, loc_weight_{other.loc_weight_}, tuple_{copy_uvec(other.tuple_)},
370 body_{copy_uvec(other.body_)}, num_cond_{other.num_cond_}, priority_{other.priority_} {};
372 StmBdAggrElem(StmBdAggrElem &&other) noexcept = default;
374 auto operator=(StmBdAggrElem const &other) -> StmBdAggrElem & = default;
376 auto operator=(StmBdAggrElem &&other) noexcept -> StmBdAggrElem & = default;
377
378 private:
379 friend class StateBdAggr;
380 friend class StateBdAggr::ElementKey;
381
382 [[nodiscard]] auto do_body() const -> ULitVec const & override;
383 [[nodiscard]] auto do_important() const -> VariableSet override;
384 [[nodiscard]] auto do_is_important(size_t index) const -> bool override;
385 void do_init([[maybe_unused]] size_t gen) override;
386 [[nodiscard]] auto do_report(EvalContext const &ctx) -> bool override;
387 void do_propagate(SymbolStore &store, OutputStm &out, Queue &queue) override;
388 [[nodiscard]] auto do_priority() const -> size_t override;
389 void do_print_head(std::ostream &out) const override;
390 void do_print(std::ostream &out) const override;
391
392 auto get_cond_(EvalContext const &ctx) -> std::pair<size_t, bool>;
393
394 StateBdAggr *state_;
395 StateBdAggr::ElementKey *elem_key_ = nullptr;
396 Location loc_weight_;
397 UTermVec tuple_;
398 ULitVec body_;
399 size_t num_cond_;
400 size_t priority_;
401 bool logged_ = false;
402};
403
404static_assert(std::is_nothrow_move_constructible_v<StmBdAggrElem>);
405static_assert(std::is_nothrow_move_assignable_v<StmBdAggrElem>);
406static_assert(std::is_copy_assignable_v<StmBdAggrElem>);
407
409class LitBdAggrStrat : public Lit {
410 public:
412 LitBdAggrStrat(StateBdAggr &state, std::vector<StmBdAggrElem> elems, Sign sign)
413 : state_{&state}, elems_{std::move(elems)}, sign_{sign} {}
414
415 private:
416 void do_vars(VariableSet &vars, VarSelectMode mode) const override;
424 [[nodiscard]] auto do_domain() const -> bool override;
426 [[nodiscard]] auto do_single_pass() const -> bool override;
427 [[nodiscard]] auto do_matcher(std::pmr::monotonic_buffer_resource &mbr, MatcherType type,
428 std::vector<bool> const &bound)
429 -> std::pair<UMatcher, std::optional<size_t>> override;
430 [[nodiscard]] auto do_score([[maybe_unused]] std::vector<bool> const &bound) const -> double override;
431 void do_print(std::ostream &out) const override;
432 auto do_output([[maybe_unused]] EvalContext const &ctx, OutputLit &out) const -> bool override;
433 [[nodiscard]] auto do_copy() const -> ULit override;
434 [[nodiscard]] auto do_hash() const -> size_t override;
435 [[nodiscard]] auto do_equal_to(Lit const &other) const -> bool override;
436 [[nodiscard]] auto do_compare_to(Lit const &other) const -> std::weak_ordering override;
437
438 StateBdAggr *state_;
439 std::vector<StmBdAggrElem> elems_;
440 size_t offset_ = invalid_offset;
441 Sign sign_;
442};
443
445
446} // namespace CppClingo::Ground
Extensible ground representation of body aggregates.
Definition body_aggregate.hh:25
auto propagate(GuardVec const &guards, Symbol const *vals) -> std::pair< bool, bool >
Check if the aggregate matches the guards (first) and is a fact (second).
auto enqueue() -> bool
Enqueue the atom for propagation.
AtomBdAggr(AggregateFunction fun)
Initialize for the given aggregate function.
Definition body_aggregate.hh:34
std::variant< std::pair< Number, Number >, std::pair< Symbol, Symbol > > Bound
The lower and upper bound for the value an aggregate can take.
Definition body_aggregate.hh:31
void accumulate(AggregateFunction fun, SymbolSpan tup, bool fact)
Accumulate a tuple.
auto state() const -> AtomBdAggrState
Get the derived state of the aggregate atom.
auto elems() const -> std::span< size_t const >
Get the aggregate elements.
auto todo() -> std::span< size_t const >
Get the aggregate elements to propagate.
auto uid() const -> std::optional< size_t >
Get the unique id of the aggregate.
auto derived_idx() const -> size_t
Get the index of the aggregate.
void dequeue()
Dequeue the atom after propagation.
void add_elem(size_t idx)
Add a new element.
The base capturing derived body aggregate atoms.
Definition body_aggregate.hh:95
auto size() const -> size_t
Get the number of derived atoms.
BaseBdAggr(size_t size)
Construct an empty base.
Definition body_aggregate.hh:102
void add(AtomMap::iterator it)
Add an atom to the base.
Util::ordered_map< Symbol const *, AtomBdAggr, Util::array_hash, Util::array_equal_to > AtomMap
Map containing the atoms.
Definition body_aggregate.hh:99
auto is_fact(Symbol const *sym) const -> bool
Check if the given atom is a fact.
The base implementation of an atom base.
Definition base.hh:148
auto contains(Key const &sym, MatcherType type) const -> std::optional< size_t >
Check if the base contains the given atom with in the given generation.
Definition base.hh:160
Context object to capture state used during instantiation.
Definition instantiator.hh:35
Literal representing a stratified body aggregate.
Definition body_aggregate.hh:409
LitBdAggrStrat(StateBdAggr &state, std::vector< StmBdAggrElem > elems, Sign sign)
Construct the aggregate literal.
Definition body_aggregate.hh:412
Literal representing an aggregate.
Definition body_aggregate.hh:305
LitBdAggr(StateBdAggr &state, Sign sign)
Construct the aggregate literal.
Definition body_aggregate.hh:308
The base class for groundable literals.
Definition literal.hh:34
A term like object used to match body aggregates.
Definition body_aggregate.hh:270
Symbol const * Key
The key to match against.
Definition body_aggregate.hh:273
auto vars() const -> VariableSet
Get the variables of the matcher.
MatchBdAggr(StateBdAggr &state)
Construct the matcher.
Definition body_aggregate.hh:276
A queue to process instantiators.
Definition instantiator.hh:206
Keys for aggregate elements storing their tuple and their aggregate index.
Definition body_aggregate.hh:144
static auto construct(auto &mbr, EvalContext const &ctx, AggregateFunction fun, size_t atom_idx, StmBdAggrElem &elem) -> bool
Construct an element key evaluating the given tuple.
ElementKey(priv_tag tag, EvalContext const &ctx, AggregateFunction fun, size_t atom_idx, StmBdAggrElem &elem, bool &res)
Construct the element.
ElementKey(ElementKey const &other)=delete
Prevent copying and moving.
auto span() const -> SymbolSpan
Get the tuple.
State storing all necessary information to ground body aggregates.
Definition body_aggregate.hh:138
auto global() const -> VariableVec const &
Get the global variables in the aggregate.
BaseBdAggr::AtomMap AtomMap
A map from global variables (including the guards) to the aggregate representation.
Definition body_aggregate.hh:177
Util::ordered_map< ElementKey *, Util::small_vector< size_t > > ElementMap
A map from tuples to their conditions.
Definition body_aggregate.hh:184
Class to store state for grounding.
Definition base.hh:438
Gather aggregate elements.
Definition body_aggregate.hh:355
StmBdAggrElem(StmBdAggrElem const &other)
Copy constructor.
Definition body_aggregate.hh:368
auto operator=(StmBdAggrElem &&other) noexcept -> StmBdAggrElem &=default
Move assignment.
StmBdAggrElem(StateBdAggr &state, Location loc_weight, UTermVec tuple, ULitVec body, size_t num_cond, size_t priority)
Construct the statement.
Definition body_aggregate.hh:362
auto operator=(StmBdAggrElem const &other) -> StmBdAggrElem &=default
Copy assignment.
StmBdAggrElem(StmBdAggrElem &&other) noexcept=default
Move constructor.
Base class for groundable statements.
Definition statement.hh:17
The Location of an expression in an input source.
Definition location.hh:44
Simple logger to report message to stderr or via a callback.
Definition logger.hh:63
An arbitrary precision integer.
Definition number.hh:27
Interface to output literals.
Definition output.hh:61
Interface to output statements.
Definition output.hh:90
A store for symbols.
Definition symbol.hh:454
Variant-like class to store symbols stored in a symbol store.
Definition symbol.hh:225
Container to store integer sequences.
Definition index_sequence.hh:15
std::span< Symbol const > SymbolSpan
A span of symbols.
Definition symbol.hh:218
std::vector< Symbol > SymbolVec
A vector of symbols.
Definition symbol.hh:220
Sign
Enumeration of signs (default negation).
Definition core.hh:16
AggregateFunction
Enumeration of aggregate functions.
Definition core.hh:87
VariableSet::values_container_type VariableVec
A vector of variables.
Definition base.hh:21
Util::ordered_set< size_t > VariableSet
A set of variables.
Definition base.hh:19
@ derived
Indicates that the atom is derived by some rule but not a fact.
@ unknown
Indicates that the atom has not yet been derived by a rule.
@ fact
Indicates that the atom is derived by a fact.
AtomBdAggrState
Derivation state of body aggregates.
Definition body_aggregate.hh:18
MatcherType
Enumeration of matcher types.
Definition instantiator.hh:48
std::unique_ptr< Matcher > UMatcher
A unique pointer to a matcher.
Definition instantiator.hh:100
std::unique_ptr< Lit > ULit
A unique pointer holding a literal.
Definition literal.hh:29
VarSelectMode
Available variable selection modes.
Definition literal.hh:21
std::vector< ULit > ULitVec
A vector of literals.
Definition literal.hh:31
auto copy_uvec(std::vector< std::unique_ptr< T > > const &vec)
Helper to copy vectors with copyable elements.
Definition term.hh:44
std::vector< std::pair< Relation, UTerm > > GuardVec
A vector of guards.
Definition term.hh:37
std::vector< UTerm > UTermVec
A vector of terms.
Definition term.hh:35
tsl::ordered_map< Key, T, Hash, KeyEqual, Allocator, ValueTypeContainer, IndexType > ordered_map
Alias for ordered maps.
Definition ordered_map.hh:16