Clingo
Loading...
Searching...
No Matches
term.hh
1#pragma once
2
3#include <clingo/ground/instantiator.hh>
4
5#include <clingo/core/core.hh>
6#include <clingo/core/fstring.hh>
7#include <clingo/core/location.hh>
8#include <clingo/core/logger.hh>
9#include <clingo/core/symbol.hh>
10
11#include <clingo/util/enum.hh>
12#include <clingo/util/ordered_set.hh>
13#include <clingo/util/unordered_map.hh>
14
15namespace CppClingo::Ground {
16
19
21using VariableSet = Util::ordered_set<size_t>;
23using VariableVec = VariableSet::values_container_type;
24
26enum class RenameMode : uint8_t {
30};
31
32class Term;
34using UTerm = std::unique_ptr<Term>;
36using UTermVec = std::vector<UTerm>;
38using GuardVec = std::vector<std::pair<Relation, UTerm>>;
39
41template <class T>
42 requires requires(T x) {
43 { x.copy() } -> std::convertible_to<std::unique_ptr<T>>;
44 }
45auto copy_uvec(std::vector<std::unique_ptr<T>> const &vec) {
46 std::vector<std::unique_ptr<T>> res;
47 res.reserve(vec.size());
48 for (auto const &x : vec) {
49 res.emplace_back(x->copy());
50 }
51 return res;
52}
54template <class T>
55 requires requires(T x) {
56 { x.copy() } -> std::convertible_to<std::unique_ptr<T>>;
57 }
58auto copy_uvec(std::vector<std::vector<std::unique_ptr<T>>> const &vec) {
59 std::vector<std::vector<std::unique_ptr<T>>> res;
60 res.reserve(vec.size());
61 for (auto const &x : vec) {
62 res.emplace_back(copy_uvec(x));
63 }
64 return res;
65}
66
68class Term {
69 public:
71 using Key = Symbol;
72
74 virtual ~Term() = default;
76 [[nodiscard]] auto score(double size, std::vector<bool> const &bound) const -> double {
77 return do_score(size, bound);
78 }
83 [[nodiscard]] auto match(EvalContext const &ctx, Symbol sym) const -> bool { return do_match(ctx, sym); }
87 [[nodiscard]] auto eval(EvalContext const &ctx) const -> std::optional<Symbol> { return do_eval(ctx); }
92 [[nodiscard]] auto rename(SymbolStore &store, RenameMode mode, String const *name, size_t *vars) const -> UTerm {
93 return do_rename(store, mode, name, vars);
94 }
96 [[nodiscard]] auto rename(Util::unordered_map<size_t, size_t> &vars) const -> UTerm { return do_rename(vars); }
98 void vars(VariableSet &vars, bool provide = false) const { do_vars(vars, provide); }
100 [[nodiscard]] auto copy() const -> UTerm { return do_copy(); }
102 [[nodiscard]] auto hash() const -> size_t { return do_hash(); }
103
108 [[nodiscard]] auto signature(VariableSet const &bound, VariableSet const &bind) const
109 -> std::pair<UTerm, VariableVec> {
111 names.reserve(bind.size() + bound.size());
112 auto sig_term = rename(names);
113 auto sig_lookup = std::vector<size_t>{};
114 sig_lookup.reserve(bound.size());
115 for (auto const &var : bound) {
116 sig_lookup.emplace_back(names[var]);
117 }
118 return {std::move(sig_term), std::move(sig_lookup)};
119 }
121 [[nodiscard]] auto vars() const -> VariableSet {
122 VariableSet set;
123 vars(set);
124 return set;
125 }
126
128 friend auto operator==(Term const &a, Term const &b) -> bool { return a.do_equal_to(b); }
130 friend auto operator<=>(Term const &a, Term const &b) -> std::strong_ordering { return a.do_compare_to(b); }
132 friend auto operator<<(std::ostream &out, Term const &term) -> std::ostream & {
133 term.do_print(out);
134 return out;
135 }
136
137 private:
138 [[nodiscard]] virtual auto do_score(double size, std::vector<bool> const &bound) const -> double = 0;
139 [[nodiscard]] virtual auto do_match(EvalContext const &ctx, Symbol sym) const -> bool = 0;
140 [[nodiscard]] virtual auto do_eval(EvalContext const &ctx) const -> std::optional<Symbol> = 0;
141 [[nodiscard]] virtual auto do_rename(SymbolStore &store, RenameMode mode, String const *name, size_t *vars) const
142 -> UTerm = 0;
143 [[nodiscard]] virtual auto do_rename(Util::unordered_map<size_t, size_t> &vars) const -> UTerm = 0;
144 virtual void do_vars(VariableSet &vars, bool provide) const = 0;
145 virtual void do_print(std::ostream &out) const = 0;
146 [[nodiscard]] virtual auto do_copy() const -> UTerm = 0;
147 [[nodiscard]] virtual auto do_hash() const -> size_t = 0;
148 [[nodiscard]] virtual auto do_equal_to(Term const &other) const -> bool = 0;
149 [[nodiscard]] virtual auto do_compare_to(Term const &other) const -> std::strong_ordering = 0;
150};
151
153class TermProjection : public Term {
154 public:
156 TermProjection() = default;
157
158 private:
159 [[nodiscard]] auto do_score(double size, std::vector<bool> const &bound) const -> double override;
160 [[nodiscard]] auto do_match(EvalContext const &ctx, Symbol sym) const -> bool override;
161 [[nodiscard]] auto do_eval(EvalContext const &ctx) const -> std::optional<Symbol> override;
162 [[nodiscard]] auto do_rename(SymbolStore &store, RenameMode mode, String const *name, size_t *vars) const
163 -> UTerm override;
164 [[nodiscard]] auto do_rename(Util::unordered_map<size_t, size_t> &vars) const -> UTerm override;
165 void do_vars(VariableSet &vars, bool provide) const override;
166 void do_print(std::ostream &out) const override;
167 [[nodiscard]] auto do_copy() const -> UTerm override;
168 [[nodiscard]] auto do_hash() const -> size_t override;
169 [[nodiscard]] auto do_equal_to(Term const &other) const -> bool override;
170 [[nodiscard]] auto do_compare_to(Term const &other) const -> std::strong_ordering override;
171};
172
174class TermSymbol : public Term {
175 public:
177 TermSymbol(Symbol sym) : sym_{sym} {}
178
180 [[nodiscard]] auto symbol() const -> Symbol const & { return *sym_; }
181
182 private:
183 [[nodiscard]] auto do_score(double size, std::vector<bool> const &bound) const -> double override;
184 [[nodiscard]] auto do_match(EvalContext const &ctx, Symbol sym) const -> bool override;
185 [[nodiscard]] auto do_eval(EvalContext const &ctx) const -> std::optional<Symbol> override;
186 [[nodiscard]] auto do_rename(SymbolStore &store, RenameMode mode, String const *name, size_t *vars) const
187 -> UTerm override;
188 [[nodiscard]] auto do_rename(Util::unordered_map<size_t, size_t> &vars) const -> UTerm override;
189 void do_vars(VariableSet &vars, bool provide) const override;
190 void do_print(std::ostream &out) const override;
191 [[nodiscard]] auto do_copy() const -> UTerm override;
192 [[nodiscard]] auto do_hash() const -> size_t override;
193 [[nodiscard]] auto do_equal_to(Term const &other) const -> bool override;
194 [[nodiscard]] auto do_compare_to(Term const &other) const -> std::strong_ordering override;
195
196 SharedSymbol sym_;
197};
198
202using FormatField = std::variant<SharedString, std::pair<UTerm, FormatSpec>>;
204using FormatFieldVec = std::vector<FormatField>;
205
207class TermFormatString : public Term {
208 public:
210 TermFormatString(FormatFieldVec elems) : elems_{std::move(elems)} {}
211
212 private:
213 [[nodiscard]] auto do_score(double size, std::vector<bool> const &bound) const -> double override;
214 [[nodiscard]] auto do_match(EvalContext const &ctx, Symbol sym) const -> bool override;
215 [[nodiscard]] auto do_eval(EvalContext const &ctx) const -> std::optional<Symbol> override;
216 [[nodiscard]] auto do_rename(SymbolStore &store, RenameMode mode, String const *name, size_t *vars) const
217 -> UTerm override;
218 [[nodiscard]] auto do_rename(Util::unordered_map<size_t, size_t> &vars) const -> UTerm override;
219 void do_vars(VariableSet &vars, bool provide) const override;
220 void do_print(std::ostream &out) const override;
221 [[nodiscard]] auto do_copy() const -> UTerm override;
222 [[nodiscard]] auto do_hash() const -> size_t override;
223 [[nodiscard]] auto do_equal_to(Term const &other) const -> bool override;
224 [[nodiscard]] auto do_compare_to(Term const &other) const -> std::strong_ordering override;
225
226 FormatFieldVec elems_;
227 mutable Util::OutputBuffer buf_;
228 mutable Util::OutputBuffer tmp_;
229};
230
232class TermVariable : public Term {
233 public:
235 TermVariable(size_t var) : var_{var} {}
236
237 private:
238 [[nodiscard]] auto do_score(double size, std::vector<bool> const &bound) const -> double override;
239 [[nodiscard]] auto do_match(EvalContext const &ctx, Symbol sym) const -> bool override;
240 [[nodiscard]] auto do_eval(EvalContext const &ctx) const -> std::optional<Symbol> override;
241 [[nodiscard]] auto do_rename(SymbolStore &store, RenameMode mode, String const *name, size_t *vars) const
242 -> UTerm override;
243 [[nodiscard]] auto do_rename(Util::unordered_map<size_t, size_t> &vars) const -> UTerm override;
244 void do_vars(VariableSet &vars, bool provide) const override;
245 void do_print(std::ostream &out) const override;
246 [[nodiscard]] auto do_copy() const -> UTerm override;
247 [[nodiscard]] auto do_hash() const -> size_t override;
248 [[nodiscard]] auto do_equal_to(Term const &other) const -> bool override;
249 [[nodiscard]] auto do_compare_to(Term const &other) const -> std::strong_ordering override;
250
251 size_t var_;
252};
253
255class TermLinear : public Term {
256 public:
258 TermLinear(Location loc, Number m, size_t var, Number n)
259 : loc_{std::move(loc)}, m_{std::move(m)}, n_{std::move(n)}, var_{var} {}
260
261 private:
262 [[nodiscard]] auto do_score(double size, std::vector<bool> const &bound) const -> double override;
263 [[nodiscard]] auto do_match(EvalContext const &ctx, Symbol sym) const -> bool override;
264 [[nodiscard]] auto do_eval(EvalContext const &ctx) const -> std::optional<Symbol> override;
265 [[nodiscard]] auto do_rename(SymbolStore &store, RenameMode mode, String const *name, size_t *vars) const
266 -> UTerm override;
267 [[nodiscard]] auto do_rename(Util::unordered_map<size_t, size_t> &vars) const -> UTerm override;
268 void do_vars(VariableSet &vars, bool provide) const override;
269 void do_print(std::ostream &out) const override;
270 [[nodiscard]] auto do_copy() const -> UTerm override;
271 [[nodiscard]] auto do_hash() const -> size_t override;
272 [[nodiscard]] auto do_equal_to(Term const &other) const -> bool override;
273 [[nodiscard]] auto do_compare_to(Term const &other) const -> std::strong_ordering override;
274
275 Location loc_;
276 Number m_;
277 Number n_;
278 size_t var_;
279 mutable bool logged_ = false;
280};
281
283enum class UnaryOperator : uint8_t {
284 minus = 0,
285 negate = 1,
286 abs = 2,
287};
288
290class TermUnary : public Term {
291 public:
294 : loc_rhs_{std::move(loc_rhs)}, rhs_{std::move(rhs)}, op_{op} {}
295
296 private:
297 [[nodiscard]] auto do_score(double size, std::vector<bool> const &bound) const -> double override;
298 [[nodiscard]] auto do_match(EvalContext const &ctx, Symbol sym) const -> bool override;
299 [[nodiscard]] auto do_eval(EvalContext const &ctx) const -> std::optional<Symbol> override;
300 [[nodiscard]] auto do_rename(SymbolStore &store, RenameMode mode, String const *name, size_t *vars) const
301 -> UTerm override;
302 [[nodiscard]] auto do_rename(Util::unordered_map<size_t, size_t> &vars) const -> UTerm override;
303 void do_vars(VariableSet &vars, bool provide) const override;
304 void do_print(std::ostream &out) const override;
305 [[nodiscard]] auto do_copy() const -> UTerm override;
306 [[nodiscard]] auto do_hash() const -> size_t override;
307 [[nodiscard]] auto do_equal_to(Term const &other) const -> bool override;
308 [[nodiscard]] auto do_compare_to(Term const &other) const -> std::strong_ordering override;
309
310 Location loc_rhs_;
311 UTerm rhs_;
312 UnaryOperator op_;
313 mutable bool logged_ = false;
314};
315
317enum class BinaryOperator : uint8_t {
318 and_,
319 div,
320 minus,
321 mod,
322 times,
323 or_,
324 plus,
325 pow,
326 xor_,
327};
328
330class TermBinary : public Term {
331 public:
333 TermBinary(Location loc_lhs, UTerm lhs, BinaryOperator op, Location loc_rhs, UTerm rhs)
334 : loc_lhs_{std::move(loc_lhs)}, loc_rhs_{std::move(loc_rhs)}, lhs_{std::move(lhs)}, rhs_{std::move(rhs)},
335 op_{op} {}
336
337 private:
338 [[nodiscard]] auto do_score(double size, std::vector<bool> const &bound) const -> double override;
339 [[nodiscard]] auto do_match(EvalContext const &ctx, Symbol sym) const -> bool override;
340 [[nodiscard]] auto do_eval(EvalContext const &ctx) const -> std::optional<Symbol> override;
341 [[nodiscard]] auto do_rename(SymbolStore &store, RenameMode mode, String const *name, size_t *vars) const
342 -> UTerm override;
343 [[nodiscard]] auto do_rename(Util::unordered_map<size_t, size_t> &vars) const -> UTerm override;
344 void do_vars(VariableSet &vars, bool provide) const override;
345 void do_print(std::ostream &out) const override;
346 [[nodiscard]] auto do_copy() const -> UTerm override;
347 [[nodiscard]] auto do_hash() const -> size_t override;
348 [[nodiscard]] auto do_equal_to(Term const &other) const -> bool override;
349 [[nodiscard]] auto do_compare_to(Term const &other) const -> std::strong_ordering override;
350
351 Location loc_lhs_;
352 Location loc_rhs_;
353 UTerm lhs_;
354 UTerm rhs_;
355 BinaryOperator op_;
356 mutable bool logged_ = false;
357};
358
360class TermTuple : public Term {
361 public:
363 TermTuple(UTermVec args) : args_{std::move(args)} { eval_.reserve(args_.size()); }
364
365 private:
366 [[nodiscard]] auto do_score(double size, std::vector<bool> const &bound) const -> double override;
367 [[nodiscard]] auto do_match(EvalContext const &ctx, Symbol sym) const -> bool override;
368 [[nodiscard]] auto do_eval(EvalContext const &ctx) const -> std::optional<Symbol> override;
369 [[nodiscard]] auto do_rename(SymbolStore &store, RenameMode mode, String const *name, size_t *vars) const
370 -> UTerm override;
371 [[nodiscard]] auto do_rename(Util::unordered_map<size_t, size_t> &vars) const -> UTerm override;
372 void do_vars(VariableSet &vars, bool provide) const override;
373 void do_print(std::ostream &out) const override;
374 [[nodiscard]] auto do_copy() const -> UTerm override;
375 [[nodiscard]] auto do_hash() const -> size_t override;
376 [[nodiscard]] auto do_equal_to(Term const &other) const -> bool override;
377 [[nodiscard]] auto do_compare_to(Term const &other) const -> std::strong_ordering override;
378
379 UTermVec args_;
380 std::vector<Symbol> mutable eval_;
381};
382
384class TermFunction : public Term {
385 public:
387 TermFunction(String name, UTermVec args) : name_{name}, args_{std::move(args)} { eval_.reserve(args_.size()); }
388
389 private:
390 [[nodiscard]] auto do_score(double size, std::vector<bool> const &bound) const -> double override;
391 [[nodiscard]] auto do_match(EvalContext const &ctx, Symbol sym) const -> bool override;
392 [[nodiscard]] auto do_eval(EvalContext const &ctx) const -> std::optional<Symbol> override;
393 [[nodiscard]] auto do_rename(SymbolStore &store, RenameMode mode, String const *name, size_t *vars) const
394 -> UTerm override;
395 [[nodiscard]] auto do_rename(Util::unordered_map<size_t, size_t> &vars) const -> UTerm override;
396 void do_vars(VariableSet &vars, bool provide) const override;
397 void do_print(std::ostream &out) const override;
398 [[nodiscard]] auto do_copy() const -> UTerm override;
399 [[nodiscard]] auto do_hash() const -> size_t override;
400 [[nodiscard]] auto do_equal_to(Term const &other) const -> bool override;
401 [[nodiscard]] auto do_compare_to(Term const &other) const -> std::strong_ordering override;
402
403 SharedString name_;
404 UTermVec args_;
405 std::vector<Symbol> mutable eval_;
406};
407
409template <class... T>
410inline auto expect(EvalContext const &ctx, Location const &loc, bool &logged, T &&...args) -> bool {
411 if (!logged && ctx.log().check(MessageCode::info_operation_undefined)) {
412 logged = true;
413 (CppClingo::Report(ctx.log(), MessageCode::info_operation_undefined, loc).out()
414 << ... << std::forward<T>(args));
415 }
416 return false;
417}
418
420
421} // namespace CppClingo::Ground
Context object to capture state used during instantiation.
Definition instantiator.hh:39
A term capturing a binary term.
Definition term.hh:330
TermBinary(Location loc_lhs, UTerm lhs, BinaryOperator op, Location loc_rhs, UTerm rhs)
Construct the term.
Definition term.hh:333
A term capturing a symbol.
Definition term.hh:207
TermFormatString(FormatFieldVec elems)
Construct the term.
Definition term.hh:210
A term capturing a tuple.
Definition term.hh:384
TermFunction(String name, UTermVec args)
Construct the term.
Definition term.hh:387
A term capturing a linear term.
Definition term.hh:255
TermLinear(Location loc, Number m, size_t var, Number n)
Construct the term.
Definition term.hh:258
A term capturing a projection.
Definition term.hh:153
TermProjection()=default
Construct the term.
A term capturing a symbol.
Definition term.hh:174
auto symbol() const -> Symbol const &
Get the symbol of the term.
Definition term.hh:180
TermSymbol(Symbol sym)
Construct the term.
Definition term.hh:177
A term capturing a tuple.
Definition term.hh:360
TermTuple(UTermVec args)
Construct the term.
Definition term.hh:363
A term capturing a unary term.
Definition term.hh:290
TermUnary(UnaryOperator op, Location loc_rhs, UTerm rhs)
Construct the term.
Definition term.hh:293
A term capturing a variable.
Definition term.hh:232
TermVariable(size_t var)
Construct the term.
Definition term.hh:235
Term interface.
Definition term.hh:68
auto score(double size, std::vector< bool > const &bound) const -> double
Compute an estimate how often the term can match size symbols given the bound variables.
Definition term.hh:76
auto signature(VariableSet const &bound, VariableSet const &bind) const -> std::pair< UTerm, VariableVec >
Compute a signature of the term.
Definition term.hh:108
auto eval(EvalContext const &ctx) const -> std::optional< Symbol >
Evaluates a term w.r.t.
Definition term.hh:87
friend auto operator<<(std::ostream &out, Term const &term) -> std::ostream &
Print the term.
Definition term.hh:132
auto copy() const -> UTerm
Create a copy of the term.
Definition term.hh:100
auto vars() const -> VariableSet
Collect all variables in the term.
Definition term.hh:121
virtual ~Term()=default
Destructor.
auto match(EvalContext const &ctx, Symbol sym) const -> bool
Match a term with the given symbol.
Definition term.hh:83
auto rename(SymbolStore &store, RenameMode mode, String const *name, size_t *vars) const -> UTerm
Create a copy of the term renaming/replacing parts of it.
Definition term.hh:92
void vars(VariableSet &vars, bool provide=false) const
Collect all variables in the term.
Definition term.hh:98
friend auto operator==(Term const &a, Term const &b) -> bool
Compare two terms.
Definition term.hh:128
auto hash() const -> size_t
Compute a hash for the term.
Definition term.hh:102
auto rename(Util::unordered_map< size_t, size_t > &vars) const -> UTerm
Create a copy of the term renaming variables in order of occurrence.
Definition term.hh:96
friend auto operator<=>(Term const &a, Term const &b) -> std::strong_ordering
Compare two terms.
Definition term.hh:130
The Location of an expression in an input source.
Definition location.hh:44
An arbitrary precision integer.
Definition number.hh:27
Helper class to ease logging.
Definition logger.hh:106
auto out() -> std::ostringstream &
Get message sink.
Definition logger.hh:117
Class managing the lifetime of a String.
Definition symbol.hh:93
Class managing the lifetime of a Symbol.
Definition symbol.hh:306
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
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
@ provide
Get variables provided by a literal.
std::vector< FormatField > FormatFieldVec
A vector of format fields.
Definition term.hh:204
auto copy_uvec(std::vector< std::unique_ptr< T > > const &vec)
Helper to copy vectors with copyable elements.
Definition term.hh:45
std::vector< std::pair< Relation, UTerm > > GuardVec
A vector of guards.
Definition term.hh:38
BinaryOperator
Available binary operations.
Definition term.hh:317
std::unique_ptr< Term > UTerm
A unique pointer holding a term.
Definition term.hh:34
UnaryOperator
Available unary operations.
Definition term.hh:283
std::variant< SharedString, std::pair< UTerm, FormatSpec > > FormatField
A format specification.
Definition term.hh:202
RenameMode
Modes determining how to handle variables in terms.
Definition term.hh:26
std::vector< UTerm > UTermVec
A vector of terms.
Definition term.hh:36
@ negate
The bitwise negation operation.
@ minus
The unary arithmetic minus operation.
@ abs
The arithmetic absolute operation.
@ rename_vars
Successively rename variables in order of traversal.
@ drop_projection
Drop projections from tuples and functions.
@ rename_projection
Successively introduce variables for projections in order of traversal.
tsl::hopscotch_map< Key, T, Hash, KeyEqual, Allocator, NeighborhoodSize, StoreHash, GrowthPolicy > unordered_map
Alias for unordered maps.
Definition unordered_map.hh:17
Format specification for a field.
Definition fstring.hh:14