8000 WIP: efficient iteration of all fact combinations · Z80coder/datalog-cpp@1a9f0be · GitHub
[go: up one dir, main page]

Skip to content

Commit 1a9f0be

Browse files
author
wright
committed
WIP: efficient iteration of all fact combinations
1 parent 1fab6bd commit 1a9f0be

File tree

1 file changed

+89
-40
lines changed

1 file changed

+89
-40
lines changed

src/Datalog.h

Lines changed: 89 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ struct Rule {
171171
const BodyType body;
172172
};
173173

174+
// N.B. Assume no repeats in RELATIONs
174175
template<typename ... RELATIONs>
175176
struct State {
176177
typedef tuple<RELATIONs...> RelationsType;
@@ -183,78 +184,90 @@ struct State {
183184
}
184185

185186
struct Iterator {
186-
Iterator(const RelationsType& relations) : sizes(relationSizes(relations)) {
187+
Iterator(const RelationsType& relations) :
188+
iterators(initIterators(relations)) {
187189
}
188190

189191
bool hasNext(const State& state) const {
190192
return not iterationFinished;
191193
}
192194

193-
template<typename RELATION_TYPE>
195+
template<size_t I, typename RELATION_TYPE>
194196
void pick(
195197
const RELATION_TYPE& relation,
196-
typename RELATION_TYPE::GroundType const*& sliceElement,
197-
unsigned int relationIndex
198+
typename RELATION_TYPE::GroundType const*& sliceElement
198199
) {
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);
202201
}
203202

204203
template<size_t ... Is>
205204
void pick(const RelationsType& relations, SliceType& slice, index_sequence<Is...>) {
206205
//cout << "[" << endl;
207-
((pick(get<Is>(relations), get<Is>(slice), Is)), ...);
206+
((pick<Is>(get<Is>(relations), get<Is>(slice))), ...);
208207
//cout << "]" << endl;
209208
}
210209

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+
}
224229
}
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 ...);
226237
}
227238

228239
SliceType next(const State& state) {
229240
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+
}
235249
return slice;
236250
}
237251

238252
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;
241254
bool iterationFinished = false;
242255

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();
250259
}
251260

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))), ...);
256264
}
257265

266+
IteratorsArrayType initIterators(const RelationsType& relations) {
267+
IteratorsArrayType iterators;
268+
initIterators(relations, iterators, make_index_sequence<tuple_size<IteratorsArrayType>::value> { });
269+
return iterators;
270+
}
258271
};
259272

260273
Iterator iterator() const {
@@ -325,4 +338,40 @@ static RELATION_TYPE merge(const RELATION_TYPE& r1, const RELATION_TYPE& r2) {
325338

326339
}
327340

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+
328377
#endif /* SRC_DATALOG_H_ */

0 commit comments

Comments
 (0)
0