Clingo
Loading...
Searching...
No Matches
disjunction.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
17// Outline:
18// - grounding of disjunctions is very similar to the grounding of head aggregates
19// - the differences are small
20// - grounding can be stopped if one element becomes true
21// - data structures do not have to store term tuples
22
29 public:
31 [[nodiscard]] auto is_fact() const -> bool;
33 void mark_fact();
35 auto enqueue() -> bool;
39 void dequeue();
41 void add_elem(size_t idx);
43 [[nodiscard]] auto elems() const -> std::span<size_t const>;
45 [[nodiscard]] auto todo() -> std::span<size_t const>;
46
48 [[nodiscard]] auto uid() const -> std::optional<size_t>;
50 void uid(size_t uid);
51
52 private:
53 Util::small_vector<size_t> elems_;
54 size_t uid_ = invalid_offset;
55 uint64_t propagated_ : 62 = 0;
56 // TODO: maybe bit set
57 uint64_t enqueued_ : 1 = 0;
58 uint64_t fact_ : 1 = 0;
59};
60
63 public:
67
69 BaseDisjunction(size_t size) : atoms_{0, size, size} {}
70
72 auto add(Symbol const *sym) -> std::pair<AtomMap::iterator, bool>;
73
75 [[nodiscard]] auto size() const -> size_t;
76
80 [[nodiscard]] auto index(Symbol const *sym) const -> size_t;
82 [[nodiscard]] auto nth(size_t i) const -> AtomMap::const_iterator;
84 [[nodiscard]] auto nth(size_t i) -> AtomMap::iterator;
85
87 [[nodiscard]] auto atoms() -> AtomMap &;
88
89 private:
90 AtomMap atoms_;
91};
92
97using DisjunctionBaseVec = std::vector<std::tuple<std::tuple<String, size_t, bool>, AtomBase *, std::vector<size_t>>>;
98
100class StateDisjunction : public State {
101 public:
105 using ElementKey = std::pair<Symbol, size_t>;
108
110 StateDisjunction(std::pmr::monotonic_buffer_resource &mbr, DisjunctionBaseVec bases, VariableVec global,
111 size_t index, bool single_pass_body)
112 : base_{global.size()}, global_{std::move(global)}, bases_{std::move(bases)}, mbr_{&mbr}, index_{index},
113 single_pass_body_{single_pass_body} {}
114
116 [[nodiscard]] auto global() const -> VariableVec const &;
118 [[nodiscard]] auto symbols() -> SymbolVec &;
121 [[nodiscard]] auto single_pass_body() const -> bool;
123 [[nodiscard]] auto index() const -> size_t;
127 [[nodiscard]] auto indices() const -> std::vector<size_t>;
128
130 void enqueue(Queue &queue);
131
133 void propagate(OutputStm &out, Queue &queue);
134
136 auto insert_atom(Assignment &ass) -> std::pair<AtomMap::iterator, bool>;
137
139 void insert_elem(EvalContext const &ctx, AtomMap::iterator it, UTerm const &head, auto const &get_cond);
140
142 void print(std::ostream &out, bool print_index);
143
145 void output(Logger &log, SymbolStore &store, OutputStm &out) override;
146
148 [[nodiscard]] auto base() -> BaseDisjunction &;
149
150 private:
152 void enqueue_(AtomMap::iterator it);
153
157 auto atom_index_(AtomMap::iterator it) -> size_t;
158
159 BaseDisjunction base_;
160 ElementMap elems_;
161 VariableVec global_;
162 SymbolVec symbols_;
163 DisjunctionBaseVec bases_;
164 std::vector<size_t> queue_;
165 std::pmr::monotonic_buffer_resource *mbr_;
166 Symbol *atom_key_ = nullptr;
167 size_t index_;
168 bool single_pass_body_;
169};
170
172class StmDisjunction : public Stm {
173 public:
175 StmDisjunction(StateDisjunction &state, Ground::ULitVec body, size_t priority)
176 : state_{&state}, body_{std::move(body)}, priority_{priority} {}
177
178 private:
179 // Stm interface
180 void do_print(std::ostream &out) const override;
181
182 [[nodiscard]] auto do_body() const -> ULitVec const & override;
183 [[nodiscard]] auto do_important() const -> VariableSet override;
184
185 // InstanceCallback interface
186 void do_print_head(std::ostream &out) const override;
187 void do_init(size_t gen) override;
188 [[nodiscard]] auto do_report(EvalContext const &ctx) -> bool override;
189 void do_propagate(SymbolStore &store, OutputStm &out, Queue &queue) override;
190 [[nodiscard]] auto do_priority() const -> size_t override;
191
192 StateDisjunction *state_;
193 ULitVec body_;
194 size_t priority_;
195};
196
198class StmDisjunctionElem : public Stm {
199 public:
202 : state_{&state}, head_{std::move(head)}, base_{&base}, body_{std::move(body)} {}
203
204 private:
205 [[nodiscard]] auto do_body() const -> ULitVec const & override;
206 [[nodiscard]] auto do_important() const -> VariableSet override;
207 void do_init(size_t gen) override;
208 [[nodiscard]] auto do_report(EvalContext const &ctx) -> bool override;
209 void do_propagate(SymbolStore &store, OutputStm &out, Queue &queue) override;
210 [[nodiscard]] auto do_priority() const -> size_t override;
211 void do_print_head(std::ostream &out) const override;
212 void do_print(std::ostream &out) const override;
213
214 StateDisjunction *state_;
215 UTerm head_;
216 AtomBase *base_;
217 ULitVec body_;
218};
219
222 public:
224 using Key = Symbol const *;
225
227 MatchDisjunction(StateDisjunction &state) : state_{&state} { eval_.reserve(state_->global().size()); }
228
230 [[nodiscard]] auto vars() const -> VariableSet;
231
233 [[nodiscard]] auto signature(VariableSet const &bound, VariableSet const &bind) const -> VariableVec;
234
236 [[nodiscard]] auto match(EvalContext const &ctx, Symbol const *sym) const -> bool;
237
239 [[nodiscard]] auto eval(EvalContext const &ctx) const -> std::optional<Symbol const *>;
240
242 friend auto operator<<(std::ostream &out, MatchDisjunction const &m) -> std::ostream &;
243
245 [[nodiscard]] auto state() const -> StateDisjunction &;
246
247 private:
248 std::vector<Symbol> mutable eval_;
249 StateDisjunction *state_;
250};
251
253class LitDisjunction : public Lit, private MatchDisjunction {
254 public:
257
258 private:
259 void do_vars(VariableSet &vars, VarSelectMode mode) const override;
260
261 [[nodiscard]] auto do_domain() const -> bool override;
262
264 [[nodiscard]] auto do_single_pass() const -> bool override;
265
266 [[nodiscard]] auto do_matcher(std::pmr::monotonic_buffer_resource &mbr, MatcherType type,
267 std::vector<bool> const &bound)
268 -> std::pair<UMatcher, std::optional<size_t>> override;
269
270 [[nodiscard]] auto do_score(std::vector<bool> const &bound) const -> double override;
271
272 void do_print(std::ostream &out) const override;
273
274 auto do_output(EvalContext const &ctx, OutputLit &out) const -> bool override;
275
276 [[nodiscard]] auto do_copy() const -> ULit override;
277
278 [[nodiscard]] auto do_hash() const -> size_t override;
279
280 [[nodiscard]] auto do_equal_to(Lit const &other) const -> bool override;
281
282 [[nodiscard]] auto do_compare_to(Lit const &other) const -> std::weak_ordering override;
283
284 size_t offset_ = invalid_offset;
285};
286
288
289} // namespace CppClingo::Ground
An atom base used to store derivable atoms and associated state.
Definition base.hh:212
Extensible ground representation of disjunctions.
Definition disjunction.hh:28
auto is_fact() const -> bool
Check if the disjunction is a fact.
void mark_fact()
Mark the disjunction as fact.
void dequeue()
Dequeue the atom after propagation.
auto uid() const -> std::optional< size_t >
Get the unique id of the disjunction atom.
auto enqueue() -> bool
Enqueue the atom for propagation.
auto elems() const -> std::span< size_t const >
Get the disjunction elements.
auto todo() -> std::span< size_t const >
Get the disjunction elements to propagate.
void add_elem(size_t idx)
Add a new element.
The base capturing derived disjunction atoms.
Definition disjunction.hh:62
auto size() const -> size_t
Get the number of derived atoms.
BaseDisjunction(size_t size)
Construct an empty base.
Definition disjunction.hh:69
auto add(Symbol const *sym) -> std::pair< AtomMap::iterator, bool >
Add an atom to the current generation.
Util::ordered_map< Symbol const *, AtomDisjunction, Util::array_hash, Util::array_equal_to > AtomMap
Mapping from global variables to disjunction atoms.
Definition disjunction.hh:66
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 disjunction.
Definition disjunction.hh:253
LitDisjunction(StateDisjunction &state)
Construct the disjunction literal.
Definition disjunction.hh:256
The base class for groundable literals.
Definition literal.hh:34
A term like object used to match disjunction atoms.
Definition disjunction.hh:221
MatchDisjunction(StateDisjunction &state)
Construct the matcher.
Definition disjunction.hh:227
auto vars() const -> VariableSet
Get the variables of the matcher.
Symbol const * Key
The key to match against.
Definition disjunction.hh:224
A queue to process instantiators.
Definition instantiator.hh:206
State storing all necessary information to ground disjunctions.
Definition disjunction.hh:100
BaseDisjunction::AtomMap AtomMap
A map from global variables (including the guards) to the disjunction representation.
Definition disjunction.hh:103
auto global() const -> VariableVec const &
Get the global variables in the disjunction.
StateDisjunction(std::pmr::monotonic_buffer_resource &mbr, DisjunctionBaseVec bases, VariableVec global, size_t index, bool single_pass_body)
Initialize a disjunction state.
Definition disjunction.hh:110
std::pair< Symbol, size_t > ElementKey
A key consisting of a head atom and a disjunction atom index.
Definition disjunction.hh:105
Util::ordered_map< ElementKey, std::pair< size_t, Util::small_vector< size_t > > > ElementMap
A map from disjunction atoms and their heads to conditions.
Definition disjunction.hh:107
Class to store state for grounding.
Definition base.hh:438
Gather disjunction elements.
Definition disjunction.hh:198
StmDisjunctionElem(StateDisjunction &state, UTerm head, AtomBase &base, ULitVec body)
Construct the statement.
Definition disjunction.hh:201
A statement deriving disjunction atoms to trigger grounding of elements.
Definition disjunction.hh:172
StmDisjunction(StateDisjunction &state, Ground::ULitVec body, size_t priority)
Construct the statement.
Definition disjunction.hh:175
Base class for groundable statements.
Definition statement.hh:17
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
Reference to a string stored in a symbol store.
Definition symbol.hh:18
A store for symbols.
Definition symbol.hh:454
Variant-like class to store symbols stored in a symbol store.
Definition symbol.hh:225
std::vector< std::optional< Symbol > > Assignment
Assignment mapping variables to symbols.
Definition symbol.hh:222
std::vector< Symbol > SymbolVec
A vector of symbols.
Definition symbol.hh:220
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
std::vector< std::tuple< std::tuple< String, size_t, bool >, AtomBase *, std::vector< size_t > > > DisjunctionBaseVec
A vector of signatures, bases, and indices.
Definition disjunction.hh:97
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
std::unique_ptr< Term > UTerm
A unique pointer holding a term.
Definition term.hh:33
tsl::ordered_map< Key, T, Hash, KeyEqual, Allocator, ValueTypeContainer, IndexType > ordered_map
Alias for ordered maps.
Definition ordered_map.hh:16