@@ -81,6 +81,7 @@ static ostream& print(ostream& out, const TUPLE_TYPE& s)
8181 return out;
8282}
8383
84+ #if 0
8485template<typename RELATION_TYPE, size_t ... Is>
8586static void unbind(const typename RELATION_TYPE::AtomicType& tuple, index_sequence<Is...>) {
8687 // TODO: why can't we use the apply pattern everywhere?
@@ -91,7 +92,21 @@ template<typename RELATION_TYPE>
9192static void unbind(const typename RELATION_TYPE::AtomicType& tuple) {
9293 unbind<RELATION_TYPE>(tuple, make_index_sequence<tuple_size<typename RELATION_TYPE::AtomicType>::value> { });
9394}
95+ #else
96+ template <typename RELATION_TYPE, size_t ... Is>
97+ static void unbind (const typename RELATION_TYPE::AtomicType& tuple, index_sequence<Is...>) {
98+ // TODO: why can't we use the apply pattern everywhere?
99+ ((get<Is>(tuple).getSym ()->unbind ()), ...);
100+ }
94101
102+ template <typename ... Ts>
103+ static void unbind (const tuple<SymbolOrValue<Ts> ...>& tuple) {
104+ auto indexSequence = make_index_sequence<tuple_size<typename Relation<Ts...>::AtomicType>::value> { };
105+ unbind<Relation<Ts...>>(tuple, indexSequence);
106+ }
107+ #endif
108+
109+ #if 0
95110// bind 1 SymbolOrValue with 1 Value
96111template<unsigned int I, typename VALUE_TYPE>
97112bool bind(SymbolOrValue<VALUE_TYPE>& s, const VALUE_TYPE& v, VALUE_TYPE& b) {
@@ -116,7 +131,6 @@ static optional<typename RELATION_TYPE::GroundType> bind(
116131 const typename RELATION_TYPE::GroundType& fact,
117132 index_sequence<Is...>
118133) {
119- unbind<RELATION_TYPE>(atom);
120134 typename RELATION_TYPE::GroundType boundAtom;
121135 bool successfulBinding = ((bind<Is>(get<Is>(atom), get<Is>(fact), get<Is>(boundAtom))) and ...);
122136 if (successfulBinding) {
@@ -145,9 +159,64 @@ static optional<typename RELATION_TYPE::GroundType> bind(
145159 typename RELATION_TYPE::AtomicType& atom,
146160 const typename RELATION_TYPE::GroundType& fact
147161) {
162+ unbind<RELATION_TYPE>(atom);
148163 return bind<RELATION_TYPE>(atom, fact, make_index_sequence<tuple_size<typename RELATION_TYPE::GroundType>::value> { });
149164}
165+ #else
166+ // bind 1 SymbolOrValue with 1 Value
167+ template <unsigned int I, typename VALUE_TYPE>
168+ bool bind (SymbolOrValue<VALUE_TYPE>& s, const VALUE_TYPE& v) {
169+ if (s.isSym ()) {
170+ Symbol<VALUE_TYPE>& symbol = *s.getSym ().get ();
171+ // has the symbol already been bound?
172+ if (symbol.isBound ()) {
173+ // is it a consistent binding?
174+ if (!(symbol.value () == v)) {
175+ return false ;
176+ }
177+ }
178+ symbol.bind (v);
179+ }
180+ return true ;
181+ }
182+
183+ template <typename RELATION_TYPE, size_t ... Is>
184+ static bool bind (
185+ typename RELATION_TYPE::AtomicType& atom,
186+ const typename RELATION_TYPE::GroundType& fact,
187+ index_sequence<Is...>
188+ ) {
189+ bool success = ((bind<Is>(get<Is>(atom), get<Is>(fact))) and ...);
190+ if (success) {
191+ {
192+ cout << " bound " ;
193+ print (cout, atom);
194+ cout << " to " ;
195+ print (cout, fact);
196+ cout << endl;
197+ }
198+ } else {
199+ cout << " failed to bind " ;
200+ print (cout, atom);
201+ cout << " with " ;
202+ print (cout, fact);
203+ cout << endl;
204+ }
205+ return success;
206+ }
150207
208+ // bind 1 atom with 1 fact (of the same relation type)
209+ template <typename RELATION_TYPE>
210+ static bool bind (
211+ typename RELATION_TYPE::AtomicType& atom,
212+ const typename RELATION_TYPE::GroundType& fact
213+ ) {
214+ // unbind<RELATION_TYPE>(atom);
215+ return bind<RELATION_TYPE>(atom, fact, make_index_sequence<tuple_size<typename RELATION_TYPE::GroundType>::value> { });
216+ }
217+ #endif
218+
219+ #if 0
151220// bind 1 atom with a relation (n facts)
152221template<typename RELATION_TYPE>
153222static RELATION_TYPE bind(
@@ -163,6 +232,7 @@ static RELATION_TYPE bind(
163232 }
164233 return RELATION_TYPE{outputTuples};
165234}
235+ #endif
166236
167237template <typename HEAD_RELATION, typename ... BODY_RELATIONs>
168238struct Rule {
@@ -181,9 +251,7 @@ struct State {
181251
182252 template <typename TUPLE_TYPE>
183253 static ostream& print (ostream& out, TUPLE_TYPE const * p) {
184- if (p) {
185- datalog::print (out, *p);
186- }
254+ if (p) { datalog::print (out, *p); }
187255 return out;
188256 }
189257
@@ -292,10 +360,81 @@ struct State {
292360 Iterator it{relations};
293361 return it;
294362 }
363+ };
295364
365+ template <typename RULE_TYPE, size_t ... Is>
366+ static void unbind (const typename RULE_TYPE::BodyType& atoms, index_sequence<Is...>) {
367+ ((unbind (get<Is>(atoms))), ...);
368+ }
296369
297- };
370+ template <typename RULE_TYPE>
371+ static void unbind (const typename RULE_TYPE::BodyType& atoms) {
372+ unbind<RULE_TYPE>(atoms, make_index_sequence<tuple_size<typename RULE_TYPE::BodyType>::value>{});
373+ }
374+
375+ #if 0
376+ // bind 1 atom with 1 fact (of the same relation type)
377+ template<typename RELATION_TYPE>
378+ static bool bind(
379+ typename RELATION_TYPE::AtomicType& atom,
380+ const typename RELATION_TYPE::GroundType& fact
381+ ) {
382+ #endif
383+
384+ template <size_t I, typename RULE_TYPE, typename ... RELATIONs>
385+ static void bind (
386+ const typename RULE_TYPE::BodyType& atoms,
387+ tuple<typename RELATIONs::GroundType const * ...>& slice
388+ ) {
389+ typedef Relation<typename tuple_element<I, const typename RULE_TYPE::BodyType>::type> AtomicRelationI;
390+ typedef typename AtomicRelationI::GroundType CorrespondingSliceRelationType;
391+ auto & atom = get<I>(atoms);
392+ auto & factPtr = get<CorrespondingSliceRelationType>(slice);
393+ // ((bind()), ...)
394+
395+ // TODO: atom type is SymbolOrValue but ground type is not
396+ #if 0
397+ ((bind<Relation<typename tuple_element<Is, const typename RULE_TYPE::BodyType>::type>>(
398+ get<Is>(atoms),
399+ (get<typename Relation<typename tuple_element<Is, const typename RULE_TYPE::BodyType>::type>::GroundType>(slice))
400+ )), ...);
401+ #endif
402+
403+ }
404+
405+ template <typename RULE_TYPE, typename ... RELATIONs, size_t ... Is>
406+ static void bind (
407+ const typename RULE_TYPE::BodyType& atoms,
408+ tuple<typename RELATIONs::GroundType const * ...>& slice,
409+ index_sequence<Is...>
410+ ) {
411+ ((bind<Is, RULE_TYPE, RELATIONs...>(atoms, slice)), ...);
412+ }
413+
414+ // bind n atoms (of multiple relation types) with 1 slice (of multiple relation types)
415+ template <typename RULE_TYPE, typename ... RELATIONs>
416+ static bool bind (
417+ const typename RULE_TYPE::BodyType& atoms, // typedef tuple<typename BODY_RELATIONs::AtomicType...> BodyType;
418+ tuple<typename RELATIONs::GroundType const * ...>& slice
419+ ) {
420+ // unbind all the symbols
421+ unbind<RULE_TYPE>(atoms);
422+ // for each atom, bind with corresponding relation type in slice
423+ bind<RULE_TYPE, RELATIONs...>(atoms, slice, make_index_sequence<tuple_size<typename RULE_TYPE::BodyType>::value>{});
424+ return false ;
425+ }
298426
427+ // apply a rule to state
428+ template <typename RULE_TYPE, typename ... RELATIONs>
429+ static void apply (const RULE_TYPE& rule, const State<RELATIONs...>& state) {
430+ auto it = state.iterator ();
431+ while (it.hasNext ()) {
432+ auto slice = it.next ();
433+ /* bool success = */ bind<RULE_TYPE, RELATIONs...>(rule.body , slice);
434+ }
435+ }
436+
437+ #if 0
299438template<typename RELATION_TYPE>
300439static bool apply(
301440 const typename RELATION_TYPE::AtomicType& atom,
@@ -331,19 +470,15 @@ static void apply(
331470 )) and ...);
332471}
333472
473+ // bind a rule body to a tuple of relations
334474template<typename RULE_TYPE, typename ... RELATIONs>
335475static void apply(
336476 const typename RULE_TYPE::BodyType& body,
337477 const typename State<RELATIONs...>::RelationsType& relations
338478) {
339479 apply<RULE_TYPE, RELATIONs...>(body, relations, make_index_sequence<tuple_size<typename RULE_TYPE::BodyType>::value> { });
340480}
341-
342- template <typename RULE_TYPE, typename ... RELATIONs>
343- static void apply (const RULE_TYPE& rule, const State<RELATIONs...>& state) {
344- apply<RULE_TYPE, RELATIONs...>(rule.body , state.relations );
345- }
346-
481+ #endif
347482
348483#if 0
349484template<typename RELATION_TYPE>
0 commit comments