Clingo
Loading...
Searching...
No Matches
theory_atom.hh
1#pragma once
2
3#include <clingo/ground/matcher.hh>
4#include <clingo/ground/statement.hh>
5#include <clingo/ground/term.hh>
6#include <clingo/ground/theory_term.hh>
7
8#include <clingo/util/macro.hh>
9#include <clingo/util/small_vector.hh>
10
11#include <memory_resource>
12
13namespace CppClingo::Ground {
14
15// Outline:
16// - rules:
17// H :- L, B.
18// accu :- A, E.
19// - literal L simply matches everything
20// - atom A matches the theory atoms output while grounding
21// - statements elem gather the ground elements of theory atoms
22// whose grounding is delayed until output
23// - propagate
24// - no propagation is necessary because theory atoms always match
25// - output
26// - as with other aggregates, output is delayed until the end of a component
27// - unlike other aggregates, elements are grounded during output
28// - classes
29// - AtomTheory (ground representation for theory atoms)
30// - BaseTheory (a base for theory atoms)
31// - StateTheoryAtom (gathers state for grounding/output)
32// - MatchTheory (match object for theory atoms)
33// - LitMatchTheory (binder to ground theory elements)
34// - StmTheoryElement (statement to accumulate elements)
35// - LitTheoryAtom (atom to capture theory atoms in bodies)
36// - StmTheoryAtom (statement to capture theory atoms in heads)
37
40
42using TheoryRGuard = std::optional<std::pair<String, UTheoryTerm>>;
43
46 public:
48 AtomTheory(Symbol name, std::optional<size_t> rhs) : name_{name}, rhs_{rhs ? *rhs : invalid_offset} {}
49
51 void add_elem(size_t idx);
53 [[nodiscard]] auto elems() const -> std::span<size_t const>;
54
56 [[nodiscard]] auto uid() const -> std::optional<size_t>;
58 void uid(size_t uid);
59
61 [[nodiscard]] auto name() const -> Symbol { return name_; }
62
64 [[nodiscard]] auto rhs() const -> std::optional<size_t> {
65 if (rhs_ != invalid_offset) {
66 return rhs_;
67 }
68 return std::nullopt;
69 }
70
71 private:
73 Symbol name_;
74 size_t uid_ = invalid_offset;
75 size_t rhs_;
76};
77
79class BaseTheory : public BaseImpl<Symbol const *, BaseTheory> {
80 public:
84
86 BaseTheory(size_t size) : atoms_{0, size, size} {}
87
89 auto add(Symbol const *sym, Symbol name, std::optional<size_t> rhs) -> std::pair<AtomMap::iterator, bool>;
90
92 [[nodiscard]] auto size() const -> size_t;
93
97 [[nodiscard]] auto index(Symbol const *sym) const -> size_t;
99 [[nodiscard]] auto nth(size_t i) const -> AtomMap::const_iterator;
101 [[nodiscard]] auto nth(size_t i) -> AtomMap::iterator;
102
104 [[nodiscard]] auto atoms() -> AtomMap &;
105
106 private:
107 AtomMap atoms_;
108};
109
111class StateTheory : public Ground::State {
112 public:
117 private:
118 struct priv_tag {};
119
120 public:
122 ElementKey(priv_tag tag, EvalContext const &ctx, OutputTheory &out, size_t atom_idx,
123 UTheoryTermVec const &terms);
125 ElementKey(ElementKey const &other) = delete;
127 static void construct(std::pmr::monotonic_buffer_resource &mbr, EvalContext const &ctx, OutputTheory &out,
128 size_t atom_idx, UTheoryTermVec const &terms, ElementKey *&target);
129
131 [[nodiscard]] auto terms() const -> UTheoryTermVec const &;
133 [[nodiscard]] auto size() const -> size_t;
135 [[nodiscard]] auto span() const -> std::span<size_t const>;
137 [[nodiscard]] auto hash() const -> size_t;
139 friend auto operator==(ElementKey const &a, ElementKey const &b) -> bool;
140
141 private:
142 size_t n_;
143 size_t atom_idx_;
144 // NOLINTBEGIN
145 CLINGO_IGNORE_ZERO_SIZED_ARRAY_B
146 size_t syms_[0];
147 CLINGO_IGNORE_ZERO_SIZED_ARRAY_E
148 // NOLINTEND
149 };
150
154 using ElementMap = Util::ordered_map<ElementKey *, Util::small_vector<size_t>>;
155
157 StateTheory(std::pmr::monotonic_buffer_resource &mbr, VariableVec global, UTerm name, TheoryRGuard guard,
158 OutputTheory::AtomType type)
159 : base_{global.size()}, mbr_{&mbr}, global_{std::move(global)}, name_{std::move(name)},
160 guard_{std::move(guard)}, type_{type} {}
161
165 auto find_atom(Assignment &ass) -> AtomMap::iterator;
169 auto insert_atom(Symbol name, std::optional<size_t> rhs, Assignment &ass) -> std::pair<AtomMap::iterator, bool>;
173 void insert_elem(EvalContext const &ctx, AtomMap::iterator it, UTheoryTermVec const &tuple, ElementKey *&elem_key,
174 auto const &get_cond);
176 void print(std::ostream &out);
178 void output(Logger &log, SymbolStore &store, OutputStm &out) override;
180 [[nodiscard]] auto global() const -> VariableVec const &;
182 [[nodiscard]] auto name() const -> UTerm const &;
184 [[nodiscard]] auto guard() const -> TheoryRGuard const &;
186 [[nodiscard]] auto base() -> BaseTheory &;
188 void elems(UStmVec elems);
189
190 private:
191 BaseTheory base_;
192 ElementMap tuples_;
193 std::pmr::monotonic_buffer_resource *mbr_;
194 VariableVec global_;
195 UTerm name_;
196 TheoryRGuard guard_;
197 UStmVec elems_;
198 Symbol *atom_key_ = nullptr;
199 OutputTheory::AtomType type_;
200};
201
204 public:
206 using Key = Symbol const *;
207
209 MatchTheory(StateTheory &state) : state_{&state} { eval_.reserve(state_->global().size()); }
210
212 [[nodiscard]] auto vars() const -> VariableSet;
213
215 [[nodiscard]] auto signature(VariableSet const &bound, VariableSet const &bind) const -> VariableVec;
216
218 [[nodiscard]] auto match(EvalContext const &ctx, Symbol const *sym) const -> bool;
219
221 [[nodiscard]] auto eval(EvalContext const &ctx) const -> std::optional<Symbol const *>;
222
224 friend auto operator<<(std::ostream &out, MatchTheory const &m) -> std::ostream &;
225
227 [[nodiscard]] auto state() const -> StateTheory &;
228
229 private:
230 std::vector<Symbol> mutable eval_;
231 StateTheory *state_;
232};
233
235class LitMatchTheory : public Lit, private MatchTheory {
236 public:
239
240 private:
241 void do_vars(VariableSet &vars, VarSelectMode mode) const override;
242 [[nodiscard]] auto do_domain() const -> bool override;
243 [[nodiscard]] auto do_single_pass() const -> bool override;
244 [[nodiscard]] auto do_matcher(std::pmr::monotonic_buffer_resource &mbr, MatcherType type,
245 std::vector<bool> const &bound)
246 -> std::pair<UMatcher, std::optional<size_t>> override;
247 [[nodiscard]] auto do_score(std::vector<bool> const &bound) const -> double override;
248 void do_print(std::ostream &out) const override;
249 auto do_output(EvalContext const &ctx, OutputLit &out) const -> bool override;
250 [[nodiscard]] auto do_copy() const -> ULit override;
251 [[nodiscard]] auto do_hash() const -> size_t override;
252 [[nodiscard]] auto do_equal_to(Lit const &other) const -> bool override;
253 [[nodiscard]] auto do_compare_to(Lit const &other) const -> std::weak_ordering override;
254
255 size_t offset_ = invalid_offset;
256};
257
259class StmTheoryElement : public Stm {
260 public:
263 : state_{&state}, tuple_{std::move(tuple)}, body_{std::move(body)} {}
264
265 private:
266 [[nodiscard]] auto do_body() const -> ULitVec const & override;
267 [[nodiscard]] auto do_important() const -> VariableSet override;
268 void do_init([[maybe_unused]] size_t gen) override;
269 [[nodiscard]] auto do_report(EvalContext const &ctx) -> bool override;
270 void do_propagate(SymbolStore &store, OutputStm &out, Queue &queue) override;
271 [[nodiscard]] auto do_priority() const -> size_t override;
272 void do_print_head(std::ostream &out) const override;
273 void do_print(std::ostream &out) const override;
274
275 StateTheory *state_;
276 StateTheory::ElementKey *elem_key_ = nullptr;
277 UTheoryTermVec tuple_;
278 ULitVec body_;
279};
280
282class LitBdTheory : public Lit {
283 public:
285 LitBdTheory(StateTheory &state, Sign sign) : state_{&state}, sign_{sign} {}
286
287 private:
288 void do_vars(VariableSet &vars, VarSelectMode mode) const override;
289 [[nodiscard]] auto do_domain() const -> bool override;
290 [[nodiscard]] auto do_single_pass() const -> bool override;
291 [[nodiscard]] auto do_matcher(std::pmr::monotonic_buffer_resource &mbr, MatcherType type,
292 std::vector<bool> const &bound)
293 -> std::pair<UMatcher, std::optional<size_t>> override;
294 [[nodiscard]] auto do_score(std::vector<bool> const &bound) const -> double override;
295 void do_print(std::ostream &out) const override;
296 auto do_output(EvalContext const &ctx, OutputLit &out) const -> bool override;
297 [[nodiscard]] auto do_copy() const -> ULit override;
298 [[nodiscard]] auto do_hash() const -> size_t override;
299 [[nodiscard]] auto do_equal_to(Lit const &other) const -> bool override;
300 [[nodiscard]] auto do_compare_to(Lit const &other) const -> std::weak_ordering override;
301
302 StateTheory *state_;
303 Symbol name_;
304 Sign sign_;
305};
306
308class StmHdTheory : public Stm {
309 public:
311 StmHdTheory(StateTheory &state, ULitVec body) : state_{&state}, body_{std::move(body)} {}
312
313 private:
314 [[nodiscard]] auto do_body() const -> ULitVec const & override;
315 [[nodiscard]] auto do_important() const -> VariableSet override;
316 void do_init([[maybe_unused]] size_t gen) override;
317 [[nodiscard]] auto do_report(EvalContext const &ctx) -> bool override;
318 void do_propagate(SymbolStore &store, OutputStm &out, Queue &queue) override;
319 [[nodiscard]] auto do_priority() const -> size_t override;
320 void do_print_head(std::ostream &out) const override;
321 void do_print(std::ostream &out) const override;
322
323 StateTheory *state_;
324 ULitVec body_;
325};
326
328
329} // namespace CppClingo::Ground
Extensible ground representation for theory atoms.
Definition theory_atom.hh:45
auto elems() const -> std::span< size_t const >
Get the theory atom's elements.
auto name() const -> Symbol
Get the name of the atom.
Definition theory_atom.hh:61
auto rhs() const -> std::optional< size_t >
Get the right hand side theory term index.
Definition theory_atom.hh:64
AtomTheory(Symbol name, std::optional< size_t > rhs)
Default construct the atom with an empty set of elements.
Definition theory_atom.hh:48
void add_elem(size_t idx)
Add a new element.
auto uid() const -> std::optional< size_t >
Get the unique id of the theory atom.
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
The base capturing theory atoms encountered during grounding.
Definition theory_atom.hh:79
auto nth(size_t i) const -> AtomMap::const_iterator
Get the i-th atom in the base.
auto add(Symbol const *sym, Symbol name, std::optional< size_t > rhs) -> std::pair< AtomMap::iterator, bool >
Add an atom.
Util::ordered_map< Symbol const *, AtomTheory, Util::array_hash, Util::array_equal_to > AtomMap
Map containing the atoms.
Definition theory_atom.hh:83
auto atoms() -> AtomMap &
Get the underlying atom map.
auto size() const -> size_t
Get the number of derived atoms.
BaseTheory(size_t size)
Construct an empty base.
Definition theory_atom.hh:86
auto index(Symbol const *sym) const -> size_t
Get the atom index of the given symbol.
Context object to capture state used during instantiation.
Definition instantiator.hh:35
Literal to match a theory atom.
Definition theory_atom.hh:282
LitBdTheory(StateTheory &state, Sign sign)
Construct the matcher.
Definition theory_atom.hh:285
Literal to match a theory atom.
Definition theory_atom.hh:235
LitMatchTheory(StateTheory &state)
Construct the matcher.
Definition theory_atom.hh:238
The base class for groundable literals.
Definition literal.hh:34
A term like object used to match theory atoms.
Definition theory_atom.hh:203
MatchTheory(StateTheory &state)
Construct the matcher.
Definition theory_atom.hh:209
auto vars() const -> VariableSet
Get the variables of the matcher.
Symbol const * Key
The key to match against.
Definition theory_atom.hh:206
A queue to process instantiators.
Definition instantiator.hh:206
Keys for aggregate elements storing their tuple and their aggregate index.
Definition theory_atom.hh:116
static void construct(std::pmr::monotonic_buffer_resource &mbr, EvalContext const &ctx, OutputTheory &out, size_t atom_idx, UTheoryTermVec const &terms, ElementKey *&target)
Construct an element key evaluating the given tuple.
ElementKey(ElementKey const &other)=delete
Prevent copying and moving.
ElementKey(priv_tag tag, EvalContext const &ctx, OutputTheory &out, size_t atom_idx, UTheoryTermVec const &terms)
Constructor.
auto terms() const -> UTheoryTermVec const &
Get the terms.
State storing all necessary information to ground theory atoms.
Definition theory_atom.hh:111
auto find_atom(Assignment &ass) -> AtomMap::iterator
Find a previously grounded theory atom.
Util::ordered_map< ElementKey *, Util::small_vector< size_t > > ElementMap
Map capturing the elements of theory atoms.
Definition theory_atom.hh:154
void insert_elem(EvalContext const &ctx, AtomMap::iterator it, UTheoryTermVec const &tuple, ElementKey *&elem_key, auto const &get_cond)
Insert a theory atom element.
BaseTheory::AtomMap AtomMap
Map containing the atoms.
Definition theory_atom.hh:152
auto global() const -> VariableVec const &
Get the global variables of the theory atom.
auto insert_atom(Symbol name, std::optional< size_t > rhs, Assignment &ass) -> std::pair< AtomMap::iterator, bool >
Insert a theory atom.
void print(std::ostream &out)
Print a debug representation of the theory atom.
void output(Logger &log, SymbolStore &store, OutputStm &out) override
Output all previously output theory atoms.
Class to store state for grounding.
Definition base.hh:438
Ground a rule with a theory atom in the head.
Definition theory_atom.hh:308
StmHdTheory(StateTheory &state, ULitVec body)
Construct the statement.
Definition theory_atom.hh:311
Gather theory atom elements.
Definition theory_atom.hh:259
StmTheoryElement(StateTheory &state, UTheoryTermVec tuple, ULitVec body)
Construct the statement.
Definition theory_atom.hh:262
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
Interface to output literals.
Definition output.hh:20
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::vector< std::optional< Symbol > > Assignment
Assignment mapping variables to symbols.
Definition symbol.hh:222
Sign
Enumeration of signs (default negation).
Definition core.hh:16
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
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::vector< UStm > UStmVec
A vector of statements.
Definition statement.hh:44
std::unique_ptr< Term > UTerm
A unique pointer holding a term.
Definition term.hh:33
std::vector< UTheoryTerm > UTheoryTermVec
A vector of theory terms.
Definition theory_term.hh:15
std::optional< std::pair< String, UTheoryTerm > > TheoryRGuard
The right-hand-side of a theory atom.
Definition theory_atom.hh:42
tsl::ordered_map< Key, T, Hash, KeyEqual, Allocator, ValueTypeContainer, IndexType > ordered_map
Alias for ordered maps.
Definition ordered_map.hh:16