10BC0 WIP: binding bodies to multiple relations · Z80coder/datalog-cpp@d90fb7f · GitHub
[go: up one dir, main page]

Skip to content

Commit d90fb7f

Browse files
author
wright
committed
WIP: binding bodies to multiple relations
1 parent cf95398 commit d90fb7f

File tree

2 files changed

+151
-18
lines changed

2 files changed

+151
-18
lines changed

src/Datalog.h

Lines changed: 146 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ static ostream& print(ostream& out, const TUPLE_TYPE& s)
8181
return out;
8282
}
8383

84+
#if 0
8485
template<typename RELATION_TYPE, size_t ... Is>
8586
static 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>
9192
static 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
96111
template<unsigned int I, typename VALUE_TYPE>
97112
bool 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)
152221
template<typename RELATION_TYPE>
153222
static RELATION_TYPE bind(
@@ -163,6 +232,7 @@ static RELATION_TYPE bind(
163232
}
164233
return RELATION_TYPE{outputTuples};
165234
}
235+
#endif
166236

167237
template<typename HEAD_RELATION, typename ... BODY_RELATIONs>
168238
struct 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
299438
template<typename RELATION_TYPE>
300439
static 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
334474
template<typename RULE_TYPE, typename ... RELATIONs>
335475
static 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
349484
template<typename RELATION_TYPE>

tests/types_test.cpp

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,36 +72,35 @@ int main() {
7272

7373
// Bind 1 atom with 1 fact
7474
Adviser::GroundType fact1 { { { "Andrew Rice" } }, { { "Mistral Contrastin" } } };
75-
auto boundAtom1 = bind<Adviser>(clause1, fact1);
76-
if (boundAtom1.has_value()) {
75+
if (bind<Adviser>(clause1, fact1)) {
7776
cout << "successful bind" << endl;
7877
} else {
7978
cout << "failed bind" << endl;
8079
}
8180

8281
// Bind 1 atom with 1 fact
8382
Adviser::AtomicType dummyClause { { x }, { x } };
84-
auto boundAtom2 = bind<Adviser>(dummyClause, fact1);
85-
if (boundAtom2.has_value()) {
83+
if (bind<Adviser>(dummyClause, fact1)) {
8684
cout << "successful bind" << endl;
8785
} else {
8886
cout << "failed bind" << endl;
8987
}
9088

9189
// Bind 1 atom with 1 fact
9290
Adviser::GroundType fact2 { { { "Mistral Contrastin" } }, { { "Mistral Contrastin" } } };
93-
auto boundAtom3 = bind<Adviser>(dummyClause, fact2);
94-
if (boundAtom3.has_value()) {
91+
if (bind<Adviser>(dummyClause, fact2)) {
9592
cout << "successful bind" << endl;
9693
} else {
9794
cout << "failed bind" << endl;
9895
}
9996

97+
#if 0
10098
// Bind 1 atom with a relation (n facts)
10199
cout << "Should bind with all relations:" << endl;
102100
auto newRelation1 = bind(clause1, advisers);
103101
cout << "Should bind with 0 relations:" << endl;
104102
auto newRelation2 = bind(dummyClause, advisers);
103+
#endif
105104

106105
typedef State<Adviser, AcademicAncestor> StateType;
107106
StateType state1{{ advisers, {} }};
@@ -118,7 +117,6 @@ int main() {
118117
it2.next();
119118
}
120119

121-
122120
apply<Rule2Type>(rule2, state1);
123121
}
124122
}

0 commit comments

Comments
 (0)
0