8000 more definitions · Z80coder/datalog-cpp@5bd7111 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5bd7111

Browse files
author
wright
committed
more definitions
1 parent 454630e commit 5bd7111

File tree

2 files changed

+171
-71
lines changed

2 files changed

+171
-71
lines changed

src/Datalog.h

Lines changed: 129 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,95 +5,182 @@
55
#include <set>
66
#include <variant>
77
#include <vector>
8+
#include <map>
89
#include <limits>
910
#include <cassert>
11+
#include <iostream>
1012

1113
namespace datalog {
1214

1315
using namespace std;
1416

15-
struct Id {
16-
const string value;
17+
struct Symbol {
18+
string name;
1719
};
1820

1921
template<typename T>
20-
struct Value {
22+
struct SymbolOrValue {
2123

22-
Value(const T& value) :
23-
isVariable(false), value(value), id(Id { "" }) {
24+
SymbolOrValue() :
25+
isSymbol(false), symbol(Symbol { "" }) {
2426
}
2527

26-
Value(const Id& id) :
27-
isVariable(true), id(id) {
28+
SymbolOrValue(const T& value) :
29+
isSymbol(false), symbol(Symbol { "" }), value(value) {
2830
}
2931

30-
bool isVar() const {
31-
return this->isVariable;
32+
SymbolOrValue(const Symbol& symbol) :
33+
isSymbol(true), symbol(symbol), value() {
34+
}
35+
36+
SymbolOrValue(const SymbolOrValue& other) :
37+
isSymbol(other.isSymbol), symbol(other.symbol), value(other.value) {
38+
}
39+
40+
bool isSym() const {
41+
return this->isSymbol;
42+
}
43+
44+
const Symbol& getSym() const {
45+
return this->symbol;
3246
}
3347

3448
const T& getVal() const {
35-
assert(!isVariable);
49+
assert(!isSymbol);
3650
return value;
3751
}
3852

39-
const unsigned int getVar() const {
40-
assert(isVariable);
41-
return id;
53+
void bindVal(const T& value) {
54+
this->value = value;
4255
}
4356

44-
bool operator <(const Value &other) const {
57+
bool operator <(const SymbolOrValue &other) const {
4558
return value < other.value;
4659
}
4760

61+
SymbolOrValue& operator =(const SymbolOrValue &other) {
62+
this->isSymbol = other.isSymbol;
63+
this->symbol = other.symbol;
64+
this->value = other.value;
65+
return *this;
66+
}
67+
4868
private:
49-
bool isVariable;
69+
bool isSymbol;
70+
Symbol symbol;
5071
T value;
51-
Id id;
5272
};
5373

54-
typedef Value<int> Int;
55-
typedef Value<string> String;
56-
5774
template<typename ... Ts>
58-
struct Relation {
59-
typedef tuple<Ts...> TupleType;
75+
struct RelationType {
76+
typedef tuple<Ts...> GroundType;
77+
typedef tuple<SymbolOrValue<Ts> ...> AtomicType;
78+
};
6079

61-
Relation(const set<TupleType>& tuples) :
80+
template<typename RELATION_TYPE>
81+
struct Relation {
82+
typedef typename RELATION_TYPE::GroundType GroundType;
83+
Relation(const set<GroundType>& tuples) :
6284
tuples(tuples) {
6385
}
64-
65-
set<TupleType> tuples;
66-
86+
const set<GroundType> tuples;
6787
};
6888

69-
template<typename ... Ts>
70-
static Relation<Ts...> merge(const Relation<Ts...>& r1, const Relation<Ts...>& r2) {
71-
set<tuple<Ts...>> tuples { r1.tuples };
72-
tuples.insert(r2.tuples.begin(), r2.tuples.end());
73-
return Relation<Ts...> { tuples };
74-
}
75-
76-
template<typename RELATION>
77-
struct Atom: RELATION {
78-
79-
Atom(const typename RELATION::TupleType& tuple) :
80-
RELATION(set<typename RELATION::TupleType> { tuple }) {
89+
template<typename RELATION_TYPE>
90+
struct Atom {
91+
typedef typename RELATION_TYPE::AtomicType AtomicType;
92+
Atom(const AtomicType& tuple) :
93+
tuple { tuple } {
94+
#if 0
95+
unsigned int index = 0;
96+
apply([this, &index](auto&&... args) {
97+
((args.isSym() ? declareSym(args, index++, symIndexMap) : noOp(index++)), ...);}, tuple);
98+
#endif
99+
}
100+
const AtomicType tuple;
101+
#if 0
102+
typedef map<string, set<unsigned int>> SymIndexMapType;
103+
SymIndexMapType symIndexMap;
104+
private:
105+
template<typename T>
106+
static void declareSym(const T& t, unsigned int index, SymIndexMapType& symIndexMap) {
107+
auto symbolName = t.getSym().name;
108+
if (symIndexMap.count(symbolName) == 0) {
109+
symIndexMap.insert( { symbolName, { } });
110+
}
111+
auto it = symIndexMap.find(symbolName);
112+
it->second.insert(index);
113+
}
114+
static void noOp(unsigned int index) {
81115
}
116+
#endif
82117
};
83118

84119
template<typename ... ATOMs>
85120
struct Body {
86121
typedef variant<ATOMs...> AtomsType;
87-
88-
vector<AtomsType> atoms;
122+
const vector<AtomsType> atoms;
89123
};
90124

91-
template<typename HEAD_ATOM, typename ... BODY_ATOMs>
125+
template<typename HEAD_RELATION, typename ... BODY_RELATIONs>
92126
struct Rule {
93-
HEAD_ATOM head;
94-
Body<BODY_ATOMs...> body;
127+
const Atom<HEAD_RELATION> head;
128+
const Body<Atom<BODY_RELATIONs> ...> body;
95129
};
96130

131+
#if 0
132+
typedef map<string, set<unsigned int>> SymBindingsType;
133+
134+
template<typename T>
135+
static void bind(const T& t, SymBindingsType& symBindings) {
136+
}
137+
138+
static void noOp() {
139+
}
140+
#endif
141+
142+
#if 0
143+
template<typename RELATION_TYPE>
144+
constexpr typename RELATION_TYPE::AtomicType bind(const typename RELATION_TYPE::AtomicType& atom, const typename RELATION_TYPE::GroundType& fact, size_t i) {
145+
typename RELATION_TYPE::AtomicType boundAtom{atom};
146+
if (get<i>(atom)) {
147+
B421 148+
}
149+
return boundAtom;
150+
}
151+
152+
// bind 1 atom with 1 fact
153+
template<typename RELATION_TYPE, size_t ... Is>
154+
static Atom<RELATION_TYPE> bind(const Atom<RELATION_TYPE>& atom, const typename RELATION_TYPE::GroundType& fact, index_sequence<Is...>) {
155+
typename RELATION_TYPE::AtomicType boundAtom { atom.tuple };
156+
157+
((boundAtom = bind<RELATION_TYPE>(boundAtom, fact, Is)), ...);
158+
//((boundAtom = bind<RELATION_TYPE>(boundAtom, fact, Is)), ...);
159+
//apply([&boundAtom](auto&&... element) {
160+
// ((atomicElement.isSym() ? bind(atomicElement, symBindings) : noOp()), ...);}, fact);
161+
162+
return Atom<RELATION_TYPE> { boundAtom };
163+
}
164+
165+
template<typename RELATION_TYPE>
166+
static Relation<RELATION_TYPE> bind(const Atom<RELATION_TYPE>& atom, const Relation<RELATION_TYPE>& relation) {
167+
Relation<RELATION_TYPE> boundAtoms;
168+
auto indexSequence = index_sequence_for<typename RELATION_TYPE::GroundType> { };
169+
for (const auto& fact : relation.tuples) {
170+
typename RELATION_TYPE::GroundType boundAtom = bind(atom, fact, indexSequence);
171+
boundAtoms.tuples.insert(boundAtom);
172+
}
173+
return boundAtoms;
174+
}
175+
#endif
176+
177+
template<typename RELATION_TYPE>
178+
static RELATION_TYPE merge(const RELATION_TYPE& r1, const RELATION_TYPE& r2) {
179+
set<typename RELATION_TYPE::GroundType> tuples { r1.tuples };
180+
tuples.insert(r2.tuples.begin(), r2.tuples.end());
181+
return RELATION_TYPE { tuples };
182+
}
183+
97184
}
98185

99186
#endif /* SRC_DATALOG_H_ */

tests/types_test.cpp

Lines changed: 42 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4,53 +4,66 @@ using namespace datalog;
44

55
int main() {
66

7+
struct Int: RelationType<int> {
8+
};
9+
struct Int_Int: RelationType<int, int> {
10+
};
11+
struct String_Int: RelationType<string, int> {
12+
};
13+
struct String_Int_String: RelationType<string, int, string> {
14+
};
715
{
8-
Relation<int> r1 { { { 1 } } };
9-
Relation<int, int> r2 { { { 1, 2 } } };
10-
Relation<string, int> r3 { { { "hello", 1 } } };
11-
Relation<string, int> r4 { { { "hello", 1 }, { "world", 2 } } };
12-
Relation<int, int> r5 { { { 1, 2 }, { 3, 4 } } };
13-
Relation<string, int, string> r6 { { { "hello", 1, "world" }, { "world", 2, "hello" }, { "world", 3, "world" } } };
14-
15-
Relation<string, int> r7 = merge(r3, r4);
16+
Relation<Int> r1 { { { 1 }, { 2 } } };
17+
18+
Relation<Int_Int> r2 { { { 1, 2 } } };
19+
Relation<Int_Int> r3 { { { 1, 2 }, { 3, 4 } } };
20+
21+
Relation<String_Int> r4 { { { "hello", 1 } } };
22+
Relation<String_Int> r5 { { { "hello", 1 }, { "world", 2 } } };
23+
24+
Relation<String_Int_String> r6 { { { "hello", 1, "world" }, { "world", 2, "hello" }, { "world", 3, "world" } } };
25+
26+
Relation<String_Int> r7 = merge(r4, r5);
1627
}
1728

1829
{
19-
Relation<Int> r2 { { { 1, Id { "2" } } } };
20-
Relation<String, Int> r4 { { { { "hello" }, 1 }, { { "world" }, Id { "2" } } } };
21-
Relation<String, Int, String> r6 { { { { "hello" }, 1, { Id { "3" } } }, { { "world" }, 2, { "hello" } }, { { Id { "4" } }, 3, { "world" } } } };
30+
Atom<Int_Int> r1 { { 1, Symbol { "2" } } };
31+
Atom<String_Int> r2 { { { "world" }, Symbol { "2" } } };
32+
Atom<String_Int_String> r3 { { { "hello" }, 1, { Symbol { "3" } } } };
2233
}
2334

2435
{
25-
struct Adviser: Relation<String, String> {
26-
using Relation<String, String>::Relation;
36+
struct Adviser: RelationType<string, string> {
2737
};
28-
Adviser advisers { { { { "Andrew Rice" }, { "Mistral Contrastin" } }, { { "Andy Hopper" }, { "Andrew Rice" } }, { { "Alan Mycroft" }, {
38+
Relation<Adviser> advisers { { { { "Andrew Rice" }, { "Mistral Contrastin" } }, { { "Andy Hopper" }, { "Andrew Rice" } }, { { "Alan Mycroft" }, {
2939
"Dominic Orchard" } }, { { "David Wheeler" }, { "Andy Hopper" } }, { { "Rod Burstall" }, { "Alan Mycroft" } }, { { "Robin Milner" }, {
3040
"Alan Mycroft" } } } };
3141

32-
struct AcademicAncestor: Relation<String, String> {
33-
using Relation<String, String>::Relation;
42+
struct AcademicAncestor: RelationType<string, string> {
3443
};
3544

3645
// Rule1
37-
Atom<AcademicAncestor> head1 { { Id { "x" }, Id { "y" } } };
38-
Atom<Adviser> clause1 { { Id { "x" }, Id { "y" } } };
39-
Rule<Atom<AcademicAncestor>, Atom<Adviser>> rule1 { head1, { { clause1 } } };
46+
Atom<AcademicAncestor> head1 { { Symbol { "x" }, Symbol { "y" } } };
47+
Atom<Adviser> clause1 { { Symbol { "x" }, Symbol { "y" } } };
48+
Rule<AcademicAncestor, Adviser> rule1 { head1, { { clause1 } } };
4049

4150
// Rule2
42-
Atom<AcademicAncestor> head2 { { Id { "x" }, Id { "z" } } };
43-
Atom<Adviser> clause21 { { Id { "x" }, Id { "y" } } };
44-
Atom<AcademicAncestor> clause22 { { Id { "y" }, Id { "z" } } };
45-
Rule<Atom<AcademicAncestor>, Atom<Adviser>, Atom<AcademicAncestor>> rule2 { head2, { { clause21, clause22 } } };
51+
Atom<AcademicAncestor> head2 { { Symbol { "x" }, Symbol { "z" } } };
52+
Atom<Adviser> clause2 { { Symbol { "x" }, Symbol { "y" } } };
53+
Atom<AcademicAncestor> clause3 { { Symbol { "y" }, Symbol { "z" } } };
54+
Rule<AcademicAncestor, Adviser, AcademicAncestor> rule2 { head2, { { clause2, clause3 } } };
4655

4756
// Query1
48-
struct Query1: Relation<String> {
49-
using Relation<String>::Relation;
57+
struct Query1: RelationType<string> {
5058
};
51-
Atom<Query1> head3 { { Id { "x" } } };
52-
Atom<AcademicAncestor> clause31 { { { "Robin Milner" }, Id { "x" } } };
53-
Atom<AcademicAncestor> clause32 { { Id { "x" }, { "Mistral Contrastin" } } };
54-
Rule<Atom<Query1>, Atom<AcademicAncestor>> query1 { head3, { { clause31, clause32 } } };
59+
Atom<Query1> head3 { { Symbol { "x" } } };
60+
Atom<AcademicAncestor> clause4 { { { "Robin Milner" }, Symbol { "x" } } };
61+
Atom<AcademicAncestor> clause5 { { Symbol { "x" }, { "Mistral Contrastin" } } };
62+
Rule<Query1, AcademicAncestor> query1 { head3, { { clause4, clause5 } } };
63+
64+
Adviser::GroundType fact1{ { "Andrew Rice" }, { "Mistral Contrastin" } };
65+
auto indexSequence = index_sequence_for<typename Adviser::GroundType>{};
66+
//auto boundAtom = bind(clause1, fact1, indexSequence);
67+
5568
}
5669
}

0 commit comments

Comments
 (0)
0