8000 lots of clean-up and simplification · Z80coder/datalog-cpp@f41d728 · GitHub
[go: up one dir, main page]

Skip to content

Commit f41d728

Browse files
author
wright
committed
lots of clean-up and simplification
1 parent 3d086f1 commit f41d728

File tree

2 files changed

+122
-158
lines changed

2 files changed

+122
-158
lines changed

src/Datalog.h

Lines changed: 38 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -67,25 +67,19 @@ struct VariableOrValue : public variant<T, Variable<T> *>
6767
}
6868
};
6969

70-
template <typename T>
71-
static VariableOrValue<T> var(Variable<T> &Variable)
72-
{
73-
return VariableOrValue<T>{&Variable};
74-
}
70+
template<typename T>
71+
VariableOrValue<T> atomElement(Variable<T>& t) {
72+
return VariableOrValue<T>{&t};
73+
};
7574

76-
template <typename T>
77-
static ostream &
78-
operator<<(ostream &out, const VariableOrValue<T> &s)
79-
{
80-
if (s.isVar())
81-
{
82-
out << s.getVar();
83-
}
84-
else
85-
{
86-
out << s.getVal();
87-
}
88-
return out;
75+
template<typename T>
76+
VariableOrValue<T> atomElement(const T& t) {
77+
return VariableOrValue<T>{t};
78+
};
79+
80+
template<typename RELATION_TYPE, typename ... Ts>
81+
typename RELATION_TYPE::Atom atom(Ts&& ... elements) {
82+
return typename RELATION_TYPE::Atom(forward_as_tuple(atomElement(elements)...));
8983
}
9084

9185
template <typename... Ts>
@@ -97,16 +91,6 @@ struct Relation : tuple<Ts...>
9791
typedef set<Relation> Set;
9892
};
9993

100-
template <typename TUPLE_TYPE>
101-
static ostream &
102-
print(ostream &out, const TUPLE_TYPE &s)
103-
{
104-
out << "[";
105-
apply([&out](auto &&... args) { ((out << "[" << args << "]"), ...); }, s);
106-
out << "] ";
107-
return out;
108-
}
109-
11094
// TODO: can we avoid unbinding non-Variables by compile-time decisions?
11195
template <typename T>
11296
static void unbind(const VariableOrValue<T> &VariableOrValue)
@@ -199,18 +183,26 @@ struct Rule
199183
template<typename RELATION_TYPE>
200184
struct RelationSet {
201185
typename RELATION_TYPE::Set set;
186+
};
202187

203-
ostream & print(ostream &out)
204-
{
205-
out << "\"" << typeid(*this).name() << "\"" << endl;
206-
for (const auto& tuple : set) {
207-
datalog::print<typename RELATION_TYPE::TupleType>(out, tuple);
208-
out << endl;
209-
}
210-
return out;
211-
}
188+
template <typename RELATION_TYPE>
189+
static ostream& operator<<(ostream& out, const typename RELATION_TYPE::TupleType& t) {
190+
out << "[";
191+
apply([&out](auto &&... args) { ((out << "[" << args << "]"), ...); }, t);
192+
out << "] ";
193+
return out;
194+
}
212195

213-
};
196+
template<typename RELATION_TYPE>
197+
static ostream & operator<<(ostream &out, const RelationSet<RELATION_TYPE>& relationSet)
198+
{
199+
out << "\"" << typeid(relationSet).name() << "\"" << endl;
200+
for (const auto& tuple : relationSet.set) {
201+
operator<< <RELATION_TYPE>(out, tuple);
202+
out << endl;
203+
}
204+
return out;
205+
}
214206

215207
template <typename... RELATIONs>
216208
struct State
@@ -227,26 +219,6 @@ struct State
227219
return totalSize;
228220
}
229221

230-
ostream & print(ostream &out)
231-
{
232-
out << "[";
233-
apply([&out](auto &&... args) { ((args.print(out)), ...); }, relations);
234-
out << "] ";
235-
return out;
236-
}
237-
238-
// Next 2 functions for printing slices. TODO: consolidate printing functions
239-
template <typename TUPLE_TYPE>
240-
static ostream &
241-
print(ostream &out, TUPLE_TYPE const *p)
242-
{
243-
if (p)
244-
{
245-
datalog::print<typename TUPLE_TYPE::TupleType>(out, *p);
246-
}
247-
return out;
248-
}
249-
250222
template<typename RULE_TYPE>
251223
struct Iterator
252224
{
@@ -257,13 +229,6 @@ struct State
257229
{
258230
}
259231

260-
static ostream &
261-
print(ostream &out, const SliceType &slice)
262-
{
263-
apply([&out](auto &&... args) { ((print(out, args), ...)); }, slice);
264-
return out;
265-
}
266-
267232
private:
268233
template <size_t I>
269234
void pick(const SetsOfRelationsType &relations, SliceType &slice)
@@ -386,6 +351,14 @@ struct State
386351
}
387352
};
388353

354+
template <typename... RELATIONs>
355+
ostream & operator<<(ostream &out, const State<RELATIONs...>& state) {
356+
out << "[";
357+
apply([&out](auto &&... args) { ((operator<<(out, args)), ...); }, state.relations);
358+
out << "] ";
359+
return out;
360+
}
361+
389362
template <typename RULE_TYPE>
390363
static void unbind(const typename RULE_TYPE::BodyType &atoms)
391364
{

tests/types_test.cpp

Lines changed: 84 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -4,134 +4,125 @@ using namespace datalog;
44

55
bool test1()
66
{
7-
enum Kind
8-
{
9-
person = 0,
10-
god
7+
// Relations
8+
typedef const char* NameType;
9+
enum Kind {person, god};
10+
struct Thing : Relation<NameType, Kind>{};
11+
struct Mortal : Relation<NameType>{};
12+
13+
// Rule
14+
Variable<NameType> x;
15+
struct PeopleAreMortal : Rule<Mortal, Thing> {} rule{
16+
atom<Mortal>(x),
17+
{
18+
atom<Thing>(x, person)
19+
}
1120
};
1221

13-
struct Thing : Relation<string, Kind>
14-
{
15-
};
22+
// Extensional data
23+
NameType socrates{"Socrates"};
24+
NameType rhiannon{"Rhiannon"};
25+
NameType albert{"Albert"};
26+
NameType anna{"Anna"};
27+
NameType henry{"Henry"};
28+
NameType ian{"Ian"};
29+
NameType zeus{"Zeus"};
30+
NameType persephone{"Persephone"};
31+
NameType thor{"Thor"};
1632

1733
Thing::Set things{
18-
{"Socrates", person},
19-
{"Rhiannon", person},
20-
{"Albert", person},
21-
{"Anna", person},
22-
{"Henry", person},
23-
{"Ian", person},
24-
{"Zeus", god},
25-
{"Persephone", god},
26-
{"Thor", god}};
27-
28-
struct Mortal : Relation<string>
29-
{
30-
};
31-
32-
struct AllPeopleAreMortal : Rule<Mortal, Thing>
33-
{
34-
Variable<string> x;
35-
36-
AllPeopleAreMortal() : Define{
37-
Mortal::Atom{var(x)},
38-
{Thing::Atom{var(x), {person}}}} {};
39-
};
34+
{socrates, person},
35+
{rhiannon, person},
36+
{albert, person},
37+
{anna, person},
38+
{henry, person},
39+
{ian, person},
40+
{zeus, god},
41+
{persephone, god},
42+
{thor, god}};
4043

4144
State<Thing, Mortal> state{things, {}};
4245

43-
cout << "before = ";
44-
state.print(cout);
45-
cout << endl;
46+
// Apply rule
47+
RuleSet<PeopleAreMortal> rules{rule};
4648

47-
RuleSet<AllPeopleAreMortal> rules{};
49+
cout << "before = " << state << endl;
4850
state = fixPoint(rules, state);
49-
50-
cout << "after = ";
51-
state.print(cout);
52-
cout << endl;
51+
cout << "after = " << state << endl;
5352

5453
return true;
5554
}
5655

5756
bool test2()
5857
{
59-
60-
struct Adviser : Relation<string, string>
61-
{
62-
};
63-
64-
Adviser::Set advisers{
65-
{"Andrew Rice", "Mistral Contrastin"},
66-
{"Dominic Orchard", "Mistral Contrastin"},
67-
{"Andy Hopper", "Andrew Rice"},
68-
{"Alan Mycroft", "Dominic Orchard"},
69-
10000 {"David Wheeler", "Andy Hopper"},
70-
{"Rod Burstall", "Alan Mycroft"},
71-
{"Robin Milner", "Alan Mycroft"}};
72-
73-
struct AcademicAncestor : Relation<string, string>
74-
{
75-
};
58+
// Relations
59+
typedef const char* NameType;
60+
struct Adviser : Relation<NameType, NameType>{};
61+
struct AcademicAncestor : Relation<NameType, NameType>{};
62+
struct QueryResult : Relation<NameType>{};
7663

7764
// Rule1
78-
struct DirectAdviserIsAnAcademicAncestor : Rule<AcademicAncestor, Adviser>
79-
{
80-
Variable<string> x, y;
65+
Variable<NameType> x, y, z;
8166

82-
DirectAdviserIsAnAcademicAncestor() : Define{
83-
AcademicAncestor::Atom{var(x), var(y)},
84-
{Adviser::Atom{var(x), var(y)}}} {};
67+
struct DirectAcademicAncestor : Rule<AcademicAncestor, Adviser> {} rule1{
68+
atom<AcademicAncestor>(x, y),
69+
{
70+
atom<Adviser>(x, y)
71+
}
8572
};
8673

8774
// Rule2
88-
struct IndirectAdviserIsAnAcademicAncestor : Rule<AcademicAncestor, Adviser, AcademicAncestor>
89-
{
90-
Variable<string> x, y, z;
91-
92-
IndirectAdviserIsAnAcademicAncestor() : Define{
93-
AcademicAncestor::Atom{var(x), var(z)},
94-
{Adviser::Atom{var(x), var(y)},
95-
AcademicAncestor::Atom{var(y), var(z)}}} {};
75+
struct IndirectAcademicAncestor : Rule<AcademicAncestor, Adviser, AcademicAncestor> {} rule2{
76+
atom<AcademicAncestor>(x, z),
77+
{
78+
atom<Adviser>(x, y),
79+
atom<Adviser>(y, z)
80+
}
9681
};
9782

98-
// Query
99-
struct QueryResult : Relation<string>
100-
{
101-
};
102-
103-
struct Query : Rule<QueryResult, AcademicAncestor, AcademicAncestor>
104-
{
105-
Variable<string> x, y;
106-
107-
Query() : Define{
108-
QueryResult::Atom{var(x)},
109-
{AcademicAncestor::Atom{{"Robin Milner"}, var(x)},
110-
AcademicAncestor::Atom{var(x), {"Mistral Contrastin"}}}} {};
111-
};
83+
// Extensional data
84+
NameType andrew{"Andrew Rice"};
85+
NameType mistral{"Mistral Contrastin"};
86+
NameType dominic{"Dominic Orchard"};
87+
NameType andy{"Andy Hopper"};
88+
NameType alan{"Alan Mycroft"};
89+
NameType rod{"Rod Burstall"};
90+
NameType robin{"Robin Milner"};
91+
NameType david{"David Wheeler"};
11292

93+
Adviser::Set advisers{
94+
{andrew, mistral},
95+
{dominic, mistral},
96+
{andy, andrew},
97+
{alan, dominic},
98+
{david, andy},
99+
{rod, alan},
100+
{robin, alan}};
113101
State<Adviser, AcademicAncestor, QueryResult> state{advisers, {}, {}};
114102

115103
// Apply multiple rules
116104
{
117-
RuleSet<DirectAdviserIsAnAcademicAncestor, IndirectAdviserIsAnAcademicAncestor> rules{};
105+
RuleSet<DirectAcademicAncestor, IndirectAcademicAncestor> rules{{rule1, rule2}};
118106

119-
cout << "before = ";
120-
state.print(cout);
121-
cout << endl;
107+
cout << "before = " << state << endl;
122108
state = fixPoint(rules, state);
123-
cout << "after = ";
124-
state.print(cout);
125-
cout << endl;
109+
cout << "after = " << state << endl;
126110
}
127111

112+
// Query
113+
struct Query : Rule<QueryResult, AcademicAncestor, AcademicAncestor> {} query{
114+
atom<QueryResult>(x),
115+
{
116+
atom<AcademicAncestor>(robin, x),
117+
atom<AcademicAncestor>(x, mistral)
118+
}
119+
};
120+
128121
// Apply a query
129122
{
130-
RuleSet<Query> rules{};
123+
RuleSet<Query> rules{query};
131124
state = fixPoint(rules, state);
132-
cout << "after = ";
133-
state.print(cout);
134-
cout << endl;
125+
cout << "after = " << state << endl;
135126
}
136127

137128
return true;

0 commit comments

Comments
 (0)
0