8000 low-level binding implemented · Z80coder/datalog-cpp@8c42dbd · GitHub
[go: up one dir, main page]

Skip to content

Commit 8c42dbd

Browse files
author
wright
committed
low-level binding implemented
1 parent 936cae6 commit 8c42dbd

File tree

2 files changed

+58
-104
lines changed

2 files changed

+58
-104
lines changed

src/Datalog.h

Lines changed: 51 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,38 @@ struct SymbolOrValue : public variant<T, shared_ptr<Symbol<T>>> {
5454
}
5555
};
5656

57+
template<typename T>
58+
static ostream& operator<<(ostream& out, const SymbolOrValue<T>& s)
59+
{
60+
if (s.isSym()) {
61+
out << s.getSym();
62+
} else {
63+
out << s.getVal();
64+
}
65+
return out;
66+
}
67+
5768
template<typename ... Ts>
5869
struct Relation {
5970
typedef tuple<Ts...> GroundType;
6071
typedef tuple<SymbolOrValue<Ts> ...> AtomicType;
6172
const set<GroundType> tuples;
6273
};
6374

75+
template<typename RELATION_TYPE>
76+
static ostream& print(ostream& out, const typename RELATION_TYPE::GroundType& s)
77+
{
78+
apply([&out](auto&&... args) {(( out << "[" << args << "] "), ...);}, s);
79+
return out;
80+
}
81+
82+
template<typename RELATION_TYPE>
83+
static ostream& print(ostream& out, const typename RELATION_TYPE::AtomicType& s)
84+
{
85+
apply([&out](auto&&... args) {(( out << "[" << args << "] "), ...);}, s);
86+
return out;
87+
}
88+
6489
template<typename HEAD_RELATION, typename ... BODY_RELATIONs>
6590
struct Rule {
6691
const typename HEAD_RELATION::AtomicType head;
@@ -80,7 +105,7 @@ static void unbind(const typename RELATION_TYPE::AtomicType& tuple) {
80105

81106
// bind 1 SymbolOrValue with 1 Value
82107
template<unsigned int I, typename VALUE_TYPE>
83-
bool bind(SymbolOrValue<VALUE_TYPE>& s, const VALUE_TYPE& v) {
108+
bool bind(SymbolOrValue<VALUE_TYPE>& s, const VALUE_TYPE& v, VALUE_TYPE& b) {
84109
if (s.isSym()) {
85110
Symbol<VALUE_TYPE>& symbol = *s.getSym().get();
86111
// has the symbol already been bound?
@@ -91,30 +116,44 @@ bool bind(SymbolOrValue<VALUE_TYPE>& s, const VALUE_TYPE& v) {
91116
}
92117
}
93118
symbol.bind(v);
94-
cout << "bound " << s.getSym() << " to " << v << endl;
119+
b = v;
95120
}
96121
return true;
97122
}
98123

99124
template<typename RELATION_TYPE, size_t ... Is>
100-
static optional<typename RELATION_TYPE::AtomicType> bind(
101-
const typename RELATION_TYPE::AtomicType& atom,
125+
static optional<typename RELATION_TYPE::GroundType> bind(
126+
typename RELATION_TYPE::AtomicType& atom,
102127
const typename RELATION_TYPE::GroundType& fact,
103128
index_sequence<Is...>
104129
) {
105-
typename RELATION_TYPE::AtomicType boundAtom { atom };
106-
unbind<RELATION_TYPE>(boundAtom);
107-
bool successfulBinding = ((bind<Is>(get<Is>(boundAtom), get<Is>(fact))) and ...);
130+
unbind<RELATION_TYPE>(atom);
131+
typename RELATION_TYPE::GroundType boundAtom;
132+
bool successfulBinding = ((bind<Is>(get<Is>(atom), get<Is>(fact), get<Is>(boundAtom))) and ...);
108133
if (successfulBinding) {
134+
{
135+
cout << "bound ";
136+
print<RELATION_TYPE>(cout, atom);
137+
cout << " to ";
138+
print<RELATION_TYPE>(cout, boundAtom);
139+
cout << endl;
140+
}
109141
return boundAtom;
110142
}
143+
{
144+
cout << "failed to bind ";
145+
print<RELATION_TYPE>(cout, atom);
146+
cout << " with ";
147+
print<RELATION_TYPE>(cout, fact);
148+
cout << endl;
149+
}
111150
return nullopt;
112151
}
113152

114153
// bind 1 atom with 1 fact
115154
template<typename RELATION_TYPE>
116-
static optional<typename RELATION_TYPE::AtomicType> bind(
117-
const typename RELATION_TYPE::AtomicType& atom,
155+
static optional<typename RELATION_TYPE::GroundType> bind(
156+
typename RELATION_TYPE::AtomicType& atom,
118157
const typename RELATION_TYPE::GroundType& fact
119158
) {
120159
auto indexSequence = make_index_sequence<tuple_size<typename RELATION_TYPE::GroundType>::value> { };
@@ -124,14 +163,14 @@ static optional<typename RELATION_TYPE::AtomicType> bind(
124163
// bind 1 atom with a relation (n facts)
125164
template<typename RELATION_TYPE>
126165
static RELATION_TYPE bind(
127-
const typename RELATION_TYPE::AtomicType& atom,
166+
typename RELATION_TYPE::AtomicType& atom,
128167
const RELATION_TYPE& relation
129168
) {
130169
set<typename RELATION_TYPE::GroundType> outputTuples;
131-
for (const auto& fact : relation.tuples) {
170+
for (auto& fact : relation.tuples) {
132171
const auto& boundAtom = bind<RELATION_TYPE>(atom, fact);
133172
if (boundAtom.has_value()) {
134-
//outputTuples.insert(boundAtom.value());
173+
outputTuples.insert(boundAtom.value());
135174
}
136175
}
137176
return RELATION_TYPE{outputTuples};
@@ -147,91 +186,3 @@ static RELATION_TYPE merge(const RELATION_TYPE& r1, const RELATION_TYPE& r2) {
147186
}
148187

149188
#endif /* SRC_DATALOG_H_ */
150-
151-
#if 0
152-
// bind 1 SymbolOrValue with 1 Value
153-
template<unsigned int I, typename VALUE_TYPE, typename VARIANT_TYPE>
154-
bool bind(SymbolOrValue<VALUE_TYPE>& s, const VALUE_TYPE& v, map<string, VARIANT_TYPE>& bindings) {
155-
if (s.isSym()) {
156-
const auto& symbolName = s.getSym().name;
157-
// Has this symbol already been bound?
158-
if (bindings.count(symbolName) > 0) {
159-
// Is this a consistent binding?
160-
#if 0
161-
const auto& boundVariant = bindings.at(symbolName);
162-
const auto& boundVariantIndex = boundVariant.index();
163-
const auto& boundValue = get<boundVariantIndex>(boundVariant);
164-
if (!(boundValue == v)) {
165-
return false;
166-
}
167-
#endif
168-
}
169-
s.bindVal(v);
170-
VARIANT_TYPE vt(in_place_index_t<I> { }, v);
171-
cout << "Recording binding at index " << I << endl;
172-
bindings.insert( { symbolName, vt });
173-
cout << "Bound " << s.getSym().name << " to " << v << endl;
174-
}
175-
return true;
176-
}
177-
178-
// bind 1 atom with 1 fact
179-
template<typename RELATION_TYPE, size_t ... Is>
180-
static optional<Atom<RELATION_TYPE>> bind(const Atom<RELATION_TYPE>& atom, const typename RELATION_TYPE::GroundType& fact, index_sequence<Is...>) {
181-
typename RELATION_TYPE::AtomicType boundAtom { atom.tuple };
182-
map<string, typename RELATION_TYPE::VariantType> bindings;
183-
bool successfulBinding = ((bind<Is>(get<Is>(boundAtom), get<Is>(fact), bindings)) and ...);
184-
if (successfulBinding) {
185-
return Atom<RELATION_TYPE> { boundAtom };
186-
}
187-
return nullopt;
188-
}
189-
#endif
190-
191-
#if 0
192-
typedef map<string, set<unsigned int>> SymBindingsType;
193-
194-
template<typename T>
195-
static void bind(const T& t, SymBindingsType& symBindings) {
196-
}
197-
198-
static void noOp() {
199-
}
200-
#endif
201-
202-
#if 0
203-
unsigned int index = 0;
204-
apply([this, &index](auto&&... args) {
205-
((args.isSym() ? declareSym(args, index++, symIndexMap) : noOp(index++)), ...);}, tuple);
206-
#endif
207-
208-
#if 0
209-
typedef map<string, set<unsigned int>> SymIndexMapType;
210-
SymIndexMapType symIndexMap;
211-
private:
212-
template<typename T>
213-
static void declareSym(const T& t, unsigned int index, SymIndexMapType& symIndexMap) {
214-
auto symbolName = t.getSym().name;
215-
if (symIndexMap.count(symbolName) == 0) {
216-
symIndexMap.insert( { symbolName, { } });
217-
}
218-
auto it = symIndexMap.find(symbolName);
219-
it->second.insert(index);
220-
}
221-
static void noOp(unsigned int index) {
222-
}
223-
#endif
224-
225-
#if 0
226-
227-
template<typename RELATION_TYPE>
228-
static Relation<RELATION_TYPE> bind(const Atom<RELATION_TYPE>& atom, const Relation<RELATION_TYPE>& relation) {
229-
Relation<RELATION_TYPE> boundAtoms;
230-
auto indexSequence = index_sequence_for<typename RELATION_TYPE::GroundType> { };
231-
for (const auto& fact : relation.tuples) {
232-
typename RELATION_TYPE::GroundType boundAtom = bind(atom, fact, indexSequence);
233-
boundAtoms.tuples.insert(boundAtom);
234-
}
235-
return boundAtoms;
236-
}
237-
#endif

tests/types_test.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ int main() {
7272
if (boundAtom1.has_value()) {
7373
cout << "successful bind" << endl;
7474
} else {
75-
cout << "could not bind" << endl;
75+
cout << "failed bind" << endl;
7676
}
7777

7878
// Bind 1 atom with 1 fact
@@ -81,7 +81,7 @@ int main() {
8181
if (boundAtom2.has_value()) {
8282
cout << "successful bind" << endl;
8383
} else {
84-
cout << "could not bind" << endl;
84+
cout << "failed bind" << endl;
8585
}
8686

8787
// Bind 1 atom with 1 fact
@@ -90,11 +90,14 @@ int main() {
9090
if (boundAtom3.has_value()) {
9191
cout << "successful bind" << endl;
9292
} else {
93-
cout << "could not bind" << endl;
93+
cout << "failed bind" << endl;
9494
}
9595

9696
// Bind 1 atom with a relation (n facts)
97-
auto newRelation = bind(clause1, advisers);
97+
cout << "Should bind with all relations:" << endl;
98+
auto newRelation1 = bind(clause1, advisers);
99+
cout << "Should bind with 0 relations:" << endl;
100+
auto newRelation2 = bind(dummyClause, advisers);
98101

99102
}
100103
}

0 commit comments

Comments
 (0)
0