Clingo
Loading...
Searching...
No Matches
instantiator.hh
1#pragma once
2
3#include <clingo/core/logger.hh>
4#include <clingo/core/output.hh>
5#include <clingo/core/symbol.hh>
6
7#include <memory>
8#include <utility>
9#include <vector>
10
11namespace CppClingo::Ground {
12
15
18 public:
22 [[nodiscard]] auto log() const -> Logger & { return *log_; }
24 [[nodiscard]] auto store() const -> SymbolStore & { return *store_; }
26 [[nodiscard]] auto out() const -> OutputStm & { return *out_; }
27
28 private:
29 Logger *log_;
30 SymbolStore *store_;
31 OutputStm *out_;
32};
33
36 public:
41 [[nodiscard]] auto ass() const -> Assignment & { return *ass_; }
42
43 private:
44 Assignment *ass_;
45};
46
48enum class MatcherType : uint8_t {
49 new_atoms,
50 old_atoms,
52};
53
55inline auto operator<<(std::ostream &out, MatcherType type) -> std::ostream & {
56 switch (type) {
58 out << "a";
59 break;
60 }
62 out << "o";
63 break;
64 }
65 case MatcherType::new_atoms: {
66 out << "n";
67 break;
68 }
69 }
70 return out;
71}
72
74class Matcher {
75 public:
77 virtual ~Matcher() = default;
79 void init(InstantiationContext const &ctx, size_t gen) { do_init(ctx, gen); }
81 void match(EvalContext const &ctx) { do_match(ctx); }
86 [[nodiscard]] auto next(EvalContext const &ctx) -> bool { return do_next(ctx); }
88 void print(std::ostream &out) const { do_print(out); }
90 [[nodiscard]] auto type() const -> MatcherType { return do_type(); }
91
92 private:
93 virtual void do_init(InstantiationContext const &ctx, size_t gen) = 0;
94 virtual void do_match(EvalContext const &ctx) = 0;
95 [[nodiscard]] virtual auto do_next(EvalContext const &ctx) -> bool = 0;
96 virtual void do_print(std::ostream &out) const = 0;
97 [[nodiscard]] virtual auto do_type() const -> MatcherType { return MatcherType::all_atoms; }
98};
100using UMatcher = std::unique_ptr<Matcher>;
102using UMatcherVec = std::vector<UMatcher>;
103
104class Queue;
105
108 public:
110 virtual ~InstanceCallback() = default;
112 void init(size_t gen) { do_init(gen); }
114 [[nodiscard]] auto report(EvalContext const &ctx) -> bool { return do_report(ctx); }
116 void propagate(SymbolStore &store, OutputStm &out, Queue &queue) { do_propagate(store, out, queue); }
118 [[nodiscard]] auto priority() const -> size_t { return do_priority(); }
120 void print_head(std::ostream &out) const { do_print_head(out); }
122 [[nodiscard]] auto is_important(size_t index) const -> bool { return do_is_important(index); }
123
124 private:
125 virtual void do_init(size_t gen) = 0;
126 [[nodiscard]] virtual auto do_report(EvalContext const &ctx) -> bool = 0;
127 virtual void do_propagate(SymbolStore &store, OutputStm &out, Queue &queue) = 0;
128 [[nodiscard]] virtual auto do_priority() const -> size_t = 0;
129 virtual void do_print_head(std::ostream &out) const = 0;
130 [[nodiscard]] virtual auto do_is_important([[maybe_unused]] size_t index) const -> bool { return true; }
131};
132
135 public:
137 using DependVec = std::vector<size_t>;
139 Instantiator(InstanceCallback &icb, size_t vars, size_t n) : icb_{&icb}, ass_{vars} { matchers_.reserve(n + 1); }
143 void init(InstantiationContext const &ctx, size_t gen);
149 void add(UMatcher matcher, DependVec depends);
154 void finalize(DependVec depends);
159 [[nodiscard]] auto enqueue() -> bool;
163 [[nodiscard]] auto instantiate(Logger &log, SymbolStore &store, OutputStm &out) -> bool;
165 void propagate(SymbolStore &store, OutputStm &out, Queue &queue);
167 void print(std::ostream &out) const;
169 [[nodiscard]] auto priority() const { return icb_->priority(); }
170
172 friend auto operator<<(std::ostream &out, Instantiator const &inst) -> std::ostream & {
173 inst.print(out);
174 return out;
175 }
176
177 private:
178 class BackjumpMatcher {
179 public:
180 BackjumpMatcher(UMatcher matcher, DependVec depend)
181 : matcher_{std::move(matcher)}, depend_{std::move(depend)} {}
182 void init(InstantiationContext const &ctx, size_t gen);
183 void match(EvalContext const &ctx);
184 auto next(EvalContext const &ctx) -> bool;
185 auto first(EvalContext const &ctx) -> bool;
186 void print(std::ostream &out, size_t index) const;
187 [[nodiscard]] auto depend() const -> DependVec const &;
188 [[nodiscard]] auto backjumpable() const -> bool;
189 void block();
190
191 private:
192 UMatcher matcher_;
193 std::vector<size_t> depend_;
194 bool backjumpable_ = true;
195 };
196 InstanceCallback *icb_;
197 Assignment ass_;
198 std::vector<BackjumpMatcher> matchers_;
199 bool enqueued_ = false;
200};
201
203using InstantiatorVec = std::vector<Instantiator>;
204
206class Queue {
207 public:
209 Queue() = default;
211 void insert(Instantiator inst, std::optional<size_t> index);
213 void propagate(size_t index);
215 [[nodiscard]] auto process(Logger &log, SymbolStore &store, OutputStm &out) -> bool;
217 auto release() -> std::vector<Instantiator> { return std::move(insts_); }
218
219 private:
221 void enter_(size_t i);
222
223 std::vector<Instantiator> insts_;
224 std::vector<std::vector<size_t>> update_;
225 std::vector<std::vector<Instantiator *>> queues_;
226 size_t size_ = 0;
227 size_t max_prio_ = 0;
228};
229
231
232} // namespace CppClingo::Ground
Context object to capture state used during instantiation.
Definition instantiator.hh:35
EvalContext(Logger &log, SymbolStore &store, OutputStm &out, Assignment &ass)
Construct an instantiation state.
Definition instantiator.hh:38
auto ass() const -> Assignment &
Get the assignment.
Definition instantiator.hh:41
Callbacks to notify statements during instantiations.
Definition instantiator.hh:107
auto report(EvalContext const &ctx) -> bool
Report an assignment giving rise to an instance for a statement.
Definition instantiator.hh:114
void propagate(SymbolStore &store, OutputStm &out, Queue &queue)
Notify a statement that instantiation has finished.
Definition instantiator.hh:116
void init(size_t gen)
Notify a statement that instantiation starts.
Definition instantiator.hh:112
auto priority() const -> size_t
The priority of the callback.
Definition instantiator.hh:118
void print_head(std::ostream &out) const
Print representation for debugging.
Definition instantiator.hh:120
auto is_important(size_t index) const -> bool
Check if the literal with the given index is important.
Definition instantiator.hh:122
virtual ~InstanceCallback()=default
Destroy the callback.
Context object to capture state used during instantiation.
Definition instantiator.hh:17
auto out() const -> OutputStm &
Get the output.
Definition instantiator.hh:26
InstantiationContext(Logger &log, SymbolStore &store, OutputStm &out)
Construct an instantiation state.
Definition instantiator.hh:20
auto store() const -> SymbolStore &
Get the store.
Definition instantiator.hh:24
auto log() const -> Logger &
Get the logger.
Definition instantiator.hh:22
An instantiator implementing the basic grounding algorithm.
Definition instantiator.hh:134
std::vector< size_t > DependVec
A vector of Matcher indices.
Definition instantiator.hh:137
void print(std::ostream &out) const
Print the instantiator.
void propagate(SymbolStore &store, OutputStm &out, Queue &queue)
Add instantiators that need grounding to queue.
friend auto operator<<(std::ostream &out, Instantiator const &inst) -> std::ostream &
Print the instantiator.
Definition instantiator.hh:172
auto priority() const
The priority of the instantiator.
Definition instantiator.hh:169
void add(UMatcher matcher, DependVec depends)
Finalize the instantiator.
auto instantiate(Logger &log, SymbolStore &store, OutputStm &out) -> bool
Find all assignments for the added matchers.
auto enqueue() -> bool
Mark enqueued for instantiation.
Instantiator(InstanceCallback &icb, size_t vars, size_t n)
Construct an instantiator with the given instance callback and number of variables.
Definition instantiator.hh:139
void finalize(DependVec depends)
Finalize the instantiator.
void init(InstantiationContext const &ctx, size_t gen)
Prepare the instantiator for the first grounding step (with generation 0).
A matcher to match expressions.
Definition instantiator.hh:74
void match(EvalContext const &ctx)
Initialize matching.
Definition instantiator.hh:81
virtual ~Matcher()=default
Destroy the matcher.
auto type() const -> MatcherType
Get the type of the matcher.
Definition instantiator.hh:90
void print(std::ostream &out) const
Print the matcher to the given stream.
Definition instantiator.hh:88
void init(InstantiationContext const &ctx, size_t gen)
Notify that instantiation starts.
Definition instantiator.hh:79
auto next(EvalContext const &ctx) -> bool
Obtain the next match.
Definition instantiator.hh:86
A queue to process instantiators.
Definition instantiator.hh:206
Queue()=default
Construct an empty queue.
auto process(Logger &log, SymbolStore &store, OutputStm &out) -> bool
Process previously enqueued instantiators.
auto release() -> std::vector< Instantiator >
Release the contained instantiators.
Definition instantiator.hh:217
void propagate(size_t index)
Propagate instantiators with the given index.
void insert(Instantiator inst, std::optional< size_t > index)
Register an instantiator with the queue.
Simple logger to report message to stderr or via a callback.
Definition logger.hh:63
Interface to output statements.
Definition output.hh:90
A store for symbols.
Definition symbol.hh:454
std::vector< std::optional< Symbol > > Assignment
Assignment mapping variables to symbols.
Definition symbol.hh:222
auto operator<<(std::ostream &out, LitCondLitType type) -> std::ostream &
Print the type of a conditional literal grounding literal.
std::vector< UMatcher > UMatcherVec
A vector of matchers.
Definition instantiator.hh:102
std::vector< Instantiator > InstantiatorVec
A vector of instantiators.
Definition instantiator.hh:203
MatcherType
Enumeration of matcher types.
Definition instantiator.hh:48
std::unique_ptr< Matcher > UMatcher
A unique pointer to a matcher.
Definition instantiator.hh:100
@ all_atoms
Indicates a matcher for previously added atoms.
@ old_atoms
Indicates a matcher for freshly added atoms.
@ depend
Get variables a literal depends on.