@@ -20,8 +20,6 @@ using namespace std;
2020template <typename T>
2121struct Symbol : optional<T>
2222{
23- // typedef shared_ptr<Symbol> Type;
24-
2523 void bind (const T &value)
2624 {
2725 this ->emplace (value);
@@ -148,7 +146,7 @@ static void unbind(const tuple<SymbolOrValue<Ts>...> &tuple)
148146}
149147
150148// bind 1 SymbolOrValue with 1 Value
151- template <unsigned int I, typename VALUE_TYPE>
149+ template <typename VALUE_TYPE>
152150bool bind (SymbolOrValue<VALUE_TYPE> &s, const VALUE_TYPE &v)
153151{
154152 if (s.isSym ())
@@ -171,7 +169,7 @@ bool bind(SymbolOrValue<VALUE_TYPE> &s, const VALUE_TYPE &v)
171169template <typename ATOM_TYPE, typename GROUND_TYPE, size_t ... Is>
172170static bool bind (ATOM_TYPE &atom, const GROUND_TYPE &fact, index_sequence<Is...>)
173171{
174- bool success = ((bind<Is> (get<Is>(atom), get<Is>(fact))) and ...);
172+ bool success = ((bind (get<Is>(atom), get<Is>(fact))) and ...);
175173 if (success)
176174 {
177175 {
@@ -234,6 +232,7 @@ template <typename HEAD_RELATION, typename... BODY_RELATIONs>
234232struct Rule
235233{
236234 typedef Rule Define;
235+ typedef HEAD_RELATION HeadRelationType;
237236 typedef typename HEAD_RELATION::Atom HeadType;
238237 HeadType head;
239238 typedef tuple<BODY_RELATIONs...> BodyRelations;
@@ -417,24 +416,28 @@ static bool bind(typename RELATION_TYPE::Atom &atom,
417416#endif
418417
419418template <size_t I, typename RULE_TYPE, typename ... RELATIONs>
420- static void bind (typename RULE_TYPE::BodyType &atoms, // typedef tuple<typename BODY_RELATIONs::Atom...> BodyType;
419+ static bool bind (typename RULE_TYPE::BodyType &atoms, // typedef tuple<typename BODY_RELATIONs::Atom...> BodyType;
421420 const tuple<RELATIONs const *...> &slice)
422421{
423422 // get the fact in the slice that can potentially bind
424423 typedef typename tuple_element<I, typename RULE_TYPE::BodyRelations>::type BodyRelationI;
425424 auto factPtr = get<BodyRelationI const *>(slice);
426- const BodyRelationI& fact = *factPtr;
427- // get the atom
428- typename BodyRelationI::Atom &atom = get<I>(atoms);
429- // try to bind the atom with the fact
430- bind (atom, fact);
425+ bool success = false ;
426+ if (factPtr) {
427+ const BodyRelationI& fact = *factPtr;
428+ // get the atom
429+ typename BodyRelationI::Atom &atom = get<I>(atoms);
430+ // try to bind the atom with the fact
431+ success = bind (atom, fact);
432+ }
433+ return success;
431434}
432435
433436template <typename RULE_TYPE, typename ... RELATIONs, size_t ... Is>
434- static void bind (typename RULE_TYPE::BodyType &atoms,
437+ static bool bind (typename RULE_TYPE::BodyType &atoms,
435438 const tuple<RELATIONs const *...> &slice, index_sequence<Is...>)
436439{
437- ((bind<Is, RULE_TYPE, RELATIONs...>(atoms, slice)), ...);
440+ return ((bind<Is, RULE_TYPE, RELATIONs...>(atoms, slice)) and ...);
438441}
439442
440443// bind n atoms (of multiple relation types) with 1 slice (of multiple relation types)
@@ -445,73 +448,61 @@ static bool bind(typename RULE_TYPE::BodyType &atoms,
445448 // unbind all the symbols
446449 unbind<RULE_TYPE>(atoms);
447450 // for each atom, bind with corresponding relation type in slice
448- bind<RULE_TYPE, RELATIONs...>(atoms, slice,
451+ return bind<RULE_TYPE, RELATIONs...>(atoms, slice,
449452 make_index_sequence<tuple_size<typename RULE_TYPE::BodyType>::value>{});
450- return false ;
451453}
452454
453- // apply a rule to state
454- template <typename RULE_TYPE, typename ... RELATIONs>
455- static void apply (RULE_TYPE &rule, const State<RELATIONs...> &state)
455+ template <typename VALUE_TYPE>
456+ void ground (const SymbolOrValue<VALUE_TYPE> &s, VALUE_TYPE &v)
456457{
457- auto it = state.iterator ();
458- while (it.hasNext ())
458+ if (s.isSym ())
459459 {
460- auto slice = it.next ();
461- // slice is type typedef tuple<typename RELATIONs::GroundType const* ...> SliceType;
462- /* bool success = */ bind<RULE_TYPE, RELATIONs...>(rule.body , slice);
460+ Symbol<VALUE_TYPE> &symbol = *s.getSym ();
461+ assert (symbol.isBound ());
462+ v = symbol.value ();
463+ } else {
464+ v = s.getVal ();
463465 }
464466}
465467
466- #if 0
467- template<typename RELATION_TYPE>
468- static bool apply(
469- const typename RELATION_TYPE::AtomicType& atom,
470- const RELATION_TYPE& relation)
471- {
472- // we have the atom, and some corresponding facts, now bind them
473- // but we don't want the ground atoms
E18F
474- // we want the bound atoms
475-
476- // to avoid copying symbols we should try and find a complete binding across all relations,
477- // and then move to next complete binding etc.
478-
479- // so basically we want to stream all the combinations of facts, where each combination
480- // consists of selecting 1 fact from each relation in the state
481- return true;
468+ template <typename RELATION_TYPE, size_t ... Is>
469+ static void ground (const typename RELATION_TYPE::Atom& atom, RELATION_TYPE& groundAtom, index_sequence<Is...>) {
470+ ((ground (get<Is>(atom), get<Is>(groundAtom))), ...);
482471}
483472
484- template<typename RULE_TYPE, typename ... RELATIONs, size_t ... Is>
485- static void apply(
486- const typename RULE_TYPE::BodyType& body,
487- const typename State<RELATIONs...>::RelationsType& relations,
488- index_sequence<Is...>
489- )
490- {
491- /*
492- * Bind n atoms (of different relation types, such as the body of a rule)
493- * with state consisting of
494- * n_{i} facts (of different relation types i = 1 ... m)
495- */
496- // for each atom in body find and bind with corresponding relation
497- bool success = ((
498- apply<typename tuple_element<Is, typename State<RELATIONs...>::RelationsType>::type>(
499- get<Is>(body),
500- get<typename tuple_element<Is, typename State<RELATIONs...>::RelationsType>::type>(relations)
501- )) and ...);
473+ template <typename RELATION_TYPE>
474+ static RELATION_TYPE ground (const typename RELATION_TYPE::Atom& atom) {
475+ RELATION_TYPE groundAtom;
476+ ground<RELATION_TYPE>(atom, groundAtom, make_index_sequence<tuple_size<typename RELATION_TYPE::Atom>::value>{});
477+ return groundAtom;
502478}
503479
504- // bind a rule body to a tuple of relations
505- template<typename RULE_TYPE, typename ... RELATIONs>
506- static void apply(
507- const typename RULE_TYPE::BodyType& body,
508- const typename State<RELATIONs...>::RelationsType& relations
509- )
480+ // apply a rule to state
481+ template <typename RULE_TYPE, typename ... RELATIONs>
482+ static typename RULE_TYPE::HeadRelationType::Set apply (RULE_TYPE &rule, const State<RELATIONs...> &state)
510483{
511- apply<RULE_TYPE, RELATIONs...>(body, relations, make_index_sequence<tuple_size<typename RULE_TYPE::BodyType>::value>
512- {});
484+ typedef typename RULE_TYPE::HeadRelationType HeadRelationType;
485+ typename HeadRelationType::Set derivedFacts;
486+ auto it = state.iterator ();
487+ while (it.hasNext ())
488+ {
489+ auto slice = it.next ();
490+ if (bind<RULE_TYPE, RELATIONs...>(rule.body , slice)) {
491+ // successful bind, therefore add (grounded) head atom to new state
492+ cout << " successful bind of body" << endl;
493+ auto derivedFact = ground<HeadRelationType>(rule.head );
494+ {
495+ cout << " adding: " ;
496+ datalog::print<typename HeadRelationType::TupleType>(cout, derivedFact); // TODO: avoid need for type
497+ cout << endl;
498+ }
499+ derivedFacts.insert (derivedFact);
500+ } else {
501+ cout << " failed to bind body" << endl;
502+ }
503+ }
504+ return derivedFacts;
513505}
514- #endif
515506
516507#if 0
517508template<typename RELATION_TYPE>
0 commit comments