@@ -171,6 +171,7 @@ struct Rule {
171
171
const BodyType body;
172
172
};
173
173
174
+ // N.B. Assume no repeats in RELATIONs
174
175
template <typename ... RELATIONs>
175
176
struct State {
176
177
typedef tuple<RELATIONs...> RelationsType;
@@ -183,78 +184,90 @@ struct State {
183
184
}
184
185
185
186
struct Iterator {
186
- Iterator (const RelationsType& relations) : sizes(relationSizes(relations)) {
187
+ Iterator (const RelationsType& relations) :
188
+ iterators (initIterators(relations)) {
187
189
}
188
190
189
191
bool hasNext (const State& state) const {
190
192
return not iterationFinished;
191
193
}
192
194
193
- template <typename RELATION_TYPE>
195
+ template <size_t I, typename RELATION_TYPE>
194
196
void pick (
195
197
const RELATION_TYPE& relation,
196
- typename RELATION_TYPE::GroundType const *& sliceElement,
197
- unsigned int relationIndex
198
+ typename RELATION_TYPE::GroundType const *& sliceElement
198
199
) {
199
- // cout << "pick relation " << relationIndex << " with " << index[relationIndex] << endl;
200
- // TODO: inefficient
201
- sliceElement = &*std::next (relation.tuples .begin (), index[relationIndex]);
200
+ sliceElement = &*get<I>(iterators);
202
201
}
203
202
204
203
template <size_t ... Is>
205
204
void pick (const RelationsType& relations, SliceType& slice, index_sequence<Is...>) {
206
205
// cout << "[" << endl;
207
- ((pick (get<Is>(relations), get<Is>(slice), Is )), ...);
206
+ ((pick<Is> (get<Is>(relations), get<Is>(slice))), ...);
208
207
// cout << "]" << endl;
209
208
}
210
209
211
- // Returns true if no more combinations of facts to iterate over
212
- bool next (size_t masterIndex, bool exhausted) {
213
- if (masterIndex >= tuple_size<RelationsType>::value) {
214
- // no more relations
215
- return exhausted and true ;
216
- }
217
- // increase index of this relation
218
- index[masterIndex]++;
219
- // have we exhausted this relation?
220
- if (index[masterIndex] >= sizes[masterIndex]) {
221
- // then reset this relation, and increase index of next relation
222
- index[masterIndex] = 0 ;
223
- return exhausted and next (masterIndex + 1 , exhausted);
210
+ typedef tuple<typename set<typename RELATIONs::GroundType>::const_iterator...> IteratorsArrayType;
211
+
212
+ template <size_t I>
213
+ bool next (
214
+ const RelationsType& relations,
215
+ IteratorsArrayType& iterators,
216
+ bool & stop
217
+ ) {
218
+ bool iterationFinished = false ;
219
+ if (not stop) {
220
+ get<I>(iterators)++;
221
+ if (get<I>(iterators) == get<I>(relations).tuples .end ()) {
222
+ get<I>(iterators) = get<I>(relations).tuples .begin ();
223
+ if (I == tuple_size<RelationsType>::value - 1 ) {
224
+ iterationFinished = true ;
225
+ }
226
+ } else {
227
+ stop = true ;
228
+ }
224
229
}
225
- return false ;
230
+ return iterationFinished;
231
+ }
232
+
233
+ template <size_t ... Is>
234
+ bool next (const RelationsType& relations, IteratorsArrayType& iterators, index_sequence<Is...>) {
235
+ bool stop = false ;
236
+ return ((next<Is>(relations, iterators, stop)) or ...);
226
237
}
227
238
228
239
SliceType next (const State& state) {
229
240
SliceType slice;
230
- pick (state.relations , slice, make_index_sequence<tuple_size<RelationsType>::value> { });
231
- iterationFinished = next (0 , true );
232
- cout << " slice = " ;
233
- print (cout, slice);
234
- cout << endl;
241
+ auto indexSequence = make_index_sequence<tuple_size<RelationsType>::value> { };
242
+ pick (state.relations , slice, indexSequence);
243
+ iterationFinished = next (state.relations , iterators, indexSequence);
244
+ {
245
+ cout << " slice = " ;
246
+ print (cout, slice);
247
+ cout << endl;
248
+ }
235
249
return slice;
236
250
}
237
251
238
252
private:
239
- const array<unsigned int , tuple_size<RelationsType>::value> sizes = {0 };
240
- array<unsigned int , tuple_size<RelationsType>::value> index = {0 };
253
+ IteratorsArrayType iterators;
241
254
bool iterationFinished = false ;
242
255
243
- template <size_t ... Is>
244
- static void relationSizes (
245
- const RelationsType& relations,
246
- array<unsigned int , tuple_size<RelationsType>::value>& sizes,
247
- index_sequence<Is...>
248
- ) {
249
- ((sizes[Is] = get<Is>(relations).tuples .size ()), ...);
256
+ template <typename RELATION_TYPE, typename ITERATOR_TYPE>
257
+ void initIterator (const RELATION_TYPE& relation, ITERATOR_TYPE& iterator) {
258
+ iterator = relation.tuples .begin ();
250
259
}
251
260
252
- static array<unsigned int , tuple_size<RelationsType>::value> relationSizes (const RelationsType& relations) {
253
- array<unsigned int , tuple_size<RelationsType>::value> sizes;
254
- relationSizes (relations, sizes, make_index_sequence<tuple_size<RelationsType>::value> { });
255
- return sizes;
261
+ template <size_t ... Is>
262
+ void initIterators (const RelationsType& relations, IteratorsArrayType& iterators, index_sequence<Is...>) {
263
+ ((initIterator (get<Is>(relations), get<Is>(iterators))), ...);
256
264
}
257
265
266
+ IteratorsArrayType initIterators (const RelationsType& relations) {
267
+ IteratorsArrayType iterators;
268
+ initIterators (relations, iterators, make_index_sequence<tuple_size<IteratorsArrayType>::value> { });
269
+ return iterators;
270
+ }
258
271
};
259
272
260
273
Iterator iterator () const {
@@ -325,4 +338,40 @@ static RELATION_TYPE merge(const RELATION_TYPE& r1, const RELATION_TYPE& r2) {
325
338
326
339
}
327
340
341
+ #if 0
342
+ template<size_t ... Is>
343
+ static void relationSizes(
344
+ const RelationsType& relations,
345
+ RelationsArrayType& sizes,
346
+ index_sequence<Is...>
347
+ ) {
348
+ ((sizes[Is] = get<Is>(relations).tuples.size()), ...);
349
+ }
350
+
351
+ static array<unsigned int, tuple_size<RelationsType>::value> relationSizes(const RelationsType& relations) {
352
+ RelationsArrayType sizes;
353
+ relationSizes(relations, sizes, make_index_sequence<tuple_size<RelationsType>::value> { });
354
+ return sizes;
355
+ }
356
+ #endif
357
+
358
+ #if 0
359
+ // Returns true if no more combinations of facts to iterate over
360
+ bool next(size_t masterIndex, bool exhausted) {
361
+ if (masterIndex >= tuple_size<RelationsType>::value) {
362
+ // no more relations
363
+ return exhausted and true;
364
+ }
365
+ // increase index of this relation
366
+ index[masterIndex]++;
367
+ // have we exhausted this relation?
368
+ if (index[masterIndex] >= sizes[masterIndex]) {
369
+ // then reset this relation, and increase index of next relation
370
+ index[masterIndex] = 0;
371
+ return exhausted and next(masterIndex + 1, exhausted);
372
+ }
373
+ return false;
374
+ }
375
+ #endif
376
+
328
377
#endif /* SRC_DATALOG_H_ */
0 commit comments