@@ -54,13 +54,38 @@ struct SymbolOrValue : public variant<T, shared_ptr<Symbol<T>>> {
54
54
}
55
55
};
56
56
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
+
57
68
template <typename ... Ts>
58
69
struct Relation {
59
70
typedef tuple<Ts...> GroundType;
60
71
typedef tuple<SymbolOrValue<Ts> ...> AtomicType;
61
72
const set<GroundType> tuples;
62
73
};
63
74
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
+
64
89
template <typename HEAD_RELATION, typename ... BODY_RELATIONs>
65
90
struct Rule {
66
91
const typename HEAD_RELATION::AtomicType head;
@@ -80,7 +105,7 @@ static void unbind(const typename RELATION_TYPE::AtomicType& tuple) {
80
105
81
106
// bind 1 SymbolOrValue with 1 Value
82
107
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 ) {
84
109
if (s.isSym ()) {
85
110
Symbol<VALUE_TYPE>& symbol = *s.getSym ().get ();
86
111
// has the symbol already been bound?
@@ -91,30 +116,44 @@ bool bind(SymbolOrValue<VALUE_TYPE>& s, const VALUE_TYPE& v) {
91
116
}
92
117
}
93
118
symbol.bind (v);
94
- cout << " bound " << s. getSym () << " to " << v << endl ;
119
+ b = v ;
95
120
}
96
121
return true ;
97
122
}
98
123
99
124
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,
102
127
const typename RELATION_TYPE::GroundType& fact,
103
128
index_sequence<Is...>
104
129
) {
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 ...);
108
133
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
+ }
109
141
return boundAtom;
110
142
}
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
+ }
111
150
return nullopt;
112
151
}
113
152
114
153
// bind 1 atom with 1 fact
115
154
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,
118
157
const typename RELATION_TYPE::GroundType& fact
119
158
) {
120
159
auto indexSequence = make_index_sequence<tuple_size<typename RELATION_TYPE::GroundType>::value> { };
@@ -124,14 +163,14 @@ static optional<typename RELATION_TYPE::AtomicType> bind(
124
163
// bind 1 atom with a relation (n facts)
125
164
template <typename RELATION_TYPE>
126
165
static RELATION_TYPE bind (
127
- const typename RELATION_TYPE::AtomicType& atom,
166
+ typename RELATION_TYPE::AtomicType& atom,
128
167
const RELATION_TYPE& relation
129
168
) {
130
169
set<typename RELATION_TYPE::GroundType> outputTuples;
131
- for (const auto & fact : relation.tuples ) {
170
+ for (auto & fact : relation.tuples ) {
132
171
const auto & boundAtom = bind<RELATION_TYPE>(atom, fact);
133
172
if (boundAtom.has_value ()) {
134
- // outputTuples.insert(boundAtom.value());
173
+ outputTuples.insert (boundAtom.value ());
135
174
}
136
175
}
137
176
return RELATION_TYPE{outputTuples};
@@ -147,91 +186,3 @@ static RELATION_TYPE merge(const RELATION_TYPE& r1, const RELATION_TYPE& r2) {
147
186
}
148
187
149
188
#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
0 commit comments