10000 simplify adding externals · Z80coder/datalog-cpp@66f4df7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 66f4df7

Browse files
committed
simplify adding externals
1 parent efa8767 commit 66f4df7

File tree

2 files changed

+61
-32
lines changed

2 files changed

+61
-32
lines changed

src/Datalog.h

Lines changed: 45 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,7 @@ static typename RELATION_TYPE::Ground ground(const tuple<Ts...> &atom)
136136
template<typename RELATION_TYPE, typename ... Ts>
137137
struct AtomTypeSpecifier {
138138
typedef RELATION_TYPE RelationType;
139+
// TODO: why not references?
139140
typedef tuple<Ts...> AtomType;
140141
AtomType atom;
141142
};
@@ -189,22 +190,20 @@ struct Externals {
189190
tuple<const EXTERNAL_TYPEs&...> externals;
190191
};
191192

193+
template<typename ... BODY_ATOM_SPECIFIERs>
194+
struct BodyAtoms {
195+
// TODO: why not references?
196+
tuple<typename BODY_ATOM_SPECIFIERs::AtomType...> body;
197+
};
198+
192199
template <typename HEAD_ATOM_SPECIFIER, typename... BODY_ATOM_SPECIFIERs>
193200
struct RuleInstance {
194201
typedef Rule<typename HEAD_ATOM_SPECIFIER::RelationType, typename BODY_ATOM_SPECIFIERs::RelationType...> RuleType;
195202
typedef typename HEAD_ATOM_SPECIFIER::AtomType HeadType;
196203
HeadType head;
204+
// TODO: why not references?
197205
typedef tuple<typename BODY_ATOM_SPECIFIERs::AtomType...> BodyType;
198206
BodyType body;
199-
200-
template <typename ... EXTERNAL_TYPEs>
201-
ExternalRuleInstance<Externals<EXTERNAL_TYPEs...>, HEAD_ATOM_SPECIFIER, BODY_ATOM_SPECIFIERs...> externals(
202-
const EXTERNAL_TYPEs&... externals
203-
) {
204-
typedef ExternalRuleInstance<Externals<EXTERNAL_TYPEs...>, HEAD_ATOM_SPECIFIER, BODY_ATOM_SPECIFIERs...> RuleInstanceType;
205-
return RuleInstanceType{head, body, Externals<EXTERNAL_TYPEs...>{externals...}};
206-
}
207-
208207
};
209208

210209
template <typename EXTERNALS_TYPE, typename HEAD_ATOM_SPECIFIER, typename... BODY_ATOM_SPECIFIERs>
@@ -223,26 +222,51 @@ static RuleInstance<HEAD_ATOM_SPECIFIER, BODY_ATOM_SPECIFIERs...> rule(
223222
return RuleInstanceType{head, body};
224223
}
225224

225+
template <typename HEAD_ATOM_SPECIFIER, typename... BODY_ATOM_SPECIFIERs>
226+
static RuleInstance<HEAD_ATOM_SPECIFIER, BODY_ATOM_SPECIFIERs...> rule(
227+
const HEAD_ATOM_SPECIFIER& h,
228+
const BodyAtoms<BODY_ATOM_SPECIFIERs...>& b
229+
) {
230+
typedef RuleInstance<HEAD_ATOM_SPECIFIER, BODY_ATOM_SPECIFIERs...> RuleInstanceType;
231+
typename RuleInstanceType::HeadType head{h.atom};
232+
return RuleInstanceType{head, b.body};
233+
}
234+
226235
// Rules with external functions
227236

228-
template<typename T, typename ... ATOM_TYPE_SPECIFIERs>
237+
template<typename T>
229238
struct ExternalFunction {
230239
Variable<T>& bindVariable;
231-
typedef tuple<const ATOM_TYPE_SPECIFIERs&...> AtomsTupleType;
232-
AtomsTupleType boundAtoms;
233-
typedef tuple<const typename ATOM_TYPE_SPECIFIERs::RelationType::Ground&...> ArgsType;
234-
function<T(const ArgsType&)> externalFunction;
240+
typedef function<T()> ExternalFunctionType;
241+
ExternalFunctionType externalFunction;
235242
};
236243

237-
template<typename T, typename ... ATOM_TYPE_SPECIFIERs>
238-
static ExternalFunction<T, ATOM_TYPE_SPECIFIERs...> external(
244+
template<typename T>
245+
static ExternalFunction<T> external(
239246
unique_ptr<Variable<T>>& bindVariable,
240-
function<T(const typename ExternalFunction<T, ATOM_TYPE_SPECIFIERs...>::ArgsType&)> externalFunction,
241-
const ATOM_TYPE_SPECIFIERs&... boundAtoms
247+
typename ExternalFunction<T>::ExternalFunctionType externalFunction) {
248+
return ExternalFunction<T> {*bindVariable, externalFunction};
249+
}
250+
251+
template<typename ... BODY_ATOM_SPECIFIERs>
252+
static BodyAtoms<BODY_ATOM_SPECIFIERs...> body(BODY_ATOM_SPECIFIERs&&... bodyAtoms) {
253+
return BodyAtoms<BODY_ATOM_SPECIFIERs...>{{bodyAtoms.atom...}};
254+
}
255+
256+
template<typename ... BODY_ATOM_SPECIFIERs>
257+
static BodyAtoms<BODY_ATOM_SPECIFIERs...> body(BODY_ATOM_SPECIFIERs&... bodyAtoms) {
258+
return BodyAtoms<BODY_ATOM_SPECIFIERs...>{{bodyAtoms.atom...}};
259+
}
260+
261+
template <typename HEAD_ATOM_SPECIFIER, typename... BODY_ATOM_SPECIFIERs, typename... EXTERNAL_TYPEs>
262+
static ExternalRuleInstance<Externals<EXTERNAL_TYPEs...>, HEAD_ATOM_SPECIFIER, BODY_ATOM_SPECIFIERs...> rule(
263+
const HEAD_ATOM_SPECIFIER& h,
264+
const BodyAtoms<BODY_ATOM_SPECIFIERs...>& b,
265+
const EXTERNAL_TYPEs&... externals
242266
) {
243-
return ExternalFunction<T, ATOM_TYPE_SPECIFIERs...> {
244-
*bindVariable, {boundAtoms...}, externalFunction
245-
};
267+
typedef ExternalRuleInstance<Externals<EXTERNAL_TYPEs...>, HEAD_ATOM_SPECIFIER, BODY_ATOM_SPECIFIERs...> RuleInstanceType;
268+
typename RuleInstanceType::HeadType head{h.atom};
269+
return RuleInstanceType{head, b.body, Externals<EXTERNAL_TYPEs...>{externals...}};
246270
}
247271

248272
template <typename RELATION_TYPE>

tests/types_test.cpp

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,13 @@ bool test2()
8383

8484
auto directAcademicAncestor = rule(atom<AcademicAncestor>(x, y), atom<Adviser>(x, y));
8585
auto indirectAcademicAncestor = rule(atom<AcademicAncestor>(x, z), atom<Adviser>(x, y), atom<AcademicAncestor>(y, z));
86-
auto query = rule(atom<QueryResult>(x), atom<AcademicAncestor>(robin, x), atom<AcademicAncestor>(x, mistral));
86+
auto query = rule(
87+
atom<QueryResult>(x),
88+
body(
89+
atom<AcademicAncestor>(robin, x),
90+
atom<AcademicAncestor>(x, mistral)
91+
)
92+
);
8793

8894
// Apply rules
8995
State<Adviser, AcademicAncestor, QueryResult> state{advisers, {}, {}};
@@ -233,22 +239,21 @@ bool test4()
233239

234240
auto heights = rule(
235241
atom<Height>(name, height),
236-
atom<Person>(name, age, female, country)
242+
body(atom<Person>(name, age, female, country))
237243
);
238244

239245
auto anyPerson = atom<Person>(name, age, gender, country);
246+
auto timPerson = atom<Person>(tim, age, gender, country);
240247

241248
auto heightsExternal = rule(
242249
atom<Height>(name, height),
243-
anyPerson
244-
).externals(
245-
external<Metres>(
246-
height,
247-
[](const tuple<const Person::Ground&>& atoms) {
248-
return 0.0f;
249-
},
250-
anyPerson
251-
)
250+
body(
251+
anyPerson,
252+
timPerson//,
253+
// TODO: allow mixing
254+
//atom<Person>(name, 25u, gender, country)
255+
),
256+
external(height, [&anyPerson]() { return 0.0f; })
252257
);
253258

254259
#endif

0 commit comments

Comments
 (0)
0