6
6
#include < numeric>
7
7
#include < optional>
8
8
#include < limits>
9
+ #include < functional>
9
10
#include < cassert>
10
11
#include < iostream>
11
12
#include < memory>
@@ -98,7 +99,11 @@ static bool bind(const GROUND_TYPE &fact, tuple<Ts...> &atom)
98
99
template <typename T>
99
100
static void ground (const Variable<T>* s, T &v)
100
101
{
101
- assert (s->isBound ());
102
+ // TODO: restrict to debug builds only
103
+ if (!s->isBound ()) {
104
+ cerr << " ERROR: unbound variable (" << s << " )" << endl;
105
+ exit (EXIT_FAILURE);
106
+ }
102
107
v = s->value ();
103
108
}
104
109
@@ -136,13 +141,13 @@ struct AtomTypeSpecifier {
136
141
};
137
142
138
143
template <typename ... Ts>
139
- static tuple<Ts...> atom (Ts&&... args) {
144
+ static tuple<Ts...> atomImpl (Ts&&... args) {
140
145
return tuple<Ts...>{args...};
141
146
}
142
147
143
148
template <typename RELATION_TYPE, typename ... Us>
144
149
static AtomTypeSpecifier<RELATION_TYPE, Us...> atom (Us&&... args) {
145
- return AtomTypeSpecifier<RELATION_TYPE, Us...>{atom (args...)};
150
+ return AtomTypeSpecifier<RELATION_TYPE, Us...>{atomImpl (args...)};
146
151
}
147
152
148
153
template <typename ... Ts>
@@ -173,17 +178,42 @@ struct Rule
173
178
typedef tuple<const typename BODY_RELATIONs::TrackedGround *...> SliceType;
174
179
};
175
180
181
+ template <typename HEAD_ATOM_SPECIFIER, typename ... BODY_ATOM_SPECIFIERs>
182
+ struct RuleInstance ;
183
+
184
+ template <typename EXTERNALS_TYPE, typename HEAD_ATOM_SPECIFIER, typename ... BODY_ATOM_SPECIFIERs>
185
+ struct ExternalRuleInstance ;
186
+
187
+ template <typename ... EXTERNAL_TYPEs>
188
+ struct Externals {
189
+ tuple<const EXTERNAL_TYPEs&...> externals;
190
+ };
191
+
176
192
template <typename HEAD_ATOM_SPECIFIER, typename ... BODY_ATOM_SPECIFIERs>
177
193
struct RuleInstance {
178
194
typedef Rule<typename HEAD_ATOM_SPECIFIER::RelationType, typename BODY_ATOM_SPECIFIERs::RelationType...> RuleType;
179
195
typedef typename HEAD_ATOM_SPECIFIER::AtomType HeadType;
180
196
HeadType head;
181
197
typedef tuple<typename BODY_ATOM_SPECIFIERs::AtomType...> BodyType;
182
198
BodyType body;
199
+
200
+ template <typename ... EXTERNAL_TYPEs>
201
+ ExternalRuleInstance<Externals<EXTERNAL_TYPEs...>, HEAD_ATOM_SPECIFIER, BODY_ATOM_SPECIFIERs...> externals (
202
+ const EXTERNAL_TYPEs&... externals
203
+ ) {
204
+ typedef ExternalRuleInstance<Externals<EXTERNAL_TYPEs...>, HEAD_ATOM_SPECIFIER, BODY_ATOM_SPECIFIERs...> RuleInstanceType;
205
+ return RuleInstanceType{head, body, Externals<EXTERNAL_TYPEs...>{externals...}};
206
+ }
207
+
208
+ };
209
+
210
+ template <typename EXTERNALS_TYPE, typename HEAD_ATOM_SPECIFIER, typename ... BODY_ATOM_SPECIFIERs>
211
+ struct ExternalRuleInstance : RuleInstance<HEAD_ATOM_SPECIFIER, BODY_ATOM_SPECIFIERs...> {
212
+ const EXTERNALS_TYPE& externals;
183
213
};
184
214
185
215
template <typename HEAD_ATOM_SPECIFIER, typename ... BODY_ATOM_SPECIFIERs>
186
- RuleInstance<HEAD_ATOM_SPECIFIER, BODY_ATOM_SPECIFIERs...> rule (
216
+ static RuleInstance<HEAD_ATOM_SPECIFIER, BODY_ATOM_SPECIFIERs...> rule (
187
217
const HEAD_ATOM_SPECIFIER& h,
188
218
const BODY_ATOM_SPECIFIERs&... b
189
219
) {
@@ -193,6 +223,28 @@ RuleInstance<HEAD_ATOM_SPECIFIER, BODY_ATOM_SPECIFIERs...> rule(
193
223
return RuleInstanceType{head, body};
194
224
}
195
225
226
+ // Rules with external functions
227
+
228
+ template <typename T, typename ... ATOM_TYPE_SPECIFIERs>
229
+ struct ExternalFunction {
230
+ Variable<T>& bindVariable;
231
+ typedef tuple<const ATOM_TYPE_SPECIFIERs&...> AtomsTupleType;
232
+ AtomsTupleType boundAtoms;
233
+ typedef tuple<const typename ATOM_TYPE_SPECIFIERs::RelationType::Ground&...> ArgsType;
234
+ function<T(const ArgsType&)> externalFunction;
235
+ };
236
+
237
+ template <typename T, typename ... ATOM_TYPE_SPECIFIERs>
238
+ static ExternalFunction<T, ATOM_TYPE_SPECIFIERs...> external (
239
+ unique_ptr<Variable<T>>& bindVariable,
240
+ function<T(const typename ExternalFunction<T, ATOM_TYPE_SPECIFIERs...>::ArgsType&)> externalFunction,
241
+ const ATOM_TYPE_SPECIFIERs&... boundAtoms
242
+ ) {
243
+ return ExternalFunction<T, ATOM_TYPE_SPECIFIERs...> {
244
+ *bindVariable, {boundAtoms...}, externalFunction
245
+ };
246
+ }
247
+
196
248
template <typename RELATION_TYPE>
197
249
static ostream& operator <<(ostream& out, const typename RELATION_TYPE::Ground& t) {
198
250
out << " [" ;
@@ -480,7 +532,6 @@ static bool bindBodyAtomsToSlice(typename RULE_INSTANCE_TYPE::BodyType &atoms,
480
532
// get the atom
481
533
auto &atom = get<I>(atoms);
482
534
// try to bind the atom with the fact
483
- // success = bind(fact.second, atom);
484
535
success = bind (fact.second , atom);
485
536
}
486
537
return success;
0 commit comments