Clingo
Loading...
Searching...
No Matches
assignment_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
11namespace CppClingo::Ground {
12
15
18 public:
23 using Values = std::variant<Util::small_vector<Number>, Util::small_vector<Symbol>>;
24
26 AtomAssignAggr(AggregateFunction fun) : values_{init_(fun)} {}
27
30
32 [[nodiscard]] auto is_fact() const;
34 [[nodiscard]] auto todo_values() -> std::variant<NumberSpan, SymbolSpan>;
35
37 void add_elem(size_t idx);
39 [[nodiscard]] auto elems() const -> std::span<size_t const>;
41 [[nodiscard]] auto enqueue() -> bool;
43 void dequeue();
45 [[nodiscard]] auto todo() -> std::span<size_t const>;
46
47 private:
48 static auto init_(AggregateFunction fun) -> Values;
49
50 [[nodiscard]] auto num_values_() const -> size_t;
51
52 std::vector<size_t> elems_;
53 Values values_;
54 size_t propagated_vals_ = 0;
55 size_t propagated_ = 0;
56 bool enqueued_ = false;
57};
58
60class BaseAssignAggr : public BaseImpl<std::pair<size_t, Symbol>, BaseAssignAggr> {
61 public:
63 using BaseImpl::Key;
68
70 BaseAssignAggr(size_t size, bool domain_elems, bool single_pass_elems)
71 : atoms_{0, size, size}, domain_elems_{domain_elems}, single_pass_elems_{single_pass_elems} {}
72
77 [[nodiscard]] auto is_fact(Key sym) const -> bool;
81 auto add(size_t idx, Symbol val) -> bool;
82
84 [[nodiscard]] auto size() const -> size_t;
85
89 [[nodiscard]] auto index(Key sym) const -> size_t;
91 [[nodiscard]] auto nth(size_t i) const -> AtomSet::const_iterator;
93 auto nth(size_t i) -> AtomSet::iterator;
94
96 [[nodiscard]] auto atoms() -> AtomMap &;
98 [[nodiscard]] auto derived() -> AtomSet &;
99
101 [[nodiscard]] auto domain_elems() const -> bool;
103 [[nodiscard]] auto single_pass_elems() const -> bool;
104
105 private:
106 AtomMap atoms_;
107 AtomSet derived_;
108 bool domain_elems_;
109 bool single_pass_elems_;
110};
111
113
115class StateAssignAggr : public State {
116 public:
117 class AtomKey;
122 private:
123 struct priv_tag {};
124
125 public:
127 ElementKey(priv_tag tag, EvalContext const &ctx, AggregateFunction fun, size_t atom_idx,
128 StmAssignAggrElem &elem, bool &res);
129
131 ElementKey(ElementKey const &other) = delete;
133 [[nodiscard]] static auto construct(auto &mbr, EvalContext const &ctx, AggregateFunction fun, size_t atom_idx,
134 StmAssignAggrElem &elem) -> bool;
135
137 [[nodiscard]] auto span() const -> SymbolSpan;
139 [[nodiscard]] auto hash() const -> size_t;
141 friend auto operator==(ElementKey const &a, ElementKey const &b) -> bool;
142
143 private:
144 // Note that these two could be combined to save a little bit of memory.
145 size_t n_;
146 size_t atom_idx_;
147 // NOLINTBEGIN
148 CLINGO_IGNORE_ZERO_SIZED_ARRAY_B
149 Symbol syms_[0];
150 CLINGO_IGNORE_ZERO_SIZED_ARRAY_E
151 // NOLINTEND
152 };
153
159 using ElementMap = Util::ordered_map<ElementKey *, Util::small_vector<size_t>>;
160
162 StateAssignAggr(std::pmr::monotonic_buffer_resource &mbr, VariableVec global, UTerm term, AggregateFunction fun,
163 size_t index, bool domain_elems, bool single_pass_elems)
164 : base_{global.size(), domain_elems, single_pass_elems}, global_{std::move(global)}, term_{std::move(term)},
165 mbr_{&mbr}, index_{index}, fun_{fun} {
166 assert(fun_ != AggregateFunction::count);
167 }
168
172 [[nodiscard]] auto global() const -> VariableVec const &;
174 [[nodiscard]] auto symbols() -> SymbolVec &;
176 [[nodiscard]] auto term() const -> Term const &;
178 [[nodiscard]] auto fun() const -> AggregateFunction;
182 [[nodiscard]] auto domain_elems() const -> bool;
187 [[nodiscard]] auto single_pass_elems() const -> bool;
189 [[nodiscard]] auto index() const -> size_t;
190
192 auto propagate(SymbolStore &store) -> bool;
193
198 auto insert_atom(EvalContext const &ctx) -> std::pair<AtomMap::iterator, bool>;
199
201 void insert_elem(EvalContext const &ctx, AtomMap::iterator it, StmAssignAggrElem &elem);
202
204 auto atom_index(AtomMap::iterator it) -> size_t;
205
207 void print(std::ostream &out, bool print_index);
208
210 [[nodiscard]] auto base() -> BaseAssignAggr &;
211
213 void output(Logger &log, SymbolStore &store, OutputStm &out) override;
214
215 private:
217 void enqueue_(AtomMap::iterator it);
218
219 BaseAssignAggr base_;
220 ElementMap tuples_;
221 VariableVec global_;
222 SymbolVec symbols_;
223 UTerm term_;
224 std::vector<size_t> queue_;
225 std::pmr::monotonic_buffer_resource *mbr_;
226 AtomKey *atom_key_ = nullptr;
227 size_t index_;
229};
230
233 public:
236
238 MatchAssignAggr(StateAssignAggr &state) : state_{&state} { eval_.reserve(state_->global().size()); }
239
241 [[nodiscard]] auto vars() const -> VariableSet;
242
244 [[nodiscard]] auto signature(VariableSet const &bound, [[maybe_unused]] VariableSet const &bind) const
245 -> VariableVec;
246
248 [[nodiscard]] auto match(EvalContext const &ctx, Key key) const -> bool;
249
251 [[nodiscard]] auto eval(EvalContext const &ctx) const -> std::optional<Key>;
252
254 friend auto operator<<(std::ostream &out, MatchAssignAggr const &m) -> std::ostream &;
255
257 [[nodiscard]] auto state() const -> StateAssignAggr &;
258
259 private:
260 std::vector<Symbol> mutable eval_;
261 StateAssignAggr *state_;
262};
263
265class LitAssignAggr : public Lit, private MatchAssignAggr {
266 public:
269
270 private:
271 void do_vars(VariableSet &vars, VarSelectMode mode) const override;
272
273 [[nodiscard]] auto do_domain() const -> bool override;
274
276 [[nodiscard]] auto do_single_pass() const -> bool override;
277
278 [[nodiscard]] auto do_matcher(std::pmr::monotonic_buffer_resource &mbr, MatcherType type,
279 std::vector<bool> const &bound)
280 -> std::pair<UMatcher, std::optional<size_t>> override;
281
282 [[nodiscard]] auto do_score([[maybe_unused]] std::vector<bool> const &bound) const -> double override;
283
284 void do_print(std::ostream &out) const override;
285
286 auto do_output([[maybe_unused]] EvalContext const &ctx, OutputLit &out) const -> bool override;
287
288 [[nodiscard]] auto do_copy() const -> ULit override;
289
290 [[nodiscard]] auto do_hash() const -> size_t override;
291
292 [[nodiscard]] auto do_equal_to(Lit const &other) const -> bool override;
293
294 [[nodiscard]] auto do_compare_to(Lit const &other) const -> std::weak_ordering override;
295
296 size_t offset_ = invalid_offset;
297};
298
305class StmAssignAggrElem : public Stm {
306 public:
312 StmAssignAggrElem(StateAssignAggr &state, Location loc_weight, UTermVec tuple, ULitVec body, size_t num_cond,
313 size_t priority)
314 : state_{&state}, loc_weight_{std::move(loc_weight)}, tuple_{std::move(tuple)}, body_{std::move(body)},
315 num_cond_{num_cond}, priority_{priority} {}
316
319 : state_{other.state_}, loc_weight_{other.loc_weight_}, tuple_{copy_uvec(other.tuple_)},
320 body_{copy_uvec(other.body_)}, num_cond_{other.num_cond_}, priority_{other.priority_} {};
322 StmAssignAggrElem(StmAssignAggrElem &&other) noexcept = default;
324 auto operator=(StmAssignAggrElem const &other) -> StmAssignAggrElem & = default;
326 auto operator=(StmAssignAggrElem &&other) noexcept -> StmAssignAggrElem & = default;
327
328 private:
329 friend class StateAssignAggr;
330 friend class StateAssignAggr::ElementKey;
331
332 [[nodiscard]] auto do_body() const -> ULitVec const & override;
333 [[nodiscard]] auto do_important() const -> VariableSet override;
334 [[nodiscard]] auto do_is_important(size_t index) const -> bool override;
335 void do_init([[maybe_unused]] size_t gen) override;
336 [[nodiscard]] auto do_report(EvalContext const &ctx) -> bool override;
337 void do_propagate(SymbolStore &store, OutputStm &out, Queue &queue) override;
338 [[nodiscard]] auto do_priority() const -> size_t override;
339 void do_print_head(std::ostream &out) const override;
340 void do_print(std::ostream &out) const override;
341
342 auto get_cond_(EvalContext const &ctx) -> std::pair<size_t, bool>;
343
344 StateAssignAggr *state_;
345 StateAssignAggr::ElementKey *key_ = nullptr;
346 Location loc_weight_;
347 UTermVec tuple_;
348 ULitVec body_;
349 size_t num_cond_;
350 size_t priority_;
351 bool logged_ = false;
352};
353
354static_assert(std::is_nothrow_move_constructible_v<StmAssignAggrElem>);
355static_assert(std::is_nothrow_move_assignable_v<StmAssignAggrElem>);
356static_assert(std::is_copy_assignable_v<StmAssignAggrElem>);
357
359class LitAssignAggrStrat : public Lit, private MatchAssignAggr {
360 public:
362 LitAssignAggrStrat(StateAssignAggr &state, std::vector<StmAssignAggrElem> elems)
363 : MatchAssignAggr{state}, elems_{std::move(elems)} {}
364
365 private:
366 void do_vars(VariableSet &vars, VarSelectMode mode) const override;
367
368 [[nodiscard]] auto do_domain() const -> bool override;
369
370 [[nodiscard]] auto do_single_pass() const -> bool override;
371
372 [[nodiscard]] auto do_matcher(std::pmr::monotonic_buffer_resource &mbr, MatcherType type,
373 std::vector<bool> const &bound)
374 -> std::pair<UMatcher, std::optional<size_t>> override;
375
376 [[nodiscard]] auto do_score([[maybe_unused]] std::vector<bool> const &bound) const -> double override;
377
378 void do_print(std::ostream &out) const override;
379
380 auto do_output([[maybe_unused]] EvalContext const &ctx, OutputLit &out) const -> bool override;
381
382 [[nodiscard]] auto do_copy() const -> ULit override;
383
384 [[nodiscard]] auto do_hash() const -> size_t override;
385
386 [[nodiscard]] auto do_equal_to(Lit const &other) const -> bool override;
387
388 [[nodiscard]] auto do_compare_to(Lit const &other) const -> std::weak_ordering override;
389
390 std::vector<StmAssignAggrElem> elems_;
391 size_t offset_ = invalid_offset;
392};
393
395
396} // namespace CppClingo::Ground
Extensible ground representation of assignment aggregates.
Definition assignment_aggregate.hh:17
auto enqueue() -> bool
Enqueue aggregate to propagate its elements.
auto is_fact() const
Check if the aggregate in its current state is a fact.
void dequeue()
Dequeue an aggregate whose elements have been propagated.
void add_elem(size_t idx)
Add a new element.
AtomAssignAggr(AggregateFunction fun)
Initialize for the given aggregate function.
Definition assignment_aggregate.hh:26
auto todo() -> std::span< size_t const >
Get the elements that have to be propagated.
std::variant< Util::small_vector< Number >, Util::small_vector< Symbol > > Values
The possible values an assignment aggregate can take.
Definition assignment_aggregate.hh:23
void accumulate(AggregateFunction fun, SymbolSpan tup, bool fact)
Accumulate a tuple.
auto todo_values() -> std::variant< NumberSpan, SymbolSpan >
Get the values to propagate.
auto elems() const -> std::span< size_t const >
Get the aggregate elements.
The base capturing derived assignment aggregate atoms.
Definition assignment_aggregate.hh:60
BaseAssignAggr(size_t size, bool domain_elems, bool single_pass_elems)
Construct an empty base.
Definition assignment_aggregate.hh:70
auto size() const -> size_t
Get the number of derived atoms.
KeyType Key
The key identifies an atom and is usually associated with further state.
Definition base.hh:151
Util::ordered_map< Symbol const *, AtomAssignAggr, Util::array_hash, Util::array_equal_to > AtomMap
Map containing the atoms.
Definition assignment_aggregate.hh:65
auto add(size_t idx, Symbol val) -> bool
Add an atom to the base.
Util::ordered_map< Key, size_t > AtomSet
Map containing the derived atoms and their values.
Definition assignment_aggregate.hh:67
auto is_fact(Key sym) const -> bool
Check if the given atom is a fact.
The base implementation of an atom base.
Definition base.hh:148
KeyType Key
The key identifies an atom and is usually associated with further state.
Definition base.hh:151
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 assignment aggregate.
Definition assignment_aggregate.hh:359
LitAssignAggrStrat(StateAssignAggr &state, std::vector< StmAssignAggrElem > elems)
Construct an assignment aggregate literal.
Definition assignment_aggregate.hh:362
Literal representing an assignment aggregate.
Definition assignment_aggregate.hh:265
LitAssignAggr(StateAssignAggr &state)
Construct an assignment aggregate literal.
Definition assignment_aggregate.hh:268
The base class for groundable literals.
Definition literal.hh:34
A term like object to match assignment aggregates.
Definition assignment_aggregate.hh:232
auto vars() const -> VariableSet
Get the variables of the matcher.
BaseAssignAggr::Key Key
The key to match against.
Definition assignment_aggregate.hh:235
MatchAssignAggr(StateAssignAggr &state)
Construct the matcher.
Definition assignment_aggregate.hh:238
A queue to process instantiators.
Definition instantiator.hh:206
Keys for aggregate elements storing their tuple and their aggregate atom index.
Definition assignment_aggregate.hh:121
ElementKey(ElementKey const &other)=delete
Prevent copying and moving.
static auto construct(auto &mbr, EvalContext const &ctx, AggregateFunction fun, size_t atom_idx, StmAssignAggrElem &elem) -> bool
Construct an element key evaluating the given tuple.
auto span() const -> SymbolSpan
Get the tuple.
ElementKey(priv_tag tag, EvalContext const &ctx, AggregateFunction fun, size_t atom_idx, StmAssignAggrElem &elem, bool &res)
Construct the element.
State storing all necessary information to ground assignment aggregates.
Definition assignment_aggregate.hh:115
Util::ordered_map< ElementKey *, Util::small_vector< size_t > > ElementMap
A map from tuples to their conditions.
Definition assignment_aggregate.hh:159
BaseAssignAggr::AtomMap AtomMap
A map from global variables to the aggregate representation.
Definition assignment_aggregate.hh:155
auto global() const -> VariableVec const &
Get the global variables in the aggregate.
Class to store state for grounding.
Definition base.hh:438
Gather aggregate elements.
Definition assignment_aggregate.hh:305
auto operator=(StmAssignAggrElem &&other) noexcept -> StmAssignAggrElem &=default
Move assignment.
StmAssignAggrElem(StmAssignAggrElem &&other) noexcept=default
Move constructor.
auto operator=(StmAssignAggrElem const &other) -> StmAssignAggrElem &=default
Copy assignment.
StmAssignAggrElem(StmAssignAggrElem const &other)
Copy constructor.
Definition assignment_aggregate.hh:318
StmAssignAggrElem(StateAssignAggr &state, Location loc_weight, UTermVec tuple, ULitVec body, size_t num_cond, size_t priority)
Construct the statement.
Definition assignment_aggregate.hh:312
Base class for groundable statements.
Definition statement.hh:17
Term interface.
Definition term.hh:67
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
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
A vector that misuses the begin, end and capacity pointers to store elements.
Definition small_vector.hh:26
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
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.
@ fact
Indicates that the atom is derived by a fact.
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::unique_ptr< Term > UTerm
A unique pointer holding a term.
Definition term.hh:33
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