3
3
4
4
#include < tuple>
5
5
#include < set>
6
+ #include < unordered_set>
6
7
#include < numeric>
7
8
#include < optional>
8
9
#include < limits>
9
10
#include < functional>
10
11
#include < cassert>
11
12
#include < iostream>
12
- #include < memory>
13
+
14
+ #include "
10000
tuple_hash.h"
13
15
14
16
namespace datalog
15
17
{
@@ -41,28 +43,30 @@ struct Variable : optional<T>
41
43
}
42
44
};
43
45
46
+ // TODO: use auto more for return type of functions
47
+
44
48
template <typename T>
45
- T val (unique_ptr< Variable<T>>& var) {
46
- return var-> value ();
49
+ Variable<T>* var ( ) {
50
+ return new Variable<T> ();
47
51
}
48
52
49
53
template <typename T>
50
- unique_ptr< Variable<T>> var ( ) {
51
- return make_unique<Variable<T>> ();
54
+ T val ( Variable<T>* t ) {
55
+ return t-> value ();
52
56
}
53
57
54
- template <typename T>
55
- static void unbind (Variable<T>* t ) {
56
- t-> unbind () ;
58
+ template <typename T>
59
+ void deleteVar (Variable<T>* v ) {
60
+ delete v ;
57
61
}
58
62
59
63
template <typename T>
60
- static void unbind (unique_ptr<Variable<T>>& t) {
61
- unbind (t.get ());
62
- }
64
+ static void unbind (const T& t) {}
63
65
64
66
template <typename T>
65
- static void unbind (const T& t) {}
67
+ static void unbind (Variable<T>* t) {
68
+ t->unbind ();
69
+ }
66
70
67
71
template <typename ... Ts>
68
72
static void unbind (const tuple<Ts...> &tuple)
@@ -84,11 +88,6 @@ static bool bind(const T& a, Variable<T>* b) {
8000
84
88
return true ;
85
89
}
86
90
87
- template <typename T>
88
- static bool bind (const T& a, unique_ptr<Variable<T>>& b) {
89
- return bind (a, b.get ());
90
- }
91
-
92
91
template <typename GROUND_TYPE, typename ... Ts, size_t ... Is>
93
92
static bool bind (const GROUND_TYPE &fact, tuple<Ts...> &atom, index_sequence<Is...>)
94
93
{
@@ -108,12 +107,6 @@ static void ground(const Variable<T>* s, T &v)
108
107
v = s->value ();
109
108
}
110
109
111
- template <typename T>
112
- static void ground (const unique_ptr<Variable<T>>& s, T &v)
113
- {
114
- ground (s.get (), v);
115
- }
116
-
117
110
template <typename T>
118
111
static void ground (const T &s, T &v)
119
112
{
@@ -137,7 +130,6 @@ static typename RELATION_TYPE::Ground ground(const tuple<Ts...> &atom)
137
130
template <typename RELATION_TYPE, typename ... Ts>
138
131
struct AtomTypeSpecifier {
139
132
typedef RELATION_TYPE RelationType;
140
- // TODO: why not references?
141
133
typedef tuple<Ts...> AtomType;
142
134
AtomType atom;
143
135
};
@@ -156,18 +148,34 @@ template <typename... Ts>
156
148
struct Relation
157
149
{
158
150
typedef tuple<Ts...> Ground;
159
- // TODO: this should be an unordered_set
151
+ #if 1
152
+ // set seems faster than unordered_set
160
153
typedef set<Ground> Set;
154
+ #else
155
+ typedef unordered_set<Ground> Set;
156
+ #endif
157
+
161
158
typedef pair<size_t , Ground> TrackedGround;
162
- // TODO: this should be an unordered_set
159
+ # if 0
163
160
struct compare {
164
161
bool operator() (const TrackedGround& lhs, const TrackedGround& rhs) const {
165
162
// ignore tracking number
166
163
return lhs.second < rhs.second;
167
164
}
168
165
};
169
-
170
166
typedef set<TrackedGround, compare> TrackedSet;
167
+ #else
168
+ // unordered set seems faster than set
169
+ struct key_hash : public std ::unary_function<TrackedGround, std::size_t >
170
+ {
171
+ size_t operator ()(const TrackedGround& k) const
172
+ {
173
+ hash<decltype (k.second )> h;
174
+ return k.first ^ h.operator ()(k.second );
175
+ }
176
+ };
177
+ typedef unordered_set<TrackedGround, key_hash> TrackedSet;
178
+ #endif
171
179
172
180
};
173
181
@@ -182,8 +190,6 @@ struct Rule
182
190
183
191
template <typename ... EXTERNAL_TYPEs>
184
192
struct Externals {
185
- // N.B. We need to store the ExternalFunctions
186
- // typedef tuple<const EXTERNAL_TYPEs&...> ExternalsTupleType;
187
193
typedef tuple<const EXTERNAL_TYPEs...> ExternalsTupleType;
188
194
ExternalsTupleType externals;
189
195
};
@@ -193,8 +199,6 @@ struct BodyAtoms {
193
199
tuple<typename BODY_ATOM_SPECIFIERs::AtomType...> body;
194
200
};
195
201
196
- // Note that RuleInstances store atoms (and therefore atoms specified during construction are copied).
197
- // This is OK since all copies of atoms still refer to the same shared variables
198
202
template <typename HEAD_ATOM_SPECIFIER, typename ... BODY_ATOM_SPECIFIERs>
199
203
struct RuleInstance {
200
204
typedef Rule<typename HEAD_ATOM_SPECIFIER::RelationType, typename BODY_ATOM_SPECIFIERs::RelationType...> RuleType;
@@ -204,22 +208,15 @@ struct RuleInstance {
204
208
BodyType body;
205
209
};
206
210
207
- #if 0
208
- template <typename EXTERNALS_TYPE, typename HEAD_ATOM_SPECIFIER, typename... BODY_ATOM_SPECIFIERs>
209
- struct ExternalRuleInstance : RuleInstance<HEAD_ATOM_SPECIFIER, BODY_ATOM_SPECIFIERs...> {
210
- const EXTERNALS_TYPE& externals;
211
- };
212
- #else
213
211
template <typename EXTERNALS_TYPE, typename HEAD_ATOM_SPECIFIER, typename ... BODY_ATOM_SPECIFIERs>
214
212
struct ExternalRuleInstance {
215
213
typedef Rule<typename HEAD_ATOM_SPECIFIER::RelationType, typename BODY_ATOM_SPECIFIERs::RelationType...> RuleType;
216
214
typedef typename HEAD_ATOM_SPECIFIER::AtomType HeadType;
217
215
const HeadType head;
218
216
typedef tuple<typename BODY_ATOM_SPECIFIERs::AtomType...> BodyType;
219
217
BodyType body;
220
- const EXTERNALS_TYPE& externals;
218
+ const EXTERNALS_TYPE externals;
221
219
};
222
- #endif
223
220
224
221
template <typename HEAD_ATOM_SPECIFIER, typename ... BODY_ATOM_SPECIFIERs>
225
222
static RuleInstance<HEAD_ATOM_SPECIFIER, BODY_ATOM_SPECIFIERs...> rule (
@@ -246,35 +243,23 @@ static RuleInstance<HEAD_ATOM_SPECIFIER, BODY_ATOM_SPECIFIERs...> rule(
246
243
247
244
template <typename T>
248
245
struct ExternalFunction {
249
- Variable<T>& bindVariable;
246
<
10000
code class="diff-text syntax-highlighted-line addition">+ Variable<T>* bindVariable;
250
247
typedef function<T()> ExternalFunctionType;
251
248
ExternalFunctionType externalFunction;
252
249
};
253
250
254
251
template <typename T>
255
252
static ExternalFunction<T> lambda (
256
- unique_ptr< Variable<T>>& bindVariable,
253
+ Variable<T>* bindVariable,
257
254
typename ExternalFunction<T>::ExternalFunctionType externalFunction) {
258
- return ExternalFunction<T> {* bindVariable, externalFunction};
255
+ return ExternalFunction<T> {bindVariable, externalFunction};
259
256
}
260
257
261
- #if 0
262
258
template <typename ... BODY_ATOM_SPECIFIERs>
263
259
static BodyAtoms<BODY_ATOM_SPECIFIERs...> body (BODY_ATOM_SPECIFIERs&&... bodyAtoms) {
264
260
return BodyAtoms<BODY_ATOM_SPECIFIERs...>{{bodyAtoms.atom ...}};
265
261
}
266
262
267
- template<typename ... BODY_ATOM_SPECIFIERs>
268
- static BodyAtoms<BODY_ATOM_SPECIFIERs...> body(BODY_ATOM_SPECIFIERs&... bodyAtoms) {
269
- return BodyAtoms<BODY_ATOM_SPECIFIERs...>{{bodyAtoms.atom...}};
270
- }
271
- #else
272
- template <typename ... BODY_ATOM_SPECIFIERs>
273
- static BodyAtoms<BODY_ATOM_SPECIFIERs...> body (BODY_ATOM_SPECIFIERs... bodyAtoms) {
274
- return BodyAtoms<BODY_ATOM_SPECIFIERs...>{{bodyAtoms.atom ...}};
275
- }
276
- #endif
277
-
278
263
template <typename HEAD_ATOM_SPECIFIER, typename ... BODY_ATOM_SPECIFIERs, typename ... EXTERNAL_TYPEs>
279
264
static ExternalRuleInstance<Externals<EXTERNAL_TYPEs...>, HEAD_ATOM_SPECIFIER, BODY_ATOM_SPECIFIERs...> rule (
280
265
const HEAD_ATOM_SPECIFIER& h,
@@ -315,7 +300,7 @@ static ostream & operator<<(ostream &out, const RelationSet<RELATION_TYPE>& rela
315
300
{
316
301
out << " \" " << typeid (relationSet).name () << " \" " << endl;
317
302
for (const auto & tuple : relationSet.set ) {
318
- operator << <RELATION_TYPE>(out, tuple.second );
303
+ datalog:: operator << <RELATION_TYPE>(out, tuple.second );
319
304
out << endl;
320
305
}
321
306
return out;
@@ -664,7 +649,7 @@ static bool bindExternal(const ExternalRuleInstance<Externals<Ts...>, HEAD_ATOM_
664
649
auto value = external.externalFunction ();
665
650
// cout << "external function returned " << value << endl;
666
651
auto & bindVariable = external.bindVariable ;
667
- return datalog::bind (value, & bindVariable);
652
+ return datalog::bind (value, bindVariable);
668
653
}
669
654
670
655
template <typename ... Ts, typename HEAD_ATOM_SPECIFIER, typename ... BODY_ATOM_SPECIFIERs, size_t ... Is>
@@ -684,7 +669,7 @@ template<size_t I, typename... Ts, typename HEAD_ATOM_SPECIFIER, typename... BOD
684
669
static void unbindExternal (const ExternalRuleInstance<Externals<Ts...>, HEAD_ATOM_SPECIFIER, BODY_ATOM_SPECIFIERs...>& rule) {
685
670
auto & external = get<I>(rule.externals .externals );
686
671
auto & bindVariable = external.bindVariable ;
687
- bindVariable. unbind ();
672
+ bindVariable-> unbind ();
688
673
}
689
674
690
675
template <typename ... Ts, typename HEAD_ATOM_SPECIFIER, typename ... BODY_ATOM_SPECIFIERs, size_t ... Is>
@@ -769,6 +754,11 @@ struct RuleSet {
769
754
tuple<RULE_TYPEs...> rules;
770
755
};
771
756
757
+ template <typename ... RULE_TYPEs>
758
+ RuleSet<RULE_TYPEs...> ruleset (RULE_TYPEs&&... r) {
759
+ return RuleSet<RULE_TYPEs...>{{r...}};
760
+ }
761
+
772
762
template <typename ... RULE_TYPEs, typename ... RELATIONs>
773
763
static void applyRuleSet (
774
764
size_t iteration,
0 commit comments